Belle II Software development
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
53ParticleKinematicFitterModule::ParticleKinematicFitterModule() : Module(), m_textTracer(nullptr), m_eventextrainfo("",
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(),
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
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
630 m_hardConstraintRecoilMass.setName("Recoil Mass [hard]");
631
632 } else if (m_orcaConstraint == "Mass") {
634
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") {
655 } else if (m_orcaConstraint == "RecoilMass") {
657 } else if (m_orcaConstraint == "Mass") {
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.
Definition: ClusterUtils.h:38
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
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
ECL cluster data.
Definition: ECLCluster.h:27
Base class for Modules.
Definition: Module.h:72
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
@ 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
void setName(const char *name_)
Set object's name.
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.
Definition: JetFitObject.h:43
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.
virtual double getValue() const override
Returns the value of the constraint.
A kinematic fitter using the Newton-Raphson method to solve the equations.
Definition: NewFitterGSL.h:51
Description of the fit algorithm and interface:
Definition: OPALFitterGSL.h:88
virtual void addToFOList(ParticleFitObject &fitobject, int flag=1)
Adds one ParticleFitObject objects to the list.
virtual void resetFOList()
Resests ParticleFitObject list.
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.
TextTracer * m_textTracer
internal text output variable
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.
double m_invMass
Invariant mass for Mass constraint.
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 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
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
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
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
void copyDaughters(Particle *mother)
Function copies all (grand-)^n-daughter particles of the argument mother Particle.
Definition: ParticleCopy.cc:55
Abstract base class for different kinds of events.
STL namespace.