FairRoot/PandaRoot
RecoTrack.cxx
Go to the documentation of this file.
1 // ******************************************************
2 // DecayTreeFitter Package
3 // We thank the original author Wouter Hulsbergen
4 // (BaBar, LHCb) for providing the sources.
5 // http://arxiv.org/abs/physics/0503191v1 (2005)
6 // Adaptation & Development for PANDA: Ralf Kliemt (2015)
7 // ******************************************************
8 #include <stdio.h>
9 
10 //#include "Event/Particle.h"
11 #include "RecoTrack.h"
12 #include "FitParams.h"
13 //#include "TrackKernel/TrackTraj.h"
14 //#include "TrackInterfaces/ITrackStateProvider.h"
15 #include "TVector3.h"
16 #include <assert.h>
17 #include <cmath>
18 #include "LineTool.h"
19 #include "RhoCalculationTools.h"
20 
21 
22 //[R.Kliemt, Dec.2014]
23 // TODO: How do we want to treat Bremsstrahlung? Certainly not inside the Fitter!
24 //namespace {
25 // void applyBremCorrection( RhoCandidate state,
26 // double bremEnergy,
27 // double bremEnergyCov )
28 // {
29 // double momentum = state.P();
30 // double momentumCov = state.covariance()(4,4) * std::pow(momentum,4) ;
31 // momentum += bremEnergy ;
32 // momentumCov += bremEnergyCov ;
33 // state.SetMomentum( momentum ) ;
34 // state.covariance()(4,4) = momentumCov / std::pow(momentum,4) ;
35 // }
36 //}
37 
38 using namespace DecayTreeFitter;
39 
41 
42 extern int vtxverbose ;
43 
45  const ParticleBase* aMother,
46  const Configuration& config)
47 : RecoParticle(cand,aMother),
48 // m_track(cand.proto()->track()),
49 m_candidate(cand),
50 m_stateprovider( config.stateProvider() ),
51 m_useTrackTraj( config.useTrackTraj() ),
52 // m_tracktraj(0),
53 m_cached(false),
54 m_flt(0)
55 // m_bremEnergy(0),
56 // m_bremEnergyCov(0)
57 {
58  //set it to something such that we have a momentum estimate
59  //m_state = m_track->firstState() ;
60  m_stateprovider->state( m_state,const_cast<RhoCandidate*>(m_candidate));
61  // get the bremenergy correction
62  //[R.Kliemt, Dec.2014]
63  // TODO: How do we want to treat Bremsstrahlung? Certainly not inside the Fitter!
64  // if( particle().particleID().abspid() == 11 ) {
65  // // FIXME: this is a hack. it will go wrong if you fit the
66  // // updated decay tree twice. to do this properly we need to use
67  // // the bremadding tools, but there are other problems with that.
68  // double momentumFromTrack = 1/std::abs(m_state.qOverP() ) ;
69  // double momentumError2FromTrack = m_state.covariance()(4,4) * std::pow(momentumFromTrack,4) ;
70  // double momentumFromParticle = particle().momentum().P() ;
71  // double momentumError2FromParticle =
72  // particle().momCovMatrix()(3,3) * std::pow(particle().momentum().E()/momentumFromParticle,2) ;
73  // m_bremEnergyCov = momentumError2FromParticle - momentumError2FromTrack ;
74  // m_bremEnergy = momentumFromParticle - momentumFromTrack ;
75  // // if the correction is too small or unphysical, ignore it. the units are MeV.
76  // if( !(m_bremEnergyCov >1*Gaudi::Units::MeV*Gaudi::Units::MeV &&
77  // m_bremEnergy>1*Gaudi::Units::MeV ) )
78  // m_bremEnergy = m_bremEnergyCov = 0 ;
79  // if(vtxverbose>=1) {
80  // std::cout << "Fitting an electron. ("
81  // << momentumFromTrack << " +/- " << std::sqrt( momentumError2FromTrack ) << ") --> ("
82  // << momentumFromParticle << " +/- " << std::sqrt( momentumError2FromParticle ) << ")" << std::endl ;
83  // std::cout << "brem correction: " << m_bremEnergy << " +/- " << std::sqrt( m_bremEnergyCov ) << std::endl ;
84  // }
85  // applyBremCorrection(m_state,m_bremEnergy,m_bremEnergyCov) ;
86  // }
87 }
88 
89 ErrCode
91 {
92  if(vtxverbose>5){std::cout<<"RecoTrack::initPar2: - updcache"<<std::endl;}
93  ErrCode rc = updCache(fitparams) ;
94  const TVector3& recoP = particle()->P3() ;
95  int momindex = momIndex() ;
96  if(vtxverbose>5){std::cout<<"RecoTrack::initPar2: - write p3 to fitparams at momindex "<<momindex<<std::endl;}
97  fitparams->par(momindex+0) = recoP.x() ;
98  fitparams->par(momindex+1) = recoP.y() ;
99  fitparams->par(momindex+2) = recoP.z() ;
100  return rc ;
101 }
102 
103 ErrCode
105 {
106  // we only need a rough estimate of the covariance
107  assert(m_cached) ;
108  TMatrixD covP = particle()->P3Cov() ;
109  int momindex = momIndex() ;
110  for(int row=0; row<3; row++)
111  fitparams->cov()(momindex+row,momindex+row) = 1000*covP(row,row) ;
112  return ErrCode() ;
113 }
114 
115 //[R.Kliemt, Dec.2014]
116 //TODO We don't cache a state right now. Let's get the fitter
117 // running at all in the first place.
118 // Goal: Update the momentum direction from the real mesured track
119 // BUT in Panda most stuff will decay inside the beam pipe anyways
120 // We can't get better mesurements than the FirtstPar from tracking!
121 // Later we should ask PndAnaCalcTools to fetch a nice state, maybe employing GEANE/Runge-Kutta
122 // Since we have no State per se, we could update the FittedCand P3/P3Cov
123 ErrCode
125 {
126  //if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - TODO: fix Stateprovider with real to-Z-propagation! "<<std::endl;}
127  ErrCode rc ;
128  //m_cached = true ; // DIRTY
129  //return rc; // Somewhat dirty
130 
131  // declare some constants
132  const double ztolerance = m_stateprovider->ToleranceZ();//0.05; //*Gaudi::Units::cm ;
133  //const double ztolerance = m_stateprovider->ToleranceZ();
134  const double maxR = 0.05; //* Gaudi::Units::cm ; Beampipe radius in PANDA is 2cm
135 
136  //A don't do anything if too few of a change
137  //B try cache
138  //C ask stateprovider
139  // TODO really from Rhocand?
141  if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - ask for fitparam z at posindex+2 = "<<mother()->posIndex()+2<<std::endl;}
142  double vx = fitparams->par()(mother()->posIndex()+0) ;
143  double vy = fitparams->par()(mother()->posIndex()+1) ;
144  double vz = fitparams->par()(mother()->posIndex()+2) ;
145  double dz = vz - m_state.z() ;
146  double x = m_state.x() + dz * m_state.tx() ;
147  double y = m_state.y() + dz * m_state.ty() ;
148  double r = std::sqrt( x*x + y*y ) ;
149  if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - fitpar z="<<vz<<" current state z="<<m_state.z()<<" dz="<<dz<<" ztolerance="<<ztolerance<<std::endl;}
150  // If we stay close to the existing state, don't change anything.
151  if( std::abs( dz ) > ztolerance )
152  {
153  // first just look for the closest cached state
154  if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - find cached state"<<std::endl;}
155  const DecayTreeFitter::State& aState = closestCachedState ( vz ) ;
156  if( std::abs( aState.z() - vz ) < std::abs( dz ) )
157  {
158  if(vtxverbose>5)std::cout << "RecoTrack::updCache(): Found a closer state! " << name() << " fitpar z=" << vz << " current state z=" << m_state.z() << " better state z=" << aState.z() << std::endl ;
159  m_state = aState ;
160  dz = vz - m_state.z() ;
161  }
162  }
163 
164  if( std::abs( dz ) > ztolerance || r > maxR )
165  {
166  if(vtxverbose>5)std::cout << "RecoTrack::updCache(): calculate a new state."<< std::endl ;
167  // now that there is no cached state closeby, we'll fetch one
168  if( !m_stateprovider ) {
169  std::cerr<<"ERROR: DecayTreeFitter::RecoTrack::updCache() has no StateProvider"<<std::endl;
170  m_cached=false;
171  rc = ErrCode::badsetup;
172  return rc;
173  }
174  if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - call stateprovider"<<std::endl;}
175  m_stateprovider->state(m_state,const_cast<RhoCandidate*>(m_candidate),vx,vy,vz) ;
176  m_StateCache.push_back(m_state);
177  }
178 
179  if(vtxverbose>5){std::cout<<"RecoTrack::updCache() - done"<<std::endl;}
180  m_cached = true ;
181  return rc ;
182 }
183 // *** Version of LHCB
184 //ErrCode
185 //DecayTreeFitter::RecoTrack::updCache(const FitParams* fitparams)
186 //{
187 // ErrCode rc ;
188 // // declare some constants
189 // const double ztolerance = 1.; //*Gaudi::Units::cm ;
190 // const double maxR = 1.; //* Gaudi::Units::cm ;
191 // // The logic is a bit non-trivial. Above all, we need to make sure
192 // // we don't apply the bremcorrection more than once on an existing
193 // // state. States that we get from the track do not have brem
194 // // correction applied.
195 //
196 // // If we stay close to the existing state, don't change anything.
197 // double prevstatez = particle().z() ;
198 // double z = fitparams->par()(mother()->posIndex() + 3 ) ;
199 // double dz = z - m_state.z() ;
200 // if( std::abs( dz ) > ztolerance ) {
201 // // first just look for the closest state on the track
202 // const DecayTreeFitter::State& state = m_track->closestState ( z ) ;
203 // if( std::abs( state.z() - z ) < std::abs( dz ) ) {
204 // //std::cout << "Found a closer state! "
205 // // << name() << " " << z << " "
206 // // << m_state.z() << " " << m_state.location() << " "
207 // // << state.z() << " " << state.location() << std::endl ;
208 // m_state = state ;
209 // dz = z - m_state.z() ;
210 // }
211 //
212 // // if that didn't work, try something else
213 // if( std::abs( dz ) > ztolerance ) {
214 // // if the existing state is closest to beam, and if we stay
215 // // inside the beampipe, then don't change anything as well.
216 // double x = m_state.x() + dz * m_state.tx() ;
217 // double y = m_state.y() + dz * m_state.ty() ;
218 // double r = std::sqrt( x*x + y*y ) ;
219 // if( m_state.location() != LHCb::State::ClosestToBeam || r > maxR ) {
220 // //std::cout << "Updating state for: "
221 // // << name() << " " << z << " " << prevstatez << " " << m_state.z() << " "
222 // // << m_stateprovider << " " << m_tracktraj << std::endl ;
223 // if( m_stateprovider ) {
224 // if( !m_useTrackTraj ) {
225 // StatusCode sc = m_stateprovider->state( m_state,*m_track,z,ztolerance) ;
226 // if( !sc.isSuccess() ) rc = ErrCode::badsetup ;
227 // } else {
228 // // cache the tracktraj
229 // if( m_tracktraj==0 ) m_tracktraj = m_stateprovider->trajectory(*m_track) ;
230 // // if nothing failed, use it.
231 // if(m_tracktraj)
232 // m_state = m_stateprovider->trajectory(*m_track)->state(z) ;
233 // else rc = ErrCode::badsetup ;
234 // }
235 // } else {
236 // // create a trajectory on the fly
237 // LHCb::TrackTraj traj( *m_track ) ;
238 // m_state = traj.state( z ) ;
239 // }
240 // }
241 // }
242 //
243 // //[R.Kliemt, Dec.2014]
244 // // TODO: How do we want to treat Bremsstrahlung? Certainly not inside the Fitter!
245 // // // deal with bremstrahlung
246 // // if( m_state.z() != prevstatez && m_bremEnergyCov > 0 )
247 // // applyBremCorrection(m_state,m_bremEnergy,m_bremEnergyCov) ;
248 // // }
249 // m_cached = true ;
250 // return rc ;
251 //}
252 
255 {
256  // give the state with the best matching z coordinate, for an empty cache vector, we'll return the "current state"
257  int beststate=-1;
258  double bestdz=9999; //[cm] initially stupidly large
259  for (unsigned int i=0;i<m_StateCache.size();i++){
260  double dz=std::abs(m_StateCache[i].z() - z);
261  if(dz < bestdz)
262  {
263  bestdz=dz;
264  beststate=i;
265  }
266  }
267  if(beststate>=0) return m_StateCache[beststate];
268  else return m_state;
269 }
270 
271 
272 
273 TVectorD symdiag(const TMatrixDSym& m) {
274  TVectorD rc(m.GetNrows()) ;
275  for(int i=0; i<m.GetNrows(); i++)
276  rc(i) = std::sqrt(m(i,i)) ;
277  return rc ;
278 }
279 
280 ErrCode
282 {
283  ErrCode status ;
284  assert(m_cached) ;
285  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint()"<<std::endl;
286  (const_cast<RecoTrack*>(this))->updCache(fitparams) ;
287  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint() cache updated"<<std::endl;
288 
289  int posindex = mother()->posIndex() ;
290  TVector3 motherpos(fitparams->par()(posindex+0),
291  fitparams->par()(posindex+1),
292  fitparams->par()(posindex+2)) ;
293 
294  int momindex = momIndex() ;
295  double px = fitparams->par()(momindex+0) ;
296  double py = fitparams->par()(momindex+1) ;
297  double pz = fitparams->par()(momindex+2) ;
298  double mom2 = px*px+py*py+pz*pz ;
299  double mom = std::sqrt(mom2) ;
300  double tx = px/pz ;
301  double ty = py/pz ;
302  double qop = charge() / mom ;
303 
304  double dtxdpx = 1./pz ;
305  double dtxdpz = -tx/pz ;
306  double dtydpy = 1./pz ;
307  double dtydpz = -ty/pz ;
308 
309  double dqopdpx = - qop * px/mom2 ;
310  double dqopdpy = - qop * py/mom2 ;
311  double dqopdpz = - qop * pz/mom2 ;
312 
313  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint() residual"<<std::endl;
314  // fill the residual
315  const TVectorD& m_m = m_state.stateVector() ;
316  const TMatrixD& m_V = m_state.covariance() ;
317  double dz = m_state.z() - motherpos.z() ;
318 
319  if(vtxverbose>=5) {
320  std::cout<<"RecoTrack::projectRecoConstraint() "<<std::endl;
321  std::cout<<"----------------------"<<std::endl;
322  std::cout<<" state position: (" <<m_state.x()<<","<<m_state.y()<<","<<m_state.z()<<")"<<std::endl;
323  std::cout<<" mother pos: (" <<motherpos.x()<<","<<motherpos.y()<<","<<motherpos.z()<<")"<<std::endl;
324  std::cout<<" state tx,ty,q/p: (" <<m_state.tx()<<","<<m_state.ty()<<","<<m_state.qOverP()<<")"<<std::endl;
325  std::cout<<" fitpar tx, ty, q/p: (" <<tx<<","<<ty<<","<<qop<<")"<<std::endl;
326  std::cout<<" drift dz*(tx,ty,1): (" <<dz*tx<<","<<dz*ty<<","<<dz<<")" <<std::endl;
327  std::cout<<" fitpar mom: (" <<px<<","<<py<<","<<pz<<")"<<std::endl;
328  std::cout<<" q, mom: (" <<charge()<<","<<mom<<")"<<std::endl;
329  std::cout<<"----------------------"<<std::endl;
330  }
332  p.r(0) = m_m(0) - motherpos.x() - dz*tx ;
333  p.r(1) = m_m(1) - motherpos.y() - dz*ty ;
334  p.r(2) = m_m(2) - tx ;
335  p.r(3) = m_m(3) - ty ;
336  p.r(4) = m_m(4) - qop ;
337 
338  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint() projection"<<std::endl;
339  // compute the projection matrix
340  // derivative of position to position of mother
341  p.H(0,posindex+0) = -1 ;
342  p.H(1,posindex+1) = -1 ;
343  p.H(0,posindex+2) = tx ;
344  p.H(1,posindex+2) = ty ;
345 
346  // derivative of position to 3-momentum
347  p.H(0,momindex+0) = -dz * dtxdpx ;
348  p.H(0,momindex+2) = -dz * dtxdpz ;
349  p.H(1,momindex+1) = -dz * dtydpy ;
350  p.H(1,momindex+2) = -dz * dtydpz ;
351 
352  // derivative of slopes/qop to 3-momentum
353  p.H(2,momindex+0) = -dtxdpx ;
354  p.H(2,momindex+2) = -dtxdpz ;
355  p.H(3,momindex+1) = -dtydpy ;
356  p.H(3,momindex+2) = -dtydpz ;
357  p.H(4,momindex+0) = -dqopdpx ;
358  p.H(4,momindex+1) = -dqopdpy ;
359  p.H(4,momindex+2) = -dqopdpz ;
360 
361  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint() covariance"<<std::endl;
362  // copy the covariance matrix
363  for(int row=0; row<dimM(); row++)
364  for(int col=0; col<dimM()/*=row*/; col++)
365  p.Vfast(row,col) = m_V(row,col) ;
366 
367  if(vtxverbose>6){
368  std::cout<<"RecoTrack::projectRecoConstraint(): projection is:"<<posindex<<std::endl;
369  std::cout<<"r "; p.r().Print();
370  std::cout<<"V "; p.V().Print();
371  std::cout<<"H "; RhoCalculationTools::PrintMatrix(p.H());
372  }
373  if(vtxverbose>=5)std::cout<<"RecoTrack::projectRecoConstraint() finished"<<std::endl;
374  return status ;
375 
376 }
377 
378 // ErrCode
379 // DecayTreeFitter::RecoTrack::projectRecoConstraint(const FitParams& fitparams, Projection& p) const
380 // {
381 // ErrCode status ;
382 // assert(m_cached) ;
383 // (const_cast<RecoTrack*>(this))->updCache(fitparams) ;
384 //
385 // int posindex = mother()->posIndex() ;
386 // TVector3 motherpos(fitparams->par()(posindex+1),
387 // fitparams->par()(posindex+2),
388 // fitparams->par()(posindex+3)) ;
389 //
390 // int momindex = momIndex() ;
391 // double px = fitparams->par()(momindex+1) ;
392 // double py = fitparams->par()(momindex+2) ;
393 // double pz = fitparams->par()(momindex+3) ;motherpos.z()
394 // double mom2 = px*px+py*py+pz*pz ;
395 // double mom = std::sqrt(mom2) ;
396 // double tx = px/pz ;
397 // double ty = py/pz ;
398 // double qop = charge() / mom ;
399 //
400 // double dtxdpx = 1/pz ;
401 // double dtxdpz = -tx/pz ;
402 // double dtydpy = 1/pz ;
403 // double dtydpz = -ty/pz ;
404 //
405 // double dqopdpx = - qop * px/mom2 ;
406 // double dqopdpy = - qop * py/mom2 ;
407 // double dqopdpz = - qop * pz/mom2 ;
408 //
409 // // fill the residual
410 // double dz = m_state.z() - motherpos.z() ;
411 // const Gaudi::Vector5& m_m = m_state.stateVector() ;
412 // const Gaudi::SymMatrix5x5& m_V = m_state.covariance() ;
413 // p.r(0) = m_m(0) - motherpos.x() - dz*tx ;
414 // p.r(1) = m_m(1) - motherpos.y() - dz*ty ;
415 // p.r(2) = m_m(2) - tx ;
416 // p.r(3) = m_m(3) - ty ;
417 // p.r(4) = m_m(4) - qop ;
418 //
419 // // compute the projection matrix
420 // // derivative of position to position of mother
421 // p.H(0,posindex+0) = -1 ;
422 // p.H(1,posindex+1) = -1 ;
423 // p.H(0,posindex+2) = tx ;
424 // p.H(1,posindex+2) = ty ;
425 //
426 // // derivative of position to 3-momentum
427 // p.H(0,momindex+0) = -dz * dtxdpx ;
428 // p.H(0,momindex+2) = -dz * dtxdpz ;
429 // p.H(1,momindex+1) = -dz * dtydpy ;
430 // p.H(1,momindex+2) = -dz * dtydpz ;
431 //
432 // // derivative of slopes/qop to 3-momentum
433 // p.H(2,momindex+0) = -dtxdpx ;
434 // p.H(2,momindex+2) = -dtxdpz ;
435 // p.H(3,momindex+1) = -dtydpy ;
436 // p.H(3,momindex+2) = -dtydpz ;
437 // p.H(4,momindex+0) = -dqopdpx ;
438 // p.H(4,momindex+1) = -dqopdpy ;
439 // p.H(4,momindex+2) = -dqopdpz ;
440 //
441 // // copy the covariance matrix
442 // for(int row=0; row<5; row++)
443 // for(int col=0; col<5/*=row*/; col++)
444 // p.Vfast(row,col) = m_V(row,col) ;
445 //
446 // return status ;
447 // }
int row
Definition: anaLmdDigi.C:67
Double_t p
Definition: anasim.C:58
const TVectorD & r() const
Definition: Projection.h:37
double r
Definition: RiemannTest.C:14
const RhoCandidate * m_candidate
Definition: RecoTrack.h:60
Int_t i
Definition: run_full.C:25
__m128 m
Definition: P4_F32vec4.h:28
ErrCode updCache(const FitParams *fitparams)
Definition: RecoTrack.cxx:124
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
RecoTrack(RhoCandidate *bc, const ParticleBase *mother, const Configuration &config)
Definition: RecoTrack.cxx:44
int col
Definition: anaLmdDigi.C:67
virtual ErrCode projectRecoConstraint(const FitParams *, Projection &) const
Definition: RecoTrack.cxx:281
Double_t mom
Definition: plot_dirc.C:14
double z() const
Definition: State.h:86
const TMatrixD & H() const
Definition: Projection.h:28
TVectorD symdiag(const TMatrixDSym &m)
Definition: RecoTrack.cxx:273
const DecayTreeFitter::State & closestCachedState(double z)
Definition: RecoTrack.cxx:254
const int particle
const TMatrixDSym & V() const
Definition: Projection.h:47
DecayTreeFitter::State m_state
Definition: RecoTrack.h:67
int vtxverbose
static void PrintMatrix(TMatrixT< double > m)
virtual ErrCode initPar2(FitParams *)
Definition: RecoTrack.cxx:90
Double_t z
TString name
Double_t x
ClassImp(PndAnaContFact)
virtual ErrCode initCov(FitParams *)
Definition: RecoTrack.cxx:104
Double_t y
void state(DecayTreeFitter::State &aState, RhoCandidate *track) const
TMatrixT< double > TMatrixD
Definition: PndLmdDim.h:52
double pz[39]
Definition: pipisigmas.h:14
TMatrixDSym & cov()
Definition: FitParams.h:34
int status[10]
Definition: f_Init.h:28
const RecoTrackStateProvider * m_stateprovider
Definition: RecoTrack.h:62
double & Vfast(int row, int col)
Definition: Projection.h:50