#include "PndTrkTracking2.h" #include "PndTrkBoundaryParStraws2.h" #include "PndTrkChi2Fits.h" #include "PndTrkCategorizeStt.h" #include "PndTrkComparisonMCtruth.h" #include "PndTrkSttConformalFilling.h" #include "PndTrkLegendreFits.h" #include "PndTrkCleanup.h" #include "PndTrkCTFindTrackInXY.h" #include "PndTrkCTFindTrackInXY2.h" #include "PndTrkCTGeometryCalculations.h" #include "PndTrkMergeSort.h" #include "PndTrkPlotMacros2.h" #include "PndTrkPrintouts.h" #include "PndTrkSttAdjacencies.h" #include "PndTrkSttClusterFinder.h" #include "PndSttHit.h" #include "PndSciTHit.h" #include "PndSttPoint.h" #include "PndSttTrack.h" #include "PndSttPoint.h" #include "PndSttHelixHit.h" #include "PndSttSingleStraw.h" #include "PndSttTube.h" #include "PndSttMapCreator.h" #include "PndSdsHit.h" #include "PndSdsMCPoint.h" #include "PndTrackCand.h" #include "PndTrackCandHit.h" #include "PndTrack.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "FairTrackParP.h" #include "FairField.h" #include "TGeoManager.h" #include "TClonesArray.h" #include "TGeoVolume.h" #include "TVector3.h" #include "TRandom.h" #include "TH1F.h" #include "TMath.h" #include "TCanvas.h" #include "TGeoTube.h" #include "TStopwatch.h" #include #include #include "PndTrkConstants.h" using namespace std; // ----- Default constructor ------------------------------------------- PndTrkTracking2::PndTrkTracking2() : FairTask("Tracking") { fPersistence = kTRUE; istampa = 0; iplotta = false; doMcComparison = false; fYesCleanMvd = false; fYesCleanStt = false; fYesSciTil = false ; fMvdAloneTracking = false; fNevents_to_plot = 10; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(Int_t verbose) : FairTask("Tracking") { fPersistence = kTRUE; istampa = verbose; iplotta = false; doMcComparison = false; fYesCleanMvd = false; fYesCleanStt = false; fYesSciTil = false ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(int istamp, bool iplot, bool imc) : FairTask("Tracking") { fPersistence = kTRUE; istampa = istamp; iplotta = iplot; doMcComparison = imc; fYesCleanMvd = false; fYesCleanStt = false; fYesSciTil = false ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(int istamp, bool iplot, bool imc, bool doSciTil) : FairTask("Tracking") { fPersistence = kTRUE; istampa = istamp; iplotta = iplot; doMcComparison = imc; fYesCleanMvd = false; fYesCleanStt = false; fYesSciTil = doSciTil ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ----- Destructor ---------------------------------------------------- PndTrkTracking2::~PndTrkTracking2() {} // ----------------------- //--------------- begin PndTrkTracking2::Initialization_ClassVariables void PndTrkTracking2::Initialization_ClassVariables() { // this is only for initializing the Class Variables. size_t len; // booleans : len = sizeof(fSingleHitListStt); memset (fSingleHitListStt,true,len); len = sizeof(fInclusionListSciTil); memset (fInclusionListSciTil,true,len); len = sizeof(fInclusionListStt); memset (fInclusionListStt,true,len); len = sizeof(finMvdTrackCandPixel); memset (finMvdTrackCandPixel,false,len); len = sizeof(finMvdTrackCandStrip); memset (finMvdTrackCandStrip,false,len); len = sizeof(fTypeConf); memset (fTypeConf,false,len); // char : len = sizeof(fSttBranch); memset (fSttBranch,0,len); len = sizeof(fMvdPixelBranch); memset (fMvdPixelBranch,0,len); len = sizeof(fMvdStripBranch); memset (fMvdStripBranch,0,len); // Short_t : fnMCTracks=0; fnSciTilHits=0; len = sizeof(fListMvdPixelHitsinTrack); memset (fListMvdPixelHitsinTrack,0,len); len = sizeof(fListMvdStripHitsinTrack); memset (fListMvdStripHitsinTrack,0,len); len = sizeof(fListSciTilHitsinTrack); memset (fListSciTilHitsinTrack,0,len); len = sizeof(fListSttParHits); memset (fListSttParHits,0,len); len = sizeof(fListSttParHitsinTrack); memset (fListSttParHitsinTrack,0,len); len = sizeof(fListSttSkewHitsinTrack); memset (fListSttSkewHitsinTrack,0,len); len = sizeof(fListSttSkewHits); memset (fListSttSkewHits,0,len); len = sizeof(fListSttSkewHitsinTrackSolution); memset (fListSttSkewHitsinTrackSolution,0,len); len = sizeof(fListTrackCandHit); memset (fListTrackCandHit,0,len); len = sizeof(fnMvdPixelHitsinTrack); memset (fnMvdPixelHitsinTrack,0,len); len = sizeof(fnMvdStripHitsinTrack); memset (fnMvdStripHitsinTrack,0,len); len = sizeof(fnTrackCandHit); memset (fnTrackCandHit,0,len); len = sizeof(fnSciTilHitsinTrack); memset (fnSciTilHitsinTrack,0,len); len = sizeof(fnSttParHitsinTrack); memset (fnSttParHitsinTrack,0,len); len = sizeof(fnSttSkewHitsinTrack); memset (fnSttSkewHitsinTrack,0,len); fnMvdDSPixelHitNotTrackCand=0; fnMvdDSStripHitNotTrackCand=0; fnMvdPixelHit=0; fnMvdStripHit=0; fnMvdTrackCand=0; fnMvdUSPixelHitNotTrackCand=0; fnMvdUSStripHitNotTrackCand=0; len = sizeof(fnHitMvdTrackCand); memset (fnHitMvdTrackCand,0,len); len = sizeof(fListHitMvdTrackCand); memset (fListHitMvdTrackCand,0,len); len = sizeof(fListHitTypeMvdTrackCand); memset (fListHitTypeMvdTrackCand,0,len); len = sizeof(fListMvdDSPixelHitNotTrackCand); memset (fListMvdDSPixelHitNotTrackCand,0,len); len = sizeof(fListMvdUSPixelHitNotTrackCand); memset (fListMvdUSPixelHitNotTrackCand,0,len); len = sizeof(fListMvdDSStripHitNotTrackCand); memset (fListMvdDSStripHitNotTrackCand,0,len); len = sizeof(fListMvdUSStripHitNotTrackCand); memset (fListMvdUSStripHitNotTrackCand,0,len); len = sizeof(fListTrackCandHitType); memset (fListTrackCandHitType,0,len); len = sizeof(fnParContiguous); memset (fnParContiguous,0,len); len = sizeof(fListParContiguous); memset (fListParContiguous,0,len); memset (fStrawCode,0,sizeof(fStrawCode)); memset (fStrawCode,0,sizeof(fStrawCode2)); // int : fNevents_to_plot = 10; // Double_t : fFimin=0.; // SEMILENGTH_STRAIGHT=75.; // ZCENTER_STRAIGHT=35.; len = sizeof(fALFA); memset (fALFA,0,len); len = sizeof(fBETA); memset (fBETA,0,len); len = sizeof(fGAMMA); memset (fGAMMA,0,len); len = sizeof(fCxMC); memset (fCxMC,0,len); len = sizeof(fCyMC); memset (fCyMC,0,len); len = sizeof(fR_MC); memset (fR_MC,0,len); len = sizeof(fMCtruthTrkInfo); memset (fMCtruthTrkInfo,0,len); len = sizeof(fMCSkewAloneX); memset (fMCSkewAloneX,0,len); len = sizeof(fMCSkewAloneY); memset (fMCSkewAloneY,0,len); len = sizeof(fradiaConf); memset (fradiaConf,0,len); len = sizeof(fOx); memset (fOx,0,len); len = sizeof(fOy); memset (fOy,0,len); len = sizeof(fR); memset (fR,0,len); len = sizeof(frefindexMvdPixel); memset (frefindexMvdPixel,0,len); len = sizeof(fsigmaXMvdPixel); memset (fsigmaXMvdPixel,0,len); len = sizeof(fsigmaYMvdPixel); memset (fsigmaYMvdPixel,0,len); len = sizeof(fsigmaZMvdPixel); memset (fsigmaZMvdPixel,0,len); len = sizeof(fXMvdPixel); memset (fXMvdPixel,0,len); len = sizeof(fYMvdPixel); memset (fYMvdPixel,0,len); len = sizeof(fZMvdPixel); memset (fZMvdPixel,0,len); len = sizeof(fXMvdStrip); memset (fXMvdStrip,0,len); len = sizeof(fYMvdStrip); memset (fYMvdStrip,0,len); len = sizeof(fZMvdStrip); memset (fZMvdStrip,0,len); len = sizeof(fsigmaXMvdStrip); memset (fsigmaXMvdStrip,0,len); len = sizeof(fsigmaYMvdStrip); memset (fsigmaYMvdStrip,0,len); len = sizeof(fsigmaZMvdStrip); memset (fsigmaZMvdStrip,0,len); len = sizeof(frefindexMvdStrip); memset (frefindexMvdStrip,0,len); len = sizeof(fMCtrack_of_Pixel); memset (fMCtrack_of_Pixel,0,len); len = sizeof(fMCtrack_of_Strip); memset (fMCtrack_of_Strip,0,len); len = sizeof(fposizSciTil); memset (fposizSciTil,0,len); len = sizeof(fxTube); memset (fxTube,0,len); len = sizeof(fyTube); memset (fyTube,0,len); len = sizeof(fzTube); memset (fzTube,0,len); len = sizeof(fxxyyTube); memset (fxxyyTube,0,len); len = sizeof(fCandidatePixelDriftRadius); memset(fCandidatePixelDriftRadius,0,len); len = sizeof(fCandidatePixelErrorDriftRadius); memset(fCandidatePixelErrorDriftRadius,0,len); len = sizeof(fCandidatePixelS); memset(fCandidatePixelS,0,len); len = sizeof(fCandidatePixelZ); memset(fCandidatePixelZ,0,len); len = sizeof(fCandidateStripDriftRadius); memset(fCandidateStripDriftRadius,0,len); len = sizeof(fCandidateStripErrorDriftRadius); memset(fCandidateStripErrorDriftRadius,0,len); len = sizeof(fCandidateStripS); memset(fCandidateStripS,0,len); len = sizeof(fCandidateStripZ); memset(fCandidateStripZ,0,len); fCandidateSciTilDriftRadius=0.; fCandidateSciTilErrorDriftRadius=0.; fCandidateSciTilS=0.; fCandidateSciTilZ=0.; // pointers : HANDLE=NULL; HANDLE2=NULL; hdeltaRPixel=NULL; hdeltaRStrip=NULL; hdeltaRPixel2=NULL; hdeltaRStrip2=NULL; fMCTrackArray=NULL; fSttTubeArray=NULL; fSttPointArray=NULL; fSttHitArray=NULL; fSttTrackArray=NULL; fSttTrackCandArray=NULL; fMvdPixelHitArray=NULL; fMvdStripHitArray=NULL; fMvdTrackCandArray=NULL; fSciTHitArray=NULL; fMvdMCPointArray=NULL; fSttMvdPndTrackCandArray=NULL; fSttMvdPndTrackArray=NULL; fSttParameters=NULL; } //--------------- end of PndTrkTracking2::Initialization_ClassVariables //----------------------------------------- begin PndTrkTracking2::Init InitStatus PndTrkTracking2::Init() { IVOLTE=-1; // SEMILENGTH_STRAIGHT = 75.; // ZCENTER_STRAIGHT = 35.; Double_t po[3], BB[3]; FairField* Field = FairRunAna::Instance()->GetField(); po[0] =0.; po[1]= 0.; po[2]= 0.; Field->GetFieldValue(po, BB); //return value in KG (G3) fBFIELD = BB[2]/10.; // value in Tesla; if(iplotta){ hdeltaRPixel = new TH1F("hdeltaRPixel", "distance MC Pixel point from trajectory in XY plane", 100, -1, 1); hdeltaRStrip = new TH1F("hdeltaRStrip", "distance MC Strip point from trajectory in XY plane", 100, -1, 1); hdeltaRPixel2 = new TH1F( "hdeltaRPixel2", "distance MC point from trajectory in XY plane (Pixels)", 100, -10, 10); hdeltaRStrip2 = new TH1F( "hdeltaRStrip2", "distance MC point from trajectory in XY plane (Strips)", 100, -10,10); } // --------------------------- opening files for special purposes if(doMcComparison >=1 ){ //---- apertura file con info su Found tracce su cui si fa Helix fit dopo HANDLE2 = fopen("info_da_PndTrackFinderReal.txt","w"); // ---- open filehandle per statistica sugli hits etc. HANDLE = fopen("statistiche.txt","w"); // --------------- } // end of if(istampa >=1) // ------------------------- // Get RootManager FairRootManager* ioman = FairRootManager::Instance(); // ioman = FairRootManager::Instance(); if ( ! ioman ) { cout << "-E- PndTrkTracking2::Init: " << "RootManager not instantiated, return!" << endl; return kFATAL; } // ----- maps of STT tubes // CHECK added PndSttMapCreator *mapper = new PndSttMapCreator(fSttParameters); fSttTubeArray = mapper->FillTubeArray(); //---------------------------------------------------- end map // load the array indicating if a straw is external of not; // remember that the numbering of the STT Straws starts at 1 and goes up to 4542 included; // StrawCode convention (in the following left or right is looking to the beam from downstream) : // -1 = not a boundary straw; // 10= inner axial boundary left; // 20= inner axial boundary right; // 12= outer left axial Stt : Vertical (BUT NOT OUTERMOST) + inside boundary ; // 22= outer right axial Stt : Vertical (BUT NOT OUTERMOST) + inside boundary ; // 13= outermost axial boundary left; // 23= outermost axial boundary right; PndTrkBoundaryParStraws2 BoundaryParStraws ; BoundaryParStraws.Set( // inputs : APOTEMAMAXINNERPARSTRAW, APOTEMAMINOUTERPARSTRAW, NUMBER_STRAWS, APOTEMASTRAWDETECTORMIN, RSTRAWDETECTORMAX, false, // printout flag; fSttTubeArray, STRAWRADIUS, VERTICALGAP, // outputs : fStrawCode, // -1 = not a boundary straw; >0 = boundary straw; fStrawCode2 // second Code; -1 = not a boundary straw; >0 = boundary straw; ); //---------------------------------------------------- // load the adjacencies table for the Stt tubes; PndTrkSttAdjacencies Adjacent; Adjacent.CalculateAdjacentStt2( NUMBER_STRAWS, fSttTubeArray, fnParContiguous, // output; number of contiguous straws (axial Stt); fListParContiguous, // output list (axial Stt); fxTube, // X position center of tube; fyTube, // Y position center of tube; fzTube, // Z position center of tube; fxxyyTube // X*X+Y*Y position center of tube; ); //----------------------------------------- // load the list of Axial/Skew/Left-Right/Inner-Outer arrays for the Stt tubes; PndTrkCategorizeStt categorize; categorize.CategorizeStt( NUMBER_STRAWS, fSttTubeArray, fnAxialOuterRight, // output; number of axial Stt, outer, on the right (looking into the beam); fnAxialInnerRight, // output; number of axial Stt, inner, on the right (looking into the beam); fnAxialOuterLeft, // output; number of axial Stt, outer, on the left (looking into the beam); fnAxialInnerLeft, // output; number of axial Stt, inner, on the left (looking into the beam); fListAxialOuterRight, // output; list of axial Stt, outer, on the right (looking into the beam); fListAxialInnerRight, // output; list of axial Stt, inner, on the lright (looking into the beam); fListAxialOuterLeft, // output; list of axial Stt, outer, on the left (looking into the beam); fListAxialInnerLeft, // output; list of axial Stt, inner, on the left (looking into the beam); fnSkewRight, // output; number of skew Stt, on the right (looking into the beam); fnSkewLeft, // output; number of skew Stt, on the right (looking into the beam); fListSkewRight, // output; list of axial Stt, inner, on the lright (looking into the beam); fListSkewLeft // output; list of axial Stt, outer, on the left (looking into the beam); ); //----------------------------------------- // calculate the sines and cosines for the Legiandre fit; // LEGIANDRE_NTHETADIV, input; // fSinus, output; // fCosine output; CalculateSinandCosin(); // get the MCTrack array fMCTrackArray = (TClonesArray*) ioman->GetObject("MCTrack"); if ( ! fMCTrackArray) { cout << "-E- PndTrkTracking2::Init: No MCTrack array!" << endl; // return kERROR; } // ------------------------- get the SciTil hits if(fYesSciTil) { fSciTHitArray = (TClonesArray*) ioman->GetObject("SciTHit"); } else { fSciTHitArray = NULL; } //--------------------------- // ------------------------- get the SciTil MC Points if(fYesSciTil && doMcComparison) { fSciTPointArray = (TClonesArray*) ioman->GetObject("SciTPoint"); } else { fSciTPointArray = NULL; } //--------------------------- // Get input array these are the MC point of STT fSttPointArray = (TClonesArray*) ioman->GetObject("STTPoint"); if ( ! fSttPointArray ) { cout << "-W- PndSttHelixHitProducer::Init: " << "No STTPoint array, return!" << endl; return kERROR; } // Get input array hit of STT after digi fSttHitArray = (TClonesArray*) ioman->GetObject(fSttBranch); // fSttHitArray = (TClonesArray*) ioman->GetObject("STTHit"); if ( ! fSttHitArray ) { cout << "-W- PndTrkTracking2::Init: " << "No STTHit array, return!" << endl; return kERROR; } // ------------------------- get the Mvd hits fMvdPixelHitArray = (TClonesArray*) ioman->GetObject(fMvdPixelBranch); // fMvdPixelHitArray = (TClonesArray*) ioman->GetObject("MVDHitsPixel"); if ( !fMvdPixelHitArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD Pixel hitArray, return!" <GetObject(fMvdStripBranch); // fMvdStripHitArray = (TClonesArray*) ioman->GetObject("MVDHitsStrip"); if ( !fMvdStripHitArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD Strip hitArray, return!" <GetObject("MVDRiemannTrackCand"); if ( !fMvdTrackCandArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD TrackCand Array, return!" <GetObject("MVDPoint"); if ( !fMvdMCPointArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD MC Point Array, return!" <Register("SttMvdTrackCand","SttMvd",fSttMvdPndTrackCandArray, kTRUE); ioman->Register("SttMvdTrackCand","SttMvd",fSttMvdPndTrackCandArray, fPersistence); // Create and register output array for PndTrack of Stt+Mvd combined fSttMvdPndTrackArray = new TClonesArray("PndTrack"); ioman->Register("SttMvdTrack","SttMvd",fSttMvdPndTrackArray, fPersistence); //----------------------- // calculate the boundaries of the Box in Conformal Space, see Gianluigi logbook on pag. 210-211 Short_t i; Double_t A, r1, r2; fradiaConf[0] = 1./RSTRAWDETECTORMAX; r1 = APOTEMASTRAWDETECTORMIN; A = (RSTRAWDETECTORMAX - r1)/NRDIVCONFORMAL; if ( NRDIVCONFORMAL > 1 ) { for(i = 1; i< NRDIVCONFORMAL ; i++){ r2 = r1 + A; fradiaConf[NRDIVCONFORMAL-i] = 1./r2; r1=r2; } } return kSUCCESS; } //----------------------------------------- end of PndTrkTracking2::Init void PndTrkTracking2::SetParContainers() { FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb(); fSttParameters = (PndGeoSttPar*) rtdb->getContainer("PndGeoSttPar"); } void PndTrkTracking2::WriteHistograms(){ TFile* file = FairRootManager::Instance()->GetOutFile(); file->cd(); file->mkdir("PndTrkTracking2"); file->cd("PndTrkTracking2"); hdeltaRPixel->Write(); hdeltaRStrip->Write(); hdeltaRPixel2->Write(); hdeltaRStrip2->Write(); delete hdeltaRPixel; delete hdeltaRStrip; delete hdeltaRPixel2; delete hdeltaRStrip2; } // ----- Public method Exec -------------------------------------------- void PndTrkTracking2::Exec(Option_t* opt) { bool flag, intersect, outcome, GoodSkewFit[MAXTRACKSPEREVENT], keepit[MAXTRACKSPEREVENT], Mvdhits[MAXTRACKSPEREVENT], status[MAXTRACKSPEREVENT], SttSZfit[MAXTRACKSPEREVENT]; Short_t tnHitsInMCTrack[MAXTRACKSPEREVENT], tnMCParalAlone[MAXTRACKSPEREVENT], tnMCSkewAlone[MAXTRACKSPEREVENT], tnParalCommon[MAXTRACKSPEREVENT], tnSkewCommon[MAXTRACKSPEREVENT], tnSkewHitsInMCTrack[MAXTRACKSPEREVENT], tnSpuriParinTrack[MAXTRACKSPEREVENT], tnSpuriSkewinTrack[MAXTRACKSPEREVENT], // given a Hit number it gives its radial box number RConformalIndex[MAXSTTHITS], // given a Hit number it gives its azimuthal box number FiConformalIndex[MAXSTTHITS], tempore[MAXSTTHITS], CandidateSkewList[2*MAXSTTHITS][2], BigList[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], // nBoxConformal, first index -> radial divisions, // 2nd index -> azimuthal divisions; n. of hits falling in this cell. nBoxConformal[NRDIVCONFORMAL*NFIDIVCONFORMAL], tParalCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tParSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], HitsinBoxConformal[MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL], Charge[MAXTRACKSPEREVENT], tdaTrackFoundaTrackMC[MAXTRACKSPEREVENT], resultFitSZagain[MAXTRACKSPEREVENT], SttStrawOn[NUMBER_STRAWS]; Vec nHitsInMCTrack(tnHitsInMCTrack, MAXTRACKSPEREVENT,"nHitsInMCTrack"), nMCParalAlone(tnMCParalAlone, MAXTRACKSPEREVENT,"nMCParalAlone"), nMCSkewAlone(tnMCSkewAlone, MAXTRACKSPEREVENT,"nMCSkewAlone"), nParalCommon(tnParalCommon,MAXTRACKSPEREVENT,"nParalCommon"), nSkewCommon(tnSkewCommon,MAXTRACKSPEREVENT,"nSkewCommon"), nSkewHitsInMCTrack(tnSkewHitsInMCTrack, MAXTRACKSPEREVENT,"nSkewHitsInMCTrack"), nSpuriParinTrack(tnSpuriParinTrack, MAXTRACKSPEREVENT,"nSpuriParinTrack"), nSpuriSkewinTrack(tnSpuriSkewinTrack, MAXTRACKSPEREVENT,"nSpuriSkewinTrack"), // given a Hit number it gives its radial box number // RConformalIndex(tRConformalIndex, MAXSTTHITS,"RConformalIndex"), // given a Hit number it gives its azimuthal box number // FiConformalIndex(tFiConformalIndex, MAXSTTHITS,"FiConformalIndex"), // tempore(ttempore, MAXSTTHITS,"tempore"), // nBoxConformal, first index -> radial divisions, // 2nd index -> azimuthal divisions; n. of hits falling in this cell. // nBoxConformal(tnBoxConformal, NRDIVCONFORMAL*NFIDIVCONFORMAL,"nBoxConformal"), ParalCommonList(tParalCommonList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"ParalCommonList"), ParSpuriList(tParSpuriList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"ParSpuriList"), SkewCommonList(tSkewCommonList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"SkewCommonList"), SkewSpuriList(tSkewSpuriList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"SkewSpuriList"), // HitsinBoxConformal(tHitsinBoxConformal, MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL,"HitsinBoxConformal"), // Charge(tCharge,MAXTRACKSPEREVENT,"Charge"), daTrackFoundaTrackMC(tdaTrackFoundaTrackMC,MAXTRACKSPEREVENT,"daTrackFoundaTrackMC"); // resultFitSZagain(tresultFitSZagain,MAXTRACKSPEREVENT,"resultFitSZagain"), // SttStrawOn(tSttStrawOn,NUMBER_STRAWS,"SttStrawOn"); // SttStrawOn[i] >= 0 --> it is the Stt hit number corresponding to Stt // i-th Tube ID; SttStrawOn[i] == -1 --> i-th Stt straw NOT hit; memset(SttStrawOn,-1,sizeof(SttStrawOn)); //----------------------------------- Short_t nalone, ncand, nhitsinfit, nMvdMCPoint, Nint, NNN, nRemainingCandidates, npixelhitsintrack, nstriphitsintrack, nTotalCandidates, nXYZhits, i, iCluster, iexcl, iParHit, ipunto, j, k, kall, l, oldPixel, oldSkew, oldStrip, save_ListMvdPixelHitsinTrack[MAXMVDPIXELHITSINTRACK], save_ListSttSkewHitsinTrack[MAXSTTHITSINTRACK], save_ListSttSkewHitsinTrackSolution[MAXSTTHITSINTRACK], save_ListMvdStripHitsinTrack[MAXMVDSTRIPHITSINTRACK], save_nMvdPixelHitsinTrack, save_nSttSkewHitsinTrack, save_nMvdStripHitsinTrack ; int oldistampa; Int_t iaccept, len, nSttHit, nSttMCPoint, nSttParHit, nSttSkewHit, nSttTrackCand ; PndSdsMCPoint * pMvdMCPoint; Int_t nrounds0, nrounds1, tListHits[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK]; Vec ListHits(tListHits,MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK,"ListHits"); Double_t tS[2*MAXSTTHITS], tZ[2*MAXSTTHITS]; Vec S(tS,2*MAXSTTHITS,"S"), Z(tZ,2*MAXSTTHITS,"Z"); Double_t Distance, Fi, Ptras, ddd, delta, dis, dista, dista0, dista1, emme, gap, highqualitycut, Pxini, px, Pyini, py, Pzini, qop, rotationangle, signPz, x, y, // AloneX[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], AloneY[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], DriftRadiusbis[2*MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+ MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK],// all skew hits have double ErrorchosenPixel[MAXMVDPIXELHITS], ErrorchosenStrip[MAXMVDSTRIPHITS], ErrorchosenSkew[MAXSTTHITS], ErrorDriftRadiusbis[2*MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+ MAXMVDSTRIPHITSINTRACK+2],// solutions FI0[MAXTRACKSPEREVENT], Fi_final_helix_referenceframe[MAXTRACKSPEREVENT], Fi_initial_helix_referenceframe[MAXTRACKSPEREVENT], Fi_low_limit[MAXTRACKSPEREVENT], Fi_up_limit[MAXTRACKSPEREVENT], KAPPA[MAXTRACKSPEREVENT], Posiz1[3], primoangolo[MAXTRACKSPEREVENT], s[2], Sbis[2*MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], // multiplication by 2 in the SchosenPixel[MAXTRACKSPEREVENT][MAXMVDPIXELHITS], SchosenStrip[MAXTRACKSPEREVENT][MAXMVDSTRIPHITS], SchosenSkew[MAXTRACKSPEREVENT][MAXSTTHITS], // NO multiplication by 2 here because for the // skew hits only one // solution is selected. Start[3], S_Skew[MAXSTTHITS], // CandidateSkewS[2*MAXSTTHITS], // CandidateSkewZ[2*MAXSTTHITS], // CandidateSkewZDrift[2*MAXSTTHITS], // CandidateSkewZError[2*MAXSTTHITS], temporeZError[MAXSTTHITSINTRACK], temporeS[MAXSTTHITSINTRACK], temporeZ[MAXSTTHITSINTRACK], temporeZDrift[MAXSTTHITSINTRACK], tmpErrorZDrift[MAXSTTHITSINTRACK+MAXSCITILHITSINTRACK], tmpS[MAXSTTHITSINTRACK+MAXSCITILHITSINTRACK], tmpZ[MAXSTTHITSINTRACK+MAXSCITILHITSINTRACK], tmpZDrift[MAXSTTHITSINTRACK+MAXSCITILHITSINTRACK], trajectory_vertex[2], Trajectory_Start[MAXTRACKSPEREVENT][2], ultimoangolo[MAXTRACKSPEREVENT], versor[2], WDX[MAXSTTHITS], WDY[MAXSTTHITS], WDZ[MAXSTTHITS], X[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], XintersectionList[2], Y[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], YintersectionList[2], z[2], ZEDbis[2*MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], // rather improbable chance that zdrift[2], zerror[2], ZDrift[2*MAXSTTHITS], ZError[2*MAXSTTHITS], zeta0, zeta1, // info[MAXSTTHITS][7], infoparalConformal[MAXSTTHITS][5], Sfinal[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], XY[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK][2], ZchosenPixel[MAXTRACKSPEREVENT][MAXMVDPIXELHITS], ZchosenStrip[MAXTRACKSPEREVENT][MAXMVDSTRIPHITS], ZchosenSkew[MAXTRACKSPEREVENT][MAXSTTHITS], Zfinal[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], ZDriftfinal[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], ZErrorfinal[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK]; //-------------------- Double_t tDriftRadius[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], tErrorDriftRadius[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK], tZED[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK]; Vec DriftRadius(tDriftRadius,MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK,"DriftRadius"), ErrorDriftRadius(tErrorDriftRadius,MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK,"ErrorDriftRadius"), ZED(tZED,MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK +MAXMVDSTRIPHITSINTRACK+MAXSCITILHITSINTRACK,"ZED"); //-------------------------------------- TVector3 ErrMomentum, ErrPosition, Momentum, Position; FairMCPoint *puntator; PndMCTrack* pMCtr; PndSttHit *pSttHit; PndSttTube *pSttTube; PndSdsHit *pMvdPixelHit, *pMvdStripHit; PndTrkCleanup Cleaner; PndTrkCTGeometryCalculations GeomCalculator; PndTrkPrintouts fPrint; // the class with all the fits. This is used for the SZ fit. bool YesGLPKfitSZ = false; // PndTrkGlpkFits fit; YesGLPKfitSZ=true; // PndTrkLegendreFits fit; PndTrkChi2Fits fit; // reset the TClones Arrays of the PndTrackCand and PndTrack; it is necessary // to do this for every event at the very beginning of the Exec (those TClones Arrays // have been registered in the Init and they are automatically writted each event). fSttMvdPndTrackCandArray->Delete(); fSttMvdPndTrackArray->Delete(); //------------------------------------ IVOLTE++; // temporaneamente per studio /* if( IVOLTE == 820 ) { istampa =1 ; iplotta = true;} else { istampa=0; iplotta = false;} */ if(istampa>=1) cout<GetEntriesFast(); } else { fnMvdPixelHit = 0; } if( fMvdStripHitArray ){ fnMvdStripHit = fMvdStripHitArray->GetEntriesFast(); } else { fnMvdStripHit = 0; } if(fnMvdPixelHit>MAXMVDPIXELHITS){ cout<<"from PndTrkTracking2, fnMvdPixelHit is > maximum allowed (" <MAXMVDSTRIPHITS){ cout<<"from PndTrkTracking2, fnMvdStripHit is > maximum allowed (" <GetEntriesFast(); } else { nMvdMCPoint = 0; } if(nMvdMCPoint>MAXMVDMCPOINTS) { cout<<"from PndTracking, nMvdMCPoint = "< the maximum number allowed ("<=1) cout<<"N. MC Points delle Mvd = "<At(i); TVector3 temp = pMvdPixelHit->GetPosition(); fXMvdPixel[i] = temp.X(); fYMvdPixel[i] = temp.Y(); fZMvdPixel[i] = temp.Z(); fsigmaXMvdPixel[i] = pMvdPixelHit->GetDx(); fsigmaYMvdPixel[i] = pMvdPixelHit->GetDy(); fsigmaZMvdPixel[i] = pMvdPixelHit->GetDz(); frefindexMvdPixel[i] = pMvdPixelHit->GetRefIndex(); // it seems incredible, but it is easier to use the following algorithm to associate // a MVD Hit to the MC truth Track! dis=999999.; fMCtrack_of_Pixel[i] = -1; if( frefindexMvdPixel[i]<0) continue; // noise hit, it CANNOT be associated with the MC points; for(j=0;jAt(j); pMvdMCPoint->Position(MCposition); Distance = (MCposition.X()-fXMvdPixel[i])*(MCposition.X()-fXMvdPixel[i])+ (MCposition.Y()-fYMvdPixel[i])*(MCposition.Y()-fYMvdPixel[i])+ (MCposition.Z()- fZMvdPixel[i])*(MCposition.Z() - fZMvdPixel[i]); if( DistanceGetTrackID(); dis=Distance; } } // end of for(j=0;jAt(i); TVector3 temp = pMvdStripHit->GetPosition(); fXMvdStrip[i] = temp.X(); fYMvdStrip[i] = temp.Y(); fZMvdStrip[i] = temp.Z(); fsigmaXMvdStrip[i] = pMvdStripHit->GetDx(); fsigmaYMvdStrip[i] = pMvdStripHit->GetDy(); fsigmaZMvdStrip[i] = pMvdStripHit->GetDz(); frefindexMvdStrip[i] = pMvdStripHit->GetRefIndex(); // it seems incredible, but it is easier to use the following algorithm to associate // a MVD Hit to the MC truth Track! dis=999999.; fMCtrack_of_Strip[i] = -1; if( frefindexMvdStrip[i]<0) continue; // noise hit, it CANNOT be associated with the MC points; for(j=0;jAt(j); pMvdMCPoint->Position(MCposition); Distance = (MCposition.X()-fXMvdStrip[i])*(MCposition.X()-fXMvdStrip[i])+ (MCposition.Y()-fYMvdStrip[i])*(MCposition.Y()-fYMvdStrip[i])+ (MCposition.Z()- fZMvdStrip[i])*(MCposition.Z() - fZMvdStrip[i]); if( DistanceGetTrackID(); dis=Distance; } } // end of for(j=0;j=1) fPrint.stampaMvdHits2( fMvdPixelBranch, fMvdStripBranch, fnMvdPixelHit, fnMvdStripHit, frefindexMvdPixel, frefindexMvdStrip, fMCtrack_of_Pixel, fMCtrack_of_Strip, fsigmaXMvdPixel, fsigmaXMvdStrip, fsigmaYMvdPixel, fsigmaYMvdStrip, fsigmaZMvdPixel, fsigmaZMvdStrip, fXMvdPixel, fXMvdStrip, fYMvdPixel, fYMvdStrip, fZMvdPixel, fZMvdStrip ); // ------------------------------------------ get info from trackcand of MVD if( fMvdAloneTracking ){ fnMvdTrackCand = fMvdTrackCandArray->GetEntriesFast(); if (fnMvdTrackCand> MAXMVDTRACKSPEREVENT) { cout<<"from PndTrkTracking2 : N. of MvdTrackCand = "<< fnMvdTrackCand<<" and it is > MAXMVDTRACKSPEREVENT (="<GetEntriesFast(); if (nSttMCPoint ==0){ if(istampa>0) cout<<"from PndTrkTracking2 : N. di Stt MC points = 0"<MAXSTTHITS){ cout<<"from PndTrkTracking2 : N. di Stt MC points = "< MAXSTTHITS ("<GetEntriesFast(); if (nSttHit ==0){ if (istampa >= 1) cout<<"from PndTrkTracking2 : N. di Stt Hits = 0, return!"< MAXSTTHITS) { cout<<"from PndTrkTracking2 : N. di Stt Hits = "< MAXSTTHITS (="<= 1) { cout<<"from PndTrkTracking2 : total # Hits in STT : "<At(i); // right way to extract the corrisponding MC point. ipunto= pSttHit->GetRefIndex(); // fTubeID[i] = STT tubeID correspondint to the hit number i ; // the STT tubeID goes from 1 to 4542 inclusive; fTubeID[i] = pSttHit->GetTubeID(); pSttTube = (PndSttTube *) fSttTubeArray->At(fTubeID[i]); // drift radius Double_t dradius = pSttHit->GetIsochrone(); // wire direction TVector3 wiredirection = pSttTube->GetWireDirection(); if(wiredirection.Z() >=0.) { WDX[i] = wiredirection.X(); WDY[i] = wiredirection.Y(); WDZ[i] = wiredirection.Z(); } else { WDX[i] = -wiredirection.X(); WDY[i] = -wiredirection.Y(); WDZ[i] = -wiredirection.Z(); } info[i][0]= pSttTube->GetPosition().X(); info[i][1]= pSttTube->GetPosition().Y(); info[i][2]= pSttTube->GetPosition().Z(); info[i][3]= dradius; info[i][4]= pSttTube->GetHalfLength(); //----------------------------------------- if(ipunto>=0) { puntator = (FairMCPoint*) fSttPointArray->At(ipunto); info[i][6]= puntator->GetTrackID(); } else { info[i][6]= -10.; } if( fabs( WDX[i] )< 0.00001 && fabs( WDY[i] )< 0.00001 ){ info[i][5]= 1.; fListSttParHits[nSttParHit]=i; nSttParHit++; } else { info[i][5]= 99.;// to signal that it is a skew straw. fListSttSkewHits[nSttSkewHit]=i; nSttSkewHit++; } // printout of the Stt hits; if (istampa >= 1 ) fPrint.stampaSttHits2(i,ipunto,dradius,WDX,WDY,WDZ,puntator,pSttTube,fTubeID[i]); } // end of for( i= 0; i< nSttHit; i++) // reordering the list of parallel hits ( fListSttParHits) by decreasing spatial radius; // first the outermost then the innermost. This is necessary because later the search // must starts from the outer hits. Initial_SttParHits_DecreasingR_Ordering( info, fListSttParHits,nSttParHit ); // fill the inclusion list for Stt, include only first hit for those straws with // multiple hits; fInclusionListStt is BY STT HIT NUMBER; MakeInclusionListStt(nSttHit, fTubeID, info); //----------------------------------- end of exclusion of straws with multiple hits // this MUST go after the MakeInclusionListStt for( i= 0; i< nSttHit; i++){ if(!fInclusionListStt[i]) continue; // SttStrawOn is a Short_t used in the XY track pattern finding later; it was initialized at -1; SttStrawOn[ fTubeID[i] - 1 ] = i; } // end of for( i= 0; i< nSttHit; i++) //-------------------------------------------- fetch the SciTil hits fnSciTilHits = 0; if( fSciTHitArray != NULL){ // number SciTil hits/event fnSciTilHits = fSciTHitArray->GetEntriesFast(); if(fnSciTilHits>MAXSCITILHITS){ cout<<"from PndTrkTracking2 : N. of SciTil Hits = "< MAXSCITILHITS (="< 0) fSciTilMaxNumber = fnSciTilHits ; else fSciTilMaxNumber = 1; Short_t nHitsInSciTile[fSciTilMaxNumber], OriginalSciTilList[fSciTilMaxNumber][fSciTilMaxNumber]; //-------- initialization (to 0) of nHitsInSciTile array; memset (nHitsInSciTile,0,sizeof(nHitsInSciTile)); //--- if(istampa>=1) cout<<"from PndTrkTracking2, event "<0 ){ // OriginalSciTilList is the list of original SciTil hits (not purged yet) // present in a given SciTil tile : // OriginalSciTilList[nacceptedhit][*]; PndSciTHit *pPndSciTHit; TVector3 posiz; // the first SciTil hit; this cannot be duplicate hit by definition. // The Sci Tiles are numbered here according to the numbering // of the (first) SciTil Hit inside the Sci Tile. pPndSciTHit = (PndSciTHit*) fSciTHitArray->At(0); posiz = pPndSciTHit->GetPosition(); if(istampa>0)cout<<"from PndTrkTracking2 SciTil n. "<<0<< " not purged, Xpos "<< posiz.X()<<", Ypos "<< posiz.Y()<<", Zpos "<At(j); posiz = pPndSciTHit->GetPosition(); if(istampa>0)cout<<"from PndTrkTracking2 SciTil n. "<0){ cout<<"from PndTrkTracking2, after purging SciTil; # hits = "<0 ) //-----------------------------------end fetching SciTil hits. //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- start the combined Mvd-Stt PR //------------------- //------------------- //------------------- //------------------- //------------------- //------------------------------------ start the timer; ftimer.Start(kTRUE); if(IVOLTE==0){ ftimer2.Start(kTRUE); } else { ftimer2.Start(kFALSE); } //---------------------------------------------------- // initialization of the (assumed) starting point of the tracks, at the origin; // needs to be modified later; trajectory_vertex[0]=trajectory_vertex[1]=0.; len = sizeof(Trajectory_Start); memset (Trajectory_Start,0,len); //-------------- PndTrkSttConformalFilling fill; fill.FromXYtoConformal( trajectory_vertex, info, fListSttParHits, nSttParHit, infoparalConformal, STRAWRADIUS ); // find the relevant Stt clusters in XY projection, necessary for the Pattern recognition PndTrkSttClusterFinder cluster; Short_t ListHitsinCluster[MAXFOUNDCLUSTERS*MAXHITSINCLUSTER], nFoundClusters, nHitsinCluster[MAXFOUNDCLUSTERS]; cluster.GetClusters( fInclusionListStt, // input; this is the exclusion of Stt hits for Stt multiple hits; fListParContiguous, // input list (axial Stt); first dimension is NUMBER_STRAWS; fListSttParHits, // input fnParContiguous, // input; number of contiguous straws (axial Stt); // NUMBER_STRAWS even if the numbering scheme for the Stt // straws goes from 1 to NUMBER_STRAWS included; nSttParHit, // input; MAXFOUNDCLUSTERS, // input; MAXHITSINCLUSTER, // input; MAXSTTHITS, // input; number of maximux allowed total Stt hits; NUMBER_STRAWS, // input; number of Stt Straws in total; fStrawCode, // input; fStrawCode2, // input; SttStrawOn, // input; fSttTubeArray, // input; array of the Stt tubes; fTubeID, // input; ListHitsinCluster, // output; nFoundClusters, // output; nHitsinCluster // output; ); //------------------------------------- stampe; if(istampa>=1){ cout<<"from PndTrkTracking2, evt "< 60, cint does NOT accept to pass them in the usual // way (parameters in the calling sequence) to PndTrkCTFindTrackInXY::FindTrackInXYProjection. FindTrackInXYProjection2_InputOutputData InOut; // loading those elements of the struct common to all the candidate tracks. InOut.apotemastrawdetectormin = APOTEMASTRAWDETECTORMIN; InOut.info = info; InOut.infoparalConformal = infoparalConformal; InOut.ListParContiguous = fListParContiguous; // array [NUMBER_STRAWS][6] large; list of Stt InOut.maxhitsinfit = MAXHITSINFIT; InOut.maxmvdpixelhitsintrack = MAXMVDPIXELHITSINTRACK; InOut.maxmvdstriphitsintrack = MAXMVDSTRIPHITSINTRACK; InOut.maxstthitsintrack = MAXSTTHITSINTRACK; InOut.minimumhitspertrack = MINIMUMHITSPERTRACK; InOut.nMvdPixelHit = fnMvdPixelHit; InOut.nMvdStripHit = fnMvdStripHit; InOut.nParContiguous = fnParContiguous; // array NUMBER_STRAWS large; nParContiguous[i] --> number of // contiguous Stt Straws (max = 6); InOut.number_straws = NUMBER_STRAWS; // r_stt_inner_par_max ==> radius of the circumscribed circumference to the //; outer hexagon defining THE INNER axial Stt straw region; InOut.r_stt_inner_par_max = APOTEMAMAXINNERPARSTRAW *2./sqrt(3.) ; InOut.StrawCode = fStrawCode; // Short_t array NUMBER_STRAWS large; InOut.StrawCode2 = fStrawCode2; // Short_t array NUMBER_STRAWS large; InOut.SttStrawOn = SttStrawOn; // tSttStrawOn[i] >= 0 --> it is the Stt hit number corresponding to Stt // i-th Tube ID; tSttStrawOn[i] == -1 --> i-th Stt straw NOT hit; InOut.TubeID = fTubeID; // list of Tube ID; fTubeID[i] is Tube Id of i-th Stt hit; InOut.thetamax = THETAMAX; InOut.thetamin = THETAMIN; InOut.XMvdPixel = fXMvdPixel; InOut.XMvdStrip = fXMvdStrip; InOut.YMvdPixel = fYMvdPixel; InOut.YMvdStrip = fYMvdStrip; InOut.xTube = fxTube; InOut.yTube = fyTube; InOut.zTube = fzTube; InOut.xxyyTube = fxxyyTube; //------------------- InOut.apotemamaxskewstraw = APOTEMAMAXSKEWSTRAW; InOut.Cosine = fCosine; InOut.deltanr = DELTAnR; InOut.dimensionscitil = DIMENSIONSCITIL; InOut.FiConformalIndex = FiConformalIndex; InOut.HitsinBoxConf = HitsinBoxConformal; InOut.InclusionListStt = fInclusionListStt; InOut.InclusionListSciTil = fInclusionListSciTil; InOut.legiandre_nthetadiv = LEGIANDRE_NTHETADIV; InOut.legiandre_nradiusdiv = LEGIANDRE_NRADIUSDIV; InOut.ListSttParHits = fListSttParHits; InOut.maxhitsinfit = MAXHITSINFIT; InOut.maxscitilhitsintrack = MAXSCITILHITSINTRACK; InOut.maxstthits = MAXSTTHITS; InOut.minouterhitspertrack = MINOUTERHITSPERTRACK; InOut.nBoxConf = nBoxConformal; InOut.nfidivconformal = NFIDIVCONFORMAL; InOut.nrdivconformal = NRDIVCONFORMAL; InOut.nSciTilHits = fnSciTilHits; InOut.nsttparhit = nSttParHit; InOut.posizSciT = fposizSciTil; InOut.radiaConf = fradiaConf; InOut.RConformalIndex = RConformalIndex; InOut.rstrawdetectormax = RSTRAWDETECTORMAX; InOut.Sinus = fSinus; InOut.StrawCode = fStrawCode; InOut.StrawCode2 = fStrawCode2; InOut.strawradius = STRAWRADIUS; InOut.trajectory_vertex = trajectory_vertex; InOut.YesSciTil = fYesSciTil; //--------------------------------------------------------------------------------- // U and V only for the parallel Stt hits. Double_t U[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], V[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK]; // variable usedd in the plotting in the Legiandre plot; InOut.icounter=0; //----- loop over the parallel hits // begins the first iteration with more severe cuts on the # hits in track candidate int iconta=0; nSttTrackCand=0; // # tracks found if(istampa>=2){ cout<<"event "<=2){ cout<<"event "<=2){ cout<<" Loop of Clusters; this cluster (n. "<= MAXTRACKSPEREVENT) { cout<<"from PndTrkTracking2 : # n. Tracks found so far = " <= MAXTRACKSPEREVENT ( = " <=2){ cout<<" Loop of Clusters; this cluster (n. "<=2){ cout<<" Loop of Clusters; this cluster (n. "<=3){ cout<<"At the bottom of Loop of Clusters; end processing cluster n." <=1){ cout<<"\tstampa dopo FindTrackInXYProjection di tutte le trackCand rimaste :\n"; //fPrint.stampetta(IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0], fPrint.stampetta(IVOLTE,keepit,&fListMvdPixelHitsinTrack[0][0], &fListMvdStripHitsinTrack[0][0],&fListSttParHitsinTrack[0][0], &fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack, fnSttSkewHitsinTrack,fnSciTilHitsinTrack,nSttTrackCand, -1, // print all candidates; MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK,MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- //----------- from here on, the XY parameters of the Helix don't change. ------------------ //----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- // use the risult just obtained from the fit in XY to do the association of the Skew Straw hits for(ncand=0; ncand< nTotalCandidates; ncand++) { if(!keepit[ncand]) continue; if( fR[ncand] < APOTEMAMAXINNERPARSTRAW/2. ) continue; // this is when the XY circle is contained in the // the Mvd region completely; skip the association of // the Skews. // the arrays fCandidateSkew.... are related to the current candidate; they loose meaning // as soon as the loop over the candidate tracks finishes; fnSttSkewHitsinTrack[ncand]= AssociateSkewHitsToXYTrack( fInclusionListStt, // hit is excluded only if it multiple hit. nSttSkewHit, fListSttSkewHits, fOx[ncand], // input : X of center of XY plane circle fOy[ncand], // input : Y of center of XY plane circle fR[ncand], // input : Radius of XY plane circle info, WDX, WDY, WDZ, Fi_low_limit[ncand], // Fi (in Helix XY frame) lower limit using the Stt detector minimum/maximum radius Fi_up_limit[ncand], // Fi (in Helix XY frame) upper limit using the Stt detector maximum/minimum radius Charge[ncand], CandidateSkewList, // output : CandidateSkewList[*][0] = list of selected skew hits // numbers(in skew numbering); // CandidateSkewList[*][1] = solution number (0 or 1) as per // the calculateintersections method; // the info on fCandidateSkewS, fCandidateSkewZ, fCandidateSkewZDrift, fCandidateSkewZError as follows : // if i is the (original) Skew Hit number, and ii (0 or 1) is // the solution, then the infos are stored in the i + ii*MAXSTTHITS location; fCandidateSkewS, // output, S coordinate of selected Skew hit fCandidateSkewZ, // output, Z coordinate of selected Skew hit (center wire) fCandidateSkewZDrift, // output, drift distance IN Z DIRECTION only, of selected Skew hit fCandidateSkewZError // output, Radius taking into account the tilt, IN Z DIRECTION only, of selected Skew hit ); // limit the total # Stt hits to MAXSTTHITSINTRACK if( fnSttSkewHitsinTrack[ncand]+fnSttParHitsinTrack[ncand] > MAXSTTHITSINTRACK ) { if(MAXSTTHITSINTRACK > fnSttParHitsinTrack[ncand]) fnSttSkewHitsinTrack[ncand]=MAXSTTHITSINTRACK-fnSttParHitsinTrack[ncand]; else fnSttSkewHitsinTrack[ncand]=0; } for(j=0;j=2){ cout<<"\tstampa dopo AssociateSkewHitsToXYTrack di solo la Traccia n. "<0) dime = nhitsinfit ; else dime=1; if(istampa>=2) cout<<"\tevt. "<=2){ cout<<"\tstampa prima del primo FitSZspace_Chi2_AnnealingtheMvdOnly, della sola traccia "<0){ resultFitSZagain[ncand] = fit.FitSZspace_Chi2_AnnealingtheMvdOnly( nhitsinfit, // n. hits to be fitted tS, tZED, tDriftRadius, tErrorDriftRadius, FI0[ncand], MAXSKEWHITSINFIT,// maximum number of STT Skew hits in fit; &emme, IVOLTE*100+ncand // trick to indicate both the evt number and the candidate; ); //----------------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------------- if( resultFitSZagain[ncand]==1 && fabs(emme) > 1.e-10 ){ KAPPA[ncand] = emme; GoodSkewFit[ncand] = true; if( ncand<= nSttTrackCand ) SttSZfit[ncand]=true; } else { keepit[ncand]=false; GoodSkewFit[ncand] = false; } } else { // continuation of if(nhitsinfit>0) keepit[ncand]=false; GoodSkewFit[ncand] = false; } // end of if(nhitsinfit>0) //-------------- stampa if(istampa>=2){ cout<<"stampa dopo il primo FitSZspace_Chi2_AnnealingtheMvdOnly, SttTrackCand n. "<0.){ // this means Pz>0. Turns= 0.5*(ZCENTER_STRAIGHT+SEMILENGTH_STRAIGHT)*KAPPA[ncand]/PI; if( fabs(Turns)<10.) { MaxTurns=(Short_t) Turns ;} else { if(Turns>0) MaxTurns=10; else MaxTurns=-10;} } else { Turns= 0.5*(ZCENTER_STRAIGHT-SEMILENGTH_STRAIGHT)*KAPPA[ncand]/PI; if( fabs(Turns)<10.) { MaxTurns=(Short_t) Turns ;} else { if(Turns>0) MaxTurns=10; else MaxTurns=-10;} } } else { MaxTurns=0; } if(istampa>=2) {cout <<"Prima del primo EliminateSpuriousSZ_bis : MaxTurns = "< 2PI or < 2PI when the particle makes more than 1 turn; // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit; this is done by design since when KAPPA is wrong due to spurious hits, especially // after the first fit, Schosen.. can be very wrong; &SchosenStrip[ncand][0], // output; this value from now on can also be > 2PI or < 2PI when the particle makes more than 1 turn; // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit; this is done by design since when KAPPA is wrong due to spurious hits, especially // after the first fit, Schosen.. can be very wrong; &SchosenSkew[ncand][0], // output; this value from now on can also be > 2PI or < 2PI when the particle makes more than 1 turn; // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit; this is done by design since when KAPPA is wrong due to spurious hits, especially // after the first fit, Schosen.. can be very wrong; &ZchosenPixel[ncand][0], // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit; &ZchosenStrip[ncand][0], // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit; &ZchosenSkew[ncand][0], // for now this value is NOT used; the inital value given by AssociateSkewHitsToXYTrack is used instead // by LoadSZetc_forSZfit;; ErrorchosenPixel, ErrorchosenStrip, ErrorchosenSkew, KAPPA[ncand], FI0[ncand], fR[ncand] ); //-------------- stampa if(istampa>=2){ cout<<"stampa dopo il primo EliminateSpuriousSZ_bis, SttTrackCand n. "<=2){ cout<<"prima del secondo FitSZspace_Chi2_AnnealingtheMvdOnly : nhitsinfit "<=2){ cout<<"stampa dopo il secondo FitSZspace_Chi2_AnnealingtheMvdOnly, SttTrackCand n. "<=2){ cout<<"stampa in Last Iteration, dopo la ricarica di Skew ed Mvd hits; SttTrackCand n. "< 2PI or < 2PI when the particle makes more than 1 turn; // this time Schosen.... will be used from now (it is supposed to be the best result); &SchosenStrip[ncand][0], // output; this value from now on can also be > 2PI or < 2PI when the particle makes more than 1 turn; &SchosenSkew[ncand][0], // output; this value from now on can also be > 2PI or < 2PI when the particle makes more than 1 turn; &ZchosenPixel[ncand][0], &ZchosenStrip[ncand][0], &ZchosenSkew[ncand][0], ErrorchosenPixel, ErrorchosenStrip, ErrorchosenSkew, KAPPA[ncand], FI0[ncand], fR[ncand] ); // END OF LAST ITERATION //--------------------------------------------------------------------------- //-------------- stampa if(istampa>=2){ cout<<"stampa dopo il secondo EliminateSpuriousSZ (e' ter), SttTrackCand n. "<=1){ cout<<"stampa dopo Mvd cleanup e prima di EliminateClones di tutte le "<1) EliminateClones(nTotalCandidates,0.6,keepit); //-------------------------------------------------------------------------- //------------------------------- // reject tracks with too few or too many hits; for(ncand=0; ncand< nTotalCandidates; ncand++){ // check if the track candidate has still at least 2 axial hits; if( fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+fnSttParHitsinTrack[ncand]<2){ keepit[ncand]=false; continue; } // limit the total # Stt hits to MAXSTTHITSINTRACK if( fnSttSkewHitsinTrack[ncand]+fnSttParHitsinTrack[ncand] > MAXSTTHITSINTRACK ) { if(MAXSTTHITSINTRACK > fnSttSkewHitsinTrack[ncand]) fnSttParHitsinTrack[ncand]=MAXSTTHITSINTRACK-fnSttSkewHitsinTrack[ncand]; else fnSttParHitsinTrack[ncand]=0; } } // end of for(ncand=0; ncand< nTotalCandidates; ncand++) //------------------------------------------------------------- Start[0]=0.; Start[1]=0.; Start[2]=0.; gap = (Double_t) (VERTICALGAP); for(ncand=0, nRemainingCandidates=0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; Short_t &nHitsPar = fnSttParHitsinTrack[ncand]; Short_t &nHitsSkew = fnSttSkewHitsinTrack[ncand]; int dime; if(nHitsSkew>0) { dime = nHitsSkew; } else { dime =1; } Double_t auxS[dime]; for(i=0;i1) cout<<"PndTrkTracking2, entra in TrackCleanup "<< "tracce normali, IVOLTE "<=1){ for(ncand=0; ncand< nTotalCandidates; ncand++){ cout<<"evento n. "<0) { zmin = -FI0/KAPPA; zmax = (2.*PI-FI0)/KAPPA; } else { zmax = -FI0/KAPPA; zmin = (2.*PI-FI0)/KAPPA; } deltaz = zmax-zmin; for(i=0; i zmax ){ tempZ[sign]=fmod( tempZ[sign]-zmax, deltaz) + zmin; } else if (tempZ[sign] Fi_up_limit) continue; } else if( S[location] > Fi_up_limit) { if( S[location]- 2.*PI < Fi_low_limit) continue; } Z[location] = auxZ[ii]; ZDrift[location] = auxZDrift[ii]; // ZError[location] = auxZError[ii]; ZError[location] = STRAWRADIUS/sin( 3.*PI/180.) ; // this is 0.5 cm / sin(3 degrees) = 9.55 cm, namely the maximum // reasonable error projected onto the Helix trajectory cylinder; // the list of the selected Skew skew hits instead, is stored sequentially; SkewList[NAssociated][0] = infoskew[iii]; // n. skew hit in original hit numbering SkewList[NAssociated][1] = ii; // solution 0 or solution 1 were accepted NAssociated++; } // end of if( auxZ[ii] < 999998.) } // end of for( ii=0; ii<2; ii++) } // for( iii=0; iii< NSkewhits; iii++) return NAssociated; } //----------end of function PndTrkTracking2::AssociateSkewHitsToXYTrack //------------------------- begin of function PndTrkTracking2::CalculateSinandCosin void PndTrkTracking2::CalculateSinandCosin() { Short_t i; fDELTATHETA = (THETAMAX-THETAMIN)/LEGIANDRE_NTHETADIV; for(i=0;i& keepit, Vec & Mvdhits, Double_t info[][7], Short_t nSttParHit, // starting investigation from candidate n. StartTrackCand Short_t StartTrackCand, // until candidate n. EndTrackCand-1 included. Short_t EndTrackCand, Double_t *KAPPA, Double_t *FI0, Double_t *Fi_low_limit, Double_t *Fi_up_limit, Short_t *nParHitsinTrack, // input/output Short_t ListParHitsinTrack[][MAXSTTHITSINTRACK] // input/output ) { Short_t i, itrack, ihit, j, k, ntot, nadd; Double_t angle, deltaZ, dist, dist1, Zpos; const Double_t NTIMES=0.4; // const Double_t NTIMES=1.; for(itrack=StartTrackCand; itrack 1.e-20){ deltaZ = 2.*PI/KAPPA[itrack]; Zpos = (angle - FI0[itrack])/KAPPA[itrack]; if( fabs(Zpos-info[ihit][2])>1.5*info[ihit][4] && fabs(Zpos+deltaZ-info[ihit][2])>1.5*info[ihit][4] && fabs(Zpos-deltaZ-info[ihit][2])>1.5*info[ihit][4] ) continue; } if( angle>Fi_up_limit[itrack]){ angle -= 2.*PI; if(angle < Fi_low_limit[itrack]) continue; } else if (angle < Fi_low_limit[itrack]){ angle += 2.*PI; if(angle > Fi_up_limit[itrack]) continue; } dist1 = fabs( sqrt( (fOx[itrack]-info[ihit][0])*(fOx[itrack]-info[ihit][0])+ (fOy[itrack]-info[ihit][1])*(fOy[itrack]-info[ihit][1]) ) - fR[itrack] ); dist = fabs( dist1 - info[ihit][3] ); // info[ihit][3] = drift radius; if info[ihit][3]>dist then // the drift circle of this straw crosses the trajectory. if(dist dist ){ ListParHitsinTrack[itrack][ nParHitsinTrack[itrack] ] =ihit; nParHitsinTrack[itrack]++; } } // end of for(i=0; i0) { cout<<"from Eliminateclones, traccia i = "< fraction * nTotalHits[i] || nCommon > fraction * nTotalHits[j]) { // arbitration; if( nTotalHits[i]>=nTotalHits[j] ){ keepit[j]=false; } else { keepit[i]=false; // in this case quit analysis of the track number i; continue; } } } // end of for(j=i+1; j 1.e-10, // see code above; MvdCut = MvdCut*sqrt(1.+Rr*Rr*KAPPA*KAPPA)/(Rr*fabs(KAPPA)); minimumSttDriftError = minimumSttDriftError*sqrt(1.+Rr*Rr*KAPPA*KAPPA)/(Rr*fabs(KAPPA)); Double_t chosenS, chosenS2, ddd, dista, dista1, dista0, Drift, d_min, error, Fi, zeta1, distance_RS, distance_Z, dista_storage[MAXSTTHITS], Z; PndTrkCTGeometryCalculations GeomC; int len = sizeof(already); memset (already,false,len); auxnMvdPixel=0; auxnMvdStrip=0; auxnSttSkew=0; Double_t Pix_distance[fnMvdPixelHitsinTrack[ncand]]; for(i=0;i< fnMvdPixelHitsinTrack[ncand] ;i++){ k = fListMvdPixelHitsinTrack[ncand][i]; Z = fCandidatePixelZ[k]; Fi= fCandidatePixelS[k]; dista = GeomC.Dist_SZ_bis(Rr,KAPPA,FI0,Z,Fi,MaxTurnofTracks,signPz,chosenS); if(istampa>=2){ cout<<"from EliminateSpuriousSZ_bis, Pixel n. "<=2){ cout<<", chosen."<=2){ cout<<", not chosen. "<=2){ cout<<"from EliminateSpuriousSZ_bis, Strip n. "<=2){ cout<<", chosen. "<=2){ cout<<", not chosen. "<ddd ) { dista = ddd; ZchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= Z-Drift; SchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= chosenS2; } else { ZchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ] = Z+Drift; SchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= chosenS; } if(istampa>=2){ cout<<"from EliminateSpuriousSZ_bis, Skew Stt n. "<dista ){ auxListSttSkew[auxnSttSkew]= fListSttSkewHitsinTrack[ncand][j] ; auxListSttSkewSolution[auxnSttSkew]= fListSttSkewHitsinTrackSolution[ncand][j]; ErrorchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]=error; auxnSttSkew++; } } else { // continuation of if( already[ ListSkewHitsinTrack[j] ] already[ fListSttSkewHitsinTrack[ncand][j] ] = true; // store the distance calculated; dista_storage[ fListSttSkewHitsinTrack[ncand][j] ]=dista; auxListSttSkew[auxnSttSkew]= fListSttSkewHitsinTrack[ncand][j] ; auxListSttSkewSolution[auxnSttSkew]=fListSttSkewHitsinTrackSolution[ncand][j]; ErrorchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]=error; auxnSttSkew++; } // end of if( already[ ListSkewHitsinTrack[j] ] ) } // end of if( dista < 4.*error ....) } // end of for(j=0;j<*nSkewHitsinTrack;j++) // reload the list of good hits fnMvdPixelHitsinTrack[ncand] = auxnMvdPixel; fnMvdStripHitsinTrack[ncand] = auxnMvdStrip; fnSttSkewHitsinTrack[ncand] = auxnSttSkew; for(j=0;j 1. ){ if( fabs( Pix_distance[i] ) < fabs( Pix_distance[j])){ inclusion[j]=false; } else { inclusion[i]=false; } dista0 = Pix_distance[i]; dista1 =Pix_distance[j]; } } // end of for(i=0;i 1. ){ if( fabs( Strip_distance[i] ) < fabs( Strip_distance[j])){ inclusion2[j]=false; } else { inclusion2[i]=false; } dista0 = Strip_distance[i]; dista1 = Strip_distance[j]; } } // end of for(i=0;i 1.e-10, // see code above; MvdCut = MvdCut*sqrt(1.+Rr*Rr*KAPPA*KAPPA)/(Rr*fabs(KAPPA)); if(istampa>=2) cout<<"from eliminatespurioussz_ter, MvdCut "<=2){ cout<<"from EliminateSpuriousSZ_ter, Pixel n. "<=2){ cout<<", chosen. "<=2){ cout<<", not chosen. "<=2){ cout<<"from EliminateSpuriousSZ_ter, Strip n. "<=2){ cout<<", chosen. "<=2){ cout<<", not chosen. "<=2){ cout<<"from EliminateSpuriousSZ_ter, Skew Stt n. "<ddd ) { dista = ddd; ZchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= Z-Drift; SchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= chosenS2; } else { ZchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ] = Z+Drift; SchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]= chosenS; } // error = Drift; // the following error is 0.5 cm/sin(3 degrees) = 9.55 cm; error = 9.55; if( dista < error // dista < 4.*error // || // dista < 2.*minimumSttDriftError ) { // check now if the other solution of the same hit // has already been selected before; if( already[ fListSttSkewHitsinTrack[ncand][j] ]){ // in this case the other solution has already been // selected; therefore in dista_storage[ ListSkewHitsinTrack[j] ] // there must be the distance previously calculated; if( dista_storage[ fListSttSkewHitsinTrack[ncand][j] ]>dista ){ auxListSttSkew[auxnSttSkew]= fListSttSkewHitsinTrack[ncand][j] ; auxListSttSkewSolution[auxnSttSkew]= fListSttSkewHitsinTrackSolution[ncand][j]; ErrorchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]=error; auxnSttSkew++; } } else { // continuation of if( already[ ListSkewHitsinTrack[j] ] already[ fListSttSkewHitsinTrack[ncand][j] ] = true; // store the distance calculated; dista_storage[ fListSttSkewHitsinTrack[ncand][j] ]=dista; auxListSttSkew[auxnSttSkew]= fListSttSkewHitsinTrack[ncand][j] ; auxListSttSkewSolution[auxnSttSkew]=fListSttSkewHitsinTrackSolution[ncand][j]; ErrorchosenSkew[ fListSttSkewHitsinTrack[ncand][j] ]=error; auxnSttSkew++; } // end of if( already[ ListSkewHitsinTrack[j] ] ) } // end of if( dista < 4.*error ....) } // end of for(j=0;j<*nSkewHitsinTrack;j++) // reload the list of good hits fnMvdPixelHitsinTrack[ncand] = auxnMvdPixel; fnMvdStripHitsinTrack[ncand] = auxnMvdStrip; fnSttSkewHitsinTrack[ncand] = auxnSttSkew; for(j=0;jAt(i); TVector3 dirSeed=pMvdTrackCand->getDirSeed(); TVector3 posSeed=pMvdTrackCand->getPosSeed(); qop = pMvdTrackCand->getQoverPseed(); // n. hits in this track cand fnHitMvdTrackCand[i] = pMvdTrackCand->GetNHits(); if( fnHitMvdTrackCand[i]>MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK){ cout<<"from PndTrkTracking2, fnHitMvdTrackCand[i] = "< MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK (=" <GetSortedHit(j); // the following case should never happen (in principle), but, just to be on // the safe side .... if(pndtrackcandhit.GetHitId()<0||pndtrackcandhit.GetDetId()<0)continue; // this is a Pixel. if( pndtrackcandhit.GetDetId()== FairRootManager::Instance()->GetBranchId(fMvdPixelBranch) && kPixel < MAXMVDPIXELHITSINTRACK){ // the following is a protection because the maximum Mvd hit n. // cannot exceed MAXMVDPIXELHITS . if( pndtrackcandhit.GetHitId()>MAXMVDPIXELHITS ){ cout<<"from PndTrkTracking2, this Pixel Mvd hit has a number = " < MAXMVDPIXELHITS (="<< MAXMVDPIXELHITS<<"), rejected!"<GetBranchId(fMvdStripBranch) && kStrip < MAXMVDSTRIPHITSINTRACK){ // the following is a protection because the maximum Mvd hit n. cannot // exceed MAXMVDSTRIPHITS . if( pndtrackcandhit.GetHitId()>MAXMVDSTRIPHITS ){ cout<<"from PndTrkTracking2, this Strip Mvd hit has a number = " < MAXMVDSTRIPHITS (="<< MAXMVDSTRIPHITS<<"), rejected!"<=0.){ fListMvdDSPixelHitNotTrackCand[fnMvdDSPixelHitNotTrackCand] = i; fnMvdDSPixelHitNotTrackCand++; } else { fListMvdUSPixelHitNotTrackCand[fnMvdUSPixelHitNotTrackCand] = i; fnMvdUSPixelHitNotTrackCand++; } } } for( i= 0; i< fnMvdStripHit ; i++){ if( ! finMvdTrackCandStrip[i] ){ if( fZMvdStrip[i]>=0.){ fListMvdDSStripHitNotTrackCand[fnMvdDSStripHitNotTrackCand] = i; fnMvdDSStripHitNotTrackCand++; } else { fListMvdUSStripHitNotTrackCand[fnMvdUSStripHitNotTrackCand] = i; fnMvdUSStripHitNotTrackCand++; } } } } //----------------------- end of function PndTrkTracking2::ExtractInfoFromMvdTrackCand //----------begin of function PndTrkTracking2::FindCharge void PndTrkTracking2::FindCharge( Double_t oX, Double_t oY, Short_t nParallelHits, Double_t *X, Double_t *Y, Short_t * Charge ) { Short_t ihit, nleft, nright; Double_t cross, disq, minl, minr; // this methods works with the hypothesis that this track comes // from (0,0) for(ihit=0, nleft=0, nright=0, minr = 9999999., minl = 9999999.; ihit0 hits stays 'on the left' (which means clockwise to go from the origin // to the hit following the smaller path) otherwise it stays 'on the right'. if (cross>0.) { disq = X[ihit]*X[ihit]+Y[ihit]*Y[ihit]; nleft++; } else { nright++; } } // end of for(ihit=0, nleft=0, nright=0;.... if( nright> nleft) { *Charge = -1; } else if ( nleft > nright) { *Charge = 1; } else { // then choose according the closest hit ti the center if( minr < minl ) *Charge = -1; else *Charge = 1; } } //----------end of function PndTrkTracking2::FindCharge //----------start of function PndTrkTracking2::FixDiscontinuitiesFiangleinSZplane void PndTrkTracking2::FixDiscontinuitiesFiangleinSZplane( Short_t CandidateSkewnSkewHitsinTrack, Vec & S, Double_t *Fi_initial_helix_referenceframe, Short_t Charge ) { Short_t i; Double_t max, min; if( Charge >0 ) { for(i=0 ; i *Fi_initial_helix_referenceframe ) S[i]-= 2.*PI; } } else { for(i=0 ; i 0){ if(fi > FI0 ) FI0 += 2.*PI; // Posiz[2] = (FI0-fi)/KAPPA; } else { if(fi < FI0 ) fi += 2.*PI; } Posiz[2] = (fi-FI0)/KAPPA; return; } //----------end of function PndTrkTracking2::InfoXYZParal //--------begin of function PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering void PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering( Double_t info[][7], Short_t *ListSttParHi, Int_t nSttParHit ) { Short_t j, OLDListSttParHits[nSttParHit]; Int_t auxIndex[nSttParHit]; Double_t auxRvalues[nSttParHit]; // ordering the parallel hits by decreasing spatial radius. for (j = 0; j< nSttParHit; j++){ auxIndex[j]=j; auxRvalues[j]= info[ListSttParHi[ j ] ][0]*info[ListSttParHi[ j ] ][0]+ info[ListSttParHi[ j ] ][1]*info[ListSttParHi[ j ] ][1]; OLDListSttParHits[j]=ListSttParHi[j]; } PndTrkMergeSort Sorter; Sorter.Merge_Sort( (Short_t) nSttParHit, auxRvalues, auxIndex); for (j = 0; j< nSttParHit; j++){ ListSttParHi[ nSttParHit-1-j] = OLDListSttParHits[ auxIndex[ j ] ]; } return; } //--------end function PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering //---------------------- begin function PndTrkTracking2::LoadPndTrack_TrackCand void PndTrkTracking2::LoadPndTrack_TrackCand( bool * keepit, bool * SttSZfit, Short_t nTotalCandidates, Short_t * Charge, Int_t nSttTrackCand, Double_t *FI0, Double_t *KAPPA, Double_t info[][7], Double_t SchosenSkew[][MAXSTTHITS], Double_t ZchosenSkew[][MAXSTTHITS], Short_t *daTrackFoundaTrackMC ) { //------- load the new PndTrackCand ; each track has the STT and the Mvd hits associated //------- also load the new PndTrack ; each track has the STT and the Mvd hits associated Int_t ipinco, j, k, l, ncand ; Double_t ddd, dis, Distance, Oxx, Oyy, Ptras, Pxini, Pyini, Pzini, px, py, qop, x, y, Posiz1[3], versor[2] ; TVector3 ErrMomentum, ErrPosition, Momentum, Position ; for(ncand=0, ipinco = 0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; // case in which there was no Skew hits and no KAPPA info and that // candidate could not be associated to any Mvd hits --> no KAPPA information! if(ncand1.e-20 ){ Pzini = -Charge[ncand]*0.003*fBFIELD/KAPPA[ncand]; if(fabs(Pzini) > PMAX) continue; } else { continue; } // PndTrackCand Array loading new((*fSttMvdPndTrackCandArray)[ipinco]) PndTrackCand; PndTrackCand *pTrckCand = (PndTrackCand*) fSttMvdPndTrackCandArray->At(ipinco); TVector3 dirSeed(Pxini,Pyini,Pzini); // momentum direction in starting point qop = Charge[ncand]/dirSeed.Mag(); dirSeed.SetMag(1.); pTrckCand->setTrackSeed(posSeed, dirSeed, qop); // pTrckCand->setMcTrackId( -1 ); pTrckCand->setMcTrackId( daTrackFoundaTrackMC[ncand] ); for(j=0; j< fnTrackCandHit[ncand]; j++){ switch (fListTrackCandHitType[ncand][j]){ case 0: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdPixelBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 1: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdStripBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 2: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 3: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; } } // PndTrack Array loading // last = last hit in found track; first = first hit in found track; // pTrckCand = pointer to the corresponding PndTrackCand. // the first hit if (fListTrackCandHitType[ncand][0] == 0){ // Mvd Pixel Posiz1[0] = fXMvdPixel[ fListTrackCandHit[ncand][0] ]; Posiz1[1] = fYMvdPixel[ fListTrackCandHit[ncand][0] ]; Posiz1[2] = fZMvdPixel[ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if (fListTrackCandHitType[ncand][0] == 1){ // Mvd Strip Posiz1[0] = fXMvdStrip[ fListTrackCandHit[ncand][0] ]; Posiz1[1] = fYMvdStrip[ fListTrackCandHit[ncand][0] ]; Posiz1[2] = fZMvdStrip[ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if( fListTrackCandHitType[ncand][0] == 2 ){ // it is a parallel straw hit InfoXYZParal( info, fListTrackCandHit[ncand][0], fOx[ncand], fOy[ncand], fR[ncand], KAPPA[ncand], FI0[ncand], Charge[ncand], Posiz1 ); // cases in which the calculation of the position failed, see // InfoXYZParal method. if(Posiz1[2]<-888888887. || Posiz1[0] < -999999998.) continue; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } else if ( fListTrackCandHitType[ncand][0] == 3 ){ // it is a skew straw hit Posiz1[0] = fOx[ncand]+fR[ncand]*cos(SchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]); Posiz1[1] = fOy[ncand]+fR[ncand]*sin(SchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]); Posiz1[2] = ZchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } Position.SetX( Posiz1[0] ); Position.SetY( Posiz1[1] ); Position.SetZ( Posiz1[2] ); versor[0] = fOx[ncand]-Posiz1[0]; versor[1] = fOy[ncand]-Posiz1[1]; Distance = sqrt(versor[0]*versor[0]+versor[1]*versor[1]); versor[0] /= Distance; versor[1] /= Distance; px = -Charge[ncand]*Ptras*versor[1]; py = Charge[ncand]*Ptras*versor[0]; Momentum.SetX(px); Momentum.SetY(py); Momentum.SetZ(Pzini); ErrMomentum.SetX(0.05*Ptras); // set at 5% all the times. ErrMomentum.SetY(0.05*Ptras); // set at 5% all the times. ErrMomentum.SetZ(0.05*Pzini); // set at 5% all the times. // the plane of this FairTrackParP better is perpendicular to // the momentum direction ddd = Ptras*sqrt(Ptras*Ptras+Pzini*Pzini); FairTrackParP first( Position, Momentum, ErrPosition, ErrMomentum, Charge[ncand], Position, TVector3(py/Ptras, -px/Ptras, 0.), // first vector defining the plane TVector3(Pzini*px/ddd,Pzini*py/ddd,-Ptras*Ptras/ddd) //second vector defining the plane ); // the last hit k = fnTrackCandHit[ncand]-1; if (fListTrackCandHitType[ncand][k] == 0){ // Mvd Pixel Posiz1[0] = fXMvdPixel[ fListTrackCandHit[ncand][k] ]; Posiz1[1] = fYMvdPixel[ fListTrackCandHit[ncand][k] ]; Posiz1[2] = fZMvdPixel[ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if (fListTrackCandHitType[ncand][k] == 1){ // Mvd Strip Posiz1[0] = fXMvdStrip[ fListTrackCandHit[ncand][k] ]; Posiz1[1] = fYMvdStrip[ fListTrackCandHit[ncand][k] ]; Posiz1[2] = fZMvdStrip[ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if( fListTrackCandHitType[ncand][k] == 2 ){ // it is a parallel straw hit InfoXYZParal ( info, fListTrackCandHit[ncand][k], fOx[ncand], fOy[ncand], fR[ncand], KAPPA[ncand], FI0[ncand], Charge[ncand], Posiz1 ); if(Posiz1[2]<-888888887. || Posiz1[0] < -999999998.) continue; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } else if ( fListTrackCandHitType[ncand][k] == 3 ){ // it is a skew straw hit Posiz1[0] = fOx[ncand]+fR[ncand]*cos(SchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]); Posiz1[1] = fOy[ncand]+fR[ncand]*sin(SchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]); Posiz1[2] = ZchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } Position.SetX( Posiz1[0] ); Position.SetY( Posiz1[1] ); Position.SetZ( Posiz1[2] ); versor[0] = fOx[ncand]-Posiz1[0]; versor[1] = fOy[ncand]-Posiz1[1]; Distance = sqrt(versor[0]*versor[0]+versor[1]*versor[1]); versor[0] /= Distance; versor[1] /= Distance; px = -Charge[ncand]*Ptras*versor[1]; py = Charge[ncand]*Ptras*versor[0]; Momentum.SetX(px); Momentum.SetY(py); Momentum.SetZ(Pzini); // the plane of this FairTrackParP better is perpendicular to // the momentum direction ddd = Ptras*sqrt(Ptras*Ptras+Pzini*Pzini); FairTrackParP last( Position, Momentum, ErrPosition, ErrMomentum, Charge[ncand], Position, TVector3(py/Ptras, -px/Ptras, 0.), // first vector defining the plane TVector3(Pzini*px/ddd,Pzini*py/ddd,-Ptras*Ptras/ddd) //second vector defining the plane ); // loading actually the PndTrack PndTrack *pTrck = new((*fSttMvdPndTrackArray)[ipinco]) PndTrack(first,last,*pTrckCand); pTrck->SetRefIndex(ipinco); pTrck->SetFlag(0); ipinco++; } // end of for(ncand=0, ipinco = 0; ncand< nTotalCandidates; ncand++) } //----------end function PndTrkTracking2::LoadPndTrack_TrackCand //----------begin function PndTrkTracking2::LoadSZetc_forSZfit void PndTrkTracking2::LoadSZetc_forSZfit( Short_t ncand, // input Short_t nhitsinfit, Vec & ErrorDriftRadius, // output Double_t * ErrorDriftRadiusbis, // output Vec & DriftRadius, // output Double_t * DriftRadiusbis, // output Vec & S, // output Double_t * Sbis, // output Vec & ZED, // output Double_t * ZEDbis // output ) { //--------------------- here calculate the S and Z values of Mvd Pixels, Mvd Strips, // Stt Skew hits and SciTil hits (if present). // the difference between S and Sbis, ZED and ZEDbis, DriftRadius and DriftRadiusbis, // ErrorDriftRadius and ErrorDriftRadiusbis, is that S, ZED etc. contain the list of // Pixel+Strips+SciTil + other Skew Stt hits in case Pixel+Strips+SciTil are <= 2; instead // Sbis, ZEDbis etc. contain Pixel+Strips+all Skew Stt hits. int i, j, k, kall, location; // the Mvd Pixels hit for(i=0; i< fnMvdPixelHitsinTrack[ncand]; i++){ k=fListMvdPixelHitsinTrack[ncand][i]; ZEDbis[i] = ZED[i] = fCandidatePixelZ[k]; S[i] = fCandidatePixelS[k]; Sbis[i] = S[i]; // DriftRadius is set conventionally at -1, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be 1cm. DriftRadiusbis[i]=DriftRadius[i]=-1.; // the following error is conventional (it was set at 0.5 previously in StoreSZ_MvdScitil) // for the chi**2 type of fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= fCandidatePixelErrorDriftRadius[k] ; } // the Mvd Strips hit for(j=0, i = fnMvdPixelHitsinTrack[ncand]; j< fnMvdStripHitsinTrack[ncand]; j++){ k=fListMvdStripHitsinTrack[ncand][j]; ZEDbis[i] = ZED[i] = fCandidateStripZ[k]; S[i] = fCandidateStripS[k]; Sbis[i] = S[i] ; // DriftRadius is set conventionally at -1, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be 1cm. DriftRadiusbis[i]=DriftRadius[i]=-1.; // the following error is conventional (it was set at 0.5 previously in StoreSZ_MvdScitil) // for the chi**2 type of fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= fCandidateStripErrorDriftRadius[k] ; i ++; } // the SciTil hit ( when they are 2, the fS_SciTilHitsinTrack is already a mean // of the two; then consider only 1 SciTil hit, the first, and make an average // of the two Z positions). i = fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]; ZED[i]=fCandidateSciTilZ; S[i]=fCandidateSciTilS; DriftRadius[i]=-2.; ErrorDriftRadius[i]=fCandidateSciTilErrorDriftRadius; // this has been set earlier to DIMENSIONSCITIL/2.; // the Skew Stt hits // the info on CandidateSkewS, CandidateSkewZ, CandidateSkewZDrift, CandidateSkewZError as follows : // if i is the (original) Skew Hit number, and ii (0 or 1) is // the solution according to the calculateintersections method , // then the infos are stored in the i + ii*MAXSTTHITS location; for(j=0;j 2 SciTil hits has already been // prevented early in PndTrkCTFindTrackInXY. i = fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+ fnSciTilHitsinTrack[ncand] +j ; } // here : k = Skew Hit number (original notation), // fListSttSkewHitsinTrackSolution[ncand][j] = number of the solution // (0 or 1) according to the calculateintersections method; k=fListSttSkewHitsinTrack[ncand][j]; location = k + fListSttSkewHitsinTrackSolution[ncand][j]*MAXSTTHITS; // calculate the quantities used for the SZ fit only. if(i& keepit, Double_t delta, Double_t highqualitycut, Short_t nSttTrackCand, Double_t *FI0, Double_t *Fifirst, Vec & CHARGE, Short_t *nPixelHitsinTrack, // output Short_t ListPixelHitsinTrack[][MAXMVDPIXELHITSINTRACK], // output Short_t *nStripHitsinTrack, // output Short_t ListStripHitsinTrack[][MAXMVDSTRIPHITSINTRACK] // output ) { bool specialcase; Short_t i, jmvdhit; Double_t angle, anglemax, anglemin, dist; for(i=0; i0){ // track must rotate clockwise looking into the beam. anglemax = FI0[i]; anglemin = Fifirst[i]; } else { anglemin = FI0[i]; anglemax = Fifirst[i]; } if(anglemax < anglemin) anglemax += 2.*PI; if(anglemax < anglemin) anglemax=anglemin; // this is just to be super-sure. } // end of if( Fifirst[i] < -99998. ) //-------------------- // first try attach the Pixels; nPixelHitsinTrack[i] = 0; for( jmvdhit=0; jmvdhitanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax) { dist=fabs( sqrt( (fOx[i]-fXMvdPixel[jmvdhit])* (fOx[i]-fXMvdPixel[jmvdhit]) +(fOy[i]-fYMvdPixel[jmvdhit])*(fOy[i]-fYMvdPixel[jmvdhit]))-fR[i]); if(dist anglemin) } // end of for( jmvdhit=0; jmvdhitanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax) { dist=fabs( sqrt( (fOx[i]-fXMvdStrip[jmvdhit])* (fOx[i]-fXMvdStrip[jmvdhit]) +(fOy[i]-fYMvdStrip[jmvdhit])*(fOy[i]-fYMvdStrip[jmvdhit]))-fR[i]); if(dist anglemin) } // end of for( jmvdhit=0; jmvdhit& keepit, Vec & Mvdhits, Double_t delta, Double_t highqualitycut, Short_t nSttTrackCand, Double_t *FI0, Double_t *Fifirst, Vec & CHARGE, Short_t *nPixelHitsinTrack, // output Short_t ListPixelHitsinTrack[][MAXMVDPIXELHITSINTRACK], // output Short_t *nStripHitsinTrack, // output Short_t ListStripHitsinTrack[][MAXMVDSTRIPHITSINTRACK] // output ) { bool // flaggo, specialcase, downstream, determined; Short_t j, itrack, ipix, istr, ndownstream, ntot, naddpix, naddstr, List[MAXMVDPIXELHITS+MAXMVDSTRIPHITS]; Double_t angle, anglemax, anglemin, dist, oldtotal, oldtotal2, total, Dist, DIST[MAXMVDTRACKSPEREVENT+1]; for(itrack=0; itrack0){ // track must rotate clockwise looking into the beam. anglemax = FI0[itrack]; anglemin = Fifirst[itrack]; } else { anglemin = FI0[itrack]; anglemax = Fifirst[itrack]; } if(anglemax < anglemin) anglemax += 2.*PI; if(anglemax < anglemin) anglemax=anglemin;// just to be super-sure. } // end of if( Fifirst[itrack] < -99998. ) // find if this track goes downstream or upstream ndownstream=0; for(j=0; j0.){ ndownstream++ ; } } for(j=0; j0.){ ndownstream++ ; } } if(ndownstream>ntot-ndownstream) downstream=true; else downstream=false; // loop over the Mvd Pixel and try to attach new Pixels to each candidate track naddpix=0; for(ipix=0; ipixanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[itrack]-fXMvdPixel[ipix])*(fOx[itrack]-fXMvdPixel[ipix]) +(fOy[itrack]-fYMvdPixel[ipix])*(fOy[itrack]-fYMvdPixel[ipix]) ) -fR[itrack]); if(dist anglemin) // } // end of if(flaggo) } // end of for(ipix=0; ipix0){ if(naddpix>MAXMVDPIXELHITSINTRACK){ // protection against strange tracks (and also from // out-of-bound indexing of arrays); naddpix=MAXMVDPIXELHITSINTRACK; } // for(j=0;j0) naddstr=0; for(istr=0; istranglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[itrack]-fXMvdStrip[istr])*(fOx[itrack]-fXMvdStrip[istr]) +(fOy[itrack]-fYMvdStrip[istr])*(fOy[itrack]-fYMvdStrip[istr]) ) -fR[itrack]); if(dist anglemin) // } // end of if(flaggo) } // end of for(istr=0; istr0){ if(naddstr>MAXMVDSTRIPHITSINTRACK){ // protection against strange tracks (and also from // out-of-bound indexing of arrays); naddstr=MAXMVDSTRIPHITSINTRACK; } // for(j=0;j0) if(nPixelHitsinTrack[itrack]+nStripHitsinTrack[itrack]>0) Mvdhits[itrack]=true; } // end of for(itrack=0; itrack0){ // track must rotate clockwise looking into the beam. anglemax = FI0[i]; anglemin = Fifirst[i]; } else { anglemin = FI0[i]; anglemax = Fifirst[i]; } if(anglemax < anglemin) anglemax += 2.*PI; if(anglemax < anglemin) anglemax=anglemin; // this is just to be super-sure. } // end of if( Fifirst[i] < -99998. ) //-------------------- ngoodmix=0; nn[0]=0; for( imvdcand=0; imvdcandGetBranchId(fMvdPixelBranch)){ ncont++; angle = atan2( fYMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]]-fOy[i], fXMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]]-fOx[i] ); if(angle<0.) angle += 2.*PI; if( angle>anglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax) { dist=fabs( sqrt( (fOx[i]-fXMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]])* (fOx[i]-fXMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]]) +(fOy[i]-fYMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]])* (fOy[i]-fYMvdPixel[fListHitMvdTrackCand[imvdcand][jmvdhit]]))-fR[i]); if(distGetBranchId(fMvdPixelBranch); Dist += dist; if( dist anglemin) } else {// at this point this is a Strip hit; already made sure // earlier in the code that there is no third possibility. ncont++; angle = atan2( fYMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]]-fOy[i], fXMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]]-fOx[i] ); if(angle<0.) angle += 2.*PI; if( angle>anglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[i]-fXMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]])* (fOx[i]-fXMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]]) +(fOy[i]-fYMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]])* (fOy[i]-fYMvdStrip[fListHitMvdTrackCand[imvdcand][jmvdhit]])) -fR[i]); if(distGetBranchId(fMvdStripBranch); Dist += dist; if( dist anglemin) } // end of if(fListHitTypeMvdTrackCand[imvdcand][jmvdhit] } // end of for( jmvdhit=0; jmvdhit0) { DIST[ngoodmix]=Dist/nn[ngoodmix]; ngoodmix++; //--------- stampaggi if(istampa>=3 ){cout<<"\tquesto Mvd candidato (n. ngoodmix = "<GetBranchId(fMvdPixelBranch)) { cout<<"\tPixel hit n. "<GetBranchId(fMvdStripBranch)){ cout<<"\tStrip hit n. "<anglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[i]-fXMvdPixel[fListMvdDSPixelHitNotTrackCand[jmvdhit]])* (fOx[i]-fXMvdPixel[fListMvdDSPixelHitNotTrackCand[jmvdhit]]) +(fOy[i]-fYMvdPixel[fListMvdDSPixelHitNotTrackCand[jmvdhit]])* (fOy[i]-fYMvdPixel[fListMvdDSPixelHitNotTrackCand[jmvdhit]]) ) -fR[i]); if(distGetBranchId(fMvdPixelBranch); DIST[ngoodmix] += dist; if( dist anglemin ) } // end of for( jmvdhit=0; jmvdhitanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[i]-fXMvdStrip[fListMvdDSStripHitNotTrackCand[jmvdhit]])* (fOx[i]-fXMvdStrip[fListMvdDSStripHitNotTrackCand[jmvdhit]]) +(fOy[i]-fYMvdStrip[fListMvdDSStripHitNotTrackCand[jmvdhit]])* (fOy[i]-fYMvdStrip[fListMvdDSStripHitNotTrackCand[jmvdhit]]) ) -fR[i]); if(distGetBranchId(fMvdStripBranch); DIST[ngoodmix] += dist; if( dist anglemin ) } // end of for( jmvdhit=0; jmvdhit0) { DIST[ngoodmix] /= nn[ngoodmix]; ngoodmix++; //--------- stampaggi if(istampa>=3){cout<<"\tevento n. "<GetBranchId(fMvdPixelBranch)) { cout<<"\tDS Pixel hit n. "<GetBranchId(fMvdStripBranch)){ cout<<"\tDS Strip hit n. "<0) //-------- now the US (upstream) Mvd hits nn[ngoodmix]=0; DIST[ngoodmix] = 0.; nHighQuality[ngoodmix]=0; for( jmvdhit=0; jmvdhitanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[i]-fXMvdPixel[fListMvdUSPixelHitNotTrackCand[jmvdhit]])* (fOx[i]-fXMvdPixel[fListMvdUSPixelHitNotTrackCand[jmvdhit]]) +(fOy[i]-fYMvdPixel[fListMvdUSPixelHitNotTrackCand[jmvdhit]])* (fOy[i]-fYMvdPixel[fListMvdUSPixelHitNotTrackCand[jmvdhit]]) ) -fR[i]); if(distGetBranchId(fMvdPixelBranch); DIST[ngoodmix] += dist; if( dist anglemin ) } // end of for( jmvdhit=0; jmvdhitanglemax){ angle -= 2.*PI; if( angle>anglemax) angle = anglemax; } else if (angle anglemin && angle < anglemax){ dist=fabs( sqrt( (fOx[i]-fXMvdStrip[fListMvdUSStripHitNotTrackCand[jmvdhit]])* (fOx[i]-fXMvdStrip[fListMvdUSStripHitNotTrackCand[jmvdhit]]) +(fOy[i]-fYMvdStrip[fListMvdUSStripHitNotTrackCand[jmvdhit]])* (fOy[i]-fYMvdStrip[fListMvdUSStripHitNotTrackCand[jmvdhit]]) ) -fR[i]); if(distGetBranchId(fMvdStripBranch); DIST[ngoodmix] += dist; if( dist anglemin ) } // end of for( jmvdhit=0; jmvdhit0) { DIST[ngoodmix] /= nn[ngoodmix]; ngoodmix++; //--------- stampaggi if(istampa>=3){cout<<"\tevento n. "<0) { for(int icc=0; iccGetBranchId(fMvdPixelBranch)) { cout<<"\tUS Pixel hit n. "<GetBranchId(fMvdStripBranch)){ cout<<"\tUS Strip hit n. "<0) //------- end of using the Mvd which are in no Mvd Track Candidate if(istampa>=3 ){cout<<"from PndTrkTracking2 : appena prima arbitration, IVOLTE = "<< IVOLTE<<", Stt track cand = "<& keepit, bool * keepit, Short_t FirstCandidate, Short_t LastCandidate, Double_t info[][7], Double_t Trajectory_Start[][2], // Vec & CHARGE, Short_t * CHARGE, Double_t SchosenSkew[][MAXSTTHITS] ) { Short_t ncand; for(ncand=FirstCandidate; ncand< LastCandidate; ncand++){ // for small radius trajectory better the ordering with conformal. if( fR[ncand]< RSTRAWDETECTORMAX/2.){ OrderingConformal_Loading_ListTrackCandHit( keepit, ncand, info, Trajectory_Start, CHARGE, SchosenSkew ); } else { // otherwise it is better distance from (0,0) method. OrderingR_Loading_ListTrackCandHit( keepit, ncand, info ); } } // end of for(ncand=FirstCandidate; ncand< LastCandidate; ncand++) return; } //----------end of function PndTrkTracking2::Ordering_Loading_ListTrackCandHit //----------begin of function PndTrkTracking2::OrderingR_Loading_ListTrackCandHit void PndTrkTracking2::OrderingR_Loading_ListTrackCandHit( bool* keepit, Short_t ncand, Double_t info[][7] ) { Short_t i, j, ipar, iskew; PndTrkMergeSort MergeSort; // ordering all the hits belonging to the candidate track, by increasing fR; // forming the new track with Mvd+Stt hits if(!keepit[ncand]) return; fnTrackCandHit[ncand] =fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand]+ fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; Short_t tempmvdindex[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ], tempmvdtype[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; Int_t auxIndex[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; Double_t auxR[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; // adding the Mvd hits (Pixel and Strips) for(i=0; i< fnMvdPixelHitsinTrack[ncand]; i++){ auxR[i] = fXMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]* fXMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]+ fYMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]* fYMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]; tempmvdindex[i]=fListMvdPixelHitsinTrack[ncand][i]; tempmvdtype[i]=0; auxIndex[i] = i; } for(i=0; i< fnMvdStripHitsinTrack[ncand]; i++){ auxR[i+fnMvdPixelHitsinTrack[ncand]] = fXMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]* fXMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]+ fYMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]* fYMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]; tempmvdindex[i+fnMvdPixelHitsinTrack[ncand]]= fListMvdStripHitsinTrack[ncand][i]; tempmvdtype[i+fnMvdPixelHitsinTrack[ncand]]=1; auxIndex[i+fnMvdPixelHitsinTrack[ncand]]= i+fnMvdPixelHitsinTrack[ncand]; } // ordering the Mvd Hits if( fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] >0){ MergeSort.Merge_Sort( fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand], auxR, auxIndex); // constructing the first part of the ordered new Track Candidate for(i=0; i< fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; i++){ fListTrackCandHit[ncand][i] = tempmvdindex[ auxIndex[i] ]; fListTrackCandHitType[ncand][i] = tempmvdtype[ auxIndex[i] ]; } } // end of if( fnMvdPixelHitsinTrack[ncand]+ // construction of the second part of the ordered new Track Candidate Short_t tempmvdindex2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ], tempmvdtype2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; Int_t auxIndex2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; Double_t auxR2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; for(i=0; i0){ MergeSort.Merge_Sort( fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand], auxR2, auxIndex2); for(j=0,ipar=0,iskew=0; j< fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand];j++){ i = j+fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; fListTrackCandHit[ncand][i] = tempmvdindex2[ auxIndex2[j] ]; fListTrackCandHitType[ncand][i] = tempmvdtype2[ auxIndex2[j] ]; if( fListTrackCandHitType[ncand][i]==2) { fListSttParHitsinTrack[ncand][ipar]=tempmvdindex2[auxIndex2[j]]; ipar++; } else { fListSttSkewHitsinTrack[ncand][iskew]=tempmvdindex2[auxIndex2[j]]; iskew++; } } } // end of if( fnSttParHitsinTrack[ncand]+ return; } //----------end of function PndTrkTracking2::OrderingR_Loading_ListTrackCandHit //----------begin of function PndTrkTracking2::OrderingSttSkewandSttParallel void PndTrkTracking2::OrderingSttSkewandSttParallel( Double_t oX, Double_t oY, Double_t Rr, Short_t nSkewhit, Short_t *ListSkewHits, Double_t *SList, // this is rekated to the skew hits. IMPORTANT : // the index must be the ORIGINAL skew hit number, // therefore SList[Infoskew[ListSkewHits[*]]]. Short_t Charge, Short_t nParHits, Short_t *ListParHits, Double_t *U, Double_t *V, Short_t *BigList // this is the final ordered Parallel+Skew list; // already in NATIVE hit number. ) { Short_t i, j, tmp[nSkewhit+nParHits], tmpList[nSkewhit]; Int_t index[nSkewhit+nParHits]; Double_t aaa, b1, sign, aux[nSkewhit+nParHits]; PndTrkMergeSort MergeSort; // here there is the ordering of the hits, under the assumption that the circumference // in XY goes through (0,0). // Moreover, the code before is supposed to have selected trajectories in XY with (fOx,fOy) // farther from (0,0) by > 0.9 * RminStrawDetector/2 and consequently fOx and fOy are not both 0. // The scheme for the ordering of the hit is as follows : // 1) order hits by increasing U of the conformal mapping; see Gianluigi's Logbook page 283; // 2) find the charge of the track by checking if it is closest to the center in XY // the first or the last of the ordered hits. // ordering of the hits aaa = atan2( oY, oX); // atan2 defined between -PI and PI. // the following statement is necessary since for unknown reason the root interpreter // gives a weird error when using PI directly in the if statement below!!!!!!! I lost // 2 hours trying to figure this out! b1 = PI/4.; if(aaa>b1&&aaa<3.*b1|| (aaa>-3.*b1&&aaa<-b1)){ // case #1 or #3;see Gianluigi's Logbook page 285. if( (aaa>b1&&aaa<3.*b1 && Charge == -1)||( aaa>-3.*b1&&aaa<-b1 && Charge == 1) ) { // for speeding up the ordering taking advantage // that the parallel hits were earlier ordered and // apply the trick of multiplying by -1. sign=-1.; } else { // normal calculation sign=1.; } for (j = 0 ; j< nParHits; j++){ aux[j] = sign*U[j]; } for (j = 0; j< nSkewhit; j++){ // this is U in conformal space aux[j+nParHits]=sign*(oX + Rr*cos(SList[ListSkewHits[j]]))/ (oX*oX+oY*oY+Rr*Rr + 2.*Rr* (oX*cos(SList[ListSkewHits[j]]) +oY*sin(SList[ListSkewHits[j]]))); } } else { // use V as ordering variable // [case 2 and 4 Gianluigi's Logbook page 285]. if( ((aaa<=-3.*b1|| aaa>=3.*b1) && Charge == -1) || ( -b1 <= aaa && aaa <= b1 && Charge == 1) ){ sign=-1.; } else { sign=1.; } for (j = 0 ; j< nParHits; j++){ aux[j] = sign*V[j]; } for (j = 0; j< nSkewhit; j++){ // this is V in conformal space. aux[j+nParHits]=sign*(oY + Rr*sin(SList[ListSkewHits[j]]))/ (oX*oX+oY*oY+Rr*Rr + 2.*Rr* (oX*cos(SList[ListSkewHits[j]]) +oY*sin(SList[ListSkewHits[j]]))); } } // end of if((aaa>b1&& .... for (j = 0 ; j< nParHits; j++){ BigList[j]=ListParHits[j]; index[j] = j; } for (j = 0; j< nSkewhit; j++){ BigList[j+nParHits]=ListSkewHits[j]; index[j+nParHits] = j+nParHits; } MergeSort.Merge_Sort( nSkewhit+nParHits, aux, index); for(i=0, j=0;i= nParHits ){ tmpList[j] = ListSkewHits[index[i]-nParHits]; j++; } } for(i=0;i 0.9 * RminStrawDetector/2 and consequently fOx and fOy are not both 0. // The scheme for the ordering of the hit is as follows : // 1) order hits by increasing U or V of the conformal mapping; see Gianluigi's Logbook page 283; // 2) find the charge of the track by checking if it is closest to the center in XY // the first or the last of the ordered hits. // 3) in case, invert the ordering of U, V and ListHits such that the first hits in the // list are always those closer to the Trajectory_Start. // ordering of the hits aaa = atan2( oY-Traj_Sta[1], oX-Traj_Sta[0]); // atan2 defined between -PI and PI. // the following statement is necessary since for unknown reason the root interpreter // gives a weird error when using PI directly in the if statement below!!!!!!! I lost // 2 hours trying to figure this out! b1 = PI/4.; if((aaa>b1&&aaa<3.*b1) || (aaa>-3.*b1&&aaa<-b1)){//use U as ordering variable; //[case 1 or 3 Gianluigi's Logbook page 285]. for (j = 0; j< nHits; j++){ bbb = XY[j][0]-Traj_Sta[0]; ccc = XY[j][1]-Traj_Sta[1]; U[j]= bbb/(bbb*bbb+ccc*ccc); } MergeSort.Merge_Sort( nHits, U, ListHits); if((aaa>b1&&aaa<3.*b1)){ // case #1; if( Charge == -1){ // inverting the order of the hits. for(i=0;ib1&&aaa<3.*b1)) } else { // use V as ordering variable [case 2 or 4 Gianluigi's Logbook page 285]. for (j = 0; j< nHits; j++){ bbb = XY[j][0]-Traj_Sta[0]; ccc = XY[j][1]-Traj_Sta[1]; V[j]= ccc/(bbb*bbb+ccc*ccc); } MergeSort.Merge_Sort( nHits, V, ListHits); if((aaa<=-3.*b1 || aaa>=3.*b1)){ // case #2; if( Charge == -1){ // inverting the order of the hits. for(i=0;ib1&& .... return; } //----------end of function PndTrkTracking2::OrderingUsingConformal //------------------ begin function PndTrkTracking2::RefitMvdStt void PndTrkTracking2::RefitMvdStt( Short_t nCandHit, Short_t *ListCandHit, Short_t *ListCandHitType, Double_t info[][7], Double_t rotationangle, // this is between 0. and 2*PI Double_t tv[2], Short_t iexcl, Double_t *pAlfa, // output of the fit Double_t *pBeta, // output of the fit Double_t *pGamma,// set at zero always for now bool *status // fit status; true = successful ) { bool Type; Short_t i, iparallel; Short_t exitstatus; Double_t dist2, mindis, emme, factor, gamma, qu, ErrorStraw = 0.03, ErrorMvd = 0.01, Xconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], Yconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], DriftRadiusconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], ErrorDriftRadiusconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK]; // PndTrkGlpkFits fit; // PndTrkLegendreFits fit; PndTrkChi2Fits fit; *status= false; factor=3.; mindis=0.5; for(i=0, iparallel=0; i 0, Type= true --> fit ok, it is a Circle in XY; // existatus > 0, Type= false --> fit ok, it is a Straigh Line in XY; // existatus < 0, fit failed; Type was set to false in this case; if( exitstatus > 0 && Type) *status=true; return; } //------------------ end function PndTrkTracking2::RefitMvdStt //------------------ begin function PndTrkTracking2::StoreSZ_MvdScitil void PndTrkTracking2::StoreSZ_MvdScitil(Short_t ncand) { Short_t i, k; // the Mvd Pixels hit for(i=0; i< fnMvdPixelHitsinTrack[ncand]; i++){ k=fListMvdPixelHitsinTrack[ncand][i]; fCandidatePixelZ[k] = fZMvdPixel[k]; fCandidatePixelS[k] = atan2( fYMvdPixel[k]-fOy[ncand],fXMvdPixel[k]-fOx[ncand]); if(fCandidatePixelS[k]<0.) fCandidatePixelS[k] +=2.*PI; // DriftRadius is set conventionally at -1, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be 0.5 cm; this is not unreasonable since to this // error the uncertainty on the Helix radius and center contributes; fCandidatePixelDriftRadius[k]=-1.; // the following error is conventional for the chi**2 type of fit; fCandidatePixelErrorDriftRadius[k]= 0.5 ; } // the Mvd Strips hit for(i = 0; i< fnMvdStripHitsinTrack[ncand]; i++){ k=fListMvdStripHitsinTrack[ncand][i]; fCandidateStripZ[k] = fZMvdStrip[k]; fCandidateStripS[k] = atan2( fYMvdStrip[k]-fOy[ncand],fXMvdStrip[k]-fOx[ncand]); if(fCandidateStripS[k]<0.) fCandidateStripS[k] +=2.*PI; // DriftRadius is set conventionally at -1, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be 1cm. fCandidateStripDriftRadius[k]=-1.; // the following error is conventional for the chi**2 type of fit; fCandidateStripErrorDriftRadius[k]= 0.5 ; } // the SciTil hit ( when they are 2, the fS_SciTilHitsinTrack is already a mean // of the two; then consider only 1 SciTil hit, the first, and make an average // of the two Z positions). if(fnSciTilHitsinTrack[ncand]==2){ fCandidateSciTilZ=0.5*(fposizSciTil[fListSciTilHitsinTrack[ncand][0]][2]+ fposizSciTil[fListSciTilHitsinTrack[ncand][1]][2]); fCandidateSciTilS = fS_SciTilHitsinTrack[ncand][0]; // DriftRadius is set conventionally at -2, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be DIMENSIONSCITIL/2. fCandidateSciTilDriftRadius=-2.; fCandidateSciTilErrorDriftRadius= DIMENSIONSCITIL/2.; ; } else if (fnSciTilHitsinTrack[ncand]==1){ fCandidateSciTilZ=fposizSciTil[fListSciTilHitsinTrack[ncand][0]][2]; fCandidateSciTilS = fS_SciTilHitsinTrack[ncand][0]; // DriftRadius is set conventionally at -2, for later use in the SZ fit; // the error on the point used in the fit is ErrorDriftRadius and this // is overestimated to be DIMENSIONSCITIL/2. fCandidateSciTilDriftRadius=-2.; fCandidateSciTilErrorDriftRadius= DIMENSIONSCITIL/2.; } return; } //------------------ end function PndTrkTracking2::StoreSZ_MvdScitil ClassImp(PndTrkTracking2)