Belle II Software development
B2BIIConvertMdstModule.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
9#include <b2bii/modules/B2BIIMdstInput/B2BIIConvertMdstModule.h>
10
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/datastore/RelationArray.h>
13#include <framework/database/Database.h>
14#include <framework/pcore/ProcHandler.h>
15
16#include <mdst/dataobjects/HitPatternVXD.h>
17#include <mdst/dataobjects/HitPatternCDC.h>
18#include <mdst/dataobjects/ECLCluster.h>
19
20// Belle II utilities
21#include <framework/gearbox/Unit.h>
22#include <framework/gearbox/Const.h>
23#include <framework/geometry/B2Vector3.h>
24#include <framework/geometry/VectorUtil.h>
25#include <analysis/dataobjects/ParticleExtraInfoMap.h>
26
27// Belle II dataobjects
28#include <framework/dataobjects/EventMetaData.h>
29#include <framework/dataobjects/Helix.h>
30#include <framework/dataobjects/UncertainHelix.h>
31
32// Belle utilities
33#include <b2bii/utility/BelleMdstToGenHepevt.h>
34
35// ROOT
36#include <Math/RotationY.h>
37#include <Math/Vector3D.h>
38#include <Math/Vector4D.h>
39#include <Math/Point3D.h>
40#include <Math/VectorUtil.h>
41
42#include <limits>
43#include <algorithm>
44#include <queue>
45#include <utility>
46
47#ifdef HAVE_EID
48#include "belle_legacy/eid/eid.h"
49#endif
50
51#ifdef HAVE_KID_ACC
52#include "belle_legacy/kid/kid_acc.h"
53#include "belle_legacy/kid/kid_cdc.h"
54#endif
55
56#ifdef HAVE_FINDKS
57#include "belle_legacy/findKs/findKs.h"
58#endif
59
60#ifdef HAVE_NISKSFINDER
61#include "belle_legacy/nisKsFinder/nisKsFinder.h"
62#endif
63
64#ifdef HAVE_GOODLAMBDA
65#include "belle_legacy/findLambda/findLambda.h"
66#endif
67
68#include "belle_legacy/benergy/BeamEnergy.h"
69#include "belle_legacy/ip/IpProfile.h"
70#include "belle_legacy/tables/evtcls.h"
71#include "belle_legacy/tables/trg.h"
72
73
74#include <cmath>
75#include <cfloat>
76#include <bitset>
77using namespace Belle2;
78
80
81bool approximatelyEqual(float a, float b, float epsilon)
82{
83 return fabs(a - b) <= ((fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
84}
85
86double adjustAngleRange(double phi)
87{
88 phi = phi - int(phi / TMath::TwoPi()) * TMath::TwoPi();
89 return phi - int(phi / TMath::Pi()) * TMath::TwoPi();
90}
91
92void fill7x7ErrorMatrix(const TrackFitResult* tfr, TMatrixDSym& error7x7, const double mass, const double bField)
93{
94 short charge = tfr->getChargeSign();
95
96 double d0 = tfr->getD0();
97 double phi0 = tfr->getPhi0();
98 double omega = tfr->getOmega();
99 //double z0 = tfr->getZ0();
100 double tanl = tfr->getTanLambda();
101
102 double alpha = tfr->getHelix().getAlpha(bField);
103
104 double cosPhi0 = TMath::Cos(phi0);
105 double sinPhi0 = TMath::Sin(phi0);
106
107 double rho;
108 if (omega != 0)
109 rho = 1.0 / alpha / omega;
110 else
111 rho = (DBL_MAX);
112
113 double energy = TMath::Sqrt(mass * mass + (1.0 + tanl * tanl) * rho * rho);
114
115 const int iPx = 0;
116 const int iPy = 1;
117 const int iPz = 2;
118 const int iE = 3;
119 const int iX = 4;
120 const int iY = 5;
121 const int iZ = 6;
122
123 const int iD0 = 0;
124 const int iPhi0 = 1;
125 const int iOmega = 2;
126 const int iZ0 = 3;
127 const int iTanl = 4;
128
129 TMatrixD jacobian(7, 5);
130 jacobian.Zero();
131
132 jacobian(iPx, iPhi0) = - fabs(rho) * sinPhi0;
133 jacobian(iPx, iOmega) = - charge * rho * rho * cosPhi0 * alpha;
134 jacobian(iPy, iPhi0) = fabs(rho) * cosPhi0;
135 jacobian(iPy, iOmega) = - charge * rho * rho * sinPhi0 * alpha;
136 jacobian(iPz, iOmega) = - charge * rho * rho * tanl * alpha;
137 jacobian(iPz, iTanl) = fabs(rho);
138 if (omega != 0 && energy != 0) {
139 jacobian(iE, iOmega) = - (1.0 + tanl * tanl) * rho * rho / omega / energy;
140 jacobian(iE, iTanl) = tanl * rho * rho / energy;
141 } else {
142 jacobian(iE, iOmega) = (DBL_MAX);
143 jacobian(iE, iTanl) = (DBL_MAX);
144 }
145 jacobian(iX, iD0) = sinPhi0;
146 jacobian(iX, iPhi0) = d0 * cosPhi0;
147 jacobian(iY, iD0) = - cosPhi0;
148 jacobian(iY, iPhi0) = d0 * sinPhi0;
149 jacobian(iZ, iZ0) = 1.0;
150
151 TMatrixDSym error5x5 = tfr->getCovariance5();
152
153 error7x7 = error5x5.Similarity(jacobian);
154}
155//-----------------------------------------------------------------
156// Register the Module
157//-----------------------------------------------------------------
158REG_MODULE(B2BIIConvertMdst);
159
160//-----------------------------------------------------------------
161// Implementation
162//-----------------------------------------------------------------
163
165 m_mcMatchingMode(c_Direct)
166{
167 //Set module properties
168 setDescription("Converts Belle mDST objects (Panther tables and records) to Belle II mDST objects.");
169
170 addParam("convertBeamParameters", m_convertBeamParameters,
171 "Convert beam parameters or use information stored in "
172 "Belle II database.", true);
173 addParam("use6x6CovarianceMatrix4Tracks", m_use6x6CovarianceMatrix4Tracks,
174 "Use 6x6 (position, momentum) covariance matrix for charged tracks instead of 5x5 (helix parameters) covariance matrix", false);
175 addParam("mcMatchingMode", m_mcMatchingModeString,
176 "MC matching mode: 'Direct', or 'GeneratorLevel'",
177 std::string("Direct"));
178 addParam("matchType2E9oE25Threshold", m_matchType2E9oE25Threshold,
179 "clusters with a E9/E25 value above this threshold are classified as neutral even if tracks are matched to their connected region (matchType == 2)",
180 -1.1);
181
182 addParam("convertEvtcls", m_convertEvtcls, "Flag to switch on conversion of Mdst_evtcls", true);
183 addParam("nisKsInfo", m_nisEnable, "Flag to switch on conversion of nisKsFinder info", true);
184 addParam("RecTrg", m_convertRecTrg, "Flag to switch on conversion of rectrg_summary3", false);
185 addParam("TrkExtra", m_convertTrkExtra, " Flag to switch on conversion of first_x,y,z and last_x,y,z from Mdst_trk_fit", true);
186 addParam("convertNbar", m_convertNbar, " Flag to switch on conversion of nbar:mdst (copy from gamma:mdst)", false);
187
188 m_realData = false;
189
190 B2DEBUG(1, "B2BIIConvertMdst: Constructor done.");
191}
192
193
195{
196}
197
199{
200 // Initialize Belle II DataStore
202 if (m_mcMatchingModeString == "Direct")
204 else if (m_mcMatchingModeString == "GeneratorLevel")
206 else
207 B2FATAL("Unknown MC matching mode: " << m_mcMatchingModeString);
208 B2INFO("B2BIIConvertMdst: initialized.");
209 if (!m_nisEnable)
210 B2WARNING("nisKsFinder output has been disabled. ksnbVLike, ksnbNoLam, ksnbStandard will not be converted.");
211}
212
214{
215 B2DEBUG(99, "[B2BIIConvertMdstModule::initializeDataStore] initialization of DataStore started");
216
217 // list here all converted Belle2 objects
218 m_eclClusters.registerInDataStore();
219 m_klmClusters.registerInDataStore();
220 m_tracks.registerInDataStore();
221 m_trackFitResults.registerInDataStore();
222 m_v0s.registerInDataStore();
224
226 extraInfoMap.registerInDataStore();
227
228 if (m_convertEvtcls || m_convertRecTrg) m_evtInfo.isRequired();
229
230 if (m_convertTrkExtra) m_belleTrkExtra.registerInDataStore();
231
232 StoreObjPtr<ParticleList> gammaParticleList("gamma:mdst");
233 gammaParticleList.registerInDataStore();
234 StoreObjPtr<ParticleList> nbarParticleList("anti-n0:mdst");
235 nbarParticleList.registerInDataStore();
236 StoreObjPtr<ParticleList> pi0ParticleList("pi0:mdst");
237 pi0ParticleList.registerInDataStore();
238 StoreObjPtr<ParticleList> kShortParticleList("K_S0:mdst");
239 kShortParticleList.registerInDataStore();
240 StoreObjPtr<ParticleList> kLongParticleList("K_L0:mdst");
241 kLongParticleList.registerInDataStore();
242 StoreObjPtr<ParticleList> lambdaParticleList("Lambda0:mdst");
243 lambdaParticleList.registerInDataStore();
244 StoreObjPtr<ParticleList> antiLambdaParticleList("anti-Lambda0:mdst");
245 antiLambdaParticleList.registerInDataStore();
246 StoreObjPtr<ParticleList> gammaConversionsParticleList("gamma:v0mdst");
247 gammaConversionsParticleList.registerInDataStore();
248
249 m_pidLikelihoods.registerInDataStore();
250
251 // needs to be registered, even if running over data, since this information is available only at the begin_run function
253
254 //list here all Relations between Belle2 objects
255 m_tracks.registerRelationTo(m_mcParticles);
256 m_tracks.registerRelationTo(m_pidLikelihoods);
257 if (m_convertTrkExtra) m_tracks.registerRelationTo(m_belleTrkExtra);
258 m_eclClusters.registerRelationTo(m_mcParticles);
259 m_tracks.registerRelationTo(m_eclClusters);
260 m_klmClusters.registerRelationTo(m_tracks);
261 m_klmClusters.registerRelationTo(m_eclClusters);
264
265 B2DEBUG(99, "[B2BIIConvertMdstModule::initializeDataStore] initialization of DataStore ended");
266}
267
268
270{
271 B2DEBUG(99, "B2BIIConvertMdst: beginRun called.");
272
274 //BeamEnergy class updated by fixmdst module in beginRun()
275 Belle::BeamEnergy::begin_run();
277 Belle::BeamEnergy::dump();
278
279 // load IP data from DB server
280 Belle::IpProfile::begin_run();
281 convertIPProfile(true);
282 Belle::IpProfile::dump();
283 bool usableIP = Belle::IpProfile::usable();
284 B2DEBUG(99, "B2BIIConvertMdst: IpProfile is usable = " << usableIP);
285 }
286
287 //init eID
288#ifdef HAVE_EID
289 Belle::eid::init_data();
290 Belle::eid::show_use("ALL");
291#endif
292}
293
294
296{
298 // Are we running on MC or DATA?
299 Belle::Belle_event_Manager& evman = Belle::Belle_event_Manager::get_manager();
300 Belle::Belle_event& evt = evman[0];
301
302 if (evt.ExpMC() == 2)
303 m_realData = false; // <- this is MC sample
304 else
305 m_realData = true; // <- this is real data sample
306
307 // 0. Convert IPProfile to BeamSpot
309
310 // Make sure beam parameters are correct: if they are not found in the
311 // database or different from the ones in the database we need to override them
312 if (!m_beamSpotDB || !(m_beamSpot == *m_beamSpotDB) ||
315 B2INFO("No database entry for this run yet, create one");
317 IntervalOfValidity iov(event->getExperiment(), event->getRun(), event->getExperiment(), event->getRun());
318 Database::Instance().storeData("CollisionBoostVector", &m_collisionBoostVector, iov);
319 Database::Instance().storeData("CollisionInvariantMass", &m_collisionInvM, iov);
320 Database::Instance().storeData("CollisionAxisCMS", &m_collisionAxisCMS, iov);
321 Database::Instance().storeData("BeamSpot", &m_beamSpot, iov);
322 }
323 if (m_realData) {
324 B2ERROR("BeamParameters from condition database are different from converted "
325 "ones, overriding database. Did you make sure the globaltag B2BII is used?");
326 } else {
327 B2INFO("BeamSpot, BoostVector, and InvariantMass from condition database are different from converted "
328 "ones, overriding database");
329 }
331 B2FATAL("Cannot reliably override the Database content in parallel processing "
332 "mode, please run the conversion in single processing mode");
333 }
335 DBStore::Instance().addConstantOverride("CollisionInvariantMass", new CollisionInvariantMass(m_collisionInvM), true);
338 }
339 }
340
341 // 1. Convert MC information
343
344 // 2. Convert Tracking information
346
347 // 3. Convert ECL information
349
350 // 4. Convert KLM information
352
353 // 5. Set Track -> ECLCluster relations
355
356 // 6. Set KLMCluster -> Track, ECLCluster relations
358
359 // 7. Convert Gamma information
361
362 // 8. Convert Pi0 information
364
365 // 9. Convert V0s
367
368 // 10. Convert KLong information
370
371 // 11. Convert Evtcls panther table information
373
374 // 12. Convert trigger information from rectrg_summary3
376
377 // 13. Copy nbar from Gamma with the cut E > 0.5 GeV
379
380}
381
382
383//-----------------------------------------------------------------------------
384// CONVERT TABLES
385//-----------------------------------------------------------------------------
387{
388 const double Eher = Belle::BeamEnergy::E_HER();
389 const double Eler = Belle::BeamEnergy::E_LER();
390 const double crossingAngle = Belle::BeamEnergy::Cross_angle();
391 const double angleLer = M_PI; //parallel to negative z axis (different from Belle II!)
392 const double angleHer = crossingAngle; //in positive z and x direction, verified to be consistent with Upsilon(4S) momentum
393 const double mass_e = Const::electronMass; //mass of electron: 0.0 in basf, 0.000510998902 in basf2;
394 TMatrixDSym covariance(3); //0 entries = no error
395 HepLorentzVector p_beam = Belle::BeamEnergy::p_beam(); // Testing only
396
397 // Get four momentum of LER and HER
398 ROOT::Math::PxPyPzEVector P_her(0.0, 0.0, TMath::Sqrt(Eher * Eher - mass_e * mass_e), Eher);
399 ROOT::Math::RotationY rotateAroundYAxis(angleHer);
400 P_her = rotateAroundYAxis(P_her);
401 ROOT::Math::PxPyPzEVector P_ler(0.0, 0.0, TMath::Sqrt(Eler * Eler - mass_e * mass_e), Eler);
402 rotateAroundYAxis.SetAngle(angleLer);
403 P_ler = rotateAroundYAxis(P_ler);
404
405 // Get four momentum of beam
406 ROOT::Math::PxPyPzEVector P_beam = P_her + P_ler;
407
408 ROOT::Math::PxPyPzEVector momentumHER = P_her;
409 ROOT::Math::VectorUtil::boost(momentumHER, -P_beam.BoostToCM());
410 double angleXZ = std::atan(momentumHER.X() / momentumHER.Z());
411 double angleYZ = std::atan(momentumHER.Y() / momentumHER.Z());
412
413 m_collisionBoostVector.setBoost(B2Vector3D(-P_beam.BoostToCM()), covariance);
414 m_collisionInvM.setMass(P_beam.M(), 0.0, 0.0);
415 m_collisionAxisCMS.setAngles(angleXZ, angleYZ, TMatrixTSym<double>(2));
416 m_collisionAxisCMS.setSpread(TMatrixTSym<double>(2), 0, 0, 0);
417
418 B2DEBUG(99, "Beam Energy: E_HER = " << Eher << "; E_LER = " << Eler << "; angle = " << crossingAngle);
419 B2DEBUG(99, "Beam Momentum (pre-convert) : P_X = " << p_beam.px() << "; P_Y = " << p_beam.py() << "; P_Z = " << p_beam.pz());
420 B2DEBUG(99, "Beam Momentum (post-convert) : P_X = " << P_beam.Px() << "; P_Y = " << P_beam.Py() << "; P_Z = " << P_beam.Pz());
421 B2DEBUG(99, "CollisionAxisCMS: angleXZ = " << m_collisionAxisCMS.getAngleXZ() << "; angleYZ = " << m_collisionAxisCMS.getAngleYZ());
422}
423
425{
426 if (!Belle::IpProfile::usable()) {
427 // No IPProfile for this run ...
428 if (beginRun) {
429 // no IPProfile, set vertex to NaN without errors for the full run
431 TVector3(std::numeric_limits<double>::quiet_NaN(),
432 std::numeric_limits<double>::quiet_NaN(),
433 std::numeric_limits<double>::quiet_NaN()
434 ), TMatrixTSym<double>()
435 );
436 }
437 return;
438 }
439 HepPoint3D ip;
440 CLHEP::HepSymMatrix ipErr;
441 if (beginRun) {
442 // use event independent average in begin run
443 ip = Belle::IpProfile::position();
444 ipErr = Belle::IpProfile::position_err();
445 } else {
446 // update evtbin
447 Belle::IpProfile::set_evtbin_number();
448 // check if it changed, if not there's nothing to do
449 if (Belle::IpProfile::EvtBinNo() == m_lastIPProfileBin) return;
450 // get event dependent position and error
451 ip = Belle::IpProfile::e_position();
452 ipErr = Belle::IpProfile::e_position_err();
453 }
454 // reset last ipprofile bin
455 m_lastIPProfileBin = Belle::IpProfile::EvtBinNo();
456
457 TMatrixDSym cov(ipErr.num_col());
458 for (int i = 0; i < ipErr.num_row(); ++i) {
459 for (int j = 0; j < ipErr.num_col(); ++j) {
460 cov(i, j) = ipErr(i + 1, j + 1);
461 }
462 }
463 m_beamSpot.setIP(TVector3(ip.x(), ip.y(), ip.z()), cov);
464}
465
467{
468 // Relations
469 RelationArray tracksToMCParticles(m_tracks, m_mcParticles);
470
471 // Loop over all Belle charged tracks
472 Belle::Mdst_charged_Manager& m = Belle::Mdst_charged_Manager::get_manager();
473 for (Belle::Mdst_charged_Manager::iterator chargedIterator = m.begin(); chargedIterator != m.end(); ++chargedIterator) {
474 Belle::Mdst_charged belleTrack = *chargedIterator;
475
476 Belle::Mdst_trk& trk = belleTrack.trk();
477 bool foundValidTrackFitResult = false;
478 for (int mhyp = 0 ; mhyp < c_nHyp; ++mhyp) {
479 Belle::Mdst_trk_fit& trk_fit = trk.mhyp(mhyp);
480
481 double pValue = TMath::Prob(trk_fit.chisq(), trk_fit.ndf());
482 if (std::isnan(pValue)) continue;
483 foundValidTrackFitResult = true;
484 }
485 if (not foundValidTrackFitResult) continue;
486
487 auto track = m_tracks.appendNew();
488
489 // convert MDST_Charged -> Track
490 convertMdstChargedObject(belleTrack, track);
491
492 convertPIDData(belleTrack, track);
493
494 if (m_realData)
495 continue;
496
497 // create Track -> MCParticle relation
498 // step 1: MDSTCharged -> Gen_hepevt
499 const Belle::Gen_hepevt& hep0 = get_hepevt(belleTrack);
500 if (hep0 == 0)
501 continue;
502 const Belle::Gen_hepevt* hep = nullptr;
503 switch (m_mcMatchingMode) {
504 case c_Direct:
505 hep = &hep0;
506 break;
507 case c_GeneratorLevel:
508 hep = &gen_level(hep0);
509 break;
510 }
511 // step 2: Gen_hepevt -> MCParticle
512 if (genHepevtToMCParticle.count(hep->get_ID()) > 0) {
513 int matchedMCParticle = genHepevtToMCParticle[hep->get_ID()];
514
515 // step 3: set the relation
516 tracksToMCParticles.add(track->getArrayIndex(), matchedMCParticle);
517
518 testMCRelation(*hep, m_mcParticles[matchedMCParticle], "Track");
519 } else {
520 B2DEBUG(99, "Can not find MCParticle corresponding to this gen_hepevt (Panther ID = " << hep->get_ID() << ")");
521 B2DEBUG(99, "Gen_hepevt: Panther ID = " << hep->get_ID() << "; idhep = " << hep->idhep() << "; isthep = " << hep->isthep());
522 }
523 }
524}
525
527{
528 // Create and initialize K_S0 particle list
529 StoreObjPtr<ParticleList> ksPList("K_S0:mdst");
530 ksPList.create();
531 ksPList->initialize(310, ksPList.getName());
532
533 // Create and initialize Lambda0 and anti-Lamda0 particle list
534 StoreObjPtr<ParticleList> lambda0PList("Lambda0:mdst");
535 lambda0PList.create();
536 lambda0PList->initialize(3122, lambda0PList.getName());
537
538 StoreObjPtr<ParticleList> antiLambda0PList("anti-Lambda0:mdst");
539 antiLambda0PList.create();
540 antiLambda0PList->initialize(-3122, antiLambda0PList.getName());
541
542 antiLambda0PList->bindAntiParticleList(*lambda0PList);
543
544 // Create and initialize converted gamma particle list
545 StoreObjPtr<ParticleList> convGammaPList("gamma:v0mdst");
546 convGammaPList.create();
547 convGammaPList->initialize(22, convGammaPList.getName());
548
549 // Loop over all Belle Vee2 candidates
550 Belle::Mdst_vee2_Manager& m = Belle::Mdst_vee2_Manager::get_manager();
551 for (Belle::Mdst_vee2_Manager::iterator vee2Iterator = m.begin(); vee2Iterator != m.end(); ++vee2Iterator) {
552 Belle::Mdst_vee2 belleV0 = *vee2Iterator;
553
554 // +ve track
555 Belle::Mdst_charged belleTrackP = belleV0.chgd(0);
556 // -ve track
557 Belle::Mdst_charged belleTrackM = belleV0.chgd(1);
558
559 // type of V0
562 int belleHypP = -1;
563 int belleHypM = -1;
564
565 switch (belleV0.kind()) {
566 case 1 : // K0s -> pi+ pi-
567 pTypeP = Const::pion;
568 pTypeM = Const::pion;
569 belleHypP = 2;
570 belleHypM = 2;
571 break;
572 case 2 : // Lambda -> p+ pi-
573 pTypeP = Const::proton;
574 pTypeM = Const::pion;
575 belleHypP = 4;
576 belleHypM = 2;
577 break;
578 case 3 : // anti-Lambda -> pi+ anti-p-
579 pTypeP = Const::pion;
580 pTypeM = Const::proton;
581 belleHypP = 2;
582 belleHypM = 4;
583 break;
584 case 4 : // gamma -> e+ e-
585 pTypeP = Const::electron;
586 pTypeM = Const::electron;
587 belleHypP = 0;
588 belleHypM = 0;
589 break;
590 default :
591 B2WARNING("Conversion of vee2 candidate of unknown kind! kind = " << belleV0.kind());
592 }
593
594 // This part is copied from Relation.cc in BASF
595 int trackID[2] = {0, 0};
596 unsigned nTrack = 0;
597 Belle::Mdst_charged_Manager& charged_mag = Belle::Mdst_charged_Manager::get_manager();
598 for (std::vector<Belle::Mdst_charged>::iterator chgIterator = charged_mag.begin(); chgIterator != charged_mag.end();
599 ++chgIterator) {
600 if (belleV0.chgd(0).get_ID() >= 1 && trackID[0] == 0 && belleV0.chgd(0).get_ID() == chgIterator->get_ID()) {
601 trackID[0] = (int)(chgIterator->get_ID()); //+ve trac
602 ++nTrack;
603 }
604 if (belleV0.chgd(1).get_ID() >= 1 && trackID[1] == 0 && belleV0.chgd(1).get_ID() == chgIterator->get_ID()) {
605 trackID[1] = (int)(chgIterator->get_ID()); //-ve trac
606 ++nTrack;
607 }
608 if (nTrack == 2)
609 break;
610 }
611 if (std::max(trackID[0], trackID[1]) > m_tracks.getEntries()) continue;
612
613 HepPoint3D dauPivot(belleV0.vx(), belleV0.vy(), belleV0.vz());
614 int trackFitPIndex = -1;
615 int trackFitMIndex = -1;
616 Particle daughterP, daughterM;
617 CLHEP::HepLorentzVector momentumP;
618 CLHEP::HepSymMatrix error7x7P(7, 0);
619 HepPoint3D positionP;
620 TMatrixFSym errMatrixP(7);
621 CLHEP::HepLorentzVector momentumM;
622 CLHEP::HepSymMatrix error7x7M(7, 0);
623 HepPoint3D positionM;
624 TMatrixFSym errMatrixM(7);
625 CLHEP::HepSymMatrix error5x5(5, 0);
626 if (trackID[0] >= 1) {
627 if (belleV0.daut()) {
628 std::vector<float> helixParam(5);
629 std::vector<float> helixError(15);
630 belleVeeDaughterHelix(belleV0, 1, helixParam, helixError);
631
632 auto trackFitP = m_trackFitResults.appendNew(helixParam, helixError, pTypeP, 0.5, -1, -1, 0);
633 trackFitPIndex = trackFitP->getArrayIndex();
634
635 belleVeeDaughterToCartesian(belleV0, 1, pTypeP, momentumP, positionP, error7x7P);
636 TrackFitResult* tmpTFR = new TrackFitResult(createTrackFitResult(momentumP, positionP, error7x7P, 1, pTypeP, 0.5, -1, -1, 0));
637 // TrackFitResult internally stores helix parameters at pivot = (0,0,0) so the momentum of the Particle will be wrong again.
638 // Overwrite it.
639
640 for (unsigned i = 0; i < 7; i++)
641 for (unsigned j = 0; j < 7; j++)
642 errMatrixP(i, j) = error7x7P[i][j];
643
644 daughterP = Particle(trackID[0] - 1, tmpTFR, pTypeP);
645 daughterP.updateMomentum(ROOT::Math::PxPyPzEVector(momentumP.px(), momentumP.py(), momentumP.pz(), momentumP.e()),
646 ROOT::Math::XYZVector(positionP.x(), positionP.y(), positionP.z()),
647 errMatrixP, 0.5);
648 delete tmpTFR;
649 } else {
650 Belle::Mdst_trk_fit& trk_fit = charged_mag[trackID[0] - 1].trk().mhyp(belleHypP);
651 double pValue = TMath::Prob(trk_fit.chisq(), trk_fit.ndf());
652 if (std::isnan(pValue)) continue;
653
654 std::vector<float> helixParam(5);
655 std::vector<float> helixError(15);
656 convertHelix(trk_fit, HepPoint3D(0., 0., 0.), helixParam, helixError);
657
658 // Checking for invalid helix curvature with parameter 2 equal to 0:
659 if (helixParam[2] == 0) {
660 B2WARNING("Helix parameter for curvature == 0. Skipping Track! The parameter is: " << helixParam[2] << "...");
661 continue;
662 }
663
664 auto trackFitP = m_trackFitResults.appendNew(helixParam, helixError, pTypeP, pValue, -1, -1, 0);
665
666 trackFitPIndex = trackFitP->getArrayIndex();
667
668 daughterP = Particle(trackID[0] - 1, trackFitP, pTypeP);
669 // set momentum/positions at pivot = V0 decay vertex
670 getHelixParameters(trk_fit, pTypeP.getMass(), dauPivot,
671 helixParam, error5x5,
672 momentumP, positionP, error7x7P);
673
674 for (unsigned i = 0; i < 7; i++)
675 for (unsigned j = 0; j < 7; j++)
676 errMatrixP(i, j) = error7x7P[i][j];
677
678 daughterP.updateMomentum(ROOT::Math::PxPyPzEVector(momentumP.px(), momentumP.py(), momentumP.pz(), momentumP.e()),
679 ROOT::Math::XYZVector(positionP.x(), positionP.y(), positionP.z()),
680 errMatrixP, pValue);
681 }
682 }
683 if (trackID[1] >= 1) {
684 if (belleV0.daut()) {
685 std::vector<float> helixParam(5);
686 std::vector<float> helixError(15);
687 belleVeeDaughterHelix(belleV0, -1, helixParam, helixError);
688
689 auto trackFitM = m_trackFitResults.appendNew(helixParam, helixError, pTypeM, 0.5, -1, -1, 0);
690 trackFitMIndex = trackFitM->getArrayIndex();
691
692 belleVeeDaughterToCartesian(belleV0, -1, pTypeM, momentumM, positionM, error7x7M);
693 TrackFitResult* tmpTFR = new TrackFitResult(createTrackFitResult(momentumM, positionM, error7x7M, -1, pTypeM, 0.5, -1, -1, 0));
694 // TrackFitResult internally stores helix parameters at pivot = (0,0,0) so the momentum of the Particle will be wrong again.
695 // Overwrite it.
696 for (unsigned i = 0; i < 7; i++)
697 for (unsigned j = 0; j < 7; j++)
698 errMatrixM(i, j) = error7x7M[i][j];
699
700 daughterM = Particle(trackID[1] - 1, tmpTFR, pTypeM);
701 daughterM.updateMomentum(ROOT::Math::PxPyPzEVector(momentumM.px(), momentumM.py(), momentumM.pz(), momentumM.e()),
702 ROOT::Math::XYZVector(positionM.x(), positionM.y(), positionM.z()),
703 errMatrixM, 0.5);
704 delete tmpTFR;
705 } else {
706 Belle::Mdst_trk_fit& trk_fit = charged_mag[trackID[1] - 1].trk().mhyp(belleHypM);
707 double pValue = TMath::Prob(trk_fit.chisq(), trk_fit.ndf());
708 if (std::isnan(pValue)) continue;
709
710 std::vector<float> helixParam(5);
711 std::vector<float> helixError(15);
712 convertHelix(trk_fit, HepPoint3D(0., 0., 0.), helixParam, helixError);
713
714 // Checking for invalid helix curvature with parameter 2 equal to 0:
715 if (helixParam[2] == 0) {
716 B2WARNING("Helix parameter for curvature == 0. Skipping Track! The parameter is: " << helixParam[2] << "...");
717 continue;
718 }
719
720 auto trackFitM = m_trackFitResults.appendNew(helixParam, helixError, pTypeM, pValue, -1, -1, 0);
721
722 trackFitMIndex = trackFitM->getArrayIndex();
723
724 daughterM = Particle(trackID[1] - 1, trackFitM, pTypeM);
725 // set momentum/positions at pivot = V0 decay vertex
726 getHelixParameters(trk_fit, pTypeM.getMass(), dauPivot,
727 helixParam, error5x5,
728 momentumM, positionM, error7x7M);
729
730 for (unsigned i = 0; i < 7; i++)
731 for (unsigned j = 0; j < 7; j++)
732 errMatrixM(i, j) = error7x7M[i][j];
733
734 daughterM.updateMomentum(ROOT::Math::PxPyPzEVector(momentumM.px(), momentumM.py(), momentumM.pz(), momentumM.e()),
735 ROOT::Math::XYZVector(positionM.x(), positionM.y(), positionM.z()),
736 errMatrixM, pValue);
737 }
738 }
739
740 Track* trackP = m_tracks[trackID[0] - 1];
741 Track* trackM = m_tracks[trackID[1] - 1];
742
743 TrackFitResult* trackFitP = m_trackFitResults[trackFitPIndex];
744 TrackFitResult* trackFitM = m_trackFitResults[trackFitMIndex];
745
746 m_v0s.appendNew(std::make_pair(trackP, trackFitP), std::make_pair(trackM, trackFitM), belleV0.vx(), belleV0.vy(), belleV0.vz());
747
748 // create Ks Particle and add it to the 'K_S0:mdst' ParticleList
749 const PIDLikelihood* pidP = trackP->getRelated<PIDLikelihood>();
750 const PIDLikelihood* pidM = trackM->getRelated<PIDLikelihood>();
751 const MCParticle* mcParticleP = trackP->getRelated<MCParticle>();
752 const MCParticle* mcParticleM = trackM->getRelated<MCParticle>();
753
754 Particle* newDaugP = m_particles.appendNew(daughterP);
755 if (pidP)
756 newDaugP->addRelationTo(pidP);
757 if (mcParticleP)
758 newDaugP->addRelationTo(mcParticleP);
759 Particle* newDaugM = m_particles.appendNew(daughterM);
760 if (pidM)
761 newDaugM->addRelationTo(pidM);
762 if (mcParticleM)
763 newDaugM->addRelationTo(mcParticleM);
764
765 ROOT::Math::PxPyPzEVector v0Momentum(belleV0.px(), belleV0.py(), belleV0.pz(), belleV0.energy());
766 ROOT::Math::XYZVector v0Vertex(belleV0.vx(), belleV0.vy(), belleV0.vz());
767
768 /*
769 * Documentation of Mdst_vee2 vertex fit:
770 * /sw/belle/belle/b20090127_0910/share/tables/mdst.tdf (L96-L125)
771 */
772 auto appendVertexFitInfo = [](Belle::Mdst_vee2 & _belle_V0, Particle & _belle2_V0) {
773 // Add chisq of vertex fit. chiSquared=10^10 means the fit fails.
774 _belle2_V0.addExtraInfo("chiSquared", _belle_V0.chisq());
775 // Ndf of the vertex kinematic fit is 1
776 _belle2_V0.addExtraInfo("ndf", 1);
777 // Add p-value to extra Info
778 double prob = TMath::Prob(_belle_V0.chisq(), 1);
779 _belle2_V0.setPValue(prob);
780 };
781
782 Particle* newV0 = nullptr;
783 if (belleV0.kind() == 1) { // K0s -> pi+ pi-
784 Particle KS(v0Momentum, 310);
785 KS.appendDaughter(newDaugP);
786 KS.appendDaughter(newDaugM);
787 KS.setVertex(v0Vertex);
788 appendVertexFitInfo(belleV0, KS);
789 newV0 = m_particles.appendNew(KS);
790 ksPList->addParticle(newV0);
791
792 // append extra info: goodKs flag
793 Belle::FindKs belleKSFinder;
794 belleKSFinder.candidates(belleV0, Belle::IpProfile::position(1));
795 newV0->addExtraInfo("goodKs", belleKSFinder.goodKs());
796
797 /*
798 std::cout << " ---- B1 Ks ---- " << std::endl;
799 std::cout << " momentum = " << std::endl;
800 v0Momentum.Print();
801 std::cout << " position = " << std::endl;
802 v0Vertex.Print();
803 std::cout << " ---- B2 Ks ---- " << std::endl;
804 std::cout << " momentum = " << std::endl;
805 newKS->get4Vector().Print();
806 std::cout << " position = " << std::endl;
807 newKS->getVertex().Print();
808 std::cout << " ---- B1 Ks.child(0) ---- " << std::endl;
809 std::cout << " momentum = " << momentumP << std::endl;
810 std::cout << " position = " << positionP << std::endl;
811 std::cout << " error7x7 = " << error7x7P << std::endl;
812 std::cout << " ---- B2 Ks.child(0) ---- " << std::endl;
813 std::cout << " momentum = " << std::endl;
814 newKS->getDaughter(0)->get4Vector().Print();
815 std::cout << " position = " << std::endl;
816 newKS->getDaughter(0)->getVertex().Print();
817 std::cout << " error7x7 = " << std::endl;
818 newKS->getDaughter(0)->getMomentumVertexErrorMatrix().Print();
819 std::cout << " ---- B1 Ks.child(1) ---- " << std::endl;
820 std::cout << " momentum = " << momentumM << std::endl;
821 std::cout << " position = " << positionM << std::endl;
822 std::cout << " error7x7 = " << error7x7M << std::endl;
823 std::cout << " ---- B2 Ks.child(1) ---- " << std::endl;
824 std::cout << " momentum = " << std::endl;
825 newKS->getDaughter(1)->get4Vector().Print();
826 std::cout << " position = " << std::endl;
827 newKS->getDaughter(1)->getVertex().Print();
828 std::cout << " error7x7 = " << std::endl;
829 newKS->getDaughter(1)->getMomentumVertexErrorMatrix().Print();
830 */
831 } else if (belleV0.kind() == 2) { // Lambda -> p+ pi-
832 Particle Lambda0(v0Momentum, 3122);
833 Lambda0.appendDaughter(newDaugP);
834 Lambda0.appendDaughter(newDaugM);
835 Lambda0.setVertex(v0Vertex);
836 appendVertexFitInfo(belleV0, Lambda0);
837 newV0 = m_particles.appendNew(Lambda0);
838 lambda0PList->addParticle(newV0);
839
840 // GoodLambda flag as extra info
841 Belle::FindLambda lambdaFinder;
842 lambdaFinder.candidates(belleV0, Belle::IpProfile::position(1));
843 newV0->addExtraInfo("goodLambda", lambdaFinder.goodLambda());
844 } else if (belleV0.kind() == 3) { // anti-Lambda -> pi+ anti-p
845 Particle antiLambda0(v0Momentum, -3122);
846 antiLambda0.appendDaughter(newDaugM);
847 antiLambda0.appendDaughter(newDaugP);
848 antiLambda0.setVertex(v0Vertex);
849 appendVertexFitInfo(belleV0, antiLambda0);
850 newV0 = m_particles.appendNew(antiLambda0);
851 antiLambda0PList->addParticle(newV0);
852
853 // GoodLambda flag as extra info
854 Belle::FindLambda lambdaFinder;
855 lambdaFinder.candidates(belleV0, Belle::IpProfile::position(1));
856 newV0->addExtraInfo("goodLambda", lambdaFinder.goodLambda());
857 } else if (belleV0.kind() == 4) { // gamma -> e+ e-
858 Particle gamma(v0Momentum, 22);
859 gamma.appendDaughter(newDaugP);
860 gamma.appendDaughter(newDaugM);
861 gamma.setVertex(v0Vertex);
862 appendVertexFitInfo(belleV0, gamma);
863 newV0 = m_particles.appendNew(gamma);
864 convGammaPList->addParticle(newV0);
865 }
866 // append extra info: nisKsFinder quality indicators
867 if (m_nisEnable) {
868 if (belleV0.kind() > 0 and belleV0.kind() <= 3) { // K_S0, Lambda, anti-Lambda
869 Belle::nisKsFinder ksnb;
870 double protIDP = atcPID(pidP, 2, 4);
871 double protIDM = atcPID(pidM, 2, 4);
872 ksnb.candidates(belleV0, Belle::IpProfile::position(1), momentumP, protIDP, protIDM);
873 // K_S0 and Lambda (inverse cut on ksnbNoLam for Lambda selection).
874 newV0->addExtraInfo("ksnbVLike", ksnb.nb_vlike());
875 newV0->addExtraInfo("ksnbNoLam", ksnb.nb_nolam());
876 // K_S0 only
877 if (belleV0.kind() == 1)
878 newV0->addExtraInfo("ksnbStandard", ksnb.standard());
879 }
880 }
881 }
882}
883
885{
886 if (m_realData)
887 return;
888
889 // clear the Gen_hepevt_ID <-> MCParticleGraphPosition map
890 genHepevtToMCParticle.clear();
891
892 // check if the Gen_hepevt table has any entries
893 Belle::Gen_hepevt_Manager& genMgr = Belle::Gen_hepevt_Manager::get_manager();
894 if (genMgr.count() == 0)
895 return;
896
897 typedef std::pair<MCParticleGraph::GraphParticle*, Belle::Gen_hepevt> halfFamily;
898 halfFamily currFamily;
899 halfFamily family;
900 std::queue < halfFamily > heritancesQueue;
901
902 // Add motherless particles. The root particle is often the first one,
903 // but this is not correct in general case; thus, all particles are added,
904 // including the beam-background ones.
906 for (Belle::Gen_hepevt_Manager::iterator genIterator = genMgr.begin();
907 genIterator != genMgr.end(); ++genIterator) {
908 Belle::Gen_hepevt hep = *genIterator;
909 // Select particles without mother.
910 if (!(hep.moFirst() == 0 && hep.moLast() == 0))
911 continue;
912
913 int position = m_particleGraph.size();
915 genHepevtToMCParticle[hep.get_ID()] = position;
916 MCParticleGraph::GraphParticle* graphParticle = &m_particleGraph[position];
917 convertGenHepevtObject(hep, graphParticle);
918 for (int iDaughter = hep.daFirst(); iDaughter <= hep.daLast();
919 ++iDaughter) {
920 if (iDaughter == 0) {
921 B2DEBUG(95, "Trying to access generated daughter with Panther ID == 0");
922 continue;
923 }
924 currFamily.first = graphParticle;
925 currFamily.second = genMgr(Belle::Panther_ID(iDaughter));
926 heritancesQueue.push(currFamily);
927 }
928 }
929
930 //now we can go through the queue:
931 while (!heritancesQueue.empty()) {
932 currFamily = heritancesQueue.front(); //get the first entry from the queue
933 heritancesQueue.pop(); //remove the entry.
934
935 MCParticleGraph::GraphParticle* currMother = currFamily.first;
936 Belle::Gen_hepevt& currDaughter = currFamily.second;
937
938 // Skip particles with idhep = 0.
939 if (currDaughter.idhep() == 0)
940 continue;
941
942 //putting the daughter in the graph:
943 int position = m_particleGraph.size();
945 genHepevtToMCParticle[currDaughter.get_ID()] = position;
946
947 MCParticleGraph::GraphParticle* graphDaughter = &m_particleGraph[position];
948 convertGenHepevtObject(currDaughter, graphDaughter);
949
950 //add relation between mother and daughter to graph:
951 currMother->decaysInto((*graphDaughter));
952
953 int nGrandChildren = currDaughter.daLast() - currDaughter.daFirst() + 1;
954
955 if (nGrandChildren > 0 && currDaughter.daFirst() != 0) {
956 for (int igrandchild = currDaughter.daFirst(); igrandchild <= currDaughter.daLast(); ++igrandchild) {
957 if (igrandchild == 0) {
958 B2DEBUG(95, "Trying to access generated daughter with Panther ID == 0");
959 continue;
960 }
961
962 family.first = graphDaughter;
963 family.second = genMgr(Belle::Panther_ID(igrandchild));
964 heritancesQueue.push(family);
965 }
966 }
967 }
968
970}
971
972
974{
975 // Relations
976 RelationArray eclClustersToMCParticles(m_eclClusters, m_mcParticles);
977
978 // Clear the mdstEcl <-> ECLCluster map
979 mdstEclToECLCluster.clear();
980
981 // Loop over all Belle Mdst_ecl
982 Belle::Mdst_ecl_Manager& ecl_manager = Belle::Mdst_ecl_Manager::get_manager();
983 Belle::Mdst_ecl_aux_Manager& ecl_aux_manager = Belle::Mdst_ecl_aux_Manager::get_manager();
984
985 for (Belle::Mdst_ecl_Manager::iterator eclIterator = ecl_manager.begin(); eclIterator != ecl_manager.end(); ++eclIterator) {
986
987 // Pull Mdst_ecl from manager
988 Belle::Mdst_ecl mdstEcl = *eclIterator;
989 Belle::Mdst_ecl_aux mdstEclAux(ecl_aux_manager(mdstEcl.get_ID()));
990
991 // Create Belle II ECLCluster
992 auto B2EclCluster = m_eclClusters.appendNew();
993
994 // Convert Mdst_ecl -> ECLCluster and create map of indices
995 convertMdstECLObject(mdstEcl, mdstEclAux, B2EclCluster);
996 mdstEclToECLCluster[mdstEcl.get_ID()] = B2EclCluster->getArrayIndex();
997
998 // set ConnectedRegionID and ClusterID to
999 // cluster's array index + 1 and 1, respectively
1000 B2EclCluster->setConnectedRegionId(B2EclCluster->getArrayIndex() + 1);
1001 B2EclCluster->setClusterId(1);
1002
1003 if (m_realData)
1004 continue;
1005
1006 // Create ECLCluster -> MCParticle relation
1007 // Step 1: MDST_ECL -> Gen_hepevt
1008 const Belle::Gen_hepevt& hep0 = get_hepevt(mdstEcl);
1009 if (hep0 == 0)
1010 continue;
1011 const Belle::Gen_hepevt* hep = nullptr;
1012 switch (m_mcMatchingMode) {
1013 case c_Direct:
1014 hep = &hep0;
1015 break;
1016 case c_GeneratorLevel:
1017 hep = &gen_level(hep0);
1018 break;
1019 }
1020 // Step 2: Gen_hepevt -> MCParticle
1021 if (genHepevtToMCParticle.count(hep->get_ID()) > 0) {
1022 int matchedMCParticleID = genHepevtToMCParticle[hep->get_ID()];
1023 // Step 3: set the relation
1024 eclClustersToMCParticles.add(B2EclCluster->getArrayIndex(), matchedMCParticleID);
1025 testMCRelation(*hep, m_mcParticles[matchedMCParticleID], "ECLCluster");
1026 } else {
1027 B2DEBUG(79, "Cannot find MCParticle corresponding to this gen_hepevt (Panther ID = " << hep->get_ID() << ")");
1028 B2DEBUG(79, "Gen_hepevt: Panther ID = " << hep->get_ID() << "; idhep = " << hep->idhep() << "; isthep = " << hep->isthep());
1029 }
1030 }
1031}
1032
1034{
1035 // There was no MC matching in Belle for KLM Clusters
1036
1037 // Clear the mdstKlm <-> KLMCluster map
1038 mdstKlmToKLMCluster.clear();
1039
1040 // Loop over all Belle Mdst_klm_cluster
1041 Belle::Mdst_klm_cluster_Manager& klm_cluster_manager = Belle::Mdst_klm_cluster_Manager::get_manager();
1042
1043 for (Belle::Mdst_klm_cluster_Manager::iterator klmC_Ite = klm_cluster_manager.begin(); klmC_Ite != klm_cluster_manager.end();
1044 ++klmC_Ite) {
1045
1046 // Pull Mdst_ecl from manager
1047 Belle::Mdst_klm_cluster mdstKlm_cluster = *klmC_Ite;
1048
1049 // Create Belle II ECLCluster
1050 auto B2KlmCluster = m_klmClusters.appendNew();
1051
1052 // Convert Mdst_klm_cluster -> KLMCluster and create map of indices
1053 convertMdstKLMObject(mdstKlm_cluster, B2KlmCluster);
1054 mdstKlmToKLMCluster[mdstKlm_cluster.get_ID()] = B2KlmCluster->getArrayIndex();
1055
1056 }
1057}
1058
1059
1061{
1062 // Relations
1063 RelationArray particlesToMCParticles(m_particles, m_mcParticles);
1064
1065 // Clear the mdstGamma <-> Particle map
1066 mdstGammaToParticle.clear();
1067
1068 // Create and initialize particle list
1069 StoreObjPtr<ParticleList> plist("gamma:mdst");
1070 plist.create();
1071 plist->initialize(22, "gamma:mdst");
1072
1073 // Loop over all Belle Mdst_gamma
1074 Belle::Mdst_gamma_Manager& gamma_manager = Belle::Mdst_gamma_Manager::get_manager();
1075
1076 for (Belle::Mdst_gamma_Manager::iterator gammaIterator = gamma_manager.begin(); gammaIterator != gamma_manager.end();
1077 ++gammaIterator) {
1078
1079 // Pull Mdst_gamma from manager and Mdst_ecl from pointer to Mdst_ecl
1080 Belle::Mdst_gamma mdstGamma = *gammaIterator;
1081 Belle::Mdst_ecl mdstEcl = mdstGamma.ecl();
1082 if (!mdstEcl)
1083 continue;
1084
1085 // Get ECLCluster from map
1086 ECLCluster* B2EclCluster = m_eclClusters[mdstEclToECLCluster[mdstEcl.get_ID()]];
1087 if (!B2EclCluster)
1088 continue;
1089
1090 // Create Particle from ECLCluster, add to StoreArray, create gamma map entry
1091 Particle* B2Gamma = m_particles.appendNew(B2EclCluster);
1092 mdstGammaToParticle[mdstGamma.get_ID()] = B2Gamma->getArrayIndex();
1093
1094 // Add particle to particle list
1095 plist->addParticle(B2Gamma);
1096
1097 if (m_realData)
1098 continue;
1099
1100 // Relation to MCParticle
1101 MCParticle* matchedMCParticle = B2EclCluster->getRelated<MCParticle>();
1102 if (matchedMCParticle)
1103 B2Gamma->addRelationTo(matchedMCParticle);
1104 }
1105}
1106
1108{
1109 StoreObjPtr<ParticleList> plist("anti-n0:mdst");
1110 plist.create();
1111 plist->initialize(Const::antiNeutron.getPDGCode(), "anti-n0:mdst");
1112
1113 B2DEBUG(99, "Getting gamma:mdst in copyNbarFromGamma");
1114 StoreObjPtr<ParticleList> plist_gamma("gamma:mdst");
1115 for (const Particle& gamma : *plist_gamma) {
1116 auto* eclCluster = gamma.getECLCluster();
1117 // Pre-select energetic gamma
1118 if (eclCluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons) <= 0.5) continue;
1119 B2DEBUG(99, "Copying anti-n0:mdst from gamma:mdst");
1120 Particle* nbar = m_particles.appendNew(eclCluster, Const::antiNeutron);
1121 plist->addParticle(nbar);
1122
1123 if (m_realData)
1124 continue;
1125
1126 // Relation to MCParticle
1127 MCParticle* matchedMCParticle = eclCluster->getRelated<MCParticle>();
1128 if (matchedMCParticle)
1129 nbar->addRelationTo(matchedMCParticle);
1130 }
1131}
1132
1134{
1135 // Create and initialize particle list
1136 StoreObjPtr<ParticleList> plist("pi0:mdst");
1137 plist.create();
1138 plist->initialize(111, "pi0:mdst");
1139
1140 // Loop over all Mdst_pi0
1141 Belle::Mdst_pi0_Manager& pi0_manager = Belle::Mdst_pi0_Manager::get_manager();
1142 for (Belle::Mdst_pi0_Manager::iterator pi0Iterator = pi0_manager.begin(); pi0Iterator != pi0_manager.end(); ++pi0Iterator) {
1143
1144 // Pull Mdst_pi0 from manager and Mdst_gammas from pointers to Mdst_gammas
1145 Belle::Mdst_pi0 mdstPi0 = *pi0Iterator;
1146 Belle::Mdst_gamma mdstGamma1 = mdstPi0.gamma(0);
1147 Belle::Mdst_gamma mdstGamma2 = mdstPi0.gamma(1);
1148 if (!mdstGamma1 || !mdstGamma2)
1149 continue;
1150
1151 ROOT::Math::PxPyPzEVector p4(mdstPi0.px(), mdstPi0.py(), mdstPi0.pz(), mdstPi0.energy());
1152
1153 // Create Particle from LorentzVector and PDG code, add to StoreArray
1154 Particle* B2Pi0 = m_particles.appendNew(p4, 111);
1155
1156 // Get Belle II photons from map
1157 Particle* B2Gamma1 = m_particles[mdstGammaToParticle[mdstGamma1.get_ID()]];
1158 Particle* B2Gamma2 = m_particles[mdstGammaToParticle[mdstGamma2.get_ID()]];
1159 if (!B2Gamma1 || !B2Gamma2)
1160 continue;
1161
1162 // Append photons as pi0 daughters
1163 B2Pi0->appendDaughter(B2Gamma1);
1164 B2Pi0->appendDaughter(B2Gamma2);
1165
1166 // Add chisq of mass-constrained Kfit
1167 B2Pi0->addExtraInfo("chiSquared", mdstPi0.chisq());
1168
1169 // Ndf of a pi0 mass-constrained kinematic fit is 1
1170 B2Pi0->addExtraInfo("ndf", 1);
1171
1172 // Add p-value to extra Info
1173 double prob = TMath::Prob(mdstPi0.chisq(), 1);
1174 B2Pi0->setPValue(prob);
1175
1176 // Add particle to particle list
1177 plist->addParticle(B2Pi0);
1178 }
1179}
1180
1182{
1183 // Relations
1184 RelationArray particlesToMCParticles(m_particles, m_mcParticles);
1185
1186
1187 // Create and initialize particle list
1188 StoreObjPtr<ParticleList> plist("K_L0:mdst");
1189 plist.create();
1190 plist->initialize(Const::Klong.getPDGCode(), "K_L0:mdst");
1191
1192 Belle::Mdst_klong_Manager& klong_manager = Belle::Mdst_klong_Manager::get_manager();
1193 for (Belle::Mdst_klong_Manager::iterator klong_Ite = klong_manager.begin(); klong_Ite != klong_manager.end(); ++klong_Ite) {
1194
1195 // Pull Mdst_klong from manager and Mdst_klm from pointer to Mdst_klm
1196 Belle::Mdst_klong mdstKlong = *klong_Ite;
1197 Belle::Mdst_klm_cluster mdstKlm = mdstKlong.klmc();
1198
1199 if (!mdstKlm)
1200 continue;
1201
1202
1203 // Get KLMCluster from map
1204 KLMCluster* B2KlmCluster = m_klmClusters[mdstKlmToKLMCluster[mdstKlm.get_ID()]];
1205 if (!B2KlmCluster)
1206 continue;
1207
1208 // Extract cluster position from Klong and save it in KLMCluster
1209 B2KlmCluster->setClusterPosition(mdstKlong.cos_x(), mdstKlong.cos_y(), mdstKlong.cos_z());
1210
1211 // Create Particle from KLMCluster, add to StoreArray, create Klong map entry
1212 Particle* B2Klong = m_particles.appendNew(B2KlmCluster);
1213 mdstKlongToParticle[mdstKlong.get_ID()] = B2Klong->getArrayIndex();
1214
1215 // Add particle to particle list
1216 plist->addParticle(B2Klong);
1217 }
1218
1219 // (Vague) MC Matching
1220 // There was no MC matching for KLongs in Belle , but a hack:
1221 // Check if MC KLong and reconstructed KLong (only without ecl) are within 15 degree for phi and theta, we set a relation
1222 // for the best reconstructed KLong to the MC KLong.
1223 // Taken and adapted from http://belle.kek.jp/secured/wiki/doku.php?id=physics:ckm:kleff
1224
1225 if (!m_realData) {
1226
1227 Belle::Gen_hepevt_Manager& GenMgr = Belle::Gen_hepevt_Manager::get_manager();
1228 const double dang(15. / 180.*M_PI); // check reconstructed candidates within 15 degrees
1229
1230 for (Belle::Gen_hepevt_Manager::iterator klong_hep_it = GenMgr.begin(); klong_hep_it != GenMgr.end(); ++klong_hep_it) {
1231
1232 if (abs((*klong_hep_it).idhep()) == Const::Klong.getPDGCode() && klong_hep_it->isthep() > 0) {
1233
1234 CLHEP::HepLorentzVector gp4(klong_hep_it->PX(), klong_hep_it->PY(), klong_hep_it->PZ(), klong_hep_it->E());
1235 double sum(0.0);
1236 int bestRecKlongID(0);
1237
1238 for (Belle::Mdst_klong_Manager::iterator klong_rec_it = klong_manager.begin(); klong_rec_it != klong_manager.end();
1239 ++klong_rec_it) {
1240
1241 // if((*klong_rec_it).klmc().ecl())continue; // check only klm cand.
1242 if ((*klong_rec_it).ecl())
1243 continue; // check only klm cand.
1244 CLHEP::Hep3Vector klp3(klong_rec_it->cos_x(), klong_rec_it->cos_y(), klong_rec_it->cos_z());
1245
1246 if (cos(gp4.theta() - klp3.theta()) > cos(dang) && cos(gp4.phi() - klp3.phi()) > cos(dang)) {
1247
1248 double tmp_sum = cos(gp4.theta() - klp3.theta()) + cos(gp4.phi() - klp3.phi());
1249 if (tmp_sum > sum) {
1250 bestRecKlongID = mdstKlongToParticle[(*klong_rec_it).get_ID()];
1251 sum = tmp_sum;
1252 }
1253 }
1254
1255 }
1256 if (sum > 0.0) {
1257 int matchedMCParticleID = genHepevtToMCParticle[(*klong_hep_it).get_ID()];
1258 particlesToMCParticles.add(bestRecKlongID, matchedMCParticleID);
1259 testMCRelation((*klong_hep_it), m_mcParticles[matchedMCParticleID], "m_particles");
1260 }
1261 }
1262 }
1263 }
1264}
1265
1267{
1268 // Create StoreObj if it is not valid
1269 if (not m_evtInfo.isValid()) {
1270 m_evtInfo.create();
1271 }
1272 // Pull Evtcls_flag(2) from manager
1273 Belle::Evtcls_flag_Manager& EvtFlagMgr = Belle::Evtcls_flag_Manager::get_manager();
1274 Belle::Evtcls_flag2_Manager& EvtFlag2Mgr = Belle::Evtcls_flag2_Manager::get_manager();
1275
1276 // Pull Evtcls_hadronic_flag from manager
1277 Belle::Evtcls_hadronic_flag_Manager& EvtHadFlagMgr = Belle::Evtcls_hadronic_flag_Manager::get_manager();
1278
1279 std::string name = "evtcls_flag";
1280 std::string name_had = "evtcls_hadronic_flag";
1281 // Only one entry in each event
1282 std::vector<Belle::Evtcls_flag>::iterator eflagIterator = EvtFlagMgr.begin();
1283 std::vector<Belle::Evtcls_flag2>::iterator eflag2Iterator = EvtFlag2Mgr.begin();
1284 std::vector<Belle::Evtcls_hadronic_flag>::iterator ehadflagIterator = EvtHadFlagMgr.begin();
1285
1286 // Converting evtcls_flag(2)
1287 std::vector<int> flag(20);
1288 for (int index = 0; index < 20; ++index) {
1289 // flag(14, 16): not filled
1290 if (index == 14 || index == 16) continue;
1291 std::string iVar = name + std::to_string(index);
1292 // 0-9 corresponding to evtcls_flag.flag(0-9)
1293 if (index < 10) {
1294 m_evtInfo->addExtraInfo(iVar, (*eflagIterator).flag(index));
1295 } else {
1296 // 10-19 corresponding to evtcls_flag2.flag(0-9)
1297 m_evtInfo->addExtraInfo(iVar, (*eflag2Iterator).flag(index - 10));
1298 }
1299 B2DEBUG(99, "evtcls_flag(" << index << ") = " << m_evtInfo->getExtraInfo(iVar));
1300 }
1301
1302 // Converting evtcls_hadronic_flag
1303 for (int index = 0; index < 6; ++index) {
1304 std::string iVar = name_had + std::to_string(index);
1305 m_evtInfo->addExtraInfo(iVar, (*ehadflagIterator).hadronic_flag(index));
1306 B2DEBUG(99, "evtcls_hadronic_flag(" << index << ") = " << m_evtInfo->getExtraInfo(iVar));
1307 }
1308
1309}
1310
1312{
1313
1314 // Create StoreObj if it is not valid
1315 if (not m_evtInfo.isValid()) {
1316 m_evtInfo.create();
1317 }
1318 // Load event info
1320
1321 if (event->getExperiment() <= 27) { // Check if it's SVD 1
1322 // Pull rectrg_summary from namager
1323 Belle::Rectrg_summary_Manager& RecTrgSummaryMgr = Belle::Rectrg_summary_Manager::get_manager();
1324 std::vector<Belle::Rectrg_summary>::iterator eflagIterator = RecTrgSummaryMgr.begin();
1325 std::string name_summary = "rectrg_summary_m_final";
1326
1327 // Converting m_final(2) from rectrg_summary
1328 for (int index = 0; index < 2; ++index) {
1329 std::string iVar = name_summary + std::to_string(index);
1330 m_evtInfo->addExtraInfo(iVar, (*eflagIterator).final(index));
1331 B2DEBUG(99, "m_final(" << index << ") = " << m_evtInfo->getExtraInfo(iVar));
1332 }
1333 } else { // For SVD2
1334 // Pull rectrg_summary3 from manager
1335 Belle::Rectrg_summary3_Manager& RecTrgSummary3Mgr = Belle::Rectrg_summary3_Manager::get_manager();
1336
1337 std::string name_summary3 = "rectrg_summary3_m_final";
1338 // Only one entry in each event
1339 std::vector<Belle::Rectrg_summary3>::iterator eflagIterator3 = RecTrgSummary3Mgr.begin();
1340
1341 // Converting m_final(3)
1342 for (int index = 0; index < 3; ++index) {
1343 std::string iVar = name_summary3 + std::to_string(index);
1344 m_evtInfo->addExtraInfo(iVar, (*eflagIterator3).final(index));
1345 B2DEBUG(99, "m_final(" << index << ") = " << m_evtInfo->getExtraInfo(iVar));
1346 }
1347 }
1348
1349}
1350
1351
1352//-----------------------------------------------------------------------------
1353// CONVERT OBJECTS
1354//-----------------------------------------------------------------------------
1355
1356#ifdef HAVE_KID_ACC
1357double B2BIIConvertMdstModule::acc_pid(const Belle::Mdst_charged& chg, int idp)
1358{
1359 static Belle::kid_acc acc_pdf(0);
1360 //static kid_acc acc_pdf(1);
1361
1362 const double pmass[5] = { 0.00051099907, 0.105658389, 0.13956995, 0.493677, 0.93827231 };
1363
1364 CLHEP::Hep3Vector mom(chg.px(), chg.py(), chg.pz());
1365 double cos_theta = mom.cosTheta();
1366 double pval = mom.mag();
1367
1368 double npe = chg.acc().photo_electron();
1369 double beta = pval / sqrt(pval * pval + pmass[idp] * pmass[idp]);
1370 double pdfval = acc_pdf.npe2pdf(cos_theta, beta, npe);
1371
1372 return pdfval;
1373}
1374
1375// this is CDC_prob5
1376double B2BIIConvertMdstModule::cdc_pid(const Belle::Mdst_charged& chg, int idp)
1377{
1378 CLHEP::Hep3Vector mom(chg.px(), chg.py(), chg.pz());
1379 double pval = mom.mag();
1380
1381 Belle::kid_cdc kidCdc(5);
1382 float factor0 = kidCdc.factor0();
1383 float factor1 = kidCdc.factor1(idp, pval);
1384
1385 if (factor0 == 1.0 && factor1 == 1.0) return chg.trk().pid(idp);
1386 //
1387 double m = chg.trk().dEdx() / factor0;
1388 double e = chg.trk().dEdx_exp(idp) * factor1;
1389 double s = chg.trk().sigma_dEdx(idp);
1390 double val = 1. / sqrt(2.*M_PI) / s * exp(-0.5 * (m - e) * (m - e) / s / s);
1391
1392 return val;
1393}
1394#endif
1395
1397 bool discard_allzero)
1398{
1399 if (discard_allzero) {
1400 const double max_l = *std::max_element(likelihoods, likelihoods + c_nHyp);
1401 if (max_l <= 0.0) {
1402 return; //likelihoods broken, ignore
1403 }
1404 }
1405
1406 for (int i = 0; i < c_nHyp; i++) {
1407 float logl = log(likelihoods[i]);
1408 pid->setLogLikelihood(det, c_belleHyp_to_chargedStable[i], logl);
1409 }
1410 //copy proton likelihood to deuterons
1411 pid->setLogLikelihood(det, Const::deuteron, pid->getLogL(Const::proton, det));
1412}
1413
1414void B2BIIConvertMdstModule::convertPIDData(const Belle::Mdst_charged& belleTrack, const Track* track)
1415{
1416 PIDLikelihood* pid = m_pidLikelihoods.appendNew();
1417 track->addRelationTo(pid);
1418
1419 //convert data handled by atc_pid: dE/dx (-> CDC), TOF (-> TOP), ACC ( -> ARICH)
1420 //this should result in the same likelihoods used when creating atc_pid(3, 1, 5, ..., ...)
1421 //and calling prob(const Mdst_charged & chg).
1422
1423 double likelihoods[c_nHyp];
1424 double accL[c_nHyp];
1425 double tofL[c_nHyp];
1426 double cdcL[c_nHyp];
1427 for (int i = 0; i < c_nHyp; i++) {
1428 accL[i] = tofL[i] = cdcL[i] = 1.0; // cppcheck-suppress unreadVariable
1429 }
1430#ifdef HAVE_KID_ACC
1431 //accq0 = 3, as implemented in acc_prob3()
1432 const auto& acc = belleTrack.acc();
1433 if (acc and acc.quality() == 0) {
1434 for (int i = 0; i < c_nHyp; i++)
1435 accL[i] = likelihoods[i] = acc_pid(belleTrack, i); // cppcheck-suppress unreadVariable
1436 setLikelihoods(pid, Const::ARICH, likelihoods, true);
1437 }
1438#endif
1439
1440 //tofq0 = 1, as implemented in tof_prob1()
1441 //uses p1 / (p1 + p2) to create probability, so this should map directly to likelihoods
1442 const Belle::Mdst_tof& tof = belleTrack.tof();
1443 if (tof and tof.quality() == 0) {
1444 for (int i = 0; i < c_nHyp; i++)
1445 tofL[i] = likelihoods[i] = tof.pid(i); // cppcheck-suppress unreadVariable
1446 setLikelihoods(pid, Const::TOP, likelihoods, true);
1447 }
1448
1449 // cdcq0 = 5, as implemented in cdc_prob0() (which is used for all values of cdcq0!)
1450 //uses p1 / (p1 + p2) to create probability, so this should map directly to likelihoods
1451 // eID actually uses cdc_pid (cdc_prob5)
1452 const Belle::Mdst_trk& trk = belleTrack.trk();
1453 if (trk.dEdx() > 0) {
1454 for (int i = 0; i < c_nHyp; i++) {
1455 likelihoods[i] = trk.pid(i);
1456 cdcL[i] = cdc_pid(belleTrack, i); // cppcheck-suppress unreadVariable
1457 }
1458 setLikelihoods(pid, Const::CDC, likelihoods, true);
1459 }
1460
1461
1462 // eid
1463 // eid is combination of atc_pid and ecl related information
1464 // since atc_pid part is already converted above only the ECL part
1465 // is converted
1466 // ECL pdfs are available only for electrons and hadrons (assumed to be pions)
1467 // likelihoods for others are set to 0
1468
1469#ifdef HAVE_EID
1470 Belle::eid electronID(belleTrack);
1471 float eclID_e_pdf = electronID.pdf_e_ecl();
1472 float eclID_h_pdf = electronID.pdf_h_ecl();
1473 float atcID_e_pdf = electronID.atc_pid_pdf(true, accL, tofL, cdcL);
1474 float atcID_h_pdf = electronID.atc_pid_pdf(false, accL, tofL, cdcL);
1475
1476 // eID
1477 float eclProb = eclID_e_pdf / (eclID_e_pdf + eclID_h_pdf);
1478 float atcProb = atcID_e_pdf / (atcID_e_pdf + atcID_h_pdf);
1479
1480 if (atcProb > 0.999999) atcProb = 0.999999;
1481 // combine the two probabilities.
1482 double eidCombinedSig = eclProb * atcProb;
1483 double eidCombinedBkg = (1. - eclProb) * (1. - atcProb);
1484
1485 likelihoods[0] = eidCombinedSig;
1486 likelihoods[1] = 0; // no muons
1487 likelihoods[2] = eidCombinedBkg;
1488 likelihoods[3] = 0; // no kaons
1489 likelihoods[4] = 0; // no protons
1490
1491 setLikelihoods(pid, Const::ECL, likelihoods, true);
1492
1493 //Hep3Vector mom(belleTrack.px(), belleTrack.py(), belleTrack.pz());
1494 //B2INFO(" p = " << mom.mag() << " le_ecl = " << electronID.le_ecl());
1495#endif
1496
1497 //muid
1498 //Note that though it says "_likelihood()" on the label, those are
1499 //actually likelihood ratios of the type L(hyp) / (L(mu) + L(pi) + L(K)),
1500 //which are set in the FixMdst module.
1501 int muid_trackid = belleTrack.muid_ID();
1502 if (muid_trackid) {
1503 //Using approach 2. from http://belle.kek.jp/secured/muid/usage_muid.html since
1504 //it's much simpler than what Muid_mdst does.
1505 Belle::Mdst_klm_mu_ex_Manager& ex_mgr = Belle::Mdst_klm_mu_ex_Manager::get_manager();
1506 Belle::Mdst_klm_mu_ex& ex = ex_mgr(Belle::Panther_ID(muid_trackid));
1507
1508 //filter out tracks with insufficient #hits (equal to cut on Muid_mdst::Chi_2())
1509 if (ex.Chi_2() > 0) {
1510 likelihoods[0] = 0; //no electrons
1511 likelihoods[1] = ex.Muon_likelihood();
1512 likelihoods[2] = ex.Pion_likelihood();
1513 likelihoods[3] = ex.Kaon_likelihood();
1514 likelihoods[4] = 0; //no protons
1515 //Miss_likelihood should only be != 0 for tracks that do not pass the Chi_2 cut.
1516
1517 // in some cases the ex.XYZ_likelihood() < 0; Set it to 0 in these cases.
1518 for (int i = 0; i < 5; i++)
1519 if (likelihoods[i] < 0)
1520 likelihoods[i] = 0;
1521
1522 //note: discard_allzero = false since all likelihoods = 0 usually means that Junk_likelihood is 1
1523 // PIDLikelihood::getProbability(hyp) will correctly return 0 then.
1524 setLikelihoods(pid, Const::KLM, likelihoods);
1525
1526 /*
1527 const double tolerance = 1e-7;
1528 if (fabs(pid->getProbability(Const::muon, nullptr, Const::KLM) - ex.Muon_likelihood()) > tolerance ||
1529 fabs(pid->getProbability(Const::pion, nullptr, Const::KLM) - ex.Pion_likelihood()) > tolerance ||
1530 fabs(pid->getProbability(Const::kaon, nullptr, Const::KLM) - ex.Kaon_likelihood()) > tolerance) {
1531
1532 B2INFO("muons: " << pid->getProbability(Const::muon, nullptr, Const::KLM) << " " << ex.Muon_likelihood());
1533 B2INFO("pion: " << pid->getProbability(Const::pion, nullptr, Const::KLM) << " " << ex.Pion_likelihood());
1534 B2INFO("kaon: " << pid->getProbability(Const::kaon, nullptr, Const::KLM) << " " << ex.Kaon_likelihood());
1535 B2INFO("miss/junk: " << ex.Miss_likelihood() << " " << ex.Junk_likelihood());
1536 }
1537 */
1538 }
1539 }
1540}
1541
1542int B2BIIConvertMdstModule::getHelixParameters(const Belle::Mdst_trk_fit& trk_fit,
1543 const double mass,
1544 const HepPoint3D& newPivot,
1545 std::vector<float>& helixParams,
1546 CLHEP::HepSymMatrix& error5x5,
1547 CLHEP::HepLorentzVector& momentum,
1548 HepPoint3D& position,
1549 CLHEP::HepSymMatrix& error7x7, const double dPhi)
1550{
1551 const HepPoint3D pivot(trk_fit.pivot_x(),
1552 trk_fit.pivot_y(),
1553 trk_fit.pivot_z());
1554
1555 CLHEP::HepVector a(5);
1556 a[0] = trk_fit.helix(0);
1557 a[1] = trk_fit.helix(1);
1558 a[2] = trk_fit.helix(2);
1559 a[3] = trk_fit.helix(3);
1560 a[4] = trk_fit.helix(4);
1561 CLHEP::HepSymMatrix Ea(5, 0);
1562 Ea[0][0] = trk_fit.error(0);
1563 Ea[1][0] = trk_fit.error(1);
1564 Ea[1][1] = trk_fit.error(2);
1565 Ea[2][0] = trk_fit.error(3);
1566 Ea[2][1] = trk_fit.error(4);
1567 Ea[2][2] = trk_fit.error(5);
1568 Ea[3][0] = trk_fit.error(6);
1569 Ea[3][1] = trk_fit.error(7);
1570 Ea[3][2] = trk_fit.error(8);
1571 Ea[3][3] = trk_fit.error(9);
1572 Ea[4][0] = trk_fit.error(10);
1573 Ea[4][1] = trk_fit.error(11);
1574 Ea[4][2] = trk_fit.error(12);
1575 Ea[4][3] = trk_fit.error(13);
1576 Ea[4][4] = trk_fit.error(14);
1577
1578 Belle::Helix helix(pivot, a, Ea);
1579
1580 int charge = 0;
1581 if (helix.kappa() > 0)
1582 charge = 1;
1583 else
1584 charge = -1;
1585
1586 if (newPivot.x() != 0. || newPivot.y() != 0. || newPivot.z() != 0.) {
1587 helix.pivot(newPivot);
1588 momentum = helix.momentum(dPhi, mass, position, error7x7);
1589 } else {
1590 if (pivot.x() != 0. || pivot.y() != 0. || pivot.z() != 0.) {
1591 helix.pivot(HepPoint3D(0., 0., 0.));
1592 momentum = helix.momentum(dPhi, mass, position, error7x7);
1593 } else {
1594 momentum = helix.momentum(dPhi, mass, position, error7x7);
1595 }
1596 }
1597
1598 convertHelix(helix, helixParams, error5x5);
1599
1600 return charge;
1601}
1602
1603void B2BIIConvertMdstModule::convertHelix(const Belle::Mdst_trk_fit& trk_fit,
1604 const HepPoint3D& newPivot,
1605 std::vector<float>& helixParams, std::vector<float>& helixError)
1606{
1607 const HepPoint3D pivot(trk_fit.pivot_x(),
1608 trk_fit.pivot_y(),
1609 trk_fit.pivot_z());
1610
1611 CLHEP::HepVector a(5);
1612 a[0] = trk_fit.helix(0);
1613 a[1] = trk_fit.helix(1);
1614 a[2] = trk_fit.helix(2);
1615 a[3] = trk_fit.helix(3);
1616 a[4] = trk_fit.helix(4);
1617 CLHEP::HepSymMatrix Ea(5, 0);
1618 Ea[0][0] = trk_fit.error(0);
1619 Ea[1][0] = trk_fit.error(1);
1620 Ea[1][1] = trk_fit.error(2);
1621 Ea[2][0] = trk_fit.error(3);
1622 Ea[2][1] = trk_fit.error(4);
1623 Ea[2][2] = trk_fit.error(5);
1624 Ea[3][0] = trk_fit.error(6);
1625 Ea[3][1] = trk_fit.error(7);
1626 Ea[3][2] = trk_fit.error(8);
1627 Ea[3][3] = trk_fit.error(9);
1628 Ea[4][0] = trk_fit.error(10);
1629 Ea[4][1] = trk_fit.error(11);
1630 Ea[4][2] = trk_fit.error(12);
1631 Ea[4][3] = trk_fit.error(13);
1632 Ea[4][4] = trk_fit.error(14);
1633
1634 Belle::Helix helix(pivot, a, Ea);
1635
1636 if (newPivot.x() != 0. || newPivot.y() != 0. || newPivot.z() != 0.) {
1637 helix.pivot(newPivot);
1638 } else {
1639 if (pivot.x() != 0. || pivot.y() != 0. || pivot.z() != 0.) {
1640 helix.pivot(HepPoint3D(0., 0., 0.));
1641 }
1642 }
1643
1644 CLHEP::HepSymMatrix error5x5(5, 0);
1645 convertHelix(helix, helixParams, error5x5);
1646
1647 unsigned int size = 5;
1648 unsigned int counter = 0;
1649 for (unsigned int i = 0; i < size; i++)
1650 for (unsigned int j = i; j < size; j++)
1651 helixError[counter++] = error5x5[i][j];
1652}
1653
1654void B2BIIConvertMdstModule::convertHelix(Belle::Helix& helix, std::vector<float>& helixParams, CLHEP::HepSymMatrix& error5x5)
1655{
1656 CLHEP::HepVector a(5);
1657 CLHEP::HepSymMatrix Ea(5, 0);
1658
1659 a = helix.a();
1660 Ea = helix.Ea();
1661
1662 // param 0: d_0 = d_rho
1663 helixParams[0] = a[0];
1664
1665 // param 1: phi = phi_0 + pi/2
1666 helixParams[1] = adjustAngleRange(a[1] + TMath::Pi() / 2.0);
1667
1668 // param 2: omega = Kappa * alpha = Kappa * B[Tesla] * speed_of_light[m/s] * 1e-11
1669 helixParams[2] = a[2] * KAPPA2OMEGA;
1670
1671 // param 3: d_z = z0
1672 helixParams[3] = a[3];
1673
1674 // param 4: tan(Lambda) = tanLambda
1675 helixParams[4] = a[4];
1676
1677 unsigned int size = 5;
1678 for (unsigned int i = 0; i < size; i++) {
1679 for (unsigned int j = 0; j < size; j++) {
1680 error5x5[i][j] = Ea[i][j];
1681 if (i == 2)
1682 error5x5[i][j] *= KAPPA2OMEGA;
1683 if (j == 2)
1684 error5x5[i][j] *= KAPPA2OMEGA;
1685
1686 if (std::isinf(error5x5[i][j])) {
1687 B2DEBUG(99, "Helix covariance matrix element found to be infinite. Setting value to DBL_MAX/2.0.");
1688 error5x5[i][j] = DBL_MAX / 2.0;
1689 }
1690 }
1691 }
1692}
1693
1694void B2BIIConvertMdstModule::convertMdstChargedObject(const Belle::Mdst_charged& belleTrack, Track* track)
1695{
1696 Belle::Mdst_trk& trk = belleTrack.trk();
1697
1698 for (int mhyp = 0 ; mhyp < c_nHyp; ++mhyp) {
1699 Belle::Mdst_trk_fit& trk_fit = trk.mhyp(mhyp);
1700
1701 double pValue = TMath::Prob(trk_fit.chisq(), trk_fit.ndf());
1702 if (std::isnan(pValue)) continue;
1703
1705 double thisMass = pType.getMass();
1706
1707 // Converted helix parameters
1708 std::vector<float> helixParam(5);
1709 // Converted 5x5 error matrix
1710 CLHEP::HepSymMatrix error5x5(5, 0);
1711 // 4-momentum
1712 CLHEP::HepLorentzVector momentum;
1713 // 7x7 (momentum, position) error matrix
1714 CLHEP::HepSymMatrix error7x7(7, 0);
1715 // position
1716 HepPoint3D position;
1717
1718 getHelixParameters(trk_fit, thisMass, HepPoint3D(0., 0., 0.),
1719 helixParam, error5x5,
1720 momentum, position, error7x7, 0.0);
1721
1722 std::vector<float> helixError(15);
1723 unsigned int size = 5;
1724 unsigned int counter = 0;
1725 for (unsigned int i = 0; i < size; i++)
1726 for (unsigned int j = i; j < size; j++)
1727 helixError[counter++] = error5x5[i][j];
1728
1729 // Create an empty cdc hitpattern and set the number of total hits
1730 // use hits from 0: axial-wire, 1:stereo-wire, 2:cathode
1731 // the actual cdc hitpattern is not converted
1732
1733 int cdcNHits = 0;
1734 for (unsigned int i = 0; i < 3; i++)
1735 cdcNHits += trk_fit.nhits(i);
1736
1737 HitPatternCDC patternCdc;
1738 patternCdc.setNHits(cdcNHits);
1739
1740 // conversion of track position in CDC layers
1741 if (m_convertTrkExtra) {
1742 double tof = 0;
1743 double path_length = 0;
1744 double tof_sigma = 0;
1745 short tof_qual = 0;
1746 int acc_ph = 0;
1747 short acc_qual = 0;
1748 double dedx = trk.dEdx();
1749 short dedx_qual = trk.quality_dedx();
1750
1751 const Belle::Mdst_tof& tof_obj = belleTrack.tof();
1752 if (tof_obj) {
1753 tof = tof_obj.tof();
1754 path_length = tof_obj.path_length();
1755 tof_qual = tof_obj.quality();
1756 tof_sigma = tof_obj.sigma_tof();
1757 }
1758
1759 const Belle::Mdst_acc& acc_obj = belleTrack.acc();
1760 if (acc_obj) {
1761 acc_ph = acc_obj.photo_electron();
1762 acc_qual = acc_obj.quality();
1763 }
1764
1765
1766 auto cdcExtraInfo = m_belleTrkExtra.appendNew(trk_fit.first_x(), trk_fit.first_y(), trk_fit.first_z(),
1767 trk_fit.last_x(), trk_fit.last_y(), trk_fit.last_z(),
1768 tof, path_length, tof_qual, tof_sigma,
1769 acc_ph, acc_qual, dedx, dedx_qual);
1770 track->addRelationTo(cdcExtraInfo);
1771 }
1772 // conversion of the SVD hit pattern
1773 int svdHitPattern = trk_fit.hit_svd();
1774 // use hits from 3: SVD-rphi, 4: SVD-z
1775 // int svdNHits = trk_fit.nhits(3) + trk_fit.nhits(4);
1776
1777 std::bitset<32> svdBitSet(svdHitPattern);
1778
1779 HitPatternVXD patternVxd;
1780
1781 unsigned short svdLayers;
1782 // taken from: http://belle.kek.jp/group/indirectcp/cpfit/cpfit-festa/2004/talks/Apr.14/CPfesta-2005-Higuchi(3).pdf
1784 // mask for the rphi hits, first 6 (8) bits/ 2 bits per layer
1785 std::bitset<32> svdUMask(static_cast<std::string>("00000000000000000000000000000011"));
1786 // mask for the z hits, second 6 (8) bits/ 2 bits per layer
1787 std::bitset<32> svdVMask;
1788
1789 // find out if the SVD has 3 (4) layers; if exp <= (>) exp 27
1790 if (event->getExperiment() <= 27) {
1791 svdVMask = svdUMask << 6;
1792 svdLayers = 3;
1793 } else {
1794 svdVMask = svdUMask << 8;
1795 svdLayers = 4;
1796 }
1797
1798 // loop over all svd layers (layer index is shifted + 3 for basf2)
1799 for (unsigned short layerId = 0; layerId < svdLayers; layerId++) {
1800 unsigned short uHits = (svdBitSet & svdUMask).count();
1801 unsigned short vHits = (svdBitSet & svdVMask).count();
1802 patternVxd.setSVDLayer(layerId + 3, uHits, vHits);
1803 // shift masks to the left
1804 svdUMask <<= 2;
1805 svdVMask <<= 2;
1806 }
1807
1808 TrackFitResult helixFromHelix(helixParam, helixError, pType, pValue, -1, patternVxd.getInteger(), 0);
1809
1811 TMatrixDSym cartesianCovariance(6);
1812 for (unsigned i = 0; i < 7; i++) {
1813 if (i == 3)
1814 continue;
1815 for (unsigned j = 0; j < 7; j++) {
1816 if (j == 3)
1817 continue;
1818
1819 cartesianCovariance(ERRMCONV[i], ERRMCONV[j]) = error7x7[i][j];
1820 }
1821 }
1822 UncertainHelix helixFromCartesian(helixFromHelix.getPosition(), helixFromHelix.getMomentum(), helixFromHelix.getChargeSign(),
1823 BFIELD, cartesianCovariance, pValue);
1824
1825 TMatrixDSym helixCovariance = helixFromCartesian.getCovariance();
1826
1827 counter = 0;
1828 for (unsigned int i = 0; i < 5; ++i)
1829 for (unsigned int j = i; j < 5; ++j)
1830 helixError[counter++] = helixCovariance(i, j);
1831 }
1832
1833 auto trackFit = m_trackFitResults.appendNew(helixParam, helixError, pType, pValue, patternCdc.getInteger(),
1834 patternVxd.getInteger(), trk_fit.ndf());
1835 track->setTrackFitResultIndex(pType, trackFit->getArrayIndex());
1836 /*
1837 B2INFO("--- B1 Track: ");
1838 std::cout << "Momentum = " << momentum << std::endl;
1839 std::cout << "Position = " << position << std::endl;
1840 std::cout << "7x7 error matrix = " << error7x7 << std::endl;
1841 B2INFO("--- B2 Track: ");
1842 std::cout << "Momentum = " << std::endl;
1843 trackFit->get4Momentum().Print();
1844 std::cout << "Position = " << std::endl;
1845 trackFit->getPosition().Print();
1846 std::cout << "6x6 error matrix = " << std::endl;
1847 trackFit->getCovariance6().Print();
1848 TMatrixDSym b2Error7x7(7);
1849 fill7x7ErrorMatrix(trackFit, b2Error7x7, thisMass, 1.5);
1850 std::cout << "7x7 error matrix = " << std::endl;
1851 b2Error7x7.Print();
1852 */
1853 }
1854}
1855
1856void B2BIIConvertMdstModule::convertGenHepevtObject(const Belle::Gen_hepevt& genHepevt, MCParticleGraph::GraphParticle* mcParticle)
1857{
1858 //B2DEBUG(80, "Gen_ehepevt: idhep " << genHepevt.idhep() << " (" << genHepevt.isthep() << ") with ID = " << genHepevt.get_ID());
1859
1860 // updating the GraphParticle information from the Gen_hepevt information
1861 const int idHep = recoverMoreThan24bitIDHEP(genHepevt.idhep());
1862 if (idHep == 0) {
1863 B2WARNING("Trying to convert Gen_hepevt with idhep = " << idHep <<
1864 ". This should never happen.");
1865 mcParticle->setPDG(Const::photon.getPDGCode());
1866 } else {
1867 mcParticle->setPDG(idHep);
1868 }
1869
1870 if (genHepevt.isthep() > 0) {
1872 }
1873
1874 mcParticle->setMass(genHepevt.M());
1875
1876 ROOT::Math::PxPyPzEVector p4(genHepevt.PX(), genHepevt.PY(), genHepevt.PZ(), genHepevt.E());
1877 mcParticle->set4Vector(p4);
1878
1879 mcParticle->setProductionVertex(genHepevt.VX()*Unit::mm, genHepevt.VY()*Unit::mm, genHepevt.VZ()*Unit::mm);
1880 mcParticle->setProductionTime(genHepevt.T()*Unit::mm / Const::speedOfLight);
1881
1882 // decay time of this particle is production time of the daughter particle
1883 if (genHepevt.daFirst() > 0) {
1884 Belle::Gen_hepevt_Manager& genMgr = Belle::Gen_hepevt_Manager::get_manager();
1885 Belle::Gen_hepevt daughterParticle = genMgr(Belle::Panther_ID(genHepevt.daFirst()));
1886 mcParticle->setDecayTime(daughterParticle.T()*Unit::mm / Const::speedOfLight);
1887 mcParticle->setDecayVertex(daughterParticle.VX()*Unit::mm, daughterParticle.VY()*Unit::mm, daughterParticle.VZ()*Unit::mm);
1888 } else {
1889 //otherwise, assume it's stable
1890 mcParticle->setDecayTime(std::numeric_limits<float>::infinity());
1891 }
1892
1893 mcParticle->setValidVertex(true);
1894}
1895
1896void B2BIIConvertMdstModule::convertMdstECLObject(const Belle::Mdst_ecl& ecl, const Belle::Mdst_ecl_aux& eclAux,
1897 ECLCluster* eclCluster)
1898{
1899 if (eclAux.e9oe25() < m_matchType2E9oE25Threshold)
1900 eclCluster->setIsTrack(ecl.match() > 0);
1901 else
1902 eclCluster->setIsTrack(ecl.match() == 1);
1903
1904 eclCluster->setEnergy(ecl.energy()); //must happen before setCovarianceMatrix()!
1907 eclCluster->setPhi(ecl.phi());
1908 eclCluster->setTheta(ecl.theta());
1909 eclCluster->setR(ecl.r());
1910 eclCluster->setdeltaL(ecl.quality());
1911
1912 double covarianceMatrix[6];
1913 covarianceMatrix[0] = ecl.error(0); // error on energy
1914 covarianceMatrix[1] = ecl.error(1);
1915 covarianceMatrix[2] = ecl.error(2); // error on phi
1916 covarianceMatrix[3] = ecl.error(3);
1917 covarianceMatrix[4] = ecl.error(4);
1918 covarianceMatrix[5] = ecl.error(5); // error on theta
1919 eclCluster->setCovarianceMatrix(covarianceMatrix);
1920
1921 eclCluster->setLAT(eclAux.width());
1922 eclCluster->setEnergyRaw(eclAux.mass());
1923 eclCluster->setE9oE21(eclAux.e9oe25());
1924 eclCluster->setEnergyHighestCrystal(eclAux.seed());
1925 // The property 2 of eclAux contains the timing information
1926 // in a bit encoded format.
1927 // The 16 bits: 0-15 contain tdc count
1928 float prop2 = eclAux.property(2);
1929 // a float to int conversion
1930 int property2;
1931 std::memcpy(&property2, &prop2, sizeof(int));
1932 //decode the bit encoded variables
1933 int tdccount;
1934 tdccount = property2 & 0xffff;
1935 eclCluster->setTime(tdccount);
1936 eclCluster->setNumberOfCrystals(eclAux.nhits());
1937 double dist = computeTrkMinDistanceBelle(eclCluster);
1938 eclCluster->setMinTrkDistance(dist);
1939}
1940
1942{
1943 const double m_extRadius(125.0);
1944 const double m_extZFWD(196.0);
1945 const double m_extZBWD(-102.2);
1946 double minDist(10000);
1947
1948 // get cluster info
1949 const int reg = eclCluster->getDetectorRegion();
1950 double eclClusterR_surface = m_extRadius / sin(eclCluster->getTheta());
1951 if (reg == 1) {eclClusterR_surface = m_extZFWD / cos(eclCluster->getTheta());}
1952 else if (reg == 3) {eclClusterR_surface = m_extZBWD / cos(eclCluster->getTheta());}
1953
1954 ROOT::Math::XYZVector eclCluster_surface_position(0, 0, 0);
1955 VectorUtil::setMagThetaPhi(eclCluster_surface_position, eclClusterR_surface, eclCluster->getTheta(), eclCluster->getPhi());
1956
1957 for (const auto& track : m_tracks) {
1958 const TrackFitResult* trackFit = track.getTrackFitResultWithClosestMass(Const::ChargedStable(Const::pion));
1959
1960 if (trackFit == NULL) {continue;}
1961 // get the track parameters
1962 const double z0 = trackFit->getZ0();
1963 const double tanlambda = trackFit->getTanLambda();
1964
1965 // use the helix class
1966 Helix h = trackFit->getHelix();
1967
1968 // extrapolate to radius
1969 const double lHelixRadius = h.getArcLength2DAtCylindricalR(m_extRadius) > 0 ? h.getArcLength2DAtCylindricalR(m_extRadius) : 999999.;
1970
1971 // extrapolate to FWD z
1972 const double lFWD = (m_extZFWD - z0) / tanlambda > 0 ? (m_extZFWD - z0) / tanlambda : 999999.;
1973
1974 // extrapolate to backward z
1975 const double lBWD = (m_extZBWD - z0) / tanlambda > 0 ? (m_extZBWD - z0) / tanlambda : 999999.;
1976
1977 // pick smallest arclength
1978 const double l = std::min(std::min(lHelixRadius, lFWD), lBWD);
1979
1980 B2DEBUG(50, lHelixRadius << " " << lFWD << " " << lBWD << " -> " << l);
1981
1982 ROOT::Math::XYZVector ext_helix = h.getPositionAtArcLength2D(l);
1983 double helixExtR_surface = m_extRadius / sin(ext_helix.Theta());
1984 if (l == lFWD) { helixExtR_surface = m_extZFWD / cos(ext_helix.Theta());}
1985 else if (l == lBWD) { helixExtR_surface = m_extZBWD / cos(ext_helix.Theta());}
1986
1987 ROOT::Math::XYZVector helixExt_surface_position(0, 0, 0);
1988 VectorUtil::setMagThetaPhi(helixExt_surface_position, helixExtR_surface, ext_helix.Theta(), ext_helix.Phi());
1989
1990 double distance = (eclCluster_surface_position - helixExt_surface_position).R();
1991 if (distance < minDist) {minDist = distance;}
1992 }
1993 if (minDist > 9999) minDist = -1;
1994 return minDist;
1995}
1996
1997void B2BIIConvertMdstModule::convertMdstKLMObject(const Belle::Mdst_klm_cluster& klm_cluster, KLMCluster* klmCluster)
1998{
1999 // note: Belle quality flag is not saved (no free int variable in Belle2 KLMCluster)
2000 klmCluster->setLayers(klm_cluster.layers());
2001 klmCluster->setInnermostLayer(klm_cluster.first_layer());
2002}
2003
2004
2005//-----------------------------------------------------------------------------
2006// RELATIONS
2007//-----------------------------------------------------------------------------
2009{
2010 // Relations
2011 RelationArray tracksToECLClusters(m_tracks, m_eclClusters);
2012
2013 Belle::Mdst_ecl_trk_Manager& m = Belle::Mdst_ecl_trk_Manager::get_manager();
2014 Belle::Mdst_charged_Manager& chgMg = Belle::Mdst_charged_Manager::get_manager();
2015
2016 // We first insert relations to tracks which are directly matched (type == 1)
2017 // secondly we had CR matched tracks (connected region) (type == 2)
2018 // finally tracks which are geometrically matched (type == 0)
2019 std::vector<int> insert_order_types = {1, 2, 0};
2020 for (auto& insert_type : insert_order_types) {
2021 for (Belle::Mdst_ecl_trk_Manager::iterator ecltrkIterator = m.begin(); ecltrkIterator != m.end(); ++ecltrkIterator) {
2022 Belle::Mdst_ecl_trk mECLTRK = *ecltrkIterator;
2023
2024 if (mECLTRK.type() != insert_type)
2025 continue;
2026
2027 Belle::Mdst_ecl mdstEcl = mECLTRK.ecl();
2028 Belle::Mdst_trk mTRK = mECLTRK.trk();
2029
2030 if (!mdstEcl)
2031 continue;
2032
2033 // the numbering in mdst_charged
2034 // not necessarily the same as in mdst_trk
2035 // therefore have to find corresponding mdst_charged
2036 for (Belle::Mdst_charged_Manager::iterator chgIterator = chgMg.begin(); chgIterator != chgMg.end(); ++chgIterator) {
2037 Belle::Mdst_charged mChar = *chgIterator;
2038 Belle::Mdst_trk mTRK_in_charged = mChar.trk();
2039
2040 if (mTRK_in_charged.get_ID() == mTRK.get_ID()) {
2041 // found the correct mdst_charged
2042 tracksToECLClusters.add(mChar.get_ID() - 1, mdstEcl.get_ID() - 1, 1.0);
2043 break;
2044 }
2045 }
2046 }
2047 }
2048}
2049
2050
2052{
2053 // Relations
2054 RelationArray klmClustersToTracks(m_klmClusters, m_tracks);
2055 RelationArray klmClustersToEclClusters(m_klmClusters, m_eclClusters);
2056
2057 Belle::Mdst_klm_cluster_Manager& klm_cluster_manager = Belle::Mdst_klm_cluster_Manager::get_manager();
2058
2059
2060 for (Belle::Mdst_klm_cluster_Manager::iterator klmC_Ite = klm_cluster_manager.begin(); klmC_Ite != klm_cluster_manager.end();
2061 ++klmC_Ite) {
2062
2063 Belle::Mdst_klm_cluster mdstKlm_cluster = *klmC_Ite;
2064 Belle::Mdst_trk mTRK = mdstKlm_cluster.trk();
2065 Belle::Mdst_ecl mECL = mdstKlm_cluster.ecl();
2066
2067 if (mTRK) klmClustersToTracks.add(mdstKlm_cluster.get_ID() - 1, mTRK.get_ID() - 1);
2068 if (mECL) klmClustersToEclClusters.add(mdstKlm_cluster.get_ID() - 1, mECL.get_ID() - 1);
2069 }
2070}
2071
2072
2073//-----------------------------------------------------------------------------
2074// MISC
2075//-----------------------------------------------------------------------------
2076
2078{
2079 /*
2080 QUICK CHECK: most of the normal particles are smaller than
2081 0x100000, while all the corrupt id has some of the high bits on.
2082
2083 This bit check has to be revised when the table below is updated.
2084 */
2085 const int mask = 0x00f00000;
2086 int high_bits = id & mask;
2087 if (high_bits == 0 || high_bits == mask) return id;
2088
2089 switch (id) {
2090 case 7114363:
2091 return 91000443; // X(3940)
2092 case 6114363:
2093 return 90000443; // Y(3940)
2094 case 6114241:
2095 return 90000321; // K_0*(800)+
2096 case 6114231:
2097 return 90000311; // K_0*(800)0
2098 case -6865004:
2099 return 9912212; // p_diff+
2100 case -6865104:
2101 return 9912112; // n_diffr
2102 case -6866773:
2103 return 9910443; // psi_diff
2104 case -6866883:
2105 return 9910333; // phi_diff
2106 case -6866993:
2107 return 9910223; // omega_diff
2108 case -6867005:
2109 return 9910211; // pi_diff+
2110 case -6867103:
2111 return 9910113; // rho_diff0
2112 case -7746995:
2113 return 9030221; // f_0(1500)
2114 case -7756773:
2115 return 9020443; // psi(4415)
2116 case -7756995:
2117 return 9020221; // eta(1405)
2118 case -7766773:
2119 return 9010443; // psi(4160)
2120 case -7776663:
2121 return 9000553; // Upsilon(5S)
2122 case -7776773:
2123 return 9000443; // psi(4040)
2124 case -7776783:
2125 return 9000433; // D_sj(2700)+
2126 case -7776995:
2127 return 9000221; // f_0(600)
2128 case -6114241:
2129 return -90000321; // K_0*(800)-
2130 case -6114231:
2131 return -90000311; // anti-K_0*(800)0
2132 case 6865004:
2133 return -9912212; // anti-p_diff-
2134 case 6865104:
2135 return -9912112; // anti-n_diffr
2136 case 6867005:
2137 return -9910211; // pi_diff-
2138 case 7776783:
2139 return -9000433; // D_sj(2700)-
2140 default:
2141 return id;
2142 }
2143}
2144
2145void B2BIIConvertMdstModule::testMCRelation(const Belle::Gen_hepevt& belleMC, const MCParticle* mcP, const std::string& objectName)
2146{
2147 int bellePDGCode = belleMC.idhep();
2148 int belleIIPDGCode = mcP->getPDG();
2149
2150 if (bellePDGCode == 0)
2151 B2WARNING("[B2BIIConvertMdstModule] " << objectName << " matched to Gen_hepevt with idhep = 0.");
2152
2153 if (bellePDGCode != belleIIPDGCode)
2154 B2WARNING("[B2BIIConvertMdstModule] " << objectName << " matched to different MCParticle! " << bellePDGCode << " vs. " <<
2155 belleIIPDGCode);
2156
2157 const double belleMomentum[] = { belleMC.PX(), belleMC.PY(), belleMC.PZ() };
2158 const double belle2Momentum[] = { mcP->get4Vector().Px(), mcP->get4Vector().Py(), mcP->get4Vector().Pz() };
2159
2160 for (unsigned i = 0; i < 3; i++) {
2161 double relDev = (belle2Momentum[i] - belleMomentum[i]) / belleMomentum[i];
2162
2163 if (relDev > 1e-3) {
2164 B2WARNING("[B2BIIConvertMdstModule] " << objectName << " matched to different MCParticle!");
2165 B2INFO(" - Gen_hepevt [" << bellePDGCode << "] px/py/pz = " << belleMC.PX() << "/" << belleMC.PY() << "/" << belleMC.PZ());
2166 B2INFO(" - TrackFitResult [" << belleIIPDGCode << "] px/py/pz = " << mcP->get4Vector().Px() << "/" << mcP->get4Vector().Py() << "/"
2167 << mcP->get4Vector().Pz());
2168 }
2169 }
2170}
2171
2172void B2BIIConvertMdstModule::belleVeeDaughterToCartesian(const Belle::Mdst_vee2& vee, const int charge,
2173 const Const::ParticleType& pType,
2174 CLHEP::HepLorentzVector& momentum, HepPoint3D& position, CLHEP::HepSymMatrix& error)
2175{
2176 const HepPoint3D pivot(vee.vx(), vee.vy(), vee.vz());
2177 CLHEP::HepVector a(5);
2178 CLHEP::HepSymMatrix Ea(5, 0);
2179 if (charge > 0) {
2180 a[0] = vee.daut().helix_p(0); a[1] = vee.daut().helix_p(1);
2181 a[2] = vee.daut().helix_p(2); a[3] = vee.daut().helix_p(3);
2182 a[4] = vee.daut().helix_p(4);
2183 Ea[0][0] = vee.daut().error_p(0); Ea[1][0] = vee.daut().error_p(1);
2184 Ea[1][1] = vee.daut().error_p(2); Ea[2][0] = vee.daut().error_p(3);
2185 Ea[2][1] = vee.daut().error_p(4); Ea[2][2] = vee.daut().error_p(5);
2186 Ea[3][0] = vee.daut().error_p(6); Ea[3][1] = vee.daut().error_p(7);
2187 Ea[3][2] = vee.daut().error_p(8); Ea[3][3] = vee.daut().error_p(9);
2188 Ea[4][0] = vee.daut().error_p(10); Ea[4][1] = vee.daut().error_p(11);
2189 Ea[4][2] = vee.daut().error_p(12); Ea[4][3] = vee.daut().error_p(13);
2190 Ea[4][4] = vee.daut().error_p(14);
2191 } else {
2192 a[0] = vee.daut().helix_m(0); a[1] = vee.daut().helix_m(1);
2193 a[2] = vee.daut().helix_m(2); a[3] = vee.daut().helix_m(3);
2194 a[4] = vee.daut().helix_m(4);
2195 Ea[0][0] = vee.daut().error_m(0); Ea[1][0] = vee.daut().error_m(1);
2196 Ea[1][1] = vee.daut().error_m(2); Ea[2][0] = vee.daut().error_m(3);
2197 Ea[2][1] = vee.daut().error_m(4); Ea[2][2] = vee.daut().error_m(5);
2198 Ea[3][0] = vee.daut().error_m(6); Ea[3][1] = vee.daut().error_m(7);
2199 Ea[3][2] = vee.daut().error_m(8); Ea[3][3] = vee.daut().error_m(9);
2200 Ea[4][0] = vee.daut().error_m(10); Ea[4][1] = vee.daut().error_m(11);
2201 Ea[4][2] = vee.daut().error_m(12); Ea[4][3] = vee.daut().error_m(13);
2202 Ea[4][4] = vee.daut().error_m(14);
2203 }
2204
2205 Belle::Helix helix(pivot, a, Ea);
2206
2207 // this is Vee daughter momentum/position/error at pivot = V0 Decay Vertex
2208 momentum = helix.momentum(0., pType.getMass(), position, error);
2209}
2210
2211void B2BIIConvertMdstModule::belleVeeDaughterHelix(const Belle::Mdst_vee2& vee, const int charge, std::vector<float>& helixParam,
2212 std::vector<float>& helixError)
2213{
2214 const HepPoint3D pivot(vee.vx(), vee.vy(), vee.vz());
2215 CLHEP::HepVector a(5);
2216 CLHEP::HepSymMatrix Ea(5, 0);
2217 if (charge > 0) {
2218 a[0] = vee.daut().helix_p(0); a[1] = vee.daut().helix_p(1);
2219 a[2] = vee.daut().helix_p(2); a[3] = vee.daut().helix_p(3);
2220 a[4] = vee.daut().helix_p(4);
2221 Ea[0][0] = vee.daut().error_p(0);
2222 Ea[1][0] = vee.daut().error_p(1);
2223 Ea[1][1] = vee.daut().error_p(2);
2224 Ea[2][0] = vee.daut().error_p(3);
2225 Ea[2][1] = vee.daut().error_p(4);
2226 Ea[2][2] = vee.daut().error_p(5);
2227 Ea[3][0] = vee.daut().error_p(6);
2228 Ea[3][1] = vee.daut().error_p(7);
2229 Ea[3][2] = vee.daut().error_p(8);
2230 Ea[3][3] = vee.daut().error_p(9);
2231 Ea[4][0] = vee.daut().error_p(10);
2232 Ea[4][1] = vee.daut().error_p(11);
2233 Ea[4][2] = vee.daut().error_p(12);
2234 Ea[4][3] = vee.daut().error_p(13);
2235 Ea[4][4] = vee.daut().error_p(14);
2236 } else {
2237 a[0] = vee.daut().helix_m(0); a[1] = vee.daut().helix_m(1);
2238 a[2] = vee.daut().helix_m(2); a[3] = vee.daut().helix_m(3);
2239 a[4] = vee.daut().helix_m(4);
2240 Ea[0][0] = vee.daut().error_m(0);
2241 Ea[1][0] = vee.daut().error_m(1);
2242 Ea[1][1] = vee.daut().error_m(2);
2243 Ea[2][0] = vee.daut().error_m(3);
2244 Ea[2][1] = vee.daut().error_m(4);
2245 Ea[2][2] = vee.daut().error_m(5);
2246 Ea[3][0] = vee.daut().error_m(6);
2247 Ea[3][1] = vee.daut().error_m(7);
2248 Ea[3][2] = vee.daut().error_m(8);
2249 Ea[3][3] = vee.daut().error_m(9);
2250 Ea[4][0] = vee.daut().error_m(10);
2251 Ea[4][1] = vee.daut().error_m(11);
2252 Ea[4][2] = vee.daut().error_m(12);
2253 Ea[4][3] = vee.daut().error_m(13);
2254 Ea[4][4] = vee.daut().error_m(14);
2255 }
2256
2257 Belle::Helix helix(pivot, a, Ea);
2258
2259 // go to the new pivot
2260 helix.pivot(HepPoint3D(0., 0., 0.));
2261
2262 CLHEP::HepSymMatrix error5x5(5, 0);
2263 convertHelix(helix, helixParam, error5x5);
2264
2265 unsigned int size = 5;
2266 unsigned int counter = 0;
2267 for (unsigned int i = 0; i < size; i++)
2268 for (unsigned int j = i; j < size; j++)
2269 helixError[counter++] = error5x5[i][j];
2270}
2271
2272TrackFitResult B2BIIConvertMdstModule::createTrackFitResult(const CLHEP::HepLorentzVector& momentum,
2273 const HepPoint3D& position,
2274 const CLHEP::HepSymMatrix& error,
2275 const short int charge,
2276 const Const::ParticleType& pType,
2277 const float pValue,
2278 const uint64_t hitPatternCDCInitializer,
2279 const uint32_t hitPatternVXDInitializer,
2280 const uint16_t ndf)
2281{
2282 ROOT::Math::XYZVector pos(position.x(), position.y(), position.z());
2283 ROOT::Math::XYZVector mom(momentum.px(), momentum.py(), momentum.pz());
2284
2285 TMatrixDSym errMatrix(6);
2286 for (unsigned i = 0; i < 7; i++) {
2287 if (i == 3)
2288 continue;
2289 for (unsigned j = 0; j < 7; j++) {
2290 if (j == 3)
2291 continue;
2292
2293 if (i == j)
2294 errMatrix(ERRMCONV[i], ERRMCONV[i]) = error[i][i];
2295 else
2296 errMatrix(ERRMCONV[i], ERRMCONV[j]) = errMatrix(ERRMCONV[j], ERRMCONV[i]) = error[i][j];
2297 }
2298 }
2299
2300 return TrackFitResult(pos, mom, errMatrix, charge, pType, pValue, BFIELD, hitPatternCDCInitializer, hitPatternVXDInitializer, ndf);
2301}
2302
2303double B2BIIConvertMdstModule::atcPID(const PIDLikelihood* pid, int sigHyp, int bkgHyp)
2304{
2305 if (!pid) return 0.5;
2306
2307 // ACC = ARICH
2308 Const::PIDDetectorSet set = Const::ARICH;
2309 double acc_sig = exp(pid->getLogL(c_belleHyp_to_chargedStable[sigHyp], set));
2310 double acc_bkg = exp(pid->getLogL(c_belleHyp_to_chargedStable[bkgHyp], set));
2311 double acc = 0.5;
2312 if (acc_sig + acc_bkg > 0.0)
2313 acc = acc_sig / (acc_sig + acc_bkg);
2314
2315 // TOF = TOP
2316 set = Const::TOP;
2317 double tof_sig = exp(pid->getLogL(c_belleHyp_to_chargedStable[sigHyp], set));
2318 double tof_bkg = exp(pid->getLogL(c_belleHyp_to_chargedStable[bkgHyp], set));
2319 double tof = 0.5;
2320 double tof_all = tof_sig + tof_bkg;
2321 if (tof_all != 0) {
2322 tof = tof_sig / tof_all;
2323 if (tof < 0.001) tof = 0.001;
2324 if (tof > 0.999) tof = 0.999;
2325 }
2326
2327 // dE/dx = CDC
2328 set = Const::CDC;
2329 double cdc_sig = exp(pid->getLogL(c_belleHyp_to_chargedStable[sigHyp], set));
2330 double cdc_bkg = exp(pid->getLogL(c_belleHyp_to_chargedStable[bkgHyp], set));
2331 double cdc = 0.5;
2332 double cdc_all = cdc_sig + cdc_bkg;
2333 if (cdc_all != 0) {
2334 cdc = cdc_sig / cdc_all;
2335 if (cdc < 0.001) cdc = 0.001;
2336 if (cdc > 0.999) cdc = 0.999;
2337 }
2338
2339 // Combined
2340 double pid_sig = acc * tof * cdc;
2341 double pid_bkg = (1. - acc) * (1. - tof) * (1. - cdc);
2342
2343 return pid_sig / (pid_sig + pid_bkg);
2344}
2345
2346
2348{
2349 B2DEBUG(99, "B2BIIConvertMdst: endRun done.");
2350}
2351
2352
2354{
2355 B2DEBUG(99, "B2BIIConvertMdst: terminate called");
2356}
double R
typedef autogenerated by FFTW
void belleVeeDaughterHelix(const Belle::Mdst_vee2 &vee, const int charge, std::vector< float > &helixParam, std::vector< float > &helixError)
obtains the helix parameters of the vee daughters
double atcPID(const PIDLikelihood *pid, int sigHyp, int bkgHyp)
calculates atc_pid(3,1,5,sigHyp,bkgHyp).prob() from converted PIDLikelihood
void convertMdstGammaTable()
Reads all entries of Mdst_Gamma Panther table, creates a particle list 'gamma:mdst' and adds them to ...
std::map< int, int > mdstKlmToKLMCluster
map of Mdst_klm Panther IDs and corresponding KLMCluster StoreArray indices
void copyNbarFromGamma()
Copies Particles in 'gamma:mdst' with energy > 0.5 GeV to be anti-n0:mdst.
void convertMdstChargedTable()
Reads and converts all entries of Mdst_charged (Mdst_trk and Mdst_trk_fit) Panther table to Track (Tr...
void setTracksToECLClustersRelations()
Sets Track -> ECLCluster relations.
OptionalDBObjPtr< CollisionBoostVector > m_collisionBoostVectorDB
CollisionBoostVector for boost vector.
StoreObjPtr< EventExtraInfo > m_evtInfo
Event Extra Info.
const int ERRMCONV[7]
CONVERSION OF TRACK ERROR MATRIX ELEMENTS.
CollisionAxisCMS m_collisionAxisCMS
CollisionAxisCMS of the beam.
StoreArray< KLMCluster > m_klmClusters
KLM clusters.
void belleVeeDaughterToCartesian(const Belle::Mdst_vee2 &vee, const int charge, const Const::ParticleType &pType, CLHEP::HepLorentzVector &momentum, HepPoint3D &position, CLHEP::HepSymMatrix &error)
Fills 4-momentum, position and 7x7 error matrix from Belle Vee daughter.
@ c_GeneratorLevel
Match to generator-level particles.
virtual void initialize() override
Initialize the module.
void setLikelihoods(PIDLikelihood *pid, Const::EDetector det, double likelihoods[c_nHyp], bool discard_allzero=false)
Add given Belle likelihoods (not log-likelihoods, in Belle hypothesis order) for given detector to pi...
OptionalDBObjPtr< CollisionAxisCMS > m_collisionAxisCMSDB
CollisionAxisCMS.
StoreArray< V0 > m_v0s
V0-particles.
virtual void event() override
Called for each event.
void convertGenHepEvtTable()
Reads and converts all entries of Gen_hepevt Panther table to MCParticle dataobjects and adds them to...
double cdc_pid(const Belle::Mdst_charged &chg, int idp)
Returns CDC likelihood for given hypothesis idp.
void convertRecTrgTable()
Reads and converts m_final from rectrg_summary3.
void setKLMClustersRelations()
Sets KLMCluster -> Track and ECLCluster relations.
bool m_convertEvtcls
Flag to switch on conversion of Evtcls table.
const double KAPPA2OMEGA
Conversion factor for Kappa -> Omega helix parameters.
double computeTrkMinDistanceBelle(ECLCluster *eclCluster)
calculate the minimal distance between a cluster and a set of tracks on the ECL surface.
virtual void endRun() override
Called when the current run is finished.
bool m_nisEnable
Flag to switch on conversion of nisKsFinder info.
StoreArray< TrackFitResult > m_trackFitResults
Track fir results.
BeamSpot m_beamSpot
Interaction Point of the beam.
StoreArray< Particle > m_particles
Particles.
virtual void terminate() override
Terminates the module.
OptionalDBObjPtr< CollisionInvariantMass > m_collisionInvMDB
CollisionInvariantMass for Invariant Mass of Beam.
void convertHelix(Belle::Helix &helix, std::vector< float > &helixParams, CLHEP::HepSymMatrix &error5x5)
Converts Belle's Helix parameters and it's covariance matrix to Belle II's version.
void convertMdstPi0Table()
Reads all entries of Mdst_Pi0 Panther table, creates a particle list 'pi0:mdst' and adds them to Stor...
std::map< int, int > genHepevtToMCParticle
map of Gen_hepevt Panther IDs and corresponding MCParticle StoreArray indices
void testMCRelation(const Belle::Gen_hepevt &belleMC, const MCParticle *mcP, const std::string &objectName)
Checks if the reconstructed object (Track, ECLCluster, ...) was matched to the same MCParticle.
bool m_convertNbar
Flag to create anti-n0:mdst list from gamma:mdst.
void convertIPProfile(bool beginRun=false)
Stores the IPProfiles in BeamSpot (currently in DataStore)
void convertMdstECLObject(const Belle::Mdst_ecl &ecl, const Belle::Mdst_ecl_aux &eclAux, ECLCluster *eclCluster)
Converts Mdst_ecl(_aux) record to ECLCluster object.
CollisionInvariantMass m_collisionInvM
CollisionInvariantMass for the invariant mass of the beam.
bool m_convertBeamParameters
Convert beam parameters or use information stored in Belle II database.
static double acc_pid(const Belle::Mdst_charged &chg, int idp)
Returns ACC likelihood for given hypothesis idp.
virtual void beginRun() override
Module functions to be called from event process.
StoreArray< Track > m_tracks
Tracks.
void convertBeamEnergy()
Stores beam parameters (energy, angles) in CollisionInvariantMass and CollisionBoostVector (currently...
void convertPIDData(const Belle::Mdst_charged &belleTrack, const Track *track)
Get PID information for belleTrack and add it to PIDLikelihood (with relation from track).
void convertMdstKLMObject(const Belle::Mdst_klm_cluster &klm, KLMCluster *klmCluster)
Converts Mdst_klm_cluster record to KLMCluster object.
Belle2::MCParticleGraph m_particleGraph
MCParticle Graph to build Belle2 MC Particles.
void convertMdstKLongTable()
Reads all entries of Mdst_Klong Panther table, creates a particle list 'K_L0:mdst' and adds them to S...
OptionalDBObjPtr< BeamSpot > m_beamSpotDB
BeamSpot for IP.
bool m_realData
flag that tells whether given data sample is for real data or MC
StoreArray< ECLCluster > m_eclClusters
ECL clusters.
void convertGenHepevtObject(const Belle::Gen_hepevt &genHepevt, MCParticleGraph::GraphParticle *mcParticle)
Converts Gen_hepevt record to MCParticleGraph object.
void initializeDataStore()
Initializes Belle II DataStore.
void convertMdstECLTable()
Reads and converts all entries of Mdst_ecl(_aux) Panther table to ECLCluster dataobjects and adds the...
CollisionBoostVector m_collisionBoostVector
CollisionBoostVector for bosst vector of the beam.
std::string m_mcMatchingModeString
MC matching mode.
int m_lastIPProfileBin
variable to tell us which IPProfile bin was active last time we looked
void convertMdstKLMTable()
Reads and converts all entries of Mdst_klm_cluster Panther table to KLMCluster dataobjects and adds t...
bool m_convertRecTrg
Flag to switch on conversion of rectrg_summary3.
std::map< int, int > mdstGammaToParticle
map of gamma Panther IDs and corresponding Particle StoreArray indices
static const Const::ChargedStable c_belleHyp_to_chargedStable[c_nHyp]
maps Belle hypotheses to Const::ChargedStable (from http://belle.kek.jp/secured/wiki/doku....
std::map< int, int > mdstKlongToParticle
map of Klong Panther IDs and corresponding Particle StoreArray indices
double m_matchType2E9oE25Threshold
E9/E25 threshold value clusters with a value above this threshold are classified as neutral even if t...
void convertMdstChargedObject(const Belle::Mdst_charged &belleTrack, Track *track)
Converts Mdst_charged (Mdst_trk(_fit)) record to Track (TrackFitResult) object.
StoreArray< MCParticle > m_mcParticles
MC particles.
void convertMdstVee2Table()
Reads and converts all entries of Mdst_vee2 Panther table to V0 dataobjects and adds them to StoreArr...
StoreArray< PIDLikelihood > m_pidLikelihoods
output PIDLikelihood array.
std::map< int, int > mdstEclToECLCluster
map of Mdst_ecl Panther IDs and corresponding ECLCluster StoreArray indices
TrackFitResult createTrackFitResult(const CLHEP::HepLorentzVector &momentum, const HepPoint3D &position, const CLHEP::HepSymMatrix &error, const short int charge, const Const::ParticleType &pType, const float pValue, const uint64_t hitPatternCDCInitializer, const uint32_t hitPatternVXDInitializer, const uint16_t ndf)
Creates TrackFitResult and fills it.
virtual ~B2BIIConvertMdstModule() override
Destructor.
const double BFIELD
B filed in TESLA.
MCMatchingMode m_mcMatchingMode
C matching mode.
StoreArray< BelleTrkExtra > m_belleTrkExtra
Belle CDC extra information.
bool m_use6x6CovarianceMatrix4Tracks
flag that tells which form of covariance matrix should be used in the conversion of charged tracks
int recoverMoreThan24bitIDHEP(int id)
Helper function to recover falsely set idhep info in GenHepEvt list.
bool m_convertTrkExtra
Flag to switch on conversion of first(last)_{x,y,z} of mdst_trk_fit.
int getHelixParameters(const Belle::Mdst_trk_fit &trk_fit, const double mass, const HepPoint3D &newPivot, std::vector< float > &helixParams, CLHEP::HepSymMatrix &error5x5, CLHEP::HepLorentzVector &momentum, HepPoint3D &position, CLHEP::HepSymMatrix &error7x7, const double dPhi=0.0)
Fills Helix parameters (converted to Belle II version), 5x5 error matrix, 4-momentum,...
static const int c_nHyp
Number of Belle track hypotheses (see c_belleHyp_to_chargedStable).
void convertEvtclsTable()
Reads and converts all entries of evtcls Panther table.
This class contains the beam spot position and size modeled as a gaussian distribution in space.
Definition: BeamSpot.h:22
void setIP(const TVector3 &ipPosition, const TMatrixDSym &covariance)
Set the IP position and its error matrix.
Definition: BeamSpot.h:59
Helix parameter class.
Definition: Helix.h:48
This class contains the measured values of the orientation of the collision axis in the CM system obt...
double getAngleYZ() const
Get the mean YZ angle of the HER beam in the CM frame obtained by pure boost.
void setSpread(const TMatrixDSym &spreadCovariance, double spreadXZunc, double spreadYZunc, double spreadPhiUnc)
Set spread covariance and uncertainties of the eigenvalues of this matrix.
double getAngleXZ() const
Get the mean XZ angle of the HER beam in the CM frame obtained by pure boost.
void setAngles(double angleXZ, double angleYZ, const TMatrixDSym &centerCovariance)
Set the central values and uncertainty of them.
This class contains the measured average boost vector vec(beta) = (beta_x, beta_y,...
void setBoost(const TVector3 &boost, const TMatrixDSym &covariance)
Set the boost vector and its error matrix.
This class contains the measured average center-of-mass energy, which is equal to the invariant mass ...
void setMass(double mass, double error, double spread)
Set the CMS energy and its uncertainty.
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:589
The ParticleType class for identifying different particle types.
Definition: Const.h:408
int getPDGCode() const
PDG code.
Definition: Const.h:473
double getMass() const
Particle mass.
Definition: UnitConst.cc:353
A class for sets of detector IDs whose content is limited to restricted set of valid detector IDs.
Definition: Const.h:296
static const ChargedStable muon
muon particle
Definition: Const.h:660
EDetector
Enum for identifying the detector components (detector and subdetector).
Definition: Const.h:42
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:678
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
static const double electronMass
electron mass
Definition: Const.h:685
static const ChargedStable proton
proton particle
Definition: Const.h:663
static const ParticleType antiNeutron
Anti-neutron particle.
Definition: Const.h:676
static const ChargedStable kaon
charged kaon particle
Definition: Const.h:662
static const ParticleType photon
photon particle
Definition: Const.h:673
static const ChargedStable electron
electron particle
Definition: Const.h:659
static const ChargedStable deuteron
deuteron particle
Definition: Const.h:664
ECL cluster data.
Definition: ECLCluster.h:27
void setE9oE21(double E9oE21)
Set E9/E21 energy ratio.
Definition: ECLCluster.h:193
void addHypothesis(EHypothesisBit bitmask)
Add bitmask to current hypothesis.
Definition: ECLCluster.h:129
void setTheta(double theta)
Set Theta of Shower (radian).
Definition: ECLCluster.h:217
void setPhi(double phi)
Set Phi of Shower (radian).
Definition: ECLCluster.h:220
double getPhi() const
Return Corrected Phi of Shower (radian).
Definition: ECLCluster.h:304
void setdeltaL(double deltaL)
Set deltaL for shower shape.
Definition: ECLCluster.h:172
void setEnergyHighestCrystal(double energyhighestcrystal)
Set energy of highest energetic crystal (GeV).
Definition: ECLCluster.h:232
void setEnergyRaw(double energyraw)
Set Incorrect Energy deposited (GeV).
Definition: ECLCluster.h:229
void setTime(double time)
Set time information.
Definition: ECLCluster.h:211
void setCovarianceMatrix(double covArray[6])
Set covariance matrix (3x3), i.e.
Definition: ECLCluster.h:152
void setMinTrkDistance(double distance)
Set distance between cluster COG and track extrapolation to ECL.
Definition: ECLCluster.h:175
int getDetectorRegion() const
Return detector region: 0: below acceptance, 1: FWD, 2: BRL, 3: BWD, 11: FWDGAP, 13: BWDGAP.
Definition: ECLCluster.cc:70
void setLAT(double LAT)
Set Lateral distribution parameter.
Definition: ECLCluster.h:205
double getEnergy(EHypothesisBit hypothesis) const
Return Energy (GeV).
Definition: ECLCluster.cc:23
void setNumberOfCrystals(double noc)
Set number of crystals (sum of weights).
Definition: ECLCluster.h:208
void setEnergy(double energy)
Set Corrected Energy (GeV).
Definition: ECLCluster.h:226
double getTheta() const
Return Corrected Theta of Shower (radian).
Definition: ECLCluster.h:307
void setIsTrack(bool istrack)
Set m_isTrack true if the cluster matches with a track.
Definition: ECLCluster.h:104
@ c_nPhotons
CR is split into n photons (N1)
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
void setR(double r)
Set R (in cm).
Definition: ECLCluster.h:223
Hit pattern of CDC hits within a track.
Definition: HitPatternCDC.h:35
void setNHits(unsigned short nHits)
Sets the 8 MSBs to the total number of hits in the CDC.
ULong64_t getInteger() const
Getter for underlying integer type.
Hit pattern of the VXD within a track.
Definition: HitPatternVXD.h:37
unsigned int getInteger() const
Getter for the underlying integer.
Definition: HitPatternVXD.h:58
void setSVDLayer(const unsigned short layerId, unsigned short uHits, unsigned short vHits)
Set the number of hits in a specific layer of the SVD.
A class that describes the interval of experiments/runs for which an object in the database is valid.
KLM cluster data.
Definition: KLMCluster.h:28
void setLayers(int layers)
Set number of layers with hits.
Definition: KLMCluster.h:145
void setClusterPosition(float globalX, float globalY, float globalZ)
Set global position.
Definition: KLMCluster.h:161
void setInnermostLayer(int innermostLayer)
Set number of the innermost layer with hits.
Definition: KLMCluster.h:152
Class to represent Particle data in graph.
void decaysInto(GraphParticle &daughter)
Tells the graph that this particle decays into daughter.
size_t size() const
Return the number of particles in the graph.
void generateList(const std::string &name="", int options=c_setNothing)
Generates the MCParticle list and stores it in the StoreArray with the given name.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
void setDecayTime(float time)
Set decay time.
Definition: MCParticle.h:379
void setMass(float mass)
Set particle mass.
Definition: MCParticle.h:355
void setDecayVertex(const ROOT::Math::XYZVector &vertex)
Set decay vertex.
Definition: MCParticle.h:436
void setValidVertex(bool valid)
Set indication whether vertex and time information is valid or just default.
Definition: MCParticle.h:367
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
Definition: MCParticle.h:385
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
Definition: MCParticle.h:196
void setPDG(int pdg)
Set PDG code of the particle.
Definition: MCParticle.h:324
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:101
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets the 4Vector of particle.
Definition: MCParticle.h:427
void setStatus(unsigned short int status)
Set Status code for the particle.
Definition: MCParticle.h:335
void setProductionTime(float time)
Set production time.
Definition: MCParticle.h:373
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Class to collect log likelihoods from TOP, ARICH, dEdx, ECL and KLM aimed for output to mdst includes...
Definition: PIDLikelihood.h:29
Class to store reconstructed particles.
Definition: Particle.h:76
void appendDaughter(const Particle *daughter, const bool updateType=true, const int daughterProperty=c_Ordinary)
Appends index of daughter to daughters index array.
Definition: Particle.cc:707
void setVertex(const ROOT::Math::XYZVector &vertex)
Sets position (decay vertex)
Definition: Particle.h:306
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 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
static bool parallelProcessingUsed()
Returns true if multiple processes have been spawned, false in single-core mode.
Definition: ProcHandler.cc:226
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:62
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
Values of the result of a track fit with a given particle hypothesis.
Helix getHelix() const
Conversion to framework Helix (without covariance).
TMatrixDSym getCovariance5() const
Getter for covariance matrix of perigee parameters in matrix form.
short getChargeSign() const
Return track charge (1 or -1).
double getOmega() const
Getter for omega.
double getD0() const
Getter for d0.
double getTanLambda() const
Getter for tanLambda.
double getZ0() const
Getter for z0.
ROOT::Math::XYZVector getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
ROOT::Math::XYZVector getPosition() const
Getter for vector of position at closest approach of track in r/phi projection.
double getPhi0() const
Getter for phi0.
Class that bundles various TrackFitResults.
Definition: Track.h:25
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
const TMatrixDSym & getCovariance() const
Getter for covariance matrix of perigee parameters in matrix form.
static const double mm
[millimeters]
Definition: Unit.h:70
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
static Database & Instance()
Instance of a singleton Database.
Definition: Database.cc:41
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:26
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition: Database.cc:140
void addConstantOverride(const std::string &name, TObject *obj, bool oneRun=false)
Add constant override payload.
Definition: DBStore.cc:202
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
void clear()
Reset particles and decay information to make the class reusable.
GraphParticle & addParticle()
Add new particle to the graph.
double charge(int pdgCode)
Returns electric charge of a particle with given pdg code.
Definition: EvtPDLUtil.cc:44
Abstract base class for different kinds of events.