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 //----------------
40  : BPHDecayVertex(nullptr),
41  massConst(-1.0),
42  massSigma(-1.0),
43  oldKPs(true),
44  oldFit(true),
45  oldMom(true),
46  kinTree(nullptr) {}
47 
49  : BPHDecayVertex(ptr, nullptr),
50  massConst(-1.0),
51  massSigma(-1.0),
52  oldKPs(true),
53  oldFit(true),
54  oldMom(true),
55  kinTree(nullptr) {
56  map<const reco::Candidate*, const reco::Candidate*> iMap;
57  const vector<const reco::Candidate*>& daug = daughters();
58  const vector<Component>& list = ptr->componentList();
59  int i;
60  int n = daug.size();
61  for (i = 0; i < n; ++i) {
62  const reco::Candidate* cand = daug[i];
63  iMap[originalReco(cand)] = cand;
64  }
65  for (i = 0; i < n; ++i) {
66  const Component& c = list[i];
67  dMSig[iMap[c.cand]] = c.msig;
68  }
69  const vector<BPHRecoConstCandPtr>& dComp = daughComp();
70  int j;
71  int m = dComp.size();
72  for (j = 0; j < m; ++j) {
73  const BPHRecoCandidate* rc = dComp[j].get();
74  const map<const reco::Candidate*, double>& dMap = rc->dMSig;
75  const map<const BPHRecoCandidate*, FlyingParticle>& cMap = rc->cKinP;
76  dMSig.insert(dMap.begin(), dMap.end());
77  cKinP.insert(cMap.begin(), cMap.end());
78  cKinP[rc];
79  }
80 }
81 
82 //--------------
83 // Destructor --
84 //--------------
86 
87 //--------------
88 // Operations --
89 //--------------
91 void BPHKinematicFit::setConstraint(double mass, double sigma) {
92  oldKPs = oldFit = oldMom = true;
93  massConst = mass;
94  massSigma = sigma;
95  return;
96 }
97 
99 double BPHKinematicFit::constrMass() const { return massConst; }
100 
101 double BPHKinematicFit::constrSigma() const { return massSigma; }
102 
104 void BPHKinematicFit::setIndependentFit(const string& name, bool flag, double mass, double sigma) {
105  string::size_type pos = name.find('/');
106  if (pos != string::npos) {
107  edm::LogPrint("WrongRequest") << "BPHKinematicFit::setIndependentFit: "
108  << "cascade decay specification not admitted " << name;
109  return;
110  }
111  const BPHRecoCandidate* comp = getComp(name).get();
112  if (comp == nullptr) {
113  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::setIndependentFit: " << name << " daughter not found";
114  return;
115  }
116  oldKPs = oldFit = oldMom = true;
118  fp.flag = flag;
119  fp.mass = mass;
120  fp.sigma = sigma;
121  return;
122 }
123 
125 const vector<RefCountedKinematicParticle>& BPHKinematicFit::kinParticles() const {
126  if (oldKPs)
127  buildParticles();
128  return allParticles;
129 }
130 
131 vector<RefCountedKinematicParticle> BPHKinematicFit::kinParticles(const vector<string>& names) const {
132  if (oldKPs)
133  buildParticles();
134  vector<RefCountedKinematicParticle> plist;
135  unsigned int m = allParticles.size();
136  if (m != numParticles())
137  return plist;
138  set<RefCountedKinematicParticle> pset;
139  int i;
140  int n = names.size();
141  plist.reserve(m);
142  for (i = 0; i < n; ++i) {
143  const string& pname = names[i];
144  if (pname == "*") {
145  int j = m;
146  while (j)
147  insertParticle(allParticles[--j], plist, pset);
148  break;
149  }
150  string::size_type pos = pname.find('/');
151  if (pos != string::npos)
152  getParticles(pname.substr(0, pos), pname.substr(pos + 1), plist, pset);
153  else
154  getParticles(pname, "", plist, pset);
155  }
156  return plist;
157 }
158 
161  if (oldFit)
162  return kinematicTree("", massConst, massSigma);
163  return kinTree;
164 }
165 
166 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name, double mass, double sigma) const {
167  if (mass < 0)
168  return kinematicTree(name);
169  if (sigma < 0)
170  return kinematicTree(name, mass);
171  ParticleMass mc = mass;
172  MassKinematicConstraint kinConst(mc, sigma);
173  return kinematicTree(name, &kinConst);
174 }
175 
176 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name, double mass) const {
177  if (mass < 0)
178  return kinematicTree(name);
179  vector<RefCountedKinematicParticle> kPart;
180  const BPHKinematicFit* ptr = splitKP(name, &kPart);
181  if (ptr == nullptr) {
182  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
183  return kinTree;
184  }
185 
186  int nn = ptr->daughFull().size();
187  ParticleMass mc = mass;
188  if (nn == 2) {
190  return kinematicTree(kPart, &kinConst);
191  } else {
193  return kinematicTree(kPart, &kinConst);
194  }
195 }
196 
197 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const string& name) const {
198  KinematicConstraint* kc = nullptr;
199  return kinematicTree(name, kc);
200 }
201 
203  vector<RefCountedKinematicParticle> kComp;
204  vector<RefCountedKinematicParticle> kTail;
205  const BPHKinematicFit* ptr = splitKP(name, &kComp, &kTail);
206  if (ptr == nullptr) {
207  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
208  return kinTree;
209  }
210  try {
212  RefCountedKinematicTree compTree = vtxFitter.fit(kComp);
213  if (compTree->isEmpty())
214  return kinTree;
215  if (kc != nullptr) {
216  KinematicParticleFitter kinFitter;
217  compTree = kinFitter.fit(kc, compTree);
218  if (compTree->isEmpty())
219  return kinTree;
220  }
221  compTree->movePointerToTheTop();
222  if (!kTail.empty()) {
223  RefCountedKinematicParticle compPart = compTree->currentParticle();
224  if (!compPart->currentState().isValid())
225  return kinTree;
226  kTail.push_back(compPart);
227  kinTree = vtxFitter.fit(kTail);
228  } else {
229  kinTree = compTree;
230  }
231  } catch (std::exception const&) {
232  edm::LogPrint("FitFailed") << "BPHKinematicFit::kinematicTree: "
233  << "kin fit reset";
234  kinTree = RefCountedKinematicTree(nullptr);
235  }
236  return kinTree;
237 }
238 
240  MultiTrackKinematicConstraint* kc) const {
241  vector<RefCountedKinematicParticle> kPart;
242  if (splitKP(name, &kPart) == nullptr) {
243  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::kinematicTree: " << name << " daughter not found";
244  return kinTree;
245  }
246  return kinematicTree(kPart, kc);
247 }
248 
251  oldKPs = oldFit = oldMom = true;
252  return;
253 }
254 
257  kinematicTree();
258  if (kinTree.get() == nullptr)
259  return true;
260  return kinTree->isEmpty();
261 }
262 
265  if (kPart.get() == nullptr)
266  return false;
267  return kPart->currentState().isValid();
268 }
269 
272  if (isEmpty())
273  return RefCountedKinematicParticle(nullptr);
274  return kinTree->currentParticle();
275 }
276 
278  if (isEmpty())
279  return RefCountedKinematicVertex(nullptr);
280  return kinTree->currentDecayVertex();
281 }
282 
285  if (isEmpty())
286  return RefCountedKinematicParticle(nullptr);
287  return kinTree->topParticle();
288 }
289 
291  if (isEmpty())
292  return RefCountedKinematicVertex(nullptr);
293  kinTree->movePointerToTheTop();
294  return kinTree->currentDecayVertex();
295 }
296 
299  if (kPart.get() == nullptr)
300  return -1.0;
301  const KinematicState kStat = kPart->currentState();
302  if (kStat.isValid())
303  return kStat.mass();
304  return -1.0;
305 }
306 
309  if (oldMom)
310  fitMomentum();
311  return totalMomentum;
312 }
313 
316  map<const reco::Candidate*, double>::const_iterator iter = dMSig.find(cand);
317  return (iter != dMSig.end() ? iter->second : -1);
318 }
319 
322  const BPHRecoCandidate* comp = getComp(name).get();
323  map<const BPHRecoCandidate*, FlyingParticle>::const_iterator iter = cKinP.find(comp);
324  return (iter != cKinP.end() ? iter->second.flag : 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) && (sigma > 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) const {
417  const BPHRecoCandidate* cptr = getComp(moth).get();
418  if (cptr != nullptr) {
419  if (cKinP.at(cptr).flag) {
420  insertParticle(kCDMap[cptr], kl, ks);
421  } else {
422  vector<string> list;
423  if (!daug.empty()) {
424  list.push_back(daug);
425  } else {
426  const vector<string>& dNames = cptr->daugNames();
427  const vector<string>& cNames = cptr->compNames();
428  list.insert(list.end(), dNames.begin(), dNames.end());
429  list.insert(list.end(), cNames.begin(), cNames.end());
430  }
431  getParticles(moth, list, kl, ks);
432  }
433  return;
434  }
435  const reco::Candidate* dptr = getDaug(moth);
436  if (dptr != nullptr) {
437  insertParticle(kinMap[dptr], kl, ks);
438  return;
439  }
440  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::getParticles: " << moth << " not found";
441  return;
442 }
443 
444 void BPHKinematicFit::getParticles(const string& moth,
445  const vector<string>& daug,
446  vector<RefCountedKinematicParticle>& kl,
447  set<RefCountedKinematicParticle>& ks) const {
448  int i;
449  int n = daug.size();
450  for (i = 0; i < n; ++i) {
451  const string& name = daug[i];
452  string::size_type pos = name.find('/');
453  if (pos != string::npos)
454  getParticles(moth + "/" + name.substr(0, pos), name.substr(pos + 1), kl, ks);
455  else
456  getParticles(moth + "/" + name, "", kl, ks);
457  }
458  return;
459 }
460 
462  if (cand == nullptr)
463  cand = this;
464  unsigned int n = cand->daughters().size();
465  const vector<string>& cnames = cand->compNames();
466  int i = cnames.size();
467  while (i) {
468  const BPHRecoCandidate* comp = cand->getComp(cnames[--i]).get();
469  if (cKinP.at(comp).flag)
470  ++n;
471  else
472  n += numParticles(comp);
473  }
474  return n;
475 }
476 
478  vector<RefCountedKinematicParticle>& kl,
479  set<RefCountedKinematicParticle>& ks) {
480  if (ks.find(kp) != ks.end())
481  return;
482  kl.push_back(kp);
483  ks.insert(kp);
484  return;
485 }
486 
488  vector<RefCountedKinematicParticle>* kComp,
489  vector<RefCountedKinematicParticle>* kTail) const {
490  kinTree = RefCountedKinematicTree(nullptr);
491  oldFit = false;
492  kinParticles();
493  if (allParticles.size() != numParticles())
494  return nullptr;
495  kComp->clear();
496  if (kTail == nullptr)
497  kTail = kComp;
498  else
499  kTail->clear();
500  if (name.empty()) {
501  *kComp = allParticles;
502  return this;
503  }
504  const BPHRecoCandidate* comp = getComp(name).get();
505  int ns;
506  if (comp != nullptr) {
507  ns = (cKinP.at(comp).flag ? 1 : numParticles(comp));
508  } else {
509  edm::LogPrint("ParticleNotFound") << "BPHKinematicFit::splitKP: " << name << " daughter not found";
510  *kTail = allParticles;
511  return nullptr;
512  }
513  vector<string> nfull(2);
514  nfull[0] = name;
515  nfull[1] = "*";
516  vector<RefCountedKinematicParticle> kPart = kinParticles(nfull);
517  vector<RefCountedKinematicParticle>::const_iterator iter = kPart.begin();
518  vector<RefCountedKinematicParticle>::const_iterator imid = iter + ns;
519  vector<RefCountedKinematicParticle>::const_iterator iend = kPart.end();
520  kComp->insert(kComp->end(), iter, imid);
521  kTail->insert(kTail->end(), imid, iend);
522  return comp;
523 }
524 
525 const RefCountedKinematicTree& BPHKinematicFit::kinematicTree(const vector<RefCountedKinematicParticle>& kPart,
526  MultiTrackKinematicConstraint* kc) const {
527  try {
529  kinTree = cvf.fit(kPart, kc);
530  } catch (std::exception const&) {
531  edm::LogPrint("FitFailed") << "BPHKinematicFit::kinematicTree: "
532  << "kin fit reset";
533  kinTree = RefCountedKinematicTree(nullptr);
534  }
535  return kinTree;
536 }
537 
539  if (isValidFit()) {
540  const KinematicState& ks = topParticle()->currentState();
541  GlobalVector tm = ks.globalMomentum();
542  double x = tm.x();
543  double y = tm.y();
544  double z = tm.z();
545  double m = ks.mass();
546  double e = sqrt((x * x) + (y * y) + (z * z) + (m * m));
547  totalMomentum.SetPxPyPzE(x, y, z, e);
548  } else {
549  edm::LogPrint("FitNotFound") << "BPHKinematicFit::fitMomentum: "
550  << "simple momentum sum computed";
552  const vector<const reco::Candidate*>& daug = daughters();
553  int n = daug.size();
554  while (n--)
555  tm += daug[n]->p4();
556  const vector<BPHRecoConstCandPtr>& comp = daughComp();
557  int m = comp.size();
558  while (m--)
559  tm += comp[m]->p4();
560  totalMomentum = tm;
561  }
562  oldMom = false;
563  return;
564 }
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
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_]
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 void getParticles(const std::string &moth, const std::string &daug, std::vector< RefCountedKinematicParticle > &kl, std::set< RefCountedKinematicParticle > &ks) const
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
~BPHKinematicFit() override
std::map< std::string, BPHRecoConstCandPtr > cMap
bool getIndependentFit(const std::string &name) const
retrieve independent fit flag
bool isValid() const
double constrSigma() const