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