#include "PndTrkCleanup.h" #include "PndTrkVectors.h" #include "PndTrkConstants.h" #include #include // Root includes #include "TROOT.h" using namespace std; //----------begin of function PndTrkCleanup::BadTrack_ParStt bool PndTrkCleanup::BadTrack_ParStt( Double_t Oxx, Double_t Oyy, Double_t Rr, Double_t strawradius, Short_t Charge, Double_t Xcross[2], // Xcross[0]=point of entrance; // Xcross[1]=point of exit. Double_t Ycross[2], Short_t nHits, Short_t* ListHits, Double_t info[][7], int istampa, Double_t cut, Short_t maxnum, Short_t islack// uncertainty allowed as far as // the n. of hits that should be present in a given section of the Stt track. ) { Short_t ibad, ihit, ninside; Double_t cut2, length, Xprevious, Yprevious, S, Distance[nHits+1]; // class with all the geometry calculations : PndTrkCTGeometryCalculations GeometryCalculator; cut2=cut*cut; ibad=0; Xprevious=Xcross[0]; Yprevious=Ycross[0]; length= GeometryCalculator.CalculateArcLength(Oxx, Oyy, Rr, Charge, Xcross, Ycross ); if(istampa>1) {cout<<"in BadTrack_ParStt : Xingresso "<1) {cout<<"in BadTrack_ParStt :hit || n. "<0){ // here S is already the fi of the last point. if( GeometryCalculator.IsInsideArc(Oxx,Oyy,Charge, Xcross, Ycross, S )) { Distance[nHits] = (info[ListHits[nHits-1]][0]-Xcross[1])* (info[ListHits[nHits-1]][0]-Xcross[1])+ (info[ListHits[nHits-1]][1]-Ycross[1])* (info[ListHits[nHits-1]][1]-Ycross[1]); ; if(istampa>1)cout<<"in BadTrack_ParStt, Stt || hit n. (original notation) " <cut2 ){ if( Distance[nHits]>16.*cut2)return true; ibad++; } // end of if( Distance[nHits]>cut2 ) } // end of if( IsInsideArc if(istampa>1)cout<<"in BadTrack_ParStt, ibad "< if this flag is true the hit of the track furthest from the origin is // at the boundary of the sector; // nHits == # hits in this track under scrutiny; // info == some information on the hits; // ListHits == list hits in this track under scrutiny; // TubeID == hit number; bool boundary, yes; Short_t i, index, index_last, inner, j, nIntersections, outer, tube_current, tube_next; Double_t C2, dist, dist2, fi, Start[3], Xend[2], Yend[2]; PndTrkCTGeometryCalculations GeometryCalculator; // the first hit is the farthest from (0,0,0); // 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 VERTICAL (BUT NOT OUTERMOST) axial boundary left; // 22= outer VERTICAL (BUT NOT OUTERMOST) axial boundary right; // 13= outermost axial boundary left; // 23= outermost axial boundary right; // the flags are 2 (StrawCode and StrawCode2) since a straw can belong to 2 boundaries; // first check if the first hit is required to be at the boundary; if so verify the condition; // only one hole is allowed; if( farthest_hit_is_boundary ){ index = TubeID[ ListHits[nHits-1] ]; // number corresponding to the Straw of the last hit in the list; if( StrawCode[ index -1 ] == -1 && StrawCode2[ index -1 ] ==-1 ) { // not at any boundary; before returning false check if one hole is still allowed and if so // check if any of the neighbours of the first hit, is at boundary : if so increment the // number of holes and go on; if( holes >= MAX_NOT_CONNECTED) return false; // because we know already that holes becomes >= MAX_NOT_CONNECTED+1; yes=false; // loop over the Straws contiguous to the current under scrutiny; for(i=0;i -1 || StrawCode2[ ListParContiguous[index-1][i] -1 ] > -1) { holes++; yes=true; break; } } // end of for(i=0;i calculate the contiguity level // of the two hits under scrutiny; // next-to-contiguos hits; if( dist2 < 16.*STRAWRADIUS*STRAWRADIUS * 1.1) { // increase holes by 1 and then check if holes>MAX_NOT_CONNECTED discard the track; holes++; if(holes > MAX_NOT_CONNECTED) return false; continue; // case accepted; } else { // distance between tube_current and tube_next >= 2 straws, discard the track; return false; } } // end of for(i=0;i MAX_NOT_CONNECTED; return false; } else { // check if any of the neighbor straws, BELONGING TO THE TRACK AND IN THE RIGHT // ORDER (according to the Charge), is a boundary track; boundary = false; Xend[0] = Yend[0] = 0. ; // the origin; Xend[1] = xTube[index_last]; Yend[1] = yTube[index_last]; for(j=0;j C2 = Ox*Ox + Oy*Oy ; dist2 = xxyyTube[tube_next-1] -2.*(xTube[tube_next-1]*Ox + yTube[tube_next-1]*Oy) +C2; dist = fabs(sqrt(dist2)-R); if( dist > STRAWRADIUS * 1.5) continue; //tubes doesn't lie on trajectory; the factor 1.5 just to be sure // now check that the tube_next lies between (0,0) and the hit = ListHits[0] when running on the // trajectory according to the charge (namely : +ve --> clockwise, -ve --> anticlockwise); // the coordinates of the ends of the arc are given in Xend[2] and Yend[2]; // fi is the angle (between 0. and 2 PI ) of the point under srutiny (==tube_next center); fi = atan2( yTube[tube_next-1]-Oy, xTube[tube_next-1]-Ox); if(fi<0.) fi += 2.*PI; if(fi<0.) fi = 0.; if( GeometryCalculator.IsInsideArc(Ox,Oy,Charge,Xend,Yend,fi)){ // check if this is at boundary; if( !(StrawCode[tube_next-1] == -1 && StrawCode2[tube_next-1] == -1) ) { boundary = true; break; } } // end of if( GeometryCalculator.IsInsideArc(Ox,Oy,Charge,Xend,Yend,f)) } // end of for(j=0;jR_STT_INNER_PAR_MAX ){ // outer Parallel hit. ListOuterHits[ *nOuterHits ] = ListHits[ihit]; (*nOuterHits)++; if(info[ListHits[ihit]][0]<0.){ ListOuterHitsLeft[ *nOuterHitsLeft ] = ListHits[ihit]; (*nOuterHitsLeft)++; } else { ListOuterHitsRight[ *nOuterHitsRight ] = ListHits[ihit]; (*nOuterHitsRight)++; } }else{ ListInnerHits[ *nInnerHits ] = ListHits[ihit]; (*nInnerHits)++; if(info[ListHits[ihit]][0]<0.){ ListInnerHitsLeft[ *nInnerHitsLeft ] = ListHits[ihit]; (*nInnerHitsLeft)++; } else { ListInnerHitsRight[ *nInnerHitsRight ] = ListHits[ihit]; (*nInnerHitsRight)++; } } } } //----------end of function PndTrkCleanup::SeparateInnerOuterParallel //----------begin of function PndTrkCleanup::SeparateInnerOuterRightLeftAxialStt void PndTrkCleanup::SeparateInnerOuterRightLeftAxialStt( // input Double_t info[][7], Short_t *ListHits, Short_t nHits, Double_t R_STT_INNER_PAR_MAX, // output Short_t *ListInnerHitsLeft, Short_t *ListInnerHitsRight, Short_t *ListOuterHitsLeft, Short_t *ListOuterHitsRight, Short_t *nInnerHitsLeft, Short_t *nInnerHitsRight, Short_t *nOuterHitsLeft, Short_t *nOuterHitsRight ) { Short_t ihit; Double_t r; // separation of inner Parallel Stt hits from outer Parallel Stt hits. *nInnerHitsLeft=0; *nInnerHitsRight=0; *nOuterHitsLeft=0; *nOuterHitsRight=0; for(ihit=0 ;ihitR_STT_INNER_PAR_MAX ){ // outer Parallel hit. if(info[ListHits[ihit]][0]<0.){ ListOuterHitsLeft[ *nOuterHitsLeft ] = ListHits[ihit]; (*nOuterHitsLeft)++; } else { ListOuterHitsRight[ *nOuterHitsRight ] = ListHits[ihit]; (*nOuterHitsRight)++; } }else{ if(info[ListHits[ihit]][0]<0.){ ListInnerHitsLeft[ *nInnerHitsLeft ] = ListHits[ihit]; (*nInnerHitsLeft)++; } else { ListInnerHitsRight[ *nInnerHitsRight ] = ListHits[ihit]; (*nInnerHitsRight)++; } } // end of if(r>R_STT_INNER_PAR_MAX ) } // end of for(ihit=0 ;ihitIsInTargetPipe( Ox, Oy, R, fi0, kappa, charge, semiverticalgap ); } //----------begin of function PndTrkCleanup::ParalCleanup bool PndTrkCleanup::SttParalCleanup( Double_t ApotemaInnerParMax, Double_t ApotemaMinOuterPar, Short_t Charge, Double_t FI0, Double_t FiLimitAdmissible, Double_t GAP, Double_t info[][7], int istampa, int IVOLTE, Short_t *Listofhits, Short_t nHits, Double_t Oxx, Double_t Oyy, Double_t Rr, Double_t RStrawDetMax, // radius of circle encompassing ALL // the straw detector; Double_t RStrawDetMin, Double_t Start[3], Double_t strawradius ) { // this method does 3 things : // // 1) finds the entrance and exit points in the STT parallel volumes of the current track; // 2) eliminates from the track hit list possible spurious hits that are not encompassed // by the entrance and exit point; // 3) eliminates the tracks if the hit sequence is not continuous enough. bool flaggo; Short_t flagInnerSttR, flagOuterSttR, flagInnerSttL, flagOuterSttL, flagOutStt; Short_t enne, i, ihit, ipurged, islack, nintersections, nnn, nInnerHits, nInnerHitsLeft, nInnerHitsRight, nOuter, nOuterHits, nOuterHitsLeft, nOuterHitsRight, nIntersections[2], ListHits[nHits], ListInnerHits[nHits], ListInnerHitsLeft[nHits], ListInnerHitsRight[nHits], ListOuterHits[nHits], ListOuterHitsLeft[nHits], ListOuterHitsRight[nHits]; Double_t epsilonTheta, fi, r, aux[2], Xcross[2], Ycross[2], XcrossL[2], YcrossL[2], XcrossR[2], YcrossR[2], XcrossOut[2], YcrossOut[2], XintersectionList[7], // there is also the last boundary FiLimitAdmissible YintersectionList[7]; // take into account and the two possible // intersections with the external circle. islack=1; // uncertainty allowed in the # of straws that should be hit in a given part // of the Stt detector. //------------------------ // elimination of hits outside the physical FI range (FiLimitAdmissible) due to finite length of // Straws. if(istampa>1) { cout<<"SttParalCleanup, evento n. "< FI0){ if( fi>FiLimitAdmissible+epsilonTheta) continue; } else { fi += 2.*PI; if( fi >FiLimitAdmissible+epsilonTheta ) continue; } // end of if( fi > FI0) } else { // continuation of if(Charge <0) if( fi > FI0){ fi -= 2.*PI; } // end of if( fi > FI0) if (fi < FiLimitAdmissible-epsilonTheta) continue; } // end of if(Charge <0) ListHits[ipurged]=Listofhits[i]; ipurged++; } // end of for(i=0, ipurged=0; i< nHits; i++) nHits = ipurged; if(istampa>1) { cout<<"SttParalCleanup, evento n. "<1) { cout<<"SttParalCleanup, evento n. "< track outside outer perimeter; // 0 --> at least 1 intersection with polygon, therefore a possible entry and an exit; // 1 --> track contained completely between the two polygons; } // end of if(nHits==0) // first of all, find possible intersection points with outer circle encompassing // the Stt system. // class with all the geometry calculations: PndTrkCTGeometryCalculations GeometryCalculator; flagOutStt = GeometryCalculator.FindIntersectionsOuterCircle( Oxx, Oyy, Rr, RStrawDetMax, XcrossOut, YcrossOut ); // intersection with Inner Section. flagInnerSttL= GeometryCalculator.FindTrackEntranceExitbiHexagonLeft( GAP, Oxx, Oyy, Rr, Charge, Start, RStrawDetMin, ApotemaInnerParMax, XcrossL, YcrossL ); // find the entrance and exit of the track in the Inner Right Parallel Straw region. // This region is bounded by two Hexagons, and it has the target gap in the middle. flagInnerSttR= GeometryCalculator.FindTrackEntranceExitbiHexagonRight( GAP, Oxx, Oyy, Rr, Charge, Start, RStrawDetMin, ApotemaInnerParMax, XcrossR, YcrossR ); if(istampa>1) { cout<<"SttParalCleanup, evento n. "<1) { cout<<"SttParalCleanup, evento n. "< cut. islack // uncertainty allowed as far as the n. of hits that should be present. ) ){ return false; } if(istampa>1) cout<<"uscito da BadTrack_ParStt.\n"; //----------------------------------------------------- } // end of if(flaggo) } // end of if( flagInnerSttL == -1 && flagInnerSttR == -1 ) //outer: ; islack=1; // reset the extra uncertainty in the # Stt. //------------ Outer Parallel Stt hits section. // find the entrance and exit of the track in the Outer Parallel Straw region, Left side. // This region is bounded by a Hexagon (inner), a Circle (outer) and it has // the target gap in the middle. // Returns -1 if there are 0 or 1 intersections, 0 if there are at least 2 intersections. flagOuterSttL= GeometryCalculator.FindTrackEntranceExitHexagonCircleLeft( Oxx, Oyy, Rr, Charge, Start, ApotemaMinOuterPar, RStrawDetMax, GAP, XcrossL, YcrossL ); //------------ // find the entrance and exit of the track in the Outer Parallel Straw region, Right side. // This region is bounded by a Hexagon (inner), a Circle (outer) and it has // the target gap in the middle. flagOuterSttR= GeometryCalculator.FindTrackEntranceExitHexagonCircleRight( Oxx, Oyy, Rr, Charge, Start, ApotemaMinOuterPar, RStrawDetMax, GAP, XcrossR, YcrossR ); if(istampa>1) { cout<<"SttParalCleanup, evento n. "<1) { cout<<"in SttParalCleanup Outer, caso traccia entra in L and R outer. Dopo scelta, flagOuterSttR " <1) { cout<<"in SttParalCleanup Outer, nhit considerati "<< nnn <1) { cout<<"in SttParalCleanup Outer, caso in cui FiLimitAdmissible = "<< FiLimitAdmissible <<" conta!" <1) { cout<<"in SttParalCleanup Outer, prima di ChooseEntranceExitbis, nintersections " << nintersections<<" e loro lista :"<=2){ cout<<"SttParalCleanup, OUTER, caso R || L true, IVOLTE = "< cut. islack // uncertainty allowed as far as the n. of hits that should be present. ) ) return false; // } // end of if(nOuterHits==0) //---------------------------------------------------------------------------- // finito: ; // if the code comes here it means that the track is acceptable. // nHits = nOuterHits+nInnerHits; return true; }; //----------end of function PndTrkCleanup::SttParalCleanup //----------begin of function PndTrkCleanup::SttSkewCleanup bool PndTrkCleanup::SttSkewCleanup( Double_t ApotemaMaxSkew, Double_t ApotemaMinSkew, Short_t Charge, Double_t cut, // cut distance (in cm). Double_t FI0, Double_t FiLimitAdmissible, Double_t GAP, Double_t info[][7], int istampa, int IVOLTE, Short_t *Listofhits, Short_t maxnum, // max number allowed of failures to pass the cut. int MAXSTTHITS, Short_t nHits, Double_t Oxx, Double_t Oyy, Double_t Rr, Double_t RStrawDetMax, Double_t *S, Double_t Start[3], Double_t strawradius ) { bool ConsiderLastHit; Short_t flagSttL, flagSttR, flagOutStt; Short_t i, ipurged, ibad, islack, nHitsLeft, nHitsRight, nintersections, ninside, nnn, nIntersections[2], ListHits[nHits], ListHitsRight[nHits], ListHitsLeft[nHits]; Double_t cut2, epsilonTheta, fi, FiStart, length, r, Sprevious, aux[2], Distance[MAXSTTHITS+1], Xcross[2], Ycross[2], XcrossL[2], YcrossL[2], XcrossR[2], YcrossR[2], XcrossOut[2], YcrossOut[2], XintersectionList[5], // second index =0 --> inner Hexagon, =1 --> outer. YintersectionList[5]; // first index : all the possible intersections // (up to 12 intersections). // class with all the geometry calculations : PndTrkCTGeometryCalculations GeometryCalculator; cut2=cut*cut; islack=1;// uncertainty allowed as far as // the n. of hits that should be present in a given section of the Stt track. //------------------------ // elimination of hits outside the physical FI range (FiLimitAdmissible) due to finite length of // Straws. epsilonTheta = strawradius/Rr; // some extra slac for being conservative. if(istampa>1) cout<<"\n\nevt "<1)cout<<"\thit // n. "< FI0){ if( fi>FiLimitAdmissible+epsilonTheta) continue; } else { fi += 2.*PI; if( fi > FiLimitAdmissible+epsilonTheta ) continue; } // end of if( fi > FI0) } else { // continuation of if(Charge <0) if( fi > FI0){ fi -= 2.*PI; } // end of if( fi > FI0) if (fi < FiLimitAdmissible-epsilonTheta) continue; } // end of if(Charge <0) if(istampa>1)cout<<"in SttSkewCleanup : hit preso!"<1)cout<<"in SttSkewCleanup : hit skew prima di purga = " <1)cout<<"in SttSkewCleanup : n. hit skew Left = " <1)cout<<"in SttSkewCleanup : flagLeft (-1,0,1) = "<1)cout<<"in SttSkewCleanup : distanza entrata-uscita<4*strawradius,flagSttR set at -1!\n"; } if( flagSttL == 0 && (XcrossL[0]-XcrossL[1])*(XcrossL[0]-XcrossL[1])+ (YcrossL[0]-YcrossL[1])*(YcrossL[0]-YcrossL[1]) < 16.*strawradius*strawradius ){ flagSttR=-1; if(istampa>1)cout<<"in SttSkewCleanup : distanza entrata-uscita<4*strawradius,flagSttL set at -1!\n"; } if (flagSttR != 0 && flagSttL != 0 ) { //nHits=0; if(istampa>1)cout<<"in SttSkewCleanup : flagSttR = "<=2){ cout<<"in SttSkewCleanup, IVOLTE = "<1)cout<<"in SttSkewCleanup :hit n. "<< ListHits[i] <<" is NOT inside the arc between entrance and exit; hit excluded!\n"; } ninside++; Distance[i] = 2.*Rr*Rr*(1.-cos(S[i]-Sprevious)); // this is the usual // distance**2 formula: (x1-x2)**2+(y1-y2)**2; // it is already 'protected' against S[i] jumps // around 2PI/0. Sprevious = S[i]; if(Distance[i]<0.) Distance[i]=0.; // rounding errors protection. if(istampa>=2)cout<<"in SttSkewCleanup, Hit n. "<< ListHits[i]<<" has Distance " <cut2){ if(Distance[i]>16.*cut2){ if(istampa>=2)cout<<"in SttSkewCleanup, Hit n. "<< ListHits[i]<<" has Distance " <4.*cut [="<=2)cout<<"in SttSkewCleanup, Hit n. "<< ListHits[i]<<" has Distance " < cut [="<1){ cout<<"in SttSkewCleanup, n. Hits inside = "<=2)cout<<"in SttSkewCleanup, last Hit n. "<< ListHits[nHits-1]<<" has Distance from boundary " <cut2 ){ if( Distance[nHits]>16.*cut2){ if(istampa>=2)cout<<"in SttSkewCleanup, last Hit n. "<< ListHits[nHits-1]<<" has Distance from boundary " <4 .*cut [="<=2)cout<<"in SttSkewCleanup, last Hit n. "<< ListHits[nHits-1]<<" has Distance from boundary " < cut [="< maxnum){ if(istampa>=2)cout<<"in SttSkewCleanup, reject this track because ibad = "<< ibad <<" and it is > maxnum [="< inner Hexagon, =1 --> outer. YintersectionList[12][2]; // first index : all the possible intersections // (up to 12 intersections). //------------------------ // calculation of the Maximum FI angle possible (if it is a +ve charge) of the Minimum // for this track, taking into account // that the maximum possible Z of a hit is ZCENTER_STRAIGHT + SEMILENGTH_STRAIGHT; the minimum // Z of a hit is ZCENTER_STRAIGHT - SEMILENGTH_STRAIGHT. if(Charge<0){ if( KAPPA>0.){ FiLimitAdmissible = FI0 + KAPPA*(ZCENTER_STRAIGHT + SEMILENGTH_STRAIGHT) ; } else { FiLimitAdmissible = FI0 + KAPPA*(ZCENTER_STRAIGHT - SEMILENGTH_STRAIGHT) ; } } else { if( KAPPA>0.){ FiLimitAdmissible = FI0 + KAPPA*(ZCENTER_STRAIGHT - SEMILENGTH_STRAIGHT) ; } else { FiLimitAdmissible = FI0 + KAPPA*(ZCENTER_STRAIGHT + SEMILENGTH_STRAIGHT) ; } } // end of if(Charge<0) //----------------------------------------------------------------------------------------------------- // parallel cleanup. //----------------stampe if(istampa>=2){ cout<<" IVOLTE = "<1) cout<<"\tentra in SttParalCleanup\n"; // if(nHitsPar>0 && !SttParalCleanup( if(!SttParalCleanup( ApotemaMaxInnerPar, ApotemaMinOuterPar, Charge, FI0, FiLimitAdmissible, GAP, info, istampa, IVOLTE, ListHitsPar, // input only for now. nHitsPar, // it doesn't get modify for now. Oxx, Oyy, Rr, RStrawDetMax, RStrawDetMin, Start, strawradius ) ){ if(istampa>1) cout<<"uscito da SttParalCleanup : false\n"; return false; } if(istampa>1) cout<<"uscito da : SttParalCleanup true\n"; //---------------------------------------------------------------------------- // skew cleanup. if(istampa>1) cout<<"\tentra in SttSkewCleanup\n"; if ( ! (SttSkewCleanup( ApotemaMaxSkew, ApotemaMinSkew, Charge, 3., // cut distance FI0, FiLimitAdmissible, GAP, info, istampa, IVOLTE, ListHitsSkew, // it doesn't get modify for now. 1, // max number of failures allowed. MAXSTTHITS, nHitsSkew, // it doesn't get modify for now. Oxx, Oyy, Rr, RStrawDetMax, auxS, Start, // starting point of trajectory. strawradius ) ) ) { if(istampa>1) cout<<"uscito da SttSkewCleanup false\n"; return false; } if(istampa>1) cout<<"uscito da SttSkewCleanup true\n"; return true; }; //----------end of function PndTrkCleanup::TrackCleanup //----------begin of function PndTrkCleanup::XYCleanup bool PndTrkCleanup::XYCleanup( // general infos about the axial Straws; int istampa, Double_t info[][7], Short_t (*ListParContiguous)[6], Short_t *nParContiguous, Short_t *StrawCode, Short_t *StrawCode2, Short_t *TubeID, Double_t *xTube, Double_t *yTube, Double_t *zTube, Double_t *xxyyTube, // the following are the info of the track under scrutiny; Double_t Ox, Double_t Oy, Double_t R, Short_t Charge, Short_t *ListHits, Short_t nHits, Double_t R_STT_INNER_PAR_MAX, Short_t nScitilHitsInTrack, // input, # of SciTil hits in the current track; Short_t* ListSciTilHitsinTrack, // input, list of SciTil hits in the current track; Double_t posizSciTil[][3] // input, info on all the SciTil position; ) { bool connected, farthest_hit_is_boundary, good; Short_t auxListHits[MAXSTTHITSINTRACK], holes, i, j, k, nArcs_populated, tListInnerHitsLeft[nHits], tListInnerHitsRight[nHits], tListOuterHitsLeft[nHits], tListOuterHitsRight[nHits], tube_adjacent, tube_current, tube_next, tube_near, ListHitsInArc[MAXSTTHITSINTRACK][56], // ordered list of hits in each Arc (from first to last // according to the charge of the particle;if the maximum // # of Intersected Sector is 56, than the maximum # of Arcs is 28; nHitsInArc[56], // number of hits in each Arc; the maximum # of Arcs is 56; nInnerHitsLeft, nInnerHitsRight, nOuterHitsLeft, nOuterHitsRight; // OrderedSectorList[56]; // ordered list of Sectors crossed (from first to last); each // Sector number is the Sector where the Arc lies; Double_t dist2, FiOrderedList[2], FiStart, Xcross[2], Ycross[2]; Vec ListInnerHitsLeft(tListInnerHitsLeft,nHits,"ListInnerHitsLeft"), ListInnerHitsRight(tListInnerHitsRight,nHits,"ListInnerHitsRight"), ListOuterHitsLeft(tListOuterHitsLeft,nHits,"ListOuterHitsLeft"), ListOuterHitsRight(tListOuterHitsRight,nHits,"ListOuterHitsRight"); // class with all the geometry calculations: PndTrkCTGeometryCalculations GeometryCalculator; //------------------------------------------------------------------------------------------------------------ // first of all, eliminate spurious with SciTil's since it is faster; // now check if there is an intersection with the SciTil; // calculate the intersection points in XY of the track trajectory with a circle tangent to the SciTil in // the middle of each SciTil tile; these can be 0 or 2; // if there are no intersections don't do anything; if there are 2 intersections check that there is a SciTil // hit in the proper place; // FindIntersectionsOuterCircle returns -1 or 0; // if FindIntersectionsOuterCircle returns -1 there are no intersections, if it returns 0 there are 2; if( GeometryCalculator.FindIntersectionsOuterCircle( Ox, Oy, R, RADIUSSCITIL, Xcross, Ycross ) >= 0 ){ // there are 2 intersections; // choose the first entrance point according to the charge of the particle; // ChooseEntranceExit3 works under the hypothesis that there are at least 2 intersections. FiStart = atan2(-Oy,-Ox); if( FiStart < 0.) FiStart += TWO_PI; if( FiStart < 0.) FiStart = 0.; GeometryCalculator.ChooseEntranceExit3( Ox, Oy, Charge, FiStart, 2, // # of Intersections between track and Circle; Xcross, // input and output; these are the intersections; Ycross, // input and output; these are the intersections; FiOrderedList // output ); // the intersection point must be close enough to at least 1 SciTil hit; good = false; for(i=0;i Axial Outer Right // Sector = 2 --> Axial Inner Right // Sector = 3 --> Axial Inner Left // Sector = 4 --> Axial Outer Left // -------------------------------------------------------------------------------------------------- // the intersections of the current track with the boundaries of each Axial Sector (Inner Left, Outer Left, // Inner Right, Outer Right) determine the number of Arcs in which the trajectory is subdivided; // for each Arc the number of ordered (according to the charge of the particle) axial STT hits are // found and listed; // nArcs_populated = # of Arcs (maximum possible 28 in the Left side + 28 in the Right Side of STT axial detector // ---> 56 maximum) populated by axial STT hits; // OrderedSectorList = ordered list, from last to first, of the Sectors corresponding to each Arc ; // nHitsInArc[56] = # of hits of the track belonging to each Arc (in order corresponding to the Sector order); // ListHitsInArc[MAXSTTHITSINTRACK][56] = list of hits in each Arc; this list is ordered clockwise or anticlockwise // according to the charge; GeometryCalculator.ListAxialSectorsCrossedbyTrack_and_Hits( Ox, // input; Oy, // input; R, // input; Charge, // input; nHits, // input; ListHits, // input; info, // input; nArcs_populated, // output; # Arcs of trajectory populated by at least 1 axial hit; this is <= 28; // OrderedSectorList, // output; ordered list of Sectors crossed (from first to last); each // // Sector number correspond to the Sector where the Arc lies; nHitsInArc, // output; number of hits in each Sector; if the maximun # of Intersected Sector is 56, // than the maximum # of Arcs is 28; ListHitsInArc // output; ordered list of hits in each Arc (from first to last // according to the charge of the particle;if the maximum // # of Intersected Sector is 56, than the maximum # of Arcs is 28; ); //------------------------------------------------- if(istampa>0){ cout<<"from XYCleanup,after ListAxialSectorsCrossedbyTrack_and_Hits :"< Right Axial Outer; // 2 --> Right Axial Inner; // 3 --> Left Axial Inner; // 4 --> Left Axial Outer; // # of "holes" in the track; holes = 0; // no_holes = false; // if the following flag is true the hit of the track furthest from the origin is at the boundary of // this sector; farthest_hit_is_boundary = false; // loop from the last Arc (the farthest according to the charge of the track) to the first one; for(i=nArcs_populated-1;i>=0; i--){ for(j=0;j0; i--) // ----------------------------------------------------------------------- } //----------end of function PndTrkCleanup::XYCleanup ClassImp(PndTrkCleanup);