Belle II Software light-2505-deimos
ParticleKinematicFitterModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <sstream>
9#define SSTR( x ) dynamic_cast< std::ostringstream && >(( std::ostringstream() << std::dec << x ) ).str()
10
11// kinfitter
12#include <analysis/modules/ParticleKinematicFitter/ParticleKinematicFitterModule.h>
13#include <analysis/OrcaKinFit/BaseFitObject.h>
14#include <analysis/OrcaKinFit/OPALFitterGSL.h>
15#include <analysis/OrcaKinFit/JetFitObject.h>
16#include <analysis/OrcaKinFit/NewtonFitterGSL.h>
17#include <analysis/OrcaKinFit/NewFitterGSL.h>
18#include <analysis/OrcaKinFit/PxPyPzMFitObject.h>
19
20#include <mdst/dataobjects/ECLCluster.h>
21
22#include <TDatabasePDG.h>
23
24// framework utilities
25#include <framework/gearbox/Const.h>
26#include <framework/logging/Logger.h>
27
28// analysis dataobjects
29#include <analysis/dataobjects/Particle.h>
30
31// analysis utilities
32#include <analysis/utility/PCmsLabTransform.h>
33#include <analysis/utility/ParticleCopy.h>
34#include <analysis/ClusterUtility/ClusterUtils.h>
35
36#include <cmath>
37
38using namespace CLHEP;
39using namespace std;
40using namespace Belle2;
41using namespace Belle2::OrcaKinFit;
42
43//-----------------------------------------------------------------
44// Register module
45//-----------------------------------------------------------------
46
47REG_MODULE(ParticleKinematicFitter);
48
49//-----------------------------------------------------------------
50// Implementation
51//-----------------------------------------------------------------
52
54 DataStore::c_Event)
55{
56 setDescription("Kinematic fitter for modular analysis");
58
59 // Add parameters
60 addParam("listName", m_listName, "Name of particle list.", string(""));
61 addParam("kinematicFitter", m_kinematicFitter, "Available: OrcaKinFit.", string("OrcaKinFit"));
62 addParam("orcaFitterEngine", m_orcaFitterEngine, "OrcaKinFit engine: NewFitterGSL, NewtonFitterGSL, OPALFitterGSL.",
63 string("OPALFitterGSL"));
64 addParam("orcaTracer", m_orcaTracer, "OrcaKinFit tracer: None, Text.", string("None"));
65 addParam("orcaConstraint", m_orcaConstraint, "OrcaKinFit constraint: HardBeam, RecoilMass.", string("HardBeam"));
66 addParam("debugFitter", m_debugFitter, "Switch on/off internal debugging output if available.", false);
67 addParam("debugFitterLevel", m_debugFitterLevel, "Internal debugging output level if available.", 10);
68 addParam("addUnmeasuredPhoton", m_addUnmeasuredPhoton, "Add one unmeasured photon (-3C).", false);
69 addParam("fixUnmeasuredToHER", m_fixUnmeasuredPhotonToHER, "fix the momentum of the unmeasured photon to HER (+2C).", false);
70 addParam("fixUnmeasuredToLER", m_fixUnmeasuredPhotonToLER, "fix the momentum of the unmeasured photon to LER (+2C).", false);
71 addParam("add3CPhoton", m_add3CPhoton, "Add one photon with unmeasured energy (-1C).", false);
72 addParam("liftPhotonTheta", m_liftPhotonTheta, "Lift theta constraint of 3CPhoton. Valid when add3CPhoton is true.", false);
73 addParam("decayString", m_decayString, "Specifies which daughter particles are included in the kinematic fit.", string(""));
74 addParam("updateMother", m_updateMother, "Update the mother kinematics.", true);
75 addParam("updateDaughters", m_updateDaughters, "Update the daughter kinematics.", false);
76 addParam("recoilMass", m_recoilMass, "Recoil mass in GeV. RecoilMass constraint only.", 0.0);
77 addParam("invMass", m_invMass, "Invariant mass in GeV. Mass constraint only.", 0.0);
78 addParam("variablePrefix", m_prefix, "Prefix attached to extra info variables.", string(""));
79 addParam("decayStringForDirectionOnlyParticles", m_decayStringForDirectionOnlyParticles,
80 "DecayString specifying the particles to use only direction information in the fit", std::string(""));
81 addParam("decayStringForAlternateMassParticles", m_decayStringForAlternateMassParticles,
82 "DecayString specifying the particles where an alternate mass hypothesis is used", std::string(""));
83 addParam("decayStringForNeutronVsAntiNeutron", m_decayStringForNeutronVsAntiNeutron,
84 "DecayString specifying the charged particle used to tag whether n or nbar. If tag particle has negative charge, PDG sign of n/nbar is flipped from default given in alternateMassHypos",
85 std::string(""));
86 addParam("alternateMassHypos", m_listAlternateMassHypo,
87 "integer list of pdg values for particles where different mass hypothesis is used in the fit");
88
89}
90
92{
93 m_eventextrainfo.isRequired();
94
95 if (m_decayString != "") {
97 B2INFO("ParticleKinematicFitter: Using specified decay string: " << m_decayString);
98 }
99
102 }
103
106 if (m_listAlternateMassHypo.size() == 0)
107 B2FATAL("decayStringForAlternateMassParticles specified but alternateMassHypos not provided.");
108 } else if (m_listAlternateMassHypo.size() > 0) {
109 B2FATAL("alternateMassHypos specified but decayStringForAlternateMassParticles not provided.");
110 }
111
114 }
115
116 m_plist.isRequired(m_listName);
117}
118
120{
121 B2INFO("ParticleKinematicFitterModule::terminate");
122}
123
125{
126 B2DEBUG(17, "ParticleKinematicFitterModule::event");
127
128 unsigned int n = m_plist->getListSize();
129
130 for (unsigned i = 0; i < n; i++) {
131 Particle* particle = m_plist->getParticle(i);
132
133 if (m_updateDaughters == true) {
134 if (m_decayString.empty()) ParticleCopy::copyDaughters(particle);
135 else B2ERROR("Daughters update works only when all daughters are selected. Daughters will not be updated");
136 }
137
138 bool ok = doKinematicFit(particle);
139
140 if (!ok) particle->setPValue(-1.);
141 }
142}
143
145{
146 B2DEBUG(17, "ParticleKinematicFitterModule::doKinematicFit");
147
148 bool ok = false;
149
150 // fitting with OrcaKinFit
151 if (m_kinematicFitter == "OrcaKinFit") {
152
153 // select subset of particles for the fit
154 if (m_decayString != "") {
155 B2FATAL("ParticleKinematicFitterModule: OrcaKinFit does not support yet selection of daughters via decay string!") ;
156 }
157
158 // check requested fit engine
159 if (!(m_orcaFitterEngine == "OPALFitterGSL" or
160 m_orcaFitterEngine == "NewtonFitterGSL" or
161 m_orcaFitterEngine == "NewFitterGSL")) {
162 B2FATAL("ParticleKinematicFitterModule: " << m_orcaFitterEngine << " is an invalid OrcaKinFit fitter engine!");
163 }
164
165 // check requested constraint
166 if (!(m_orcaConstraint == "HardBeam" or
167 m_orcaConstraint == "RecoilMass" or
168 m_orcaConstraint == "Mass")) {
169 B2FATAL("ParticleKinematicFitterModule: " << m_orcaConstraint << " is an invalid OrcaKinFit constraint!");
170 }
171
172 // basic check is good, go to fitting routine
173 ok = doOrcaKinFitFit(mother);
174 } else { // invalid fitter
175 B2FATAL("ParticleKinematicFitter: " << m_kinematicFitter << " is an invalid kinematic fitter!");
176 }
177
178 if (!ok) return false;
179
180 return true;
181
182}
183
185{
186 if (mother->getNDaughters() <= 1) {
187 B2WARNING("ParticleKinematicFitterModule: Cannot fit with " << mother->getNDaughters() << " daughters.");
188 return false;
189 }
190
191 //use getMdstSource as unique identifier
192 std::vector<int> directionOnlyParticlesIdentifiers;
194 std::vector<const Particle*> selparticles = m_decaydescriptorForDirectionOnlyParticles.getSelectionParticles(mother);
195 for (unsigned int i = 0; i < selparticles.size(); i++) {
196 directionOnlyParticlesIdentifiers.push_back(selparticles[i]->getMdstSource());
197 }
198 }
199
200 //use getMdstSource as unique identifier
201 std::vector<int> alternateMassHypoIdentifiers;
203 std::vector<const Particle*> selparticles = m_decaydescriptorForAlternateMassParticles.getSelectionParticles(mother);
204 for (unsigned int i = 0; i < selparticles.size(); i++) {
205 alternateMassHypoIdentifiers.push_back(selparticles[i]->getMdstSource());
206 }
207 if (alternateMassHypoIdentifiers.size() != m_listAlternateMassHypo.size()) {
208 B2FATAL("alternateMassHypoIdentifiers size must match listAlternateMassHypo");
209 }
210 }
211
212 //Determine if n or nbar based on charge of tag particle indicated
213 //If tag particle has negative charge, sign of n and nbar are flipped.
214 //Required to use optimal position resolution
215 bool flipNeutronPDGsign = 0;
217 std::vector<const Particle*> selparticles = m_decaydescriptorForNeutronVsAntiNeutron.getSelectionParticles(mother);
218 if (selparticles.size() != 1) {
219 B2FATAL("Select only one particle to tag neutron vs. antineutron");
220 }
221 if (selparticles[0]->getCharge() < 0) flipNeutronPDGsign = 1;
222 }
223
224
225 // fill particles
226 std::vector<Particle*> particleChildren;
227 bool validChildren = fillFitParticles(mother, particleChildren);
228
229 if (!validChildren) {
230 B2WARNING("ParticleKinematicFitterModule: Cannot find valid children for the fit.");
231 return false;
232 }
233
234 // set fit engine
235 BaseFitter* pfitter;
236
237 // internal debugger
238 int debugfitter = 0;
239 if (m_debugFitter) debugfitter = m_debugFitterLevel;
240
241 // choose minimization
242 if (m_orcaFitterEngine == "OPALFitterGSL") {
243 pfitter = new OPALFitterGSL(); // OPAL fitter has no debugger
244 } else if (m_orcaFitterEngine == "NewtonFitterGSL") {
245 pfitter = new NewtonFitterGSL();
246 (dynamic_cast<NewtonFitterGSL*>(pfitter))->setDebug(debugfitter);
247 } else if (m_orcaFitterEngine == "NewFitterGSL") {
248 pfitter = new NewFitterGSL();
249 (dynamic_cast<NewFitterGSL*>(pfitter))->setDebug(debugfitter);
250 } else {
251 B2FATAL("ParticleKinematicFitterModule: " << m_orcaFitterEngine << " is an invalid OrcaKinFit fitter engine!");
252 return false;
253 }
254
255 if (!pfitter) return false;
256 BaseFitter& fitter(*pfitter);
257
258 // reset fitter
259 resetFitter(fitter);
260
261 // set constraints (not connected to a fitter or particles at this point!)
263
264
265 // add fit particles from particle list to the fitter and to all constraints
266 for (unsigned iChild = 0; iChild < particleChildren.size(); iChild++) {
267
268 bool useDirectionOnly = false;
269 if (directionOnlyParticlesIdentifiers.size() > 0) {
270 if (std::find(directionOnlyParticlesIdentifiers.begin(), directionOnlyParticlesIdentifiers.end(),
271 particleChildren[iChild]->getMdstSource()) != directionOnlyParticlesIdentifiers.end()) useDirectionOnly = true;
272 }
273
274 int massHypo = 0;
275 if (alternateMassHypoIdentifiers.size() > 0) {
276 for (unsigned int i = 0; i < alternateMassHypoIdentifiers.size(); i++) {
277 if (alternateMassHypoIdentifiers[i] == particleChildren[iChild]->getMdstSource()) {
278 massHypo = m_listAlternateMassHypo[i];
279 break;
280 }
281 }
282 //Always use direction only for neutrons
283 if (abs(massHypo) == Const::neutron.getPDGCode()) {
284 if (useDirectionOnly == false)
285 B2WARNING("Neutron mass hypothesis assigned to fit particle but directionOnly flag not specified for same particle. Setting candidate to useDirectionOnly.");
286 useDirectionOnly = true;
287 if (flipNeutronPDGsign) massHypo = -massHypo;
288 }
289 }
290 addParticleToOrcaKinFit(fitter, particleChildren[iChild], iChild, useDirectionOnly, massHypo);
291 }
292
293 // add unmeasured photon to the fitter and to all constraints
295
296 // add constraints to the fitter
298
299 // add tracers to the fitter
300 addTracerToFitter(fitter);
301
302 //store information before the fit
303 storeOrcaKinFitParticles("Measured", fitter, particleChildren, mother);
304
305 double prob = fitter.fit();
306 double chi2 = fitter.getChi2();
307 int niter = fitter.getIterations();
308 int ndof = fitter.getDoF();
309 int errorcode = fitter.getError();
310
311 B2DEBUG(17, "ParticleKinematicFitterModule: -------------------------------------------");
312 B2DEBUG(17, "ParticleKinematicFitterModule: Fit result of OrcaKinFit using " << m_orcaFitterEngine);
313 B2DEBUG(17, "ParticleKinematicFitterModule: prob " << prob);
314 B2DEBUG(17, "ParticleKinematicFitterModule: chi2 " << chi2);
315 B2DEBUG(17, "ParticleKinematicFitterModule: iterations " << niter);
316 B2DEBUG(17, "ParticleKinematicFitterModule: ndf " << ndof);
317 B2DEBUG(17, "ParticleKinematicFitterModule: errorcode " << errorcode);
318 B2DEBUG(17, "ParticleKinematicFitterModule: -------------------------------------------");
319
320 // default update mother information
321 if (m_updateMother) updateOrcaKinFitMother(fitter, particleChildren, mother);
322
323 // update daughter information if that is requested
324 if (m_updateDaughters) updateOrcaKinFitDaughters(fitter, mother);
325
326 // store information after the fit
327 storeOrcaKinFitParticles("Fitted", fitter, particleChildren, mother);
328
329 //store general fit results
330 mother->addExtraInfo(m_prefix + "OrcaKinFitProb", prob);
331 mother->setPValue(prob);
332 mother->addExtraInfo(m_prefix + "OrcaKinFitChi2", chi2);
333 mother->addExtraInfo(m_prefix + "OrcaKinFitErrorCode", errorcode);
334
335 // if we added an unmeasured photon, add the kinematics to the mother - at some point we may want to create a particle list from this?
336 std::vector <BaseFitObject*>* fitObjectContainer = fitter.getFitObjects();
337 for (auto fo : *fitObjectContainer) {
339 const std::string name = fo->getName();
340 if (name.find("Unmeasured") != std::string::npos) {
341 auto* fitobject = static_cast<ParticleFitObject*>(fo);
342 ROOT::Math::PxPyPzEVector tlv = getLorentzVector(fitobject);
343 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "Theta", tlv.Theta());
344 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "Phi", tlv.Phi());
345 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "E", tlv.E());
346
347 // Uncertainty
348 // const double err0 = getFitObjectError(fitobject, 0);
349 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "ErrorTheta", getFitObjectError(fitobject, 1));
350 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "ErrorPhi", getFitObjectError(fitobject, 2));
351 mother->addExtraInfo(m_prefix + "OrcaKinFit" + name + "ErrorE", getFitObjectError(fitobject, 0));
352 }
353 }
354 delete fo;
355 }
356
357 delete pfitter;
358 delete m_textTracer;
359 return true;
360}
361
362bool ParticleKinematicFitterModule::fillFitParticles(Particle* mother, std::vector<Particle*>& particleChildren)
363{
364 for (unsigned ichild = 0; ichild < mother->getNDaughters(); ichild++) {
365 auto* child = const_cast<Particle*>(mother->getDaughter(ichild));
366
367 if (child->getNDaughters() > 0) {
368 bool err = fillFitParticles(child, particleChildren);
369 if (!err) {
370 B2WARNING("ParticleKinematicFitterModule: Cannot find valid children for the fit.");
371 return false;
372 }
373 } else if (child->getPValue() > 0) {
374 particleChildren.push_back(child);
375 } else {
376 B2ERROR("Daughter with PDG code " << child->getPDGCode() << " does not have a valid p-value: p=" << child->getPValue() << ", E=" <<
377 child->getEnergy() << " GeV");
378 return false; // error matrix not valid
379 }
380 }
381 return true;
382}
383
385{
386 TMatrixFSym MomentumVertexErrorMatrix(7);
387 for (unsigned ichild = 0; ichild < mother->getNDaughters(); ichild++) {
388 auto* child = const_cast<Particle*>(mother->getDaughter(ichild));
389
390 if (child->getPValue() > 0) {
391 MomentumVertexErrorMatrix += child->getMomentumVertexErrorMatrix();
392 } else if (child->getNDaughters() > 0) {
393 AddFour(child);
394 MomentumVertexErrorMatrix += child->getMomentumVertexErrorMatrix();
395 } else {
396 B2ERROR("Daughter with PDG code " << child->getPDGCode() << " does not have a valid p-value: p=" << child->getPValue() << ", E=" <<
397 child->getEnergy() << " GeV");
398 return false; // error matrix not valid
399 }
400 }
401 mother->setMomentumVertexErrorMatrix(MomentumVertexErrorMatrix);
402 return true;
403}
404
406 bool useOnlyDirection, int massHypoPDG)
407{
408 B2DEBUG(17, "ParticleKinematicFitterModule: adding a particle to the fitter!");
409
410 if (m_add3CPhoton && index == 0) {
411 if (particle -> getPDGCode() != Const::photon.getPDGCode()) {
412 B2ERROR("In 3C Kinematic fit, the first daughter should be the Unmeasured Photon!");
413 }
414
415 const ECLCluster* cluster = particle->getECLCluster();
416 double startingE = cluster->getEnergy(particle->getECLClusterEHypothesisBit());
417 double startingPhi = cluster->getPhi();
418 double startingTheta = cluster->getTheta();
419
420 ClusterUtils clutls;
421 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster);
422 double startingEError = sqrt(fabs(EPhiThetaCov[0][0]));
423 double startingPhiError = sqrt(fabs(EPhiThetaCov[1][1]));
424 double startingThetaError = sqrt(fabs(EPhiThetaCov[2][2]));
425
426 B2DEBUG(17, startingPhi << " " << startingTheta << " " << startingPhiError << " " << startingThetaError);
427 // create a fit object
428 ParticleFitObject* pfitobject;
429 // memory allocated: it will be deallocated via "delete fo" in doOrcaKinFitFit
430 pfitobject = new JetFitObject(startingE, startingTheta, startingPhi, startingEError, startingThetaError, startingPhiError, 0.);
431 pfitobject->setParam(0, startingE, false, false);
433 pfitobject->setParam(1, startingTheta, false, false);
434 else
435 pfitobject->setParam(1, startingTheta, true, false);
436 pfitobject->setParam(2, startingPhi, true, false);
437
438 std::string fitObjectName = "Unmeasured3C";
439 pfitobject->setName(fitObjectName.c_str());
440 ParticleFitObject& fitobject = *pfitobject;
441
442 // add this fit object (=particle) to the constraints
443 addFitObjectToConstraints(fitobject);
444
445 // add fit particle to the fitter
446 fitter.addFitObject(fitobject);
447
448 } else if (useOnlyDirection || massHypoPDG) {
449
450 ParticleFitObject* pfitobject;
451
452 const ECLCluster* cluster = particle->getECLCluster();
453
454 if (particle->getCharge() != 0 or !cluster) {
455 B2FATAL("ParticleKinematicFitterModule: Direction only and alternate mass options only implemented for neutral particles with ECL cluster");
456 }
457
458 double mass = particle->getPDGMass();
459 if (massHypoPDG != 0) {
460 if (TDatabasePDG::Instance()->GetParticle(massHypoPDG) == nullptr) {
461 B2FATAL("ParticleKinematicFitterModule: " << massHypoPDG << " is an unknown PDG code!");
462 }
463 mass = TDatabasePDG::Instance()->GetParticle(massHypoPDG)->Mass();
464 }
465 double clusterE = cluster->getEnergy(particle->getECLClusterEHypothesisBit());
466 double startingE = sqrt(clusterE * clusterE + mass * mass);
467 double startingPhi = cluster->getPhi();
468 double startingTheta = cluster->getTheta();
469
470 ClusterUtils clutls;
471 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster, massHypoPDG);
472 double startingEError = sqrt(fabs(EPhiThetaCov[0][0]));
473 double startingPhiError = sqrt(fabs(EPhiThetaCov[1][1]));
474 double startingThetaError = sqrt(fabs(EPhiThetaCov[2][2]));
475
476 // memory allocated: it will be deallocated via "delete fo" in doOrcaKinFitFit
477 pfitobject = new JetFitObject(startingE, startingTheta, startingPhi, startingEError, startingThetaError, startingPhiError, mass);
478 pfitobject->setParam(0, startingE, true, false);
479 if (useOnlyDirection) pfitobject->setParam(0, startingE, false, false);
480 pfitobject->setParam(1, startingTheta, true, false);
481 pfitobject->setParam(2, startingPhi, true, false);
482
483 std::string fitObjectName = "particle_" + SSTR(index);
484 pfitobject->setName(fitObjectName.c_str());
485 ParticleFitObject& fitobject = *pfitobject;
486
487 // add this fit object (=particle) to the constraints
488 addFitObjectToConstraints(fitobject);
489
490 // add fit particle to the fitter
491 fitter.addFitObject(fitobject);
492
493 } else {
494 // four vector
495 CLHEP::HepLorentzVector clheplorentzvector = getCLHEPLorentzVector(particle);
496
497 // error matrix
498 CLHEP::HepSymMatrix clhepmomentumerrormatrix = getCLHEPMomentumErrorMatrix(particle);
499
500 // create the fit object (ParticleFitObject is the base class)
501 ParticleFitObject* pfitobject;
502 // memory allocated: it will be deallocated via "delete fo" in doOrcaKinFitFit
503 pfitobject = new PxPyPzMFitObject(clheplorentzvector, clhepmomentumerrormatrix);
504 std::string fitObjectName = "particle_" + SSTR(index);
505 pfitobject->setName(fitObjectName.c_str());
506 ParticleFitObject& fitobject = *pfitobject;
507
508 // add this fit object (=particle) to the constraints
509 addFitObjectToConstraints(fitobject);
510
511 // add fit particle to the fitter
512 fitter.addFitObject(fitobject);
513 }
514
515 return;
516}
517
519{
520 CLHEP::HepSymMatrix covMatrix(4);
521 TMatrixFSym errMatrix = particle->getMomentumErrorMatrix();
522
523 for (int i = 0; i < 4; i++) {
524 for (int j = 0; j < 4; j++) {
525 covMatrix[i][j] = errMatrix[i][j];
526 }
527 }
528
529 return covMatrix;
530}
531
533{
534 CLHEP::HepSymMatrix covMatrix(7);
535 TMatrixFSym errMatrix = particle->getMomentumVertexErrorMatrix();
536
537 for (int i = 0; i < 7; i++) {
538 for (int j = 0; j < 7; j++) {
539 covMatrix[i][j] = errMatrix[i][j];
540 }
541 }
542
543 return covMatrix;
544}
545
547{
548 CLHEP::HepLorentzVector mom(particle->getPx(), particle->getPy(), particle->getPz(), particle->get4Vector().E());
549 return mom;
550}
551
553{
554 ROOT::Math::PxPyPzEVector mom(fitobject->getPx(), fitobject->getPy(), fitobject->getPz(), fitobject->getE());
555 return mom;
556}
557
558// TMatrixFSym ParticleKinematicFitterModule::getTMatrixFSymMomentumErrorMatrix(ParticleFitObject* fitobject) //fix the warning
560{
561 TMatrixFSym errMatrix(4);
562
563 for (int i = 0; i < 4; i++) {
564 for (int j = i; j < 4; j++) {
565 errMatrix[i][j] = 0.0;
566 }
567 }
568
569 return errMatrix;
570}
571
572// TMatrixFSym ParticleKinematicFitterModule::getTMatrixFSymMomentumVertexErrorMatrix(ParticleFitObject* fitobject) //fix the warning
574{
575 TMatrixFSym errMatrix(7);
576
577 for (int i = 0; i < 7; i++) {
578 for (int j = i; j < 7; j++) {
579 errMatrix[i][j] = 0.0;
580 }
581 }
582
583 return errMatrix;
584}
585
587{
588 if (m_orcaConstraint == "HardBeam") {
589 ROOT::Math::PxPyPzEVector constraints4vector(m_hardConstraintPx.getValue(),
590 m_hardConstraintPy.getValue(),
591 m_hardConstraintPz.getValue(),
592 m_hardConstraintE.getValue());
593 return constraints4vector;
594 } else {
595 B2FATAL("ParticleKinematicFitterModule: " << m_orcaConstraint << " is an invalid OrcaKinFit constraint!");
596 }
597
598 // should not reach this point...
599 return ROOT::Math::PxPyPzEVector(0., 0., 0., 0.);
600}
601
603{
604 if (m_orcaConstraint == "HardBeam") {
606 const ROOT::Math::PxPyPzEVector boost = T.getBeamFourMomentum();
607
608 m_hardConstraintPx = MomentumConstraint(0, 1, 0, 0, boost.Px());
609 m_hardConstraintPy = MomentumConstraint(0, 0, 1, 0, boost.Py());
610 m_hardConstraintPz = MomentumConstraint(0, 0, 0, 1, boost.Pz());
611 m_hardConstraintE = MomentumConstraint(1, 0, 0, 0, boost.E());
612
613 m_hardConstraintPx.resetFOList();
614 m_hardConstraintPy.resetFOList();
615 m_hardConstraintPz.resetFOList();
616 m_hardConstraintE.resetFOList();
617
618 m_hardConstraintPx.setName("Sum(p_x) [hard]");
619 m_hardConstraintPy.setName("Sum(p_y) [hard]");
620 m_hardConstraintPz.setName("Sum(p_z) [hard]");
621 m_hardConstraintE.setName("Sum(E) [hard]");
622
623 } else if (m_orcaConstraint == "RecoilMass") {
625 const ROOT::Math::PxPyPzEVector boost = T.getBeamFourMomentum();
626
627 m_hardConstraintRecoilMass = RecoilMassConstraint(m_recoilMass, boost.Px(), boost.Py(), boost.Pz(), boost.E());
628
629 m_hardConstraintRecoilMass.resetFOList();
630 m_hardConstraintRecoilMass.setName("Recoil Mass [hard]");
631
632 } else if (m_orcaConstraint == "Mass") {
634
635 m_hardConstraintMass.resetFOList();
636 m_hardConstraintMass.setName("Mass [hard]");
637 } else {
638 B2FATAL("ParticleKinematicFitterModule: " << m_orcaConstraint << " is an invalid OrcaKinFit constraint!");
639 }
640}
641
643{
644 B2DEBUG(17, "ParticleKinematicFitterModule: Resetting the fitter");
645 fitter.reset();
646}
647
649{
650 if (m_orcaConstraint == "HardBeam") {
651 m_hardConstraintPx.addToFOList(fitobject);
652 m_hardConstraintPy.addToFOList(fitobject);
653 m_hardConstraintPz.addToFOList(fitobject);
654 m_hardConstraintE.addToFOList(fitobject);
655 } else if (m_orcaConstraint == "RecoilMass") {
656 m_hardConstraintRecoilMass.addToFOList(fitobject);
657 } else if (m_orcaConstraint == "Mass") {
658 m_hardConstraintMass.addToFOList(fitobject);
659 } else {
660 B2FATAL("ParticleKinematicFitterModule: " << m_orcaConstraint << " is an invalid OrcaKinFit constraint!");
661 }
662}
663
665{
666 if (m_orcaConstraint == "HardBeam") {
667 fitter.addConstraint(m_hardConstraintPx);
668 fitter.addConstraint(m_hardConstraintPy);
669 fitter.addConstraint(m_hardConstraintPz);
670 fitter.addConstraint(m_hardConstraintE);
671 } else if (m_orcaConstraint == "RecoilMass") {
672 fitter.addConstraint(m_hardConstraintRecoilMass);
673 } else if (m_orcaConstraint == "Mass") {
674 fitter.addConstraint(m_hardConstraintMass);
675 }
676
677 else {
678 B2FATAL("ParticleKinematicFitterModule: " << m_orcaConstraint << " is an invalid OrcaKinFit constraint!");
679 }
680}
681
683{
684 if (m_orcaTracer == "Text") {
685 m_textTracer = new TextTracer(std::cout);
686 fitter.setTracer(m_textTracer);
687 } else if (m_orcaTracer != "None") {
688 B2FATAL("ParticleKinematicFitterModule: " << m_orcaTracer << " is an invalid OrcaKinFit tracer!");
689 }
690}
691
693{
694 B2DEBUG(17, "ParticleKinematicFitterModule::addUnmeasuredGammaToOrcaKinFit: adding an unmeasured photon to the fitter!");
695 // Initialize photon using the existing constraints
696 ROOT::Math::PxPyPzEVector tlv = getLorentzVectorConstraints();
697 double startingE = tlv.E();
698 double startingPhi = tlv.Phi();
699 double startingTheta = tlv.Theta();
700 bool paramFlag = false;
701
702 // create a fit object
703 ParticleFitObject* pfitobject;
704
705 std::string fitObjectName = "UnmeasuredAlongBeam";
706
708 startingTheta = 41.5e-3; // TODO: Read beam crossing angle from db if it's available
709 startingPhi = 0.0;
710 paramFlag = true;
711 } else if (m_fixUnmeasuredPhotonToLER) {
712 startingTheta = TMath::Pi() - 41.5e-3;
713 startingPhi = 0.0;
714 paramFlag = true;
715 } else {
716 fitObjectName = "Unmeasured";
717 }
718
719 // memory allocated: it will be deallocated via "delete fo" in doOrcaKinFitFit
720 pfitobject = new JetFitObject(startingE, startingTheta, startingPhi, 0.0, 0.0, 0.0, 0.);
721 pfitobject->setParam(0, startingE, false, false);
722 pfitobject->setParam(1, startingTheta, paramFlag, paramFlag);
723 pfitobject->setParam(2, startingPhi, paramFlag, paramFlag);
724
725 pfitobject->setName(fitObjectName.c_str());
726 ParticleFitObject& fitobject = *pfitobject;
727
728 // add this fit object (=particle) to the constraints
729 addFitObjectToConstraints(fitobject);
730
731 // add fit particle to the fitter
732 fitter.addFitObject(fitobject);
733}
734
736{
737 std::vector <Belle2::Particle*> bDau = mother->getDaughters();
738 std::vector <BaseFitObject*>* fitObjectContainer = fitter.getFitObjects();
739
740 const unsigned nd = bDau.size();
741 unsigned l = 0;
742 std::vector<std::vector<unsigned>> pars;
743 std::vector<Particle*> allparticles;
744 for (unsigned ichild = 0; ichild < nd; ichild++) {
745 const Particle* daughter = mother->getDaughter(ichild);
746 std::vector<unsigned> pard;
747 if (daughter->getNDaughters() > 0) {
748 updateMapOfTrackAndDaughter(l, pars, pard, allparticles, daughter);
749 pars.push_back(pard);
750 allparticles.push_back(bDau[ichild]);
751 } else {
752 pard.push_back(l);
753 pars.push_back(pard);
754 allparticles.push_back(bDau[ichild]);
755 l++;
756 }
757 }
758
759 if (l == fitObjectContainer->size() - m_addUnmeasuredPhoton) {
760
761 if (fitter.getError() == 0) {
762 for (unsigned iDaug = 0; iDaug < allparticles.size(); iDaug++) {
763 ROOT::Math::PxPyPzEVector tlv ;
764 TMatrixFSym errMatrixU(7);
765 if (pars[iDaug].size() > 0) {
766 for (unsigned int iChild : pars[iDaug]) {
767 BaseFitObject* fo = fitObjectContainer->at(iChild);
768 auto* fitobject = static_cast<ParticleFitObject*>(fo);
769 ROOT::Math::PxPyPzEVector tlv_sub = getLorentzVector(fitobject);
770 TMatrixFSym errMatrixU_sub = getCovMat7(fitobject);
771 tlv = tlv + tlv_sub;
772 errMatrixU = errMatrixU + errMatrixU_sub;
773 }
774 } else {
775 B2FATAL("ParticleKinematicFitterModule: no fitObject could be used to update the daughter!");
776 }
777 ROOT::Math::XYZVector pos = allparticles[iDaug]->getVertex(); // we don't update the vertex yet
778 TMatrixFSym errMatrix = allparticles[iDaug]->getMomentumVertexErrorMatrix();
779 TMatrixFSym errMatrixMom = allparticles[iDaug]->getMomentumErrorMatrix();
780 TMatrixFSym errMatrixVer = allparticles[iDaug]->getVertexErrorMatrix();
781
782 for (int i = 0; i < 3; i++) {
783 for (int j = i; j < 3; j++) {
784 errMatrixU[i + 4][j + 4] = errMatrixVer[i][j];
785 }
786 }
787
788 allparticles[iDaug]->set4Vector(tlv);
789 allparticles[iDaug]->setVertex(pos);
790 allparticles[iDaug]->setMomentumVertexErrorMatrix(errMatrixU);
791 }
792 }
793
794 return true;
795 } else {
796 B2ERROR("updateOrcaKinFitDaughters: Cannot update daughters, mismatch between number of daughters and number of fitobjects!");
797 return false;
798 }
799}
800
801void ParticleKinematicFitterModule::updateMapOfTrackAndDaughter(unsigned& l, std::vector<std::vector<unsigned>>& pars,
802 std::vector<unsigned>& parm, std::vector<Particle*>& allparticles, const Particle* daughter)
803{
804 std::vector <Belle2::Particle*> dDau = daughter->getDaughters();
805 for (unsigned ichild = 0; ichild < daughter->getNDaughters(); ichild++) {
806 const Particle* child = daughter->getDaughter(ichild);
807 std::vector<unsigned> pard;
808 if (child->getNDaughters() > 0) {
809 updateMapOfTrackAndDaughter(l, pars, pard, allparticles, child);
810 parm.insert(parm.end(), pard.begin(), pard.end());
811 pars.push_back(pard);
812 allparticles.push_back(dDau[ichild]);
813 } else {
814 pard.push_back(l);
815 parm.push_back(l);
816 pars.push_back(pard);
817 allparticles.push_back(dDau[ichild]);
818 l++;
819 }
820 }
821}
822
823void ParticleKinematicFitterModule::updateOrcaKinFitMother(BaseFitter& fitter, std::vector<Particle*>& particleChildren,
824 Particle* mother)
825{
826 // get old values
827 ROOT::Math::XYZVector pos = mother->getVertex();
828 TMatrixFSym errMatrix = mother->getMomentumVertexErrorMatrix();
829 float pvalue = mother->getPValue();
830
831 // update momentum vector
832 ROOT::Math::PxPyPzEVector momnew(0., 0., 0., 0.);
833
834 std::vector <BaseFitObject*>* fitObjectContainer = fitter.getFitObjects();
835 for (unsigned iChild = 0; iChild < particleChildren.size(); iChild++) {
836 BaseFitObject* fo = fitObjectContainer->at(iChild);
837 auto* fitobject = static_cast<ParticleFitObject*>(fo);
838 ROOT::Math::PxPyPzEVector tlv = getLorentzVector(fitobject);
839 momnew += tlv;
840 }
841
842 // update
843 // TODO: use pvalue of the fit or the old one of the mother? use fit covariance matrix?
844 // Maybe here should use the pvalue and errmatrix of the fit ----Yu Hu
845 mother->updateMomentum(momnew, pos, errMatrix, pvalue);
846}
847
849 std::vector<Particle*>& particleChildren, Particle* mother)
850{
851 bool updated = false;
852 std::vector <BaseFitObject*>* fitObjectContainer = fitter.getFitObjects();
853
854 for (unsigned iChild = 0; iChild < particleChildren.size(); iChild++) {
855 BaseFitObject* fo = fitObjectContainer->at(iChild);
856 auto* fitobject = static_cast<ParticleFitObject*>(fo);
857 ROOT::Math::PxPyPzEVector tlv = getLorentzVector(fitobject);
858
859 // name of extra variables
860 std::string extraVariableParticlePx = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_Px";
861 std::string extraVariableParticlePy = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_Py";
862 std::string extraVariableParticlePz = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_Pz";
863 std::string extraVariableParticleE = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_E";
864 std::string extraVariableParticlePxErr = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_PxErr";
865 std::string extraVariableParticlePyErr = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_PyErr";
866 std::string extraVariableParticlePzErr = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_PzErr";
867 std::string extraVariableParticleEErr = m_prefix + "OrcaKinFit" + fitSuffix + "_" + SSTR(iChild) + "_EErr";
868
869 mother->addExtraInfo(extraVariableParticlePx, tlv.Px());
870 mother->addExtraInfo(extraVariableParticlePy, tlv.Py());
871 mother->addExtraInfo(extraVariableParticlePz, tlv.Pz());
872 mother->addExtraInfo(extraVariableParticleE, tlv.E());
873 mother->addExtraInfo(extraVariableParticlePxErr, getFitObjectError(fitobject, 0));
874 mother->addExtraInfo(extraVariableParticlePyErr, getFitObjectError(fitobject, 1));
875 mother->addExtraInfo(extraVariableParticlePzErr, getFitObjectError(fitobject, 2));
876 mother->addExtraInfo(extraVariableParticleEErr, -1.0);
877
878 }
879
880 return updated;
881}
882
884{
885 //check if it is a PxPyPzMFitObject
886 auto* pxpypzmfitobject = static_cast<PxPyPzMFitObject*>(fitobject);
887 if (pxpypzmfitobject) {
888 return fitobject->getError(ilocal);
889 } else {
890 B2FATAL("ParticleKinematicFitterModule: not implemented yet");
891 }
892}
893
894// this returns the local covariance matrix
896{
897
898 //check if it is a PxPyPzMFitObject
899 auto* pxpypzmfitobject = static_cast<PxPyPzMFitObject*>(fitobject);
900 if (pxpypzmfitobject) {
901
902 TMatrixFSym errMatrix(3);
903
904 //loop over the i-j local variables.
905 for (int i = 0; i < 3; i++) {
906 for (int j = 0; j < 3; j++) {
907 errMatrix[i][j] = pxpypzmfitobject->getCov(i, j);
908 }
909 }
910
911 return errMatrix;
912 } else {
913 B2FATAL("ParticleKinematicFitterModule: not implemented yet");
914 }
915}
916
918{
919 TMatrixFSym fitCovMatrix(3);
920
921 if (strcmp(fitobject->getParamName(0), "E") == 0) {
922 //check if it is a JetFitObject
923 auto* jetfitObject = static_cast<JetFitObject*>(fitobject);
924 if (jetfitObject) {
925
926 fitCovMatrix = getFitObjectCovMat(fitobject);
927 ROOT::Math::PxPyPzEVector tlv = getLorentzVector(fitobject);
928
929 const double energy = tlv.E();
930 const double theta = tlv.Theta();
931 const double phi = tlv.Phi();
932
933 const double st = sin(theta);
934 const double ct = cos(theta);
935 const double sp = sin(phi);
936 const double cp = cos(phi);
937
938 // updated covariance matrix is: A * cov * A^T where A is the Jacobi matrix (use Similarity)
939 TMatrixF A(7, 3);
940 A(0, 0) = cp * st ; // dpx/dE
941 A(0, 1) = energy * cp * ct ; // dpx/dtheta
942 A(0, 2) = -energy * sp * st ; // dpx/dphi
943 A(1, 0) = sp * st ; // dpy/dE
944 A(1, 1) = energy * sp * ct ; // dpz/dtheta
945 A(1, 2) = energy * cp * st ; // dpy/dphi
946 A(2, 0) = ct ; // dpz/dE
947 A(2, 1) = -energy * st ; // dpz/dtheta
948 A(2, 2) = 0 ; // dpz/dphi
949 A(3, 0) = 1.0; // dE/dE
950 A(3, 1) = 0.0; // dE/dphi
951 A(3, 2) = 0.0; // dE/dtheta
952
953 TMatrixFSym D = fitCovMatrix.Similarity(A);
954 return D;
955
956 } else {
957 B2FATAL("ParticleKinematicFitterModule: not implemented yet");
958 }
959 } else {
960 //check if it is a PxPyPzMFitObject
961 auto* pxpypzmfitobject = static_cast<PxPyPzMFitObject*>(fitobject);
962 if (pxpypzmfitobject) {
963
964 fitCovMatrix = getFitObjectCovMat(fitobject);
965
966 // updated covariance matrix is: A * cov * A^T where A is the Jacobi matrix (use Similarity)
967 ROOT::Math::PxPyPzEVector tlv = getLorentzVector(fitobject);
968 TMatrixF A(7, 3);
969 A[0][0] = 1.; // px/dpx
970 A[0][1] = 0.; // px/dpy
971 A[0][2] = 0.; // px/dpz
972 A[1][0] = 0.; // py/dpx
973 A[1][1] = 1.; // py/dpy
974 A[1][2] = 0.; // py/dpz
975 A[2][0] = 0.; // pz/dpx
976 A[2][1] = 0.; // pz/dpy
977 A[2][2] = 1.; // pz/dpz
978 if (tlv.E() > 0.0) {
979 A[3][0] = tlv.Px() / tlv.E(); // E/dpx, E=sqrt(px^2 + py^2 + pz^2 + m^2)
980 A[3][1] = tlv.Py() / tlv.E(); // E/dpy
981 A[3][2] = tlv.Pz() / tlv.E(); // E/dpz
982 }
983
984 TMatrixFSym D = fitCovMatrix.Similarity(A);
985
986 return D;
987 } else {
988 B2FATAL("ParticleKinematicFitterModule: not implemented yet");
989 }
990 }
991}
Class to provide momentum-related information from ECLClusters.
const TMatrixDSym GetCovarianceMatrix3x3FromCluster(const ECLCluster *cluster, int particleHypo=Const::photon.getPDGCode())
Returns 3x3 covariance matrix (E, theta, phi)
static const ParticleType neutron
neutron particle
Definition Const.h:675
static const ParticleType photon
photon particle
Definition Const.h:673
In the store you can park objects that have to be accessed by various modules.
Definition DataStore.h:51
ECL cluster data.
Definition ECLCluster.h:27
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
virtual const char * getParamName(int ilocal) const =0
Get name of parameter ilocal.
virtual double getError(int ilocal) const
Get error of parameter ilocal.
virtual bool setParam(int ilocal, double par_, bool measured_, bool fixed_=false)
Set value and measured flag of parameter i; return: significant change.
void setName(const char *name_)
Set object's name.
Abstract base class for fitting engines of kinematic fits.
Definition BaseFitter.h:47
Class for jets with (E, eta, phi) in kinematic fits.
Implements constraint 0 = mass1 - mass2 - m.
Implements a constraint of the form efact*sum(E)+pxfact*sum(px)+pyfact*sum(py)+pzfact*sum(pz)=value.
A kinematic fitter using the Newton-Raphson method to solve the equations.
Description of the fit algorithm and interface:
virtual double getPx() const
Return px.
virtual double getPz() const
Return pz.
virtual double getPy() const
Return py.
virtual double getE() const
Return E.
bool fillFitParticles(Particle *mother, std::vector< Particle * > &particleChildren)
Fills valid particle's children (with valid error matrix) in the vector of Particles that will enter ...
void addFitObjectToConstraints(ParticleFitObject &fitobject)
Adds Orca fit object to the constraints.
void updateMapOfTrackAndDaughter(unsigned &l, std::vector< std::vector< unsigned > > &pars, std::vector< unsigned > &pard, std::vector< Particle * > &allparticles, const Particle *daughter)
update the map of daughter and tracks, find out which tracks belong to each daughter.
bool m_liftPhotonTheta
lift theta constraint of the 3CPhoton.
bool AddFour(Particle *mother)
Added four vectors and calculated a covariance matrix for a combined particles.
std::string m_orcaConstraint
Constraint (softBeam, hardBeam (default))
std::string m_decayStringForNeutronVsAntiNeutron
n or nbar particle tag selection
int m_debugFitterLevel
internal debugging level (for New and Newton fitter only)
virtual void initialize() override
Initialize the Module.
CLHEP::HepSymMatrix getCLHEPMomentumVertexErrorMatrix(Particle *particle)
Returns particle's 7x7 momentum-vertex-error matrix as a HepSymMatrix.
MomentumConstraint m_hardConstraintE
hard beam constraint E
std::string m_prefix
prefix attached to extrainfo names
DecayDescriptor m_decaydescriptorForDirectionOnlyParticles
Decay descriptor of direction only particles selection.
bool m_debugFitter
activate internal debugging (for New and Newton fitter only)
void addParticleToOrcaKinFit(BaseFitter &fitter, Particle *particle, const int index, bool useOnlyDirection, int massHypoPDG)
Adds given particle to the OrcaKinFit.
void addUnmeasuredGammaToOrcaKinFit(BaseFitter &fitter)
Adds an unmeasured gamma (E, phi, theta) to the fit (-3C) stored as EventExtraInfo TODO.
std::string m_decayStringForAlternateMassParticles
alternate mass particles selection
MomentumConstraint m_hardConstraintPz
hard beam constraint pz
float getFitObjectError(ParticleFitObject *fitobject, int ilocal)
Returns fit object error on the parameter ilocal.
ROOT::Math::PxPyPzEVector getLorentzVectorConstraints()
Get constraints (at whatever stage before/after fitting)
std::vector< int > m_listAlternateMassHypo
index of particles where only direction is used
bool doOrcaKinFitFit(Particle *p)
Kinematic fit using OrcaKinFit.
bool m_add3CPhoton
add one photon with unmeasured energy to the fit (costs 1 constraints)
TMatrixFSym getTMatrixFSymMomentumErrorMatrix()
Returns particle's 7x7 momentum-error matrix as a TMatrixFSym.
DecayDescriptor m_decaydescriptorForAlternateMassParticles
Decay descriptor of alternate particles selection.
void addConstraintsToFitter(BaseFitter &fitter)
Adds Orca fit object to the constraints.
void addTracerToFitter(BaseFitter &fitter)
Adds tracer to the fitter.
RecoilMassConstraint m_hardConstraintRecoilMass
hard recoil mass constraint
TMatrixFSym getTMatrixFSymMomentumVertexErrorMatrix()
Returns particle's 7x7 momentum-vertex-error matrix as a TMatrixFSym.
StoreObjPtr< EventExtraInfo > m_eventextrainfo
StoreObjPtr for the EventExtraInfo in this mode.
MomentumConstraint m_hardConstraintPy
hard beam constraint py
double m_recoilMass
Recoil mass for RecoilMass constraint.
CLHEP::HepLorentzVector getCLHEPLorentzVector(Particle *particle)
Returns particle's 4-momentum as a HepLorentzVector.
std::string m_decayStringForDirectionOnlyParticles
direction only particles selection
DecayDescriptor m_decaydescriptor
Decay descriptor of decays to look for.
TMatrixFSym getCovMat7(ParticleFitObject *fitobject)
Returns covariance matrix.
ROOT::Math::PxPyPzEVector getLorentzVector(ParticleFitObject *fitobject)
bool updateOrcaKinFitDaughters(BaseFitter &fitter, Particle *mother)
Update the daughters: momentum is sum of daughters TODO update covariance matrix.
void setConstraints()
Sets constraints, this is not connect to particles or a fitter at this stage.
bool m_addUnmeasuredPhoton
add one unmeasured photon to the fit (costs 3 constraints)
TMatrixFSym getFitObjectCovMat(ParticleFitObject *fitobject)
Returns covariance matrix.
bool storeOrcaKinFitParticles(const std::string &fitSuffix, BaseFitter &fitter, std::vector< Particle * > &particleChildren, Particle *mother)
store fit object information as ExtraInfo
CLHEP::HepSymMatrix getCLHEPMomentumErrorMatrix(Particle *particle)
Returns particle's 4x4 momentum-error matrix as a HepSymMatrix.
bool m_fixUnmeasuredPhotonToHER
fix the momentum of the unmeasured photon to HER
DecayDescriptor m_decaydescriptorForNeutronVsAntiNeutron
Decay descriptor of n or nbar particle tag selection.
StoreObjPtr< ParticleList > m_plist
StoreObjPtr for the particle list.
void updateOrcaKinFitMother(BaseFitter &fitter, std::vector< Particle * > &particleChildren, Particle *mother)
Update the mother: momentum is sum of daughters TODO update covariance matrix.
void resetFitter(BaseFitter &fitter)
Resets all objects associated with the OrcaKinFit fitter.
bool m_fixUnmeasuredPhotonToLER
fix the momentum of the unmeasured photon to LER
bool doKinematicFit(Particle *p)
Main steering routine for any kinematic fitter.
MomentumConstraint m_hardConstraintPx
hard beam constraint px
Class to hold Lorentz transformations from/to CMS and boost vector.
ROOT::Math::PxPyPzEVector getBeamFourMomentum() const
Returns LAB four-momentum of e+e-, i.e.
Class to store reconstructed particles.
Definition Particle.h:76
double getPx() const
Returns x component of momentum.
Definition Particle.h:607
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
Definition Particle.cc:976
double getPz() const
Returns z component of momentum.
Definition Particle.h:625
double getPValue() const
Returns chi^2 probability of fit if done or -1.
Definition Particle.h:687
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition Particle.h:651
double getPy() const
Returns y component of momentum.
Definition Particle.h:616
unsigned getNDaughters(void) const
Returns number of daughter particles.
Definition Particle.h:747
std::vector< Belle2::Particle * > getDaughters() const
Returns a vector of pointers to daughter particles.
Definition Particle.cc:668
double getPDGMass(void) const
Returns uncertainty on the invariant mass (requires valid momentum error matrix)
Definition Particle.cc:635
double getCharge(void) const
Returns particle charge.
Definition Particle.cc:653
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition Particle.h:567
TMatrixFSym getMomentumErrorMatrix() const
Returns the 4x4 momentum error matrix.
Definition Particle.cc:466
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition Particle.cc:1421
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
Definition Particle.cc:424
void setPValue(double pValue)
Sets chi^2 probability of fit.
Definition Particle.h:377
void updateMomentum(const ROOT::Math::PxPyPzEVector &p4, const ROOT::Math::XYZVector &vertex, const TMatrixFSym &errMatrix, double pValue)
Sets Lorentz vector, position, 7x7 error matrix and p-value.
Definition Particle.h:397
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition Particle.cc:451
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
Definition Particle.cc:662
ECLCluster::EHypothesisBit getECLClusterEHypothesisBit() const
Returns the ECLCluster EHypothesisBit for this Particle.
Definition Particle.h:1029
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
void copyDaughters(Particle *mother)
Function copies all (grand-)^n-daughter particles of the argument mother Particle.
Abstract base class for different kinds of events.
STL namespace.