#include "PndTrkTracking2.h" #include "PndTrkBoundaryParStraws2.h" #include "PndTrkChi2Fits.h" #include "PndTrkComparisonMCtruth.h" #include "PndTrkSttConformalFilling.h" #include "PndTrkLegendreFits.h" #include "PndTrkCleanup.h" #include "PndTrkCTFindTrackInXY.h" #include "PndTrkCTFindTrackInXY2.h" #include "PndTrkCTGeometryCalculations.h" #include "PndTrkMergeSort.h" #include "PndTrkPlotMacros2.h" #include "PndTrkPrintouts.h" #include "PndTrkSttAdjacencies.h" #include "PndTrkSttClusterFinder.h" #include "PndSttHit.h" #include "PndSciTHit.h" #include "PndSttPoint.h" #include "PndSttTrack.h" #include "PndSttPoint.h" #include "PndSttHelixHit.h" #include "PndSttSingleStraw.h" #include "PndSttTube.h" #include "PndSttMapCreator.h" #include "PndSdsHit.h" #include "PndSdsMCPoint.h" #include "PndTrackCand.h" #include "PndTrackCandHit.h" #include "PndTrack.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "FairTrackParP.h" #include "FairField.h" #include "TGeoManager.h" #include "TClonesArray.h" #include "TGeoVolume.h" #include "TVector3.h" #include "TRandom.h" #include "TH1F.h" #include "TMath.h" #include "TCanvas.h" #include "TGeoTube.h" #include "TStopwatch.h" #include #include // 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 MAXFOUNDCLUSTERS 100 // maximum allowed clusters in the event; #define MAXHITSINCLUSTER 200 // maximum allowed hits in a cluster; #define MAXHITSINFIT 50 #define MAXMVDMCPOINTS 2000 #define MAXSKEWHITSINFIT 8 #define MINIMUMHITSPERTRACK 2 #define MINOUTERHITSPERTRACK 5 #define PI 3.141592654 #define TIMEOUT 60 // floating point constants // APOTEMA means the radius of a circle INSCRIBED in a Hexagon (this is the same as the // mathematical definition); otherwise the name Radius is used instead; #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 APOTEMASTRAWDETECTORMIN 16.119 // minimum APOTEMA of the Stt detector in cm // this is the Radius of the circle INSCRIBED in the // smaller Hexagon delimiting the STT detector; #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 PMAX 100. #define RSTRAWDETECTORMAX 40.73 // maximum radius of the Stt detector in cm; this is // the radius CIRCUMSCRIBED to the outer Hexagon // delimiting the STT detector; #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 ------------------------------------------- PndTrkTracking2::PndTrkTracking2() : 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"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(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"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(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"); } // ------------------------------------------------------------------------- PndTrkTracking2::PndTrkTracking2(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 ---------------------------------------------------- PndTrkTracking2::~PndTrkTracking2() {} // ----------------------- //--------------- begin PndTrkTracking2::Initialization_ClassVariables void PndTrkTracking2::Initialization_ClassVariables() { // this is only for initializing the Class Variables. size_t len; // booleans : len = sizeof(fSingleHitListStt); memset (fSingleHitListStt,true,len); len = sizeof(fInclusionListSciTil); memset (fInclusionListSciTil,true,len); len = sizeof(fInclusionListStt); memset (fInclusionListStt,true,len); len = sizeof(finMvdTrackCandPixel); memset (finMvdTrackCandPixel,false,len); len = sizeof(finMvdTrackCandStrip); memset (finMvdTrackCandStrip,false,len); len = sizeof(fTypeConf); memset (fTypeConf,false,len); // char : len = sizeof(fSttBranch); memset (fSttBranch,0,len); len = sizeof(fMvdPixelBranch); memset (fMvdPixelBranch,0,len); len = sizeof(fMvdStripBranch); memset (fMvdStripBranch,0,len); // Short_t : fnMCTracks=0; fnSciTilHits=0; len = sizeof(fListMvdPixelHitsinTrack); memset (fListMvdPixelHitsinTrack,0,len); len = sizeof(fListMvdStripHitsinTrack); memset (fListMvdStripHitsinTrack,0,len); len = sizeof(fListSciTilHitsinTrack); memset (fListSciTilHitsinTrack,0,len); len = sizeof(fListSttParHits); memset (fListSttParHits,0,len); len = sizeof(fListSttParHitsinTrack); memset (fListSttParHitsinTrack,0,len); len = sizeof(fListSttSkewHitsinTrack); memset (fListSttSkewHitsinTrack,0,len); len = sizeof(fListSttSkewHits); memset (fListSttSkewHits,0,len); len = sizeof(fListSttSkewHitsinTrackSolution); memset (fListSttSkewHitsinTrackSolution,0,len); len = sizeof(fListTrackCandHit); memset (fListTrackCandHit,0,len); len = sizeof(fnMvdPixelHitsinTrack); memset (fnMvdPixelHitsinTrack,0,len); len = sizeof(fnMvdStripHitsinTrack); memset (fnMvdStripHitsinTrack,0,len); len = sizeof(fnTrackCandHit); memset (fnTrackCandHit,0,len); len = sizeof(fnSciTilHitsinTrack); memset (fnSciTilHitsinTrack,0,len); len = sizeof(fnSttParHitsinTrack); memset (fnSttParHitsinTrack,0,len); len = sizeof(fnSttSkewHitsinTrack); memset (fnSttSkewHitsinTrack,0,len); fnMvdDSPixelHitNotTrackCand=0; fnMvdDSStripHitNotTrackCand=0; fnMvdPixelHit=0; fnMvdStripHit=0; fnMvdTrackCand=0; fnMvdUSPixelHitNotTrackCand=0; fnMvdUSStripHitNotTrackCand=0; len = sizeof(fnHitMvdTrackCand); memset (fnHitMvdTrackCand,0,len); len = sizeof(fListHitMvdTrackCand); memset (fListHitMvdTrackCand,0,len); len = sizeof(fListHitTypeMvdTrackCand); memset (fListHitTypeMvdTrackCand,0,len); len = sizeof(fListMvdDSPixelHitNotTrackCand); memset (fListMvdDSPixelHitNotTrackCand,0,len); len = sizeof(fListMvdUSPixelHitNotTrackCand); memset (fListMvdUSPixelHitNotTrackCand,0,len); len = sizeof(fListMvdDSStripHitNotTrackCand); memset (fListMvdDSStripHitNotTrackCand,0,len); len = sizeof(fListMvdUSStripHitNotTrackCand); memset (fListMvdUSStripHitNotTrackCand,0,len); len = sizeof(fListTrackCandHitType); memset (fListTrackCandHitType,0,len); len = sizeof(fnParContiguous); memset (fnParContiguous,0,len); len = sizeof(fListParContiguous); memset (fListParContiguous,0,len); memset (fStrawCode,0,sizeof(fStrawCode)); memset (fStrawCode,0,sizeof(fStrawCode2)); // int : fNevents_to_plot = 10; // Double_t : fFimin=0.; SEMILENGTH_STRAIGHT=75.; ZCENTER_STRAIGHT=35.; len = sizeof(fALFA); memset (fALFA,0,len); len = sizeof(fBETA); memset (fBETA,0,len); len = sizeof(fGAMMA); memset (fGAMMA,0,len); len = sizeof(fCxMC); memset (fCxMC,0,len); len = sizeof(fCyMC); memset (fCyMC,0,len); len = sizeof(fR_MC); memset (fR_MC,0,len); len = sizeof(fMCtruthTrkInfo); memset (fMCtruthTrkInfo,0,len); len = sizeof(fMCSkewAloneX); memset (fMCSkewAloneX,0,len); len = sizeof(fMCSkewAloneY); memset (fMCSkewAloneY,0,len); len = sizeof(fradiaConf); memset (fradiaConf,0,len); len = sizeof(fOx); memset (fOx,0,len); len = sizeof(fOy); memset (fOy,0,len); len = sizeof(fR); memset (fR,0,len); len = sizeof(frefindexMvdPixel); memset (frefindexMvdPixel,0,len); len = sizeof(fsigmaXMvdPixel); memset (fsigmaXMvdPixel,0,len); len = sizeof(fsigmaYMvdPixel); memset (fsigmaYMvdPixel,0,len); len = sizeof(fsigmaZMvdPixel); memset (fsigmaZMvdPixel,0,len); len = sizeof(fXMvdPixel); memset (fXMvdPixel,0,len); len = sizeof(fYMvdPixel); memset (fYMvdPixel,0,len); len = sizeof(fZMvdPixel); memset (fZMvdPixel,0,len); len = sizeof(fXMvdStrip); memset (fXMvdStrip,0,len); len = sizeof(fYMvdStrip); memset (fYMvdStrip,0,len); len = sizeof(fZMvdStrip); memset (fZMvdStrip,0,len); len = sizeof(fsigmaXMvdStrip); memset (fsigmaXMvdStrip,0,len); len = sizeof(fsigmaYMvdStrip); memset (fsigmaYMvdStrip,0,len); len = sizeof(fsigmaZMvdStrip); memset (fsigmaZMvdStrip,0,len); len = sizeof(frefindexMvdStrip); memset (frefindexMvdStrip,0,len); len = sizeof(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 of PndTrkTracking2::Initialization_ClassVariables //----------------------------------------- begin PndTrkTracking2::Init InitStatus PndTrkTracking2::Init() { IVOLTE=-1; SEMILENGTH_STRAIGHT = 75.; ZCENTER_STRAIGHT = 35.; Double_t po[3], BB[3]; FairField* Field = FairRunAna::Instance()->GetField(); po[0] =0.; po[1]= 0.; po[2]= 0.; Field->GetFieldValue(po, BB); //return value in KG (G3) fBFIELD = BB[2]/10.; // value in Tesla; if(iplotta){ hdeltaRPixel = new TH1F("hdeltaRPixel", "distance MC Pixel point from trajectory in XY plane", 100, -1, 1); hdeltaRStrip = new TH1F("hdeltaRStrip", "distance MC Strip point from trajectory in XY plane", 100, -1, 1); hdeltaRPixel2 = new TH1F( "hdeltaRPixel2", "distance MC point from trajectory in XY plane (Pixels)", 100, -10, 10); hdeltaRStrip2 = new TH1F( "hdeltaRStrip2", "distance MC point from trajectory in XY plane (Strips)", 100, -10,10); } // --------------------------- opening files for special purposes if(doMcComparison >=1 ){ //---- apertura file con info su Found tracce su cui si fa Helix fit dopo HANDLE2 = fopen("info_da_PndTrackFinderReal.txt","w"); // ---- open filehandle per statistica sugli hits etc. HANDLE = fopen("statistiche.txt","w"); // --------------- } // end of if(istampa >=1) // ------------------------- // Get RootManager FairRootManager* ioman = FairRootManager::Instance(); // ioman = FairRootManager::Instance(); if ( ! ioman ) { cout << "-E- PndTrkTracking2::Init: " << "RootManager not instantiated, return!" << endl; return kFATAL; } // ----- maps of STT tubes // CHECK added PndSttMapCreator *mapper = new PndSttMapCreator(fSttParameters); fSttTubeArray = mapper->FillTubeArray(); //---------------------------------------------------- end map // load the array indicating if a straw is external of not; // remember that the numbering of the STT Straws starts at 1 and goes up to 4542 included; // StrawCode convention (in the following left or right is looking to the beam from downstream) : // -1 = not a boundary straw; // 10= inner axial boundary left; // 20= inner axial boundary right; // 12= outer left axial Stt : Vertical (BUT NOT OUTERMOST) + inside boundary ; // 22= outer right axial Stt : Vertical (BUT NOT OUTERMOST) + inside boundary ; // 13= outermost axial boundary left; // 23= outermost axial boundary right; PndTrkBoundaryParStraws2 BoundaryParStraws ; BoundaryParStraws.Set( // inputs : APOTEMAMAXINNERPARSTRAW, APOTEMAMINOUTERPARSTRAW, NUMBER_STRAWS, APOTEMASTRAWDETECTORMIN, RSTRAWDETECTORMAX, false, // printout flag; fSttTubeArray, STRAWRADIUS, VERTICALGAP, // outputs : fStrawCode, fStrawCode2 ); //---------------------------------------------------- // 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); ); //----------------------------------------- // calculate the sines and cosines for the Legiandre fit; // LEGIANDRE_NTHETADIV, input; // fSinus, output; // fCosine output; CalculateSinandCosin( ); // get the MCTrack array fMCTrackArray = (TClonesArray*) ioman->GetObject("MCTrack"); if ( ! fMCTrackArray) { cout << "-E- PndTrkTracking2::Init: No MCTrack array!" << endl; // return kERROR; } // ------------------------- get the SciTil hits if(fYesSciTil) { fSciTHitArray = (TClonesArray*) ioman->GetObject("SciTHit"); } else { fSciTHitArray = NULL; } //--------------------------- // ------------------------- get the SciTil MC Points if(fYesSciTil && doMcComparison) { fSciTPointArray = (TClonesArray*) ioman->GetObject("SciTPoint"); } else { fSciTPointArray = NULL; } //--------------------------- // Get input array these are the MC point of STT fSttPointArray = (TClonesArray*) ioman->GetObject("STTPoint"); if ( ! fSttPointArray ) { cout << "-W- PndSttHelixHitProducer::Init: " << "No STTPoint array, return!" << endl; return kERROR; } // Get input array hit of STT after digi fSttHitArray = (TClonesArray*) ioman->GetObject(fSttBranch); // fSttHitArray = (TClonesArray*) ioman->GetObject("STTHit"); if ( ! fSttHitArray ) { cout << "-W- PndTrkTracking2::Init: " << "No STTHit array, return!" << endl; return kERROR; } // ------------------------- get the Mvd hits fMvdPixelHitArray = (TClonesArray*) ioman->GetObject(fMvdPixelBranch); // fMvdPixelHitArray = (TClonesArray*) ioman->GetObject("MVDHitsPixel"); if ( !fMvdPixelHitArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD Pixel hitArray, return!" <GetObject(fMvdStripBranch); // fMvdStripHitArray = (TClonesArray*) ioman->GetObject("MVDHitsStrip"); if ( !fMvdStripHitArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD Strip hitArray, return!" <GetObject("MVDRiemannTrackCand"); if ( !fMvdTrackCandArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD TrackCand Array, return!" <GetObject("MVDPoint"); if ( !fMvdMCPointArray){ cout << "-W- PndTrkTracking2::Init: " << "No MVD MC Point Array, return!" <Register("SttMvdTrackCand","SttMvd",fSttMvdPndTrackCandArray, kTRUE); ioman->Register("SttMvdTrackCand","SttMvd",fSttMvdPndTrackCandArray, fPersistence); // Create and register output array for PndTrack of Stt+Mvd combined fSttMvdPndTrackArray = new TClonesArray("PndTrack"); ioman->Register("SttMvdTrack","SttMvd",fSttMvdPndTrackArray, fPersistence); //----------------------- // calculate the boundaries of the Box in Conformal Space, see Gianluigi logbook on pag. 210-211 Short_t i; Double_t A, r1, r2; fradiaConf[0] = 1./RSTRAWDETECTORMAX; r1 = APOTEMASTRAWDETECTORMIN; A = (RSTRAWDETECTORMAX - r1)/NRDIVCONFORMAL; if ( NRDIVCONFORMAL > 1 ) { for(i = 1; i< NRDIVCONFORMAL ; i++){ r2 = r1 + A; fradiaConf[NRDIVCONFORMAL-i] = 1./r2; r1=r2; } } return kSUCCESS; } //----------------------------------------- end of PndTrkTracking2::Init void PndTrkTracking2::SetParContainers() { FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb(); fSttParameters = (PndGeoSttPar*) rtdb->getContainer("PndGeoSttPar"); } void PndTrkTracking2::WriteHistograms(){ TFile* file = FairRootManager::Instance()->GetOutFile(); file->cd(); file->mkdir("PndTrkTracking2"); file->cd("PndTrkTracking2"); hdeltaRPixel->Write(); hdeltaRStrip->Write(); hdeltaRPixel2->Write(); hdeltaRStrip2->Write(); delete hdeltaRPixel; delete hdeltaRStrip; delete hdeltaRPixel2; delete hdeltaRStrip2; } // ----- Public method Exec -------------------------------------------- void PndTrkTracking2::Exec(Option_t* opt) { bool flag, intersect, outcome; //---------------------------------------------- /* 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"); */ //---------------------------------------------- bool GoodSkewFit[MAXTRACKSPEREVENT], keepit[MAXTRACKSPEREVENT], Mvdhits[MAXTRACKSPEREVENT], status[MAXTRACKSPEREVENT], SttSZfit[MAXTRACKSPEREVENT]; Short_t tnHitsInMCTrack[MAXTRACKSPEREVENT], tnMCParalAlone[MAXTRACKSPEREVENT], tnMCSkewAlone[MAXTRACKSPEREVENT], tnParalCommon[MAXTRACKSPEREVENT], tnSkewCommon[MAXTRACKSPEREVENT], tnSkewHitsInMCTrack[MAXTRACKSPEREVENT], tnSpuriParinTrack[MAXTRACKSPEREVENT], tnSpuriSkewinTrack[MAXTRACKSPEREVENT], // given a Hit number it gives its radial box number RConformalIndex[MAXSTTHITS], // given a Hit number it gives its azimuthal box number FiConformalIndex[MAXSTTHITS], tempore[MAXSTTHITS], 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], tParalCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tParSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewCommonList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], tSkewSpuriList[MAXTRACKSPEREVENT*MAXSTTHITSINTRACK], HitsinBoxConformal[MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL], Charge[MAXTRACKSPEREVENT], tdaTrackFoundaTrackMC[MAXTRACKSPEREVENT], resultFitSZagain[MAXTRACKSPEREVENT], statusflag[MAXTRACKSPEREVENT], SttStrawOn[NUMBER_STRAWS]; Vec nHitsInMCTrack(tnHitsInMCTrack, MAXTRACKSPEREVENT,"nHitsInMCTrack"), nMCParalAlone(tnMCParalAlone, MAXTRACKSPEREVENT,"nMCParalAlone"), nMCSkewAlone(tnMCSkewAlone, MAXTRACKSPEREVENT,"nMCSkewAlone"), nParalCommon(tnParalCommon,MAXTRACKSPEREVENT,"nParalCommon"), nSkewCommon(tnSkewCommon,MAXTRACKSPEREVENT,"nSkewCommon"), nSkewHitsInMCTrack(tnSkewHitsInMCTrack, MAXTRACKSPEREVENT,"nSkewHitsInMCTrack"), nSpuriParinTrack(tnSpuriParinTrack, MAXTRACKSPEREVENT,"nSpuriParinTrack"), nSpuriSkewinTrack(tnSpuriSkewinTrack, MAXTRACKSPEREVENT,"nSpuriSkewinTrack"), // given a Hit number it gives its radial box number // RConformalIndex(tRConformalIndex, MAXSTTHITS,"RConformalIndex"), // given a Hit number it gives its azimuthal box number // FiConformalIndex(tFiConformalIndex, MAXSTTHITS,"FiConformalIndex"), // tempore(ttempore, MAXSTTHITS,"tempore"), // nBoxConformal, first index -> radial divisions, // 2nd index -> azimuthal divisions; n. of hits falling in this cell. // nBoxConformal(tnBoxConformal, NRDIVCONFORMAL*NFIDIVCONFORMAL,"nBoxConformal"), ParalCommonList(tParalCommonList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"ParalCommonList"), ParSpuriList(tParSpuriList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"ParSpuriList"), SkewCommonList(tSkewCommonList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"SkewCommonList"), SkewSpuriList(tSkewSpuriList, MAXTRACKSPEREVENT*MAXSTTHITSINTRACK,"SkewSpuriList"), // HitsinBoxConformal(tHitsinBoxConformal, MAXHITSINCELL*NRDIVCONFORMAL*NFIDIVCONFORMAL,"HitsinBoxConformal"), // Charge(tCharge,MAXTRACKSPEREVENT,"Charge"), daTrackFoundaTrackMC(tdaTrackFoundaTrackMC,MAXTRACKSPEREVENT,"daTrackFoundaTrackMC"); // resultFitSZagain(tresultFitSZagain,MAXTRACKSPEREVENT,"resultFitSZagain"), // statusflag(tstatusflag,MAXTRACKSPEREVENT,"statusflag"), // SttStrawOn(tSttStrawOn,NUMBER_STRAWS,"SttStrawOn"); // SttStrawOn[i] >= 0 --> it is the Stt hit number corresponding to Stt // i-th Tube ID; SttStrawOn[i] == -1 --> i-th Stt straw NOT hit; memset(SttStrawOn,-1,sizeof(SttStrawOn)); //----------------------------------- Short_t nalone, ncand, nhitsinfit, Nint, NNN, nRemainingCandidates, npixelhitsintrack, nstriphitsintrack, nTotalCandidates, nXYZhits, i, iCluster, iexcl, 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, rotationangle, 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 PndTrkTracking2, fnMvdPixelHit is > maximum allowed (" <MAXMVDSTRIPHITS){ cout<<"from PndTrkTracking2, 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 PndTrkTracking2 : N. of MvdTrackCand = "<< fnMvdTrackCand<<" and it is > MAXMVDTRACKSPEREVENT (="<GetEntriesFast(); if (nSttMCPoint ==0){ if(istampa>0) cout<<"from PndTrkTracking2 : N. di Stt MC points = 0"<MAXSTTHITS){ cout<<"from PndTrkTracking2 : N. di Stt MC points = "< MAXSTTHITS ("<GetEntriesFast(); if (nSttHit ==0){ if (istampa >= 1) cout<<"from PndTrkTracking2 : N. di Stt Hits = 0, return!"< MAXSTTHITS) { cout<<"from PndTrkTracking2 : N. di Stt Hits = "< MAXSTTHITS (="<= 1) { cout<<"from PndTrkTracking2 : total # Hits in STT : "<At(i); // right way to extract the corrisponding MC point. ipunto= pSttHit->GetRefIndex(); // fTubeID[i] = STT tubeID correspondint to the hit number i ; // the STT tubeID goes from 1 to 4542 inclusive; fTubeID[i] = pSttHit->GetTubeID(); pSttTube = (PndSttTube *) fSttTubeArray->At(fTubeID[i]); // drift radius Double_t dradius = pSttHit->GetIsochrone(); // wire direction TVector3 wiredirection = pSttTube->GetWireDirection(); if(wiredirection.Z() >=0.) { WDX[i] = wiredirection.X(); WDY[i] = wiredirection.Y(); WDZ[i] = wiredirection.Z(); } else { WDX[i] = -wiredirection.X(); WDY[i] = -wiredirection.Y(); WDZ[i] = -wiredirection.Z(); } info[i][0]= pSttTube->GetPosition().X(); info[i][1]= pSttTube->GetPosition().Y(); info[i][2]= pSttTube->GetPosition().Z(); info[i][3]= dradius; info[i][4]= pSttTube->GetHalfLength(); //----------------------------------------- if(ipunto>=0) { puntator = (FairMCPoint*) fSttPointArray->At(ipunto); info[i][6]= puntator->GetTrackID(); } else { info[i][6]= -10.; } if( fabs( WDX[i] )< 0.00001 && fabs( WDY[i] )< 0.00001 ){ info[i][5]= 1.; fListSttParHits[nSttParHit]=i; nSttParHit++; } else { info[i][5]= 99.;// to signal that it is a skew straw. fListSttSkewHits[nSttSkewHit]=i; nSttSkewHit++; } // printout of the Stt hits; if (istampa >= 1 ) fPrint.stampaSttHits2(i,ipunto,dradius,WDX,WDY,WDZ,puntator,pSttTube,fTubeID[i]); } // end of for( i= 0; i< nSttHit; i++) // reordering the list of parallel hits ( fListSttParHits) by decreasing spatial radius; // first the outermost then the innermost. This is necessary because later the search // must starts from the outer hits. Initial_SttParHits_DecreasingR_Ordering( info, fListSttParHits,nSttParHit ); // fill the inclusion list for Stt, include only first hit for those straws with // multiple hits; fInclusionListStt is BY STT HIT NUMBER; MakeInclusionListStt(nSttHit, fTubeID, info); //----------------------------------- end of exclusion of straws with multiple hits // this MUST go after the MakeInclusionListStt for( i= 0; i< nSttHit; i++){ if(!fInclusionListStt[i]) continue; // SttStrawOn is a Short_t used in the XY track pattern finding later; it was initialized at -1; SttStrawOn[ fTubeID[i] - 1 ] = i; } // end of for( i= 0; i< nSttHit; i++) //-------------------------------------------- fetch the SciTil hits fnSciTilHits = 0; if( fSciTHitArray != NULL){ // number SciTil hits/event fnSciTilHits = fSciTHitArray->GetEntriesFast(); if(fnSciTilHits>MAXSCITILHITS){ cout<<"from PndTrkTracking2 : N. of SciTil Hits = "< MAXSCITILHITS (="< 0) fSciTilMaxNumber = fnSciTilHits ; else fSciTilMaxNumber = 1; Short_t nHitsInSciTile[fSciTilMaxNumber], OriginalSciTilList[fSciTilMaxNumber][fSciTilMaxNumber]; //-------- initialization (to 0) of nHitsInSciTile array; memset (nHitsInSciTile,0,sizeof(nHitsInSciTile)); //--- if(istampa>0) cout<<"from PndTrkTracking2, event "<0 ){ // OriginalSciTilList is the list of original SciTil hits (not purged yet) // present in a given SciTil tile : // OriginalSciTilList[nacceptedhit][*]; PndSciTHit *pPndSciTHit; TVector3 posiz; // the first SciTil hit; this cannot be duplicate hit by definition. // The Sci Tiles are numbered here according to the numbering // of the (first) SciTil Hit inside the Sci Tile. pPndSciTHit = (PndSciTHit*) fSciTHitArray->At(0); posiz = pPndSciTHit->GetPosition(); if(istampa>0)cout<<"from PndTrkTracking2 SciTil n. "<<0<< " not purged, Xpos "<< posiz.X()<<", Ypos "<< posiz.Y()<<", Zpos "<At(j); posiz = pPndSciTHit->GetPosition(); if(istampa>0)cout<<"from PndTrkTracking2 SciTil n. "<0){ cout<<"from PndTrkTracking2, after purging SciTil; # hits = "<0 ) //-----------------------------------end fetching SciTil hits. //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- //------------------- start the combined Mvd-Stt PR //------------------- //------------------- //------------------- //------------------- //------------------- //------------------------------------ start the timer; ftimer.Start(kTRUE); if(IVOLTE==0){ ftimer2.Start(kTRUE); } else { ftimer2.Start(kFALSE); } //---------------------------------------------------- // initialization of the (assumed) starting point of the tracks, at the origin; // needs to be modified later; trajectory_vertex[0]=trajectory_vertex[1]=0.; len = sizeof(Trajectory_Start); memset (Trajectory_Start,0,len); //-------------- PndTrkSttConformalFilling fill; fill.FromXYtoConformal( trajectory_vertex, info, fListSttParHits, nSttParHit, infoparalConformal, STRAWRADIUS ); // find the relevant Stt clusters in XY projection, necessary for the Pattern recognition PndTrkSttClusterFinder cluster; Short_t ListHitsinCluster[MAXFOUNDCLUSTERS*MAXHITSINCLUSTER], nFoundClusters, nHitsinCluster[MAXFOUNDCLUSTERS]; cluster.GetClusters( fInclusionListStt, // input; this is the exclusion of Stt hits for Stt multiple hits; fListParContiguous, // input list (axial Stt); first dimension is NUMBER_STRAWS; fListSttParHits, // input fnParContiguous, // input; number of contiguous straws (axial Stt); // NUMBER_STRAWS even if the numbering scheme for the Stt // straws goes from 1 to NUMBER_STRAWS included; nSttParHit, // input; MAXFOUNDCLUSTERS, // input; MAXHITSINCLUSTER, // input; MAXSTTHITS, // input; number of maximux allowed total Stt hits; NUMBER_STRAWS, // input; number of Stt Straws in total; fStrawCode, // input; fStrawCode2, // input; SttStrawOn, // input; fSttTubeArray, // input; array of the Stt tubes; fTubeID, // input; ListHitsinCluster, // output; nFoundClusters, // output; nHitsinCluster // output; ); //------------------------------------- stampe; if(istampa>=2){ cout<<"from PndTrkTracking2, evt "< 60, cint does NOT accept to pass them in the usual // way (parameters in the calling sequence) to PndTrkCTFindTrackInXY::FindTrackInXYProjection. FindTrackInXYProjection2_InputOutputData InOut; // loading those elements of the struct common to all the candidate tracks. InOut.apotemastrawdetectormin = APOTEMASTRAWDETECTORMIN; InOut.info = info; InOut.infoparalConformal = infoparalConformal; InOut.ListParContiguous = fListParContiguous; // array [NUMBER_STRAWS][6] large; list of Stt InOut.maxhitsinfit = MAXHITSINFIT; InOut.maxmvdpixelhitsintrack = MAXMVDPIXELHITSINTRACK; InOut.maxmvdstriphitsintrack = MAXMVDSTRIPHITSINTRACK; InOut.maxstthitsintrack = MAXSTTHITSINTRACK; InOut.minimumhitspertrack = MINIMUMHITSPERTRACK; InOut.nMvdPixelHit = fnMvdPixelHit; InOut.nMvdStripHit = fnMvdStripHit; InOut.nParContiguous = fnParContiguous; // array NUMBER_STRAWS large; nParContiguous[i] --> number of // contiguous Stt Straws (max = 6); InOut.number_straws = NUMBER_STRAWS; // r_stt_inner_par_max ==> radius of the circumscribed circumference to the //; outer hexagon defining THE INNER axial Stt straw region; InOut.r_stt_inner_par_max = APOTEMAMAXINNERPARSTRAW *2./sqrt(3.) ; InOut.StrawCode = fStrawCode; // Short_t array NUMBER_STRAWS large; InOut.StrawCode2 = fStrawCode2; // Short_t array NUMBER_STRAWS large; InOut.SttStrawOn = SttStrawOn; // tSttStrawOn[i] >= 0 --> it is the Stt hit number corresponding to Stt // i-th Tube ID; tSttStrawOn[i] == -1 --> i-th Stt straw NOT hit; InOut.TubeID = fTubeID; // list of Tube ID; fTubeID[i] is Tube Id of i-th Stt hit; InOut.thetamax = THETAMAX; InOut.thetamin = THETAMIN; InOut.XMvdPixel = fXMvdPixel; InOut.XMvdStrip = fXMvdStrip; InOut.YMvdPixel = fYMvdPixel; InOut.YMvdStrip = fYMvdStrip; //------------------- InOut.apotemamaxskewstraw = APOTEMAMAXSKEWSTRAW; InOut.Cosine = fCosine; InOut.deltanr = DELTAnR; InOut.dimensionscitil = DIMENSIONSCITIL; InOut.FiConformalIndex = FiConformalIndex; InOut.HitsinBoxConf = HitsinBoxConformal; InOut.InclusionListStt = fInclusionListStt; InOut.InclusionListSciTil = fInclusionListSciTil; InOut.legiandre_nthetadiv = LEGIANDRE_NTHETADIV; InOut.legiandre_nradiusdiv = LEGIANDRE_NRADIUSDIV; InOut.ListSttParHits = fListSttParHits; InOut.maxhitsinfit = MAXHITSINFIT; InOut.maxscitilhitsintrack = MAXSCITILHITSINTRACK; InOut.maxstthits = MAXSTTHITS; InOut.minouterhitspertrack = MINOUTERHITSPERTRACK; InOut.nBoxConf = nBoxConformal; InOut.nfidivconformal = NFIDIVCONFORMAL; InOut.nrdivconformal = NRDIVCONFORMAL; InOut.nSciTilHits = fnSciTilHits; InOut.nsttparhit = nSttParHit; InOut.posizSciT = fposizSciTil; InOut.radiaConf = fradiaConf; InOut.RConformalIndex = RConformalIndex; InOut.rstrawdetectormax = RSTRAWDETECTORMAX; InOut.Sinus = fSinus; InOut.strawradius = STRAWRADIUS; InOut.trajectory_vertex = trajectory_vertex; InOut.YesSciTil = fYesSciTil; //--------------------------------------------------------------------------------- // U and V only for the parallel Stt hits. Double_t U[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK], V[MAXTRACKSPEREVENT][MAXSTTHITSINTRACK]; // variable usedd in the plotting in the Legiandre plot; InOut.icounter=0; //----- loop over the parallel hits // begins the first iteration with more severe cuts on the # hits in track candidate int iconta=0; nSttTrackCand=0; // # tracks found for(iCluster=0; iCluster=2){ cout<<"Begin of Loop of Clusters; processing cluster n. "<=1){ cout<<" Loop of Clusters; this cluster (n. "<= MAXTRACKSPEREVENT) { cout<<"from PndTrkTracking2 : # n. Tracks found so far = " <= MAXTRACKSPEREVENT ( = " <=1){ cout<<" Loop of Clusters; this cluster (n. "<=1){ cout<<" Loop of Clusters; this cluster (n. "<=2){ cout<<"At the bottome of Loop of Clusters; end processing cluster n." <=1){ cout<<"\tstampa dopo FindTrackInXYProjection di tutte le trackCand rimaste :\n"; //fPrint.stampetta(IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0], fPrint.stampetta(IVOLTE,keepit,&fListMvdPixelHitsinTrack[0][0], &fListMvdStripHitsinTrack[0][0],&fListSttParHitsinTrack[0][0], &fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack, fnSttSkewHitsinTrack,fnSciTilHitsinTrack,nSttTrackCand, -1, // print all candidates; MAXMVDPIXELHITSINTRACK,MAXMVDSTRIPHITSINTRACK,MAXSCITILHITSINTRACK,MAXSTTHITSINTRACK,fR,fOx,fOy,FI0,KAPPA); } //-------------- fine stampa //----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- //----------- from here on, the XY parameters of the Helix don't change. ------------------ //----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- // use the risult just obtained from the fit in XY to do the association of the Skew Straw hits for(ncand=0; ncand< nTotalCandidates; ncand++) { if(!keepit[ncand]) continue; if( 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], fPrint.stampetta(IVOLTE,keepit,&fListMvdPixelHitsinTrack[0][0], &fListMvdStripHitsinTrack[0][0],&fListSttParHitsinTrack[0][0], &fListSttSkewHitsinTrack[0][0],&fListSciTilHitsinTrack[0][0], fnMvdPixelHitsinTrack,fnMvdStripHitsinTrack,fnSttParHitsinTrack, fnSttSkewHitsinTrack,fnSciTilHitsinTrack,nSttTrackCand, 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. nhitsinfit = nXYZhits + fnSttSkewHitsinTrack[ncand]; // 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], IVOLTE,keepit,&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. resultFitSZagain[ncand] = 0; // default value, corresponding to a bad SZ fit result; if(nhitsinfit>0){ // resultFitSZagain[ncand] = fit.FitSZspace( resultFitSZagain[ncand] = fit.FitSZspace_Chi2_AnnealingtheMvdOnly( nhitsinfit, // n. hits to be fitted tS, tZED, tDriftRadius, tErrorDriftRadius, FI0[ncand], MAXSKEWHITSINFIT,// maximum number of STT Skew hits in fit; &emme, IVOLTE*100+ncand // number of the accumulation plot. ); if( resultFitSZagain[ncand]==1){ KAPPA[ncand] = emme; GoodSkewFit[ncand] = true; if( ncand<= nSttTrackCand ) SttSZfit[ncand]=true; } else { keepit[ncand]=false; GoodSkewFit[ncand] = false; } } else { // continuation of if(nhitsinfit>0) keepit[ncand]=false; GoodSkewFit[ncand] = false; } // end of if(nhitsinfit>0) //-------------- stampa if(istampa>=2){ cout<<"stampa dopo FitSZspace, [not in Mvd track section], SttTrackCand n. "<=2){ cout<<"\tstampa dopo il Cleanup piccolo\n"; fPrint.stampetta( //IVOLTE,tkeepit,&fListMvdPixelHitsinTrack[0][0],&fListMvdStripHitsinTrack[0][0], IVOLTE,keepit,&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 //------------------------------- // reject tracks with too few or too many hits; for(ncand=0; ncand< nTotalCandidates; ncand++){ // check if the track candidate has still at least 2 axial hits; if( fnMvdPixelHitsinTrack[ncand]+fnMvdStripHitsinTrack[ncand]+fnSttParHitsinTrack[ncand]<2){ keepit[ncand]=false; continue; } // limit the total # Stt hits to MAXSTTHITSINTRACK if( fnSttSkewHitsinTrack[ncand]+fnSttParHitsinTrack[ncand] > MAXSTTHITSINTRACK ) { if(MAXSTTHITSINTRACK > fnSttSkewHitsinTrack[ncand]) fnSttParHitsinTrack[ncand]=MAXSTTHITSINTRACK-fnSttSkewHitsinTrack[ncand]; else fnSttParHitsinTrack[ncand]=0; } } // end of for(ncand=0; ncand< nTotalCandidates; ncand++) //--------------- // 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, // starting from candidate # 0 nTotalCandidates, // .... up to candidate # nTotalCandidates -1; 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;j0) { dime = nHitsSkew; } else { dime =1; } Double_t auxS[dime]; for(i=0;i1) cout<<"PndTrkTracking2, entra in TrackCleanup "<< "tracce normali, IVOLTE "<1){ for(ncand=0; ncand< nTotalCandidates; ncand++){ cout<<"evento n. "<0) { zmin = -FI0/KAPPA; zmax = (2.*PI-FI0)/KAPPA; } else { zmax = -FI0/KAPPA; zmin = (2.*PI-FI0)/KAPPA; } deltaz = zmax-zmin; for(i=0; i zmax ){ tempZ[sign]=fmod( tempZ[sign]-zmax, deltaz) + zmin; } else if (tempZ[sign] 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 PndTrkTracking2::AssociateSkewHitsToXYTrack //------------------------- begin of function PndTrkTracking2::CalculateSinandCosin void PndTrkTracking2::CalculateSinandCosin() { Short_t i; fDELTATHETA = (THETAMAX-THETAMIN)/LEGIANDRE_NTHETADIV; for(i=0;i& keepit, Vec & Mvdhits, Double_t info[][7], Short_t nSttParHit, // starting investigation from candidate n. StartTrackCand Short_t StartTrackCand, // until candidate n. EndTrackCand-1 included. Short_t EndTrackCand, Double_t *KAPPA, Double_t *FI0, Double_t *Fi_low_limit, Double_t *Fi_up_limit, Short_t *nParHitsinTrack, // input/output Short_t ListParHitsinTrack[][MAXSTTHITSINTRACK] // input/output ) { Short_t i, itrack, ihit, j, k, ntot, nadd; Double_t angle, deltaZ, dist, dist1, Zpos; const Double_t NTIMES=0.4; // const Double_t NTIMES=1.; for(itrack=StartTrackCand; itrack 1.e-20){ deltaZ = 2.*PI/KAPPA[itrack]; Zpos = (angle - FI0[itrack])/KAPPA[itrack]; if( fabs(Zpos-info[ihit][2])>1.5*info[ihit][4] && fabs(Zpos+deltaZ-info[ihit][2])>1.5*info[ihit][4] && fabs(Zpos-deltaZ-info[ihit][2])>1.5*info[ihit][4] ) continue; } if( angle>Fi_up_limit[itrack]){ angle -= 2.*PI; if(angle < Fi_low_limit[itrack]) continue; } else if (angle < Fi_low_limit[itrack]){ angle += 2.*PI; if(angle > Fi_up_limit[itrack]) continue; } dist1 = fabs( sqrt( (fOx[itrack]-info[ihit][0])*(fOx[itrack]-info[ihit][0])+ (fOy[itrack]-info[ihit][1])*(fOy[itrack]-info[ihit][1]) ) - fR[itrack] ); dist = fabs( dist1 - info[ihit][3] ); // info[ihit][3] = drift radius; if info[ihit][3]>dist then // the drift circle of this straw crosses the trajectory. if(dist dist ){ ListParHitsinTrack[itrack][ nParHitsinTrack[itrack] ] =ihit; nParHitsinTrack[itrack]++; } } // end of for(i=0; 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 PndTrkTracking2, this Pixel Mvd hit has a number = " < MAXMVDPIXELHITS (="<< MAXMVDPIXELHITS<<"), rejected!"<GetBranchId(fMvdStripBranch) && kStrip < MAXMVDSTRIPHITSINTRACK){ // the following is a protection because the maximum Mvd hit n. cannot // exceed MAXMVDSTRIPHITS . if( pndtrackcandhit.GetHitId()>MAXMVDSTRIPHITS ){ cout<<"from PndTrkTracking2, this Strip Mvd hit has a number = " < MAXMVDSTRIPHITS (="<< MAXMVDSTRIPHITS<<"), rejected!"<=0.){ fListMvdDSPixelHitNotTrackCand[fnMvdDSPixelHitNotTrackCand] = i; fnMvdDSPixelHitNotTrackCand++; } else { fListMvdUSPixelHitNotTrackCand[fnMvdUSPixelHitNotTrackCand] = i; fnMvdUSPixelHitNotTrackCand++; } } } for( i= 0; i< fnMvdStripHit ; i++){ if( ! finMvdTrackCandStrip[i] ){ if( fZMvdStrip[i]>=0.){ fListMvdDSStripHitNotTrackCand[fnMvdDSStripHitNotTrackCand] = i; fnMvdDSStripHitNotTrackCand++; } else { fListMvdUSStripHitNotTrackCand[fnMvdUSStripHitNotTrackCand] = i; fnMvdUSStripHitNotTrackCand++; } } } } //----------------------- end of function PndTrkTracking2::ExtractInfoFromMvdTrackCand //----------begin of function PndTrkTracking2::FindCharge void PndTrkTracking2::FindCharge( Double_t oX, Double_t oY, Short_t nParallelHits, Double_t *X, Double_t *Y, Short_t * Charge ) { Short_t ihit, nleft, nright; Double_t cross, disq, minl, minr; // this methods works with the hypothesis that this track comes // from (0,0) for(ihit=0, nleft=0, nright=0, minr = 9999999., minl = 9999999.; ihit0 hits stays 'on the left' (which means clockwise to go from the origin // to the hit following the smaller path) otherwise it stays 'on the right'. if (cross>0.) { disq = X[ihit]*X[ihit]+Y[ihit]*Y[ihit]; nleft++; } else { nright++; } } // end of for(ihit=0, nleft=0, nright=0;.... if( nright> nleft) { *Charge = -1; } else if ( nleft > nright) { *Charge = 1; } else { // then choose according the closest hit ti the center if( minr < minl ) *Charge = -1; else *Charge = 1; } } //----------end of function PndTrkTracking2::FindCharge //----------start of function PndTrkTracking2::FixDiscontinuitiesFiangleinSZplane void PndTrkTracking2::FixDiscontinuitiesFiangleinSZplane( Short_t 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 PndTrkTracking2::InfoXYZParal //--------begin of function PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering void PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering( Double_t info[][7], Short_t *ListSttParHi, Int_t nSttParHit ) { Short_t j, OLDListSttParHits[nSttParHit]; Int_t auxIndex[nSttParHit]; Double_t auxRvalues[nSttParHit]; // ordering the parallel hits by decreasing spatial radius. for (j = 0; j< nSttParHit; j++){ auxIndex[j]=j; auxRvalues[j]= info[ListSttParHi[ j ] ][0]*info[ListSttParHi[ j ] ][0]+ info[ListSttParHi[ j ] ][1]*info[ListSttParHi[ j ] ][1]; OLDListSttParHits[j]=ListSttParHi[j]; } PndTrkMergeSort Sorter; Sorter.Merge_Sort( (Short_t) nSttParHit, auxRvalues, auxIndex); for (j = 0; j< nSttParHit; j++){ ListSttParHi[ nSttParHit-1-j] = OLDListSttParHits[ auxIndex[ j ] ]; } return; } //--------end function PndTrkTracking2::Initial_SttParHits_DecreasingR_Ordering //---------------------- begin function PndTrkTracking2::LoadPndTrack_TrackCand void PndTrkTracking2::LoadPndTrack_TrackCand( bool * keepit, bool * SttSZfit, Short_t nTotalCandidates, Short_t * Charge, Int_t nSttTrackCand, Double_t *FI0, Double_t *KAPPA, Double_t info[][7], Double_t SchosenSkew[][MAXSTTHITS], Double_t ZchosenSkew[][MAXSTTHITS], Short_t *daTrackFoundaTrackMC ) { //------- load the new PndTrackCand ; each track has the STT and the Mvd hits associated //------- also load the new PndTrack ; each track has the STT and the Mvd hits associated Int_t ipinco, j, k, l, ncand ; Double_t ddd, dis, Distance, Oxx, Oyy, Ptras, Pxini, Pyini, Pzini, px, py, qop, x, y, Posiz1[3], versor[2] ; TVector3 ErrMomentum, ErrPosition, Momentum, Position ; for(ncand=0, ipinco = 0; ncand< nTotalCandidates; ncand++){ if(!keepit[ncand]) continue; // case in which there was no Skew hits and no KAPPA info and that // candidate could not be associated to any Mvd hits --> no KAPPA information! if(ncand1.e-20 ){ Pzini = -Charge[ncand]*0.003*fBFIELD/KAPPA[ncand]; if(fabs(Pzini) > PMAX) continue; } else { continue; } // PndTrackCand Array loading new((*fSttMvdPndTrackCandArray)[ipinco]) PndTrackCand; PndTrackCand *pTrckCand = (PndTrackCand*) fSttMvdPndTrackCandArray->At(ipinco); TVector3 dirSeed(Pxini,Pyini,Pzini); // momentum direction in starting point qop = Charge[ncand]/dirSeed.Mag(); dirSeed.SetMag(1.); pTrckCand->setTrackSeed(posSeed, dirSeed, qop); // pTrckCand->setMcTrackId( -1 ); pTrckCand->setMcTrackId( daTrackFoundaTrackMC[ncand] ); for(j=0; j< fnTrackCandHit[ncand]; j++){ switch (fListTrackCandHitType[ncand][j]){ case 0: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdPixelBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 1: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fMvdStripBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 2: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; case 3: pTrckCand->AddHit(FairRootManager::Instance()-> GetBranchId(fSttBranch), (Int_t)fListTrackCandHit[ncand][j],j); break; } } // PndTrack Array loading // last = last hit in found track; first = first hit in found track; // pTrckCand = pointer to the corresponding PndTrackCand. // the first hit if (fListTrackCandHitType[ncand][0] == 0){ // Mvd Pixel Posiz1[0] = fXMvdPixel[ fListTrackCandHit[ncand][0] ]; Posiz1[1] = fYMvdPixel[ fListTrackCandHit[ncand][0] ]; Posiz1[2] = fZMvdPixel[ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdPixel[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if (fListTrackCandHitType[ncand][0] == 1){ // Mvd Strip Posiz1[0] = fXMvdStrip[ fListTrackCandHit[ncand][0] ]; Posiz1[1] = fYMvdStrip[ fListTrackCandHit[ncand][0] ]; Posiz1[2] = fZMvdStrip[ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdStrip[ fListTrackCandHit[ncand][0] ]/sqrt(12.)); } else if( fListTrackCandHitType[ncand][0] == 2 ){ // it is a parallel straw hit InfoXYZParal( info, fListTrackCandHit[ncand][0], fOx[ncand], fOy[ncand], fR[ncand], KAPPA[ncand], FI0[ncand], Charge[ncand], Posiz1 ); // cases in which the calculation of the position failed, see // InfoXYZParal method. if(Posiz1[2]<-888888887. || Posiz1[0] < -999999998.) continue; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } else if ( fListTrackCandHitType[ncand][0] == 3 ){ // it is a skew straw hit Posiz1[0] = fOx[ncand]+fR[ncand]*cos(SchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]); Posiz1[1] = fOy[ncand]+fR[ncand]*sin(SchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]); Posiz1[2] = ZchosenSkew[ncand][ fListTrackCandHit[ncand][0] ]; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } Position.SetX( Posiz1[0] ); Position.SetY( Posiz1[1] ); Position.SetZ( Posiz1[2] ); versor[0] = fOx[ncand]-Posiz1[0]; versor[1] = fOy[ncand]-Posiz1[1]; Distance = sqrt(versor[0]*versor[0]+versor[1]*versor[1]); versor[0] /= Distance; versor[1] /= Distance; px = -Charge[ncand]*Ptras*versor[1]; py = Charge[ncand]*Ptras*versor[0]; Momentum.SetX(px); Momentum.SetY(py); Momentum.SetZ(Pzini); ErrMomentum.SetX(0.05*Ptras); // set at 5% all the times. ErrMomentum.SetY(0.05*Ptras); // set at 5% all the times. ErrMomentum.SetZ(0.05*Pzini); // set at 5% all the times. // the plane of this FairTrackParP better is perpendicular to // the momentum direction ddd = Ptras*sqrt(Ptras*Ptras+Pzini*Pzini); FairTrackParP first( Position, Momentum, ErrPosition, ErrMomentum, Charge[ncand], Position, TVector3(py/Ptras, -px/Ptras, 0.), // first vector defining the plane TVector3(Pzini*px/ddd,Pzini*py/ddd,-Ptras*Ptras/ddd) //second vector defining the plane ); // the last hit k = fnTrackCandHit[ncand]-1; if (fListTrackCandHitType[ncand][k] == 0){ // Mvd Pixel Posiz1[0] = fXMvdPixel[ fListTrackCandHit[ncand][k] ]; Posiz1[1] = fYMvdPixel[ fListTrackCandHit[ncand][k] ]; Posiz1[2] = fZMvdPixel[ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdPixel[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if (fListTrackCandHitType[ncand][k] == 1){ // Mvd Strip Posiz1[0] = fXMvdStrip[ fListTrackCandHit[ncand][k] ]; Posiz1[1] = fYMvdStrip[ fListTrackCandHit[ncand][k] ]; Posiz1[2] = fZMvdStrip[ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetY(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); ErrPosition.SetZ(fsigmaXMvdStrip[ fListTrackCandHit[ncand][k] ]/sqrt(12.)); } else if( fListTrackCandHitType[ncand][k] == 2 ){ // it is a parallel straw hit InfoXYZParal ( info, fListTrackCandHit[ncand][k], fOx[ncand], fOy[ncand], fR[ncand], KAPPA[ncand], FI0[ncand], Charge[ncand], Posiz1 ); if(Posiz1[2]<-888888887. || Posiz1[0] < -999999998.) continue; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } else if ( fListTrackCandHitType[ncand][k] == 3 ){ // it is a skew straw hit Posiz1[0] = fOx[ncand]+fR[ncand]*cos(SchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]); Posiz1[1] = fOy[ncand]+fR[ncand]*sin(SchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]); Posiz1[2] = ZchosenSkew[ncand][ fListTrackCandHit[ncand][k] ]; ErrPosition.SetX(0.02); // 200 microns ErrPosition.SetY(0.02); // 200 microns ErrPosition.SetZ(1.); // 1 cm } Position.SetX( Posiz1[0] ); Position.SetY( Posiz1[1] ); Position.SetZ( Posiz1[2] ); versor[0] = fOx[ncand]-Posiz1[0]; versor[1] = fOy[ncand]-Posiz1[1]; Distance = sqrt(versor[0]*versor[0]+versor[1]*versor[1]); versor[0] /= Distance; versor[1] /= Distance; px = -Charge[ncand]*Ptras*versor[1]; py = Charge[ncand]*Ptras*versor[0]; Momentum.SetX(px); Momentum.SetY(py); Momentum.SetZ(Pzini); // the plane of this FairTrackParP better is perpendicular to // the momentum direction ddd = Ptras*sqrt(Ptras*Ptras+Pzini*Pzini); FairTrackParP last( Position, Momentum, ErrPosition, ErrMomentum, Charge[ncand], Position, TVector3(py/Ptras, -px/Ptras, 0.), // first vector defining the plane TVector3(Pzini*px/ddd,Pzini*py/ddd,-Ptras*Ptras/ddd) //second vector defining the plane ); // loading actually the PndTrack PndTrack *pTrck = new((*fSttMvdPndTrackArray)[ipinco]) PndTrack(first,last,*pTrckCand); pTrck->SetRefIndex(ipinco); pTrck->SetFlag(0); ipinco++; } // end of for(ncand=0, ipinco = 0; ncand< nTotalCandidates; ncand++) } //----------end function PndTrkTracking2::LoadPndTrack_TrackCand //----------begin function PndTrkTracking2::LoadSZetc_forSZfit void PndTrkTracking2::LoadSZetc_forSZfit( Short_t ncand, // input Short_t nhitsinfit, 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<<"from PndTrkTracking2 : appena prima arbitration, IVOLTE = "<< IVOLTE<<", Stt track cand = "<& keepit, bool * keepit, Short_t FirstCandidate, Short_t LastCandidate, Double_t info[][7], Double_t Trajectory_Start[][2], // Vec & CHARGE, Short_t * CHARGE, Double_t SchosenSkew[][MAXSTTHITS] ) { Short_t ncand; for(ncand=FirstCandidate; ncand< LastCandidate; ncand++){ // for small radius trajectory better the ordering with conformal. if( fR[ncand]< RSTRAWDETECTORMAX/2.){ OrderingConformal_Loading_ListTrackCandHit( keepit, ncand, info, Trajectory_Start, CHARGE, SchosenSkew ); } else { // otherwise it is better distance from (0,0) method. OrderingR_Loading_ListTrackCandHit( keepit, ncand, info ); } } // end of for(ncand=FirstCandidate; ncand< LastCandidate; ncand++) return; } //----------end of function PndTrkTracking2::Ordering_Loading_ListTrackCandHit //----------begin of function PndTrkTracking2::OrderingR_Loading_ListTrackCandHit void PndTrkTracking2::OrderingR_Loading_ListTrackCandHit( bool* keepit, Short_t ncand, Double_t info[][7] ) { Short_t i, j, ipar, iskew; PndTrkMergeSort MergeSort; // ordering all the hits belonging to the candidate track, by increasing fR; // forming the new track with Mvd+Stt hits if(!keepit[ncand]) return; fnTrackCandHit[ncand] =fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand]+ fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; Short_t tempmvdindex[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ], tempmvdtype[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; Int_t auxIndex[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; Double_t auxR[fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] ]; // adding the Mvd hits (Pixel and Strips) for(i=0; i< fnMvdPixelHitsinTrack[ncand]; i++){ auxR[i] = fXMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]* fXMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]+ fYMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]* fYMvdPixel[ fListMvdPixelHitsinTrack[ncand][i] ]; tempmvdindex[i]=fListMvdPixelHitsinTrack[ncand][i]; tempmvdtype[i]=0; auxIndex[i] = i; } for(i=0; i< fnMvdStripHitsinTrack[ncand]; i++){ auxR[i+fnMvdPixelHitsinTrack[ncand]] = fXMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]* fXMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]+ fYMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]* fYMvdStrip[ fListMvdStripHitsinTrack[ncand][i] ]; tempmvdindex[i+fnMvdPixelHitsinTrack[ncand]]= fListMvdStripHitsinTrack[ncand][i]; tempmvdtype[i+fnMvdPixelHitsinTrack[ncand]]=1; auxIndex[i+fnMvdPixelHitsinTrack[ncand]]= i+fnMvdPixelHitsinTrack[ncand]; } // ordering the Mvd Hits if( fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand] >0){ MergeSort.Merge_Sort( fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand], auxR, auxIndex); // constructing the first part of the ordered new Track Candidate for(i=0; i< fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; i++){ fListTrackCandHit[ncand][i] = tempmvdindex[ auxIndex[i] ]; fListTrackCandHitType[ncand][i] = tempmvdtype[ auxIndex[i] ]; } } // end of if( fnMvdPixelHitsinTrack[ncand]+ // construction of the second part of the ordered new Track Candidate Short_t tempmvdindex2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ], tempmvdtype2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; Int_t auxIndex2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; Double_t auxR2[fnSttParHitsinTrack[ncand]+ fnSttSkewHitsinTrack[ncand] ]; for(i=0; i0){ MergeSort.Merge_Sort( fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand], auxR2, auxIndex2); for(j=0,ipar=0,iskew=0; j< fnSttParHitsinTrack[ncand]+fnSttSkewHitsinTrack[ncand];j++){ i = j+fnMvdPixelHitsinTrack[ncand]+ fnMvdStripHitsinTrack[ncand]; fListTrackCandHit[ncand][i] = tempmvdindex2[ auxIndex2[j] ]; fListTrackCandHitType[ncand][i] = tempmvdtype2[ auxIndex2[j] ]; if( fListTrackCandHitType[ncand][i]==2) { fListSttParHitsinTrack[ncand][ipar]=tempmvdindex2[auxIndex2[j]]; ipar++; } else { fListSttSkewHitsinTrack[ncand][iskew]=tempmvdindex2[auxIndex2[j]]; iskew++; } } } // end of if( fnSttParHitsinTrack[ncand]+ return; } //----------end of function PndTrkTracking2::OrderingR_Loading_ListTrackCandHit //----------begin of function PndTrkTracking2::OrderingSttSkewandSttParallel void PndTrkTracking2::OrderingSttSkewandSttParallel( Double_t oX, Double_t oY, Double_t Rr, Short_t nSkewhit, Short_t *ListSkewHits, Double_t *SList, // this is rekated to the skew hits. IMPORTANT : // the index must be the ORIGINAL skew hit number, // therefore SList[Infoskew[ListSkewHits[*]]]. Short_t Charge, Short_t nParHits, Short_t *ListParHits, Double_t *U, Double_t *V, Short_t *BigList // this is the final ordered Parallel+Skew list; // already in NATIVE hit number. ) { Short_t i, j, tmp[nSkewhit+nParHits], tmpList[nSkewhit]; Int_t index[nSkewhit+nParHits]; Double_t aaa, b1, sign, aux[nSkewhit+nParHits]; PndTrkMergeSort MergeSort; // here there is the ordering of the hits, under the assumption that the circumference // in XY goes through (0,0). // Moreover, the code before is supposed to have selected trajectories in XY with (fOx,fOy) // farther from (0,0) by > 0.9 * RminStrawDetector/2 and consequently fOx and fOy are not both 0. // The scheme for the ordering of the hit is as follows : // 1) order hits by increasing U of the conformal mapping; see Gianluigi's Logbook page 283; // 2) find the charge of the track by checking if it is closest to the center in XY // the first or the last of the ordered hits. // ordering of the hits aaa = atan2( oY, oX); // atan2 defined between -PI and PI. // the following statement is necessary since for unknown reason the root interpreter // gives a weird error when using PI directly in the if statement below!!!!!!! I lost // 2 hours trying to figure this out! b1 = PI/4.; if(aaa>b1&&aaa<3.*b1|| (aaa>-3.*b1&&aaa<-b1)){ // case #1 or #3;see Gianluigi's Logbook page 285. if( (aaa>b1&&aaa<3.*b1 && Charge == -1)||( aaa>-3.*b1&&aaa<-b1 && Charge == 1) ) { // for speeding up the ordering taking advantage // that the parallel hits were earlier ordered and // apply the trick of multiplying by -1. sign=-1.; } else { // normal calculation sign=1.; } for (j = 0 ; j< nParHits; j++){ aux[j] = sign*U[j]; } for (j = 0; j< nSkewhit; j++){ // this is U in conformal space aux[j+nParHits]=sign*(oX + Rr*cos(SList[ListSkewHits[j]]))/ (oX*oX+oY*oY+Rr*Rr + 2.*Rr* (oX*cos(SList[ListSkewHits[j]]) +oY*sin(SList[ListSkewHits[j]]))); } } else { // use V as ordering variable // [case 2 and 4 Gianluigi's Logbook page 285]. if( ((aaa<=-3.*b1|| aaa>=3.*b1) && Charge == -1) || ( -b1 <= aaa && aaa <= b1 && Charge == 1) ){ sign=-1.; } else { sign=1.; } for (j = 0 ; j< nParHits; j++){ aux[j] = sign*V[j]; } for (j = 0; j< nSkewhit; j++){ // this is V in conformal space. aux[j+nParHits]=sign*(oY + Rr*sin(SList[ListSkewHits[j]]))/ (oX*oX+oY*oY+Rr*Rr + 2.*Rr* (oX*cos(SList[ListSkewHits[j]]) +oY*sin(SList[ListSkewHits[j]]))); } } // end of if((aaa>b1&& .... for (j = 0 ; j< nParHits; j++){ BigList[j]=ListParHits[j]; index[j] = j; } for (j = 0; j< nSkewhit; j++){ BigList[j+nParHits]=ListSkewHits[j]; index[j+nParHits] = j+nParHits; } MergeSort.Merge_Sort( nSkewhit+nParHits, aux, index); for(i=0, j=0;i= nParHits ){ tmpList[j] = ListSkewHits[index[i]-nParHits]; j++; } } for(i=0;i 0.9 * RminStrawDetector/2 and consequently fOx and fOy are not both 0. // The scheme for the ordering of the hit is as follows : // 1) order hits by increasing U or V of the conformal mapping; see Gianluigi's Logbook page 283; // 2) find the charge of the track by checking if it is closest to the center in XY // the first or the last of the ordered hits. // 3) in case, invert the ordering of U, V and ListHits such that the first hits in the // list are always those closer to the Trajectory_Start. // ordering of the hits aaa = atan2( oY-Traj_Sta[1], oX-Traj_Sta[0]); // atan2 defined between -PI and PI. // the following statement is necessary since for unknown reason the root interpreter // gives a weird error when using PI directly in the if statement below!!!!!!! I lost // 2 hours trying to figure this out! b1 = PI/4.; if((aaa>b1&&aaa<3.*b1) || (aaa>-3.*b1&&aaa<-b1)){//use U as ordering variable; //[case 1 or 3 Gianluigi's Logbook page 285]. for (j = 0; j< nHits; j++){ bbb = XY[j][0]-Traj_Sta[0]; ccc = XY[j][1]-Traj_Sta[1]; U[j]= bbb/(bbb*bbb+ccc*ccc); } MergeSort.Merge_Sort( nHits, U, ListHits); if((aaa>b1&&aaa<3.*b1)){ // case #1; if( Charge == -1){ // inverting the order of the hits. for(i=0;ib1&&aaa<3.*b1)) } else { // use V as ordering variable [case 2 or 4 Gianluigi's Logbook page 285]. for (j = 0; j< nHits; j++){ bbb = XY[j][0]-Traj_Sta[0]; ccc = XY[j][1]-Traj_Sta[1]; V[j]= ccc/(bbb*bbb+ccc*ccc); } MergeSort.Merge_Sort( nHits, V, ListHits); if((aaa<=-3.*b1 || aaa>=3.*b1)){ // case #2; if( Charge == -1){ // inverting the order of the hits. for(i=0;ib1&& .... return; } //----------end of function PndTrkTracking2::OrderingUsingConformal //------------------ begin function PndTrkTracking2::RefitMvdStt void PndTrkTracking2::RefitMvdStt( Short_t nCandHit, Short_t *ListCandHit, Short_t *ListCandHitType, Double_t info[][7], Double_t rotationangle, // this is between 0. and 2*PI Double_t tv[2], Short_t iexcl, Double_t *pAlfa, // output of the fit Double_t *pBeta, // output of the fit Double_t *pGamma,// set at zero always for now bool *status // fit status; true = successful ) { bool Type; Short_t i, iparallel; Short_t exitstatus; Double_t dist2, mindis, emme, factor, gamma, qu, ErrorStraw = 0.03, ErrorMvd = 0.01, Xconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], Yconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], DriftRadiusconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK], ErrorDriftRadiusconformal[MAXSTTHITSINTRACK+MAXMVDPIXELHITSINTRACK+MAXMVDSTRIPHITSINTRACK]; // PndTrkGlpkFits fit; // PndTrkLegendreFits fit; PndTrkChi2Fits fit; *status= false; factor=3.; mindis=0.5; for(i=0, iparallel=0; i 0, Type= true --> fit ok, it is a Circle in XY; // existatus > 0, Type= false --> fit ok, it is a Straigh Line in XY; // existatus < 0, fit failed; Type was set to false in this case; if( exitstatus > 0 && Type) *status=true; return; } //------------------ end function PndTrkTracking2::RefitMvdStt ClassImp(PndTrkTracking2)