// #include "glpk.h" #include "PndTrkTracking.h" #include "PndTrkBoundaryParStraws.h" #include "PndTrkChi2Fits.h" #include "PndTrkComparisonMCtruth.h" #include "PndTrkSttConformalFilling.h" // #include "PndTrkGlpkFits.h" #include "PndTrkLegendreFits.h" #include "PndTrkCleanup.h" #include "PndTrkCTFindTrackInXY.h" #include "PndTrkCTGeometryCalculations.h" #include "PndTrkMergeSort.h" #include "PndTrkPlotMacros.h" #include "PndTrkPrintouts.h" #include "PndTrkSttAdjacencies.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 "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 #include // definition of constants used in this class // integer constants #define MAXHITSINCELL 20 // the following MAXHITSINFIT cannot be too large because the fit // crashes 'silently' for too much memory consumption in the character arrays // or takes too long time; // MAXHITSINFIT has to be 12 when using the GLPK fitting procedure; there is no limitation // with the other type of fits; //#define MAXHITSINFIT 12 #define MAXHITSINFIT 50 #define MAXMVDMCPOINTS 2000 #define MAXSKEWHITSINFIT 8 #define MINIMUMHITSPERTRACK 3 #define MINOUTERHITSPERTRACK 5 #define TIMEOUT 60 // floating point constants #define APOTEMAMAXINNERPARSTRAW 23.246827 #define APOTEMAMAXSKEWSTRAW 31.517569 // delimitation of the skew area #define APOTEMAMINOUTERPARSTRAW 31.863369 #define APOTEMAMINSKEWSTRAW 23.246827 // delimitation of the skew area #define BFIELD 2. // in Tesla #define CVEL 2.99792 // velocity of light #define DELTAnR 2. //range of nR in TrkAssociatedParallelHitsToHelixquater #define DIAMETERSTRAWTUBE 1. #define DIMENSIONSCITIL 2.85 // cm #define ERRORPIXEL 0.02611 #define ERRORSTRIP 0.02611 #define ERRORSQPIXEL 0.00068175 #define ERRORSQSTRIP 0.00068175 #define PI 3.141592654 #define PMAX 100. #define RSTRAWDETECTORMAX 40.73 // maximum radius of the Stt detector in cm #define RSTRAWDETECTORMIN 16.119 // minimum radius of the Stt detector in cm #define STRAWRADIUS 0.5 #define STRAWRESOLUTION 0.015 #define STRAW_SKEW_INCLINATION 3. #define STTDRIFTVEL 0.0025 // in cm/nsec #define VERTICALGAP 4. // (cm) gap between Left and Right sections of detector. using namespace std; // ----- Default constructor ------------------------------------------- PndTrkTracking::PndTrkTracking() : FairTask("Tracking") { fPersistence = kTRUE; istampa = 0; iplotta = false; doMcComparison = false; fYesClean = false; fYesCleanMvd = true; fYesSciTil = false ; fMvdAloneTracking = false; fNevents_to_plot = 10; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking::PndTrkTracking(Int_t verbose) : FairTask("Tracking") { fPersistence = kTRUE; istampa = verbose; iplotta = false; doMcComparison = false; fYesClean = false; fYesCleanMvd = true; fYesSciTil = false ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking::PndTrkTracking(int istamp, bool iplot, bool imc) : FairTask("Tracking") { fPersistence = kTRUE; istampa = istamp; iplotta = iplot; doMcComparison = imc; fYesClean = false; fYesCleanMvd = true; fYesSciTil = false ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ------------------------------------------------------------------------- PndTrkTracking::PndTrkTracking(int istamp, bool iplot, bool imc, bool doSciTil) : FairTask("Tracking") { fPersistence = kTRUE; istampa = istamp; iplotta = iplot; doMcComparison = imc; fYesClean = false; fYesCleanMvd = true; fYesSciTil = doSciTil ; fMvdAloneTracking = false; Initialization_ClassVariables(); sprintf(fSttBranch,"STTHit"); sprintf(fMvdPixelBranch,"MVDHitsPixel"); sprintf(fMvdStripBranch,"MVDHitsStrip"); } // ----- Destructor ---------------------------------------------------- PndTrkTracking::~PndTrkTracking() {} // ------------------------------------------------------------------------- //--------------- begin PndTrkTracking::Initialization_ClassVariables void PndTrkTracking::Initialization_ClassVariables() { // this is only for initializing the Class Variables. size_t len; // booleans : len = sizeof(SingleHitListStt); memset (SingleHitListStt,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); // 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(fposizSciTil); memset (fposizSciTil,0,len); // 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 PndTrkTracking::Initialization_ClassVariables // ----- Public method Init -------------------------------------------- InitStatus PndTrkTracking::Init() { IVOLTE=-1; SEMILENGTH_STRAIGHT = 75.; ZCENTER_STRAIGHT = 35.; 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- PndTrkTracking::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 exetrnal of not; // true --> it is external; false --> it is internal; // remember that the numbering of the STT Straws starts at 1; PndTrkBoundaryParStraws BoundaryParStraws ; fExternal_Straws[0] = false; // just to be super-safe; for(int i=1;i<= NUMBER_STRAWS;i++){ fExternal_Straws[i] = BoundaryParStraws.Set(i); } //---------------------------------------------------- // get the MCTrack array fMCTrackArray = (TClonesArray*) ioman->GetObject("MCTrack"); if ( ! fMCTrackArray) { cout << "-E- PndTrkTracking::Init: No MCTrack array, return!" << 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 questi sono i MC point di STT fSttPointArray = (TClonesArray*) ioman->GetObject("STTPoint"); if ( ! fSttPointArray ) { cout << "-W- PndSttHelixHitProducer::Init: " << "No STTPoint array, return!" << endl; return kERROR; } // Get input array hit di STT after digi fSttHitArray = (TClonesArray*) ioman->GetObject(fSttBranch); // fSttHitArray = (TClonesArray*) ioman->GetObject("STTHit"); if ( ! fSttHitArray ) { cout << "-W- PndTrkTracking::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- PndTrkTracking::Init: " << "No MVD Pixel hitArray!" <GetObject(fMvdStripBranch); // fMvdStripHitArray = (TClonesArray*) ioman->GetObject("MVDHitsStrip"); if ( !fMvdStripHitArray){ cout << "-W- PndTrkTracking::Init: " << "No MVD Strip hitArray!" <GetObject("MVDRiemannTrackCand"); if ( !fMvdTrackCandArray){ cout << "-W- PndTrkTracking::Init: " << "No MVD TrackCand Array, return!" <GetObject("MVDPoint"); if ( !fMvdMCPointArray){ cout << "-W- PndTrkTracking::Init: " << "No MVD MC Point Array!" <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 = RSTRAWDETECTORMIN; A = (RSTRAWDETECTORMAX - r1)/NRDIVCONFORMAL; if ( NRDIVCONFORMAL > 1 ) { for(i = 1; i< NRDIVCONFORMAL ; i++){ r2 = r1 + A; fradiaConf[NRDIVCONFORMAL-i] = 1./r2; r1=r2; } } // load the adjacencies table for the Stt tubes; PndTrkSttAdjacencies Adjacent; Adjacent.CalculateAdjacentStt( NUMBER_STRAWS, fSttTubeArray, fnParContiguous, // output; number of contiguous straws (axial Stt); fListParContiguous // output list (axial Stt); ); return kSUCCESS; } // ------------------------------------------------------------------------- void PndTrkTracking::SetParContainers() { FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb(); fSttParameters = (PndGeoSttPar*) rtdb->getContainer("PndGeoSttPar"); } void PndTrkTracking::WriteHistograms(){ TFile* file = FairRootManager::Instance()->GetOutFile(); file->cd(); file->mkdir("PndTrkTracking"); file->cd("PndTrkTracking"); hdeltaRPixel->Write(); hdeltaRStrip->Write(); hdeltaRPixel2->Write(); hdeltaRStrip2->Write(); delete hdeltaRPixel; delete hdeltaRStrip; delete hdeltaRPixel2; delete hdeltaRStrip2; } // ----- Public method Exec -------------------------------------------- // ----- Public method Exec -------------------------------------------- void PndTrkTracking::Exec(Option_t* opt) { bool flag, intersect, outcome; //---------------------------------------------- bool tGoodSkewFit[MAXTRACKSPEREVENT], tkeepit[MAXTRACKSPEREVENT], tMvdhits[MAXTRACKSPEREVENT], tstatus[MAXTRACKSPEREVENT], tSttSZfit[MAXTRACKSPEREVENT]; Vec GoodSkewFit(tGoodSkewFit,MAXTRACKSPEREVENT,"GoodSkewFit"), keepit(tkeepit ,MAXTRACKSPEREVENT,"keepit"), Mvdhits(tMvdhits, MAXTRACKSPEREVENT,"Mvdhits"), status(tstatus, MAXTRACKSPEREVENT,"status"), SttSZfit(tSttSZfit, MAXTRACKSPEREVENT,"SttSZfit"); //---------------------------------------------- memset(tMvdhits,false,sizeof(tMvdhits)); 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 tRConformalIndex[MAXSTTHITS], // given a Hit number it gives its azimuthal box number tFiConformalIndex[MAXSTTHITS], ttempore[MAXSTTHITS], TemporarySkewList[2*MAXSTTHITS][2], BigList[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], // nBoxConformal, first index -> radial divisions, // 2nd index -> azimuthal divisions; n. of hits falling in this cell. tnBoxConformal[NRDIVCONFORMAL*NFIDIVCONFORMAL], tParalCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tParSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tHitsinBoxConformal[MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL], tCharge[MAXTRACKSPEREVENT], tdaTrackFoundaTrackMC[MAXTRACKSPEREVENT], tresultFitSZagain[MAXTRACKSPEREVENT], tstatusflag[MAXTRACKSPEREVENT]; 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"), statusflag(tstatusflag,MAXTRACKSPEREVENT,"statusflag"); //----------------------------------- Short_t nalone, ncand, nhitsinfit, Nint, NNN, nRemainingCandidates, npixelhitsintrack, nstriphitsintrack, nTotalCandidates, nXYZhits, i, iParHit, ipunto, j, k, kall, l ; Int_t iaccept, len, nSttHit, nSttMCPoint, nSttParHit, nSttSkewHit, nSttTrackCand ; 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, 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], TemporaryS[2*MAXSTTHITS], TemporaryZ[2*MAXSTTHITS], TemporaryZDrift[2*MAXSTTHITS], TemporaryZErrorafterTilt[2*MAXSTTHITS], temporeZErrorafterTilt[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], ZErrorafterTilt[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], ZErrorafterTiltfinal[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++; if(istampa>0) cout<GetEntriesFast(); } else { fnMvdPixelHit = 0; } if( fMvdStripHitArray ) { fnMvdStripHit = fMvdStripHitArray->GetEntriesFast(); } else { fnMvdStripHit = 0; } if(fnMvdPixelHit>MAXMVDPIXELHITS){ cout<<"from PndTrkTracking, fnMvdPixelHit is > maximum allowed (" <MAXMVDSTRIPHITS){ cout<<"from PndTrkTracking, fnMvdStripHit is > maximum allowed (" <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(); } // ------------------------------------------- extract info from HITS Strip MVD for( i= 0; i< fnMvdStripHit; i++){ pMvdStripHit = (PndSdsHit *) fMvdStripHitArray->At(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(); } // --------------- printout of Mvd Hits; if(istampa>=1) fPrint.stampaMvdHits( fMvdPixelBranch, fMvdStripBranch, fnMvdPixelHit, fnMvdStripHit, frefindexMvdPixel, frefindexMvdStrip, 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 PndTrkTracking : N. of MvdTrackCand = "<< fnMvdTrackCand<<" and it is > MAXMVDTRACKSPEREVENT (="<GetEntriesFast(); if (nSttMCPoint ==0){ if(istampa>0) cout<<"warning from PndTrkTracking : N. of Stt MC points = 0"<MAXSTTHITS){ cout<<"warning from PndTrkTracking : N. of Stt MC points = "< MAXSTTHITS ("<GetEntriesFast(); if (nSttHit ==0){ if (istampa >= 1) cout<<"warning from PndTrkTracking, evt "< MAXSTTHITS) { cout<<"warning from PndTrkTracking, evt "< MAXSTTHITS (="<= 1) { cout<<"from PndTrkTracking : n. total # Hits in STT : "<At(i); // right way to extract the corrisponding MC point. ipunto= pSttHit->GetRefIndex(); // tubeID = pSttHit->GetTubeID(); // fTubeID[i] = STT tubeID correspondint to the hit number i ; 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. MakeInclusionListStt(nSttHit, info); //----------------------------------- end of exclusion of straws with multiple hits //-------------------------------------------- fetch the SciTil hits fnSciTilHits = 0; if( fSciTHitArray != NULL){ // number SciTil hits/event fnSciTilHits = fSciTHitArray->GetEntriesFast(); if(fnSciTilHits>MAXSCITILHITS){ cout<<"from PndTrkTracking : 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>0) cout<<"da PndTrkTracking, 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<<"da PndTrkTracking SciTil n. "<<0<< " non purgato, Xpos "<< posiz.X()<<", Ypos "<< posiz.Y()<<", Zpos "<At(j); posiz = pPndSciTHit->GetPosition(); if(istampa>0)cout<<"da PndTrkTracking SciTil n. "<0){ cout<<"da PndTrkTracking, dopo purga di SciTil; n. hits = "<0 ) //-----------------------------------end fetching SciTil hits. //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- start the combined Mvd-Stt PR //------------------- //------------------- //------------------- //------------------- //------------------- // 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 ); fill.BoxConformalFilling( FiConformalIndex, HitsinBoxConformal, fInclusionListStt, infoparalConformal, fListSttParHits, MAXHITSINCELL, nBoxConformal, NFIDIVCONFORMAL, nSttParHit, NRDIVCONFORMAL, fradiaConf, RConformalIndex ); nSttTrackCand=0; // # tracks found //----- // class that finds the track (Stt hits only) in XY projection PndTrkCTFindTrackInXY SttTrackXYFinder; // struct necessary to pass all the parametrs to the PndTrkCTFindTrackInXY::FindTrackInXYProjection // method. Since these parameters are > 60, cint does NOT accept to pass them in the usual // way (parameters in the calling sequence) to PndTrkCTFindTrackInXY::FindTrackInXYProjection. FindTrackInXYProjection_InputData input; // loading those elements of the struct common to all the candidate tracks. input.apotemamaxskewstraw = APOTEMAMAXSKEWSTRAW; input.deltanr = DELTAnR; input.dimensionscitil = DIMENSIONSCITIL; input.FiConformalIndex = tFiConformalIndex; input.HitsinBoxConf = tHitsinBoxConformal; input.InclusionListStt = fInclusionListStt; input.InclusionListSciTil = fInclusionListSciTil; input.info = info; input.infoparalConformal = infoparalConformal; input.ListSttParHits = fListSttParHits; input.maxhitsinfit = MAXHITSINFIT; input.maxscitilhitsintrack = MAXSCITILHITSINTRACK; input.maxstthits = MAXSTTHITS; input.maxstthitsintrack = MAXSTTHITSINTRACK; input.minimumhitspertrack = MINIMUMHITSPERTRACK; input.minouterhitspertrack = MINOUTERHITSPERTRACK; input.nBoxConf = tnBoxConformal; input.nfidivconformal = NFIDIVCONFORMAL; input.nrdivconformal = NRDIVCONFORMAL; input.nSciTilHits = fnSciTilHits; input.nsttparhit = nSttParHit; input.posizSciT = fposizSciTil; input.radiaConf = fradiaConf; input.RConformalIndex = tRConformalIndex; input.rstrawdetectormax = RSTRAWDETECTORMAX; input.rstrawdetectormin = RSTRAWDETECTORMIN; input.strawradius = STRAWRADIUS; input.trajectory_vertex = trajectory_vertex; input.YesSciTil = fYesSciTil; //---------------------- //----- loop over the SciTil hits first; // 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; input.icounter=0; if(fYesSciTil) { for(i=0; i= MAXTRACKSPEREVENT ){ cout<<"from PndTrkTracking : # n. Tracks found so far = " <= MAXTRACKSPEREVENT ( = " < NFIDIVCONFORMAL ) { input.nFicell = NFIDIVCONFORMAL; } else if (input.nFicell<0) { input.nFicell = 0; } input.posizSciTilx = fposizSciTil[i][0]; input.posizSciTily = fposizSciTil[i][1]; // outputs from the FindTrackInXYProjection class are stored here; input.ALFA = &fALFA[nSttTrackCand]; input.BETA = &fBETA[nSttTrackCand]; input.Charge = &Charge[nSttTrackCand]; input.Fi_final_helix_referenceframe = &Fi_final_helix_referenceframe[nSttTrackCand]; input.Fi_initial_helix_referenceframe = &Fi_initial_helix_referenceframe[nSttTrackCand]; input.Fi_low_limit = &Fi_low_limit[nSttTrackCand]; input.Fi_up_limit = &Fi_up_limit[nSttTrackCand]; input.GAMMA = &fGAMMA[nSttTrackCand]; input.ListHitsinTrack = &fListSttParHitsinTrack[nSttTrackCand][0]; input.ListSciTilHitsinTrack = &fListSciTilHitsinTrack[nSttTrackCand][0]; input.nHitsinTrack = &fnSttParHitsinTrack[nSttTrackCand]; input.nSciTilHitsinTrack = &fnSciTilHitsinTrack[nSttTrackCand]; input.Oxx = &fOx[nSttTrackCand]; input.Oyy = &fOy[nSttTrackCand]; input.Rr = &fR[nSttTrackCand]; input.S_SciTilHitsinTrack = &fS_SciTilHitsinTrack[nSttTrackCand][0]; input.TypeConf = &fTypeConf[nSttTrackCand]; input.U = &U[nSttTrackCand][0]; input.V = &V[nSttTrackCand][0]; input.icounter++; // this is the plot number; outcome = SttTrackXYFinder.FindTrackInXYProjection(&input); if(!outcome){ continue; } for(j=0; j= MAXTRACKSPEREVENT) { cout<<"from PndTrkTracking : # n. Tracks found so far = " <= MAXTRACKSPEREVENT ( = " <=2){ cout<<"from PndTrkTracking, before Ordering, after primo loop sui paralleli.\n"; cout<<"\tevt. n. "< Fi_low_limit and // possibly > 2PI. &statusflag[ncand],//it is a vector; =0, all well; =1, track contained completely between RMin // and RMax; = -1 track contained within RMin; =-2 track outside RMax. RSTRAWDETECTORMIN, RSTRAWDETECTORMAX ); if( statusflag[ncand] == -1) { Fi_low_limit[ncand] = -99999.; } else if (statusflag[ncand] == -2){ keepit[ncand] = false; }; } // end of for( ncand= 0; ncand< nSttTrackCand; ncand++) //--------------------- here call to the function that matches Mvd hits with Stt tracks delta=0.5; // parameter of proximity for associating Mvd hits to Stt tracks highqualitycut=0.2; // parameter of proximity for associating Mvd hits to Stt tracks // This method matches the Mvd hits to the found tracks. MatchMvdHitsToSttTracks( keepit,// input and output. delta, highqualitycut, nSttTrackCand, FI0, Fi_low_limit, Charge, fnMvdPixelHitsinTrack, // output fListMvdPixelHitsinTrack, // output fnMvdStripHitsinTrack, // output fListMvdStripHitsinTrack // output ); //-------------- stampa if(istampa>=2){ cout<<"dopo MatchMvdHitsToSttTracks[1646], evt. "< MAXMVDPIXELHITSINTRACK){ cout<<"from PndTrkTracking, fnMvdPixelHitsinTrack["< MAXMVDPIXELHITSINTRACK (" < MAXMVDSTRIPHITSINTRACK){ cout<<"from PndTrkTracking, fnMvdStripHitsinTrack["< MAXMVDSTRIPHITSINTRACK (" <=2){ fPrint.stampetta( IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], &fListSttParHitsinTrack[0][0],&fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack,fnSttSkewHitsinTrack, fnSciTilHitsinTrack,nSttTrackCand,-1,MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //--------------------- refit the Helix in XY plane using Stt + Mvd associated hits Short_t iexcl; Double_t d, diff, rotationangle; for(ncand=0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; if( !Mvdhits[ncand]) continue; // Py/Px = m in v = m*u + q formula rotationangle= atan2( Charge[ncand]*fOx[ncand],-Charge[ncand]*fOy[ncand]); // Py/Px = m in if( rotationangle<0. ) rotationangle += 2.*PI; //---------- translation of the reference system in the best Mvd hit position for(i=0, diff = 1.e20;i Pixel; = 1 --> Strip; = 2 Stt parallel; 3 = Stt Skew. // There are no -1 type hits at this point. if(!(fListTrackCandHitType[ncand][i]==1 || fListTrackCandHitType[ncand][i]==0) ) continue; if( fListTrackCandHitType[ncand][i] == 0 ){ d = fabs( sqrt( (fOx[ncand]-fXMvdPixel[fListTrackCandHit[ncand][i]]) *(fOx[ncand]-fXMvdPixel[fListTrackCandHit[ncand][i]]) +(fOy[ncand]-fYMvdPixel[fListTrackCandHit[ncand][i]]) *(fOy[ncand]-fYMvdPixel[fListTrackCandHit[ncand][i]]) ) - fR[ncand]); if( d < diff ){ diff = d; iexcl=i; trajectory_vertex[0]= fXMvdPixel[fListTrackCandHit[ncand][i]]; trajectory_vertex[1]= fYMvdPixel[fListTrackCandHit[ncand][i]]; } } else { d = fabs( sqrt( (fOx[ncand]-fXMvdStrip[fListTrackCandHit[ncand][i]]) *(fOx[ncand]-fXMvdStrip[fListTrackCandHit[ncand][i]]) +(fOy[ncand]-fYMvdStrip[fListTrackCandHit[ncand][i]]) *(fOy[ncand]-fYMvdStrip[fListTrackCandHit[ncand][i]]) ) - fR[ncand]); if( d < diff ){ diff = d; iexcl=i; trajectory_vertex[0]= fXMvdStrip[fListTrackCandHit[ncand][i]]; trajectory_vertex[1]= fYMvdStrip[fListTrackCandHit[ncand][i]]; } } } // end of for(i=0, diff = 1.e20;i<..... if( diff > 0.5 ) { trajectory_vertex[0]=trajectory_vertex[1]=0.; iexcl=-1; } //---------------- inizio stampe. if(istampa>=2){ if(iexcl!= -1){ cout<<"from PndSttMvdTracking, evt. "<0){ //--------------------- here call to the function that matches Mvd hits with the new // circular trajectory in XY found for the second time, after first refit delta=0.5; // parameter of proximity for associating Mvd hits to Stt tracks // highqualitycut=0.3; // parameter of proximity for associating Mvd hits to Stt tracks highqualitycut=0.5; // parameter of proximity for associating Mvd hits to Stt tracks MatchMvdHitsToSttTracksagain( keepit, Mvdhits, delta, highqualitycut, nSttTrackCand, FI0, Fi_low_limit, // because here we deal with hits in Mvd region Charge, fnMvdPixelHitsinTrack, // input and output fListMvdPixelHitsinTrack, // input and output fnMvdStripHitsinTrack, // input and output fListMvdStripHitsinTrack // input and output ); } // end of if(fnMvdPixelHit+fnMvdStripHit>0) //--------------------- // check if the track candidate has still at least 2 axial hits; for(ncand=0; ncand< nTotalCandidates; ncand++) { if( fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+fnSttParHitsinTrack[ncand]<2) keepit[ncand]=false; } // end of for(ncand=0; ncand< nTotalCandidates; ncand++) //--------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo il Match Again.\n"; fPrint.stampetta(IVOLTE,tkeepit,&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( statusflag[ncand] == -1 ) continue; // this is when the XY circle is contained in the // the Mvd region completely; skip the association of // the Skews. // the arrays Temporary.... 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], TemporarySkewList, // output : TemporarySkewList[*][0] = list of selected skew hits // numbers(in skew numbering); // TemporarySkewList[*][1] = solution number (0 or 1) as per // the calculateintersections method; // the info on TemporaryS, TemporaryZ, TemporaryZDrift, TemporaryZErrorafterTilt 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; TemporaryS, // output, S coordinate of selected Skew hit TemporaryZ, // output, Z coordinate of selected Skew hit (center wire) TemporaryZDrift, // output, drift distance IN Z DIRECTION only, of selected Skew hit TemporaryZErrorafterTilt // 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;\n";fPrint.stampetta(IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0], &fListMvdStripHitsinTrack[0][0],&fListSttParHitsinTrack[0][0], &fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0],fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack, fnSttSkewHitsinTrack,fnSciTilHitsinTrack,nSttTrackCand, ncand, // print the candidate ncand; MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK,MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa // calculate the number of hits to use in the SZ fit later; // nXYZhits = n. of Mvd hits + SciTil hits. However, if there are 2 SciTil // hits in this track (namely two adjacent SciTil tiles have a hit // caused PRESUMABLY by the same track) then count them AS ONE because below // the average of their postions is considered ! if( fnSciTilHitsinTrack[ncand] == 2) { nXYZhits = fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+ 1; }else{ // in this case fnSciTilHitsinTrack[ncand] is 0 or 1; nXYZhits = fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+ fnSciTilHitsinTrack[ncand]; } // calculate if there is the need of using some skew hits in the subsequent SZ fit; // put in nhitsinfit the number of hits used in the subsequent SZ fit. // the following is valid only for GLPK fits; if(YesGLPKfitSZ) { // flag for the GLPK choice of fit; if( nXYZhits <=2){ fnSttSkewHitsinTrack[ncand]<5 ? nhitsinfit = nXYZhits + fnSttSkewHitsinTrack[ncand] : nhitsinfit = nXYZhits + 5 ; // 1 0 2 XYZ hit + 5 Skew hits. } else { nhitsinfit= nXYZhits; } } else { // other fit choice; // the following is valid for non-GLPK fits; nhitsinfit = nXYZhits + fnSttSkewHitsinTrack[ncand]; } // end of if(YesGLPKfitSZ) // the following is a protection against declaration of 0 dimension array; int dime ; if(nhitsinfit>0) dime = nhitsinfit ; else dime=1; //--------------------- 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. // load the quantities needed for the SZ fit; LoadSZetc_forSZfit( ncand, // input nhitsinfit, TemporaryS, // input TemporaryZ, // input TemporaryZDrift, // input TemporaryZErrorafterTilt, // input YesGLPKfitSZ, // input ErrorDriftRadius, // output ErrorDriftRadiusbis, // output DriftRadius, // output DriftRadiusbis, // output S, // output Sbis, // output ZED, // output ZEDbis // output ); // --------------- fit in SZ with Mvd + SciTil only // finding if there are discontinuity at 0 for fi value of the Mvd Hit. // In case of discontinuity at 0, add 2*PI to fi of those hits with fi in the 1st quadrant. // This is necessary because the discontinuities would make the fit // in the SZ plane fail. // In this discontinuity fixing, the value FI0 of the vertex (0,0) is also included. // If there is discontinuity fixing, the values of S[i] might be modified (+2.*PI). FixDiscontinuitiesFiangleinSZplane( nhitsinfit, S, // S can be modified by +-2*PI if necessary. &FI0[ncand], // this remains unchanged. Charge[ncand] // this remains unchanged. ); //-------------- stampa if(istampa>=2){ cout<<"\tstampa prima di FitSZspace, [non in Mvd track section] .\n"; fPrint.stampetta( IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], &fListSttParHitsinTrack[0][0],&fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack,fnSttSkewHitsinTrack, fnSciTilHitsinTrack,nSttTrackCand,ncand,MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //--------------------- here do the fit again in the SZ space if there are Mvd hits. // For this, reordering of the Mvd hits is not necessary. if(nhitsinfit>0){ resultFitSZagain[ncand] = fit.FitSZspace( 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 // number of the accumulation plot. ); //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo FitSZspace, [not in Mvd track section], result (1 va bene) = " <0) keepit[ncand]=false; GoodSkewFit[ncand] = false; } // end of if(nhitsinfit>0) //------------------------------------------- // use the risult just obtained from the fit in SZ to reject the spurious Skew Straw hits // and the Mvd spurious hits; also in this function there is the calculation of the Z position // of the SKEW hits and the MVD hits, for a given track candidate (ie for a given Helix // circle in the XY plane) Short_t MaxTurns; Double_t Turns; if(keepit[ncand]){ if(fR[ncand] < RSTRAWDETECTORMAX/2.){ if(-Charge[ncand]*KAPPA[ncand]>0.){ // this means Pz>0. Turns= 0.5*fabs((ZCENTER_STRAIGHT+SEMILENGTH_STRAIGHT) *KAPPA[ncand])/PI; if( fabs(Turns)<10.) MaxTurns=(Short_t) Turns ; else MaxTurns=10; } else { Turns= 0.5*fabs((ZCENTER_STRAIGHT-SEMILENGTH_STRAIGHT) *KAPPA[ncand])/PI; if( fabs(Turns)<10.) MaxTurns=(Short_t) Turns ; else MaxTurns=10; } } else { MaxTurns=0; } EliminateSpuriousSZ( MaxTurns, &fnMvdPixelHitsinTrack[ncand], // input and output &fListMvdPixelHitsinTrack[ncand][0],// input and output &fnMvdStripHitsinTrack[ncand], // input and output &fListMvdStripHitsinTrack[ncand][0],// input and output &fnSttSkewHitsinTrack[ncand], // input and output &fListSttSkewHitsinTrack[ncand][0],// input and output Sbis, // input, position of the central wire on the Helix cylinder; ZEDbis, // input, position of the central wire on the Helix cylinder. DriftRadiusbis, // input ErrorDriftRadiusbis, // input &SchosenPixel[ncand][0], // this value from now on &SchosenStrip[ncand][0], // can also be > 2PI or < 2PI when &SchosenSkew[ncand][0], // 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 if(keepit[ncand]) //------------------------ //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo EliminateSpuriousSZ, [non in Mvd track section] .\n"; fPrint.stampetta( IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], &fListSttParHitsinTrack[0][0],&fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack,fnSttSkewHitsinTrack, fnSciTilHitsinTrack,nSttTrackCand,ncand,MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //-------------------------------------------------------------------------- // redo fit after spurious cleaning; // recalculate the input values with the new list of hits // belonging to this track cand; /* resultFitSZagain[ncand] = fit.FitSZspace( nhitsinfit, // n. hits to be fitted tS, tZED, tDriftRadius, tErrorDriftRadius, FI0[ncand], MAXSKEWHITSINFIT,// maximum number of STT Skew hits in fit; &emme, 0 // number of the accumulation plot;no meaning // here for this type of fit; ); if( resultFitSZagain[ncand]==1){ KAPPA[ncand] = emme; GoodSkewFit[ncand] = true; if( ncand<= nSttTrackCand ) SttSZfit[ncand]=true; } else { keepit[ncand]=false; GoodSkewFit[ncand] = false; } // redo the spurious cleaning after the second iteration SZ fit; if(keepit[ncand]){ if(fR[ncand] < RSTRAWDETECTORMAX/2.){ if(-Charge[ncand]*KAPPA[ncand]>0.){ // this means Pz>0. Turns= 0.5*fabs((ZCENTER_STRAIGHT+SEMILENGTH_STRAIGHT) *KAPPA[ncand])/PI; if( fabs(Turns)<10.) MaxTurns=(Short_t) Turns ; else MaxTurns=10; } else { Turns= 0.5*fabs((ZCENTER_STRAIGHT-SEMILENGTH_STRAIGHT) *KAPPA[ncand])/PI; if( fabs(Turns)<10.) MaxTurns=(Short_t) Turns ; else MaxTurns=10; } } else { MaxTurns=0; } EliminateSpuriousSZ( MaxTurns, &fnMvdPixelHitsinTrack[ncand], // input and output &fListMvdPixelHitsinTrack[ncand][0],// input and output &fnMvdStripHitsinTrack[ncand], // input and output &fListMvdStripHitsinTrack[ncand][0],// input and output &fnSttSkewHitsinTrack[ncand], // input and output &fListSttSkewHitsinTrack[ncand][0],// input and output Sbis, // input, position of the central wire on the Helix cylinder; ZEDbis, // input, position of the central wire on the Helix cylinder. DriftRadiusbis, // input ErrorDriftRadiusbis, // input &SchosenPixel[ncand][0], // this value from now on &SchosenStrip[ncand][0], // can also be > 2PI or < 2PI when &SchosenSkew[ncand][0], // 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 if(keepit[ncand]) */ //------------------------ //-------------------------------------------------------------------------- // First cleanup based on the absence of Mvd hits if(fYesCleanMvd){ // reject the candidate if it is NOT contained in the pipe and // therefore it should have at least 1 Mvd hit but it has none. if( (!GeomCalculator.IsInTargetPipe( fOx[ncand], fOy[ncand], fR[ncand], FI0[ncand], KAPPA[ncand], Charge[ncand], VERTICALGAP/2.) ) && fnMvdStripHitsinTrack[ncand]+fnMvdPixelHitsinTrack[ncand]==0) { keepit[ncand]=false; } } // end of (fYesCleanMvd) } // end of for(ncand=0; ncand< nTotalCandidates; ncand++) // In case some candidate track were not processed in the previous loop, there might // be still GoodSkewFit[ncand] = false; in that case the candidate track is rejected // because it has no information on KAPPA; for(ncand=0; ncand< nTotalCandidates; ncand++){ if(!GoodSkewFit[ncand]) keepit[ncand]=false; } //-------- //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo il Cleanup piccolo\n"; fPrint.stampetta( IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], &fListSttParHitsinTrack[0][0],&fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack,fnSttSkewHitsinTrack, fnSciTilHitsinTrack,nSttTrackCand,-1,MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //--- redo association of parallel Stt straw hits to this track, after better refit. if(fnMvdPixelHit+fnMvdStripHit>0){ CollectParSttHitsagain( keepit, Mvdhits, info, nSttParHit, 0, // starting candidate n. (included). nTotalCandidates, // ending candidate n. (excluded). KAPPA, FI0, Fi_low_limit, Fi_up_limit, fnSttParHitsinTrack, // input and output fListSttParHitsinTrack // input and output ); //------------------------------- 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++) //--------------- //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo CollectParSttHitsagain\n"; fPrint.stampetta( IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], &fListSttParHitsinTrack[0][0],&fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack,fnSttSkewHitsinTrack, fnSciTilHitsinTrack,nSttTrackCand,-1,MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa } // end of if(fnMvdPixelHit+fnMvdStripHit>0 //--------------------- end of the section where the Mvd hits are added to the track candidates // the following is valid for all tracks; // ordering all the hits belonging to the candidate track, by increasing fR (large // trajectories) or Conformal variables (better for small trajectories); // from candidate n. 0 to candidate n. nTotalCandidates-1; loading fListTrackCandHit. // the array ordered are : // fListTrackCandHit, fListTrackCandHitType, fListSttParHitsinTrack, fListSttSkewHitsinTrack // and also at the end the SciTil hit (if present) is added. Ordering_Loading_ListTrackCandHit( keepit, 0, nTotalCandidates, info, Trajectory_Start, Charge, SchosenSkew ); // adding at the end the SciTil hits (if present). for(ncand=0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; i=fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+ fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand]; for(j=0;j=2){ cout<<"\tstampa prima del Cleanup grosso\n"; fPrint.stampetta(IVOLTE,tkeepit,&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 for(ncand=0, nRemainingCandidates=0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; Short_t &nHitsPar = fnSttParHitsinTrack[ncand]; Short_t &nHitsSkew = fnSttSkewHitsinTrack[ncand]; Double_t auxS[nHitsSkew]; for(i=0;i1) cout<<"PndTrkTracking, entra in TrackCleanup "<< "tracce normali, IVOLTE "<0) { // load the UsedPixel and UsedStrip vectors. bool UsedPixel[MAXMVDPIXELHITS], UsedStrip[MAXMVDSTRIPHITS]; Short_t List[MAXMVDPIXELHITS+MAXMVDSTRIPHITS], ListType[MAXMVDPIXELHITS+MAXMVDSTRIPHITS]; Double_t centrex, centrey, radius; for(i=0;i= MAXTRACKSPEREVENT -1 ) break; // protection for the // length of many arrays. nalone=0; npixelhitsintrack=0; nstriphitsintrack=0; for(j=0;jGetBranchId(fMvdPixelBranch)){ if(UsedPixel[ fListHitMvdTrackCand[i][j] ]) continue; if(npixelhitsintrack>MAXMVDPIXELHITSINTRACK) continue; AloneX[nalone] = fXMvdPixel[ fListHitMvdTrackCand[i][j] ]; AloneY[nalone] = fYMvdPixel[ fListHitMvdTrackCand[i][j] ]; List[nalone] = fListHitMvdTrackCand[i][j]; ListType[nalone] = 0; nalone++; npixelhitsintrack++; }else {// at this point this is a Strip hit; already made sure // earlier in the code that there is no third possibility. // if (fListHitTypeMvdTrackCand[i][j] == // this condition in principle at this // // point is always satisfied. // FairRootManager::Instance()->GetBranchId(fMvdStripBranch)){ if(UsedStrip[ fListHitMvdTrackCand[i][j] ]) continue; if(nstriphitsintrack>MAXMVDSTRIPHITSINTRACK) continue; AloneX[nalone] = fXMvdStrip[ fListHitMvdTrackCand[i][j] ]; AloneY[nalone] = fYMvdStrip[ fListHitMvdTrackCand[i][j] ]; List[nalone] = fListHitMvdTrackCand[i][j]; ListType[nalone] = 1; nalone++; nstriphitsintrack++; } } // end of for(j=0;j RSTRAWDETECTORMIN/2.){ fOx[nTotalCandidates] = centrex; fOy[nTotalCandidates] = centrey; fR[nTotalCandidates] = radius; FI0[nTotalCandidates] = atan2(-fOy[nTotalCandidates], -fOx[nTotalCandidates]); if( FI0[nTotalCandidates] < 0. ) FI0[nTotalCandidates]+= 2.*PI; fnSttParHitsinTrack[nTotalCandidates]=0; fnSttSkewHitsinTrack[nTotalCandidates]=0; fnMvdPixelHitsinTrack[nTotalCandidates]=0; fnMvdStripHitsinTrack[nTotalCandidates]=0; for(j=0; j=2){ cout<<"from PndSttMvdTracking, evt. "<=fnMvdPixelHit ){ cout<<"from PndTrkTracking, problem event "<=fnMvdStripHit ){ cout<<"from PndTrkTracking, problem event "<=nSttHit ){ cout<<"from PndTrkTracking, problem event "<=nSttHit ){ cout<<"from PndTrkTracking, problem event "<=fnSciTilHits ){ cout<<"from PndTrkTracking, problem event "< 0){ // make the struct for the data to pass to the // method PndTrkComparisonMCtruth::ComparisonwithMC ; PndTrkComparisonMCtruth_io_Data ioData; // load the structure; ioData.Bfield = BFIELD; ioData.Charge = tCharge; ioData.Cvel = CVEL; ioData.daTrackFoundaTrackMC = tdaTrackFoundaTrackMC; ioData.DIMENSIONSciTil = DIMENSIONSCITIL; ioData.Errorsqpixel = ERRORSQPIXEL; ioData.Errorsqstrip = ERRORSQSTRIP; ioData.FI0 = FI0; ioData.fMCTrackArray = fMCTrackArray; ioData.fMvdMCPointArray = fMvdMCPointArray; ioData.fSciTilMaxNumber = fSciTilMaxNumber; ioData.fSciTHitArray = fSciTHitArray; ioData.fSciTPointArray = fSciTPointArray; ioData.fSttPointArray = fSttPointArray; ioData.HANDLE = HANDLE, ioData.HANDLE2 = HANDLE2, ioData.info = &info[0][0]; ioData.istampa = istampa; ioData.IVOLTE = IVOLTE; ioData.KAPPA = KAPPA; ioData.keepit = tkeepit; ioData.InclusionListStt = fInclusionListStt; ioData.ListMvdPixelHitsinTrack = &fListMvdPixelHitsinTrack[0][0]; ioData.ListMvdStripHitsinTrack = &fListMvdStripHitsinTrack[0][0]; ioData.ListSciTilHitsinTrack = &fListSciTilHitsinTrack[0][0]; ioData.ListSttParHitsinTrack = &fListSttParHitsinTrack[0][0]; ioData.ListSttSkewHitsinTrack = &fListSttSkewHitsinTrack[0][0]; ioData.ListTrackCandHit = &fListTrackCandHit[0][0]; ioData.ListTrackCandHitType = &fListTrackCandHitType[0][0]; ioData.MAXMCTRACKS = MAXMCTRACKS; ioData.MAXMVDPIXELHITS = MAXMVDPIXELHITS; ioData.MAXMVDPIXELHITSINTRACK = MAXMVDPIXELHITSINTRACK; ioData.Maxmvdmcpoints = MAXMVDMCPOINTS; ioData.MAXMVDSTRIPHITS = MAXMVDSTRIPHITS; ioData.MAXMVDSTRIPHITSINTRACK = MAXMVDSTRIPHITSINTRACK; ioData.MAXSCITILHITS = MAXSCITILHITS ; ioData.MAXSCITILHITSINTRACK = MAXSCITILHITSINTRACK; ioData.MAXSTTHITS = MAXSTTHITS; ioData.MAXSTTHITSINTRACK = MAXSTTHITSINTRACK; ioData.MAXTRACKSPEREVENT = MAXTRACKSPEREVENT; ioData.MCMvdPixelAloneList = MCMvdPixelAloneList; ioData.MCMvdStripAloneList = MCMvdStripAloneList; ioData.MCParalAloneList = MCParalAloneList; ioData.MCSciTilAloneList = MCSciTilAloneList; ioData.MCSkewAloneList = MCSkewAloneList; ioData.MCSkewAloneX = fMCSkewAloneX ; ioData.MCSkewAloneY = fMCSkewAloneY ; ioData.MvdPixelCommonList = MvdPixelCommonList; ioData.MvdPixelSpuriList = MvdPixelSpuriList; ioData.MvdStripCommonList = MvdStripCommonList; ioData.MvdStripSpuriList = MvdStripSpuriList; ioData.nHitsInMCTrack = tnHitsInMCTrack; ioData.nHitsInSciTile = nHitsInSciTile; ioData.nMCMvdPixelAlone = nMCMvdPixelAlone; ioData.nMCMvdStripAlone = nMCMvdStripAlone; ioData.nMCParalAlone = tnMCParalAlone; ioData.nMCSciTilAlone = nMCSciTilAlone; ioData.nMCSkewAlone = tnMCSkewAlone; ioData.nMvdPixelCommon = nMvdPixelCommon; ioData.nMvdPixelHitsinTrack = fnMvdPixelHitsinTrack; ioData.nMvdStripHitsinTrack = fnMvdStripHitsinTrack; ioData.nMvdPixelHit = fnMvdPixelHit; ioData.nMvdPixelSpuriinTrack = nMvdPixelSpuriinTrack; ioData.nMvdStripCommon = nMvdStripCommon; ioData.nMvdStripHit = fnMvdStripHit; ioData.nMvdStripSpuriinTrack = nMvdStripSpuriinTrack; ioData.nParalCommon = tnParalCommon; ioData.nSciTilCommon = nSciTilCommon; ioData.nSciTilHits = fnSciTilHits; ioData.nSciTilHitsinTrack = fnSciTilHitsinTrack ; ioData.nSciTilSpuriinTrack = nSciTilSpuriinTrack ; ioData.nSkewCommon = tnSkewCommon; ioData.nSkewHitsInMCTrack = tnSkewHitsInMCTrack; ioData.nSpuriParinTrack = tnSpuriParinTrack; ioData.nSpuriSkewinTrack = tnSpuriSkewinTrack; ioData.nSttHit = nSttHit; ioData.nSttParHitsinTrack = fnSttParHitsinTrack; ioData.nSttSkewHitsinTrack = fnSttSkewHitsinTrack; ioData.nTotalCandidates = nTotalCandidates; ioData.OriginalSciTilList = &OriginalSciTilList[0][0]; ioData.Ox = fOx; ioData.Oy = fOy; ioData.ParalCommonList = tParalCommonList; ioData.ParSpuriList = tParSpuriList; ioData.R = fR; ioData.refindexMvdPixel = frefindexMvdPixel; ioData.refindexMvdStrip = frefindexMvdStrip; ioData.resultFitSZagain = tresultFitSZagain; ioData.SciTilCommonList = SciTilCommonList; ioData.SciTilSpuriList = SciTilSpuriList; ioData.SkewCommonList = tSkewCommonList; ioData.SkewSpuriList = tSkewSpuriList; ioData.SttSZfit = tSttSZfit; ioData.XMvdPixel = fXMvdPixel; ioData.XMvdStrip = fXMvdStrip; ioData.XSciTilCenter = fpSciTilx; ioData.YMvdPixel = fYMvdPixel; ioData.YMvdStrip = fYMvdStrip; ioData.YSciTilCenter = fpSciTily; ioData.ZMvdPixel = fZMvdPixel; ioData.ZMvdStrip = fZMvdStrip; ioData.ZSciTilCenter = fpSciTilz; // class for the MC comparison; PndTrkComparisonMCtruth cmp; fnMCTracks = cmp.ComparisonwithMC( ioData); } //---------- // write the Macro for visualization of tracks and hits; if(iplotta && IVOLTE< fNevents_to_plot){ // the following initialization is necessary when the MC comparison // is not done just above (when doMcComparison=false). In this case // in fact it is necessary to have the arrays nParalCommon, nSpuriParinTrack etc.etc. // set at 0 otherwise some WriteMacro methods crash; if(!doMcComparison){ for(i=0; i0) { 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] 1.e-10){ Tiltdirection1[0] = vz1/bbb; Tiltdirection1[1] = SkewInclWithRespectToS/bbb; } else { Tiltdirection1[0] = 1.; Tiltdirection1[1] = 0.; } LL = fabs(vx1*Rx + vy1*Ry); if( LL < 1.e-10) continue; Aellipsis1 = info[i][3]*aaa/LL; Bellipsis1 = info[i][3]/Rr; Tilted_Radius = STRAWRADIUS*aaa/LL; // info[i][4] = semilength of the wire; // the following statement adds some margin to take into account the imprecision in the determination // of the Helix radius; dista = 2.*Aellipsis1 > Tilted_Radius ? Tilted_Radius : 2.*Aellipsis1; if( distance >= info[i][4]+ dista ){ continue; } // store S, Z, ZDrift, ZErrorafterTilt 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; location = i + ii*MAXSTTHITS; S[location] = atan2(POINTS1[j+1]-Oyy, POINTS1[j]-Oxx) ; // atan2 returns radians in (-pi and +pi] if( S[location] < 0.) S[location] += 2.*PI; if( S[location] < Fi_low_limit) { if( S[location]+2.*PI > Fi_up_limit) continue; } else if( S[location] > Fi_up_limit) { if( S[location]- 2.*PI < Fi_low_limit) continue; } //--------------------------- end check Z[location] = POINTS1[j+2]; ZDrift[location] = Aellipsis1*Tiltdirection1[0]; ZErrorafterTilt[location] = 0.02*aaa*Tiltdirection1[0]/LL; // the list of the selected Skew skew hits instead, is stored sequentially; SkewList[NAssociated][0] = i; // n. skew hit in original hit numbering SkewList[NAssociated][1] = ii; // solution 0 or solution 1 were accepted // check if this skew hit doesn't "push out" the most external parallel hit // (see Gianluigi's logbook on page 251) /* Double_t Zh1 = Z[location] - ZDrift[location]; Double_t Zh2 = Z[location] + ZDrift[location]; Double_t Sh1 = S[location] - Aellipsis1*Tiltdirection1[1]; Double_t Sh2 = S[location] + Aellipsis1*Tiltdirection1[1]; Double_t Zlast1 = (Fi_final_helix_referenceframe-Fi_initial_helix_referenceframe)*Zh1 /(Sh1-Fi_initial_helix_referenceframe); Double_t Zlast2 = (Fi_final_helix_referenceframe-Fi_initial_helix_referenceframe)*Zh2 /(Sh2-Fi_initial_helix_referenceframe); if( fabs(Zlast1 - ZCENTER_STRAIGHT) > SEMILENGTH_STRAIGHT && fabs(Zlast2 - ZCENTER_STRAIGHT) > SEMILENGTH_STRAIGHT ) continue; */ NAssociated++; } // end of for( ii=0; ii<2; ii++) } // for( iii=0; iii< NSkewhits; iii++) return NAssociated; } //----------end of function PndTrkTracking::AssociateSkewHitsToXYTrack //------------------------- begin of function PndTrkTracking::CollectParSttHitsagain void PndTrkTracking::CollectParSttHitsagain( Vec & 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; i=0)SchosenPixel[ListPixelHitsinTrack[i]]=S[i]+nrounds0*2.*PI; else SchosenPixel[ListPixelHitsinTrack[i]]=S[i]+(nrounds0-1)*2.*PI; ZchosenPixel[ListPixelHitsinTrack[i]]=ZED[i]; ErrorchosenPixel[ListPixelHitsinTrack[i]]=ERRORPIXEL; auxnMvdPixel++; } } // end of for(i=0;i<*nPixelHitsinTrack;i++) for(j=0;j<*nStripHitsinTrack;j++){ i=j+(*nPixelHitsinTrack); if( fabs(GeomC.Dist_SZ(Rr,KAPPA,FI0,ZED[i],S[i],&nrounds0)) < MvdCut && abs(nrounds0)<=MaxTurnofTracks){ auxListMvdStrip[auxnMvdStrip]=ListStripHitsinTrack[j]; if(nrounds0>=0)SchosenStrip[ListStripHitsinTrack[j]]=S[i]+nrounds0*2.*PI; else SchosenStrip[ListStripHitsinTrack[j]]=S[i]+(nrounds0-1)*2.*PI; ZchosenStrip[ListStripHitsinTrack[j]]=ZED[i]; ErrorchosenStrip[ListStripHitsinTrack[j]]=ERRORSTRIP; auxnMvdStrip++; } } // end of for(j=0;j<*nStripHitsinTrack;j++) //-----------------stampe. if(istampa>3){ cout<<"in EliminateSpuriousSZ : nSkew hit = "<<*nSkewHitsinTrack <<", K = "<< KAPPA<<", FI0 = "<< FI0 <3){ cout<<"in EliminateSpuriousSZ : skew hit n. "< MaxTurnofTracks && abs(nr2)>MaxTurnofTracks) { continue; } else if ( abs(nr2)>MaxTurnofTracks) { zeta0 = ZED[i]+DriftRadius[i]; nchosen=nrounds0; } else if ( abs(nrounds0) > MaxTurnofTracks ) { dista = ddd; zeta0 = ZED[i]-DriftRadius[i]; nchosen=nr2; } else { if( fabs(dista)>fabs(ddd) ) { dista = ddd; zeta0 = ZED[i]-DriftRadius[i]; nchosen=nr2; } else { zeta0 = ZED[i]+DriftRadius[i]; nchosen=nrounds0; } } error = DriftRadius[i]; if(nchosen>=0)SchosenSkew[ListSkewHitsinTrack[j]]=S[i]+nchosen*2.*PI; else SchosenSkew[ListSkewHitsinTrack[j]]=S[i]+(nchosen-1)*2.*PI; ZchosenSkew[ListSkewHitsinTrack[j]]=zeta0; //-----------------stampe. if(istampa>3){ cout<<"in EliminateSpuriousSZ : insomma, dista prima della selezione = "<< dista<< ", ed e' da comparare\n\tcon 4*error = "<< 4.*error< 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 PndTrkTracking, 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 PndTrkTracking, 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 PndTrkTracking::ExtractInfoFromMvdTrackCand //----------begin of function PndTrkTracking::FindCharge void PndTrkTracking::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 PndTrkTracking::FindCharge //----------start function PndTrkTracking::FindingParallelTrackAngularRange void PndTrkTracking::FindingParallelTrackAngularRange( Double_t oX, Double_t oY, Double_t Rr, Short_t Charge, Double_t *Fi_low_limit, Double_t *Fi_up_limit, Short_t * status, Double_t Rmi, // Rmin of cylindrical volume intersected by track; Double_t Rma // Rmax of cylindrical volume intersected by track; ) { // -------------- calculate the maximum fi and minimum fi spanned by this track, // see logbook pag.270; by using the Rmin and Rmax of the straw detector. // this function works also when circular trajectory in XY doesn't pass through (0,0). bool intersection_inner, intersection_outer; Double_t teta1, teta2, tetavertex, a, cosT, cost, cosFi, cosfi, Fi, fi, FI0, Px, Py, tmp; Rma += 1. ; // add a safety margin. Rmi -= 1. ; // add a safety margin. a = sqrt(oX*oX+oY*oY); // preliminary condition if(a + Rr <= Rmi ) // in this case there might be hits at radius < Rmi. { *status = -1 ;return;} if( a >= Rr + Rma || Rr >= a + Rma) // in this case there can be no hits with radius < Rma. { *status = -2;return;} if( a - Rr >= Rmi ) intersection_inner = false; else intersection_inner = true; if( a + Rr <= Rma || a - Rr >= Rma ) intersection_outer = false; else intersection_outer = true; if( (! intersection_inner) && (! intersection_outer) ){ *Fi_low_limit = 0.; *Fi_up_limit = 2.*PI; *status = 1; return; } // now the calculation FI0 = atan2(-oY,-oX); if( intersection_outer ){ cosFi = (a*a + Rr*Rr - Rma*Rma)/(2.*Rr*a); if(cosFi<-1.) cosFi=-1.; else if(cosFi>1.) cosFi=1.; Fi = acos(cosFi); } if( intersection_inner ){ cosfi = (a*a + Rr*Rr - Rmi*Rmi)/(2.*Rr*a); if(cosfi<-1.) cosfi=-1.; else if(cosfi>1.) cosfi=1.; fi = acos(cosfi); } if( Charge < 0.){ // this particle rotates counterclockwise when looking into the beam if( intersection_outer && intersection_inner){ *Fi_low_limit=FI0 + fi; *Fi_up_limit= FI0 +Fi; } else if (intersection_inner) { *Fi_low_limit=FI0 + fi; *Fi_up_limit= FI0 - fi; } else { *Fi_low_limit=FI0 - Fi; *Fi_up_limit= FI0 + Fi; } // end of if( intersection_outer && intersection_inner } else { // continuation of if( Charge < 0.) if( intersection_outer && intersection_inner){ *Fi_low_limit=FI0 - Fi; *Fi_up_limit= FI0 - fi; } else if (intersection_inner) { *Fi_low_limit=FI0 + fi; // must invert because low limit must be < up limit *Fi_up_limit= FI0 - fi; } else { *Fi_low_limit=FI0 - Fi; *Fi_up_limit= FI0 + Fi; } // end of if( intersection_outer && intersection_inner } // end of if( Charge < 0.) if(*Fi_low_limit<0.) { *Fi_low_limit=fmod(*Fi_low_limit,2.*PI); *Fi_low_limit += 2.*PI; } else if (*Fi_low_limit>=2.*PI){ *Fi_low_limit=fmod(*Fi_low_limit,2.*PI); } if(*Fi_up_limit<0.) { *Fi_up_limit=fmod(*Fi_up_limit,2.*PI); *Fi_up_limit += 2.*PI; } else if (*Fi_up_limit>=2.*PI){ *Fi_up_limit=fmod(*Fi_up_limit,2.*PI); } // Modify *Fi_up_limit by adding // 2PI if it is the case, in order to make *Fi_up_limit > *Fi_low_limit. if( *Fi_up_limit < *Fi_low_limit ) *Fi_up_limit += 2.*PI; if( *Fi_up_limit < *Fi_low_limit ) *Fi_up_limit = *Fi_low_limit; *status = 0; return; } //---------- end of function PndTrkTracking::FindingParallelTrackAngularRange //----------start of function PndTrkTracking::FixDiscontinuitiesFiangleinSZplane void PndTrkTracking::FixDiscontinuitiesFiangleinSZplane( Short_t TemporarynSkewHitsinTrack, 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 PndTrkTracking::InfoXYZParal //--------begin of function PndTrkTracking::Initial_SttParHits_DecreasingR_Ordering void PndTrkTracking::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 PndTrkTracking::Initial_SttParHits_DecreasingR_Ordering //---------------------- begin function PndTrkTracking::LoadPndTrack_TrackCand void PndTrkTracking::LoadPndTrack_TrackCand( Vec & keepit, Vec & SttSZfit, Short_t nTotalCandidates, Vec & Charge, Int_t nSttTrackCand, Double_t *FI0, Double_t *KAPPA, Double_t info[][7], Double_t SchosenSkew[][MAXSTTHITS], Double_t ZchosenSkew[][MAXSTTHITS] ) { //------- 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 ; //-------------------------- int nSttHit = fSttHitArray->GetEntriesFast(); //--------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------- 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*BFIELD/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 ); 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 PndTrkTracking::LoadPndTrack_TrackCand //----------begin function PndTrkTracking::LoadSZetc_forSZfit void PndTrkTracking::LoadSZetc_forSZfit( Short_t ncand, // input Short_t nhitsinfit, Double_t * TemporaryS, // input Double_t * TemporaryZ, // input Double_t * TemporaryZDrift, // input Double_t * TemporaryZErrorafterTilt, // input bool YesGLPKfitSZ, // input 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] = fZMvdPixel[k]; S[i] = atan2( fYMvdPixel[k]-fOy[ncand],fXMvdPixel[k]-fOx[ncand]); if(S[i]<0.) S[i] +=2.*PI; 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.; if(YesGLPKfitSZ){ // the following is the error in case of GLPK fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= 1. ; } else{ // the following error is conventional for the chi**2 type of fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= 0.5 ; } } // the Mvd Strips hit for(j=0, i = fnMvdPixelHitsinTrack[ncand]; j< fnMvdStripHitsinTrack[ncand]; j++){ k=fListMvdStripHitsinTrack[ncand][j]; ZEDbis[i] = ZED[i] = fZMvdStrip[k]; S[i] = atan2( fYMvdStrip[k]-fOy[ncand],fXMvdStrip[k]-fOx[ncand]); if(S[i]<0.) S[i] +=2.*PI; 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.; if(YesGLPKfitSZ){ // the following is the error in case of GLPK fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= 1. ; } else { // the following error is conventional for the chi**2 type of fit; ErrorDriftRadiusbis[i]=ErrorDriftRadius[i]= 0.5 ; } 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]; if(fnSciTilHitsinTrack[ncand]==2){ ZED[i]=0.5*(fposizSciTil[fListSciTilHitsinTrack[ncand][0]][2]+ fposizSciTil[fListSciTilHitsinTrack[ncand][1]][2]); S[i] = 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. DriftRadius[i]=-2.; ErrorDriftRadius[i]= DIMENSIONSCITIL/2.; ; } else if (fnSciTilHitsinTrack[ncand]==1){ ZED[i]=fposizSciTil[fListSciTilHitsinTrack[ncand][0]][2]; S[i] = 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. DriftRadius[i]=-2.; ErrorDriftRadius[i]= DIMENSIONSCITIL/2.; ; } // the Skew Stt hits // the info on TemporaryS, TemporaryZ, TemporaryZDrift, TemporaryZErrorafterTilt 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(i1.e-10) { ErrorDriftRadiusbis[kall]=TemporaryZErrorafterTilt[location]; } else { ErrorDriftRadiusbis[kall]=0.5; } } // end of for(j=0;j& 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<<"da PndTrkTracking : appena prima arbitration, IVOLTE = "<< IVOLTE<<", Stt track cand = "<& keepit, Short_t FirstCandidate, Short_t LastCandidate, Double_t info[][7], Double_t Trajectory_Start[][2], Vec & 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 PndTrkTracking::Ordering_Loading_ListTrackCandHit //----------begin of function PndTrkTracking::OrderingR_Loading_ListTrackCandHit void PndTrkTracking::OrderingR_Loading_ListTrackCandHit( Vec & keepit, Short_t ncand, Double_t info[][7] ) { Short_t dime, 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]; dime = fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]; if(dime == 0 ) dime =1; // just for protection; Short_t tempmvdindex[dime ], tempmvdtype[dime ]; Int_t auxIndex[dime ]; Double_t auxR[dime ]; // 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 dime = fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand]; if(dime == 0) dime =1; // only for protection; Short_t tempmvdindex2[dime ], tempmvdtype2[dime ]; Int_t auxIndex2[dime ]; Double_t auxR2[dime ]; 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 PndTrkTracking::OrderingR_Loading_ListTrackCandHit //----------begin of function PndTrkTracking::OrderingSttSkewandSttParallel void PndTrkTracking::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 PndTrkTracking::OrderingUsingConformal //------------------ begin function PndTrkTracking::RefitMvdStt void PndTrkTracking::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 PndTrkTracking::RefitMvdStt ClassImp(PndTrkTracking)