// $Id: PndFTSCAGBTracker.cxx,v 1.16 2016/12/22 11:45:25 mpugach Exp $ // ************************************************************************** // This file is property of and copyright by the FIAS PANDA group * // PANDA Experiment at FIAS-GSI, All rights reserved. * // * // Primary Authors: Ivan Kisel * // Igor Kulakov * // Mykhailo Pugach * // Maksym Zyzak * // for The FIAS PANDA group . * // * // Permission to use, copy, modify and distribute this software and its * // documentation strictly for non-commercial purposes is hereby granted * // without fee, provided that the above copyright notice appears in all * // copies and that both the copyright notice and this permission notice * // appear in the supporting documentation. The authors make no claims * // about the suitability of this software for any purpose. It is * // provided "as is" without express or implied warranty. * // * //*************************************************************************** #ifdef DRAW #include "PndFTSCADisplay.h" #define MAIN_DRAW #define DRAW_FIT #define USE_CA_FIT //25.01.17 // #define DRAW_FIT_LOCAL #define DRAW_CA #endif //DRAW #ifdef STAR_HFT #define START_FROM_TARGET // how to fit #elif defined(PANDA_STT) || defined(PANDA_FTS) #define START_FROM_TARGET #define USE_CA_FIT //14.02.17 #else #endif #include "PndFTSCAGBTracker.h" #include "PndFTSCAGBHit.h" #include "PndFTSCAGBTrack.h" // #include "PndFTSCATrackParam.h" #include "PndFTSArray.h" #include "PndFTSCAMath.h" #if !defined(PANDA_FTS) #include "PndFTSCATrackLinearisationVector.h" #endif #include "PndFTSCAPerformance.h" #include "TStopwatch.h" #include "L1Timer.h" #include "FTSCATarget.h" #include "FTSCAHits.h" #include "FTSCAHitsV.h" #include "FTSCATracks.h" #include "Math/SMatrix.h" #include "TMatrixD.h" #include "TVectorD.h" #include #include #include #include using namespace std; //TODO DELL ME!!! #include "PndFTSCAPerformance.h" #include "PndFTSCAMCPoint.h" #include "PndFTSPerformanceBase.h" bool SINGLE_THREADED = false; PndFTSCAGBTracker::PndFTSCAGBTracker() : fHits( 0 ), fNHits( 0 ), fTrackHits( 0 ), fTracks( 0 ), fNTracks( 0 ), fTime( 0 ), fStatNEvents( 0 ), fSliceTrackerTime( 0 ), fSliceTrackerCpuTime( 0 ), fGTi(), fTi(fNFindIterations), fStatGTi(), fStatTi(fNFindIterations) { //* constructor for ( int i = 0; i < 20; i++ ) fStatTime[i] = 0; fGTi.Add("init "); fGTi.Add("iters "); fGTi.Add("tracker"); fGTi.Add("fitter "); fTi.SetNIter( fNFindIterations ); // for iterations fTi.Add("init "); fTi.Add("1plet "); fTi.Add("2plet "); fTi.Add("3plet "); fTi.Add("4plet "); fTi.Add("5plet "); fTi.Add("6plet "); fTi.Add("convrt"); fTi.Add("plets "); fTi.Add("nghbrs"); fTi.Add("tracks"); fTi.Add("merger"); fTi.Add("finish"); fStatGTi = fGTi; fStatTi = fTi; } void PndFTSCAGBTracker::Init() { fNHits = 0; fTrackHits = 0; fTracks = 0; fNTracks = 0; fTime = 0.; fStatNEvents = 0; fSliceTrackerTime = 0.; fSliceTrackerCpuTime = 0.; for ( int i = 0; i < 20; ++i ) { fStatTime[i] = 0.; } } PndFTSCAGBTracker::~PndFTSCAGBTracker() { StartEvent(); } void PndFTSCAGBTracker::StartEvent() { //* clean up track and hit arrays if(fTrackHits) delete[] fTrackHits; fTrackHits = 0; if(fTracks) delete[] fTracks; fTracks = 0; fNHits = 0; fNTracks = 0; } void PndFTSCAGBTracker::SetNHits( int nHits ) { //* set the number of hits fHits.Resize( nHits ); fNHits = nHits; } void PndFTSCAGBTracker::IdealTrackFinder() { //* Creation of ideal tracks based on hits, which correspond to the MC-points. PndFTSCAPerformance* perf = &PndFTSCAPerformance::Instance(); if (fHits.Size() > 0) sort( &(fHits[0]), &(fHits[fHits.Size()-1]), PndFTSCAGBHit::Compare ); const int NMCTracks = perf->GetMCTracks()->Size(); vector > hits(NMCTracks+1); for(int iH=0; iHHitLabel(id).fLab[0]; for( int k = 1; k < 3 && trackId < 0; k++ ) trackId = perf->HitLabel(id).fLab[k]; if ( trackId < 0 ) continue; hits[trackId].push_back(iH); } int nTracks = NMCTracks; if(fTracks) delete [] fTracks; fTracks = new PndFTSCAGBTrack[nTracks]; fNTracks = nTracks; if(fTrackHits) delete [] fTrackHits; fTrackHits = new int[fHits.Size()]; int curHit = 0; int curTr = 0; for(int iT=0; iTGetMCTracks())[iT].FirstMCPointID(); //21.03 int nMCPoints = (*perf->GetMCTracks())[iT].NMCPoints(); fTracks[curTr].SetFirstHitRef( curHit ); //begin:mod //21.03 PndFTSCAMCTrack curMcTrack = perf->MCTrack(curTr); //21.03 int idmcpoint = curMcTrack.FirstMCPointID(); PndFTSCALocalMCPoint *points = &((*perf->GetMCPoints()).Data()[nFirstMC]); PndFTSCATrackParam mcTrackParam; // USING AS INITIAL APPROXIMATION MC-INFO mcTrackParam.SetX(points[0].X()); mcTrackParam.SetY(points[0].Y()); mcTrackParam.SetTX(points[0].Px()/points[0].Pz()); mcTrackParam.SetTY(points[0].Py()/points[0].Pz()); mcTrackParam.SetQP(points[0].QP()); //(1/abs(curMcTrack.P())); mcTrackParam.SetZ(points[0].Z()); fTracks[curTr].SetInnerParam(mcTrackParam); //fTracks[curTr].SetOuterParam(mcTrackParam); //end:mod //fTracks[curTr].SetTrackHitIdsArraySize(hits[iT].size()); int curStation = -1; int nHits = 0; for(unsigned int iH=0; iH= fNTracks) nTracksVector = fNTracks - iTr; // for(int iTr=0; iTr6) //nTrackHits[iv]=6; memFirstHits[iv] = fTracks[iTr+iv].FirstHitRef(); startPoint[iv] = fTracks[iTr+iv].InnerParam(); endPoint[iv] = startPoint[iv]; } #ifdef DRAW_FIT PndFTSCAPerformance* perf = &PndFTSCAPerformance::Instance(); PndFTSCADisplay::Instance().DrawTPC(); uint_v nHitsDraw(nTrackHits); for(unsigned int ihit = 0; ihit nTrackHits[iV] - 1) continue; const unsigned int jhit = ihit; PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]]; #ifdef DRAW_FIT_LOCAL { float xLoc, yLoc, zLoc; PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc ); PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kGreen+1); } const int iMCP = perf->GetMCPoint( h ); if (iMCP < 0) continue; const PndFTSCALocalMCPoint &mcPoint = (*perf->GetMCPoints())[iMCP]; { float xLoc, yLoc, zLoc; PndFTSCAParameters::GlobalToCALocal( mcPoint.X(), mcPoint.Y(), mcPoint.Z(), h.Angle(), xLoc, yLoc, zLoc ); PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kRed, (Size_t)1); } #else PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(), kGreen+1); #endif } } uint_m mcmask(true); foreach_bit(unsigned int iV, mcmask){ if (mcmask[iV]==0) continue; PndFTSCAGBHit &hh = fHits[fTrackHits[memFirstHits[iV] ]]; const PndFTSPerformanceBase::PndFTSCAHitLabel &l = perf->HitLabel( hh.ID() ); const int MCIndex = l.fLab[0]; if(MCIndex>-1) { PndFTSCAMCTrack &mc = (*perf->GetMCTracks())[MCIndex]; for( int iP = 0; iP < mc.NMCPoints(); iP++ ) { PndFTSCALocalMCPoint mcPoint = (*perf->GetMCPoints())[mc.FirstMCPointID()+iP]; #ifdef DRAW_FIT_LOCAL // float xLoc, yLoc, zLoc; // PndFTSCAParameters::GlobalToCALocal( mcPoint.X(), mcPoint.Y(), mcPoint.Z(), mcPoint.Angle(), xLoc, yLoc, zLoc ); // PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, kRed, (Size_t)1); #else double mcX0 = mcPoint.X(); double mcY0 = mcPoint.Y(); double mcZ = mcPoint.Z(); PndFTSCADisplay::Instance().DrawGBPoint((float)mcX0, (float)mcY0, (float)mcZ, kOrange+1, (Size_t)1); #endif } } } PndFTSCADisplay::Instance().Ask(); #endif PndFTSCATrackParamVector vStartPoint; PndFTSCATrackParamVector vEndPoint; vStartPoint.ConvertTrackParamToVector(startPoint, nTracksVector); vEndPoint.ConvertTrackParamToVector(endPoint, nTracksVector); float_m active0 = static_cast( uint_v( Vc::IndexesFromZero ) < nTracksVector ); uint_v firstHits(memFirstHits); float_m fitted = float_m(true); fitted &= static_cast(static_cast(nTrackHits) > 0); #ifdef USE_CA_FIT #ifdef DRAW_FIT1 // PndFTSCADisplay::Instance().ClearView(); // PndFTSCADisplay::Instance().SetTPCView(); // PndFTSCADisplay::Instance().DrawTPC(); PndFTSCADisplay::Instance().DrawGBPoint(0,0,0, kMagenta, 0.5); // target PndFTSCADisplay::Instance().Ask(); #endif for (unsigned int i=0; i<1; i++){ vEndPoint = vStartPoint; vEndPoint.SetCov( 0, 1.f); vEndPoint.SetCov( 1, 0.f); vEndPoint.SetCov( 2, 10.f); vEndPoint.SetCov( 3, 0.f); vEndPoint.SetCov( 4, 0.f); vEndPoint.SetCov( 5, 1.f); vEndPoint.SetCov( 6, 0.f); vEndPoint.SetCov( 7, 0.f); vEndPoint.SetCov( 8, 0.f); vEndPoint.SetCov( 9, 1.f); vEndPoint.SetCov( 10, 0.f); vEndPoint.SetCov( 11, 0.f); vEndPoint.SetCov( 12, 0.f); vEndPoint.SetCov( 13, 0.f); vEndPoint.SetCov( 14, 10.f); vEndPoint.SetChi2( 0.f); vEndPoint.SetNDF(-5); vEndPoint.SetDirection(true); bool init = false; if(i==0) init = true; fitted &= FitTrackCA( vEndPoint, firstHits, nTrackHits, nTracksVector, active0, 0, init ); vStartPoint = vEndPoint; /*cout<<"End of fit in >> direction\n"; cout< nTrackHits[iV] - 1) continue; const int jhit = ihit; PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]]; #ifdef DRAW_FIT_LOCAL float xLoc, yLoc, zLoc; PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc ); PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, iV); #else PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV); //TODO kMagenta?? #endif } } //20.01.17 PndFTSCADisplay::Instance().Ask(); #endif vStartPoint = vEndPoint; //refit in the backward direction: going from the last hit to the first fitted &= FitTrack( vStartPoint, firstHits, nTrackHits, nTracksVector,active0, 1 ); #ifdef DRAW_FIT1 // PndFTSCADisplay::Instance().ClearView(); // PndFTSCADisplay::Instance().SetTPCView(); // PndFTSCADisplay::Instance().DrawTPC(); for(int ihit = 0; ihit nTrackHits[iV] - 1) continue; const int jhit = ihit; PndFTSCAGBHit &h = fHits[fTrackHits[memFirstHits[iV] + jhit]]; #ifdef DRAW_FIT_LOCAL float xLoc, yLoc, zLoc; PndFTSCAParameters::GlobalToCALocal( h.X(), h.Y(), h.Z(), h.Angle(), xLoc, yLoc, zLoc ); PndFTSCADisplay::Instance().DrawGBPoint( xLoc, yLoc, zLoc, iV); #else PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV);//TODO kMagenta?? #endif } } //20.01.17 PndFTSCADisplay::Instance().Ask(); #endif } } #endif // USE_CA_FIT for(int iV=0; iV < nTracksVector; iV++) { startPoint[iV] = PndFTSCATrackParam( vStartPoint, iV ); endPoint[iV] = PndFTSCATrackParam( vEndPoint, iV ); if ( !fitted[iV] ) { startPoint[iV].SetAsInvalid(); endPoint[iV].SetAsInvalid(); } } //cout<<"begin fitted "<<(static_cast(nTrackHits) > 0)<= 3; if (active.isEmpty()) return active; // cout<<"active1 "<(!active)); /* //nplets-case bool SkipMe; for (unsigned int xxx=0; xxx<42; xxx++){ SkipMe = false; cout<<"############# \n"; cout<<"#6-plet start from "<(false); const unsigned int NHitsMax = 6; // check x-lets fit const unsigned int FirstHit = 15; // check part of the track begining from x-th hit const bool AddLastHit = true; #endif //active &= NTHits >= NHitsMax+FirstHit; if (active.isEmpty()) return active; // cout<<"active2 "< hits( NHitsMax ); //cout<<"track-begin\n"; for ( unsigned int ihit = FirstHit; (ihit-FirstHit) < NHitsMax; ihit++ ) { const uint_m valid = ihit < NTHits; uint_v::Memory id; const PndFTSCAGBHit **hs = new const PndFTSCAGBHit*[float_v::Size]; foreach_bit(unsigned int iV, valid) { if ( dir ) id[iV] = firstHits[iV] + (NTHits[iV]-static_cast(1)) - ihit; else id[iV] = firstHits[iV] + ihit; hs[iV] = &(fHits[fTrackHits[id[iV]]]); } hits[ihit-FirstHit] = FTSCAHitV( hs, uint_v(id), static_cast(valid) ); //cout<<"hits[ihit-FirstHit].X0() "<20.f || isnan(t.Err2X())); //here to add IsNAN-condition for Err2X //cout<<"flashback "< 0; iihit-- ) { // active &= float_m(uint_v(iihit)>=0); // const FTSCAHitV& hit1 = hits[iihit]; // active &= t.Transport( hit1, GetParameters(), qp0, active ) ; // active &= t.Filter( hit1, GetParameters(), active ); // cout<= 0; ihit-- ) { const FTSCAHitV& hit = hits[ihit]; active &= float_m(uint_v(ihit) Vc::Zero) && (t.Cov(2) > Vc::Zero) && (t.Cov(5) > Vc::Zero) && (t.Cov(9) > Vc::Zero) && (t.Cov(14) > Vc::Zero); //t.SetNDF(1);//HACK return ok; } void PndFTSCAGBTracker::InitialTrackApproximation( PndFTSCATrackParamVector &track, uint_v &firstHits, uint_v::Memory &NTrackHits, int &nTracksV, float_m active0 ) { //*Initial approximation for the track reconstruction by the least-square method. uint_v nHits(NTrackHits); nHits.setZero(static_cast(!active0)); //float_m good = nHits > 2; unsigned int nHitsMax = nHits.max(); float_v X(Vc::Zero), Y(Vc::Zero), R(Vc::Zero); float_v lx(Vc::Zero), ly(Vc::Zero), lx2(Vc::Zero), ly2(Vc::Zero), lr2(Vc::Zero); float_v x(Vc::Zero), y(Vc::Zero), x2(Vc::Zero), y2(Vc::Zero), xy(Vc::Zero), r2(Vc::Zero), xr2(Vc::Zero), yr2(Vc::Zero), r4(Vc::Zero); float_v::Memory xH0, yH0, zH0, angle0; for(int iV=0; iV < nTracksV; iV++) { if( !(active0[iV]) ) continue; PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV]]]; xH0[iV] = h.X(); yH0[iV] = h.Y(); zH0[iV] = h.Z(); angle0[iV] = h.Angle(); } float_v xTmp(xH0); float_v yTmp(yH0); float_v zTmp(yH0); const float_v angleV0(angle0); float_v xV0, yV0, zV0(zH0); PndFTSCAParameters::GlobalToCALocal(xTmp, yTmp, zV0, angleV0, xV0, yV0, zV0); vector xV(nHitsMax), yV(nHitsMax), zV(nHitsMax); for (unsigned int ihit = 0; ihit < nHitsMax; ihit++ ) { float_m active = static_cast( ihit < nHits ); if(active.isEmpty()) continue; float_v::Memory xH, yH, zH; for(int iV=0; iV < nTracksV; iV++) { if( !(active[iV]) ) continue; if( ihit > NTrackHits[iV] - 1) continue; PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + ihit]]; xH[iV] = h.X(); yH[iV] = h.Y(); zH[iV] = h.Z(); } xTmp.load(xH); yTmp.load(yH); zTmp.load(zH); PndFTSCAParameters::GlobalToCALocal(xTmp, yTmp, zTmp, angleV0, xV[ihit], yV[ihit], zV[ihit]); } #ifdef PANDA_FTS // float_v A0, A1=0.f, A2=0.f, A3=0.f, A4=0.f, A5=0.f, a0, a1=0.f, a2=0.f, // b0, b1=0.f, b2=0.f; // float_v z0, x, y, z, S, w, wz, wS; // // int i=NHits-1; // z0 = zV[i]; // w = 1.f; // A0 = w; // a0 = w*xV[i]; // b0 = w*yV[i]; // for( int ihit = 0; ihit < nHitsMax; ihit++) // { // float_m active = static_cast( ihit < nHits ); // x = xV[i]; // y = yV[i]; // w = 1.f; // z = zV[i] - z0; // S = Sy[i]; // wz = w*z; // wS = w*S; // A0(active) +=w; // A1(active) +=wz; A2(active) +=wz*z; // A3(active) +=wS; A4(active) +=wS*z; A5(active) +=wS*S; // a0(active) +=w*x; a1(active) +=wz*x; a2(active) +=wS*x; // b0(active) +=w*y; b1(active) +=wz*y; b2(active) +=wS*y; // } // // // // float_v ANew[6] = {A0, A1, A2, A3, A4, A5}; // InvertCholetsky3(ANew); // // float_v L, L1; // t.SetX( ANew[0]*a0 + ANew[1]*a1 + ANew[3]*a2 ); // t.SetTx( ANew[1]*a0 + ANew[2]*a1 + ANew[4]*a2 ); // float_v txtx1 = 1.+t.tx*t.tx; // L = (ANew[3]*a0 + ANew[4]*a1 + ANew[5]*a2) /(txtx1); // if(fabs(A3[0]) < 1.e-6) // { // ANew[0] = A0; // ANew[1] = A1; // ANew[2] = A2; // InvertCholetsky2(ANew); // t.x = ANew[0]*a0 + ANew[1]*a1; // t.tx =ANew[1]*a0 + ANew[2]*a1; // } // // L1 = L*t.tx; // A1 = A1 + A3*L1; // A2 = A2 + ( A4 + A4 + A5*L1 )*L1; // b1+= b2 * L1; // ANew[0] = A0; // ANew[1] = A1; // ANew[2] = A2; // InvertCholetsky2(ANew); // // track.SetY( ANew[0]*b0 + ANew[1]*b1 ); // track.SetTy ( ANew[1]*b0 + ANew[2]*b1 ); // // float_v zeroS = !float_v(fabs(A5) < float_v(1.e-8f)); // track.q = -L*c_light_i*rsqrt(txtx1 + t.ty*t.ty); // track.qp = track.qp & zeroS; // track.z = z0; #else for( int ihit = 0; ihit < nHitsMax; ihit++) { float_m active = static_cast( ihit < nHits ); if(active.isEmpty()) continue; lx = xV[ihit] - xV0; ly = yV[ihit] - yV0; lx2 = lx*lx; ly2 = ly*ly; lr2 = lx2+ly2; x(active) += lx; y(active) += ly; x2(active) += lx2; y2(active) += ly2; xy(active) += lx*ly; r2(active) += lr2; xr2(active)+= lx*lr2; yr2(active)+= ly*lr2; r4(active) += lr2*lr2; } x /= static_cast(nHits); y /= static_cast(nHits); xy /= static_cast(nHits); x2 /= static_cast(nHits); y2 /= static_cast(nHits); xr2 /= static_cast(nHits); yr2 /= static_cast(nHits); r2 /= static_cast(nHits); r4 /= static_cast(nHits); const float_v Cxx = x2 - x*x; const float_v Cxy = xy - x*y; const float_v Cyy = y2 - y*y; const float_v Cxr2 = xr2 - x*r2; const float_v Cyr2 = yr2 - y*r2; const float_v Cr2r2 = r4 - r2*r2; const float_v Q1 = Cr2r2*Cxy - Cxr2*Cyr2; const float_v Q2 = Cr2r2*(Cxx-Cyy) - Cxr2*Cxr2 + Cyr2*Cyr2; const float_v Phi = 0.5f * CAMath::ATan2(2.f*Q1, Q2); const float_v SinPhi = CAMath::Sin(Phi); const float_v CosPhi = CAMath::Cos(Phi); const float_v Kappa = (SinPhi*Cxr2 - CosPhi*Cyr2)/Cr2r2; const float_v Delta = SinPhi*x - CosPhi*y - Kappa*r2; const float_v Rho = 2.f*Kappa / CAMath::Sqrt(float_v(Vc::One) - 4.f*Delta*Kappa); const float_v D = 2.f*Delta / ( float_v(Vc::One) + CAMath::Sqrt(float_v(Vc::One) - 4.f*Delta*Kappa)); R = float_v(Vc::One)/Rho; X = (D+R)*SinPhi; Y = -(D+R)*CosPhi; float_v kappa(Vc::Zero); kappa(good) = Rho; const float_v sinPhi0 = -X*kappa; const float_v cosPhi0 = Y*kappa; float_v dS(Vc::Zero), dS2(Vc::Zero), Z(Vc::Zero), dSZ(Vc::Zero); for ( int ihit = 0; ihit < nHitsMax; ihit++ ) { float_m active = static_cast( ihit < nHits ); if(active.isEmpty()) continue; lx(active) = xV[ihit]-xV0; ly(active) = yV[ihit]-yV0; const float_v ex = cosPhi0; const float_v ey = sinPhi0; const float_v dx = lx; float_v ey1 = kappa * dx + ey; // check for intersection with X=x float_v ex1 = 1.f - ey1 * ey1; ex1(ex1 1.0e-4f ) ? ( 2.f * CAMath::ASin( dSin ) / kappa ) : dl; dS(active) += ds; dS2(active) += ds*ds; Z(active) += zV[ihit]; dSZ(active) += ds*zV[ihit]; } float_v det = Vc::One/( static_cast(nHits)*dS2 - dS*dS ); float_v Z0(Vc::Zero), X0(Vc::Zero), Y0(Vc::Zero), dzds(Vc::Zero); Z0(good) = det*( dS2*Z - dS*dSZ); dzds(good) = det*( static_cast(nHits)*dSZ - Z*dS ); float_v signCosPhi0(Vc::One); signCosPhi0(cosPhi0( ihit < nHits ); if( !(active[iV]) ) continue; if( ihit > NTrackHits[iV] - 1) continue; PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + ihit]]; PndFTSCADisplay::Instance().DrawGBPoint(h.X(), h.Y(), h.Z(), h.Angle(),iV); } } double xCL = (X+xV0)[0]; double yCL = (Y+yV0)[0]; double zCL = 0, xC=0, yC=0, zC=0; PndFTSCAParameters::CALocalToGlobal(xCL,yCL,zCL, double(angleV0[0]), xC, yC, zC ); double rad = fabs(R[0]); PndFTSCADisplay::Instance().DrawArc(xC, yC, rad, -1, 1); PndFTSCADisplay::Instance().DrawGBPoint(xC, yC, 0.f, 0.f,-1); PndFTSCADisplay::Instance().Ask(); #endif track.SetAngle(angleV0); track.SetSinPhi(-sinPhi0); // -1 factor is a correction for direction (should be from inner to outer, but previous formula calculate for fromOuterToInner) track.SetSignCosPhi(-signCosPhi0); track.SetX(xV0); track.SetY(yV0); track.SetZ(Z0); track.SetDzDs(-dzds); track.SetQPt(-kappa/GetParameters().cBz()); #endif } float_m PndFTSCAGBTracker::FitTrack( PndFTSCATrackParamVector &t, uint_v &firstHits, uint_v::Memory &NTrackHits, int &nTracksV, float_m active0, bool dir ) { //* Fitting of the track by using Kalman Filter, //* taking into account changes of his parameters due crossing through the detector material. #ifdef PANDA_FTS UNUSED_PARAM6( t, firstHits, NTrackHits, nTracksV, active0, dir ); return float_m(true); #else PndFTSCATrackParamVector::PndFTSCATrackFitParam fitPar; PndFTSCATrackLinearisationVector l( t ); bool first = 1; t.CalculateFitParameters( fitPar ); uint_v nHits(NTrackHits); nHits.setZero(static_cast(!active0)); int nHitsMax = nHits.max(); for ( unsigned int ihit = 0; ihit < nHitsMax; ihit++ ) { float_m active = active0 && static_cast( ihit < nHits ); if(active.isEmpty()) continue; float_v::Memory xH, yH, zH, hitAlpha; float_v::Memory memXOverX0, memXTimesRho; float_v::Memory err2X1h, err2x2h, errX12h; int_v::Memory mHitNDF; #ifdef DRIFT_TUBES float_v::Memory rh, isLeftH; #endif for(int iV=0; iV < nTracksV; iV++) { if( !(active[iV]) ) continue; if( ihit > NTrackHits[iV] - 1) continue; const unsigned int jhit = dir ? ( NTrackHits[iV] - 1 - ihit ) : ihit; PndFTSCAGBHit &h = fHits[fTrackHits[firstHits[iV] + jhit]]; hitAlpha[iV] = h.Angle(); xH[iV] = h.X(); yH[iV] = h.Y(); zH[iV] = h.Z(); err2X1h[iV] = h.Err2X1(); #ifdef PANDA_FTS // TODO why "-" ? errX12h[iV] = -h.ErrX12(); #else errX12h[iV] = h.ErrX12(); #endif err2x2h[iV] = h.Err2X2(); #ifdef DRIFT_TUBES rh[iV] = h.R(); isLeftH[iV] = h.IsLeft() ? 1.f : 0.f; #endif mHitNDF[iV] = GetParameters().Station( h.IRow() ).NDF; memXOverX0[iV] = GetParameters().GetXOverX0(h.IRow()); memXTimesRho[iV] = GetParameters().GetXTimesRho(h.IRow()); } const float_v err2X1(err2X1h), err2x2(err2x2h), errX12(errX12h); #ifdef DRIFT_TUBES const float_v isLeftF(isLeftH),r(rh); const float_m isLeft = isLeftF > float_v(Vc::Zero); #endif const int_v hitNDF(mHitNDF); float_v xV(xH); float_v yV(yH); float_v zV(zH); const float_v hitAlphaV(hitAlpha); const float_v xOverX0(memXOverX0); const float_v xTimesRho(memXTimesRho); #ifdef DRAW_FIT #ifdef DRAW_FIT_LOCAL assert(0); // TODO #endif for(int iV=0; iV(active) ); t.CalculateFitParameters( fitPar ); t.SetAngle(float_v( hitAlpha )); first = 0; } float_v x1 = yV; #ifdef DRIFT_TUBES float_v sinPhi = t.SinPhi(); float_v xCorr = r - r/(sqrt(1-sinPhi*sinPhi)); x1(isLeft) += xCorr; x1(!isLeft) -= xCorr; #endif const float_m &filtered = t.FilterWithMaterial(x1, zV, err2X1, errX12, err2x2, 0.999f, active, hitNDF); active &= filtered; if(active.isEmpty()) continue; #ifdef DRAW_FIT #ifdef DRAW_FIT_LOCAL assert(0); // TODO #endif xL = t.X(); yL = t.Y(); zL = t.Z(); PndFTSCAParameters::CALocalToGlobal(xL, yL, zL, t.Angle(), xGl, yGl, zGl); for(int iV=0; iV 50 ); //this check is wrong! X could be < 50, when a sector is rotated! ok &= (t.Cov(0) > Vc::Zero) && (t.Cov(2) > Vc::Zero) && (t.Cov(5) > Vc::Zero) && (t.Cov(9) > Vc::Zero) && (t.Cov(14) > Vc::Zero); ok &= CAMath::Abs( t.SinPhi() ) < .999f; t.SetSignCosPhi( 1.f, ok && static_cast(l.CosPhi() >= Vc::Zero) ); t.SetSignCosPhi(-1.f, ok && static_cast(l.CosPhi() < Vc::Zero) ); return ok; #endif } void PndFTSCAGBTracker::FindTracks() { //* main tracking routine fStatNEvents++; #ifdef MAIN_DRAW PndFTSCAPerformance::Instance().SetTracker( this ); PndFTSCADisplay::Instance().Init(); PndFTSCADisplay::Instance().SetGB( this ); PndFTSCADisplay::Instance().SetTPC( GetParameters() ); #endif //MAIN_DRAW #ifdef MAIN_DRAW #if defined(PANDA_STT) || defined(PANDA_FTS) PndFTSCADisplay::Instance().SetTPC( GetParameters() ); PndFTSCADisplay::Instance().DrawTPC(); //PndFTSCADisplay::Instance().DrawGBPoints(); PndFTSCADisplay::Instance().DrawGBHits( *this, kGreen+2, 0.1, 1 ); PndFTSCADisplay::Instance().SaveCanvasToFile( "Hits.pdf"); PndFTSCADisplay::Instance().Ask(); #endif // // PndFTSCADisplay::Instance().DrawGBHits( *this, kRed, 0.2, 2 ); // // PndFTSCADisplay::Instance().SaveCanvasToFile( "Hits_b.pdf"); // // PndFTSCADisplay::Instance().Ask(); #endif //MAIN_DRAW //cout << " NHits = " << fNHits << endl; /// \brief The necessary data is transfered to the track-finder /// The necessary data is transfered to the track-finder ///Data is structured and saved by track-finders for each sector. ///To speed up the process in each row 2D-grid with the bin size ///inversely proportional to the number of hits in the row is introduced. ///Hits are sorted by grid bins and for each grid bin 1st hit is found and saved. ///Such data structure allows to quickly find closest hits to the point with given ///coordinates, which is required while neighbours hits are searched and additional ///hits are attached to segments. #ifdef USE_IDEAL_TF IdealTrackFinder(); #else // USE_IDEAL_TF CATrackFinder(); FitTracks(); #ifndef USE_CA_FIT // fitted in CATrackFinder FitTracks(); #endif #endif // USE_IDEAL_TF #ifdef DRAW_CA PndFTSCADisplay &disp = PndFTSCADisplay::Instance(); for( int i=0; i &hits) { const int NHits2 = hits.size(); SetNHits(NHits2); fFStrips.Resize(NHits2); // create a virtual strip for each hit (currently strips position is not used for FTS, so don't have to fill them) fBStrips.Resize(NHits2); // create a virtual strip for each hit fHits.Resize(NHits2); for (int iH = 0; iH < NHits2; iH++){ fHits[iH] = hits[iH]; fHits[iH].SetFStripP( &fFStrips[iH] ); fHits[iH].SetBStripP( &fBStrips[iH] ); } } void PndFTSCAGBTracker::ReadSettings( std::istream &in ) { //* Read settings from the file in >> fParameters; } bool PndFTSCAGBTracker::ReadSettingsFromFile(string prefix) { ifstream ifile((prefix).data()); if ( !ifile.is_open() ) return 0; ReadSettings(ifile); return 1; } const int StartStationShift = 1; //BEGIN@@@@!!!!STT===>>>FTS COMBINATORIAL PART!!!!@@@@@ //ATTENTION LAST VERSION OF STT_CA_TRACK_FINDER FROM PANDAROOT_TRUNK /* */ void PndFTSCAGBTracker::CATrackFinder() { #ifdef DRAW_CA PndFTSCADisplay::Instance().SetTPC( GetParameters() ); //PndFTSCADisplay::Instance().SetTPCView(); PndFTSCADisplay::Instance().ClearView(); #endif // prepare memory for tracks if(fTracks) delete [] fTracks; if(fTrackHits) delete [] fTrackHits; fTracks = new PndFTSCAGBTrack[5000]; // TODO fTrackHits = new int[3000*PndFTSCAParameters::MaxNStations]; // TODO fNTracks = 0; //std::sort( fHits.Data(), fHits.Data() + fNHits, PndFTSCAGBHit::Compare ); to make convertion faster FTSCAHits hits( NStations(), fHits.Size()/NStations() ); // suppose approximately equal nHits per station //convert hits for( int iH = 0; iH < fNHits; ++iH ) { hits.Add( FTSCAHit( fHits[iH], iH ) ); } hits.Sort(); //estimate PV float xT = 0, yT = 0, zT = 0; /// Find Tracks // set parameters; TODO depend on iteration // const float kCorr = 4.;//1;//.2; // correction on pulls width const float kCorr = 2.; const float kCorr2 = kCorr*kCorr; fPick_m = 3.*kCorr; //3.*kCorr; fPick_r = 5.*kCorr; //5.*kCorr; fPickNeighbour = 7.*kCorr;//3.*kCorr; 7*kCorr TRACK_PROB_CUT = 0.01; //0.01; TRACK_CHI2_CUT = 10.*kCorr2;//10.*kCorr2; // TRIPLET_CHI2_CUT = 15.*kCorr2; // TMath::Prob(20,-3+1+6) = TMath::Prob(15,2) = 5e-04 TRIPLET_CHI2_CUT = 20.*kCorr2; // TMath::Prob(20,-3+1+6) = TMath::Prob(15,2) = 5e-04 // Set correction in order to take into account overlaping // The reason is that low momentum tracks are too curved and goes not from target direction. That's why hit sort is not work idealy fMaxDX0 = 0; // fMaxInvMom = 2; fMaxInvMom = 5; // fTarget = FTSCATarget( xT, yT, zT, 10, 10, fMaxInvMom/3.f, GetParameters(), 0 ); fTarget = FTSCATarget( xT, yT, zT, 10, 10, fMaxInvMom, GetParameters(), 0 ); //cout<<"MaxCellLength = "< gTrackHitRecords; void PndFTSCAGBTracker::Create1Plets( const FTSCATarget& target, const FTSCAHits& hits, FTSCAElementsOnStation &r, int iS ) { const FTSCAElementsOnStation& hs = hits.OnStation(iS); r.clear(); r.reserve(hs.size()/float_v::Size + 1); TrackHitRecord hitRecord; hitRecord.fPrevHit = -1; hitRecord.fStation = iS; //no vectorization for hits... for( unsigned int iH = 0; iH < hs.size(); iH += 1 ) //check with 2508 { const FTSCAHit &hit_t = hs[iH]; int ISta = (int) hit_t.IStation(); //const PndFTSCAGBHit &hit_1 = fHits[hit_t.Id()]; //float_v Tx_1 = float_v(hit_1.point_Px/hit_1.point_Pz); float_m valid = static_cast(uint_v::IndexesFromZero() < uint_v(hs.size() - iH) ); FTSCAHitV hit( &(hs[iH]), valid ); PndFTSCATrackParamVector param; float_m active = hit.IsValid(); if (ISta<32) { // start from target param.InitByTarget(target); float_v r0(10.f); float_v r1(10.f); float_v r2(10.f); r0(active) = hit.X0() - target.X0(); r1(active) = hit.X1() - target.X1(); r2(active) = hit.X2() - target.X2(); param.InitDirection(r0, r1, r2); //param.InitDirection( hit.X0() - target.X0(), hit.X1() - target.X1(), hit.X2() - target.X2() ); param.SetAngle( hit.Angle() ); active &= param.Transport( hit, GetParameters(), active /*float_m(true)*/ ); // active &= param.Filter( hit, GetParameters(), active ); } else { param.SetAngle( hit.Angle() ); param.InitByHit( hit, GetParameters(), target.DQMom() ); param.SetTx(0.f); } if( active.isEmpty() ) continue; uint_v iHit = uint_v::IndexesFromZero() + iH; r.resize(r.size()+1); FTSCANPletV &nPlet = r.back(); nPlet = FTSCANPletV(iHit, int_v(hit.IStation()), param, active); nPlet.fNHits=1; //nPlet.fParam=param; //nPlet.fIsValid = active; nPlet.fLastHit = -1; foreach_bit( unsigned int iBit, active ) { hitRecord.fIHit = iHit[iBit]; nPlet.fLastHit[iBit] = gTrackHitRecords.size(); gTrackHitRecords.push_back(hitRecord); } } //cout<<"singlets on stat "< &nPlets, int iS, int cellLength ) { FTSCAElementsOnStation tmp0; FTSCAElementsOnStation tmp1; tmp0.fHitsRef = &hits; tmp0.fISta = iS; tmp1.fHitsRef = &hits; tmp1.fISta = iS; FTSCAElementsOnStation *rCurr = &tmp0; FTSCAElementsOnStation *rNext = &tmp1; Create1Plets( target, hits, *rCurr, iS ); //draw singlets #ifdef MAIN_DRAW1 PndFTSCADisplay::Instance().DrawGBNPlets(*rCurr); PndFTSCADisplay::Instance().Ask(); #endif for( int iLen=1; iLen<=cellLength; iLen++) { if ( rCurr->size() <= 0 ) break; if ( (*rCurr)[0].N() >= GetParameters().Station( iS ).CellLength ) break; //track-segment size check if ((rCurr->HitsRef())->OnStationConst( iS ).size() == 0) continue; //to take into account gapped tracks rNext->clear(); //cout << " iS+iLen " << (int) (iS+iLen) << endl; PickUpHits( *rCurr, *rNext, iS+iLen ); FTSCAElementsOnStation *rr = rCurr; rCurr=rNext; //draw cells #ifdef MAIN_DRAW1 PndFTSCADisplay::Instance().DrawGBNPlets(*rr); PndFTSCADisplay::Instance().Ask(); #endif rNext = rr; } nPlets = *rCurr; } void PndFTSCAGBTracker::PickUpHits( FTSCAElementsOnStation& curr, FTSCAElementsOnStation& next, int iS ) { next.SetStation( curr.IStation() ); next.clear(); if ( curr.size() <= 0 ) return; next.reserve(5*curr.size()); const float_v Pick2 = fPick*fPick; const FTSCAHits* allHits = curr.HitsRef(); const FTSCAElementsOnStation &hits = allHits->OnStationConst( iS ); //ATTENTION the hit-size is doubled because of lr-division //therefore twice more than necessary track-segments are created for( unsigned int iD1 = 0; iD1 < curr.size(); ++iD1 ) { FTSCANPletV& D1 = curr[iD1]; float_m valid1G = D1.IsValid(); if( valid1G.isEmpty() ) continue; //mod:begin /*PndFTSCATrackParamVector paramTransp; paramTransp = D1.ParamRef(); float_m activeTransp = valid1G; activeTransp &= paramTransp.Transport( hits[0], GetParameters(), valid1G );*/ //mod:end for( unsigned int ih=0; ih hit.Err2X1()*hit.Err2X1() ) { active &= dx1*dx1 < Pick_temp*((hit.R()*hit.R() + hit.Err2R())*Correction2 + hit.Err2X1()); } else { active &= dx1*dx1 < coeff*Pick2*(param.Err2X1() + hit.Err2X1() + hit.Err2R()*Correction2); } if ( active.isEmpty() ) continue; active &= param.Filter( hit, GetParameters(), active, TRIPLET_CHI2_CUT ); if ( active.isEmpty() ) continue; TrackHitRecord hitRecord; hitRecord.fStation = iS; hitRecord.fIHit = ih; FTSCANPletV nPlet( D1, iS, ih, param, active ); //compare these two constructors and if necessary update the new one with features from the old //FTSCANPletV( D1, D2, iV, param, active ) nPlet.fLastHit = -1; foreach_bit( unsigned int iBit, active ) { nPlet.fLastHit[iBit] = gTrackHitRecords.size(); hitRecord.fPrevHit = D1.fLastHit[iBit]; gTrackHitRecords.push_back(hitRecord); } //if (nPlet.N()>1) //{ //amount of hits on the segment is manual //cout<<"beforeRefit N "< TRIPLET_CHI2_CUT ) continue; next.push_back( nPlet ); //} //else {next.push_back( nPlet );} //cout<<"nPlet.N() "< thits( N ); float_m active = triplet.IsValid(); for ( int ihit = 0; ihit < N; ihit++ ) { const TESV& index = triplet.IHit(ihit); FTSCAHit hs[float_v::Size]; foreach_bit(unsigned int iV, active) { hs[iV] = hits[index.s[iV]][index.e[iV]]; } thits[ihit] = FTSCAHitV( hs, active ); } const FTSCAHitV& hit0 = thits[0]; FTSCATarget target = fTarget; //const float_v qp = param.QP(); //param.SetQP(qp); /*param.InitByTarget(target); param.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() ); param.SetAngle( hit0.Angle() );*/ //param.Transport( hit0, GetParameters(), active ); param.InitByTarget(target); //direction initialization (tx,ty) by hit-neighbour // if (hit0.IsValid() != thits[1].IsValid()) // { // //FTSCAHitV hit1(); //create from thits[1] such a hit-set that it would work out with all hits from thits[0] // cout<<"WE'VE GOT A PROBLEM \n"; // } //param.InitDirection(thits[1].X0() - hit0.X0(), thits[1].X1() - hit0.X1(), thits[1].X2() - hit0.X2()); param.InitDirection( hit0.X0(), hit0.X1(), hit0.X2() ); param.SetAngle( hit0.Angle() ); //param.InitCovMatrix(target.Err2QMom()); //cout<<"1. fit fwd NDF "<(active)) = -4; param.SetNDF(ndf); param.SetChi2(0.f); //cout<<"2. fit bckwrd NDF "<= 0; ihit-- ) { const FTSCAHitV& hit = thits[ihit]; active &= param.Transport( hit, GetParameters(), active ); active &= param.Filter( hit, GetParameters(), active ); //cout<<"2.after filter NDF "< pick ) return false; // neighbours must have same qp (or some other criteria) chi2 *= chi2; //cout<<"picked neigh \n"; //cout<= 0; --iS ) { // CHECKME FTSCAElementsOnStation& ts1 = triplets.OnStation( iS ); for( unsigned int iT1 = 0; iT1 < ts1.size(); ++iT1 ) { FTSCANPlet& t1 = ts1[iT1]; int neighIStation = t1.ISta(0) + StartStationShift; //cout<<"neighIStation "<= triplets.NStations() ) continue; // triplets can't start from this (non-existent) station FTSCAElementsOnStation& ts2 = triplets.OnStation( neighIStation ); /*if (ts2.size()==0) { int ncalls = 0; while (triplets.OnStation( neighIStation ).size()==0 && (neighIStation >=0 && neighIStation<47)) { if (ncalls>5) break; if (neighIStation==iS) {neighIStation-=1; continue;} neighIStation-=1; ncalls++; } } ts2 = triplets.OnStation( neighIStation );*/ char maxLevel = -1; // maxLevel of neighbour triplets vector< pair > neighCands; // save neighbour candidates for( unsigned int iT2 = 0; iT2 < ts2.size(); ++iT2 ) { const FTSCANPlet& t2 = ts2[iT2]; float chi2; if( !IsRightNeighbour( t1, t2, fPick, chi2 ) ) continue; if ( maxLevel < t2.Level() ) maxLevel = t2.Level(); if ( maxLevel == t2.Level() ) neighCands.push_back(pair(chi2 + t2.Chi2Level(),iT2)); } t1.Level() = maxLevel + 1; //cout<<"neighCands.size() "<0 ) { t1.Chi2Level() = t1.Chi2Neighbours(0); const pair tmp = t1.Neighbours()[0]; // leave only one. CHECKME for 1000tracks events t1.Neighbours().clear(); t1.Neighbours().push_back( tmp ); //cout<<"Got a neighbour! \n"; } } // iTrip1 //sort( ts1.begin(), ts1.end(), PndCANPlet::compare ); } //iStation } void PndFTSCAGBTracker::CreateTracks( const FTSCANPlets& triplets, FTSCATracks& tracks ) { const int Nlast = PndFTSCAParameters::LastCellLength; // N hits in the rightmost triplet int min_level = 1; // min level to start triplet. So min track length = min_level+3. // collect consequtive: the longest tracks, shorter, more shorter and so on for (int ilev = NStations()-Nlast; ilev >= min_level; ilev--) { // choose length FTSCATracks vtrackcandidate( tracks.HitsRef() ); //how many levels to check //lose maximum one hit and find all hits for min_level //const unsigned char min_best_l = (ilev > min_level) ? ilev-1 : min_level; //find all hits (slower) const unsigned char min_best_l = ilev + 3; //find candidates for( int istaF = 0; istaF <= NStations()-Nlast-ilev; istaF++ ) { const FTSCAElementsOnStation& tsF = triplets.OnStation( istaF ); for( unsigned int iTrip=0; iTrip < tsF.size(); iTrip++ ) { const FTSCANPlet* tripF = &(tsF[iTrip]); if (0) { // ghost supression !!! if ( tripF->Level() == 0 ) continue; // ghost suppression // find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet if ( tripF->Level() < ilev ) continue; // try only triplets, which can start track with ilev+3 length. w\o it have more ghosts, but efficiency either if ( (ilev == 0) && (tripF->ISta(0) != 0) ) continue; // ghost supression // collect only MAPS tracks-triplets } if ( tripF->Level() < min_best_l ) continue; FTSCATrack curr_tr; bool isUsed = false; for( int i = 0; i < tripF->N(); i++ ) { if( triplets.OnStation( tripF->ISta(0) ).GetHit( i, iTrip ).IsUsed() ) { isUsed = true; break; } curr_tr.AddHit( tripF->IHit(i) ); } if (isUsed) continue; curr_tr.Level()++; curr_tr.Chi2() = tripF->Param().Chi2(); FTSCATrack best_tr = curr_tr; unsigned int nCalls = 0; FindBestCandidate(istaF, best_tr, iTrip, curr_tr, min_best_l, triplets, nCalls ); if ( best_tr.Level() < min_best_l ) continue; if ( best_tr.NHits() < PndFTSCAParameters::MinimumHitsForRecoTrack ) continue; // if ( best_tr.Fit( *tracks.HitsRef(), fTarget, GetParameters(), tripF->QMomentum() ).QPt() > 0.5*fMaxInvMom ) continue; // fit to determine Chi2 and NDF vtrackcandidate.push_back(best_tr); // best_tr.SetHitsAsUsed(*tracks.HitsRef()); TODO // tracks.push_back(best_tr); } } // istaF // select and save best candidates vtrackcandidate.SelectAndSaveTracks( tracks ); } // ilev } void PndFTSCAGBTracker::FindBestCandidate( int ista, FTSCATrack &bT, // best track int currITrip, // index of current triplet FTSCATrack &cT, // current track unsigned char min_best_l, const FTSCANPlets& triplets, unsigned int& nCalls) { //if (nCalls > 100) return; // avoid long processing in confusing cases nCalls++; const FTSCAElementsOnStation& trs = triplets.OnStation( ista ); const FTSCANPlet* curr_trip = &(trs[currITrip]); if (curr_trip->Level() == 0) // && nCalls>7) { // the end of the track -> check and store // -- finish with current track // if( cT.Level() < min_best_l - 1 ) return; // suppose that only one hit can be added by extender // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF // takes 20 times more time then the rest // -- select the best if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) ) bT = cT; } else { // level != 0 // try to extend. try all possible triplets int NNeighs = curr_trip->NNeighbours(); for (int in = 0; in < NNeighs; in++) { int newITrip = curr_trip->INeighbours(in); const FTSCANPlet* new_trip = &(triplets.OnStation( curr_trip->ISta(0) + StartStationShift )[newITrip]); // check new triplet bool isUsed = false; const int newTripLength = new_trip->N(); ASSERT( newTripLength - curr_trip->N() >= -1, newTripLength << " - " << curr_trip->N() ); for( int i = curr_trip->N() - 1; i < newTripLength; i++ ) { if( triplets.OnStation( new_trip->ISta(0) ).GetHit( i, newITrip ).IsUsed() ) { isUsed = true; break; } } if (isUsed) { // cT.Fit( *trs.HitsRef(), fTarget, GetParameters() ); // fit to determine Chi2 and NDF // no used hits allowed -> compare and store track if ( (cT.NDF() > bT.NDF()) || ( (cT.NDF() == bT.NDF()) && (cT.Chi2() < bT.Chi2()) ) ) bT = cT; } else { // add new triplet to the current track // restore current track // save current tracklet FTSCATrack nT = cT; // new track // add new triplet nT.Level()++; int start = curr_trip->N() - StartStationShift; if( start<0 ) start = 0; for( int i = start; i < newTripLength; i++ ) { nT.AddHit( new_trip->IHit(i) ); } const float qp1 = curr_trip->QMomentum(); const float qp2 = new_trip->QMomentum(); float dqp = fabs(qp1 - qp2); float Cqp = curr_trip->QMomentumErr(); Cqp += new_trip->QMomentumErr(); dqp = dqp/Cqp; nT.Chi2() += dqp*dqp; FindBestCandidate(new_trip->ISta(0), bT, newITrip, nT, min_best_l, triplets, nCalls); } // add triplet to track } // for neighbours } // level != 0 } void PndFTSCAGBTracker::Merge ( FTSCATracks& tracks ) { const int NTracksS = tracks.size(); vector< pair > fittedTracks; fittedTracks.reserve(NTracksS); //cout<<"NTracksS "<20. || isnan(innerParam.Err2X())) { //innerParam = t1.Fit( *tracks.HitsRef(), fTarget, GetParameters(), true, true, outerParam ); innerParam = outerParam; innerParam.SetX((*tracks.HitsRef())[t1.IHits()[0]].X1()); innerParam.SetY((*tracks.HitsRef())[t1.IHits()[0]].X2()); innerParam.SetZ((*tracks.HitsRef())[t1.IHits()[0]].X0()); innerParam.SetTX(innerParam.X()/innerParam.Z()); innerParam.SetTY(innerParam.Y()/innerParam.Z()); } if (abs(outerParam.Err2X())>20. || isnan(outerParam.Err2X())) { outerParam = innerParam; outerParam.SetX((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X1()); outerParam.SetY((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X2()); outerParam.SetZ((*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X0()); outerParam.SetTX(outerParam.X()/outerParam.Z()); outerParam.SetTY(outerParam.Y()/outerParam.Z()); } fittedTracks.push_back(pair(innerParam,outerParam)); //float X0_back = (*tracks.HitsRef())[t1.IHits()[0]].X0(); //float X0_front = (*tracks.HitsRef())[t1.IHits()[t1.NHits()-1]].X0(); //cout<<"Z_first "<20. || isnan(t_middleOuter.Err2X())) { float coefQP = 10.; int counterX = 0; while ((abs(t_middleOuter.Err2X())>20. || isnan(t_middleOuter.Err2X())) && (counterX<5)) { t_middleOuter = buf_t_middle; t_middleOuter.SetQP(buf_t_middle.QP()/coefQP); t_middleOuter.Transport( (*tracks.HitsRef())[t_end.IHits().front()], GetParameters() ); counterX+=1; coefQP/=2.; } } //cout<<"1. after transp t_endInner.X() "<=1 && xDiff1<6) deltaX1=5.0; if (xDiff1>=6 && xDiff1<10) deltaX1=7.5; if (xDiff1>=10 && xDiff1<20) deltaX1=10.0; if (xDiff1>=20 && xDiff1<30) deltaX1=11.0; if (xDiff1>=30) deltaX1=12.0; if (xDiff1>=120) deltaX1=25.0; if ((fabs(t_endInner.X()-Xt_middleOuterBuf)=0) continue; PndFTSCATrackParam t_startOuter = fittedTracks[iT_start].second; //recursiveParam=t_middleInner cout<<"t_startOuter.Z() "<-1) deltaX2=2.5; if (xDiff2<=-1 && xDiff2>-6) deltaX2=5.0; if (xDiff2<=-6 && xDiff2>-10) deltaX2=7.5; if (xDiff2<=-10 && xDiff2>-20) deltaX2=10.0; if (xDiff2<=-20 && xDiff2>-30) deltaX2=12.5; if (xDiff2<=-30) deltaX2=15.0; if ((fabs(t_endInner.X()-Xt_middleOuterBuf)>>FTS COMBINATORIAL PART!!!!@@@@@ void PndFTSCAGBTracker::EstimatePV( const FTSCAHitsV& all, float& zPV ) { //* Estimate coordinates of the primary vertex. int iS = 0; const float maxZ = GetParameters().MaxZ(); const float maxPVR = 0.1; // max distance between PV and beam line const unsigned int N = 2*maxZ/0.01; // n bins in histo vector pvHist(N,0); const FTSCAElementsOnStation& s = all.OnStation( iS ); const FTSCAElementsOnStation& s2 = all.OnStation( iS+1 ); for( unsigned int i = 0; i < s.size(); ++i ) { const FTSCAHitV &h = s[i]; foreach_bit( int iV, h.IsValid() ) { float gx, gy, gz; h.GetGlobalCoor( iV, gx, gy, gz ); PndFTSCAParameters::CALocalToGlobal(float(h.X0()[iV]), float(h.X1()[iV]), float(h.X2()[iV]), float(h.Angle()[iV]), gx, gy, gz); float r = sqrt(gx*gx+gy*gy); for( unsigned int i2 = 0; i2 < s2.size(); ++i2 ) { const FTSCAHitV &h2 = s2[i2]; foreach_bit( int iV2, h2.IsValid() ) { float gx2, gy2, gz2; h2.GetGlobalCoor( iV2, gx2, gy2, gz2 ); float r2 = sqrt(gx2*gx2+gy2*gy2); float gz0 = -(gz2-gz)/(r2-r)*r + gz; float gx0 = -(gx2-gx)/(r2-r)*r + gx; float gy0 = -(gy2-gy)/(r2-r)*r + gy; if ( abs(gz0) < maxZ && abs(gx0) < maxPVR && abs(gy0) < maxPVR ) pvHist[(gz0/maxZ+1)*N/2]++; } } } } #ifdef DRAW_CA const double *pv = PndFTSCAPerformance::Instance().PV(); // dbg PndFTSCADisplay::Instance().DrawGBHits(all); PndFTSCADisplay::Instance().DrawPVHisto( pvHist, GetParameters() ); PndFTSCADisplay::Instance().DrawGBPoint(pv[0],pv[1],pv[2],2,0.5); PndFTSCADisplay::Instance().SaveCanvasToFile( "DrawPVHisto.pdf" ); PndFTSCADisplay::Instance().Ask(); #endif float max = -1; int maxI = -1; for( unsigned int i = 0; i < pvHist.size(); ++i ) { if ( max < pvHist[i] ) { max = pvHist[i]; maxI = i; } } zPV = (2.f*maxI/N-1)*maxZ; } void PndFTSCAGBTracker::InvertCholetsky(float a[15]) const { float d[5], uud, u[5][5]; for(int i=0; i<5; i++) { d[i]=0.f; for(int j=0; j<5; j++) u[i][j]=0.; } for(int i=0; i<5; i++) { uud=0.; for(int j=0; j