CMS 3D CMS Logo

BPHKinematicFit.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author Paolo Ronchese INFN Padova
5  *
6  */
7 
8 //-----------------------
9 // This Class' Header --
10 //-----------------------
12 
13 //-------------------------------
14 // Collaborating Class Headers --
15 //-------------------------------
26 
27 //---------------
28 // C++ Headers --
29 //---------------
30 using namespace std;
31 
32 //-------------------
33 // Initializations --
34 //-------------------
35 
36 //----------------
37 // Constructors --
38 //----------------
39 BPHKinematicFit::BPHKinematicFit(int daugNum, int compNum)
40  : BPHDecayMomentum(daugNum, compNum),
41  BPHDecayVertex(nullptr),
42  massConst(-1.0),
43  massSigma(-1.0),
44  oldKPs(true),
45  oldFit(true),
46  oldMom(true),
47  kinTree(nullptr) {}
48 
50  : BPHDecayVertex(ptr, nullptr),
51  massConst(-1.0),
52  massSigma(-1.0),
53  oldKPs(true),
54  oldFit(true),
55  oldMom(true),
56  kinTree(nullptr) {
57  map<const reco::Candidate*, const reco::Candidate*> iMap;
58  const vector<const reco::Candidate*>& daug = daughters();
59  const vector<Component>& list = ptr->componentList();
60  int i;
61  int n = daug.size();
62  for (i = 0; i < n; ++i) {
63  const reco::Candidate* cand = daug[i];
64  iMap[originalReco(cand)] = cand;
65  }
66  for (i = 0; i < n; ++i) {
67  const Component& c = list[i];
68  dMSig[iMap[c.cand]] = c.msig;
69  }
70  const vector<BPHRecoConstCandPtr>& dComp = daughComp();
71  int j;
72  int m = dComp.size();
73  for (j = 0; j < m; ++j) {
74  const BPHRecoCandidate* rc = dComp[j].get();
75  const map<const reco::Candidate*, double>& dMap = rc->dMSig;
76  const map<const BPHRecoCandidate*, FlyingParticle>& cMap = rc->cKinP;
77  dMSig.insert(dMap.begin(), dMap.end());
78  cKinP.insert(cMap.begin(), cMap.end());
79  cKinP[rc];
80  }
81 }
82 
83 //--------------
84 // Operations --
85 //--------------
87 void BPHKinematicFit::setConstraint(double mass, double sigma) {
88  oldKPs = oldFit = oldMom = true;
89  massConst = mass;
90  massSigma = sigma;
91  return;
92 }
93 
95 double BPHKinematicFit::constrMass() const { return massConst; }
96 
97 double BPHKinematicFit::constrSigma() const { return massSigma; }
98 
100 void BPHKinematicFit::setIndependentFit(const string& name, bool flag, double mass, double sigma) {
101  string::size_type pos = name.find('/');
102  if (pos != string::npos) {
103  edm::LogPrint("WrongRequest") << "BPHKinematicFit::setIndependentFit: "
104  << "cascade decay specification not admitted " << name;
105  return;
106  }
107  const BPHRecoCandidate* comp = getComp(name).get();
108  if (comp == nullptr) {
109  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::setIndependentFit: " << name << " daughter not found";
110  return;
111  }
112  oldKPs = oldFit = oldMom = true;
114  fp.flag = flag;
115  fp.mass = mass;
116  fp.sigma = sigma;
117  return;
118 }
119 
121 const vector<RefCountedKinematicParticle>& BPHKinematicFit::kinParticles() const {
122  if (oldKPs)
123  buildParticles();
124  return allParticles;
125 }
126 
127 vector<RefCountedKinematicParticle> BPHKinematicFit::kinParticles(const vector<string>& names) const {
128  if (oldKPs)
129  buildParticles();
130  vector<RefCountedKinematicParticle> plist;
131  unsigned int m = allParticles.size();
132  if (m != numParticles())
133  return plist;
134  set<RefCountedKinematicParticle> pset;
135  int i;
136  int n = names.size();
137  plist.reserve(m);
138  for (i = 0; i < n; ++i) {
139  const string& pname = names[i];
140  if (pname == "*") {
141  int j = m;
142  while (j)
143  insertParticle(allParticles[--j], plist, pset);
144  break;
145  }
146  string::size_type pos = pname.find('/');
147  if (pos != string::npos)
148  getParticles(pname.substr(0, pos), pname.substr(pos + 1), plist, pset, this);
149  else
150  getParticles(pname, "", plist, pset, this);
151  }
152  return plist;
153 }
154 
157  if (oldFit)
158  return kinematicTree("", massConst, massSigma);
159  return kinTree;
160 }
161 
162 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name, double mass, double sigma) const {
163  if (mass < 0)
164  return kinematicTree(name);
165  if (sigma < 0)
166  return kinematicTree(name, mass);
167  ParticleMass mc = mass;
168  MassKinematicConstraint kinConst(mc, sigma);
169  return kinematicTree(name, &kinConst);
170 }
171 
172 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name, double mass) const {
173  if (mass < 0)
174  return kinematicTree(name);
175  vector<RefCountedKinematicParticle> kPart;
176  const BPHKinematicFit* ptr = splitKP(name, &kPart);
177  if (ptr == nullptr) {
178  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
179  return kinTree;
180  }
181  int nn = ptr->daughFull().size();
182  ParticleMass mc = mass;
183  if (nn == 2) {
185  return kinematicTree(kPart, &kinConst);
186  } else {
188  return kinematicTree(kPart, &kinConst);
189  }
190 }
191 
192 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name) const {
193  KinematicConstraint* kc = nullptr;
194  return kinematicTree(name, kc);
195 }
196 
198  vector<RefCountedKinematicParticle> kComp;
199  vector<RefCountedKinematicParticle> kTail;
200  const BPHKinematicFit* ptr = splitKP(name, &kComp, &kTail);
201  if (ptr == nullptr) {
202  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
203  return kinTree;
204  }
205  try {
207  RefCountedKinematicTree compTree = vtxFitter.fit(kComp);
208  if (compTree->isEmpty())
209  return kinTree;
210  if (kc != nullptr) {
211  KinematicParticleFitter kinFitter;
212  compTree = kinFitter.fit(kc, compTree);
213  if (compTree->isEmpty())
214  return kinTree;
215  }
216  compTree->movePointerToTheTop();
217  if (!kTail.empty()) {
218  RefCountedKinematicParticle compPart = compTree->currentParticle();
219  if (!compPart->currentState().isValid())
220  return kinTree;
221  kTail.push_back(compPart);
222  kinTree = vtxFitter.fit(kTail);
223  } else {
224  kinTree = compTree;
225  }
226  } catch (std::exception const&) {
227  edm::LogPrint("FitFailed") << "BPHKinematicFit::kinematicTree: "
228  << "kin fit reset";
229  kinTree = RefCountedKinematicTree(nullptr);
230  }
231  return kinTree;
232 }
233 
235  MultiTrackKinematicConstraint* kc) const {
236  vector<RefCountedKinematicParticle> kPart;
237  if (splitKP(name, &kPart) == nullptr) {
238  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
239  return kinTree;
240  }
241  return kinematicTree(kPart, kc);
242 }
243 
246  oldKPs = oldFit = oldMom = true;
247  return;
248 }
249 
252  kinematicTree();
253  if (kinTree.get() == nullptr)
254  return true;
255  return kinTree->isEmpty();
256 }
257 
260  if (kPart.get() == nullptr)
261  return false;
262  return kPart->currentState().isValid();
263 }
264 
267  if (isEmpty())
268  return RefCountedKinematicParticle(nullptr);
269  return kinTree->currentParticle();
270 }
271 
273  if (isEmpty())
274  return RefCountedKinematicVertex(nullptr);
275  return kinTree->currentDecayVertex();
276 }
277 
280  if (isEmpty())
281  return RefCountedKinematicParticle(nullptr);
282  return kinTree->topParticle();
283 }
284 
286  if (isEmpty())
287  return RefCountedKinematicVertex(nullptr);
288  kinTree->movePointerToTheTop();
289  return kinTree->currentDecayVertex();
290 }
291 
294  if (kPart.get() == nullptr)
295  return -1.0;
296  const KinematicState kStat = kPart->currentState();
297  if (kStat.isValid())
298  return kStat.mass();
299  return -1.0;
300 }
301 
304  if (oldMom)
305  fitMomentum();
306  return totalMomentum;
307 }
308 
311  map<const reco::Candidate*, double>::const_iterator iter = dMSig.find(cand);
312  return (iter != dMSig.end() ? iter->second : -1);
313 }
314 
316 bool BPHKinematicFit::getIndependentFit(const string& name, double& mass, double& sigma) const {
317  const BPHRecoCandidate* comp = getComp(name).get();
318  map<const BPHRecoCandidate*, FlyingParticle>::const_iterator iter = cKinP.find(comp);
319  if ((iter != cKinP.end()) && iter->second.flag) {
320  mass = iter->second.mass;
321  sigma = iter->second.sigma;
322  return true;
323  }
324  return false;
325 }
326 
329 void BPHKinematicFit::addK(const string& name, const reco::Candidate* daug, double mass, double sigma) {
330  addK(name, daug, "cfhpmig", mass, sigma);
331  return;
332 }
333 
336  const string& name, const reco::Candidate* daug, const string& searchList, double mass, double sigma) {
337  addV(name, daug, searchList, mass);
338  dMSig[daughters().back()] = sigma;
339  return;
340 }
341 
343 void BPHKinematicFit::addK(const string& name, const BPHRecoConstCandPtr& comp) {
344  addV(name, comp);
345  const map<const reco::Candidate*, double>& dMap = comp->dMSig;
346  const map<const BPHRecoCandidate*, FlyingParticle>& cMap = comp->cKinP;
347  dMSig.insert(dMap.begin(), dMap.end());
348  cKinP.insert(cMap.begin(), cMap.end());
349  cKinP[comp.get()];
350  return;
351 }
352 
353 // utility function used to cash reconstruction results
357  return;
358 }
359 
360 // build kin particles, perform the fit and compute the total momentum
362  kinMap.clear();
363  kCDMap.clear();
364  allParticles.clear();
365  allParticles.reserve(daughFull().size());
367  oldKPs = false;
368  return;
369 }
370 
371 void BPHKinematicFit::addParticles(vector<RefCountedKinematicParticle>& kl,
372  map<const reco::Candidate*, RefCountedKinematicParticle>& km,
373  map<const BPHRecoCandidate*, RefCountedKinematicParticle>& cm) const {
374  const vector<const reco::Candidate*>& daug = daughters();
376  int n = daug.size();
377  float chi = 0.0;
378  float ndf = 0.0;
379  while (n--) {
380  const reco::Candidate* cand = daug[n];
381  ParticleMass mass = cand->mass();
382  float sigma = dMSig.find(cand)->second;
383  if (sigma < 0)
384  sigma = 1.0e-7;
386  if (tt != nullptr)
387  kl.push_back(km[cand] = pFactory.particle(*tt, mass, chi, ndf, sigma));
388  }
389  const vector<BPHRecoConstCandPtr>& comp = daughComp();
390  int m = comp.size();
391  while (m--) {
392  const BPHRecoCandidate* cptr = comp[m].get();
393  const FlyingParticle& fp = cKinP.at(cptr);
394  if (fp.flag) {
395  BPHRecoCandidate* tptr = cptr->clone();
396  double mass = fp.mass;
397  double sigma = fp.sigma;
398  if (mass > 0.0)
399  tptr->setConstraint(mass, sigma);
400  tmpList.push_back(BPHRecoConstCandPtr(tptr));
401  if (tptr->isEmpty())
402  return;
403  if (!tptr->isValidFit())
404  return;
405  kl.push_back(cm[cptr] = tptr->topParticle());
406  } else {
407  cptr->addParticles(kl, km, cm);
408  }
409  }
410  return;
411 }
412 
413 void BPHKinematicFit::getParticles(const string& moth,
414  const string& daug,
415  vector<RefCountedKinematicParticle>& kl,
416  set<RefCountedKinematicParticle>& ks,
417  const BPHKinematicFit* curr) const {
418  const BPHRecoCandidate* cptr = getComp(moth).get();
419  if (cptr != nullptr) {
420  if (curr->cKinP.at(cptr).flag) {
421  insertParticle(kCDMap[cptr], kl, ks);
422  } else {
423  vector<string> list;
424  if (!daug.empty()) {
425  list.push_back(daug);
426  } else {
427  const vector<string>& dNames = cptr->daugNames();
428  const vector<string>& cNames = cptr->compNames();
429  list.insert(list.end(), dNames.begin(), dNames.end());
430  list.insert(list.end(), cNames.begin(), cNames.end());
431  }
432  getParticles(moth, list, kl, ks, cptr);
433  }
434  return;
435  }
436  const reco::Candidate* dptr = getDaug(moth);
437  if (dptr != nullptr) {
438  insertParticle(kinMap[dptr], kl, ks);
439  return;
440  }
441  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::getParticles: " << moth << " not found";
442  return;
443 }
444 
445 void BPHKinematicFit::getParticles(const string& moth,
446  const vector<string>& daug,
447  vector<RefCountedKinematicParticle>& kl,
448  set<RefCountedKinematicParticle>& ks,
449  const BPHKinematicFit* curr) const {
450  int i;
451  int n = daug.size();
452  for (i = 0; i < n; ++i) {
453  const string& name = daug[i];
454  string::size_type pos = name.find('/');
455  if (pos != string::npos)
456  getParticles(moth + "/" + name.substr(0, pos), name.substr(pos + 1), kl, ks, curr);
457  else
458  getParticles(moth + "/" + name, "", kl, ks, curr);
459  }
460  return;
461 }
462 
464  if (cand == nullptr)
465  cand = this;
466  unsigned int n = cand->daughters().size();
467  const vector<string>& cnames = cand->compNames();
468  int i = cnames.size();
469  while (i) {
470  const BPHRecoCandidate* comp = cand->getComp(cnames[--i]).get();
471  if (cand->cKinP.at(comp).flag)
472  ++n;
473  else
474  n += numParticles(comp);
475  }
476  return n;
477 }
478 
480  vector<RefCountedKinematicParticle>& kl,
481  set<RefCountedKinematicParticle>& ks) {
482  if (ks.find(kp) != ks.end())
483  return;
484  kl.push_back(kp);
485  ks.insert(kp);
486  return;
487 }
488 
490  vector<RefCountedKinematicParticle>* kComp,
491  vector<RefCountedKinematicParticle>* kTail) const {
492  kinTree = RefCountedKinematicTree(nullptr);
493  oldFit = false;
494  kinParticles();
495  if (allParticles.size() != numParticles())
496  return nullptr;
497  kComp->clear();
498  if (kTail == nullptr)
499  kTail = kComp;
500  else
501  kTail->clear();
502  if (name.empty()) {
503  *kComp = allParticles;
504  return this;
505  }
506  const BPHRecoCandidate* comp = getComp(name).get();
507  int ns;
508  if (comp != nullptr) {
509  ns = (cKinP.at(comp).flag ? 1 : numParticles(comp));
510  } else {
511  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::splitKP: " << name << " daughter not found";
512  *kTail = allParticles;
513  return nullptr;
514  }
515  vector<string> nfull(2);
516  nfull[0] = name;
517  nfull[1] = "*";
518  vector<RefCountedKinematicParticle> kPart = kinParticles(nfull);
519  vector<RefCountedKinematicParticle>::const_iterator iter = kPart.begin();
520  vector<RefCountedKinematicParticle>::const_iterator imid = iter + ns;
521  vector<RefCountedKinematicParticle>::const_iterator iend = kPart.end();
522  kComp->insert(kComp->end(), iter, imid);
523  kTail->insert(kTail->end(), imid, iend);
524  return comp;
525 }
526 
527 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const vector<RefCountedKinematicParticle>& kPart,
528  MultiTrackKinematicConstraint* kc) const {
529  try {
531  kinTree = cvf.fit(kPart, kc);
532  } catch (std::exception const&) {
533  edm::LogPrint("FitFailed") << "BPHKinematicFit::kinematicTree: "
534  << "kin fit reset";
535  kinTree = RefCountedKinematicTree(nullptr);
536  }
537  return kinTree;
538 }
539 
541  if (isValidFit()) {
542  const KinematicState& ks = topParticle()->currentState();
543  GlobalVector tm = ks.globalMomentum();
544  double x = tm.x();
545  double y = tm.y();
546  double z = tm.z();
547  double m = ks.mass();
548  double e = sqrt((x * x) + (y * y) + (z * z) + (m * m));
549  totalMomentum.SetPxPyPzE(x, y, z, e);
550  } else {
551  edm::LogPrint("FitNotFound") << "BPHKinematicFit::fitMomentum: "
552  << "simple momentum sum computed";
554  const vector<const reco::Candidate*>& daug = daughters();
555  int n = daug.size();
556  while (n--)
557  tm += daug[n]->p4();
558  const vector<BPHRecoConstCandPtr>& comp = daughComp();
559  int m = comp.size();
560  while (m--)
561  tm += comp[m]->p4();
562  totalMomentum = tm;
563  }
564  oldMom = false;
565  return;
566 }
size
Write out results.
virtual const reco::Candidate * originalReco(const reco::Candidate *daug) const
get the original particle from the clone
virtual const RefCountedKinematicParticle topParticle() const
get top particle
RefCountedKinematicTree fit(const std::vector< RefCountedKinematicParticle > &part)
virtual const RefCountedKinematicTree & kinematicTree() const
perform the kinematic fit and get the result
virtual const BPHKinematicFit * splitKP(const std::string &name, std::vector< RefCountedKinematicParticle > *kComp, std::vector< RefCountedKinematicParticle > *kTail=nullptr) const
virtual void fitMomentum() const
virtual void addK(const std::string &name, const reco::Candidate *daug, double mass=-1.0, double sigma=-1.0)
virtual BPHRecoCandidate * clone(int level=-1) const
RefCountedKinematicTree fit(const std::vector< RefCountedKinematicParticle > &particles) const
BPHGenericPtr< const BPHRecoCandidate >::type BPHRecoConstCandPtr
std::map< const BPHRecoCandidate *, RefCountedKinematicParticle > kCDMap
T z() const
Definition: PV3DBase.h:61
virtual unsigned int numParticles(const BPHKinematicFit *cand=nullptr) const
bool getIndependentFit(const std::string &name, double &mass, double &sigma) const
retrieve independent fit flag
virtual void addParticles(std::vector< RefCountedKinematicParticle > &kl, std::map< const reco::Candidate *, RefCountedKinematicParticle > &km, std::map< const BPHRecoCandidate *, RefCountedKinematicParticle > &cm) const
double ParticleMass
Definition: ParticleMass.h:4
virtual const RefCountedKinematicVertex topDecayVertex() const
reco::TransientTrack * getTransientTrack(const reco::Candidate *cand) const
get TransientTrack for a daughter
const std::vector< Component > & componentList() const
std::map< std::string, const reco::Candidate * > dMap
virtual const std::vector< RefCountedKinematicParticle > & kinParticles() const
get kinematic particles
uint16_t size_type
const std::string names[nVars_]
BPHKinematicFit(const BPHKinematicFit &x)=delete
virtual const std::vector< const reco::Candidate * > & daughFull() const
std::vector< BPHRecoConstCandPtr > tmpList
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
std::map< const reco::Candidate *, RefCountedKinematicParticle > kinMap
void setNotUpdated() const override
void setIndependentFit(const std::string &name, bool flag=true, double mass=-1.0, double sigma=-1.0)
set a decaying daughter as an unique particle fitted independently
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
virtual const reco::Candidate * getDaug(const std::string &name) const
std::map< const reco::Candidate *, double > dMSig
virtual const RefCountedKinematicVertex currentDecayVertex() const
virtual void addV(const std::string &name, const reco::Candidate *daug, const std::string &searchList, double mass)
T sqrt(T t)
Definition: SSEVec.h:19
GlobalVector globalMomentum() const
static void insertParticle(RefCountedKinematicParticle &kp, std::vector< RefCountedKinematicParticle > &kl, std::set< RefCountedKinematicParticle > &ks)
RefCountedKinematicParticle particle(const reco::TransientTrack &initialTrack, const ParticleMass &massGuess, float chiSquared, float degreesOfFr, float &m_sigma) const
Log< level::Warning, true > LogPrint
virtual void resetKinematicFit() const
reset the kinematic fit
virtual const std::vector< std::string > & compNames() const
ReferenceCountingPointer< KinematicVertex > RefCountedKinematicVertex
ReferenceCountingPointer< KinematicTree > RefCountedKinematicTree
virtual BPHRecoConstCandPtr getComp(const std::string &name) const
virtual bool isValidFit() const
std::vector< RefCountedKinematicParticle > allParticles
virtual const std::vector< BPHRecoConstCandPtr > & daughComp() const
RefCountedKinematicTree kinTree
std::map< const BPHRecoCandidate *, FlyingParticle > cKinP
std::vector< RefCountedKinematicTree > fit(KinematicConstraint *cs, const std::vector< RefCountedKinematicTree > &trees) const
virtual const std::vector< std::string > & daugNames() const
virtual const RefCountedKinematicParticle currentParticle() const
get current particle
ReferenceCountingPointer< KinematicParticle > RefCountedKinematicParticle
virtual bool isEmpty() const
get fit status
double constrMass() const
retrieve the constraint
virtual const math::XYZTLorentzVector & p4() const
compute total momentum after the fit
void setNotUpdated() const override
ParticleMass mass() const
virtual void buildParticles() const
virtual const std::vector< const reco::Candidate * > & daughters() const
void setConstraint(double mass, double sigma)
apply a mass constraint
math::XYZTLorentzVector totalMomentum
double getMassSigma(const reco::Candidate *cand) const
retrieve particle mass sigma
virtual ParticleMass mass() const
std::map< std::string, BPHRecoConstCandPtr > cMap
virtual void getParticles(const std::string &moth, const std::string &daug, std::vector< RefCountedKinematicParticle > &kl, std::set< RefCountedKinematicParticle > &ks, const BPHKinematicFit *curr) const
bool isValid() const
double constrSigma() const