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