From b3430bfdaf02fe7ee14def8f6892e705ed0e9459 Mon Sep 17 00:00:00 2001 From: Clenain <cyril.lenain1@gmail.com> Date: Wed, 18 Sep 2019 15:15:44 +0200 Subject: [PATCH] Adding analyse codes for MINOS --- NPLib/Detectors/Minos/CMakeLists.txt | 28 +- NPLib/Detectors/Minos/MTreeStructureLinkDef.h | 11 + NPLib/Detectors/Minos/TMinosClust.cxx | 43 + NPLib/Detectors/Minos/TMinosClust.h | 26 + NPLib/Detectors/Minos/TMinosPhysics.cxx | 785 ++++++++++++++---- NPLib/Detectors/Minos/TMinosPhysics.h | 250 ++++-- NPLib/Detectors/Minos/TMinosResult.cxx | 37 + NPLib/Detectors/Minos/TMinosResult.h | 25 + NPLib/TrackReconstruction/CMakeLists.txt | 6 +- .../NPTrackReconstructionLinkDef.h | 1 + NPLib/TrackReconstruction/Tracking.cxx | 488 +++++++++++ NPLib/TrackReconstruction/Tracking.h | 33 + 12 files changed, 1534 insertions(+), 199 deletions(-) create mode 100644 NPLib/Detectors/Minos/MTreeStructureLinkDef.h create mode 100644 NPLib/Detectors/Minos/TMinosClust.cxx create mode 100644 NPLib/Detectors/Minos/TMinosClust.h create mode 100644 NPLib/Detectors/Minos/TMinosResult.cxx create mode 100644 NPLib/Detectors/Minos/TMinosResult.h create mode 100644 NPLib/TrackReconstruction/Tracking.cxx create mode 100644 NPLib/TrackReconstruction/Tracking.h diff --git a/NPLib/Detectors/Minos/CMakeLists.txt b/NPLib/Detectors/Minos/CMakeLists.txt index c3874b7f6..4e7173cab 100644 --- a/NPLib/Detectors/Minos/CMakeLists.txt +++ b/NPLib/Detectors/Minos/CMakeLists.txt @@ -1,6 +1,28 @@ +include(CheckLanguage) + add_custom_command(OUTPUT TMinosPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TMinosPhysics.h TMinosPhysicsDict.cxx TMinosPhysics.rootmap libNPMinos.dylib DEPENDS TMinosPhysics.h) add_custom_command(OUTPUT TMinosDataDict.cxx COMMAND ../../scripts/build_dict.sh TMinosData.h TMinosDataDict.cxx TMinosData.rootmap libNPMinos.dylib DEPENDS TMinosData.h) -add_library(NPMinos SHARED TMinosSpectra.cxx TMinosData.cxx TMinosPhysics.cxx TMinosDataDict.cxx TMinosPhysicsDict.cxx ) -target_link_libraries(NPMinos ${ROOT_LIBRARIES} NPCore) -install(FILES TMinosData.h TMinosPhysics.h TMinosSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) +add_custom_command(OUTPUT TMinosClustDict.cxx COMMAND ../../scripts/build_dict.sh TMinosClust.h TMinosClustDict.cxx TMinosClust.rootmap libNPMinos.dylib DEPENDS TMinosClust.h) +add_custom_command(OUTPUT TMinosResultDict.cxx COMMAND ../../scripts/build_dict.sh TMinosResult.h TMinosResultDict.cxx TMinosResult.rootmap libNPMinos.dylib DEPENDS TMinosResult.h) + +## Check if MINUIT2 is installed along with ROOT +find_library(libMinuit_FOUND NAMES Minuit HINTS "$ENV{ROOTSYS}/lib") +if(libMinuit_FOUND) + message(STATUS "Minuit support enabled for Minos.") + add_definitions(-DHAVE_MINUIT) +else() + message(STATUS "Minuit support disabled for Minos. Not found in $ENV{ROOTSYS}/lib") +endif() + +add_library(NPMinos SHARED TMinosClust.cxx TMinosData.cxx TMinosPhysics.cxx TMinosResult TMinosDataDict.cxx TMinosPhysicsDict.cxx TMinosClustDict.cxx TMinosResultDict.cxx) + +if(libMinuit_FOUND) +## Link to Minuit2 library + target_link_libraries(NPMinos ${ROOT_LIBRARIES} NPCore NPTrackReconstruction Minuit) +else() +## No Minuit2 library, skip linking + target_link_libraries(NPMinos ${ROOT_LIBRARIES} NPCore NPTrackReconstruction) +endif() + +install(FILES TMinosClust.h TMinosData.h TMinosPhysics.h TMinosResult.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) diff --git a/NPLib/Detectors/Minos/MTreeStructureLinkDef.h b/NPLib/Detectors/Minos/MTreeStructureLinkDef.h new file mode 100644 index 000000000..8745cb31f --- /dev/null +++ b/NPLib/Detectors/Minos/MTreeStructureLinkDef.h @@ -0,0 +1,11 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ nestedclasses; + +#pragma link C++ class TMinosClust+; +#pragma link C++ class TMinosResult+; + +#endif diff --git a/NPLib/Detectors/Minos/TMinosClust.cxx b/NPLib/Detectors/Minos/TMinosClust.cxx new file mode 100644 index 000000000..9f2d61d5c --- /dev/null +++ b/NPLib/Detectors/Minos/TMinosClust.cxx @@ -0,0 +1,43 @@ +//---------- Written by C. Santamaria / CEA Saclay !---------- +#include "TMinosClust.h" + +ClassImp(TMinosClust) + +TMinosClust::TMinosClust() +: TObject(), x_mm(0), y_mm(0), t_ns(0), z_mm(0), Chargemax(0), n_Cluster(0), n_Pads(0), Chi2(0){ +// Constructor +} +TMinosClust::TMinosClust(Double_t xmm, Double_t ymm, Double_t tns, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t chi2) + : TObject() +{ + // Constructor + x_mm = xmm; + y_mm= ymm; + t_ns = tns; + z_mm = zmm; + Chargemax = chargemax; + n_Cluster = ncluster; + n_Pads = npads; + Chi2 = chi2; +} +TMinosClust::~TMinosClust() +{ +// Destructor +} + +void TMinosClust::Set(Double_t xmm, Double_t ymm, Double_t tns, Double_t zmm, Double_t chargemax, Double_t ncluster, Double_t npads, Double_t chi2) +{ + x_mm = xmm; + y_mm= ymm; + t_ns = tns; + z_mm = zmm; + Chargemax = chargemax; + n_Cluster = ncluster; + n_Pads = npads; + Chi2 = chi2; +} + +void TMinosClust::SetZ(Double_t zmm) +{ + z_mm = zmm; +} diff --git a/NPLib/Detectors/Minos/TMinosClust.h b/NPLib/Detectors/Minos/TMinosClust.h new file mode 100644 index 000000000..d7ee47d67 --- /dev/null +++ b/NPLib/Detectors/Minos/TMinosClust.h @@ -0,0 +1,26 @@ +//----------! Written by C. Santamaria / CEA Saclay !---------- +#ifndef TMINOSCLUST_H +#define TMINOSCLUST_H + +#include "TObject.h" + +class TMinosClust : public TObject { + public: + TMinosClust(); + TMinosClust(Double_t xmm, Double_t ymm, Double_t tns, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t chi2); + void Set(Double_t xmm, Double_t ymm, Double_t tns, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t chi2); + void SetZ(Double_t zmm); + virtual ~TMinosClust(); + public: + Double_t x_mm; + Double_t y_mm; + Double_t t_ns; + Double_t z_mm; + Double_t Chargemax; + Double_t n_Cluster; + Double_t n_Pads; + Double_t Chi2; + + ClassDef(TMinosClust,1); +}; +#endif // end of #ifndef TMINOSCLUST_H diff --git a/NPLib/Detectors/Minos/TMinosPhysics.cxx b/NPLib/Detectors/Minos/TMinosPhysics.cxx index 6ea1a9931..e5302de98 100644 --- a/NPLib/Detectors/Minos/TMinosPhysics.cxx +++ b/NPLib/Detectors/Minos/TMinosPhysics.cxx @@ -1,18 +1,19 @@ /***************************************************************************** - * Copyright (C) 2009-2018 this file is part of the NPTool Project * + * Copyright (C) 2009-2018 this file is part of the NPTool Project * * * * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * * For the list of contributors see $NPTOOL/Licence/Contributors * *****************************************************************************/ /***************************************************************************** - * Original Author: Elidiano Tronchin contact address: tronchin@lpccaen.in2p3.fr * + * Original Author: Developed by C. Santamaria / CEA Saclay * * * - * Creation Date : October 2018 * - * Last update : * + * Creation Date : 2014/11/24 * + * Last update : 2019/09 implemeted in NPTool by Cyril Lenain * + * lenain@lpccaen.in2p3.fr * *---------------------------------------------------------------------------* * Decription: * - * This class hold Minos Treated data * + * This class hold Minos Treated data * * * *---------------------------------------------------------------------------* * Comment: * @@ -35,23 +36,40 @@ using namespace std; #include "RootOutput.h" #include "NPDetectorFactory.h" #include "NPOptionManager.h" +#include "TMinosClust.h" +#include "TMinosResult.h" // ROOT #include "TChain.h" +#include "TROOT.h" +#include "TMath.h" +#include "TMinuit.h" +#include "/opt/cern/root/root_v5.34.36/math/genvector/inc/Math/Vector3D.h" +#include "TStyle.h" +#include "TClonesArray.h" -ClassImp(TMinosPhysics) - +TMinosPhysics* current_phy = 0; /////////////////////////////////////////////////////////////////////////// TMinosPhysics::TMinosPhysics() : m_EventData(new TMinosData), m_PreTreatedData(new TMinosData), m_EventPhysics(this), - m_Spectra(0), + Tracking_functions(new Tracking), m_E_RAW_Threshold(0), // adc channels m_E_Threshold(0), // MeV + hfit(new TH1F("hfit","hfit",512,0,512)), + grxztmp(new TGraph()), + gryztmp(new TGraph()), + npoint_temp(0), + allevt_2pfiltered(0), m_NumberOfDetectors(0) { -} + current_phy = this; + data_result.SetClass("TMinosResult"); + fitdata.SetClass("TMinosClust"); + } + +int NclusterFit; /////////////////////////////////////////////////////////////////////////// /// A usefull method to bundle all operation to add a detector @@ -63,70 +81,506 @@ void TMinosPhysics::AddDetector(TVector3 , string ){ } /////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::AddDetector(double R, double Theta, double Phi, string shape){ +void TMinosPhysics::AddDetector(double R, double Theta, TVector3 POS, double Phi, double TargetLenght){ // Compute the TVector3 corresponding - TVector3 Pos(R*sin(Theta)*cos(Phi),R*sin(Theta)*sin(Phi),R*cos(Theta)); // Call the cartesian method - AddDetector(Pos,shape); } /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::BuildSimplePhysicalEvent() { - /* BuildPhysicalEvent(); */ + BuildPhysicalEvent(); } - - /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::BuildPhysicalEvent() { // apply thresholds and calibration - /* PreTreat(); */ - - // match energy and time together - /* unsigned int mysizeE = m_PreTreatedData->GetMultEnergy(); */ - /* unsigned int mysizeT = m_PreTreatedData->GetMultTime(); */ - /* for (UShort_t e = 0; e < mysizeE ; e++) { */ - /* for (UShort_t t = 0; t < mysizeT ; t++) { */ - /* if (m_PreTreatedData->GetE_DetectorNbr(e) == m_PreTreatedData->GetT_DetectorNbr(t)) { */ - /* DetectorNumber.push_back(m_PreTreatedData->GetE_DetectorNbr(e)); */ - /* Energy.push_back(m_PreTreatedData->Get_Energy(e)); */ - /* Time.push_back(m_PreTreatedData->Get_Time(t)); */ - /* } */ - /* } */ - /* } */ + PreTreat(); +} + +// definition of the fit function for the signal Q(t) +double TMinosPhysics::conv_fit(double *x, double *p){ + double val; + if(!(x[0]<p[1] || x[0]>512.)) val = p[0] * exp(-3.*(x[0]-p[1])/p[2]) * sin((x[0]-p[1])/p[2]) * pow((x[0]-p[1])/p[2], 3) + 250; + //else val = p[3]; + else val = 250; + return(val); } /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::PreTreat() { - /* // This method typically applies thresholds and calibrations */ - /* // Might test for disabled channels for more complex detector */ - - /* // clear pre-treated object */ - /* ClearPreTreatedData(); */ - - /* // instantiate CalibrationManager */ - /* static CalibrationManager* Cal = CalibrationManager::getInstance(); */ - - /* // Energy */ - /* unsigned int mysize = m_EventData->GetMultEnergy(); */ - /* for (UShort_t i = 0; i < mysize ; ++i) { */ - /* if (m_EventData->Get_Energy(i) > m_E_RAW_Threshold) { */ - /* Double_t Energy = Cal->ApplyCalibration("Minos/ENERGY"+NPL::itoa(m_EventData->GetE_DetectorNbr(i)),m_EventData->Get_Energy(i)); */ - /* if (Energy > m_E_Threshold) { */ - /* m_PreTreatedData->SetEnergy(m_EventData->GetE_DetectorNbr(i), Energy); */ - /* } */ - /* } */ - /* } */ - /* // Time */ - /* mysize = m_EventData->GetMultTime(); */ - /* for (UShort_t i = 0; i < mysize; ++i) { */ - /* Double_t Time= Cal->ApplyCalibration("Minos/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i)); */ - /* m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time); */ - /* } */ -} + // This method applies thresholds and calibrations + // Isolate 2D tracks with the modified HoughTransformation + // Calculate z for each pad + + data_result.Clear(); + fitdata.Clear(); + + TMinosClust *minosfitdata; + + ////////////////////fit variables////////////////////// + + fit_function = new TF1("fit_function",conv_fit, 0, 511, 3); + int fit2DStatus = 0.; + double fit_function_max = 0., fit_function_Tpad = 0.; + double Chi2 = 0.; + double Tshaping = 333.9; + const double TimeBinElec = 30.; // in ns + double MINOSthresh, VDrift, Z_Shift, DelayTrig; + + if(SimulationBool){ // case of simulated data + MINOSthresh = 1000000000.; // + DelayTrig = 0.; + /* VDrift = 0.036; */ + VDrift = 0.03; + Z_Shift = 0; + } + else{ // case of experiment data + MINOSthresh = 100000.; + DelayTrig = 10170; + VDrift = 0.03475; // in mm/ns + /* Z_Shift = 57.16; // */ + Z_Shift = 0. ; // + } + + /////////////////////////////////////////////////////// + ClearPreTreatedData(); + /// Read Q(t) signal to fit and extract DriftTime + + unsigned int NbOfPad = m_EventData->GetPadNumberMult(); + filled =0;trackNbr=0; + trackNbr_FINAL=0; + ringsum=0; + zmax=0.;Iteration=0; + for (unsigned int e = 0; e < NbOfPad; e++){ + + x_mm = 0.; y_mm = 0.; z_mm = 0.;maxCharge = 0.; t_pad =0; q_pad=0; + x_mm = m_EventData->GetPadX(e); + y_mm = m_EventData->GetPadY(e); + + if ( !(abs(x_mm)<0.0001 && abs(y_mm)<0.0001) ) { + for (UShort_t o = 0; o < m_EventData->GetTime(e).size() ; ++o){ + if(m_EventData->GetCharge(e)[o]> maxCharge){ + maxCharge = m_EventData->GetCharge(e)[o]; + } + } + + if((maxCharge < MINOSthresh && round((sqrt(x_mm*x_mm+y_mm*y_mm)-44.15)/2.1) < 16 && round((sqrt(x_mm*x_mm+y_mm*y_mm)-44.15)/2.1) >4 )) { // to remove rings 1,2,3,4 and 16,17,18 + /* if((maxCharge < MINOSthresh && ( SimulationBool==1 || round((sqrt(x_mm*x_mm+y_mm*y_mm)-44.15)/2.1) < 16 && round((sqrt(x_mm*x_mm+y_mm*y_mm)-43.8)/2.1) >4 )) ) { // to remove rings 1,2,3,4 and 16,17,18 // to not apply the ring condition for simulation*/ + Xpad.push_back(x_mm); + Ypad.push_back(y_mm); + Qpad.push_back(maxCharge); + filled++; // + } + } + } //end of NbOfPad + + if(filled>0) { // Nbr of activated pads + while(Xpad.size()>=10 && Iteration< 20 ) { // !!!!!!!! + filter_result = 0; // Nbr of pads in the Track + Iteration++; + XpadTemp.clear(); + YpadTemp.clear(); + QpadTemp.clear(); + clusterringboolTemp.clear(); + + filter_result = Tracking_functions->Hough_modified(&Xpad, &Ypad, &Qpad, &XpadTemp, &YpadTemp, &QpadTemp, &clusterringboolTemp); + + if(filter_result<0) break; + if(filter_result>10 && clusterringboolTemp.back()==1){ + /* if(filter_result>4 ){ // modified for the simu w 0 dispersion */ + trackNbr++; + for(int ik=0; ik<filter_result; ik++) { + XpadNew.push_back(XpadTemp[ik]); + YpadNew.push_back(YpadTemp[ik]); + ZpadNew.push_back(-10000); + QpadNew.push_back(QpadTemp[ik]); + clusterringbool.push_back(clusterringboolTemp[ik]); + clusternbr.push_back(Iteration); + clusterpads.push_back(filter_result); + } + } + + + } + } + + for(unsigned int il=0; il<XpadNew.size(); il++){ + minosfitdata = (TMinosClust*)fitdata.ConstructedAt(il); + minosfitdata->Set(XpadNew[il], YpadNew[il], + -10000, -10000, QpadNew[il], + clusternbr[il],clusterpads[il], 0.); + ZpadNew.push_back(-10000.); + + } + + if(trackNbr>0 && trackNbr < 5 ){ /////////// + + if(filled==0) cerr << "Error !!!" << endl; + //------------------------------------------------------- + // STEP 4.1: Fitting taken pads for Qmax and Ttrig info + //------------------------------------------------------- + + for(unsigned int i=0 ; i< NbOfPad; i++ ) { + hfit->Reset(); + bool fitbool = false; + x_mm = m_EventData->GetPadX(i); + y_mm = m_EventData->GetPadY(i); + + for(unsigned int jj=0; jj<XpadNew.size(); jj++) { + if( abs(XpadNew[jj]-x_mm)<0.0001 && abs(YpadNew[jj]-y_mm)<0.0001) { + fitbool = true; + indexfill=jj; + break; + } + } + + if( fitbool==true ) { + + /* TGraph gfit( m_EventData->GetTime(i).size() ,&(m_EventData->GetTime(i)[0]),&(m_EventData->GetCharge(i)[0])); */ + /* for (UShort_t o = 0; o < m_EventData->GetTime(i).size() ; ++o){ */ + /* gfit.SetPoint(o,m_EventData->GetTime(i)[o],m_EventData->GetCharge(i)[o]+250); */ + /* if(m_EventData->GetCharge(i)[o]+250> hfit_max){ */ + /* hfit_max_T = m_EventData->GetTime(i)[o]; */ + /* hfit_max=m_EventData->GetCharge(i)[o]+250; */ + /* } */ + /* } */ + + for(Int_t j=0; j< m_EventData->GetTime(i).size(); j++) { + if(m_EventData->GetCharge(i)[j]>=0){ + hfit->SetBinContent(hfit->FindBin(m_EventData->GetTime(i)[j]), m_EventData->GetCharge(i)[j]+250); + } + } + + // Fitting the hfit histogram of last channel if not empty + + if(hfit->GetSumOfWeights()>0) { + hfit->GetXaxis()->SetRange(0,510); + hfit_max = hfit->GetMaximum(); + hfit_max_T = hfit->GetMaximumBin(); + T_min=-1; + T_max=-1; + + // Find the T_min & T_max limits of the signal non zero + for(int h=hfit_max_T;h>0;h--) { + if(T_min == -1 && (hfit->GetBinContent(h))<=250 ) { + T_min = h; + break; + } + } + for(int h=hfit_max_T;h<510;h++) { + if(T_max == -1 && (hfit->GetBinContent(h)) < 1 ) { + T_max = h; + break; + } + } + + if((hfit_max_T-3.5*(Tshaping/TimeBinElec)) > T_min) T_min = hfit_max_T-2*Tshaping/TimeBinElec; + if((hfit_max_T+10) < T_max || T_max==-1) T_max = hfit_max_T+10.; + T_min = max(T_min,0.); + if(T_max>510) T_max = 510; + + // Set fit parameters + fit_function->SetParameter(0, hfit_max-250.); + fit_function->SetParameter(1,hfit_max_T - Tshaping/TimeBinElec); + fit_function->SetParameter(2, Tshaping/TimeBinElec); + fit_function->SetParLimits(0,0,MINOSthresh); + fit_function->SetParLimits(1,-20,512); + fit_function->SetParLimits(2,0,512); + + fit2DStatus = hfit->Fit(fit_function,"QN","",T_min,T_max); + /* fit2DStatus = gfit.Fit(fit_function,"QN","",hfit_max-2*Tshaping,hfit_max+2*Tshaping); */ + + double fit_function_max = 0., fit_function_Tpad = 0.; + if(fit2DStatus==0) { + Chi2 = fit_function->GetChisquare(); + fit_function_max = fit_function->GetMaximum(); + fit_function_Tpad = fit_function->GetParameter(1); + } + + //attribute q_pad and z_mm value + if(fit2DStatus!=0 || fit_function_max<=20. || + fit_function_max >= MINOSthresh || fit_function_Tpad<=0.15 || + fit_function_Tpad>=513. || fit_function->GetParameter(2)<=0.15 || + fit_function->GetParameter(2)>=513.) { + q_pad = hfit_max-250.; + z_mm = -10000; + + } + + else { + t_pad = fit_function_Tpad; + /* z_mm = 300.-(-t_pad*TimeBinElec+DelayTrig)*VDrift[int((sqrt(x_mm*x_mm+y_mm*y_mm)-43.8)/2.1)] */ + + if(SimulationBool)z_mm = t_pad*TimeBinElec*VDrift; // for simu + else z_mm = 300.-(-t_pad*TimeBinElec+DelayTrig)*VDrift; + + Q_Pad.push_back(fit_function_max-250); + + T_Pad.push_back(t_pad*TimeBinElec); + X_Pad.push_back(x_mm); + Y_Pad.push_back(y_mm); + Z_Pad.push_back(z_mm); + q_pad = fit_function_max-250.; + + } + ZpadNew[indexfill] = z_mm; + minosfitdata = (TMinosClust*)fitdata.ConstructedAt(indexfill); + minosfitdata->Set(XpadNew[indexfill], YpadNew[indexfill], t_pad*TimeBinElec, ZpadNew[indexfill], q_pad, clusternbr[indexfill], clusterpads[indexfill], Chi2); + QpadNew[indexfill] = q_pad ; + + } // end if SumOfWeights > 0 + + } // end if fitbool==True + else continue; + } // end of NbOfPad + + //------------------------------------------------------- + // STEP 3.2: Filtering the tracks off possible noise + // with Hough3D (3*2D planes) + //------------------------------------------------------- + + cluster_temp = 0; + int ringtouch[19]={0}; + /* for(int ko=1; ko<19; ko++) ringtouch[ko] = 0; ///// Added by Cyril */ + + for(unsigned int i=0;i<(XpadNew.size());i++){ + if(xin.size()>0 && ((cluster_temp!=int(clusternbr[i]) && i!=0) || i==(XpadNew.size() - 1))){ + + Tracking_functions->Hough_3D(&xin, &yin, &zin, &qin, &xout, &yout, &zout, &qout); + + for(unsigned int ij=0; ij<xout.size();ij++){ + if(zout[ij]>zmax) {zmax = zout[ij];} + ringtouch[int(round((sqrt(xout[ij]*xout[ij]+yout[ij]*yout[ij])-44.15)/2.1))]++; // Corr by Cyril + } + + for(int ko=0; ko<19; ko++){ + if(ringtouch[ko]>0) ringsum++; + } + + /* if(zmax> 290 ) ringsum = 16; //comment it if z_mm is not well reconstruct by Vdrift and DelayTrig ! */ + + // Tracks of interest: >10 pads and >=12 rings hit + + /* if(xout.size()>10 &&(SimulationBool==1 || ringsum>=8)){ */ + if(xout.size()>10 && ringsum>=8){ + + npoint=0; + trackNbr_FINAL++; + double charge_temp=0.; + double lenght_temp=0; + double zintarget=300; + double zouttarget=0; + int indexin=0; int indexout=0; + for(unsigned int ij=0; ij<xout.size(); ij++){ + + point.SetXYZ(xout[ij],yout[ij],zout[ij]); + point.RotateZ(0.);//15.6*TMath::DegToRad() CHANGE#### + xoutprime.push_back(point.X());youtprime.push_back(point.Y());zoutprime.push_back(point.Z()); + TOTxoutprime.push_back(point.X()); + // Added line to see events used for fit of lines in tree + TOTyoutprime.push_back(point.Y()); + TOTzoutprime.push_back(point.Z()); + TOTqout.push_back(qout[ij]); + // save cluster_temp + // save numbtrack + trackclusternbr.push_back(clusternbr[i]); + tracknbr.push_back( trackNbr_FINAL ) ; + + grxztmp->SetPoint(npoint,zoutprime[ij],xoutprime[ij]); + gryztmp->SetPoint(npoint,zoutprime[ij],youtprime[ij]); + charge_temp += qout[ij]; + minosdata_result = (TMinosResult*)data_result.ConstructedAt(array_final); + minosdata_result->Set(xoutprime[ij], youtprime[ij], zoutprime[ij], qout[ij], trackNbr_FINAL, xout.size(), zmax); + array_final++; + npoint++; + + ///////// to exclude data w/ rings from 15to18 + if(sqrt(xout[ij]*xout[ij]+yout[ij]*yout[ij])<70 && sqrt(xout[ij]*xout[ij]+yout[ij]*yout[ij])> 53 ){ + if(zoutprime[ij]<zintarget) {zintarget=zoutprime[ij];indexin=ij;} + if(zoutprime[ij]>zouttarget) {zouttarget=zoutprime[ij];indexout=ij;} + } + } + + if(xout.size()>0)lenght_temp=sqrt(pow(zoutprime[indexin]-zoutprime[indexout],2)+pow(youtprime[indexin]-youtprime[indexout],2)+pow(xoutprime[indexin]-xoutprime[indexout],2)); + + grxz.push_back(*grxztmp); + gryz.push_back(*gryztmp); + grxztmp->Set(0); + gryztmp->Set(0); + + chargeTot.push_back(charge_temp); + lenght.push_back(lenght_temp); + } // end of if(xout.size()>10 &&) + + //X_mm->Fill(); + + xin.clear(); + yin.clear(); + zin.clear(); + qin.clear(); + xout.clear(); + yout.clear(); + zout.clear(); + xoutprime.clear(); + youtprime.clear(); + zoutprime.clear(); + qout.clear(); + npoint_temp=0; + ringsum=0;// angle between 1st track and z axis in 3D in degrees + zmax=0.; + for(int ko=0; ko<18; ko++) ringtouch[ko] = 0; + + } // if(xin.size()>0 && (( cluster_temp .... ) + + cluster_temp = clusternbr[i]; + + if(!(clusterpads[i]>=10 && clusterringbool[i]==1 && ZpadNew[i]>-100 && ZpadNew[i]<=310)) continue; + else + { + xin.push_back(XpadNew[i]); + yin.push_back(YpadNew[i]); + zin.push_back(ZpadNew[i]); + qin.push_back(QpadNew[i]); + npoint_temp++; + } + + }//end of loop on padsNews + + + /* //------------------------------------------------------- */ + /* // STEP 3.2: Fitting the filtered tracks in 3D */ + /* // (weight by charge, TMinuit) */ + /* //------------------------------------------------------- */ + + + if(trackNbr_FINAL>= 1){ // !!! Just for 1 or more tracks! + /* if(trackNbr_FINAL== 2){ */ + + //////////Minimization in 3D to reconstruct track lines + allevt_2pfiltered++; + + for(int itr= 0 ; itr<trackNbr_FINAL; itr++) { + + + pStart[0]=0; pStart[2]=0; pStart[1]=1; pStart[3]=3; + min = new TMinuit(4); + min->SetPrintLevel(-1); + arglist[0] = 3; + + Tracking_functions->FindStart(pStart,chi,fitStatus, &grxz.at(itr), &gryz.at(itr)); + + NclusterFit = itr+1; + current_phy=this; + min->SetFCN(SumDistance); + + + // Set starting values and step sizes for parameters + min->mnparm(0,"x0",pStart[0],0.1,-500,500,iflag); + min->mnparm(1,"Ax",pStart[1],0.1,-10,10,iflag); + min->mnparm(2,"y0",pStart[2],0.1,-500,500,iflag); + min->mnparm(3,"Ay",pStart[3],0.1,-10,10,iflag); + arglist[0] = 200; // number of function calls + arglist[1] = 0.000001; // tolerance + + min->mnexcm("MIGRAD",arglist,2,iflag); // minimization with MIGRAD + + min->mnstat(amin,edm,errdef,nvpar,nparx,iflag); //returns current status of the minimization + + + // get fit parameters + + for(int i = 0; i <4; i++) min->GetParameter(i,parFit_temp[i],err_temp[i]); + + /* if( (parFit_temp[0] >-499 && parFit_temp[0]<499) && (parFit_temp[2] >-499 && parFit_temp[2]<499)) { */ + parFit1.push_back(parFit_temp[0]); + parFit2.push_back(parFit_temp[1]); + parFit3.push_back(parFit_temp[2]); + parFit4.push_back(parFit_temp[3]); + /* } */ + delete min; + } + + if(trackNbr_FINAL==2){ + + double ParTrack1[4]; + double ParTrack2[4]; + + ParTrack1[0] = parFit1[0]; + ParTrack1[1] = parFit2[0]; + ParTrack1[2] = parFit3[0]; + ParTrack1[3] = parFit4[0]; + + ParTrack2[0] = parFit1[1]; + ParTrack2[1] = parFit2[1]; + ParTrack2[2] = parFit3[1]; + ParTrack2[3] = parFit4[1]; + + Dist_min=0, Theta_tr1=0, Theta_tr2=0; + Tracking_functions->vertex(ParTrack1, ParTrack2, xv, yv, zv, Dist_min, Theta_tr1, Theta_tr2); + + /* if(abs(xv)<20 && abs(yv)<20){ */ + Xvertex.push_back(xv); + Yvertex.push_back(yv); + Zvertex.push_back(zv-Z_Shift); + + /* if (zv <-50){ */ + /* cout << ParTrack1[0]<< " " << ParTrack1[1]<< " " << ParTrack1[2]<<" " << ParTrack1[3]<<endl; */ + /* cout << xv<< " " << yv<< " " << zv<<endl; */ + /* } */ + + + if(Theta_tr1>Theta_tr2){ + Theta1.push_back(Theta_tr1); + Theta2.push_back(Theta_tr2); + } + else if(Theta_tr1<Theta_tr2){ + Theta1.push_back(Theta_tr2); + Theta2.push_back(Theta_tr1); + } + + sumTheta.push_back(Theta_tr1+Theta_tr2); + /* sumTheta.push_back(156.9-(Theta_tr1+Theta_tr2)); */ + /* } */ + /* else{ */ + + /* Xvertex.push_back(-99); */ + /* Yvertex.push_back(-99); */ + /* Zvertex.push_back(-99); */ + /* sumTheta.push_back(1000); */ + /* } */ + + } + else + { + Xvertex.push_back(-1000); + Yvertex.push_back(-1000); + Zvertex.push_back(-1000); + sumTheta.push_back(1000); + } + + }// end if trackNbr_FINAL>=1 + else + { + Xvertex.push_back(-1000); + Yvertex.push_back(-1000); + Zvertex.push_back(-1000); + sumTheta.push_back(1000); + } + + } // end loop if 0<trackNbr < 5 + else + { + Xvertex.push_back(-1000); + Yvertex.push_back(-1000); + Zvertex.push_back(-1000); + sumTheta.push_back(1000); + } + // instantiate CalibrationManager + static CalibrationManager* Cal = CalibrationManager::getInstance(); +} /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::ReadAnalysisConfig() { @@ -188,100 +642,158 @@ void TMinosPhysics::ReadAnalysisConfig() { } } } -} - - -/////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::Clear() { - DetectorNumber.clear(); - Energy.clear(); - Time.clear(); } +double TMinosPhysics::distance2(double x,double y,double z, double *p) { + // distance line point is D= | (xp-x0) cross ux | + // where ux is direction of line and x0 is a point in the line (like t = 0) + ROOT::Math::XYZVector xp(x,y,z); //point of the track + ROOT::Math:: XYZVector x0(p[0], p[2], 0. ); + ROOT::Math::XYZVector x1(p[0] + p[1], p[2] + p[3], 1. ); //line + ROOT::Math::XYZVector u = (x1-x0).Unit(); + double d2 = ((xp-x0).Cross(u)) .Mag2(); + return d2; +} - -/////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::ReadConfiguration(NPL::InputParser parser) { - vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Minos"); - if(NPOptionManager::getInstance()->GetVerboseLevel()) - cout << "//// " << blocks.size() << " detectors found " << endl; - - vector<string> cart = {"POS","Shape"}; - vector<string> sphe = {"R","Theta","Phi","Shape"}; - - for(unsigned int i = 0 ; i < blocks.size() ; i++){ - if(blocks[i]->HasTokenList(cart)){ - if(NPOptionManager::getInstance()->GetVerboseLevel()) - cout << endl << "//// Minos " << i+1 << endl; - - TVector3 Pos = blocks[i]->GetTVector3("POS","mm"); - string Shape = blocks[i]->GetString("Shape"); - AddDetector(Pos,Shape); - } - else if(blocks[i]->HasTokenList(sphe)){ - if(NPOptionManager::getInstance()->GetVerboseLevel()) - cout << endl << "//// Minos " << i+1 << endl; - double R = blocks[i]->GetDouble("R","mm"); - double Theta = blocks[i]->GetDouble("Theta","deg"); - double Phi = blocks[i]->GetDouble("Phi","deg"); - string Shape = blocks[i]->GetString("Shape"); - AddDetector(R,Theta,Phi,Shape); - } - else{ - cout << "ERROR: check your input file formatting " << endl; - exit(1); +void TMinosPhysics::SumDistance(int &, double *, double & sum, double * par, int) { + TMinosPhysics* phy = current_phy; + int nused=0; + double qtot=0; + sum = 0; + + for(int i=0; i < phy->data_result.GetEntriesFast(); i++) + { + phy->minosdata_result = (TMinosResult*)phy->data_result.At(i); + if(phy->minosdata_result->n_Cluster==NclusterFit) + { + float x=phy->minosdata_result->x_mm; + float y=phy->minosdata_result->y_mm; + float z=phy->minosdata_result->z_mm; + float q=phy->minosdata_result->Chargemax; + //if(nused<2)cout<<minosdata_result->n_Cluster<<" "<<x<<" "<<y<<" "<<z<<" "<<q<<endl; + /* double d = Tracking_functions->distance2(x, y, z, par); */ + double d = TMinosPhysics::distance2(x, y, z, par); + sum += d*q; + nused++; + qtot+=q; + } } - } + //sum/=nused; + sum/=qtot; + return; } /////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::InitSpectra() { - m_Spectra = new TMinosSpectra(m_NumberOfDetectors); -} - - - -/////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::FillSpectra() { - m_Spectra -> FillRawSpectra(m_EventData); - m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); - m_Spectra -> FillPhysicsSpectra(m_EventPhysics); -} - +void TMinosPhysics::Clear() { + + Xpad.clear(); + Ypad.clear(); + Qpad.clear(); + XpadNew.clear(); + YpadNew.clear(); + ZpadNew.clear(); + QpadNew.clear(); + + clusterringboolTemp.clear(); + clusterringbool.clear(); + clusternbr.clear(); + clusterpads.clear(); + hfit->Reset(); + + xin.clear(); + yin.clear(); + zin.clear(); + qin.clear(); + xout.clear(); + yout.clear(); + zout.clear(); + xoutprime.clear(); + youtprime.clear(); + zoutprime.clear(); + qout.clear(); + + trackclusternbr.clear(); + tracknbr.clear(); + TOTxoutprime.clear(); + TOTyoutprime.clear(); + TOTzoutprime.clear(); + TOTqout.clear(); + + lenght.clear(); + chargeTot.clear(); + parFit1.clear(); + parFit2.clear(); + parFit3.clear(); + parFit4.clear(); + + Xvertex.clear(); + Yvertex.clear(); + Zvertex.clear(); + sumTheta.clear(); + + grxz.clear(); + gryz.clear(); + + Theta1.clear(); + Theta2.clear(); + + hfit->Reset(); + + + filled=0; + indexfill = 0; + ChargeBin = 0.; + maxCharge = 0.; + Iteration=0; + filter_result=0; + fit2DStatus=0; + trackNbr=0; + trackNbr_FINAL=0; + x_mm = 0.; y_mm = 0.; z_mm = 0.; q_pad = 0.; t_pad = 0.; + array_final=0; + ringsum=0; + zmax=0.; -/////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::CheckSpectra() { - m_Spectra->CheckSpectra(); } - - /////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::ClearSpectra() { - // To be done -} - +void TMinosPhysics::ReadConfiguration(NPL::InputParser parser) { + /* vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Minos"); */ + /* if(NPOptionManager::getInstance()->GetVerboseLevel()) */ + /* cout << "//// " << blocks.size() << " detectors found " << endl; */ + /* vector<string> cart = {"POS","Shape"}; */ + /* vector<string> sphe = {"R","THETA","POS","Phi","TargetLength"}; */ -/////////////////////////////////////////////////////////////////////////// -map< string , TH1*> TMinosPhysics::GetSpectra() { - if(m_Spectra) - return m_Spectra->GetMapHisto(); - else{ - map< string , TH1*> empty; - return empty; - } -} - -/////////////////////////////////////////////////////////////////////////// -void TMinosPhysics::WriteSpectra() { - m_Spectra->WriteSpectra(); + /* for(unsigned int i = 0 ; i < blocks.size() ; i++){ */ + /* if(blocks[i]->HasTokenList(cart)){ */ + /* if(NPOptionManager::getInstance()->GetVerboseLevel()) */ + /* cout << endl << "//// Minos " << i+1 << endl; */ + + /* TVector3 Pos = blocks[i]->GetTVector3("POS","mm"); */ + /* string Shape = blocks[i]->GetString("Shape"); */ + /* AddDetector(Pos,Shape); */ + /* } */ + /* else if(blocks[i]->HasTokenList(sphe)){ */ + /* if(NPOptionManager::getInstance()->GetVerboseLevel()) */ + /* cout << endl << "//// Minos " << i+1 << endl; */ + /* double R = blocks[i]->GetDouble("R","mm"); */ + /* double Theta = blocks[i]->GetDouble("THETA","deg"); */ + /* TVector3 POS = blocks[i]->GetTVector3("POS","cm"); */ + /* double Phi = blocks[i]->GetDouble("PHI","deg"); */ + /* double TargetLenght = blocks[i]->GetDouble("TargetLength","mm"); */ + /* AddDetector(R,Theta,POS,Phi,TargetLenght); */ + /* } */ + /* else{ */ + /* cout << "ERROR: check your input file formatting " << endl; */ + /* exit(1); */ + /* } */ + /* } */ } - /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::AddParameterToCalibrationManager() { CalibrationManager* Cal = CalibrationManager::getInstance(); @@ -291,33 +803,26 @@ void TMinosPhysics::AddParameterToCalibrationManager() { } } - - /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::InitializeRootInputRaw() { TChain* inputChain = RootInput::getInstance()->GetChain(); inputChain->SetBranchStatus("Minos", true ); inputChain->SetBranchAddress("Minos", &m_EventData ); + if( strlen(inputChain->GetTree()->GetName())==13) SimulationBool= true; // Test if TreeName==SimulatedTree } - - /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::InitializeRootInputPhysics() { TChain* inputChain = RootInput::getInstance()->GetChain(); inputChain->SetBranchAddress("Minos", &m_EventPhysics); } - - /////////////////////////////////////////////////////////////////////////// void TMinosPhysics::InitializeRootOutput() { TTree* outputTree = RootOutput::getInstance()->GetTree(); outputTree->Branch("Minos", "TMinosPhysics", &m_EventPhysics); } - - //////////////////////////////////////////////////////////////////////////////// // Construct Method to be pass to the DetectorFactory // //////////////////////////////////////////////////////////////////////////////// @@ -325,8 +830,6 @@ NPL::VDetector* TMinosPhysics::Construct() { return (NPL::VDetector*) new TMinosPhysics(); } - - //////////////////////////////////////////////////////////////////////////////// // Registering the construct method to the factory // //////////////////////////////////////////////////////////////////////////////// diff --git a/NPLib/Detectors/Minos/TMinosPhysics.h b/NPLib/Detectors/Minos/TMinosPhysics.h index f35fa2777..23d9d57e5 100644 --- a/NPLib/Detectors/Minos/TMinosPhysics.h +++ b/NPLib/Detectors/Minos/TMinosPhysics.h @@ -1,20 +1,20 @@ #ifndef TMinosPHYSICS_H #define TMinosPHYSICS_H /***************************************************************************** - * Copyright (C) 2009-2018 this file is part of the NPTool Project * + * Copyright (C) 2009-2018 this file is part of the NPTool Project * * * * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * * For the list of contributors see $NPTOOL/Licence/Contributors * *****************************************************************************/ /***************************************************************************** - * Original Author: Elidiano Tronchin contact address: tronchin@lpccaen.in2p3.fr * + * Original Author: Cyril Lenain contact address: lenain@lpccaen.in2p3.fr * * * - * Creation Date : October 2018 * + * Creation Date : 2019 * * Last update : * *---------------------------------------------------------------------------* * Decription: * - * This class hold Minos Treated data * + * This class hold Minos Treated data * * * *---------------------------------------------------------------------------* * Comment: * @@ -32,16 +32,23 @@ using namespace std; #include "TObject.h" #include "TH1.h" #include "TVector3.h" +#include "TF1.h" +#include "TH2F.h" +#include "TMinuit.h" + + // NPTool headers #include "TMinosData.h" -#include "TMinosSpectra.h" #include "NPCalibrationManager.h" #include "NPVDetector.h" #include "NPInputParser.h" -// forward declaration -class TMinosSpectra; +#include "Tracking.h" +#include "TMinosResult.h" +#include "TClonesArray.h" +using namespace NPL; +// forward declaration class TMinosPhysics : public TObject, public NPL::VDetector { ////////////////////////////////////////////////////////////// @@ -49,91 +56,86 @@ class TMinosPhysics : public TObject, public NPL::VDetector { public: TMinosPhysics(); ~TMinosPhysics() {}; - - ////////////////////////////////////////////////////////////// // Inherited from TObject and overriden to avoid warnings public: void Clear(); - void Clear(const Option_t*) {}; - - ////////////////////////////////////////////////////////////// + void Clear(const Option_t*) {}; + + /* static void SumDistance(int &, double *, double & sum, double * par, int); */ + + ////////////////////////////////////////////////////////////// // data obtained after BuildPhysicalEvent() and stored in // output ROOT file public: - vector<int> DetectorNumber; - vector<double> Energy; - vector<double> Time; + + vector<double> X_Pad; + vector<double> Y_Pad; + vector<double> Z_Pad; + vector<double> Q_Pad; + vector<double> T_Pad; /// A usefull method to bundle all operation to add a detector - void AddDetector(TVector3 POS, string shape); - void AddDetector(double R, double Theta, double Phi, string shape); + void AddDetector(TVector3 POS, string shape); + void AddDetector(double R, double Theta,TVector3 POS, double Phi, double TargetLenght); ////////////////////////////////////////////////////////////// // methods inherited from the VDetector ABC class public: // read stream from ConfigFile to pick-up detector parameters void ReadConfiguration(NPL::InputParser); - // add parameters to the CalibrationManger void AddParameterToCalibrationManager(); - // method called event by event, aiming at extracting the // physical information from detector void BuildPhysicalEvent(); - // same as BuildPhysicalEvent() method but with a simpler // treatment void BuildSimplePhysicalEvent(); - // same as above but for online analysis void BuildOnlinePhysicalEvent() {BuildPhysicalEvent();}; - // activate raw data object and branches from input TChain // in this method mother branches (Detector) AND daughter leaves // (fDetector_parameter) have to be activated void InitializeRootInputRaw(); - // activate physics data object and branches from input TChain // in this method mother branches (Detector) AND daughter leaves // (fDetector_parameter) have to be activated void InitializeRootInputPhysics(); - // create branches of output ROOT file void InitializeRootOutput(); - // clear the raw and physical data objects event by event void ClearEventPhysics() {Clear();} void ClearEventData() {m_EventData->Clear();} - - // methods related to the TMinosSpectra class - // instantiate the TMinosSpectra class and // declare list of histograms - void InitSpectra(); - - // fill the spectra - void FillSpectra(); - - // used for Online mainly, sanity check for histograms and - // change their color if issues are found, for example - void CheckSpectra(); - - // used for Online only, clear all the spectra - void ClearSpectra(); - - // write spectra to ROOT output file - void WriteSpectra(); - ////////////////////////////////////////////////////////////// // specific methods to Minos array public: + + NPL::Tracking* Tracking_functions; //! + + /* int NclusterFit; //! */ + // fit function for the Q(t) signals at each pad + static double conv_fit(double *x, double *p); + static double distance2(double x,double y,double z, double *p); + static void SumDistance(int &, double *, double & sum, double * par, int); + + // remove bad channels, calibrate the data and apply thresholds void PreTreat(); // clear the pre-treated object - void ClearPreTreatedData() {m_PreTreatedData->Clear();} + void ClearPreTreatedData() { + + m_PreTreatedData->Clear(); + Q_Pad.clear(); + X_Pad.clear(); + Y_Pad.clear(); + Z_Pad.clear(); + T_Pad.clear(); + } // read the user configuration file. If no file is found, load standard one void ReadAnalysisConfig(); @@ -141,40 +143,182 @@ class TMinosPhysics : public TObject, public NPL::VDetector { // give and external TMinosData object to TMinosPhysics. // needed for online analysis for example void SetRawDataPointer(TMinosData* rawDataPointer) {m_EventData = rawDataPointer;} - + // objects are not written in the TTree private: TMinosData* m_EventData; //! TMinosData* m_PreTreatedData; //! TMinosPhysics* m_EventPhysics; //! + TMinuit* min;//! + +TClonesArray data_result;//! +TMinosResult *minosdata_result;//! + + TClonesArray fitdata;//! // getters for raw and pre-treated data object public: TMinosData* GetRawData() const {return m_EventData;} TMinosData* GetPreTreatedData() const {return m_PreTreatedData;} + vector<double> GetPad_X() {return X_Pad;} + vector<double> GetPad_Y() {return Y_Pad;} + vector<double> GetPad_Z() {return Z_Pad;} + vector<double> GetParFit1() {return parFit1;} + vector<double> GetParFit2() {return parFit2;} + vector<double> GetParFit3() {return parFit3;} + vector<double> GetParFit4() {return parFit4;} + double GetVertexZ() {return Zvertex[0];} + + /* TClonesArray fitdata; */ + + /* fitdata.SetClass("TMinosClust"); */ + // parameters used in the analysis private: + + + bool SimulationBool=false;//! + // thresholds double m_E_RAW_Threshold; //! double m_E_Threshold; //! + // used in PreTreatedData() + vector<int> clusterringboolTemp;//! + vector<int> clusterringbool;//! + vector<int> clusternbr;//! + vector<int> clusterpads;//! + + vector<double> Xpad;//! + vector<double> Ypad;//! + vector<double> Qpad;//! + vector<double> XpadNew; + vector<double> YpadNew; + vector<double> QpadNew;//! + vector<double> ZpadNew;//! + + vector<double> XpadTemp;//! + vector<double> YpadTemp;//! + vector<double> QpadTemp;//! + vector<double> ZpadTemp;//! + + double x_mm;//! + double y_mm;//! + double z_mm;//! + double q_pad;//! + double t_pad;//! + double Chi2;//! + double maxCharge;//! + double ChargeBin;//! + + double hfit_max; //! + double hfit_max_T; //! + double T_min; //! + double T_max; //! + + + int Iteration;/// + int filter_result;//! + int filled;//! + int fit2DStatus;//! + int indexfill;//! + int trackNbr;//! + + TF1 *fit_function;//! + /* TH1F *hfit = new TH1F("hfit","hfit",512,0,512);//! */ + TH1F *hfit ;//! + + int npoint_temp=0;//! + int cluster_temp;//! + int ringsum;//! + int ringtouch[19];//! + + TGraph *gryztmp;//! + TGraph* grxztmp;//! + + double zmax;//! + vector<double> xin;//! + vector<double> yin;//! + vector<double> zin;//! + vector<double> qin;//! + vector<double> xout;//! + vector<double> yout;//! + vector<double> zout;//! + vector<double> qout;//! + vector<double> xoutprime;//! + vector<double> youtprime;//! + vector<double> zoutprime;//! + vector<double> qoutprime;//! + + vector<double> TOTxoutprime; + vector<double> TOTyoutprime; + vector<double> TOTzoutprime; + vector<double> TOTqout; + + vector<double> Xvertex; + vector<double> Yvertex; + vector<double> Zvertex; + + vector<double> sumTheta; + vector<double> Theta1; + vector<double> Theta2; + + vector<int> trackclusternbr;//! + vector<int> tracknbr;//! + + double Tot_tracks=0; //! + int trackNbr_FINAL;//! + vector<TGraph> gryz;//! + vector<TGraph> grxz;//! + + int npoint;//! + int array_final;//! + TVector3 point;//! + + // Variables only filled when trackNbr_FINAL>=1 + int allevt_2pfiltered;//! + Double_t pStart[4];//! + double parFit_temp[4];//! + double err_temp[4];//! + Double_t chi[2];//! + Int_t fitStatus[2];//! + Double_t arglist[10];//! + Int_t iflag;//! + int nvpar;//! + int nparx;//! + double amin;//! + double edm;//! + double errdef;//! + + vector<double> lenght; + vector<double> chargeTot; + vector<double> parFit1; + vector<double> parFit2; + vector<double> parFit3; + vector<double> parFit4; + vector<double> errFit1_local; + vector<double> errFit2_local; + vector<double> errFit3_local; + vector<double> errFit4_local; + + + double xv;//! + double yv;//! + double zv;//! + + double Dist_min;//! + double Theta_tr1;//! + double Theta_tr2;//! // number of detectors private: int m_NumberOfDetectors; //! - // spectra class - private: - TMinosSpectra* m_Spectra; // ! - - // spectra getter - public: - map<string, TH1*> GetSpectra(); - // Static constructor to be passed to the Detector Factory public: static NPL::VDetector* Construct(); ClassDef(TMinosPhysics,1) // MinosPhysics structure }; + #endif diff --git a/NPLib/Detectors/Minos/TMinosResult.cxx b/NPLib/Detectors/Minos/TMinosResult.cxx new file mode 100644 index 000000000..6ec3a453f --- /dev/null +++ b/NPLib/Detectors/Minos/TMinosResult.cxx @@ -0,0 +1,37 @@ +//----------! Written by C. Santamaria / CEA Saclay !---------- +#include "TMinosResult.h" + +ClassImp(TMinosResult) + +TMinosResult::TMinosResult() +: TObject(), x_mm(0), y_mm(0), z_mm(0), Chargemax(0), n_Cluster(0), n_Pads(0), z_max(0){ +// Constructor +} +TMinosResult::TMinosResult(Double_t xmm, Double_t ymm, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t zmax) + : TObject() +{ + // Constructor + x_mm = xmm; + y_mm= ymm; + z_mm = zmm; + Chargemax = chargemax; + n_Cluster=ncluster; + n_Pads = npads; + z_max = zmax; +} +TMinosResult::~TMinosResult() +{ +// Destructor +} + +void TMinosResult::Set(Double_t xmm, Double_t ymm, Double_t zmm, Double_t chargemax, Double_t ncluster, Double_t npads, Double_t zmax) +{ + x_mm = xmm; + y_mm= ymm; + z_mm = zmm; + Chargemax = chargemax; + n_Cluster=ncluster; + n_Pads = npads; + z_max = zmax; +} + diff --git a/NPLib/Detectors/Minos/TMinosResult.h b/NPLib/Detectors/Minos/TMinosResult.h new file mode 100644 index 000000000..38e04f1e9 --- /dev/null +++ b/NPLib/Detectors/Minos/TMinosResult.h @@ -0,0 +1,25 @@ +//----------! Written by C. Santamaria / CEA Saclay !---------- +#ifndef TMINOSRESULT_H +#define TMINOSRESULT_H + +//#include "TClonesArray.h" +#include "TObject.h" + +class TMinosResult : public TObject { + public: + TMinosResult(); + TMinosResult(Double_t xmm, Double_t ymm, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t zmax); + void Set(Double_t xmm, Double_t ymm, Double_t zmm , Double_t chargemax, Double_t ncluster, Double_t npads, Double_t zmax); + virtual ~TMinosResult(); + public: + Double_t x_mm; + Double_t y_mm; + Double_t z_mm; + Double_t Chargemax; + Double_t n_Cluster; + Double_t n_Pads; + Double_t z_max; + + ClassDef(TMinosResult,1); +}; +#endif // end of #ifndef TMINOSRESULT_H diff --git a/NPLib/TrackReconstruction/CMakeLists.txt b/NPLib/TrackReconstruction/CMakeLists.txt index 4ae6ea5f7..7b71a04dc 100644 --- a/NPLib/TrackReconstruction/CMakeLists.txt +++ b/NPLib/TrackReconstruction/CMakeLists.txt @@ -2,7 +2,9 @@ add_custom_command(OUTPUT NPRansacDict.cxx COMMAND ../scripts/build_dict.sh NPRa add_custom_command(OUTPUT NPClusterDict.cxx COMMAND ../scripts/build_dict.sh NPCluster.h NPClusterDict.cxx NPCluster.rootmap libNPTrackReconstruction.so NPTrackReconstructionLinkDef.h DEPENDS NPCluster.h) -add_library(NPTrackReconstruction SHARED NPRansac.cxx NPCluster.cxx NPTrack.cxx NPRansacDict.cxx NPClusterDict.cxx) +add_custom_command(OUTPUT TrackingDict.cxx COMMAND ../scripts/build_dict.sh Tracking.h TrackingDict.cxx Tracking.rootmap libNPTrackReconstruction.so NPTrackReconstructionLinkDef.h DEPENDS Tracking.h) + +add_library(NPTrackReconstruction SHARED NPRansac.cxx NPCluster.cxx NPTrack.cxx Tracking.cxx NPRansacDict.cxx NPClusterDict.cxx TrackingDict.cxx) target_link_libraries(NPTrackReconstruction ${ROOT_LIBRARIES} NPCore) -install(FILES NPRansac.h NPCluster.h NPTrack.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) +install(FILES NPRansac.h NPCluster.h NPTrack.h Tracking.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) diff --git a/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h b/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h index 485465f52..8fc0faa4b 100644 --- a/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h +++ b/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h @@ -1,4 +1,5 @@ #ifdef __CINT__ #pragma link C++ defined_in "./NPRansac.h"; #pragma link C++ defined_in "./NPCluster.h"; +#pragma link C++ defined_in "./Tracking.h"; #endif diff --git a/NPLib/TrackReconstruction/Tracking.cxx b/NPLib/TrackReconstruction/Tracking.cxx new file mode 100644 index 000000000..8a93d564e --- /dev/null +++ b/NPLib/TrackReconstruction/Tracking.cxx @@ -0,0 +1,488 @@ +//----------! Developed by C. Santamaria / CEA Saclay !---------- +//----------! Version date :: 2014/11/12 !---------- +// Tracking Functions + +#include <fstream> +#include <string> +#include <iostream> +#include <vector> +#include "TTree.h" +#include "TFile.h" +#include "TClonesArray.h" +#include <vector> +#include "TF1.h" +#include "TH1.h" +#include "TH2.h" +#include "TMath.h" +#include "TGraph.h" +// #include "/opt/root/v5.34.14/include/Math/Vector3D.h" +#include "/opt/cern/root/root_v5.34.36/math/genvector/inc/Math/Vector3D.h" +/* #include "TMinosResult.h" */ +/* #include "Vector3D.h" */ +#include "Tracking.h" + +using namespace std; + +/* TClonesArray data_result; */ +/* TMinosResult *minosdata_result; */ + +ClassImp(NPL::Tracking) + +NPL::Tracking::Tracking() +{ +// Constructor +} + +NPL::Tracking::~Tracking() +{ +// Destructor +} + +// Fit function for E(T) +/* double NPL::Tracking::conv_fit(double *x, double *p) { */ +/* double val; */ +/* if(!(x[0]<p[1] || x[0]>512.)) val = p[0] * exp(-3.*(x[0]-p[1])/p[2]) * sin((x[0]-p[1])/p[2]) * pow((x[0]-p[1])/p[2], 3) + 250; */ +/* //else val = p[3]; */ +/* else val = 250; */ +/* return(val); */ +/* } */ + +int NPL::Tracking::Hough_modified(vector<double> *x,vector<double> *y,vector<double> *q, vector<double> *x_out,vector<double> *y_out, vector<double> *q_out, vector<int> *ringbool) { + double bint1=2.; + double bint2=2.; + int maxt = 360.; + int mint = 0.; + int nt1=(maxt-mint)/bint1; + int nt2=(maxt-mint)/bint1; + + double PI = TMath::Pi(); + double Rint = 45.2; + double Rext = 45.2 + 18*2.1; + int filter_result = 0; + + TH2F *hp_xy = new TH2F("hp_xy","hp_xy",nt1,mint,maxt,nt2,mint,maxt); + TH2F *hpDiag_xy = new TH2F("hpDiag_xy","hpDiag_xy",nt1,mint,maxt,nt2,mint,maxt); + + double max_xy; + + vector<double> xTemp, yTemp, qTemp; + + double theta1, theta2, xt1, yt1, xt2, yt2; + double line0=0., line1=0.; + double delta=0., AA=0., BB=0., CC=0.; + double maxtheta1=0., maxtheta2=0., xmax1=0., ymax1=0., xmax2=0., ymax2=0.; + double par0=0., par1=0.; + double r_mm=0.; + int ringsum=0; + bool maxfound = false; + + for(unsigned int i=0;i<x->size();i++){ + xTemp.push_back(x->at(i)); + yTemp.push_back(y->at(i)); + qTemp.push_back(q->at(i)); + + //Loop of indices + for(int j=0;j<nt1;j++){ + + theta1 = (j+0.5)*bint1 + mint; + xt1 = Rint * TMath::Cos(theta1*PI/180.); + yt1 = Rint * TMath::Sin(theta1*PI/180.); + line1 = (yt1 - y->at(i))/(xt1 - x->at(i)); + line0 = yt1 - xt1 * line1; + AA = 1 + line1*line1; + BB = 2*line0*line1; + CC = line0*line0 - Rext*Rext; + + delta = BB*BB - 4*AA*CC; + + if(delta>=0){ + xt2 = (-BB - sqrt(delta))/(2*AA); + yt2 = line0 + line1*xt2; + + if(xt2<=0) theta2= 180 - asin(yt2/Rext)*180/PI; + + else if(xt2>0){ + if(yt2>0) theta2= asin(yt2/Rext)*180/PI; + else if(yt2<=0) theta2= 360 + asin(yt2/Rext)*180/PI; + } + + if( (xt1*x->at(i) + yt1*y->at(i))>=0 && (xt2*x->at(i) + yt2*y->at(i))>=0 && (xt1*xt2+yt1*yt2)>=0){ + hp_xy->Fill(theta1,theta2); + if(abs(theta1-theta2)<=10) hpDiag_xy->Fill(theta1,theta2); + } + else{ + if(delta!=0){ + xt2 = (-BB + sqrt(delta))/(2*AA); + yt2 = line0 + line1*xt2; + + if(xt2<=0) theta2= 180 - asin(yt2/Rext)*180/PI; + + else if(xt2>0){ + if(yt2>0) theta2= asin(yt2/Rext)*180/PI; + else if(yt2<=0) theta2= 360 + asin(yt2/Rext)*180/PI; + } + + if( (xt1*x->at(i) + yt1*y->at(i))>=0 && (xt2*x->at(i) + yt2*y->at(i))>=0 && (xt1*xt2+yt1*yt2)>=0){ + hp_xy->Fill(theta1,theta2); + if(abs(theta1-theta2)<=10) hpDiag_xy->Fill(theta1,theta2); + } + } + } + } // end if delta>=0 + } // end loop on indices + } // end loop on pads + + x->clear(); + y->clear(); + q->clear(); + + if(hpDiag_xy->GetMaximum()>=10) max_xy = hpDiag_xy->GetMaximum(); +// cout << "Max taken in diag... withh value=" << max_xy << endl; + else max_xy = hp_xy->GetMaximum(); + + for(int ii=0; ii<nt1; ii++){ + if(maxfound ==true) break; + for(int jj=0; jj<nt2; jj++){ + if(hp_xy->GetBinContent(ii+1, jj+1) == max_xy){ + maxtheta1 = (ii+0.5)*bint1 + mint; + maxtheta2 = (jj+0.5)*bint2 + mint; + maxfound = true; + //cout << "xy: theta max are " << maxtheta1 << " , " << maxtheta2 << endl; + } + if(maxfound ==true) break; + } + } + + xmax1 = Rint * TMath::Cos(maxtheta1*PI/180.); + ymax1 = Rint * TMath::Sin(maxtheta1*PI/180.); + xmax2 = Rext * TMath::Cos(maxtheta2*PI/180.); + ymax2 = Rext * TMath::Sin(maxtheta2*PI/180.); + + // xy PEAK + par1 = (ymax2-ymax1)/(xmax2-xmax1); + par0 = (ymax1 - xmax1*par1); + //Selection of x,y points IN the maxmean+/-1 found in Obertelli transform of xy plane + for(unsigned int i=0;i<xTemp.size();i++){ + if( (abs(par1*xTemp[i]-yTemp[i]+par0)/sqrt(1+par1*par1))<= 6 && ((xmax1*xTemp[i] + ymax1*yTemp[i]) >= 0) && ((xmax2*xTemp[i] + ymax2*yTemp[i]) >= 0) && ((xmax1*xmax2 + ymax1*ymax2) >= 0)){ +// couti<< "Taken points= " << xTemp[i] << " , " << yTemp[i] << " , " << zTemp[i] << endl; +// hcnew_xy->Fill(xTemp[i],yTemp[i],qTemp[i]); + x_out->push_back(xTemp[i]); + y_out->push_back(yTemp[i]); + q_out->push_back(qTemp[i]); + filter_result++; + /* r_mm = sqrt(xTemp[i]*xTemp[i]+yTemp[i]*yTemp[i]); */ + /* if(r_mm<(45.2+5*2.1)) ringsum++; */ // commented by Cyril + + } + else{ + x->push_back(xTemp[i]); + y->push_back(yTemp[i]); + q->push_back(qTemp[i]); + + } + } + + + /* cout << "ringsum = " << ringsum << endl; */ + /* cout << "Filter_result = " << filter_result << endl; */ + for(int ip=0; ip<filter_result; ip++){ + /* if(ringsum>2) ringbool->push_back(1); */ + /* else ringbool->push_back(0); */ + ringbool->push_back(1); + } + + delete hp_xy; + delete hpDiag_xy; + + return filter_result; + +} + +double NPL::Tracking::FitFunction(double *x, double *p) { + double val=p[0]+p[1]*x[0]; + return(val); +} +void NPL::Tracking::FindStart(double pStart[4], double chi[2], int fitStatus[2],TGraph *grxz, TGraph *gryz) { + double par1D[2]; + TF1 *myfit1 = new TF1("myfit1","[0]+[1]*x", -100,500); + myfit1->SetParameter(0,0); + myfit1->SetParameter(1,10); + fitStatus[0] =0; + grxz->Fit(myfit1,"RQM"); + chi[0]=myfit1->GetChisquare(); + par1D[0]=myfit1->GetParameter(0); + par1D[1]=myfit1->GetParameter(1); + pStart[0]=par1D[0]; + pStart[1]=par1D[1]; + fitStatus[1] =0; + gryz->Fit(myfit1,"RQM"); + chi[1]=myfit1->GetChisquare(); + par1D[0]=myfit1->GetParameter(0); + par1D[1]=myfit1->GetParameter(1); + pStart[2]=par1D[0]; + pStart[3]=par1D[1]; + //AC 07/12/14 + delete myfit1; +} + +// Calculation of the distance line-point +double NPL::Tracking::distance2(double x,double y,double z, double *p) { + // distance line point is D= | (xp-x0) cross ux | + // where ux is direction of line and x0 is a point in the line (like t = 0) + ROOT::Math::XYZVector xp(x,y,z); //point of the track + ROOT::Math:: XYZVector x0(p[0], p[2], 0. ); + ROOT::Math::XYZVector x1(p[0] + p[1], p[2] + p[3], 1. ); //line + ROOT::Math::XYZVector u = (x1-x0).Unit(); + double d2 = ((xp-x0).Cross(u)) .Mag2(); + return d2; +} + +//void Hough_3D(TCanvas *c1, vector<double> *x,vector<double> *y,vector<double> *z,vector<double> *q, vector<double> *x_out,vector<double> *y_out,vector<double> *z_out,vector<double> *q_out) { +void NPL::Tracking::Hough_3D(vector<double> *x,vector<double> *y,vector<double> *z,vector<double> *q,vector<double> *x_out,vector<double> *y_out,vector<double> *z_out,vector<double> *q_out) { + + int nt_xy=180; + int nt_xz=180; + int nt_yz=180; + int nr_xy=45; + int nr_xz=300; + int nr_yz=300; + double bint_xy=2.; + double bint_xz=2.; + double bint_yz=2.; + double binr_xy=3.; + double binr_xz=3.; + double binr_yz=3.; + int nt,nr; + double PI = TMath::Pi(); + + double rho_xy,rho_xz,rho_yz; + double theta_xy,theta_xz,theta_yz; + + TH2F *hp_xy = new TH2F("hp_xy","hp_xy",nt_xy,0,180,nr_xy,-1*nr_xy,nr_xy); + TH2F *hp_xz = new TH2F("hp_xz","hp_xz",nt_xz,0,180,nr_xz,-1*nr_xz,nr_xz); + TH2F *hp_yz = new TH2F("hp_yz","hp_yz",nt_yz,0,180,nr_yz,-1*nr_yz,nr_yz); + + // int npeaks_xy, npeaks_xz, npeaks_yz; + vector<double> thetapeaks_xy, rpeaks_xy, thetapeaks_xz, rpeaks_xz, thetapeaks_yz, rpeaks_yz; + double max_xy, max_xz, max_yz; + double rmean_xy=0, thetamean_xy=0, rmean_xz=0, thetamean_xz=0, rmean_yz=0, thetamean_yz=0; + + double r0_xy=0., r0_xz=0., r0_yz=0., rmin_xy=0., rmin_xz=0., rmin_yz=0., rmax_xy=0., rmax_xz=0., rmax_yz=0.; + double tmin=0., tmax=0.; + double rinf=0., rsup=0.; + + nt=nt_xy; + nr=nr_xy; + if(nt<nt_xz)nt=nt_xz; + if(nr<nr_xz)nr=nr_xz; + if(nt<nt_yz)nt=nt_yz; + if(nr<nr_yz)nr=nr_yz; + + for(unsigned int i=0;i<x->size();i++) + { + //Fill coordinate space histograms for plots + //Loop of indices and fill Histograms + for(int j=0;j<nt;j++) + { + + //xy + theta_xy = j*180./nt_xy; + + /* cout <<y->at(i) << endl; */ + rho_xy = x->at(i)*TMath::Cos(theta_xy*PI/180.)+y->at(i)*TMath::Sin(theta_xy*PI/180.); + if(abs(theta_xy)<180. && abs(rho_xy)<nr_xy) + { + hp_xy->Fill(theta_xy,rho_xy); + } + + //xz + theta_xz = j*180./nt_xz; + rho_xz = z->at(i)*TMath::Cos(theta_xz*PI/180.)+x->at(i)*TMath::Sin(theta_xz*PI/180.); + if(abs(theta_xz)<180. && abs(rho_xz)<nr_xz) + { + hp_xz->Fill(theta_xz,rho_xz); + } + + //yz + theta_yz = j*180./nt_yz; + rho_yz = z->at(i)*TMath::Cos(theta_yz*PI/180.)+y->at(i)*TMath::Sin(theta_yz*PI/180.); + if(abs(theta_yz)<180. && abs(rho_yz)<nr_yz) + { + hp_yz->Fill(theta_yz,rho_yz); + } + } + } + + max_xy = hp_xy->GetMaximum(); + max_xz = hp_xz->GetMaximum(); + max_yz = hp_yz->GetMaximum(); + + for(int ii=0; ii<nt; ii++) + { + for(int jj=0; jj<nr; jj++) + { + if(hp_xy->GetBinContent(ii+1, jj+1) == max_xy && jj<nr_xy) + { + thetapeaks_xy.push_back((ii+0.5)*nt_xy/nt); + rpeaks_xy.push_back((jj+0.5)*2 - nr_xy); + rmean_xy += rpeaks_xy.back(); + thetamean_xy += thetapeaks_xy.back(); + } + if(hp_xz->GetBinContent(ii+1, jj+1) == max_xz) + { + thetapeaks_xz.push_back((ii+0.5)*nt_xz/nt); + rpeaks_xz.push_back((jj+0.5)*2 - nr_xz); + rmean_xz += rpeaks_xz.back(); + thetamean_xz += thetapeaks_xz.back(); + } + if(hp_yz->GetBinContent(ii+1, jj+1) == max_yz) + { + thetapeaks_yz.push_back((ii+0.5)*nt_yz/nt); + rpeaks_yz.push_back((jj+0.5)*2 - nr_yz); + rmean_yz += rpeaks_yz.back(); + thetamean_yz += thetapeaks_yz.back(); + } + } + } + + // xy PEAK + rmean_xy = rmean_xy / rpeaks_xy.size(); + thetamean_xy = thetamean_xy / thetapeaks_xy.size(); + + // xz PEAK + rmean_xz = rmean_xz / rpeaks_xz.size(); + thetamean_xz = thetamean_xz / thetapeaks_xz.size(); + + // yz PEAK + rmean_yz = rmean_yz / rpeaks_yz.size(); + thetamean_yz = thetamean_yz / thetapeaks_yz.size(); + + rmean_xy = rpeaks_xy[0]; + thetamean_xy = thetapeaks_xy[0]; + rmean_xz = rpeaks_xz[0]; + thetamean_xz = thetapeaks_xz[0]; + rmean_yz = rpeaks_yz[0]; + thetamean_yz = thetapeaks_yz[0]; + + //Selection of x,y,z points COMMON to the 3 maxmean+/-1 found in Hough spaces for xy, xz and yz spaces + for(unsigned int i=0;i<x->size();i++) + { + r0_xy = x->at(i)*TMath::Cos(thetamean_xy*PI/180.)+y->at(i)*TMath::Sin(thetamean_xy*PI/180.); + tmin = thetamean_xy-bint_xy; + tmax = thetamean_xy+bint_xy; + if((tmin)<0) tmin = tmin + 180.; + if((tmax)>180) tmax = tmax - 180.; + rmin_xy = x->at(i)*TMath::Cos(tmin*PI/180.)+y->at(i)*TMath::Sin(tmin*PI/180.); + rmax_xy = x->at(i)*TMath::Cos(tmax*PI/180.)+y->at(i)*TMath::Sin(tmax*PI/180.); + + rinf = min( rmean_xy - binr_xy, rmean_xy + binr_xy); + rsup = max( rmean_xy - binr_xy, rmean_xy + binr_xy); + if((r0_xy>=rinf || rmin_xy>=rinf || rmax_xy>=rinf) && (r0_xy<=rsup || rmin_xy<=rsup || rmax_xy<=rsup)) + { + r0_xz = z->at(i)*TMath::Cos(thetamean_xz*PI/180.)+x->at(i)*TMath::Sin(thetamean_xz*PI/180.); + tmin = thetamean_xz-bint_xz; + tmax = thetamean_xz+bint_xz; + if((tmin)<0) tmin = tmin + 180.; + if((tmax)>180) tmax = tmax - 180.; + rmin_xz = z->at(i)*TMath::Cos(tmin*PI/180.)+x->at(i)*TMath::Sin(tmin*PI/180.); + rmax_xz = z->at(i)*TMath::Cos(tmax*PI/180.)+x->at(i)*TMath::Sin(tmax*PI/180.); + + rinf = min( rmean_xz - binr_xz, rmean_xz + binr_xz); + rsup = max( rmean_xz - binr_xz, rmean_xz + binr_xz); + + if((r0_xz>=rinf || rmin_xz>=rinf || rmax_xz>=rinf) && (r0_xz<=rsup || rmin_xz<=rsup || rmax_xz<=rsup)) + { + r0_yz = z->at(i)*TMath::Cos(thetamean_yz*PI/180.)+y->at(i)*TMath::Sin(thetamean_yz*PI/180.); + tmin = thetamean_yz-bint_yz; + tmax = thetamean_yz+bint_yz; + if((tmin)<0) tmin = tmin + 180.; + if((tmax)>180) tmax = tmax - 180.; + rmin_yz = z->at(i)*TMath::Cos(tmin*PI/180.)+y->at(i)*TMath::Sin(tmin*PI/180.); + rmax_yz = z->at(i)*TMath::Cos(tmax*PI/180.)+y->at(i)*TMath::Sin(tmax*PI/180.); + + rinf = min( rmean_yz - binr_yz, rmean_yz + binr_yz); + rsup = max( rmean_yz - binr_yz, rmean_yz + binr_yz); + + if((r0_yz>=rinf || rmin_yz>=rinf || rmax_yz>=rinf) && (r0_yz<=rsup || rmin_yz<=rsup || rmax_yz<=rsup)) + { + x_out->push_back(x->at(i)); + y_out->push_back(y->at(i)); + z_out->push_back(z->at(i)); + q_out->push_back(q->at(i)); + } + } + } + + } + delete hp_xy; + delete hp_xz; + delete hp_yz; + +} + +// Calculation of the minimal distance between 2 lines in 3D space & calculation of mid-point=>vertex of interaction +void NPL::Tracking::vertex(double *p, double *pp, double &xv,double &yv,double &zv,double &min_dist, double &Theta_tr1, double &Theta_tr2) { + double a1 = p[0]; + double a2 = p[2]; + double b1 = p[1]; + double b2 = p[3]; + double ap1 = pp[0]; + double ap2 = pp[2]; + double bp1 = pp[1]; + double bp2 = pp[3]; + + double alpha, beta, A, B, C; + + alpha = (bp1*(a1-ap1)+bp2*(a2-ap2))/(bp1*bp1 + bp2*bp2 + 1); + beta = (bp1*b1+bp2*b2+1)/(bp1*bp1 + bp2*bp2 + 1); + + A = beta*(bp1*bp1 + bp2*bp2 + 1) - (bp1*b1 + bp2*b2 + 1); + B = (b1*b1 + b2*b2 + 1) - beta*(bp1*b1+bp2*b2+1); + C = beta*(bp1*(ap1-a1) + bp2*(ap2-a2)) - (b1*(ap1-a1) + b2*(ap2-a2)); + + double sol1, solf1; + double x,y,z,xp,yp,zp; + + + sol1 = -(A*alpha + C)/(A*beta + B); + solf1 = alpha + beta* sol1; + + x = a1 + b1*sol1; + y = a2 + b2*sol1; + z = sol1; + xp = ap1 + bp1*solf1; + yp = ap2 + bp2*solf1; + zp = solf1; + + xv = (x+xp)/2.; + yv = (y+yp)/2.; + zv = (z+zp)/2.; + + Theta_tr1 = TMath::ATan(TMath::Sqrt((x-a1)*(x-a1)+(y-a2)*(y-a2))/TMath::Abs(sol1)); + Theta_tr2 = TMath::ATan(TMath::Sqrt((xp-ap1)*(xp-ap1)+(yp-ap2)*(yp-ap2))/TMath::Abs(solf1)); + Theta_tr1 = Theta_tr1*180./TMath::Pi(); + Theta_tr2 = Theta_tr2*180./TMath::Pi(); + + //cout << "Vertex 1st :" << x << "," << y << "," << z << endl; + //cout << "Vertex 2nd :" << xp << "," << yp << "," << zp << endl; + //cout << "Vertex middle :" << xv << "," << yv << "," << zv << endl; + + //cout << "min dist " << sqrt(pow((x-xp),2) + pow((y-yp),2) + pow((z-zp),2)) << endl; + +} + +void NPL::Tracking::ParFor_Vertex(double *a, double *b, double *parFit) { + // input 2 points in 3D, output parFit format for the use in vertex function + double APX, APY, APZ, X0, Y0, APX0, APY0; + + APX=a[0]-b[0]; APY=a[1]-b[1]; APZ=a[2]-b[2]; + APX0=APX/APZ; APY0=APY/APZ; + X0=a[0]-a[2]*APX0; Y0=a[1]-a[2]*APY0; //Z0=0 + + parFit[0]=X0; + parFit[1]=APX0; + parFit[2]=Y0; + parFit[3]=APY0; +} + + diff --git a/NPLib/TrackReconstruction/Tracking.h b/NPLib/TrackReconstruction/Tracking.h new file mode 100644 index 000000000..ee158a5bb --- /dev/null +++ b/NPLib/TrackReconstruction/Tracking.h @@ -0,0 +1,33 @@ +//----------! Developed by C. Santamaria / CEA Saclay !---------- +//----------! Version date :: 2014/11/12 !---------- +// Tracking Functions +#ifndef TRACKING_H +#define TRACKING_H + +#include <fstream> +#include <string> +#include <iostream> +#include <vector> +#include "TGraph.h" + +using namespace std; + +namespace NPL{ +class Tracking { + public: + Tracking(); + virtual ~Tracking(); + /* double conv_fit(double *x, double *p); */ + int Hough_modified(vector<double> *x,vector<double> *y,vector<double> *q, vector<double> *x_out,vector<double> *y_out, vector<double> *q_out, vector<int> *ringbool); + double FitFunction(double *x, double *p); + void FindStart(double pStart[4], double chi[2], int fitStatus[2],TGraph *grxz, TGraph *gryz); + double distance2(double x,double y,double z, double *p); + void Hough_3D(vector<double> *x,vector<double> *y,vector<double> *z,vector<double> *q,vector<double> *x_out,vector<double> *y_out,vector<double> *z_out,vector<double> *q_out); + void vertex(double *p, double *pp, double &xv,double &yv,double &zv, double &min_dist, double &Theta_tr1, double &Theta_tr2); + void ParFor_Vertex(double *a, double *b, double *parFit); + + ClassDef(Tracking,1); + +}; +} +#endif -- GitLab