CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CandKinematicVertexFitter.cc
Go to the documentation of this file.
9 #include <sstream>
10 #include <iostream>
11 using namespace reco;
12 using namespace std;
13 
14 // perform the kinematic fit
15 bool CandKinematicVertexFitter::fit(const vector<RefCountedKinematicParticle> & particles) const {
16  try {
17  tree_ = fitter_.fit(particles);
18  } catch (std::exception & err) {
19  std::cerr << ">>> exception thrown by KinematicParticleVertexFitter:\n"
20  << err.what() << "\n"
21  << ">>> candidate not fitted to common vertex" << std::endl;
22  return false;
23  }
24  //check tree_ is valid here!
25  if (tree_->isValid())
26  return true;
27  else return false;
28 }
29 
30 // main method called by CandProducer sets the VertexCompositeCandidate
32  if(bField_ == 0)
34  << "B-Field was not set up CandKinematicVertexFitter.\n"
35  << "the following method must be called before fitting a candidate:\n"
36  << " CandKinematicVertexFitter:.set( const MagneticField * )" << endl;
37  vector<RefCountedKinematicParticle> particles;
38  vector<Candidate *> daughters;
39  vector<RecoCandidate::TrackType> trackTypes;
40  // fill particles with KinematicParticles and daughters with Candidates of the daughters of c
41  fill(particles, daughters, trackTypes, c);
42  assert(particles.size() == daughters.size());
43 
44  // attempt to fit the KinematicParticles, particles
45  if(fit(particles)) {
46  // after the fit, tree_ contains the KinematicTree from the fit
47  tree_->movePointerToTheTop();
48  // set the kinematic properties of the daughters from the fit
49  RefCountedKinematicVertex vertex = tree_->currentDecayVertex();
50  if(vertex->vertexIsValid()) {
51  Candidate::Point vtx(vertex->position());
52  c.setVertex(vtx);
53  vector<RefCountedKinematicParticle> treeParticles = tree_->daughterParticles();
54  vector<RefCountedKinematicParticle>::const_iterator particleIt = treeParticles.begin();
55  vector<Candidate *>::const_iterator daughterIt = daughters.begin(), daughtersEnd = daughters.end();
56  vector<RecoCandidate::TrackType>::const_iterator trackTypeIt = trackTypes.begin();
57  Candidate::LorentzVector mp4(0, 0, 0, 0);
58  for(; daughterIt != daughtersEnd; ++ particleIt, ++ daughterIt, ++trackTypeIt) {
59  Candidate & daughter = * * daughterIt;
60  GlobalVector p3 = (*particleIt)->currentState().globalMomentum();
61  double px = p3.x(), py = p3.y(), pz = p3.z(), p = p3.mag();
62  double energy;
63 
64  if(!daughter.longLived()) daughter.setVertex(vtx);
65  double scale;
66  switch(*trackTypeIt) {
68  //gsf used for electron tracks
69  energy = daughter.energy();
70  scale = energy / p;
71  px *= scale; py *= scale; pz *= scale;
72  default:
73  double mass = (*particleIt)->currentState().mass();
74  energy = sqrt(p*p + mass*mass);
75  };
76  Candidate::LorentzVector dp4(px, py, pz, energy);
77  daughter.setP4(dp4);
78  mp4 += dp4;
79  }
80  c.setP4(mp4);
81  c.setChi2AndNdof(chi2_ = vertex->chiSquared(), ndof_ = vertex->degreesOfFreedom());
82  GlobalError err = vertex->error();
83  cov_(0,0) = err.cxx();
84  cov_(0,1) = err.cyx();
85  cov_(0,2) = err.czx();
86  cov_(1,2) = err.czy();
87  cov_(1,1) = err.cyy();
88  cov_(2,2) = err.czz();
89  c.setCovariance(cov_);
90  }
91  } else {
92  c.setChi2AndNdof(chi2_ = -1, ndof_ = 0);
93  c.setCovariance(cov_ = CovarianceMatrix(ROOT::Math::SMatrixIdentity()));
94  }
95 }
96 
97 // methond to fill the properties of a CompositeCandidate's daughters
98 void CandKinematicVertexFitter::fill(vector<RefCountedKinematicParticle> & particles,
99  vector<Candidate *> & daughters,
100  vector<RecoCandidate::TrackType> & trackTypes,
101  Candidate & c) const {
102  size_t nDau = c.numberOfDaughters();
103  // loop through CompositeCandidate daughters
104  for(unsigned int j = 0; j < nDau ; ++j) {
105  Candidate * d = c.daughter(j);
106  if(d == 0) {
107  ostringstream message;
108  message << "Can't access in write mode candidate daughters. "
109  << "pdgId = " << c.pdgId() << ".\n";
110  const Candidate * d1 = c.daughter(j);
111  if(d1 == 0)
112  message << "Null daughter also found in read-only mode\n";
113  else
114  message << "Daughter found in read-only mode with id: " << d1->pdgId() << "\n";
115  throw edm::Exception(edm::errors::InvalidReference) << message.str();
116  }
117  //check for a daughter which itself is a composite
118  if(d->numberOfDaughters() > 0) {
119  //try to cast to VertexCompositeCandiate
120  VertexCompositeCandidate * vtxDau = dynamic_cast<VertexCompositeCandidate*>(d);
121  if( vtxDau!=0 && vtxDau->vertexChi2()>0 ) {
122  // if VertexCompositeCandidate refit vtxDau via the set method
123  (*this).set(*vtxDau);
124  // if mass constraint is desired, do it here
125  if ( vtxDau->massConstraint() ) {
126  KinematicParticleFitter csFitter;
127  //get particle mass from pdg table via pdgid number
128  const ParticleData *data = pdt_->particle(vtxDau->pdgId());
129  ParticleMass mass = data->mass();
130  float mass_sigma = mass*0.000001; //needs a sigma for the fit
131  // create a KinematicConstraint and refit the tree with it
132  //KinematicConstraint * mass_c = new MassKinematicConstraint(mass,mass_sigma);
133  MassKinematicConstraint mkc(mass,mass_sigma);
134  KinematicConstraint * mass_c(&mkc);
135  tree_ = csFitter.fit(mass_c,tree_);
136  //CHECK THIS! the following works, but might not be safe
137  //tree_ = csFitter.fit(&(MassKinematicConstraint(mass,mass_sigma)),tree_);
138  }
139  // add the kinematic particle from the fit to particles
140  RefCountedKinematicParticle current = (*this).currentParticle();
141  particles.push_back(current);
142  daughters.push_back(d);
143  trackTypes.push_back(RecoCandidate::noTrackType);
144  } else {
145  fill(particles, daughters, trackTypes, *d);
146  }
147  } else {
148  //get track, make KinematicParticle and add to particles so it can be fit
149  TrackRef trk = d->get<TrackRef>();
151  if (!trk.isNull()){
152  TransientTrack trTrk(trk, bField_);
153  float chi2 = 0, ndof = 0;
154  ParticleMass mass = d->mass();
155  float sigma = mass *1.e-6;
156  particles.push_back(factory_.particle(trTrk, mass, chi2, ndof, sigma));
157  daughters.push_back(d);
158  trackTypes.push_back(type);
159  } else {
160  cerr << ">>> warning: candidate of type " << d->pdgId()
161  << " has no track reference." << endl;
162  }
163  }
164  }
165 }
type
Definition: HCALResponse.h:21
virtual double energy() const =0
energy
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
string fill
Definition: lumiContext.py:319
virtual void setP4(const LorentzVector &p4)=0
set 4-momentum
TrackType
track type
Definition: RecoCandidate.h:57
virtual double mass() const =0
mass
assert(m_qm.get())
double ParticleMass
Definition: ParticleMass.h:5
T y() const
Definition: PV3DBase.h:63
math::Error< 5 >::type CovarianceMatrix
std::vector< RefCountedKinematicTree > fit(KinematicConstraint *cs, const std::vector< RefCountedKinematicTree > &trees) const
tuple d
Definition: ztail.py:151
virtual size_type numberOfDaughters() const =0
number of daughters
bool fit(const std::vector< RefCountedKinematicParticle > &tracks) const
void setChi2AndNdof(double chi2, double ndof)
set chi2 and ndof
T mag() const
Definition: PV3DBase.h:67
virtual double vertexChi2() const
chi-squares
T sqrt(T t)
Definition: SSEVec.h:18
virtual void setVertex(const Point &vertex)=0
set vertex
T z() const
Definition: PV3DBase.h:64
void setCovariance(const CovarianceMatrix &m)
set covariance matrix
int j
Definition: DBlmapReader.cc:9
HepPDT::ParticleData ParticleData
virtual void setVertex(const Point &vertex)
set vertex
bool isNull() const
Checks for null.
Definition: Ref.h:249
virtual int pdgId() const =0
PDG identifier.
virtual void setP4(const LorentzVector &p4) final
set 4-momentum
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
void fill(std::vector< RefCountedKinematicParticle > &, std::vector< reco::Candidate * > &, std::vector< reco::RecoCandidate::TrackType > &, reco::Candidate &) const
virtual int pdgId() const final
PDG identifier.
void set(const MagneticField *bField)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
T get() const
get a component
Definition: Candidate.h:217
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
virtual bool longLived() const =0
is long lived?
virtual bool massConstraint() const final
do mass constraint?
T x() const
Definition: PV3DBase.h:62
double p3[4]
Definition: TauolaWrapper.h:91