// ------------------------------------------------------------------------- // ----- PndSttTrackFinderReal source file ----- // ----- Created 28/03/06 by V. Friese ----- // ------------------------------------------------------------------------- #include "glpk.h" // Pnd includes #include "PndSttTrackFinderReal.h" #include "PndSttHit.h" #include "PndSttPoint.h" #include #include "FairMCPoint.h" #include "FairRootManager.h" #include "GFKalman.h" // ROOT includes #include "TClonesArray.h" #include "TDatabasePDG.h" #include "TRandom.h" #include "TH1.h" #include "TH2.h" #include "TH3.h" // C++ includes #include #include using std::cout; using std::cin; using std::endl; using std::map; // ----- Default constructor ------------------------------------------- PndSttTrackFinderReal::PndSttTrackFinderReal() { fVerbose = 1; MINIMUMOUTERHITSPERTRACK=5; Fimin=0.; Fimax=2.*PI; FI0min = 0.; FI0max = 2.*PI; stepD=(Dmax-Dmin)/nbinD; stepFi=(Fimax-Fimin)/nbinFi; stepR=(Rmax-Rmin)/nbinR; stepKAPPA=(KAPPAmax-KAPPAmin)/nbinKAPPA; stepFI0=(FI0max-FI0min)/nbinFI0; stepfineKAPPA=2.*DELTA_KAPPA/nbinKAPPA; stepfineFI0=2.*DELTA_FI0/nbinFI0; RminStrawSkewArea = RStrawDetectorMin*2./1.732051 + 18.*StrawRadius ; // delimitation of the skew area RmaxStrawSkewArea = RminStrawSkewArea + 8.*1.732051 *StrawRadius ; } // ------------------------------------------------------------------------- // ----- Standard constructor ------------------------------------------ PndSttTrackFinderReal::PndSttTrackFinderReal(Int_t verbose) { fVerbose = verbose; MINIMUMOUTERHITSPERTRACK=5; Fimin=0.; Fimax=2.*PI; FI0min = 0.; FI0max = 2.*PI; stepD=(Dmax-Dmin)/nbinD; stepFi=(Fimax-Fimin)/nbinFi; stepR=(Rmax-Rmin)/nbinR; stepKAPPA=(KAPPAmax-KAPPAmin)/nbinKAPPA; stepFI0=(FI0max-FI0min)/nbinFI0; stepfineKAPPA=2.*DELTA_KAPPA/nbinKAPPA; stepfineFI0=2.*DELTA_FI0/nbinFI0; RminStrawSkewArea = RStrawDetectorMin*2./1.732051 + 18.*StrawRadius ; // delimitation of the skew area RmaxStrawSkewArea = RminStrawSkewArea + 8.*1.732051 *StrawRadius ; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndSttTrackFinderReal::~PndSttTrackFinderReal() { } // ------------------------------------------------------------------------- // ----- Public method Init -------------------------------------------- void PndSttTrackFinderReal::Init() { UShort_t i, j, k; Double_t r1, r2, A , rConfMin, rConfMax, tempRadiaConf[nRdivConformal]; IVOLTE=0; ntimes = 0; // Get and check FairRootManager FairRootManager* ioman = FairRootManager::Instance(); // get the MCTrack array fMCTrackArray = (TClonesArray*) ioman->ActivateBranch("MCTrack"); // ------------------------------------------------------------------- // -------------------- initializations for the Kalman with Genfit later /* fSttHitArray=(TClonesArray*) ioman->GetObject("STTHit"); if(fSttHitArray==0){ Error("PndSttKalmanTask2::Init","stt pattern recognition; hit-array not found!"); return ; } // Build hit factory ----------------------------- _theRecoHitFactory = new GFRecoHitFactory(); _theRecoHitFactory->addProducer(3, new GFRecoHitProducer(fSttHitArray)); // */ // -------------------- end initializations for the Kalman with Genfit later if (!ioman) { cout << "-E- PndSttTrackFinderReal::Init: " << "RootManager not instantised!" << endl; return; } // calculate the boundaries of the Box in Conformal Space, see Gianluigi logbook on pag. 210-211 radiaConf[0] = 1./RStrawDetectorMax; r1 = RStrawDetectorMin; // A = (RStrawDetectorMax*RStrawDetectorMax - r1)/nRdivConformal; A = (RStrawDetectorMax - r1)/nRdivConformal; if ( nRdivConformal > 1 ) { for(i = 1; i< nRdivConformal ; i++){ r2 = r1 + A; // tempRadiaConf[nRdivConformal-i] = 1./sqrt(r2); tempRadiaConf[nRdivConformal-i] = 1./r2; r1=r2; } } rConfMin = 1./RmaxStrawSkewArea; rConfMax = 1./RminStrawSkewArea; // now take into account the zone of the skew straws, which is 'empty' as far as the parallel straws is concerned for(i = 1; i< nRdivConformal ; i++){ radiaConf[i] = tempRadiaConf[i]; } nRdivConformalEffective = nRdivConformal; } // ------------------------------------------------------------------------- // ----- Public method DoFind ------------------------------------------ Int_t PndSttTrackFinderReal::DoFind(TClonesArray* trackArray) { UShort_t auxIndex[nmaxHits], OLDinfoparal[nmaxHits]; UShort_t istep,inclination_type; Double_t aaa, ddd, delta, deltabis, deltaZ, mindis, distanza, X, Y, Z, ap1, ap2, ap3, cross1, cross2, cross3, info[nmaxHits][6], WDX, WDY, WDZ, auxRvalues[nmaxHits], inclinationversors[nmaxinclinationversors][3]; inclinationversors[0][0]=inclinationversors[0][1]=0., inclinationversors[0][2]=1.; Int_t Ninclinations = 1, Ninclinate; Int_t Minclinations[nmaxinclinationversors]; // Check pointers if (fHitCollectionList.GetEntries() == 0) { cout << "-E- PndSttTrackFinderReal::DoFind: " << "No hit arrays present, call AddHitCollection() first (at least once)! " << endl; return -1; } if (fPointCollectionList.GetEntries() == 0) { cout << "-E- PndSttTrackFinderReal::DoFind: " << "No point arrays present, call AddHitCollection() first (at least once)! " << endl; return -1; } if ( !trackArray ) { cout << "-E- PndSttTrackFinderReal::DoFind: " << "Track array missing! " << endl; return -1; } PndMCTrack* pMCtr = NULL; nMCTracks = fMCTrackArray->GetEntriesFast(); // num. tracce/evento if(nMCTracks>MAXMCTRACKS){ cout<<"from DoFind : nMCTracks = "<At(iMCTrack); if ( ! pMCtr ) continue; Double_t R, D, Fi, Ox, Oy, Cx, Cy, Px, Py ; Int_t icode; icode = pMCtr->GetPdgCode() ; // PDG code of track Ox = pMCtr->GetStartVertex().X(); // X of starting point track Oy = pMCtr->GetStartVertex().Y(); // Y of starting point track Px = pMCtr->GetMomentum().X(); Py = pMCtr->GetMomentum().Y(); aaa = sqrt( Px*Px + Py*Py); R = aaa*1000./(BFIELD*CVEL); // R (cm) of Helix of track projected in XY plane; B = 2 Tesla if( icode > 0 ) { Cx = Ox -Py*1000./(BFIELD*CVEL); // MC truth X of center of circle of Helix trajectory Cy = Oy + Px*1000./(BFIELD*CVEL); // MC truth Y of center of circle of Helix trajectory } else { Cx = Ox + Py*1000./(BFIELD*CVEL); // MC truth X of center of circle of Helix trajectory Cy = Oy - Px*1000./(BFIELD*CVEL); // MC truth Y of center of circle of Helix trajectory } Fi = atan2(Cy, Cx); // MC truth Fi angle of circle of Helix trajectory if(Fi<0.) Fi += 2.*PI; D = sqrt( Cx*Cx+Cy*Cy) - R; CxMC[iMCTrack]= Cx; CyMC[iMCTrack]= Cy; R_MC[iMCTrack]= R; MCtruthTrkInfo[0][iMCTrack] = Ox; // X of starting point track MCtruthTrkInfo[1][iMCTrack] = Oy; // Y of starting point track MCtruthTrkInfo[2][iMCTrack] = pMCtr->GetStartVertex().Z(); // Z of starting point track MCtruthTrkInfo[3][iMCTrack] = Px; // Px at starting point of track MCtruthTrkInfo[4][iMCTrack] = Py; // Py at starting point of track MCtruthTrkInfo[5][iMCTrack] = pMCtr->GetMomentum().Z(); // Pz at starting point of track MCtruthTrkInfo[6][iMCTrack] = D; // D of Helix of track projected in XY plane MCtruthTrkInfo[7][iMCTrack] = Fi; // Fi of Helix of track projected in XY plane MCtruthTrkInfo[8][iMCTrack] = R; // R of Helix of track projected in XY plane MCtruthTrkInfo[9][iMCTrack] = Cx; // Cx of Helix of track projected in XY plane MCtruthTrkInfo[10][iMCTrack] = Cy; // Cy of Helix of track projected in XY plane MCtruthTrkInfo[11][iMCTrack] = icode ; // PDG code of track MCtruthTrkInfo[12][iMCTrack] = 0.001*BFIELD*CVEL/MCtruthTrkInfo[5][iMCTrack] ; // KAPPA of Helix of track in cm*-1 double tempoang = atan2(-MCtruthTrkInfo[10][iMCTrack]+MCtruthTrkInfo[1][iMCTrack], -MCtruthTrkInfo[9][iMCTrack]+MCtruthTrkInfo[0][iMCTrack]); if(tempoang<0.) tempoang+= 2.*PI; MCtruthTrkInfo[13][iMCTrack] = tempoang ; // FI0 of Helix of track nHitsInMCTrack[iMCTrack] = 0; nSkewHitsInMCTrack[iMCTrack] = 0; } IVOLTE++; // Initialise control counters Int_t nNoTrack = 0; Int_t nNoSttPoint = 0; Int_t nNoSttHit = 0; // Create pointers to hit and SttPoint PndSttHit* pMhit = NULL; FairMCPoint* pMCpt = NULL; // Number of STT hits Int_t nHits = 0; for (Int_t hitListCounter = 0; hitListCounter < fHitCollectionList.GetEntries(); hitListCounter++) { nHits += ((TClonesArray *)fHitCollectionList.At(hitListCounter))->GetEntriesFast(); } if(nHits > nmaxHits ) { cout<<"From DoFind : nHits = "< > hitMap; for(Int_t j=0; jGetRefIndex(); if (ptIndex < 0) continue; // fake or background hit pMCpt = GetPointFromCollections(iHit); // <== FairMCPoint if (!pMCpt) continue; // real hit center of tube coordinates TVector3 center(pMhit->GetX(), pMhit->GetY(), pMhit->GetZ()); // drift radius Double_t dradius = pMhit->GetIsochrone(); // wire direction TVector3 wiredirection = pMhit->GetWireDirection(); // "real" MC coordinates (in + out)/2. TVector3 mcpoint( ((PndSttPoint*)pMCpt)->GetXtot(), ((PndSttPoint*)pMCpt)->GetYtot(), ((PndSttPoint*)pMCpt)->GetZtot()); if(wiredirection.Z() >=0.) { WDX = wiredirection.X(); WDY = wiredirection.Y(); WDZ = wiredirection.Z(); } else { WDX = -wiredirection.X(); WDY = -wiredirection.Y(); WDZ = -wiredirection.Z(); } // stampe di controllo info[iHit][0]= pMhit->GetX(); info[iHit][1]= pMhit->GetY(); info[iHit][2]= pMhit->GetZ(); info[iHit][3]= dradius; info[iHit][4]=pMhit->GetTubeHalfLength(); if( fabs( WDX )< 0.00001 && fabs( WDY )< 0.00001 ){ info[iHit][5]= 1.; infoparal[Minclinations[0]]= iHit ; Minclinations[0]++; ZCENTER_STRAIGHT = info[iHit][2]; // this works because just few lines below there is the SEMILENGTH_STRAIGHT = info[iHit][4]; // requirement that Minclinations[0] > 2 (= at least 3 parallel straws) } else { for (Int_t i=2; i<=Ninclinations;i++) { if (fabs( WDX-inclinationversors[i-1][0] )< 0.00001 && fabs( WDY -inclinationversors[i-1][1])< 0.00001 && fabs( WDZ -inclinationversors[i-1][2])< 0.00001 ){ info[iHit][5]= i; infoskew[Ninclinate]= iHit; Ninclinate++; Minclinations[i-1]++; goto jumpout; } } Ninclinations++; inclinationversors[Ninclinations-1][0]=(Double_t) WDX; inclinationversors[Ninclinations-1][1]=(Double_t) WDY; inclinationversors[Ninclinations-1][2]=(Double_t) WDZ; info[iHit][5]= Ninclinations; infoskew[Ninclinate]= iHit; Ninclinate++; Minclinations[Ninclinations-1]++; jumpout: ; } NSkewhits = Ninclinate; // calcoli validi solo per il MC ----------------------------- veritaMC[iHit][0]= ((PndSttPoint*)pMCpt)->GetXtot(); veritaMC[iHit][1]= ((PndSttPoint*)pMCpt)->GetYtot(); veritaMC[iHit][2]= ((PndSttPoint*)pMCpt)->GetZtot(); // association of this hit (in this part only if it is a 'parallel hit')to the MC track if(info[iHit][5]==1. ){ deltabis = 9999999999.; FromHitToMCTrack[iHit] = 888888888; // just some large unrealistic number for( Int_t iMCTrack = 0; iMCTrack < nMCTracks; iMCTrack++){ delta = fabs( sqrt(R_MC[iMCTrack]*R_MC[iMCTrack]+info[iHit][3]*info[iHit][3]-StrawRadius*StrawRadius )+ info[iHit][3] - sqrt( (info[iHit][0]-CxMC[iMCTrack])*(info[iHit][0]-CxMC[iMCTrack]) + (info[iHit][1]-CyMC[iMCTrack])*(info[iHit][1]-CyMC[iMCTrack]) ) ); if( delta < deltabis && delta < 4.*StrawRadius) { FromHitToMCTrack[iHit] = iMCTrack; deltabis = delta; } } if(FromHitToMCTrack[iHit]< MAXMCTRACKS){ FromMCTrackToHit[ FromHitToMCTrack[iHit] ][ nHitsInMCTrack[ FromHitToMCTrack[iHit] ]] = iHit; nHitsInMCTrack[ FromHitToMCTrack[iHit] ]++ ; } //---------------------------------------------------------------- } // end of if(info[iHit][5]==1. ) } // end of for (Int_t iHit = 0; //------------------------------------------------------------------------------------------ // associazione degli hits non paralleli // Loop over hits for (Int_t iHit = 0; iHit < nHits; iHit++) { if(info[iHit][5]==1. ) continue; FromSkewHitToMCTrack[iHit] = 888888888; // just some large unrealistic number inclination_type = (UShort_t) info[iHit][5] -1; deltaZ = 2.*info[iHit][4]*inclinationversors[inclination_type][2]/2000.; for (Int_t iMCTrack = 0; iMCTrack < nMCTracks; iMCTrack++) { // now the stepping for(istep=0, mindis=99999999999.; istep<2000; istep++){ Z = istep*deltaZ + info[iHit][2] - info[iHit][4]*inclinationversors[inclination_type][2]; X = MCtruthTrkInfo[9][iMCTrack] + MCtruthTrkInfo[8][iMCTrack]*cos( MCtruthTrkInfo[13][iMCTrack]+ MCtruthTrkInfo[12][iMCTrack]*Z); Y = MCtruthTrkInfo[10][iMCTrack] + MCtruthTrkInfo[8][iMCTrack]*sin( MCtruthTrkInfo[13][iMCTrack]+ MCtruthTrkInfo[12][iMCTrack]*Z); ap1 = info[iHit][0]-X; ap2 = info[iHit][1]-Y; ap3 = info[iHit][2]-Z; cross1 = ap2*inclinationversors[inclination_type][2]-ap3*inclinationversors[inclination_type][1]; cross2 = ap3*inclinationversors[inclination_type][0]-ap1*inclinationversors[inclination_type][2]; cross3 = ap1*inclinationversors[inclination_type][1]-ap2*inclinationversors[inclination_type][0]; distanza = sqrt( cross1*cross1+cross2*cross2+cross3*cross3) ; if(distanza0 && Minclinations[0] > 2 ) { PndSttTrkFinderPartial(nHits,info,Ninclinations,Minclinations,inclinationversors, Ninclinate, trackArray // this is the output, ie the TClonesArray * od PndSttTrack // classes containing the info for a found track, one class per each track ); }; Int_t nTracks = 1; return nTracks; } //------------------------------------------------------------------------------------------------------------------- PndSttHit* PndSttTrackFinderReal::GetHitFromCollections(Int_t hitCounter) { PndSttHit *retval = NULL; Int_t relativeCounter = hitCounter; for (Int_t collectionCounter = 0; collectionCounter < fHitCollectionList.GetEntries(); collectionCounter++) { Int_t size = ((TClonesArray *)fHitCollectionList.At(collectionCounter))->GetEntriesFast(); if (relativeCounter < size) { retval = (PndSttHit*) ((TClonesArray *)fHitCollectionList.At(collectionCounter))->At(relativeCounter); break; } else { relativeCounter -= size; } } return retval; } //------------------------------------------------------------------------------------------------------------------- FairMCPoint* PndSttTrackFinderReal::GetPointFromCollections(Int_t hitCounter) { FairMCPoint *retval = NULL; Int_t relativeCounter = hitCounter; for (Int_t collectionCounter = 0; collectionCounter < fHitCollectionList.GetEntries(); collectionCounter++) { Int_t size = ((TClonesArray *)fHitCollectionList.At(collectionCounter))->GetEntriesFast(); if (relativeCounter < size) { Int_t tmpHit = ((PndSttHit*) ((TClonesArray *)fHitCollectionList.At(collectionCounter))->At(relativeCounter))->GetRefIndex(); retval = (FairMCPoint*) ((TClonesArray *)fPointCollectionList.At(collectionCounter))->At(tmpHit); break; } else { relativeCounter -= size; } } return retval; } //------------------------------------------------------------------------------------------------------------------- void PndSttTrackFinderReal::WriteHistograms(){ }; //------------------------------------------------------------------------------------------------------------------- void PndSttTrackFinderReal::PndSttTrkFinderPartial( Int_t Nhits, Double_t info[][6], Int_t Nincl,Int_t Minclinations[],Double_t inclination[][3], Int_t Ninclinate, TClonesArray * trackArray // this is the TClonesArray * of PndSttTrack classes in output ) { bool ExclusionList[nmaxHits], TypeConf[MAXTRACKSPEREVENT], // if TypeConf[]=false --> the track is a line in the Conformal space, // if TypeConf[]=true it is a crf; TypeConfSkew[MAXTRACKSPEREVENT]; UShort_t iExclude, imc,jexp,mchit,exphit, nTracksFoundSoFar, NN, Nouter, Naux, Nbaux, nTotalHits, iParHit, SeedParallelNumber, OLDnHitsinTrack, TemporarynSkewHitsinTrack, nParspuri, nSkewspuri, BigList[nmaxHits], TemporarySkewList[nmaxHits][2], nHitsinTrack[MAXTRACKSPEREVENT], nSkewHitsinTrack[MAXTRACKSPEREVENT], tempore[nmaxHits], auxListHitsinTrack[nmaxHits], ListHitsinTrack[MAXTRACKSPEREVENT][nmaxHits], ListHitsinTrackinWhichToSearch[nmaxHits], OLDListHitsinTrack[nmaxHits], OutputListHitsinTrack[nmaxHits], OutputList2HitsinTrack[nmaxHits], ListSkewHitsinTrack[MAXTRACKSPEREVENT][nmaxHits], nParalMax[MAXMCTRACKS], nParalCommon[MAXTRACKSPEREVENT], TempParalCommonList[MAXMCTRACKS][nmaxHits], ParalCommonList[MAXMCTRACKS][nmaxHits], nSkewMax[MAXMCTRACKS], nSkewCommon[MAXTRACKSPEREVENT], TempSkewCommonList[MAXMCTRACKS][nmaxHits], SkewCommonList[MAXMCTRACKS][nmaxHits], daMCTrackaParTrackFound[MAXMCTRACKS], daMCTrackaSkewTrackFound[MAXMCTRACKS], RConformalIndex[nmaxHits], // given a Hit number it gives its radial box number FiConformalIndex[nmaxHits], // given a Hit number it gives its azimuthal box number nBoxConformal[nRdivConformal][nFidivConformal], // first index -> radial divisions, 2nd index -> azimuthal divisions; n. of // hits falling in this cell HitsinBoxConformal[nRdivConformal][nFidivConformal][nmaxHits]; // first index -> radial divisions, 2nd index -> azimuthal divisions; // list of hit numbers of those falling in this cell Short_t Charge, Status[MAXTRACKSPEREVENT], daParTrackFoundaTrackMC[MAXTRACKSPEREVENT], daSkewTrackFoundaTrackMC[MAXTRACKSPEREVENT]; Int_t status; Int_t i, j,ii,jj,k,kk,n1,n2,n3, i1,j1,k1,imaxima, jmaxima, iofmax, jofmax, kofmax, index[nmaxHits], integer, Ncirc, nSkew1, nSkew2, n_K, n_FI0, n_R, n_D, n_Fi,STATUS, Nremaining, Nremaining2, NumberofMaximaDFiR, NumberofMaximaKFI0, // MaximaIndexesDFiR[MAXElementsOverThresholdinHough][3], // MaximaIndexesKFI0[MAXElementsOverThresholdinHough][2], nAssociatedParallelHits ; int iimax,jjmax, ncount; Double_t angle, max1, HoughR, HoughD, HoughFi, HoughKAPPA, HoughFI0, tempR, tempD,tempFi,tempKAPPA,tempFI0, Rlow, Rup, Dlow, Dup,Filow,Fiup, KAPPAlow, KAPPAup, FI0low, FI0up, gamma; Double_t D,Fi, rotationangle, rotationsin, rotationcos,ptotal, m[MAXTRACKSPEREVENT], q[MAXTRACKSPEREVENT], ALFA[MAXTRACKSPEREVENT], BETA[MAXTRACKSPEREVENT], GAMMA[MAXTRACKSPEREVENT], R[MAXTRACKSPEREVENT], Ox[MAXTRACKSPEREVENT], Oy[MAXTRACKSPEREVENT], KAPPA[MAXTRACKSPEREVENT], FI0[MAXTRACKSPEREVENT], trajectory_vertex[3], infoparalConformal[nmaxHits][5], auxinfoparalConformal[nmaxHits][5], S[nmaxHits], Z[nmaxHits], ZDrift[nmaxHits], ZErrorafterTilt[nmaxHits]; Float_t RemainingR[MAXSTTINFO], RemainingFi[MAXSTTINFO], RemainingD[MAXSTTINFO], RemainingCX[MAXSTTINFO], RemainingCY[MAXSTTINFO], RemainingKAPPA[MAXSTTINFO], RemainingFI0[MAXSTTINFO]; bool Goodflag[MAXSTTINFO], temporflag[8], IFLAG; CalculatedCircles Result; CalculatedHelix HelixResult; AssociatedHitsToHelix ResultAssociatedHits ; char nomef[100], nome[30],titolo[100]; for(i=0; i< Minclinations[0]; i++){ ExclusionList[ infoparal[i] ]= true ; } trajectory_vertex[0]=trajectory_vertex[1]=trajectory_vertex[2]=0.; PndSttFromXYtoConformal(trajectory_vertex,info, Minclinations[0],infoparalConformal, &status); PndSttBoxConformalFilling(infoparalConformal, Minclinations[0], nBoxConformal, HitsinBoxConformal, RConformalIndex, FiConformalIndex); // start the track finding procedure //----- loop over the parallel hits nTracksFoundSoFar=0; // # tracks found // begins the first iteration with more severe cuts on the # hits in track candidate MINIMUMHITSPERTRACK=4; for(iParHit=0; iParHit= MINIMUMOUTERHITSPERTRACK) { for(i=0; i< Nouter;i++){ ListHitsinTrackinWhichToSearch[i]=ListHitsinTrack[nTracksFoundSoFar][i]; } for(i=0; i< Nouter;i++){ SeedParallelNumber = ListHitsinTrackinWhichToSearch[i]; Naux = PndSttFindTrackPatterninBoxConformalSpecial( 3, // NRCELLDISTANCE 1, // NFiCELLDISTANCE Minclinations[0], Nouter, SeedParallelNumber, ListHitsinTrackinWhichToSearch, info, ExclusionList, RConformalIndex, FiConformalIndex, nBoxConformal, HitsinBoxConformal, OutputListHitsinTrack); if( Naux >= MINIMUMOUTERHITSPERTRACK && Naux > 0.7 * Nouter ) break; if( Naux >= MINIMUMOUTERHITSPERTRACK) { // further collection of hits in the inner region but this time strictly connected to the outer ones // first the list of non outer hits for(j=Nouter;j= MINIMUMOUTERHITSPERTRACK) // finding the rotation angle for best utilization of the MILP procedure for(j=0, rotationcos=0., rotationsin=0.; jGetParamLast()->SetTx(R[i]); Double_t inv=R[i]*KAPPA[i]; if(fabs(inv) > 1.e-10){ pt->GetParamLast()->SetTy(1./inv); }else{ pt->GetParamLast()->SetTy(1.e10); } ptotal = sqrt(Pxini*Pxini+Pyini*Pyini+Pzini*Pzini); if( fabs(ptotal) > 1.e-10){ pt->GetParamLast()->SetQp(Charge/ptotal); } else { pt->GetParamLast()->SetQp(Charge/1.e-10); } */ } // end of for(i=0; i0.){ S = d/a; T = -c/a; BBB = y1; CCC = (S-T*Radius)*(S-T*Radius)-Radius*Radius-2.*x1*(S-T*Radius)-2.*i1*Radius*r1+x1*x1+y1*y1-r1*r1; DELTA = BBB*BBB-CCC; if(DELTA<0.) { continue; } else if (DELTA ==0.){ Nsol++; R[Nsol-1] = Radius ; CX[Nsol-1] = S-T*Radius; CY[Nsol-1] = -BBB; } else{ Nsol+=2; R[Nsol-2] = Radius ; CX[Nsol-2] = S-T*Radius; CY[Nsol-2] = -BBB+sqrt(DELTA); R[Nsol-1] = Radius ; CX[Nsol-1] = S-T*Radius; CY[Nsol-1] = -BBB-sqrt(DELTA); } } // end if ( Radius >0.) } else if(bp*c-b*cp != 0.) { Radius = (-bp*d+b*dp)/(bp*c-b*cp) ; if( Radius > 0. && b != 0. ){ S = (d+c*Radius)/b; T = a/b; AAA = 1+T*T; BBB = -(T*S+x1-T*y1); CCC = S*S-Radius*Radius-2.*y1*S-2.*i1*r1*Radius+x1*x1+y1*y1-r1*r1; DELTA= BBB*BBB-AAA*CCC; //cout<<"AAA ="< 0.){ Nsol++; R[Nsol-1] = solution; CX[Nsol-1] = A+B*R[Nsol-1]; CY[Nsol-1] = C+D*R[Nsol-1]; } solution=(-BBB-radix)/AAA; //cout<<"-BBB[j] radix AAA[j] : "<<-BBB <<"; "<< radix <<"; "<< AAA<<"; solution=- :"< 0.){ Nsol++; R[Nsol-1] = solution; CX[Nsol-1] = A+B*R[Nsol-1]; CY[Nsol-1] = C+D*R[Nsol-1]; } } // end of if(AAA == 0.) } // end for(i3 } // end for(i2 } // end for(i1 } // end if ( aaa == 0.) //cout<<"----------------------------------------\n"; // cout<<"n. soluzioni : "<0; j--){ if( RRR> radiaConf[j] ){ iR = j; break; } } HitsinBoxConformal[iR][iFi][ nBoxConformal[iR][iFi] ]=(UShort_t) i; nBoxConformal[iR][iFi]++; RConformalIndex[ infoparal[i] ] = iR; FiConformalIndex[ infoparal[i] ] = iFi; } return; } //----------end of function PndSttTrackFinderReal::PndSttBoxConformalFilling //----------begin of function PndSttTrackFinderReal::PndStt_Merge_Sort void PndSttTrackFinderReal::PndStt_Merge_Sort(UShort_t n_ele, Double_t *array, UShort_t *ind) { UShort_t nr, nl, middle, i, ind_left[n_ele], ind_right[n_ele]; Double_t left[n_ele], right[n_ele], result[n_ele]; if( n_ele <= 1) return; middle = n_ele/2 ; for(i=0; i right[0]) { PndStt_Merge(middle, left,ind_left, n_ele-middle, right, ind_right, array, ind); } else { // do the appending for(i=0; i 0 && nr >0){ if( left[nl_curr] <= right[nr_curr]){ result[i] = left[nl_curr]; ind[i] = ind_left[nl_curr]; nl--; nl_curr++; } else { result[i] = right [nr_curr]; ind[i] = ind_right [nr_curr]; nr--; nr_curr++; } i++; } //-------------------- if( nl ==0) { for(j=0; j 0 && i < nHitsinTrack) { nRcell = RConformalIndex[ infoparal[ ListHitsinTrack[i] ] ]; nFicell = FiConformalIndex[ infoparal[ ListHitsinTrack[i] ] ]; //--------------- if (nRcell - NRCELLDISTANCE < 0 ) { nRmin = 0; } else { nRmin = nRcell - NRCELLDISTANCE; } if (nRcell + NRCELLDISTANCE >= nRdivConformalEffective ) { nRmax = nRdivConformalEffective-1; } else { nRmax = nRcell + NRCELLDISTANCE; } for( iR= nRmin ; iR<= nRmax ; iR++){ for( iFi2 = nFicell - NFiCELLDISTANCE ; iFi2<= nFicell + NFiCELLDISTANCE ; iFi2++){ if ( iFi2 < 0 ) { iFi = nFidivConformal + iFi2; } else if ( iFi2 >= nFidivConformal) { iFi = iFi2 - nFidivConformal; } else { iFi = iFi2; } for (j = 0; j< nBoxConformal[iR][iFi]; j++){ if( ExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ] && TemporaryExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ]) { ListHitsinTrack[nHitsinTrack]=HitsinBoxConformal[iR][iFi][j] ; // hit number in the PARALLEL straws scheme nHitsinTrack++; TemporaryExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ]= false; nRemainingHits--; } } } } //---------------- i++; } // end while ( nRemainingHits > 0 && i < nHitsinTrack) // ordering the hits by INCREASING CONFORMAL RADIUS (decreasing space radius) return nHitsinTrack; } //----------end of function PndSttTrackFinderReal::PndSttFindTrackPatterninBoxConformal //----------begin of function PndSttTrackFinderReal::PndSttFindTrackPatterninBoxConformalSpecial Short_t PndSttTrackFinderReal::PndSttFindTrackPatterninBoxConformalSpecial( UShort_t NRCELLDISTANCE, UShort_t NFiCELLDISTANCE, UShort_t Nparal, UShort_t NparallelToSearch, UShort_t iSeed, UShort_t *ListHitsinTrackinWhichToSearch, Double_t info[][6], bool ExclusionList[nmaxHits], UShort_t RConformalIndex[nmaxHits], UShort_t FiConformalIndex[nmaxHits], UShort_t nBoxConformal[nRdivConformal][nFidivConformal], UShort_t HitsinBoxConformal[nRdivConformal][nFidivConformal][nmaxHits], UShort_t *OutputListHitsinTrack ) { bool TemporaryExclusionList[nmaxHits]; UShort_t i, i2, j, iR, iFi, nRmin, nRmax, nRemainingHits, nRcell, nFicell, nHitsinTrack, Remaining[nmaxHits], auxIndex[nmaxHits]; Short_t iFi2; Double_t auxRvalues[nmaxHits]; // iSeed is the hit number in the PARALLEL number scheme //cout<<" Nparal "< 0 && i < nHitsinTrack) { nRcell = RConformalIndex[ infoparal[ OutputListHitsinTrack[i] ] ]; nFicell = FiConformalIndex[ infoparal[ OutputListHitsinTrack[i] ] ]; //cout<<"From PatterninBoxConformal HIT collezionatore ora ha nRcell e nFicell "<= nRdivConformalEffective ) { nRmax = nRdivConformalEffective-1; } else { nRmax = nRcell + NRCELLDISTANCE; } for( iR= nRmin ; iR<= nRmax ; iR++){ for( iFi2 = nFicell - NFiCELLDISTANCE ; iFi2<= nFicell + NFiCELLDISTANCE ; iFi2++){ if ( iFi2 < 0 ) { iFi = nFidivConformal + iFi2; } else if ( iFi2 >= nFidivConformal) { iFi = iFi2 - nFidivConformal; } else { iFi = iFi2; } for (j = 0; j< nBoxConformal[iR][iFi]; j++){ if( ExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ] && TemporaryExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ]) { OutputListHitsinTrack[nHitsinTrack]=HitsinBoxConformal[iR][iFi][j] ; // hit number in the PARALLEL straws scheme nHitsinTrack++; TemporaryExclusionList[ infoparal[ HitsinBoxConformal[iR][iFi][j] ] ]= false; nRemainingHits--; } } } } //---------------- i++; } // end while ( nRemainingHits > 0 && i < nHitsinTrack) return nHitsinTrack; } //----------end of function PndSttTrackFinderReal::PndSttFindTrackPatterninBoxConformalSpecial //----------begin of function PndSttTrackFinderReal::PndSttFindTrackStrictCollection Short_t PndSttTrackFinderReal::PndSttFindTrackStrictCollection( UShort_t NFiCELLDISTANCE, UShort_t iSeed, // seed track (parallel notation) as fa as the Fi angle is concerned UShort_t NParallelToSearch, // n. of hits to search in ListHitsinTrackinWhichToSearch UShort_t *ListHitsinTrackinWhichToSearch, bool ExclusionList[nmaxHits], UShort_t FiConformalIndex[nmaxHits], UShort_t *OutputListHitsinTrack ) { UShort_t i, j, iR, iFi, iFiseed, nHitsinTrack; Double_t auxRvalues[nmaxHits]; // iSeed is the hit number in the PARALLEL number scheme iFiseed = FiConformalIndex[ infoparal[ iSeed ] ]; nHitsinTrack=0; for(i=0; i iFiseed if( -iFiseed + iFi <= NFiCELLDISTANCE ) { OutputListHitsinTrack[nHitsinTrack]=ListHitsinTrackinWhichToSearch[i]; nHitsinTrack++; } else { if( -iFi + nFidivConformal + iFiseed<= NFiCELLDISTANCE ) { OutputListHitsinTrack[nHitsinTrack]=ListHitsinTrackinWhichToSearch[i]; nHitsinTrack++; } } } // end of if( iFi == iFiseed ) } // end of if( ExclusionList[ infoparal[ ListHitsinTrackinWhichToSearch[i] ] ] ) } // end of for(i=0; i 1.e-10) { // trajectory is a circle in XY space ALFA[nTracksFoundSoFar] = *emme/(*qu); BETA[nTracksFoundSoFar] = -1./(*qu); TypeConf[nTracksFoundSoFar]=true; // now take into account the rotation and correct; the only affected quantities are ALFA and BETA alfetta = ALFA[nTracksFoundSoFar]; ALFA[nTracksFoundSoFar] = ALFA[nTracksFoundSoFar]*cose - BETA[nTracksFoundSoFar]*sine; BETA[nTracksFoundSoFar] = alfetta*sine + BETA[nTracksFoundSoFar]*cose; } else if(fabs(*emme)> 1.e-10) { // trajectory is a straight line in XY space of equation y= m*x // the rotation first angle = atan(*emme) + rotationangle; if( fabs(cos(angle)) > 1.e-10 ) { ALFA[nTracksFoundSoFar] = 999999.; BETA[nTracksFoundSoFar] = -ALFA[nTracksFoundSoFar]/tan(angle); } else { // in this case the equation is y = 0. ALFA[nTracksFoundSoFar] = 999999.; BETA[nTracksFoundSoFar] = 0.; TypeConf[nTracksFoundSoFar]=false; } } else { // in this case also the equation in XY plane is y = 0. ALFA[nTracksFoundSoFar] = 999999.; BETA[nTracksFoundSoFar] = 0.; TypeConf[nTracksFoundSoFar]=false; } // now take into account the displacement and correct GAMMA[nTracksFoundSoFar] += (trajectory_vertex[0]*trajectory_vertex[0]+ trajectory_vertex[1]*trajectory_vertex[1] -ALFA[nTracksFoundSoFar]*trajectory_vertex[0]-BETA[nTracksFoundSoFar]*trajectory_vertex[1]); ALFA[nTracksFoundSoFar] -= 2.*trajectory_vertex[0]; BETA[nTracksFoundSoFar] -= 2.*trajectory_vertex[1]; //------------------------ end of transformation of the result in terms of ALFA, BETA, GAMMA //-------- end of taking into account the traslation that was performed and undoing that // taking into account the rotation that was performed and calculate emme and qu in the normal conformal plane if(fabs(cose-*emme*sine)> 1.e-10) { *qu=*qu/(cose-*emme*sine); *emme=(*emme*cose+sine)/(cose-*emme*sine); return 1; } else { // in this case the equation is 0 = x+*qu . if(fabs(sine+*emme*cose) < 1.e-10) { cout<<" From PndSttFitHelixCylinder, situation impossible in principle! Returning -1" < FFimax ) FFimax = FiConformalIndex[i]; if( FFimax > 3.*nFidivConformal/4. && FFimin < nFidivConformal/4.) { FFimin = 10000; FFimax = 0; for(j=0; j FFimax ) FFimax = Fi; } } // finding the boundaries in the Conformal plane. The basic assumption is that the range // in Fi is much less that 180 degrees. FFimin -= (Short_t) nFidivConformal/Nextra; FFimax += (Short_t) nFidivConformal/Nextra; if( FFimax - FFimin > nFidivConformal/2 ) { cout<<"something fishy is going on in PndSttTrkAssociatedParallelHitsToHelixTris!" <<"Range in Fi (rad) is "<<(FFimax - FFimin)*2.*PI/nFidivConformal< 1.e-10 ) { passamax=false; passamin=false; for(itemp=FFimin; itemp<=FFimax;itemp++){ i=itemp; if( i< 0 ) { i += nFidivConformal; } else if (i>=nFidivConformal){ i -= nFidivConformal*( i/nFidivConformal ); } angle = (i+0.5)*2.*PI/nFidivConformal; aaa = cos(angle); if( fabs(cos(angle)) <1.e-10) continue; r = -q/aaa; if(r< radiaConf[0] || r>= 1./RStrawDetectorMin) continue; for(j=nRdivConformalEffective-1; j>=0;j--){ if( r>= radiaConf[j] ){ nR = j; break; } } for(l=-DELTAnR; l= nRdivConformalEffective ) continue; for( k=0;k=nFidivConformal) i2 -= nFidivConformal; for(l=-2; l<3;l++){ l3 = nR+l; if( l3<0 || l3 >= nRdivConformalEffective ) continue; for( k=0;k= nRdivConformalEffective ) continue; for( k=0;k x=0 if( FFimax > nRdivConformal/4 && Fimin < nRdivConformal/4 ) { iFi0 = (Short_t) (nRdivConformal/4 ); } else if ( FFimax > 3*nRdivConformal/4 && Fimin < 3*nRdivConformal/4 ){ iFi0 = (Short_t) (3*nRdivConformal/4 ); } else { cout <<"From PndSttTrackFinderReal::PndSttTrkAssociatedParallelHitsToHelixTris :" <<" inconsistency, 0 associated hits to this track candidate\n"; return 0; } for(itemp=iFi0-5; itemp<=iFi0+5;itemp++){ i=itemp; if( i< 0 ) { i += nFidivConformal; } else if (i>=nFidivConformal){ i -= nFidivConformal*( i/nFidivConformal ); } for(l=0; l 1.e-10 ) } else if( fabs(q)> 1.e-10) { // second part of if( Status ==99), in this case y = m*x +q Fi0 = atan2(q, -m*q); if(Fi0<0.) { Fi0 += PI; if (Fi0 <0. ) Fi0 =0.; }; ddd= fabs(q)/sqrt(1.+m*m); for(itemp=FFimin; itemp<=FFimax;itemp++){ i=itemp; if( i< 0 ) { i += nFidivConformal; } else if (i>=nFidivConformal){ i -= nFidivConformal*( i/nFidivConformal ); } fi1 = i*2.*(PI/nFidivConformal); if( fabs(sin(fi1)-m*cos(fi1))>1.e-10) { erre1 = q/(sin(fi1)-m*cos(fi1)); } else { erre1 = 99999999999.; } fi2 = (i+1)*2.*(PI/nFidivConformal); if( fabs(sin(fi2)-m*cos(fi2))>1.e-10) { erre2 = q/(sin(fi2)-m*cos(fi2)); } else { erre2 = 99999999999.; } for(j=0; j Rout ){ continue; } } else if(fabs(erre1) < 1.e-10){ if( Fi0 > fi2 || Fi0 < fi1) continue; } else if ( erre1 Rout && erre2 > Rout && !( fi1<=Fi0 && Fi0<=fi2 && ddd<=Rout ) ) { continue; } for(l=itemp-2; l<=itemp+2; l++){ if( l< 0 ) { l2 = l+nFidivConformal; } else if (l>=nFidivConformal){ l2 = l- nFidivConformal*( i/nFidivConformal ); } else { l2 = l; } if( j-1<0) { kstart=0; } else { kstart = j-1; } if ( j+1 >= nRdivConformal ) { kend = nRdivConformal; } else { kend = j+2; } for(k=kstart;k=nFidivConformal){ i -= nFidivConformal*( i/nFidivConformal ); // i -= nFidivConformal; } for(l=0; l= info[i][4] ) continue; Rx = POINTS1[j]-Ox ; // x component Radial vector of cylinder of trajectory Ry = POINTS1[1+j]-Oy ; // y direction Radial vector of cylinder of trajectory aaa = sqrt(Rx*Rx+Ry*Ry); SkewInclWithRespectToS = (-Ry*vx1 + Rx*vy1)/aaa ; SkewInclWithRespectToS /= R; bbb = sqrt( SkewInclWithRespectToS*SkewInclWithRespectToS + vz1*vz1); // the tilt direction of this ellipse is (1,0) when major axis along Z direction if( bbb > 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]/R; S[NAssociated] = atan2(POINTS1[j+1]-Oy, POINTS1[j]-Ox) ; // atan2 returns radians in (-pi and +pi] if( S[NAssociated] < 0.) S[NAssociated] += 2.*PI; Z[NAssociated] = POINTS1[j+2]; ZDrift[NAssociated] = Aellipsis1*Tiltdirection1[0]; ZErrorafterTilt[NAssociated] = StrawDriftError*aaa*Tiltdirection1[0]/LL; SkewList[NAssociated][0] = iii; // n. skew hit in skew hit numbering SkewList[NAssociated][1] = ii; // solution 0 or solution 1 were accepted NAssociated++; } // end of for( ii=0; ii<2; ii++) } // for( iii=0; iii< NSkewhits; iii++) return NAssociated; } //----------end of function PndSttTrackFinderReal::AssociateSkewHitsToXYTrack //----------begin of function PndSttTrackFinderReal::PndSttFitSZspace Short_t PndSttTrackFinderReal::PndSttFitSZspace( UShort_t nHitsinTrack, Double_t *S, Double_t *Z, Double_t *DriftRadius, UShort_t nParallelTrack, Double_t rotationangle, UShort_t NMAX, Double_t *emme, Double_t *qu ) { // definition of variables for the glpsol solver // ROWS (for read_rows function) // UShort_t NpointsInFit = nHitsinTrack-NMAX <0 ? nHitsinTrack : NMAX; int nRows= NpointsInFit*9 +1; int typeRows[nRows]; char * nameRows[nRows]; char auxnameRows[nRows][20]; //------- end ROWS information //--------begin COLUMNS information int NStructVar=5+NpointsInFit*4; // number of structural variables int NStructRows = 8*NpointsInFit ; // maximum number of ROWS in which a structural variable can be found double final_values[NStructVar]; int NRowsInWhichStructVarArePresent[NStructVar]; char *StructVarName[NStructVar]; char auxStructVarName[NStructVar][20]; char *NameRowsInWhichStructVarArePresent[NStructVar*NStructRows]; char aux[NStructVar*NStructRows][20]; // double Coefficients[NStructVar][NStructRows]; double Coefficients[NStructVar*NStructRows]; //--------end COLUMNS information //--------begin RHS information double ValueB[9*NpointsInFit]; //--------end RHS information //--------begin RANGES information int nRanges = NpointsInFit; double ValueRanges[nRanges]; char *NameRanges[nRanges]; char auxNameRanges[nRanges][20]; //--------end RANGES information //--------start BOUNDS information int nBounds=2*NpointsInFit+1; double BoundValue[nBounds]; char *BoundStructVarName[nBounds]; char auxBoundStructVarName[nBounds][20]; char *TypeofBound[nBounds]; //--------end BOUNDS information //---------------------------------------------------- Double_t M = 50., m_result, q_result, A, alfetta, angle, offsety, Ox[nmaxHits], Oy[nmaxHits], Delta[nmaxHits]; UShort_t i, ii; Short_t Status; char nome[100], stringa[100], stringa2[100]; // FILE * MACRO ; float m1_result,m2_result, q1_result,q2_result, A1_result, A2_result; // -- if( nHitsinTrack < MINIMUMHITSPERTRACK) { return -1; } // use the trick of increasing the rotation angle by 10 degrees in order to obtain always a positive m // rotationangle -= PI/18.; Double_t cose = cos(rotationangle), sine = sin(rotationangle); for(i=0;i 1.e-10) { *qu=*qu/(cose-*emme*sine); *emme=(*emme*cose+sine)/(cose-*emme*sine); return 1; } else { // in this case the equation is 0 = x+*qu . if(fabs(sine+*emme*cose) < 1.e-10) { cout<<" From PndSttFitSZspace, situation impossible in principle! Returning -1" <0. for (old=auxFivalues[0],flag=0, j = 1; j< nParallelHits; j++){ if( fabs(old - auxFivalues[j]) > PI ) { flag=1; break; } else { old=auxFivalues[j]; } } if( flag==1) { for (j = 0; j< nParallelHits; j++){ if( auxFivalues[j] < PI) auxFivalues[j] += 2.*PI; } } // now ordering of the skew hits if( flag==1) { for (j = 0; j< nSkewHits; j++){ if( S[j] < PI) { auxFiSkewvalues[j] = S[j] + 2.*PI; } else { auxFiSkewvalues[j] = S[j]; } } } else { for (j = 0; j< nSkewHits; j++){ auxFiSkewvalues[j] = S[j]; } } PndStt_Merge_Sort( nSkewHits, auxFiSkewvalues, ListSkewHits); // merge the parallel and skew hits for(j = 0;j< nParallelHits; j++){ BigListFi[j]=auxFivalues[j]; BigList [j] = Infoparal[ ListParallelHits[i] ] ; } for(j=0; j auxFivalues[nParallelHits]) { for(j=0; jGetMomentum(); Double_t momerr; // = 4% of mc mom // momerr = 0.04 * mcStartMom.Mag(); momerr = 0.04 * Ptras; pterr = momerr; plerr = momerr; TVector3 StartMomErr = TVector3(pterr, pterr, plerr); // Int_t pdg = mctrack->GetPdgCode(); Int_t pdg = 13; TDatabasePDG *fdbPDG= TDatabasePDG::Instance(); TParticlePDG *fParticle= fdbPDG->GetParticle(pdg); Double_t fCharge= fParticle->Charge()/3.; TVector3 u(0.,1.,0.); TVector3 v(0.,0.,1.); GFDetPlane pl(StartPos,u,v); GFAbsTrackRep* rep = 0; GeaneTrackRep *grep = new GeaneTrackRep(fPro,pl,StartMom,StartPosErr,StartMomErr,fCharge,pdg); grep->setPropDir(1); // propagate in flight direction! rep=grep; GFTrack* trk = new GFTrack(rep); GFTrackCand *cand = new GFTrackCand(); int detId; for(int iPoint = 0; iPoint < nTotal; iPoint++) { PndSttHit * currenthit = (PndSttHit*) GetHitFromCollections(BigList[iPoint]); if(!currenthit) continue; detId = currenthit->GetDetectorID() ; cand->addHit(detId, BigList[iPoint]); } // end of for(int iPoint = 0; iPoint < nTotal; iPoint++) trk->setCandidate(*cand); // here the candidate is copied! //---- now the Kalman trk->addHitVector(_theRecoHitFactory->createMany(trk->getCand())); GFKalman k; k.setLazy(1); k.setNumIterations(1); k.processTrack(trk); //------ estrazione delle info dal Kalman secondo Lia TVector3 dum = trk->getCardinalRep()->getMom(); //------------ delete grep; delete trk; delete cand; return; } //----------end of function PndSttTrackFinderReal::PndSttFitwithKalman //----------begin of function PndSttTrackFinderReal::PndSttOrdering void PndSttTrackFinderReal::PndSttOrdering( Double_t oX, Double_t oY, Double_t info[][6], UShort_t nParallelHits, UShort_t *ListParallelHits, UShort_t nSkewHits, UShort_t *ListSkewHits, Double_t *S, UShort_t *Infoparal, UShort_t *Infoskew, UShort_t *nTotal, UShort_t *BigList, Short_t * Charge ) { *nTotal = nParallelHits+nSkewHits; UShort_t i,j,flag, aux[*nTotal]; Double_t old, auxFivalues[nmaxHits], auxFiSkewvalues[nmaxHits], auxRvalues[nmaxHits], BigListFi[*nTotal]; // here there is the ordering of the hits // ordering of the parallel hits first for (j = 0; j< nParallelHits; j++){ auxRvalues[j]= info[ infoparal[ ListParallelHits[j] ] ][0]* info[ infoparal[ ListParallelHits[j] ] ][0]+ info[ infoparal[ ListParallelHits[j] ] ][1]* info[ infoparal[ ListParallelHits[j] ] ][1]; } PndStt_Merge_Sort( nParallelHits, auxRvalues, ListParallelHits); for (j = 0; j< nParallelHits; j++){ auxFivalues[j] = atan2( info[ infoparal[ ListParallelHits[j] ] ][1]-oY, info[ infoparal[ ListParallelHits[j] ] ][0]-oX); if( auxFivalues[j] < 0. ) auxFivalues[j] += 2.*PI; } // fixing possible discontinuity between fi<2*PI and fi>0. for (old=auxFivalues[0],flag=0, j = 1; j< nParallelHits; j++){ if( fabs(old - auxFivalues[j]) > PI ) { flag=1; break; } else { old=auxFivalues[j]; } } if( flag==1) { for (j = 0; j< nParallelHits; j++){ if( auxFivalues[j] < PI) auxFivalues[j] += 2.*PI; } } // finding the charge of the track if( auxFivalues[0] > auxFivalues[nParallelHits-1]) { *Charge = 1; } else { *Charge = -1; } // now ordering of the skew hits if( flag==1) { for (j = 0; j< nSkewHits; j++){ if( S[j] < PI) { auxFiSkewvalues[j] = S[j] + 2.*PI; } else { auxFiSkewvalues[j] = S[j]; } } } else { for (j = 0; j< nSkewHits; j++){ auxFiSkewvalues[j] = S[j]; } } PndStt_Merge_Sort( nSkewHits, auxFiSkewvalues, ListSkewHits); // merge the parallel and skew hits for(j = 0;j< nParallelHits; j++){ BigListFi[j]=auxFivalues[j]; BigList[j] = Infoparal[ ListParallelHits[j] ] ; // cout<<"from Ordering, Parallel; j= "<