#include "glpk.h" #include "PndTrkTracking.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 "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; #define MAXHITSINFIT 12 #define MAXMVDMCPOINTS 2000 #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; YesClean = false; YesCleanMvd = true; YesSciTil = false ; MvdAloneTracking = true; 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; YesClean = false; YesCleanMvd = true; YesSciTil = false ; MvdAloneTracking = true; 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; YesClean = false; YesCleanMvd = true; YesSciTil = false ; MvdAloneTracking = true; 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; YesClean = false; YesCleanMvd = true; YesSciTil = doSciTil ; MvdAloneTracking = true; 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(InclusionListSciTil); memset (InclusionListSciTil,true,len); len = sizeof(InclusionListStt); memset (InclusionListStt,true,len); len = sizeof(inMvdTrackCandPixel); memset (inMvdTrackCandPixel,false,len); len = sizeof(inMvdTrackCandStrip); memset (inMvdTrackCandStrip,false,len); len = sizeof(TypeConf); memset (TypeConf,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 : nMCTracks=0; nSciTilHits=0; len = sizeof(ListMvdPixelHitsinTrack); memset (ListMvdPixelHitsinTrack,0,len); len = sizeof(ListMvdStripHitsinTrack); memset (ListMvdStripHitsinTrack,0,len); len = sizeof(ListSciTilHitsinTrack); memset (ListSciTilHitsinTrack,0,len); len = sizeof(ListSttParHits); memset (ListSttParHits,0,len); len = sizeof(ListSttParHitsinTrack); memset (ListSttParHitsinTrack,0,len); len = sizeof(ListSttSkewHitsinTrack); memset (ListSttSkewHitsinTrack,0,len); len = sizeof(ListSttSkewHits); memset (ListSttSkewHits,0,len); len = sizeof(ListSttSkewHitsinTrackSolution); memset (ListSttSkewHitsinTrackSolution,0,len); len = sizeof(ListTrackCandHit); memset (ListTrackCandHit,0,len); len = sizeof(nMvdPixelHitsinTrack); memset (nMvdPixelHitsinTrack,0,len); len = sizeof(nMvdStripHitsinTrack); memset (nMvdStripHitsinTrack,0,len); len = sizeof(nTrackCandHit); memset (nTrackCandHit,0,len); len = sizeof(nSciTilHitsinTrack); memset (nSciTilHitsinTrack,0,len); len = sizeof(nSttParHitsinTrack); memset (nSttParHitsinTrack,0,len); len = sizeof(nSttSkewHitsinTrack); memset (nSttSkewHitsinTrack,0,len); // Short_t : nMvdDSPixelHitNotTrackCand=0; nMvdDSStripHitNotTrackCand=0; nMvdPixelHit=0; nMvdStripHit=0; nMvdTrackCand=0; nMvdUSPixelHitNotTrackCand=0; nMvdUSStripHitNotTrackCand=0; len = sizeof(nHitMvdTrackCand); memset (nHitMvdTrackCand,0,len); len = sizeof(ListHitMvdTrackCand); memset (ListHitMvdTrackCand,0,len); len = sizeof(ListHitTypeMvdTrackCand); memset (ListHitTypeMvdTrackCand,0,len); len = sizeof(ListMvdDSPixelHitNotTrackCand); memset (ListMvdDSPixelHitNotTrackCand,0,len); len = sizeof(ListMvdUSPixelHitNotTrackCand); memset (ListMvdUSPixelHitNotTrackCand,0,len); len = sizeof(ListMvdDSStripHitNotTrackCand); memset (ListMvdDSStripHitNotTrackCand,0,len); len = sizeof(ListMvdUSStripHitNotTrackCand); memset (ListMvdUSStripHitNotTrackCand,0,len); len = sizeof(ListTrackCandHitType); memset (ListTrackCandHitType,0,len); // int : fNevents_to_plot = 10; // Double_t : Fimin=0.; SEMILENGTH_STRAIGHT=75.; ZCENTER_STRAIGHT=35.; len = sizeof(ALFA); memset (ALFA,0,len); len = sizeof(BETA); memset (BETA,0,len); len = sizeof(GAMMA); memset (GAMMA,0,len); len = sizeof(CxMC); memset (CxMC,0,len); len = sizeof(CyMC); memset (CyMC,0,len); len = sizeof(R_MC); memset (R_MC,0,len); len = sizeof(MCtruthTrkInfo); memset (MCtruthTrkInfo,0,len); len = sizeof(MCSkewAloneX); memset (MCSkewAloneX,0,len); len = sizeof(MCSkewAloneY); memset (MCSkewAloneY,0,len); len = sizeof(radiaConf); memset (radiaConf,0,len); len = sizeof(Ox); memset (Ox,0,len); len = sizeof(Oy); memset (Oy,0,len); len = sizeof(R); memset (R,0,len); len = sizeof(refindexMvdPixel); memset (refindexMvdPixel,0,len); len = sizeof(sigmaXMvdPixel); memset (sigmaXMvdPixel,0,len); len = sizeof(sigmaYMvdPixel); memset (sigmaYMvdPixel,0,len); len = sizeof(sigmaZMvdPixel); memset (sigmaZMvdPixel,0,len); len = sizeof(XMvdPixel); memset (XMvdPixel,0,len); len = sizeof(YMvdPixel); memset (YMvdPixel,0,len); len = sizeof(ZMvdPixel); memset (ZMvdPixel,0,len); len = sizeof(XMvdStrip); memset (XMvdStrip,0,len); len = sizeof(YMvdStrip); memset (YMvdStrip,0,len); len = sizeof(ZMvdStrip); memset (ZMvdStrip,0,len); len = sizeof(sigmaXMvdStrip); memset (sigmaXMvdStrip,0,len); len = sizeof(sigmaYMvdStrip); memset (sigmaYMvdStrip,0,len); len = sizeof(sigmaZMvdStrip); memset (sigmaZMvdStrip,0,len); len = sizeof(refindexMvdStrip); memset (refindexMvdStrip,0,len); len = sizeof(posizSciTil); memset (posizSciTil,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 // 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(YesSciTil) { fSciTHitArray = (TClonesArray*) ioman->GetObject("SciTHit"); } else { fSciTHitArray = NULL; } //--------------------------- // ------------------------- get the SciTil MC Points if(YesSciTil && 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, return!" <GetObject(fMvdStripBranch); // fMvdStripHitArray = (TClonesArray*) ioman->GetObject("MVDHitsStrip"); if ( !fMvdStripHitArray){ cout << "-W- PndTrkTracking::Init: " << "No MVD Strip hitArray, return!" <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, return!" <Register("SttMvdTrackCand","SttMvd",fSttMvdPndTrackCandArray, kTRUE); // Create and register output array for PndTrack of Stt+Mvd combined fSttMvdPndTrackArray = new TClonesArray("PndTrack"); ioman->Register("SttMvdTrack","SttMvd",fSttMvdPndTrackArray, kTRUE); //----------------------- // calculate the boundaries of the Box in Conformal Space, see Gianluigi logbook on pag. 210-211 Short_t i; Double_t A, r1, r2; radiaConf[0] = 1./RSTRAWDETECTORMAX; r1 = RSTRAWDETECTORMIN; A = (RSTRAWDETECTORMAX - r1)/NRDIVCONFORMAL; if ( NRDIVCONFORMAL > 1 ) { for(i = 1; i< NRDIVCONFORMAL ; i++){ r2 = r1 + A; radiaConf[NRDIVCONFORMAL-i] = 1./r2; r1=r2; } } 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, GoodSkewFit[MAXTRACKSPEREVENT], keepit[MAXTRACKSPEREVENT], Mvdhits[MAXTRACKSPEREVENT], outcome, status[MAXTRACKSPEREVENT], SttSZfit[MAXTRACKSPEREVENT]; Short_t nalone, ncand, nhitsinfit, Nint, NNN, nRemainingCandidates, nXYZhits, nHitsInMCTrack[MAXTRACKSPEREVENT], nMCParalAlone[MAXTRACKSPEREVENT], nMCSkewAlone[MAXTRACKSPEREVENT], nParalCommon[MAXTRACKSPEREVENT], npixelhitsintrack, nSkewCommon[MAXTRACKSPEREVENT], nSkewHitsInMCTrack[MAXTRACKSPEREVENT], nSpuriParinTrack[MAXTRACKSPEREVENT], nSpuriSkewinTrack[MAXTRACKSPEREVENT], nstriphitsintrack, // given a Hit number it gives its radial box number RConformalIndex[MAXSTTHITS], // given a Hit number it gives its azimuthal box number FiConformalIndex[MAXSTTHITS], nTotalCandidates, tempore[MAXSTTHITS], TemporarySkewList[2*MAXSTTHITS][2], BigList[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], // nBoxConformal, first index -> radial divisions, // 2nd index -> azimuthal divisions; n. of hits falling in this cell. nBoxConformal[NRDIVCONFORMAL*NFIDIVCONFORMAL], ParalCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], ParSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], SkewCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], SkewSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], HitsinBoxConformal[MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL]; Short_t i, iParHit, ipunto, j, k, kall, l, tubeID, Charge[MAXTRACKSPEREVENT], daTrackFoundaTrackMC[MAXTRACKSPEREVENT], resultFitSZagain[MAXTRACKSPEREVENT], statusflag[MAXTRACKSPEREVENT] ; Int_t iaccept, len, nSttHit, nSttMCPoint, nSttParHit, nSttSkewHit, nSttTrackCand ; Int_t nrounds0, nrounds1, ListHits[MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK]; Double_t S[2*MAXSTTHITS], Z[2*MAXSTTHITS]; 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]; 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. PndTrkGlpkFits fit; // PndTrkLegendreFits fit; //------------------------------------ IVOLTE++; if(istampa>0) cout<GetEntriesFast(); nMvdStripHit = fMvdStripHitArray->GetEntriesFast(); if(nMvdPixelHit>MAXMVDPIXELHITS){ cout<<"from PndTrkTracking, nMvdPixelHit is > maximum allowed (" <MAXMVDSTRIPHITS){ cout<<"from PndTrkTracking, nMvdStripHit is > maximum allowed (" <At(i); TVector3 temp = pMvdPixelHit->GetPosition(); XMvdPixel[i] = temp.X(); YMvdPixel[i] = temp.Y(); ZMvdPixel[i] = temp.Z(); sigmaXMvdPixel[i] = pMvdPixelHit->GetDx(); sigmaYMvdPixel[i] = pMvdPixelHit->GetDy(); sigmaZMvdPixel[i] = pMvdPixelHit->GetDz(); refindexMvdPixel[i] = pMvdPixelHit->GetRefIndex(); } // ------------------------------------------- extract info from HITS Strip MVD for( i= 0; i< nMvdStripHit; i++){ pMvdStripHit = (PndSdsHit *) fMvdStripHitArray->At(i); TVector3 temp = pMvdStripHit->GetPosition(); XMvdStrip[i] = temp.X(); YMvdStrip[i] = temp.Y(); ZMvdStrip[i] = temp.Z(); sigmaXMvdStrip[i] = pMvdStripHit->GetDx(); sigmaYMvdStrip[i] = pMvdStripHit->GetDy(); sigmaZMvdStrip[i] = pMvdStripHit->GetDz(); refindexMvdStrip[i] = pMvdStripHit->GetRefIndex(); } // --------------- printout of Mvd Hits; if(istampa>=1) fPrint.stampaMvdHits( fMvdPixelBranch, fMvdStripBranch, nMvdPixelHit, nMvdStripHit, refindexMvdPixel, refindexMvdStrip, sigmaXMvdPixel, sigmaXMvdStrip, sigmaYMvdPixel, sigmaYMvdStrip, sigmaZMvdPixel, sigmaZMvdStrip, XMvdPixel, XMvdStrip, YMvdPixel, YMvdStrip, ZMvdPixel, ZMvdStrip ); // ------------------------------------------ get info from trackcand of MVD nMvdTrackCand = fMvdTrackCandArray->GetEntriesFast(); if (nMvdTrackCand> MAXMVDTRACKSPEREVENT) { cout<<"da PndTrkTracking : N. of MvdTrackCand = "<< nMvdTrackCand<<" and it is > MAXMVDTRACKSPEREVENT (="<GetEntriesFast(); if (nSttMCPoint ==0){ cout<<"da PndTrkTracking : N. di Stt MC points = 0"<MAXSTTHITS){ cout<<"da PndTrkTracking : N. di Stt MC points = "< MAXSTTHITS ("<GetEntriesFast(); if (nSttHit ==0){ cout<<"da PndTrkTracking : N. di Stt Hits = 0, return!"< MAXSTTHITS) { cout<<"da PndTrkTracking : N. di Stt Hits = "< MAXSTTHITS (="<= 1) { cout<<"da PndTrkTracking : n. totale Hits in STT : "<At(i); // right way to extract the corrisponding MC point. ipunto= pSttHit->GetRefIndex(); tubeID = pSttHit->GetTubeID(); pSttTube = (PndSttTube *) fSttTubeArray->At(tubeID); TVector3 center = pSttTube->GetPosition(); // 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.; ListSttParHits[nSttParHit]=i; nSttParHit++; } else { info[i][5]= 99.;// to signal that it is a skew straw. ListSttSkewHits[nSttSkewHit]=i; nSttSkewHit++; } // printout of the Stt hits; if (istampa >= 1 ) fPrint.stampaSttHits(i,ipunto,dradius,WDX,WDY,WDZ,puntator,pSttTube); } // end of for( i= 0; i< nSttHit; i++) // reordering the list of parallel hits ( ListSttParHits) 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, ListSttParHits,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 nSciTilHits = 0; if( fSciTHitArray != NULL){ // number SciTil hits/event nSciTilHits = fSciTHitArray->GetEntriesFast(); if(nSciTilHits>MAXSCITILHITS){ cout<<"da PndTrkTracking : N. of SciTil Hits = "< MAXSCITILHITS (="< 0) fSciTilMaxNumber = nSciTilHits ; 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, ListSttParHits, nSttParHit, infoparalConformal, STRAWRADIUS ); fill.BoxConformalFilling( FiConformalIndex, HitsinBoxConformal, InclusionListStt, infoparalConformal, ListSttParHits, MAXHITSINCELL, nBoxConformal, NFIDIVCONFORMAL, nSttParHit, NRDIVCONFORMAL, radiaConf, 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 = FiConformalIndex; input.HitsinBoxConf = HitsinBoxConformal; input.InclusionListStt = InclusionListStt; input.InclusionListSciTil = InclusionListSciTil; input.info = info; input.infoparalConformal = infoparalConformal; input.ListSttParHits = ListSttParHits; input.maxhitsinfit = MAXHITSINFIT; input.maxscitilhitsintrack = MAXSCITILHITSINTRACK; input.maxstthits = MAXSTTHITS; input.maxstthitsintrack = MAXSTTHITSINTRACK; input.minimumhitspertrack = MINIMUMHITSPERTRACK; input.minouterhitspertrack = MINOUTERHITSPERTRACK; input.nBoxConf = nBoxConformal; input.nfidivconformal = NFIDIVCONFORMAL; input.nrdivconformal = NRDIVCONFORMAL; input.nSciTilHits = nSciTilHits; input.nsttparhit = nSttParHit; input.posizSciT = posizSciTil; input.radiaConf = radiaConf; input.RConformalIndex = RConformalIndex; input.rstrawdetectormax = RSTRAWDETECTORMAX; input.rstrawdetectormin = RSTRAWDETECTORMIN; input.strawradius = STRAWRADIUS; input.trajectory_vertex = trajectory_vertex; input.YesSciTil = YesSciTil; //---------------------- //----- 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(YesSciTil) { 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 = posizSciTil[i][0]; input.posizSciTily = posizSciTil[i][1]; // outputs from the FindTrackInXYProjection class are stored here; input.ALFA = &ALFA[nSttTrackCand]; input.BETA = &BETA[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 = &GAMMA[nSttTrackCand]; input.ListHitsinTrack = &ListSttParHitsinTrack[nSttTrackCand][0]; input.ListSciTilHitsinTrack = &ListSciTilHitsinTrack[nSttTrackCand][0]; input.nHitsinTrack = &nSttParHitsinTrack[nSttTrackCand]; input.nSciTilHitsinTrack = &nSciTilHitsinTrack[nSttTrackCand]; input.Oxx = &Ox[nSttTrackCand]; input.Oyy = &Oy[nSttTrackCand]; input.Rr = &R[nSttTrackCand]; input.S_SciTilHitsinTrack = &S_SciTilHitsinTrack[nSttTrackCand][0]; input.TypeConf = &TypeConf[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, after AssociateBetterAfterFitSkewHitsToXYTrack.\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa // now the ordering the parallel and skew hits. for(i=0; iDelete(); fSttMvdPndTrackArray->Delete(); nTotalCandidates = nSttTrackCand; // nSttTrackCand is already <= MAXTRACKSPEREVENT. //---- find the angular range (in Fi) allowed for the STT hits, with the present Ox,Oy and R // of the track candidates, and for the Mvd hits (FI0 and Fi_low_limit ). for( ncand= 0; ncand< nSttTrackCand; ncand++){ keepit[ncand]=true; FindingParallelTrackAngularRange( Ox[ncand], Oy[ncand], R[ncand], Charge[ncand], &Fi_low_limit[ncand], // Fi (in XY Helix frame) lower limit using // the Stt detector minimum/maximum radius // Fi_low_limit is ALWAYS between 0. and 2PI &Fi_up_limit[ncand], // Fi (in XY Helix frame) upper limit using // the Stt detector maximum/minimum radius // Fi_up_limit is ALWAYS > 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. MatchMvdHitsToSttTracks2( keepit,// input and output. delta, highqualitycut, nSttTrackCand, FI0, Fi_low_limit, Charge, nMvdPixelHitsinTrack, // output ListMvdPixelHitsinTrack, // output nMvdStripHitsinTrack, // output ListMvdStripHitsinTrack // output ); //-------------- stampa if(istampa>=2){ cout<<"dopo MatchMvdHitsToSttTracks2[1646], evt. "< MAXMVDPIXELHITSINTRACK){ cout<<"from PndTrkTracking, nMvdPixelHitsinTrack["< MAXMVDPIXELHITSINTRACK (" < MAXMVDSTRIPHITSINTRACK){ cout<<"from PndTrkTracking, nMvdStripHitsinTrack["< MAXMVDSTRIPHITSINTRACK (" <=2){ cout<<"\tstampa dopo ordering, prima di refit.\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, 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]*Ox[ncand],-Charge[ncand]*Oy[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(!(ListTrackCandHitType[ncand][i]==1 || ListTrackCandHitType[ncand][i]==0) ) continue; if( ListTrackCandHitType[ncand][i] == 0 ){ d = fabs( sqrt( (Ox[ncand]-XMvdPixel[ListTrackCandHit[ncand][i]]) *(Ox[ncand]-XMvdPixel[ListTrackCandHit[ncand][i]]) +(Oy[ncand]-YMvdPixel[ListTrackCandHit[ncand][i]]) *(Oy[ncand]-YMvdPixel[ListTrackCandHit[ncand][i]]) ) - R[ncand]); if( d < diff ){ diff = d; iexcl=i; trajectory_vertex[0]= XMvdPixel[ListTrackCandHit[ncand][i]]; trajectory_vertex[1]= YMvdPixel[ListTrackCandHit[ncand][i]]; } } else { d = fabs( sqrt( (Ox[ncand]-XMvdStrip[ListTrackCandHit[ncand][i]]) *(Ox[ncand]-XMvdStrip[ListTrackCandHit[ncand][i]]) +(Oy[ncand]-YMvdStrip[ListTrackCandHit[ncand][i]]) *(Oy[ncand]-YMvdStrip[ListTrackCandHit[ncand][i]]) ) - R[ncand]); if( d < diff ){ diff = d; iexcl=i; trajectory_vertex[0]= XMvdStrip[ListTrackCandHit[ncand][i]]; trajectory_vertex[1]= YMvdStrip[ListTrackCandHit[ncand][i]]; } } } // end of for(i=0, diff = 1.e20;i<..... if( diff > 0.5 ) { trajectory_vertex[0]=trajectory_vertex[1]=0.; iexcl=-1; } RefitMvdStt( nTrackCandHit[ncand], //this is input &ListTrackCandHit[ncand][0],//this is both input and output &ListTrackCandHitType[ncand][0],//this is both input and output info, rotationangle, trajectory_vertex, iexcl, &ALFA[ncand], // output of the fit &BETA[ncand], // output of the fit &GAMMA[ncand],// output of the fit &status[ncand] // fit status; true = successful ); if(status[ncand]){ Ox[ncand] = -ALFA[ncand]/2.; Oy[ncand] = -BETA[ncand]/2.; R[ncand] = Ox[ncand]*Ox[ncand]+Oy[ncand]*Oy[ncand]-GAMMA[ncand]; if( R[ncand] > 0. ) R[ncand]=sqrt(R[ncand]) ; else R[ncand]=0.; FI0[ncand] = atan2(Trajectory_Start[1][ncand]-Oy[ncand], Trajectory_Start[0][ncand]-Ox[ncand]); if( FI0[ncand] < 0. ) FI0[ncand]+= 2.*PI; } if(R[ncand] Fi_low_limit and // possibly > 2PI. // Fi_low_limit and Fi_up_limit are undefined // when statusflag is negative. &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 ); // Fi_low_limit set to -99999. when it is contained in Mvd // region completely. if( statusflag[ncand] == -1 ) Fi_low_limit[ncand] = -99999.; if( statusflag[ncand] == -2) keepit[ncand] = false; } // end of for(ncand=0; ncand< nTotalCandidates; ncand++) //--------------------- end of refit the Helix in XY plane using Stt + Mvd associated hits //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo il Refit.\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa if(nMvdPixelHit+nMvdStripHit>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, nMvdPixelHitsinTrack, // input and output ListMvdPixelHitsinTrack, // input and output nMvdStripHitsinTrack, // input and output ListMvdStripHitsinTrack // input and output ); } // end of if(nMvdPixelHit+nMvdStripHit>0) //--------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo il Match Again.\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa // use the risult just obtained from the fit in XY to redo the association of the Skew Straw hits for(ncand=0; ncand< nTotalCandidates; ncand++) { if(!keepit[ncand]) continue; if( ! Mvdhits[ncand]) // the philosophy of this cut is : there is no sense in doing // the SZ fita again, unless there are Mvd hits that can improve the result a lot. { if(YesCleanMvd){ // 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( Ox[ncand], Oy[ncand], R[ncand], FI0[ncand], KAPPA[ncand], Charge[ncand], VERTICALGAP/2.) ) ) keepit[ncand]=false; } // end of (YesCleanMvd) 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. nSttSkewHitsinTrack[ncand]= AssociateSkewHitsToXYTrack( InclusionListStt, // hit is excluded only if it multiple hit. nSttSkewHit, ListSttSkewHits, Ox[ncand], // input : X of center of XY plane circle Oy[ncand], // input : Y of center of XY plane circle R[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, list of selected skew hits (in skew numbering) 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( nSttSkewHitsinTrack[ncand]+nSttParHitsinTrack[ncand] > MAXSTTHITSINTRACK ) { if(MAXSTTHITSINTRACK > nSttParHitsinTrack[ncand]) nSttSkewHitsinTrack[ncand]=MAXSTTHITSINTRACK-nSttParHitsinTrack[ncand]; else nSttSkewHitsinTrack[ncand]=0; } for(j=0;j 2 SciTil hits has already been // prevented early in PndTrkCTFindTrackInXY. i = nMvdPixelHitsinTrack[ncand]+nMvdStripHitsinTrack[ncand]+ nSciTilHitsinTrack[ncand] +j ; } // calculate the quantities used for the SZ fit only. if(i1.e-10) { ErrorDriftRadiusbis[kall]=TemporaryZErrorafterTilt[j]; } else { ErrorDriftRadiusbis[kall]=0.5; } } // end of for(j=0;j0.){ // 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, &nMvdPixelHitsinTrack[ncand], // input and output &ListMvdPixelHitsinTrack[ncand][0],// input and output &nMvdStripHitsinTrack[ncand], // input and output &ListMvdStripHitsinTrack[ncand][0],// input and output &nSttSkewHitsinTrack[ncand], // input and output &ListSttSkewHitsinTrack[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], R[ncand] ); } // end of if(keepit[ncand]) //------------------------ // First cleanup based on the absence of Mvd hits if(YesCleanMvd){ // 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( Ox[ncand], Oy[ncand], R[ncand], FI0[ncand], KAPPA[ncand], Charge[ncand], VERTICALGAP/2.) ) && nMvdStripHitsinTrack[ncand]+nMvdPixelHitsinTrack[ncand]==0) { keepit[ncand]=false; } } // end of (YesCleanMvd) } // 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, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa //--- redo association of parallel Stt straw hits to this track, after better refit. if(nMvdPixelHit+nMvdStripHit>0){ CollectParSttHitsagain( keepit, Mvdhits, info, nSttParHit, 0, // starting candidate n. (included). nTotalCandidates, // ending candidate n. (excluded). KAPPA, FI0, Fi_low_limit, Fi_up_limit, nSttParHitsinTrack, // input and output ListSttParHitsinTrack // input and output ); //-------------- stampa if(istampa>=2){ cout<<"\tstampa dopo CollectParSttHitsagain\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa // ordering all the hits belonging to the candidate track, by increasing R (large // trajectories) or Conformal variables (better for small trajectories); // from candidate n. 0 to candidate n. nTotalCandidates-1; loading ListTrackCandHit. // the array ordered are : // ListTrackCandHit, ListTrackCandHitType, ListSttParHitsinTrack, ListSttSkewHitsinTrack // and also at the end the SciTil hit (if present) is added. //------------------------------- for(ncand=0; ncand< nTotalCandidates; ncand++){ // limit the total # Stt hits to MAXSTTHITSINTRACK if( nSttSkewHitsinTrack[ncand]+nSttParHitsinTrack[ncand] > MAXSTTHITSINTRACK ) { if(MAXSTTHITSINTRACK > nSttSkewHitsinTrack[ncand]) nSttParHitsinTrack[ncand]=MAXSTTHITSINTRACK-nSttSkewHitsinTrack[ncand]; else nSttParHitsinTrack[ncand]=0; } } //--------------- 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=nMvdPixelHitsinTrack[ncand]+nMvdStripHitsinTrack[ncand]+ nSttParHitsinTrack[ncand]+nSttSkewHitsinTrack[ncand]; for(j=0;j0) //------------- cleanup section. Start[0]=0.; Start[1]=0.; Start[2]=0.; gap = (Double_t) (VERTICALGAP); //-------------- stampa if(istampa>=2){ cout<<"\tstampa prima del Cleanup grosso\n"; fPrint.stampetta( IVOLTE, keepit, &ListMvdPixelHitsinTrack[0][0], &ListMvdStripHitsinTrack[0][0], &ListSttParHitsinTrack[0][0], &ListSttSkewHitsinTrack[0][0], &ListSciTilHitsinTrack[0][0], nMvdPixelHitsinTrack, nMvdStripHitsinTrack, nSttParHitsinTrack, nSttSkewHitsinTrack, nSciTilHitsinTrack, nSttTrackCand, MAXMVDPIXELHITSINTRACK, MAXMVDSTRIPHITSINTRACK, MAXSCITILHITSINTRACK, MAXSTTHITSINTRACK, R, Ox, Oy, FI0, KAPPA ); } //-------------- fine stampa for(ncand=0, nRemainingCandidates=0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; Short_t &nHitsPar = nSttParHitsinTrack[ncand]; Short_t &nHitsSkew = nSttSkewHitsinTrack[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[ ListHitMvdTrackCand[i][j] ]) continue; if(npixelhitsintrack>MAXMVDPIXELHITSINTRACK) continue; AloneX[nalone] = XMvdPixel[ ListHitMvdTrackCand[i][j] ]; AloneY[nalone] = YMvdPixel[ ListHitMvdTrackCand[i][j] ]; List[nalone] = ListHitMvdTrackCand[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 (ListHitTypeMvdTrackCand[i][j] == // this condition in principle at this // // point is always satisfied. // FairRootManager::Instance()->GetBranchId(fMvdStripBranch)){ if(UsedStrip[ ListHitMvdTrackCand[i][j] ]) continue; if(nstriphitsintrack>MAXMVDSTRIPHITSINTRACK) continue; AloneX[nalone] = XMvdStrip[ ListHitMvdTrackCand[i][j] ]; AloneY[nalone] = YMvdStrip[ ListHitMvdTrackCand[i][j] ]; List[nalone] = ListHitMvdTrackCand[i][j]; ListType[nalone] = 1; nalone++; nstriphitsintrack++; } } // end of for(j=0;j RSTRAWDETECTORMIN/2.){ Ox[nTotalCandidates] = centrex; Oy[nTotalCandidates] = centrey; R[nTotalCandidates] = radius; FI0[nTotalCandidates] = atan2(-Oy[nTotalCandidates], -Ox[nTotalCandidates]); if( FI0[nTotalCandidates] < 0. ) FI0[nTotalCandidates]+= 2.*PI; nSttParHitsinTrack[nTotalCandidates]=0; nSttSkewHitsinTrack[nTotalCandidates]=0; nMvdPixelHitsinTrack[nTotalCandidates]=0; nMvdStripHitsinTrack[nTotalCandidates]=0; for(j=0; j2){ cout<<"from PndSttMvdTracking, evt. "< 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 = Charge; ioData.Cvel = CVEL; ioData.daTrackFoundaTrackMC = daTrackFoundaTrackMC; 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 = keepit; ioData.InclusionListStt = InclusionListStt; ioData.ListMvdPixelHitsinTrack = &ListMvdPixelHitsinTrack[0][0]; ioData.ListMvdStripHitsinTrack = &ListMvdStripHitsinTrack[0][0]; ioData.ListSciTilHitsinTrack = &ListSciTilHitsinTrack[0][0]; ioData.ListSttParHitsinTrack = &ListSttParHitsinTrack[0][0]; ioData.ListSttSkewHitsinTrack = &ListSttSkewHitsinTrack[0][0]; ioData.ListTrackCandHit = &ListTrackCandHit[0][0]; ioData.ListTrackCandHitType = &ListTrackCandHitType[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 = MCSkewAloneX ; ioData.MCSkewAloneY = MCSkewAloneY ; ioData.MvdPixelCommonList = MvdPixelCommonList; ioData.MvdPixelSpuriList = MvdPixelSpuriList; ioData.MvdStripCommonList = MvdStripCommonList; ioData.MvdStripSpuriList = MvdStripSpuriList; ioData.nHitsInMCTrack = nHitsInMCTrack; ioData.nHitsInSciTile = nHitsInSciTile; ioData.nMCMvdPixelAlone = nMCMvdPixelAlone; ioData.nMCMvdStripAlone = nMCMvdStripAlone; ioData.nMCParalAlone = nMCParalAlone; ioData.nMCSciTilAlone = nMCSciTilAlone; ioData.nMCSkewAlone = nMCSkewAlone; ioData.nMvdPixelCommon = nMvdPixelCommon; ioData.nMvdPixelHitsinTrack = nMvdPixelHitsinTrack; ioData.nMvdStripHitsinTrack = nMvdStripHitsinTrack; ioData.nMvdPixelHit = nMvdPixelHit; ioData.nMvdPixelSpuriinTrack = nMvdPixelSpuriinTrack; ioData.nMvdStripCommon = nMvdStripCommon; ioData.nMvdStripHit = nMvdStripHit; ioData.nMvdStripSpuriinTrack = nMvdStripSpuriinTrack; ioData.nParalCommon = nParalCommon; ioData.nSciTilCommon = nSciTilCommon; ioData.nSciTilHits = nSciTilHits; ioData.nSciTilHitsinTrack = nSciTilHitsinTrack ; ioData.nSciTilSpuriinTrack = nSciTilSpuriinTrack ; ioData.nSkewCommon = nSkewCommon; ioData.nSkewHitsInMCTrack = nSkewHitsInMCTrack; ioData.nSpuriParinTrack = nSpuriParinTrack; ioData.nSpuriSkewinTrack = nSpuriSkewinTrack; ioData.nSttHit = nSttHit; ioData.nSttParHitsinTrack = nSttParHitsinTrack; ioData.nSttSkewHitsinTrack = nSttSkewHitsinTrack; ioData.nTotalCandidates = nTotalCandidates; ioData.OriginalSciTilList = &OriginalSciTilList[0][0]; ioData.Ox = Ox; ioData.Oy = Oy; ioData.ParalCommonList = ParalCommonList; ioData.ParSpuriList = ParSpuriList; ioData.R = R; ioData.refindexMvdPixel = refindexMvdPixel; ioData.refindexMvdStrip = refindexMvdStrip; ioData.resultFitSZagain = resultFitSZagain; ioData.SciTilCommonList = SciTilCommonList; ioData.SciTilSpuriList = SciTilSpuriList; ioData.SkewCommonList = SkewCommonList; ioData.SkewSpuriList = SkewSpuriList; ioData.SttSZfit = SttSZfit; ioData.XMvdPixel = XMvdPixel; ioData.XMvdStrip = XMvdStrip; ioData.XSciTilCenter = pSciTilx; ioData.YMvdPixel = YMvdPixel; ioData.YMvdStrip = YMvdStrip; ioData.YSciTilCenter = pSciTily; ioData.ZMvdPixel = ZMvdPixel; ioData.ZMvdStrip = ZMvdStrip; ioData.ZSciTilCenter = pSciTilz; // class for the MC comparison; PndTrkComparisonMCtruth cmp; nMCTracks = 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; if( distance >= info[i][4]+Aellipsis1 ){ continue; } S[NAssociated] = atan2(POINTS1[j+1]-Oyy, POINTS1[j]-Oxx) ; // atan2 returns radians in (-pi and +pi] if( S[NAssociated] < 0.) S[NAssociated] += 2.*PI; if( S[NAssociated] < Fi_low_limit) { if( S[NAssociated]+2.*PI > Fi_up_limit) continue; } else if( S[NAssociated] > Fi_up_limit) { if( S[NAssociated]- 2.*PI < Fi_low_limit) continue; } //--------------------------- end check Z[NAssociated] = POINTS1[j+2]; ZDrift[NAssociated] = Aellipsis1*Tiltdirection1[0]; ZErrorafterTilt[NAssociated] = 0.02*aaa*Tiltdirection1[0]/LL; 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[NAssociated] - ZDrift[NAssociated]; Double_t Zh2 = Z[NAssociated] + ZDrift[NAssociated]; Double_t Sh1 = S[NAssociated] - Aellipsis1*Tiltdirection1[1]; Double_t Sh2 = S[NAssociated] + 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( bool *keepit, bool *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( (Ox[itrack]-info[ihit][0])*(Ox[itrack]-info[ihit][0])+ (Oy[itrack]-info[ihit][1])*(Oy[itrack]-info[ihit][1]) ) - R[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.){ ListMvdDSPixelHitNotTrackCand[nMvdDSPixelHitNotTrackCand] = i; nMvdDSPixelHitNotTrackCand++; } else { ListMvdUSPixelHitNotTrackCand[nMvdUSPixelHitNotTrackCand] = i; nMvdUSPixelHitNotTrackCand++; } } } for( i= 0; i< nMvdStripHit ; i++){ if( ! inMvdTrackCandStrip[i] ){ if( ZMvdStrip[i]>=0.){ ListMvdDSStripHitNotTrackCand[nMvdDSStripHitNotTrackCand] = i; nMvdDSStripHitNotTrackCand++; } else { ListMvdUSStripHitNotTrackCand[nMvdUSStripHitNotTrackCand] = i; nMvdUSStripHitNotTrackCand++; } } } } //----------------------- 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, Double_t *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( bool *keepit, bool *SttSZfit, Short_t nTotalCandidates, Short_t *Charge, Int_t nSttTrackCand, Double_t *FI0, Double_t *KAPPA, Double_t info[][7], Double_t SchosenSkew[][MAXSTTHITS], Double_t ZchosenSkew[][MAXSTTHITS] ) { //------- load the new PndTrackCand ; each track has the STT and the Mvd hits associated //------- also load the new PndTrack ; each track has the STT and the Mvd hits associated Int_t ipinco, j, k, l, ncand ; Double_t ddd, dis, Distance, Oxx, Oyy, Ptras, Pxini, Pyini, Pzini, px, py, qop, x, y, Posiz1[3], versor[2] ; TVector3 ErrMomentum, ErrPosition, Momentum, Position ; for(ncand=0, ipinco = 0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; // case in which there was no Skew hits and no KAPPA info and that // candidate could not be associated to any Mvd hits --> no KAPPA information! if(ncand1.e-20 ){ Pzini = -Charge[ncand]*0.003*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< nTrackCandHit[ncand]; j++){ switch (ListTrackCandHitType[ncand][j]){ case 0: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdPixelBranch), (Int_t)ListTrackCandHit[ncand][j],j); break; case 1: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdStripBranch), (Int_t)ListTrackCandHit[ncand][j],j); break; case 2: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)ListTrackCandHit[ncand][j],j); break; case 3: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)ListTrackCandHit[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 (ListTrackCandHitType[ncand][0] == 0){ // Mvd Pixel Posiz1[0] = XMvdPixel[ ListTrackCandHit[ncand][0] ]; Posiz1[1] = YMvdPixel[ ListTrackCandHit[ncand][0] ]; Posiz1[2] = ZMvdPixel[ ListTrackCandHit[ncand][0] ]; ErrPosition.SetX(sigmaXMvdPixel[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(sigmaXMvdPixel[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(sigmaXMvdPixel[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if (ListTrackCandHitType[ncand][0] == 1){ // Mvd Strip Posiz1[0] = XMvdStrip[ ListTrackCandHit[ncand][0] ]; Posiz1[1] = YMvdStrip[ ListTrackCandHit[ncand][0] ]; Posiz1[2] = ZMvdStrip[ ListTrackCandHit[ncand][0] ]; ErrPosition.SetX(sigmaXMvdStrip[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(sigmaXMvdStrip[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(sigmaXMvdStrip[ ListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if( ListTrackCandHitType[ncand][0] == 2 ){ // it is a parallel straw hit InfoXYZParal( info, ListTrackCandHit[ncand][0], Ox[ncand], Oy[ncand], R[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 ( ListTrackCandHitType[ncand][0] == 3 ){ // it is a skew straw hit Posiz1[0] = Ox[ncand]+R[ncand]*cos(SchosenSkew[ncand][ ListTrackCandHit[ncand][0] ]); Posiz1[1] = Oy[ncand]+R[ncand]*sin(SchosenSkew[ncand][ ListTrackCandHit[ncand][0] ]); Posiz1[2] = ZchosenSkew[ncand][ ListTrackCandHit[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] = Ox[ncand]-Posiz1[0]; versor[1] = Oy[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 = nTrackCandHit[ncand]-1; if (ListTrackCandHitType[ncand][k] == 0){ // Mvd Pixel Posiz1[0] = XMvdPixel[ ListTrackCandHit[ncand][k] ]; Posiz1[1] = YMvdPixel[ ListTrackCandHit[ncand][k] ]; Posiz1[2] = ZMvdPixel[ ListTrackCandHit[ncand][k] ]; ErrPosition.SetX(sigmaXMvdPixel[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(sigmaXMvdPixel[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(sigmaXMvdPixel[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if (ListTrackCandHitType[ncand][k] == 1){ // Mvd Strip Posiz1[0] = XMvdStrip[ ListTrackCandHit[ncand][k] ]; Posiz1[1] = YMvdStrip[ ListTrackCandHit[ncand][k] ]; Posiz1[2] = ZMvdStrip[ ListTrackCandHit[ncand][k] ]; ErrPosition.SetX(sigmaXMvdStrip[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(sigmaXMvdStrip[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(sigmaXMvdStrip[ ListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if( ListTrackCandHitType[ncand][k] == 2 ){ // it is a parallel straw hit InfoXYZParal ( info, ListTrackCandHit[ncand][k], Ox[ncand], Oy[ncand], R[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 ( ListTrackCandHitType[ncand][k] == 3 ){ // it is a skew straw hit Posiz1[0] = Ox[ncand]+R[ncand]*cos(SchosenSkew[ncand][ ListTrackCandHit[ncand][k] ]); Posiz1[1] = Oy[ncand]+R[ncand]*sin(SchosenSkew[ncand][ ListTrackCandHit[ncand][k] ]); Posiz1[2] = ZchosenSkew[ncand][ ListTrackCandHit[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] = Ox[ncand]-Posiz1[0]; versor[1] = Oy[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::MakeInclusionListStt void PndTrkTracking::MakeInclusionListStt( Int_t nSttHit, Double_t info[][7] ) { int i,j; // it needs to be initialized for each event ! for(i=0;i0){ // 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( (Ox[itrack]-XMvdPixel[ipix])*(Ox[itrack]-XMvdPixel[ipix]) +(Oy[itrack]-YMvdPixel[ipix])*(Oy[itrack]-YMvdPixel[ipix]) ) -R[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( (Ox[itrack]-XMvdStrip[istr])*(Ox[itrack]-XMvdStrip[istr]) +(Oy[itrack]-YMvdStrip[istr])*(Oy[itrack]-YMvdStrip[istr]) ) -R[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( YMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]]-Oy[i], XMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]]-Ox[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( (Ox[i]-XMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]])* (Ox[i]-XMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]]) +(Oy[i]-YMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]])* (Oy[i]-YMvdPixel[ListHitMvdTrackCand[imvdcand][jmvdhit]]))-R[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( YMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]]-Oy[i], XMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]]-Ox[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( (Ox[i]-XMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]])* (Ox[i]-XMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]]) +(Oy[i]-YMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]])* (Oy[i]-YMvdStrip[ListHitMvdTrackCand[imvdcand][jmvdhit]])) -R[i]); if(distGetBranchId(fMvdStripBranch); Dist += dist; if( dist anglemin) } // end of if(ListHitTypeMvdTrackCand[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( (Ox[i]-XMvdPixel[ListMvdDSPixelHitNotTrackCand[jmvdhit]])* (Ox[i]-XMvdPixel[ListMvdDSPixelHitNotTrackCand[jmvdhit]]) +(Oy[i]-YMvdPixel[ListMvdDSPixelHitNotTrackCand[jmvdhit]])* (Oy[i]-YMvdPixel[ListMvdDSPixelHitNotTrackCand[jmvdhit]]) ) -R[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( (Ox[i]-XMvdStrip[ListMvdDSStripHitNotTrackCand[jmvdhit]])* (Ox[i]-XMvdStrip[ListMvdDSStripHitNotTrackCand[jmvdhit]]) +(Oy[i]-YMvdStrip[ListMvdDSStripHitNotTrackCand[jmvdhit]])* (Oy[i]-YMvdStrip[ListMvdDSStripHitNotTrackCand[jmvdhit]]) ) -R[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( (Ox[i]-XMvdPixel[ListMvdUSPixelHitNotTrackCand[jmvdhit]])* (Ox[i]-XMvdPixel[ListMvdUSPixelHitNotTrackCand[jmvdhit]]) +(Oy[i]-YMvdPixel[ListMvdUSPixelHitNotTrackCand[jmvdhit]])* (Oy[i]-YMvdPixel[ListMvdUSPixelHitNotTrackCand[jmvdhit]]) ) -R[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( (Ox[i]-XMvdStrip[ListMvdUSStripHitNotTrackCand[jmvdhit]])* (Ox[i]-XMvdStrip[ListMvdUSStripHitNotTrackCand[jmvdhit]]) +(Oy[i]-YMvdStrip[ListMvdUSStripHitNotTrackCand[jmvdhit]])* (Oy[i]-YMvdStrip[ListMvdUSStripHitNotTrackCand[jmvdhit]]) ) -R[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 = "<0){ MergeSort.Merge_Sort( nMvdPixelHitsinTrack[ncand]+ nMvdStripHitsinTrack[ncand], auxR, auxIndex); // constructing the first part of the ordered new Track Candidate for(i=0; i< nMvdPixelHitsinTrack[ncand]+ nMvdStripHitsinTrack[ncand]; i++){ ListTrackCandHit[ncand][i] = tempmvdindex[ auxIndex[i] ]; ListTrackCandHitType[ncand][i] = tempmvdtype[ auxIndex[i] ]; } } // end of if( nMvdPixelHitsinTrack[ncand]+ // construction of the second part of the ordered new Track Candidate Short_t tempmvdindex2[nSttParHitsinTrack[ncand]+ nSttSkewHitsinTrack[ncand] ], tempmvdtype2[nSttParHitsinTrack[ncand]+ nSttSkewHitsinTrack[ncand] ]; Int_t auxIndex2[nSttParHitsinTrack[ncand]+ nSttSkewHitsinTrack[ncand] ]; Double_t auxR2[nSttParHitsinTrack[ncand]+ nSttSkewHitsinTrack[ncand] ]; for(i=0; i0){ MergeSort.Merge_Sort( nSttParHitsinTrack[ncand]+nSttSkewHitsinTrack[ncand], auxR2, auxIndex2); for(j=0,ipar=0,iskew=0; j< nSttParHitsinTrack[ncand]+nSttSkewHitsinTrack[ncand];j++){ i = j+nMvdPixelHitsinTrack[ncand]+ nMvdStripHitsinTrack[ncand]; ListTrackCandHit[ncand][i] = tempmvdindex2[ auxIndex2[j] ]; ListTrackCandHitType[ncand][i] = tempmvdtype2[ auxIndex2[j] ]; if( ListTrackCandHitType[ncand][i]==2) { ListSttParHitsinTrack[ncand][ipar]=tempmvdindex2[auxIndex2[j]]; ipar++; } else { ListSttSkewHitsinTrack[ncand][iskew]=tempmvdindex2[auxIndex2[j]]; iskew++; } } } // end of if( nSttParHitsinTrack[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 (Ox,Oy) // farther from (0,0) by > 0.9 * RminStrawDetector/2 and consequently Ox and Oy 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 Ox and Oy 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; *status= false; factor=3.; mindis=0.5; // trajectory_vertex[0]=trajectory_vertex[1]=0.; 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. if( exitstatus > 0 && Type) *status=true; return; } //------------------ end function PndTrkTracking::RefitMvdStt ClassImp(PndTrkTracking)