// ------------------------------------------------------------------------- // ----- PndSttTrackFinderReal source file ----- // ----- Created 28/03/06 by V. Friese ----- // ------------------------------------------------------------------------- // Pnd includes #include "PndSttTrackFinderReal.h" #include "PndSttHit.h" #include "PndSttPoint.h" #include "PndSttTrack.h" #include #include "FairMCPoint.h" #include "FairRootManager.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; int IVOLTE=0, ntimes = 0; // Double_t SEMILENGTH_STRAIGHT = 75.; Double_t SEMILENGTH_STRAIGHT ; Double_t ZCENTER_STRAIGHT = 75.; const bool iplotta = true , ianalizza = true ; const int istampa = 1 ; TH1F * hx; FILE * HANDLE ; Double_t veritaMC[nmaxHits][3]; // UShort_t BoxCXCYR[nbinCX][nbinCY][nbinR]; UShort_t BoxDFiR[nbinD][nbinFi][nbinR]; UShort_t BoxKFI0[nbinKAPPA][nbinFI0]; // ----- Default constructor ------------------------------------------- PndSttTrackFinderReal::PndSttTrackFinderReal() { fVerbose = 1; } // ------------------------------------------------------------------------- // ----- Standard constructor ------------------------------------------ PndSttTrackFinderReal::PndSttTrackFinderReal(Int_t verbose) { fVerbose = verbose; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndSttTrackFinderReal::~PndSttTrackFinderReal() { } // ------------------------------------------------------------------------- // ----- Public method Init -------------------------------------------- void PndSttTrackFinderReal::Init() { // Get and check FairRootManager FairRootManager* ioman = FairRootManager::Instance(); hx = new TH1F("hx", "Associated Z", 400, -200., 200.); if (!ioman) { cout << "-E- PndSttTrackFinderReal::Init: " << "RootManager not instantised!" << endl; return; } } // ------------------------------------------------------------------------- // ----- Public method DoFind ------------------------------------------ Int_t PndSttTrackFinderReal::DoFind(TClonesArray* trackArray) { Double_t info[nmaxHits][6], WDX, WDY, WDZ, inclinationversors[nmaxinclinationversors][3]; inclinationversors[0][0]=inclinationversors[0][1]=0., inclinationversors[0][2]=1.; Int_t Ninclinations = 1; 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; } //------------------------------------ modifiche Gianluigi, 9-7-08 IVOLTE++; // cout<<"\nGianluigi da DoFind IVOLTE "<GetEntriesFast(); } // Declare some variables outside the loops Int_t trackIndex = 0; // STTTrack index // Create STL map from MCtrack index to number of valid SttHits map > 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 veritaMC[iHit][0]= ((PndSttPoint*)pMCpt)->GetXtot(); veritaMC[iHit][1]= ((PndSttPoint*)pMCpt)->GetYtot(); veritaMC[iHit][2]= ((PndSttPoint*)pMCpt)->GetZtot(); 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.; 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; 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; Minclinations[Ninclinations-1]++; jumpout: ; } } // end of for (Int_t iHit = 0; if( nHits >0 && Minclinations[0] > 2 ) { if(ianalizza) PndSttTrkFinderPartial(nHits,info,Ninclinations,Minclinations,inclinationversors); }; // la parte seguente andra' messa a posto per // dare in output la traccia PndSttTrack 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::PndSttTrkFinderPartial(Int_t Nhits, Double_t info[][6], Int_t Nincl,Int_t Mincl[],Double_t inclination[][3]) { Int_t i, j,ii,jj,k,kk,n1,n2,n3, i1,j1,k1,imaxima, jmaxima, iofmax, jofmax, kofmax, index[nmaxHits], integer,indexskew[nmaxHits], Ncirc, nSkew1, nSkew2, STATUS, n_K, n_FI0, n_R, n_D, n_Fi, Nstraight, Nslanted, Nremaining, Nremaining2, NumberofMaximaDFiR, NumberofMaximaKFI0, MaximaIndexesDFiR[MAXElementsOverThresholdinHough][3], MaximaIndexesKFI0[MAXElementsOverThresholdinHough][2]; Int_t 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; Float_t RemainingR[MAXSTTINFO], RemainingFi[MAXSTTINFO], RemainingD[MAXSTTINFO], RemainingCX[MAXSTTINFO], RemainingCY[MAXSTTINFO], RemainingKAPPA[MAXSTTINFO], RemainingFI0[MAXSTTINFO]; Double_t D,Fi, skewinclination[nmaxHits][3]; CalculatedCircles Result; CalculatedHelix HelixResult; AssociatedHitsToHelix ResultAssociatedHits ; char nomef[100], nome[30],titolo[100]; for(j=0, Nstraight=0, Nslanted=0; j< Nhits ;j++){ // sort out all hits of wires parallel to Z from those not parallel if( info[j][5] == 1. ){ index[Nstraight]=j; Nstraight++; } else { indexskew[Nslanted]=j; integer = (Int_t) info[j][5]; skewinclination[Nslanted][0]=inclination[ integer-1 ] [0]; skewinclination[Nslanted][1]=inclination[ integer-1 ] [1]; skewinclination[Nslanted][2]=inclination[ integer-1 ] [2]; Nslanted++; } } // start the track finding procedure for(i=0; i=0 && n1=0 && n2=0 && n3 MAXSTTINFO) { cout<<"in EVENT n. "<Rlow && RemainingR[i]Dlow && RemainingD[i]Filow && RemainingFi[i]= KAPPAmax) continue; if(HelixResult.FI0[ii][jj]< FI0min || HelixResult.FI0[ii][jj]>= FI0max) continue; n_K = (int) ( (HelixResult.KAPPA[ii][jj]-KAPPAmin)/stepKAPPA ); n_FI0 = (int) ( (HelixResult.FI0[ii][jj]-FI0min)/stepFI0 ); BoxKFI0[n_K][n_FI0]++; RemainingKAPPA[Nremaining2]=HelixResult.KAPPA[ii][jj]; RemainingFI0[Nremaining2]=HelixResult.FI0[ii][jj]; Nremaining2++; } // end of for(jj=0; jj< HelixResult.Nhelix[ii]; jj++) } // end of for(ii=0; ii<3; ii++) } // end of for(nSkew=nSkew1+1; } // end of for(nSkew1=0; //----------------------------------------------------------------------------------------------------------------------- // searching the maxima of Hough histo of KAPPA and FI0, new method findmaximaKFI0( BoxKFI0, MINIMUMCOUNTSKAPPAFI0, &NumberofMaximaKFI0, MaximaIndexesKFI0, &STATUS ); if(STATUS<=0) { cout<<"Ricerca grossa con skew inclinate fallisce : STATUS = "<0.){ 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 : "<= semilengthSkew1 ){ BAD1[i] = true ; } else { BAD1[i]= false ; } } //---------------- if ( BAD1[0] && BAD1[1] ) { *STATUS = -4; return Result; } //---------------- calculateintersections(Ox,Oy,R,C0x2,C0y2,C0z2,r2,vx2,vy2,vz2, STATUS,POINTS2); if(*STATUS < 0 ) { return Result;} //------------------------- for( i=0; i<2; i++){ j=3*i; distance2[i] = sqrt( (POINTS2[j]-C0x2)*(POINTS2[j]-C0x2) + (POINTS2[1+j]-C0y2)*(POINTS2[1+j]-C0y2) + (POINTS2[2+j]-C0z2)*(POINTS2[2+j]-C0z2) ); if( distance2[i] >= semilengthSkew2 ){ BAD2[i] = true ; } else { BAD2[i]= false ; } } //------------------------- if ( BAD2[0] && BAD2[1] ) { *STATUS = -5; return Result; } //--------------------------------------------------------------------------------------------------------------------- for(k1=0; k1<2;k1++){ // if( BAD1[k1] ) { cout<<"per k1 = "< 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 = r1*aaa/LL; // checks that the projected ellipsis doesn't go out the boundaries of both the skew straw and the trajectory cylinder // under the safe assumption that the ellipse has the major axis in Z direction. if( Aellipsis1 > semilengthStraight1-fabs(POINTS1[i1+2]-Zcenter1) || Aellipsis1 > semilengthStraight2-fabs(POINTS1[i1+2]-Zcenter2) || Aellipsis1 > semilengthStraight3-fabs(POINTS1[i1+2]-Zcenter3) || distance1[k1] + Aellipsis1 > semilengthSkew1 // the ellipsis goes out of the boundaries of the skew straw ) continue; fi1 = atan2(POINTS1[i1+1]-Oy, POINTS1[i1]-Ox) ; // atan2 returns radians in (-pi and +pi] if( fi1 < 0.) fi1 += 2.*PI; for(k2=0; k2<2;k2++){ if( BAD2[k2] ) continue; i2 = 3*k2; // calculation of the approximate axis length of the ellipses projection of the skew straw on the plane tangent to the trajectory cylinder. // first skew straw Rx = POINTS2[i2]-Ox ; // x direction along R of cylinder of trajectory Ry = POINTS2[1+i2]-Oy ; // y direction along R of cylinder of trajectory aaa = sqrt(Rx*Rx+Ry*Ry); SkewInclWithRespectToS = (-Ry*vx2 + Rx*vy2)/aaa ; SkewInclWithRespectToS /= R; bbb = sqrt( SkewInclWithRespectToS*SkewInclWithRespectToS + vz2*vz2); // the tilt direction of this ellipse is (1,0) when major axis along Z direction if( bbb > 1.e-10){ Tiltdirection2[0] = vz2/bbb; Tiltdirection2[1] = SkewInclWithRespectToS/bbb; } else { Tiltdirection2[0] = 1.; Tiltdirection2[1] = 0.; } LL = fabs(vx2*Rx + vy2*Ry); if(LL < 1.e-10) continue; Aellipsis2 = r2*aaa/LL; // Bellipsis2 = r2; // checks that the projected ellipsis doesn't go out the boundaries of both the skew straw and the trajectory cylinder if( Aellipsis2 > semilengthStraight1-fabs(POINTS2[i2+2]-Zcenter1) || // the ellipsis goes out of the boundaries of the straight straws Aellipsis2 > semilengthStraight2-fabs(POINTS2[i2+2]-Zcenter2) || Aellipsis2 > semilengthStraight3-fabs(POINTS2[i2+2]-Zcenter3) || distance2[k2] + Aellipsis2 > semilengthSkew2 // the ellipsis goes out of the boundaries of the skew straw ) continue; // end of boundaries checks, now find KAPPA and FI0 fi2 = atan2(POINTS2[i2+1]-Oy, POINTS2[i2]-Ox) ; // atan2 returns radians in (-pi and +pi] if ( fi2 < 0.) fi2 += 2.*PI; // translation with the new variables ( those of the lateral surface of the trajectory cylinder and with the first ellipsis // positioned at 0,0 for ( enne = -1; enne<2; enne++) { // enne is the order of the solution // translation with the new variables ( those of the lateral surface of the trajectory cylinder and with the first ellipsis // positioned at 0,0 Result.Nhelix[enne+1] = 4; for(i=0; i<2; i++){ for(j=0; j<2; j++){ x1 = POINTS1[i1+2] + (1 - 2*j)*Aellipsis1*Tiltdirection1[0]; y1 = fi1 + (1 - 2*j)*Aellipsis1*Tiltdirection1[1] ; x2 = POINTS2[i2+2] + (1 - 2*i)*Aellipsis2*Tiltdirection2[0]; y2 = fi2 + (1 - 2*i)*Aellipsis2*Tiltdirection2[1] + enne * 2. * PI ; Nsolutions = j + 2*i; if ( x2-x1 != 0.){ Result.KAPPA[enne+1][Nsolutions] = (y2-y1) / (x2-x1) ; Result.FI0[enne+1][Nsolutions] = -Result.KAPPA[enne+1][Nsolutions] * x1 + y1; } else { Result.KAPPA[enne+1][Nsolutions] = 1.e14; Result.FI0[enne+1][Nsolutions] = x1; } } } // end of for(i=0; i<2; i++) // --------------------- inizio stampe diagnostiche e macros diagnostiche // -------------------------------------------------------------------- stampa delle macro di controllo // --------------------- fine stampe diagnostiche e macros diagnostiche } // end for(enne=0; enne<2; enne++) } // end for(k2=0; } // end for(k1=0; NTOTAL=4; *STATUS = NTOTAL; //---------------------------------------------------------------------------------------------------------------------- /* cout<<"ultima stampa, N totale soluzioni = "< nAdmittedRadia*StrawRadius ) continue; if(distance > R ) distance *= -1.; if( KAPPA == 0.) { ResultAssociatedHits.AssociatedHitsCoordinates[0][0][ResultAssociatedHits.NAssociatedHits]= info[i][0]+info[i][3]*dx/distance; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][0][ResultAssociatedHits.NAssociatedHits]= info[i][1]+info[i][3]*dy/distance; // Y of the hit ResultAssociatedHits.AssociatedHitsCoordinates[2][0][ResultAssociatedHits.NAssociatedHits] = -1.e20; ResultAssociatedHits.mAmbiguities[ResultAssociatedHits.NAssociatedHits]=1; ResultAssociatedHits.AssociatedWireDirection[0][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][0]; ResultAssociatedHits.AssociatedWireDirection[1][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][1]; ResultAssociatedHits.AssociatedWireDirection[2][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][2]; ResultAssociatedHits.AssociatedWireCenter[0][ResultAssociatedHits.NAssociatedHits]=info[i][0]; ResultAssociatedHits.AssociatedWireCenter[1][ResultAssociatedHits.NAssociatedHits]=info[i][1]; ResultAssociatedHits.AssociatedWireCenter[2][ResultAssociatedHits.NAssociatedHits]=info[i][2]; ResultAssociatedHits.AssociatedWireDriftRadius[ResultAssociatedHits.NAssociatedHits]=info[i][3]; ResultAssociatedHits.Hitnumber[ResultAssociatedHits.NAssociatedHits]=i; // temporaneo! ResultAssociatedHits.NAssociatedHits++; ResultAssociatedHits.NAssociatedParallelHits++; continue; } else { diff = FI0-angle; major = 0.5*(KAPPA*(info[i][2]+info[i][4])+diff)/PI ; minor = 0.5*(KAPPA*(info[i][2]-info[i][4])+diff)/PI ; if ( major < minor) { aaa=minor; minor=major; major=aaa; } minor <= 0. ? nlow = (int) minor : nlow = ( (int) minor) + 1; major < 0. ? nup = ((int) major)-1 : nup = (int) major; if( nlow> nup) continue; if( nup-nlow+1 > nmaxAmbiguities ) continue; step = fabs(2.*PI/KAPPA) ; aaa = -diff/KAPPA ; bbb = info[i][0]+info[i][3]*dx/distance; // X of the hit ccc = info[i][1]+info[i][3]*dy/distance; // Y of the hit for(ii=nlow; ii<=nup; ii++){ ResultAssociatedHits.AssociatedHitsCoordinates[0][ii-nlow][ResultAssociatedHits.NAssociatedHits]= bbb; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][ii-nlow][ResultAssociatedHits.NAssociatedHits]= ccc ; // Y of the hit ResultAssociatedHits.AssociatedHitsCoordinates[2][ii-nlow][ResultAssociatedHits.NAssociatedHits] = aaa + ii*step; // Z of the hit } ResultAssociatedHits.mAmbiguities[ResultAssociatedHits.NAssociatedHits] = nup - nlow + 1; ResultAssociatedHits.AssociatedWireDirection[0][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][0]; ResultAssociatedHits.AssociatedWireDirection[1][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][1]; ResultAssociatedHits.AssociatedWireDirection[2][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][2]; ResultAssociatedHits.AssociatedWireCenter[0][ResultAssociatedHits.NAssociatedHits]=info[i][0]; ResultAssociatedHits.AssociatedWireCenter[1][ResultAssociatedHits.NAssociatedHits]=info[i][1]; ResultAssociatedHits.AssociatedWireCenter[2][ResultAssociatedHits.NAssociatedHits]=info[i][2]; ResultAssociatedHits.AssociatedWireDriftRadius[ResultAssociatedHits.NAssociatedHits]=info[i][3]; ResultAssociatedHits.Hitnumber[ResultAssociatedHits.NAssociatedHits]=i; // temporaneo! ResultAssociatedHits.NAssociatedHits++; ResultAssociatedHits.NAssociatedParallelHits++; } // end if( KAPPA == 0.) } else { //------------------------------ starts here association of skew straw hits // calculation of the intersection points between skew straw axis and trajectory cylinder aaa = sqrt(inclination[Kincl][0]*inclination[Kincl][0]+inclination[Kincl][1]*inclination[Kincl][1]+ inclination[Kincl][2]*inclination[Kincl][2]); vx1 = inclination[Kincl][0]/aaa; vy1 = inclination[Kincl][1]/aaa; vz1 = inclination[Kincl][2]/aaa; C0x1 = info[i][0]; C0y1 = info[i][1]; C0z1 = info[i][2]; calculateintersections(Ox,Oy,R,C0x1,C0y1,C0z1,info[i][3], vx1,vy1,vz1, &STATUS,POINTS1); if(STATUS < 0 ) continue ; for( ii=0; ii<2; ii++){ j=3*ii; distance = sqrt( (POINTS1[j]-C0x1)*(POINTS1[j]-C0x1) + (POINTS1[1+j]-C0y1)*(POINTS1[1+j]-C0y1) + (POINTS1[2+j]-C0z1)*(POINTS1[2+j]-C0z1) ); if( distance >= 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; // checks that the projected ellipsis doesn't go out the boundaries of both the skew straw and the trajectory cylinder if( fabs(POINTS1[j+2]-ZCENTER_STRAIGHT) > SEMILENGTH_STRAIGHT- Aellipsis1 || distance + bbb > info[i][4] // the ellipsis goes out of the boundaries of the skew straw ) continue; //-------------------------- fi1 = atan2(POINTS1[j+1]-Oy, POINTS1[j]-Ox) ; // atan2 returns radians in (-pi and +pi] if( fi1 < 0.) fi1 += 2.*PI; // now calculate the distance (along the Z direction) from the edge of the ellipsis and the predicted Helix // trajectory if(fabs(KAPPA) > 1.e-10) { z1 = POINTS1[j+2] + Aellipsis1*Tiltdirection1[0]; y1 = fi1 + Aellipsis1*Tiltdirection1[1] ; zpos1 = (y1 - FI0)/KAPPA; d1 = fabs(zpos1 - z1); z2 = POINTS1[j+2] - Aellipsis1*Tiltdirection1[0]; y2 = fi1 - Aellipsis1*Tiltdirection1[1] ; zpos2 = (y2 - FI0)/KAPPA; d2 = fabs(zpos2 - z2); if ( d2>d1 ) { distance = d1; if( distance < nAdmittedRadia * Aellipsis1 ) { ResultAssociatedHits.AssociatedHitsCoordinates[0][0][ResultAssociatedHits.NAssociatedHits]= R*cos(y1) + Ox; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][0][ResultAssociatedHits.NAssociatedHits]= R*sin(y1) + Oy; // Y of the hit ResultAssociatedHits.AssociatedHitsCoordinates[2][0][ResultAssociatedHits.NAssociatedHits] = z1; ResultAssociatedHits.mAmbiguities[ResultAssociatedHits.NAssociatedHits]=1; ResultAssociatedHits.AssociatedWireDirection[0][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][0]; ResultAssociatedHits.AssociatedWireDirection[1][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][1]; ResultAssociatedHits.AssociatedWireDirection[2][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][2]; ResultAssociatedHits.AssociatedWireCenter[0][ResultAssociatedHits.NAssociatedHits]=info[i][0]; ResultAssociatedHits.AssociatedWireCenter[1][ResultAssociatedHits.NAssociatedHits]=info[i][1]; ResultAssociatedHits.AssociatedWireCenter[2][ResultAssociatedHits.NAssociatedHits]=info[i][2]; ResultAssociatedHits.AssociatedWireDriftRadius[ResultAssociatedHits.NAssociatedHits]=info[i][3]; ResultAssociatedHits.Hitnumber[ResultAssociatedHits.NAssociatedHits]=-i; // temporaneo! ResultAssociatedHits.NAssociatedHits++; ResultAssociatedHits.NAssociatedSkewHits++; } } else { distance = d2 ; if( distance < nAdmittedRadia * Aellipsis1 ) { ResultAssociatedHits.AssociatedHitsCoordinates[0][0][ResultAssociatedHits.NAssociatedHits]= R*cos(y2) + Ox; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][0][ResultAssociatedHits.NAssociatedHits]= R*sin(y2) + Oy; // Y of the hit ResultAssociatedHits.AssociatedHitsCoordinates[2][0][ResultAssociatedHits.NAssociatedHits] = z2; ResultAssociatedHits.mAmbiguities[ResultAssociatedHits.NAssociatedHits]=1; ResultAssociatedHits.AssociatedWireDirection[0][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][0]; ResultAssociatedHits.AssociatedWireDirection[1][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][1]; ResultAssociatedHits.AssociatedWireDirection[2][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][2]; ResultAssociatedHits.AssociatedWireCenter[0][ResultAssociatedHits.NAssociatedHits]=info[i][0]; ResultAssociatedHits.AssociatedWireCenter[1][ResultAssociatedHits.NAssociatedHits]=info[i][1]; ResultAssociatedHits.AssociatedWireCenter[2][ResultAssociatedHits.NAssociatedHits]=info[i][2]; ResultAssociatedHits.AssociatedWireDriftRadius[ResultAssociatedHits.NAssociatedHits]=info[i][3]; ResultAssociatedHits.Hitnumber[ResultAssociatedHits.NAssociatedHits]=-i; // temporaneo! ResultAssociatedHits.NAssociatedHits++; ResultAssociatedHits.NAssociatedSkewHits++; } } } else { // case when fabs(KAPPA) < 1.e-10 // pick up the hits whose ellipse is close to the staight line at constant FI0 z1 = POINTS1[j+2] + Aellipsis1*Tiltdirection1[0]; y1 = fi1 + Aellipsis1*Tiltdirection1[1] ; d1 = fabs(y1 - FI0); z2 = POINTS1[j+2] - Aellipsis1*Tiltdirection1[0]; y2 = fi1 - Aellipsis1*Tiltdirection1[1] ; d1 = fabs(y2 - FI0); if(d1 FI0 ? factor = -1. : factor = 1.; ResultAssociatedHits.AssociatedHitsCoordinates[0][0][ResultAssociatedHits.NAssociatedHits]= R*cos(y1+factor*Bellipsis1) + Ox; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][0][ResultAssociatedHits.NAssociatedHits]= R*sin(y1+factor*Bellipsis1) + Oy; // Y of the hit } else { y2 > FI0 ? factor = -1. : factor = 1.; ResultAssociatedHits.AssociatedHitsCoordinates[0][0][ResultAssociatedHits.NAssociatedHits]= R*cos(y2+factor*Bellipsis1) + Ox; // X of the hit ResultAssociatedHits.AssociatedHitsCoordinates[1][0][ResultAssociatedHits.NAssociatedHits]= R*sin(y2+factor*Bellipsis1) + Oy; // Y of the hit } ResultAssociatedHits.AssociatedHitsCoordinates[2][0][ResultAssociatedHits.NAssociatedHits] = (z1+z2)/2.; ResultAssociatedHits.mAmbiguities[ResultAssociatedHits.NAssociatedHits]=1; ResultAssociatedHits.AssociatedWireDirection[0][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][0]; ResultAssociatedHits.AssociatedWireDirection[1][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][1]; ResultAssociatedHits.AssociatedWireDirection[2][ResultAssociatedHits.NAssociatedHits]=inclination[Kincl][2]; ResultAssociatedHits.AssociatedWireCenter[0][ResultAssociatedHits.NAssociatedHits]=info[i][0]; ResultAssociatedHits.AssociatedWireCenter[1][ResultAssociatedHits.NAssociatedHits]=info[i][1]; ResultAssociatedHits.AssociatedWireCenter[2][ResultAssociatedHits.NAssociatedHits]=info[i][2]; ResultAssociatedHits.AssociatedWireDriftRadius[ResultAssociatedHits.NAssociatedHits]=info[i][3]; ResultAssociatedHits.Hitnumber[ResultAssociatedHits.NAssociatedHits]=-i; // temporaneo! ResultAssociatedHits.NAssociatedHits++; ResultAssociatedHits.NAssociatedSkewHits++; } } // end of if(fabs(KAPPA) > 1.e-10) } // end of for( ii=0; ii<2; ii++) } // end of if( info[i][5] == 1 ) else } // end of for( i=1; i< Nhits; i++) return ResultAssociatedHits; } //----------end of function PndSttTrackFinderReal::PndSttTrkAssociatedHitsToHelix Int_t PndSttTrackFinderReal::PndSttTrkAssociatedParallelHitsToHelix( Double_t D,Double_t Fi,Double_t R, Int_t Nhits, Double_t info[][6], Int_t Nincl, Int_t Mincl[], Double_t inclination[][3] ) { Int_t i,Kincl; Int_t Nassociatedhits; Double_t Ox, Oy,dx, dy,distance, angle; Ox = (D+R)*cos(Fi); Oy = (D+R)*sin(Fi); // association of hits in the XY plane Nassociatedhits=0; for( i=0; i< Nhits; i++) { Kincl = (int) info[i][5] - 1; // -------------------- association of the hits from parallel straws if( info[i][5] == 1. ) { // parallel straws dx = -Ox+info[i][0]; dy = -Oy+info[i][1]; distance = sqrt(dx*dx+dy*dy); if( distance < 1.e-10) continue; angle = atan2(dy,dx); if ( fabs(R - distance ) > nAdmittedRadia*StrawRadius ) continue; Nassociatedhits++; } // end of if( info[i][5] == 1 ) else } // end of for( i=1; i< Nhits; i++) return Nassociatedhits; } //----------end of function PndSttTrackFinderReal::PndSttTrkAssociatedParallelHitsToHelix //----------start of function PndSttTrackFinderReal::plottamentiParalleleGenerali void PndSttTrackFinderReal::plottamentiParalleleGenerali( Int_t Nremaining, Float_t * RemainingR, Float_t * RemainingD, Float_t * RemainingFi, Float_t * RemainingCX, Float_t * RemainingCY ) { int itemp, i, j, ii, jj; Double_t D, Fi; char nome[100],titolo[100]; sprintf(nome,"HoughGeneralPlotsEvent%d.root",IVOLTE); TFile hfile(nome,"RECREATE", "STT pattern recognition"); //---------- sprintf(titolo,"Cxofcircle"); TH1F hCX(titolo,titolo,nbinCX,CXmin,CXmax); //---------- sprintf(titolo,"Cyofcircle"); TH1F hCY(titolo,titolo,nbinCY,CYmin,CYmax); //----- sprintf(titolo,"Radiusofcircle"); TH1F hR(titolo,titolo,nbinR,Rmin,Rmax); //----- sprintf(titolo,"CxabscissavsCy"); TH2F hCX_CY(titolo,titolo,nbinCX,CXmin,CXmax,nbinCY,CYmin,CYmax); //----- sprintf(titolo,"CxabscissavsRadius"); TH2F hCX_R(titolo,titolo,nbinCX,CXmin,CXmax,nbinR,Rmin,Rmax); //----- sprintf(titolo,"CyabscissavsRadius"); TH2F hCY_R(titolo,titolo,nbinCY,CYmin,CYmax,nbinR,Rmin,Rmax); //----- sprintf(titolo,"CxabscissavsCyordinatevsRadius"); TH3F hCX_CY_R(titolo,titolo,nbinCX,CXmin,CXmax,nbinCY,CYmin,CYmax,nbinR,Rmin,Rmax); //----- sprintf(titolo,"Distanceofclosestapproachofcircle"); TH1F hD(titolo,titolo,nbinD,Dmin,Dmax); //---------- sprintf(titolo,"Firadofcircle"); TH1F hFi(titolo,titolo,nbinFi,Fimin,Fimax); //----- sprintf(titolo,"DabscissavsFi"); TH2F hD_Fi(titolo,titolo,nbinD,Dmin,Dmax,nbinFi,Fimin,Fimax); //----- sprintf(titolo,"DabscissavsRadius"); TH2F hD_R(titolo,titolo,nbinD,Dmin,Dmax,nbinR,Rmin,Rmax); //----- sprintf(titolo,"FiabscissavsRadius"); TH2F hFi_R(titolo,titolo,nbinFi,Fimin,Fimax,nbinR,Rmin,Rmax); //----- sprintf(titolo,"DabscissavsFiordinatevsRadius"); TH3F hD_Fi_R(titolo,titolo,nbinD,Dmin,Dmax,nbinFi,Fimin,Fimax,nbinR,Rmin,Rmax); //----- for(Int_t itemp = 0; itempRlow && RemainingR[itemp]Dlow && RemainingD[itemp]Filow && RemainingFi[itemp]KAPPAlow && RemainingKAPPA[ii]FI0low && RemainingFI0[ii]= 0){ hXdiffparallel.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[0][j][i]-veritaMC[ResultAssociatedHits.Hitnumber[i]][0]); hYdiffparallel.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[1][j][i]-veritaMC[ResultAssociatedHits.Hitnumber[i]][1]); hZdiffparallel.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[2][j][i]-veritaMC[ResultAssociatedHits.Hitnumber[i]][2]); } else { hXdiffskew.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[0][j][i]-veritaMC[-ResultAssociatedHits.Hitnumber[i]][0]); hYdiffskew.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[1][j][i]-veritaMC[-ResultAssociatedHits.Hitnumber[i]][1]); hZdiffskew.Fill(ResultAssociatedHits.AssociatedHitsCoordinates[2][j][i]-veritaMC[-ResultAssociatedHits.Hitnumber[i]][2]); } } } hfile.Write(nome); hfile.Close(); } //----------end of function PndSttTrackFinderReal::plottamentiSkewconMassimo void PndSttTrackFinderReal::findmaximaDFiR( UShort_t BoxDFiR[nbinD][nbinFi][nbinR], Int_t MINIMUMCOUNTS, Int_t * NumberofMaximaDFiR, Int_t MaximaIndexesDFiR[][3], Int_t * STATUS) { Int_t i, j, iD, iFi, iR, icount, ntotClusters, NinCluster, nClusterElementsFound, nRemai, nRemainingElements, max, nElementsinCluster[MAXElementsOverThresholdinHough]; UShort_t found[MAXElementsOverThresholdinHough][MAXElementsOverThresholdinHough][3], auxDFiRIndex[MAXElementsOverThresholdinHough][3], Remai[MAXElementsOverThresholdinHough][3], RemainingElements[MAXElementsOverThresholdinHough][3], Cluster[MAXElementsOverThresholdinHough][3], ClusterElementsFound[MAXElementsOverThresholdinHough][3]; icount=0; for(iD=0; iD MINIMUMCOUNTS ) { auxDFiRIndex[icount][0]=iD; auxDFiRIndex[icount][1]=iFi; auxDFiRIndex[icount][2]=iR; icount++; if(icount == MAXElementsOverThresholdinHough){ *STATUS=-1; cout<<"Temporary printout from findmaximaDFiR : too many cells (>= "<0) { clustering3( (UShort_t *) (&Cluster[i][0]), // inputs to function clustering3 nRemai, Remai, // inputs to function clustering3 nClusterElementsFound, ClusterElementsFound, // ouputs from function clustering3 nRemainingElements, RemainingElements // ouputs from function clustering3 ); for(j=0; j0) nElementsinCluster[ntotClusters]= NinCluster; for( j=0; j1){ NinCluster=1; for(i=0; i<3; i++){ Cluster[0][i] = Remai[0][i]; } nRemai--; for(j=0;j1) } // end of while(1) // now find the indeces for the maxima *NumberofMaximaDFiR = ntotClusters; for(i=0; icd("PndSttTrackFinderReal"); hx->Write(); delete hx; } //----------end of function PndSttTrackFinderReal::WriteHistograms //----------start of function PndSttTrackFinderReal::WriteMacroParallelHitsGeneral void PndSttTrackFinderReal::WriteMacroParallelHitsGeneral( Int_t Nhits, Double_t info[][6], Int_t Nincl, Int_t Mincl[], Double_t inclination[][3] ) { Int_t i, j, i1, ii, index, Kincl, nlow, nup, STATUS; Double_t xmin , xmax, ymin, ymax, Ox, Oy, dx, dy, diff, d1, d2, delta, deltax, deltay, deltaz, deltaS, factor, zmin, zmax, Smin, Smax, S1, S2, z1, z2, y1, y2, vx1, vy1, vz1, C0x1, C0y1, C0z1, aaa, bbb, ccc, angle, minor, major, distance, Rx, Ry, LL, Aellipsis1, Bellipsis1,fi1, fmin, fmax, offset, step, SkewInclWithRespectToS, zpos, zpos1, zpos2, Tiltdirection1[2], zl[200],zu[200], POINTS1[6]; // Ox = (D+R)*cos(Fi); // Oy = (D+R)*sin(Fi); //---------- parallel straws Macro now char nome[50], nome2[50]; sprintf(nome,"MacroGeneralParallelHitsEvent%d", IVOLTE); sprintf(nome2,"%s.C",nome); FILE * MACRO = fopen(nome2,"w"); fprintf(MACRO,"void %s()\n{\n",nome); xmin=1.e20; xmax=-1.e20; ymin=1.e20; ymax=-1.e20; for( i=1; i< Nhits; i++) { if( info[i][5] == 1 ) { // parallel straws if (info[i][0]-info[i][3] < xmin) xmin = info[i][0]-info[i][3]; if (info[i][0]+info[i][3] > xmax) xmax = info[i][0]+info[i][3]; if (info[i][1]-info[i][3] < ymin) ymin = info[i][1]-info[i][3]; if (info[i][1]+info[i][3] > ymax) ymax = info[i][1]+info[i][3]; } } if( xmin > 0. ) xmin = 0.; if( xmax < 0.) xmax = 0.; if( ymin > 0. ) ymin = 0.; if( ymax < 0.) ymax = 0.; deltax = xmax-xmin; deltay = ymax - ymin; if( deltax > deltay) { ymin -= 0.5*(deltax-deltay); ymax = ymin+ deltax; delta = deltax; } else { xmin -= 0.5*(deltay-deltax); xmax = xmin+ deltay; delta= deltay; } xmax = xmax + delta*0.05; xmin = xmin - delta*0.05; ymax = ymax + delta*0.05; ymin = ymin - delta*0.05; fprintf(MACRO,"TCanvas* my= new TCanvas();\nmy->Range(%f,%f,%f,%f);\n",xmin,ymin,xmax,ymax); // fprintf(MACRO,"TEllipse* TC = new TEllipse(%f,%f,%f,%f,0.,360.);\n",Ox,Oy,R,R); // fprintf(MACRO,"TC->SetLineColor(4);\nTC->Draw();\n"); fprintf(MACRO,"TGaxis *Assex = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n",xmin,0.,xmax,0.,xmin,xmax); fprintf(MACRO,"Assex->Draw();\n"); fprintf(MACRO,"TGaxis *Assey = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n", 0.,ymin,0.,ymax,ymin,ymax); fprintf(MACRO,"Assey->Draw();\n"); for( i=0; i< Nhits; i++) { if( info[i][5] == 1 ) { // parallel straws fprintf(MACRO,"TEllipse* E%d = new TEllipse(%f,%f,%f,%f,0.,360.);\nE%d->Draw();\n", i,info[i][0],info[i][1],info[i][3],info[i][3],i); } } fprintf(MACRO,"}\n"); fclose(MACRO); return ; } //----------end of function PndSttTrackFinderReal::WriteMacroParallelHitsGeneral //----------start of function PndSttTrackFinderReal::WriteMacroParallelAssociatedHits void PndSttTrackFinderReal::WriteMacroParallelAssociatedHits( Double_t D,Double_t Fi,Double_t R, Int_t Nhits, Double_t info[][6], Int_t Nincl, Int_t Mincl[], Double_t inclination[][3], Int_t imaxima ) { Int_t i, j, i1, ii, index, Kincl, nlow, nup, STATUS; Double_t xmin , xmax, ymin, ymax, Ox, Oy, dx, dy, diff, d1, d2, delta, deltax, deltay, deltaz, deltaS, factor, zmin, zmax, Smin, Smax, S1, S2, z1, z2, y1, y2, vx1, vy1, vz1, C0x1, C0y1, C0z1, aaa, bbb, ccc, angle, minor, major, distance, Rx, Ry, LL, Aellipsis1, Bellipsis1,fi1, fmin, fmax, offset, step, SkewInclWithRespectToS, zpos, zpos1, zpos2, Tiltdirection1[2], zl[200],zu[200], POINTS1[6]; Ox = (D+R)*cos(Fi); Oy = (D+R)*sin(Fi); //---------- parallel straws Macro now char nome[50], nome2[50]; sprintf(nome,"MacroPMaxN%dParallelHitsSummary%d",imaxima, IVOLTE); sprintf(nome2,"%s.C",nome); FILE * MACRO = fopen(nome2,"w"); fprintf(MACRO,"void %s()\n{\n",nome); xmin=1.e20; xmax=-1.e20; ymin=1.e20; ymax=-1.e20; for( i=1; i< Nhits; i++) { if( info[i][5] == 1 ) { // parallel straws if (info[i][0]-info[i][3] < xmin) xmin = info[i][0]-info[i][3]; if (info[i][0]+info[i][3] > xmax) xmax = info[i][0]+info[i][3]; if (info[i][1]-info[i][3] < ymin) ymin = info[i][1]-info[i][3]; if (info[i][1]+info[i][3] > ymax) ymax = info[i][1]+info[i][3]; } } if( xmin > 0. ) xmin = 0.; if( xmax < 0.) xmax = 0.; if( ymin > 0. ) ymin = 0.; if( ymax < 0.) ymax = 0.; deltax = xmax-xmin; deltay = ymax - ymin; if( deltax > deltay) { ymin -= 0.5*(deltax-deltay); ymax = ymin+ deltax; delta = deltax; } else { xmin -= 0.5*(deltay-deltax); xmax = xmin+ deltay; delta= deltay; } xmax = xmax + delta*0.05; xmin = xmin - delta*0.05; ymax = ymax + delta*0.05; ymin = ymin - delta*0.05; fprintf(MACRO,"TCanvas* my= new TCanvas();\nmy->Range(%f,%f,%f,%f);\n",xmin,ymin,xmax,ymax); fprintf(MACRO,"TEllipse* TC = new TEllipse(%f,%f,%f,%f,0.,360.);\n",Ox,Oy,R,R); fprintf(MACRO,"TC->SetLineColor(4);\nTC->Draw();\n"); fprintf(MACRO,"TGaxis *Assex = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n",xmin,0.,xmax,0.,xmin,xmax); fprintf(MACRO,"Assex->Draw();\n"); fprintf(MACRO,"TGaxis *Assey = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n", 0.,ymin,0.,ymax,ymin,ymax); fprintf(MACRO,"Assey->Draw();\n"); for( i=0; i< Nhits; i++) { if( info[i][5] == 1 ) { // parallel straws fprintf(MACRO,"TEllipse* E%d = new TEllipse(%f,%f,%f,%f,0.,360.);\nE%d->Draw();\n", i,info[i][0],info[i][1],info[i][3],info[i][3],i); } } fprintf(MACRO,"}\n"); fclose(MACRO); return ; } //----------end of function PndSttTrackFinderReal::WriteMacroParallelAssociatedHits void PndSttTrackFinderReal::WriteMacroSkewAssociatedHits( Double_t KAPPA,Double_t FI0,Double_t D,Double_t Fi,Double_t R, Int_t Nhits, Double_t info[][6], Int_t Nincl, Int_t Mincl[], Double_t inclination[][3], Int_t imaxima, Int_t nMaxima ) { Int_t i, j, i1, ii, index, Kincl, nlow, nup, STATUS; Double_t xmin , xmax, ymin, ymax, Ox, Oy, dx, dy, diff, d1, d2, delta, deltax, deltay, deltaz, deltaS, factor, zmin, zmax, Smin, Smax, S1, S2, z1, z2, y1, y2, vx1, vy1, vz1, C0x1, C0y1, C0z1, aaa, bbb, ccc, angle, minor, major, distance, Rx, Ry, LL, Aellipsis1, Bellipsis1,fi1, fmin, fmax, offset, step, SkewInclWithRespectToS, zpos, zpos1, zpos2, Tiltdirection1[2], zl[200],zu[200], POINTS1[6]; //------------------- skew straws hits Macro now char nome2[50]; FILE *MACRO; sprintf(nome2, "MacroPMaxN%dSMaxN%dSkewHitsSummary%d.C",imaxima+1,nMaxima+1, IVOLTE); MACRO = fopen(nome2,"w"); sprintf(nome2, "MacroPMaxN%dSMaxN%dSkewHitsSummary%d",imaxima+1,nMaxima+1, IVOLTE); fprintf(MACRO,"void %s()\n{\n",nome2); //KAPPA = 1./166.67 ; FI0 = 1.5*PI; Smin=zmin = 1.e10; Smax=zmax = -zmin; index=0; for( i=1; i< Nhits; i++) { if( info[i][5] == 1. ) continue; // exclude parallel straws Kincl = (int) info[i][5] - 1; aaa = sqrt(inclination[Kincl][0]*inclination[Kincl][0]+inclination[Kincl][1]*inclination[Kincl][1]+ inclination[Kincl][2]*inclination[Kincl][2]); vx1 = inclination[Kincl][0]/aaa; vy1 = inclination[Kincl][1]/aaa; vz1 = inclination[Kincl][2]/aaa; C0x1 = info[i][0]; C0y1 = info[i][1]; C0z1 = info[i][2]; Ox = (R+D)*cos(Fi); Oy = (R+D)*sin(Fi); calculateintersections(Ox,Oy,R,C0x1,C0y1,C0z1,info[i][3], vx1,vy1,vz1, &STATUS,POINTS1); if(STATUS < 0 ) continue ; for( ii=0; ii<2; ii++){ j=3*ii; distance = sqrt( (POINTS1[j]-C0x1)*(POINTS1[j]-C0x1) + (POINTS1[1+j]-C0y1)*(POINTS1[1+j]-C0y1) + (POINTS1[2+j]-C0z1)*(POINTS1[2+j]-C0z1) ); if( distance >= 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; // checks that the projected ellipsis doesn't go out the boundaries of both the skew straw and the trajectory cylinder if( fabs(POINTS1[j+2]-ZCENTER_STRAIGHT) > SEMILENGTH_STRAIGHT- Aellipsis1 || distance + bbb > info[i][4] // the ellipsis goes out of the boundaries of the skew straw ) continue; //-------------------------- fi1 = atan2(POINTS1[j+1]-Oy, POINTS1[j]-Ox) ; // atan2 returns radians in (-pi and +pi] if( fi1 < 0.) fi1 += 2.*PI; if( zmin > POINTS1[j+2] - Aellipsis1 ) zmin = POINTS1[j+2] - Aellipsis1; if( zmax < POINTS1[j+2] + Aellipsis1 ) zmax = POINTS1[j+2] + Aellipsis1; if( Smin > fi1 - Bellipsis1 ) Smin = fi1 - Bellipsis1; if( Smax < fi1 + Bellipsis1 ) Smax = fi1 + Bellipsis1; Double_t rotation1 = 180.*atan2(Tiltdirection1[1],Tiltdirection1[0])/PI; fprintf(MACRO,"TEllipse* E%d = new TEllipse(%f,%f,%f,%f,0.,360.,%f);\n", index,POINTS1[j+2],fi1,Aellipsis1,Bellipsis1,rotation1); index++; } // end of for( ii=0; ii<2; ii++) } // end of for( i=1; i< Nhits; i++) if(index==0) goto nohits ; if( zmax < zmin ) goto nohits ; if( Smax < Smin ) goto nohits; aaa = Smax-Smin; Smin -= aaa*0.05; Smax += aaa*0.05; aaa = zmax-zmin; zmin -= aaa*0.05; zmax += aaa*0.05; if(Smax > 2.*PI) Smax = 2.*PI; if( Smin < 0.) Smin = 0.; if ( KAPPA >= 0.) { fmin = KAPPA*zmin + FI0; fmax = KAPPA*zmax + FI0; } else { fmax = KAPPA*zmin + FI0; fmin = KAPPA*zmax + FI0; } j = (int) (0.5*fmax/ PI); i = (int) (0.5*fmin/PI); fmin -= i*2.*PI; if(fmin < 0.) { fmin += 2.*PI; fmax -= (i-1)*2.*PI; offset = (i-1)*2.*PI; j -= (i-1) ; } else { fmax -= i*2.*PI; offset = i*2.*PI; j -= i; } if ( j == 0){ if( Smax < fmax) Smax = fmax; if( Smin > fmin) Smin = fmin; } else if (j > 0) { Smax = 2.*PI; Smin = 0.; } fprintf(MACRO,"TCanvas* my= new TCanvas();\nmy->Range(%f,%f,%f,%f);\n",zmin,Smin,zmax,Smax); for( ii=0; ii< index; ii++) { fprintf(MACRO,"E%d->Draw();\n",ii); } if( j == 0 ) { fprintf(MACRO,"TLine* FOUND = new TLine(%f,%f,%f,%f);\nFOUND->SetLineColor(2);\nFOUND->Draw();\n", zmin,KAPPA*zmin+FI0-offset,zmax, KAPPA*zmax+FI0-offset); } else { zl[0]=zmin; zu[j]=zmax; for( ii = 0; ii < j ; ii++){ zu[ii]=zl[ii+1]= ((ii+1)*2.*PI + offset - FI0)/KAPPA; } for( ii = 0; ii < j+1 ; ii++){ fprintf(MACRO,"TLine* FOUND%d = new TLine(%f,%f,%f,%f);\nFOUND%d->SetLineColor(2);\nFOUND%d->Draw();\n", ii, zl[ii] , KAPPA*zl[ii]+FI0-offset-ii*2.*PI , zu[ii], KAPPA*zu[ii]+FI0-offset-ii*2.*PI ,ii,ii); } } // end of if(j == 0 ) deltaz = zmax-zmin; deltaS = Smax-Smin; fprintf(MACRO,"TGaxis *Assex = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n", zmin+0.05*deltaz,Smin+0.05*deltaS,zmax-0.05*deltaz,Smin+0.05*deltaS,zmin+0.05*deltaz,zmax-0.05*deltaz); fprintf(MACRO,"Assex->Draw();\n"); fprintf(MACRO,"TGaxis *Assey = new TGaxis(%f,%f,%f,%f,%f,%f,510);\n", zmin+0.05*deltaz,Smin+0.05*deltaS,zmin+0.05*deltaz,Smax-0.05*deltaS,Smin+0.05*deltaS,Smax-0.05*deltaS); fprintf(MACRO,"Assey->Draw();\n"); nohits: ; fprintf(MACRO,"}\n"); fclose(MACRO); } //----------end of function PndSttTrackFinderReal::WriteMacroSkewAssociatedHits ClassImp(PndSttTrackFinderReal)