Belle II Software  release-05-02-19
CDCDedxPIDModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2012 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Jake Bennett, Christian Pulvermacher
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <reconstruction/modules/CDCDedxPID/CDCDedxPIDModule.h>
12 
13 #include <reconstruction/dataobjects/DedxConstants.h>
14 #include <reconstruction/modules/CDCDedxPID/LineHelper.h>
15 
16 #include <framework/gearbox/Const.h>
17 
18 #include <cdc/dataobjects/CDCHit.h>
19 #include <cdc/dataobjects/CDCRecoHit.h>
20 
21 #include <cdc/translators/LinearGlobalADCCountTranslator.h>
22 #include <cdc/translators/RealisticTDCCountTranslator.h>
23 
24 #include <cdc/geometry/CDCGeometryPar.h>
25 #include <tracking/dataobjects/RecoHitInformation.h>
26 
27 #include <genfit/AbsTrackRep.h>
28 #include <genfit/Exception.h>
29 #include <genfit/MaterialEffects.h>
30 #include <genfit/KalmanFitterInfo.h>
31 
32 #include <TH2F.h>
33 #include <TRandom.h>
34 
35 #include <memory>
36 #include <cmath>
37 #include <algorithm>
38 
39 using namespace Belle2;
40 using namespace CDC;
41 using namespace Dedx;
42 
43 REG_MODULE(CDCDedxPID)
44 
46 {
47  setPropertyFlags(c_ParallelProcessingCertified);
48 
49  //Set module properties
50  setDescription("Extract dE/dx and corresponding log-likelihood from fitted tracks and hits in the CDC.");
51 
52  //Parameter definitions
53  addParam("usePrediction", m_usePrediction,
54  "Use parameterized means and resolutions to determine PID values. If false, lookup table PDFs are used.", true);
55  addParam("removeLowest", m_removeLowest,
56  "Portion of events with low dE/dx that should be discarded", double(0.05));
57  addParam("removeHighest", m_removeHighest,
58  "Portion of events with high dE/dx that should be discarded", double(0.25));
59  addParam("useBackHalfCurlers", m_backHalfCurlers,
60  "Whether to use the back half of curlers", false);
61  addParam("enableDebugOutput", m_enableDebugOutput,
62  "Option to write out debugging information to CDCDedxTracks (DataStore objects).", true);
63  addParam("useIndividualHits", m_useIndividualHits,
64  "If using lookup table PDFs, include PDF value for each hit in likelihood. If false, the truncated mean of dedx values will be used.",
65  true);
66  addParam("ignoreMissingParticles", m_ignoreMissingParticles,
67  "Ignore particles for which no PDFs are found", false);
68  addParam("trackLevel", m_trackLevel,
69  "ONLY USEFUL FOR MC: Use track-level MC. If false, use hit-level MC", true);
70  addParam("onlyPrimaryParticles", m_onlyPrimaryParticles,
71  "ONLY USEFUL FOR MC: Only save data for primary particles", false);
72 }
73 
75 
77 {
78  if (!m_DBDedxPDFs) B2FATAL("No Dedx pdfs found in database");
79  //load dedx:momentum PDFs
80  int nBinsX, nBinsY;
81  double xMin, xMax, yMin, yMax;
82  nBinsX = nBinsY = -1;
83  xMin = xMax = yMin = yMax = 0.0;
84  for (unsigned int iPart = 0; iPart < 6; iPart++) {
85  const int pdgCode = Const::chargedStableSet.at(iPart).getPDGCode();
86  const TH2F* pdf = m_DBDedxPDFs->getCDCPDF(iPart, !m_useIndividualHits);
87 
88  if (pdf->GetEntries() == 0) {
89  if (m_ignoreMissingParticles)
90  continue;
91  B2FATAL("Couldn't find PDF for PDG " << pdgCode);
92  }
93 
94  //check that PDFs have the same dimensions and same binning
95  const double epsFactor = 1e-5;
96  if (nBinsX == -1 and nBinsY == -1) {
97  nBinsX = pdf->GetNbinsX();
98  nBinsY = pdf->GetNbinsY();
99  xMin = pdf->GetXaxis()->GetXmin();
100  xMax = pdf->GetXaxis()->GetXmax();
101  yMin = pdf->GetYaxis()->GetXmin();
102  yMax = pdf->GetYaxis()->GetXmax();
103  } else if (nBinsX != pdf->GetNbinsX()
104  or nBinsY != pdf->GetNbinsY()
105  or fabs(xMin - pdf->GetXaxis()->GetXmin()) > epsFactor * xMax
106  or fabs(xMax - pdf->GetXaxis()->GetXmax()) > epsFactor * xMax
107  or fabs(yMin - pdf->GetYaxis()->GetXmin()) > epsFactor * yMax
108  or fabs(yMax - pdf->GetYaxis()->GetXmax()) > epsFactor * yMax) {
109  B2FATAL("PDF for PDG " << pdgCode << " has binning/dimensions differing from previous PDF.");
110  }
111  }
112 }
113 
115 {
116 
117  // required inputs
118  m_tracks.isRequired();
119  m_recoTracks.isRequired();
120 
121  // optional inputs
122  m_mcparticles.isOptional();
123  m_tracks.optionalRelationTo(m_mcparticles);
124 
125  // register optional outputs
126  if (m_enableDebugOutput) {
127  m_dedxTracks.registerInDataStore();
128  m_tracks.registerRelationTo(m_dedxTracks);
129  }
130 
131  // register outputs
132  m_dedxLikelihoods.registerInDataStore();
133  m_tracks.registerRelationTo(m_dedxLikelihoods);
134 
135  m_DBDedxPDFs.addCallback([this]() { checkPDFs(); });
136  checkPDFs();
137 
138  // lookup table for number of wires per layer (indexed on superlayer)
139  m_nLayerWires[0] = 1280;
140  for (int i = 1; i < 9; ++i) {
141  m_nLayerWires[i] = m_nLayerWires[i - 1] + 6 * (160 + (i - 1) * 32);
142  }
143 
144  // make sure the mean and resolution parameters are reasonable
145  if (!m_DBMeanPars || m_DBMeanPars->getSize() == 0) {
146  B2WARNING("No dE/dx mean parameters!");
147  for (int i = 0; i < 15; ++i)
148  m_meanpars.push_back(1.0);
149  } else m_meanpars = m_DBMeanPars->getMeanPars();
150 
151  if (!m_DBSigmaPars || m_DBSigmaPars->getSize() == 0) {
152  B2WARNING("No dE/dx sigma parameters!");
153  for (int i = 0; i < 12; ++i)
154  m_sigmapars.push_back(1.0);
155  } else m_sigmapars = m_DBSigmaPars->getSigmaPars();
156 
157  // get the hadron correction parameters
158  if (!m_DBHadronCor || m_DBHadronCor->getSize() == 0) {
159  B2WARNING("No hadron correction parameters!");
160  for (int i = 0; i < 4; ++i)
161  m_hadronpars.push_back(0.0);
162  m_hadronpars.push_back(1.0);
163  } else m_hadronpars = m_DBHadronCor->getHadronPars();
164 
165  // create instances here to not confuse profiling
167 
168  if (!genfit::MaterialEffects::getInstance()->isInitialized()) {
169  B2FATAL("Need to have SetupGenfitExtrapolationModule in path before this one.");
170  }
171 }
172 
174 {
175  // go through Tracks
176  // get fitresult and RecoTrack and do extrapolations, save corresponding dE/dx and likelihood values
177  // get hit indices through RecoTrack::getHitPointsWithMeasurement(...)
178  // create one CDCDedxTrack per fitresult/recoTrack
179  // create one DedkLikelihood per Track (plus rel)
180 
181  // inputs
182  const int numMCParticles = m_mcparticles.getEntries();
183 
184  // get the geometry of the cdc
185  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
186 
187  // **************************************************
188  //
189  // LOOP OVER TRACKS
190  //
191  // **************************************************
192 
193  m_dedxTracks.clear();
194  m_dedxLikelihoods.clear();
195 
196  int mtrack = 0;
197  for (const auto& track : m_tracks) {
198  std::shared_ptr<CDCDedxTrack> dedxTrack = std::make_shared<CDCDedxTrack>();
199  dedxTrack->m_track = mtrack++;
200 
201  // load the pion fit hypothesis or the hypothesis which is the closest in mass to a pion
202  // the tracking will not always successfully fit with a pion hypothesis
203  const TrackFitResult* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
204  if (!fitResult) {
205  B2WARNING("No related fit for track ...");
206  continue;
207  }
208 
209  if ((m_enableDebugOutput or m_onlyPrimaryParticles) and numMCParticles != 0) {
210  // find MCParticle corresponding to this track
211  const MCParticle* mcpart = track.getRelatedTo<MCParticle>();
212 
213  if (mcpart) {
214  if (m_onlyPrimaryParticles && !mcpart->hasStatus(MCParticle::c_PrimaryParticle)) {
215  continue; //not a primary particle, ignore
216  }
217 
218  //add some MC truths to CDCDedxTrack object
219  dedxTrack->m_pdg = mcpart->getPDG();
220  dedxTrack->m_mcmass = mcpart->getMass();
221  const MCParticle* mother = mcpart->getMother();
222  dedxTrack->m_motherPDG = mother ? mother->getPDG() : 0;
223 
224  const TVector3 trueMomentum = mcpart->getMomentum();
225  dedxTrack->m_pTrue = trueMomentum.Mag();
226  dedxTrack->m_cosThetaTrue = trueMomentum.CosTheta();
227  }
228  } else {
229  dedxTrack->m_pdg = -999;
230  }
231 
232  // get momentum (at origin) from fit result
233  const TVector3& trackMom = fitResult->getMomentum();
234  dedxTrack->m_p = trackMom.Mag();
235  bool nomom = (dedxTrack->m_p != dedxTrack->m_p);
236  double costh = std::cos(std::atan(1 / fitResult->getCotTheta()));
237  int charge = 1;
238  if (!nomom) {
239  costh = trackMom.CosTheta();
240  charge = fitResult->getChargeSign();
241  }
242  dedxTrack->m_cosTheta = costh;
243  dedxTrack->m_charge = charge;
244 
245  // dE/dx values will be calculated using associated RecoTrack
246  const RecoTrack* recoTrack = track.getRelatedTo<RecoTrack>();
247  if (!recoTrack) {
248  B2WARNING("No related track for this fit...");
249  continue;
250  }
251 
252  // Check to see if the track is pruned
253  if (recoTrack->getTrackFitStatus()->isTrackPruned()) {
254  B2ERROR("GFTrack is pruned, please run CDCDedxPID only on unpruned tracks! Skipping this track.");
255  continue;
256  }
257 
258  // scale factor to make electron dE/dx ~ 1
259  dedxTrack->m_scale = (m_DBScaleFactor) ? m_DBScaleFactor->getScaleFactor() : 1.0;
260 
261  // store run gains only for data!
262  dedxTrack->m_runGain = (m_DBRunGain && m_usePrediction && numMCParticles == 0) ? m_DBRunGain->getRunGain() : 1.0;
263 
264  // get the cosine correction only for data!
265  dedxTrack->m_cosCor = (m_DBCosineCor && m_usePrediction && numMCParticles == 0) ? m_DBCosineCor->getMean(costh) : 1.0;
266 
267  // get the cosine edge correction only for data!
268  bool isEdge = false;
269  if ((abs(costh + 0.860) < 0.010) || (abs(costh - 0.955) <= 0.005))isEdge = true;
270  dedxTrack->m_cosEdgeCor = (m_DBCosEdgeCor && m_usePrediction && numMCParticles == 0
271  && isEdge) ? m_DBCosEdgeCor->getMean(costh) : 1.0;
272 
273  // initialize a few variables to be used in the loop over track points
274  double layerdE = 0.0; // total charge in current layer
275  double layerdx = 0.0; // total path length in current layer
276  double cdcMom = 0.0; // momentum valid in the CDC
277  int nhitscombined = 0; // number of hits combined per layer
278  int wirelongesthit = 0; // wire number of longest hit
279  double longesthit = 0; // path length of longest hit
280 
281  // loop over all CDC hits from this track
282  // Get the TrackPoints, which contain the hit information we need.
283  // Then iterate over each point.
284  int tpcounter = 0;
285  const std::vector< genfit::AbsTrackRep* >& gftrackRepresentations = recoTrack->getRepresentations();
286  const std::vector< genfit::TrackPoint* >& gftrackPoints = recoTrack->getHitPointsWithMeasurement();
287  for (std::vector< genfit::TrackPoint* >::const_iterator tp = gftrackPoints.begin();
288  tp != gftrackPoints.end(); ++tp) {
289  tpcounter++;
290 
291  // should also be possible to use this for svd and pxd hits...
292  genfit::AbsMeasurement* aAbsMeasurementPtr = (*tp)->getRawMeasurement(0);
293  const CDCRecoHit* cdcRecoHit = dynamic_cast<const CDCRecoHit* >(aAbsMeasurementPtr);
294  if (!cdcRecoHit) continue;
295  const CDCHit* cdcHit = cdcRecoHit->getCDCHit();
296  if (!cdcHit) continue;
297 
298  // get the poca on the wire and track momentum for this hit
299  // make sure the fitter info exists
300  const genfit::AbsFitterInfo* fi = (*tp)->getFitterInfo();
301  if (!fi) {
302  B2DEBUG(29, "No fitter info, skipping...");
303  continue;
304  }
305 
306  // get the wire ID (not between 0 and 14336) and the layer info
307  WireID wireID = cdcRecoHit->getWireID();
308  const int wire = wireID.getIWire(); // use getEWire() for encoded wire number
309  int layer = cdcHit->getILayer(); // layer within superlayer
310  int superlayer = cdcHit->getISuperLayer();
311 
312  // check which algorithm found this hit
313  int foundByTrackFinder = 0;
314  const RecoHitInformation* hitInfo = recoTrack->getRecoHitInformation(cdcHit);
315  foundByTrackFinder = hitInfo->getFoundByTrackFinder();
316 
317  // add weights for hypotheses
318  double weightPionHypo = 0;
319  double weightProtHypo = 0;
320  double weightKaonHypo = 0;
321  // loop over all the present hypotheses
322  for (std::vector<genfit::AbsTrackRep* >::const_iterator trep = gftrackRepresentations.begin();
323  trep != gftrackRepresentations.end(); ++trep) {
324  const int pdgCode = TMath::Abs((*trep)->getPDG());
325  // configured to only save weights for one of these 3
326  if (!(pdgCode == Const::pion.getPDGCode() ||
327  pdgCode == Const::kaon.getPDGCode() ||
328  pdgCode == Const::proton.getPDGCode())) continue;
329  const genfit::KalmanFitterInfo* kalmanFitterInfo = (*tp)->getKalmanFitterInfo(*trep);
330  if (kalmanFitterInfo == NULL) {
331  //B2WARNING("No KalmanFitterInfo for hit in "<<pdgCode<<" track representationt. Skipping.");
332  continue;
333  }
334 
335  // there are always 2 hits, one of which is ~1, the other ~0; or both ~0. Store only the largest.
336  std::vector<double> weights = kalmanFitterInfo->getWeights();
337  const double maxWeight = weights[0] > weights[1] ? weights[0] : weights[1];
338  if (pdgCode == Const::pion.getPDGCode()) weightPionHypo = maxWeight;
339  else if (pdgCode == Const::kaon.getPDGCode()) weightKaonHypo = maxWeight;
340  else if (pdgCode == Const::proton.getPDGCode()) weightProtHypo = maxWeight;
341 
342  }
343 
344  // continuous layer number
345  int currentLayer = (superlayer == 0) ? layer : (8 + (superlayer - 1) * 6 + layer);
346  int nextLayer = currentLayer;
347 
348  // dense packed wire number (between 0 and 14336)
349  const int iwire = (superlayer == 0) ? 160 * layer + wire : m_nLayerWires[superlayer - 1] + (160 + 32 *
350  (superlayer - 1)) * layer + wire;
351 
352  // if multiple hits in a layer, we may combine the hits
353  const bool lastHit = (tp + 1 == gftrackPoints.end());
354  bool lastHitInCurrentLayer = lastHit;
355  if (!lastHit) {
356  // peek at next hit
357  genfit::AbsMeasurement* aAbsMeasurementPtrNext = (*(tp + 1))->getRawMeasurement(0);
358  const CDCRecoHit* nextcdcRecoHit = dynamic_cast<const CDCRecoHit* >(aAbsMeasurementPtrNext);
359  // if next hit fails, assume this is the last hit in the layer
360  if (!nextcdcRecoHit || !(cdcRecoHit->getCDCHit()) || !((*(tp + 1))->getFitterInfo())) {
361  lastHitInCurrentLayer = true;
362  break;
363  }
364  const CDCHit* nextcdcHit = nextcdcRecoHit->getCDCHit();
365  const int nextILayer = nextcdcHit->getILayer();
366  const int nextSuperlayer = nextcdcHit->getISuperLayer();
367  nextLayer = (nextSuperlayer == 0) ? nextILayer : (8 + (nextSuperlayer - 1) * 6 + nextILayer);
368  lastHitInCurrentLayer = (nextLayer != currentLayer);
369  }
370 
371  // find the position of the endpoints of the sense wire
372  const TVector3& wirePosF = cdcgeo.wireForwardPosition(wireID, CDCGeometryPar::c_Aligned);
373  const TVector3& wirePosB = cdcgeo.wireBackwardPosition(wireID, CDCGeometryPar::c_Aligned);
374  const TVector3 wireDir = (wirePosB - wirePosF).Unit();
375 
376  int nWires = cdcgeo.nWiresInLayer(currentLayer);
377 
378  // radii of field wires for this layer
379  double inner = cdcgeo.innerRadiusWireLayer()[currentLayer];
380  double outer = cdcgeo.outerRadiusWireLayer()[currentLayer];
381 
382  double topHeight = outer - wirePosF.Perp();
383  double bottomHeight = wirePosF.Perp() - inner;
384  double cellHeight = topHeight + bottomHeight;
385  double topHalfWidth = M_PI * outer / nWires;
386  double bottomHalfWidth = M_PI * inner / nWires;
387  double cellHalfWidth = M_PI * wirePosF.Perp() / nWires;
388 
389  // first construct the boundary lines, then create the cell
390  const DedxPoint tl = DedxPoint(-topHalfWidth, topHeight);
391  const DedxPoint tr = DedxPoint(topHalfWidth, topHeight);
392  const DedxPoint br = DedxPoint(bottomHalfWidth, -bottomHeight);
393  const DedxPoint bl = DedxPoint(-bottomHalfWidth, -bottomHeight);
394  DedxDriftCell c = DedxDriftCell(tl, tr, br, bl);
395 
396  // make sure the MOP is reasonable (an exception is thrown for bad numerics)
397  try {
398  const genfit::MeasuredStateOnPlane& mop = fi->getFittedState();
399 
400  // use the MOP to determine the DOCA and entrance angle
401  B2Vector3D fittedPoca = mop.getPos();
402  const TVector3& pocaMom = mop.getMom();
403  if (tp == gftrackPoints.begin() || cdcMom == 0) {
404  cdcMom = pocaMom.Mag();
405  dedxTrack->m_pCDC = cdcMom;
406  }
407  if (nomom)
408  dedxTrack->m_p = cdcMom;
409 
410  // get the doca and entrance angle information.
411  // constructPlane places the coordinate center in the POCA to the
412  // wire. Using this is the default behavior. If this should be too
413  // slow, as it has to re-evaluate the POCA
414  // B2Vector3D pocaOnWire = cdcRecoHit->constructPlane(mop)->getO();
415 
416  // uses the plane determined by the track fit.
417  B2Vector3D pocaOnWire = mop.getPlane()->getO(); // DOUBLE CHECK THIS --\/
418 
419  // The vector from the wire to the track.
420  B2Vector3D B2WireDoca = fittedPoca - pocaOnWire;
421 
422  // the sign of the doca is defined here to be positive in the +x dir in the cell
423  double doca = B2WireDoca.Perp();
424  double phidiff = fittedPoca.Phi() - pocaOnWire.Phi();
425  // be careful about "wrap around" cases when the poca and wire are close, but
426  // the difference in phi is largy
427  if (phidiff > -3.1416 && (phidiff < 0 || phidiff > 3.1416)) doca *= -1;
428 
429  // The opening angle of the track momentum direction
430  const double px = pocaMom.x();
431  const double py = pocaMom.y();
432  const double wx = pocaOnWire.x();
433  const double wy = pocaOnWire.y();
434  const double cross = wx * py - wy * px;
435  const double dot = wx * px + wy * py;
436  double entAng = atan2(cross, dot);
437 
438  // re-scaled (RS) doca and entAng variable: map to square cell
439  double cellR = 2 * cellHalfWidth / cellHeight;
440  double tana = 100.0;
441  if (std::abs(2 * atan(1) - std::abs(entAng)) < 0.01)tana = 100 * (entAng / std::abs(entAng)); //avoid infinity at pi/2
442  else tana = std::tan(entAng);
443  double docaRS = doca * std::sqrt((1 + cellR * cellR * tana * tana) / (1 + tana * tana));
444  double entAngRS = std::atan(tana / cellR);
445 
447  int adcbaseCount = cdcHit->getADCCount(); // pedestal subtracted?
448  int adcCount = (m_DBNonlADC && m_usePrediction
449  && numMCParticles == 0) ? m_DBNonlADC->getCorrectedADC(adcbaseCount, currentLayer) : adcbaseCount;
450 
451  double hitCharge = translator.getCharge(adcCount, wireID, false, pocaOnWire.Z(), pocaMom.Phi());
452  int driftT = cdcHit->getTDCCount();
453 
454  // we want electrons to be one, so artificially scale the adcCount
455  double dadcCount = 1.0 * adcCount;
456  if (dedxTrack->m_scale != 0) dadcCount /= dedxTrack->m_scale;
457 
458  RealisticTDCCountTranslator realistictdc;
459  double driftDRealistic = realistictdc.getDriftLength(driftT, wireID, 0, true, pocaOnWire.Z(), pocaMom.Phi(), pocaMom.Theta());
460  double driftDRealisticRes = realistictdc.getDriftLengthResolution(driftDRealistic, wireID, true, pocaOnWire.Z(), pocaMom.Phi(),
461  pocaMom.Theta());
462 
463  // now calculate the path length for this hit
464  double celldx = c.dx(doca, entAng);
465  if (c.isValid()) {
466  // get the wire gain constant
467  double wiregain = (m_DBWireGains && m_usePrediction && numMCParticles == 0) ? m_DBWireGains->getWireGain(iwire) : 1.0;
468 
469  //normalization of rescaled doca wrt cell size for layer dependent 2D corrections
470  double normDocaRS = docaRS / cellHalfWidth;
471  double twodcor = (m_DB2DCell && m_usePrediction
472  && numMCParticles == 0) ? m_DB2DCell->getMean(currentLayer, normDocaRS, entAngRS) : 1.0;
473 
474  // get the 1D cleanup correction
475  double onedcor = (m_DB1DCell && m_usePrediction && numMCParticles == 0) ? m_DB1DCell->getMean(currentLayer, entAngRS) : 1.0;
476 
477  // apply the calibration to dE to propagate to both hit and layer measurements
478  // Note: could move the sin(theta) here since it is common accross the track
479  // It is applied in two places below (hit level and layer level)
480  double correction = dedxTrack->m_runGain * dedxTrack->m_cosCor * dedxTrack->m_cosEdgeCor * wiregain * twodcor * onedcor;
481 
482  // --------------------
483  // save individual hits (even for dead wires)
484  // --------------------
485  if (correction != 0) dadcCount = dadcCount / correction;
486  else dadcCount = 0;
487 
488  double cellDedx = (dadcCount / celldx);
489 
490  // correct for path length through the cell
491  if (nomom) cellDedx *= std::sin(std::atan(1 / fitResult->getCotTheta()));
492  else cellDedx *= std::sin(trackMom.Theta());
493 
494  if (m_enableDebugOutput)
495  dedxTrack->addHit(wire, iwire, currentLayer, doca, docaRS, entAng, entAngRS,
496  adcCount, adcbaseCount, hitCharge, celldx, cellDedx, cellHeight, cellHalfWidth, driftT,
497  driftDRealistic, driftDRealisticRes, wiregain, twodcor, onedcor,
498  foundByTrackFinder, weightPionHypo, weightKaonHypo, weightProtHypo);
499 
500  // --------------------
501  // save layer hits only with active wires
502  // --------------------
503  if (correction != 0) {
504 
505  layerdE += dadcCount;
506  layerdx += celldx;
507 
508  if (celldx > longesthit) {
509  longesthit = celldx;
510  wirelongesthit = iwire;
511  }
512  nhitscombined++;
513  }
514  }
515  } catch (genfit::Exception&) {
516  B2WARNING("Track: " << mtrack << ": genfit::MeasuredStateOnPlane exception...");
517  continue;
518  }
519 
520  // check if there are any more hits in this layer
521  if (lastHitInCurrentLayer) {
522  if (layerdx > 0) {
523  double totalDistance;
524  if (nomom) totalDistance = layerdx / std::sin(std::atan(1 / fitResult->getCotTheta()));
525  else totalDistance = layerdx / std::sin(trackMom.Theta());
526  double layerDedx = layerdE / totalDistance;
527 
528  // save the information for this layer
529  if (layerDedx > 0) {
530  dedxTrack->addDedx(nhitscombined, wirelongesthit, currentLayer, totalDistance, layerDedx);
531  // save the PID information if using individual hits
532  if (m_useIndividualHits) {
533  // use the momentum valid in the cdc
534  saveLookupLogl(dedxTrack->m_cdcLogl, dedxTrack->m_pCDC, layerDedx);
535  }
536  }
537  }
538  // stop when the track starts to curl
539  if (!m_backHalfCurlers && nextLayer < currentLayer) break;
540 
541  layerdE = 0;
542  layerdx = 0;
543  nhitscombined = 0;
544  wirelongesthit = 0;
545  longesthit = 0;
546  }
547  } // end of loop over CDC hits for this track
548 
549  // Determine the number of hits to be used
550  //m_lDedx is a ector for layerDedx and created w/ ->adddedx method above
551  if (dedxTrack->m_lDedx.empty()) {
552  B2DEBUG(29, "Found track with no hits, ignoring.");
553  continue;
554  } else {
555  // determine the number of hits for this track (used below)
556  const int numDedx = dedxTrack->m_lDedx.size();
557  // add a factor of 0.51 here to make sure we are rounding appropriately...
558  const int lowEdgeTrunc = int(numDedx * m_removeLowest + 0.51);
559  const int highEdgeTrunc = int(numDedx * (1 - m_removeHighest) + 0.51);
560  dedxTrack->m_lNHitsUsed = highEdgeTrunc - lowEdgeTrunc;
561  }
562 
563  // Get the truncated mean
564  //
565  // If using track-level MC, get the predicted mean and resolution and throw a random
566  // number to get the simulated dE/dx truncated mean. Otherwise, calculate the truncated
567  // mean from the simulated hits (hit-level MC).
568  if (!m_useIndividualHits or m_enableDebugOutput) {
569  calculateMeans(&(dedxTrack->m_dedxAvg),
570  &(dedxTrack->m_dedxAvgTruncatedNoSat),
571  &(dedxTrack->m_dedxAvgTruncatedErr),
572  dedxTrack->m_lDedx);
573 
574  // apply the "hadron correction" only to data
575  if (numMCParticles == 0)
576  dedxTrack->m_dedxAvgTruncated = D2I(costh, I2D(costh, 1.00) / 1.00 * dedxTrack->m_dedxAvgTruncatedNoSat);
577  else dedxTrack->m_dedxAvgTruncated = dedxTrack->m_dedxAvgTruncatedNoSat;
578  }
579 
580  // If this is a MC track, get the track-level dE/dx
581  if (numMCParticles != 0 && dedxTrack->m_mcmass > 0 && dedxTrack->m_pTrue != 0) {
582  // determine the predicted mean and resolution
583  double mean = getMean(dedxTrack->m_pCDC / dedxTrack->m_mcmass);
584  double sigma = getSigma(mean, dedxTrack->m_lNHitsUsed, std::sqrt(1 - dedxTrack->m_cosTheta * dedxTrack->m_cosTheta));
585  dedxTrack->m_simDedx = gRandom->Gaus(mean, sigma);
586  while (dedxTrack->m_simDedx < 0)
587  dedxTrack->m_simDedx = gRandom->Gaus(mean, sigma);
588  if (m_trackLevel)
589  dedxTrack->m_dedxAvgTruncated = dedxTrack->m_simDedx;
590  }
591 
592  // save the PID information for both lookup tables and parameterized means and resolutions
593  saveChiValue(dedxTrack->m_cdcChi, dedxTrack->m_predmean, dedxTrack->m_predres, dedxTrack->m_pCDC, dedxTrack->m_dedxAvgTruncated,
594  std::sqrt(1 - dedxTrack->m_cosTheta * dedxTrack->m_cosTheta), dedxTrack->m_lNHitsUsed);
595  if (!m_useIndividualHits)
596  saveLookupLogl(dedxTrack->m_cdcLogl, dedxTrack->m_pCDC, dedxTrack->m_dedxAvgTruncated);
597 
598  // save CDCDedxLikelihood
599  // use parameterized method if called or if pdf file for lookup tables are empty
600  double pidvalues[Const::ChargedStable::c_SetSize];
602  if (m_usePrediction) {
603  for (const Const::ChargedStable& pdgIter : set) {
604  pidvalues[pdgIter.getIndex()] = -0.5 * dedxTrack->m_cdcChi[pdgIter.getIndex()] * dedxTrack->m_cdcChi[pdgIter.getIndex()];
605  }
606  } else {
607  for (const Const::ChargedStable& pdgIter : set) {
608  pidvalues[pdgIter.getIndex()] = dedxTrack->m_cdcLogl[pdgIter.getIndex()];
609  }
610  }
611 
612  CDCDedxLikelihood* likelihoodObj = m_dedxLikelihoods.appendNew(pidvalues);
613  track.addRelationTo(likelihoodObj);
614 
615  if (m_enableDebugOutput) {
616  // book the information for this track
617  CDCDedxTrack* newCDCDedxTrack = m_dedxTracks.appendNew(*dedxTrack);
618  track.addRelationTo(newCDCDedxTrack);
619  }
620 
621  } // end of loop over tracks
622 }
623 
625 {
626 
627  B2DEBUG(29, "CDCDedxPIDModule exiting");
628 }
629 
630 void CDCDedxPIDModule::calculateMeans(double* mean, double* truncatedMean, double* truncatedMeanErr,
631  const std::vector<double>& dedx) const
632 {
633  // Calculate the truncated average by skipping the lowest & highest
634  // events in the array of dE/dx values
635  std::vector<double> sortedDedx = dedx;
636  std::sort(sortedDedx.begin(), sortedDedx.end());
637  sortedDedx.erase(std::remove(sortedDedx.begin(), sortedDedx.end(), 0), sortedDedx.end());
638  sortedDedx.shrink_to_fit();
639 
640  double truncatedMeanTmp = 0.0;
641  double meanTmp = 0.0;
642  double sumOfSquares = 0.0;
643  int numValuesTrunc = 0;
644  const int numDedx = sortedDedx.size();
645 
646  // add a factor of 0.51 here to make sure we are rounding appropriately...
647  const int lowEdgeTrunc = int(numDedx * m_removeLowest + 0.51);
648  const int highEdgeTrunc = int(numDedx * (1 - m_removeHighest) + 0.51);
649  for (int i = 0; i < numDedx; i++) {
650  meanTmp += sortedDedx[i];
651  if (i >= lowEdgeTrunc and i < highEdgeTrunc) {
652  truncatedMeanTmp += sortedDedx[i];
653  sumOfSquares += sortedDedx[i] * sortedDedx[i];
654  numValuesTrunc++;
655  }
656  }
657 
658  if (numDedx != 0) {
659  meanTmp /= numDedx;
660  }
661  if (numValuesTrunc != 0) {
662  truncatedMeanTmp /= numValuesTrunc;
663  } else {
664  truncatedMeanTmp = meanTmp;
665  }
666 
667  *mean = meanTmp;
668  *truncatedMean = truncatedMeanTmp;
669 
670  if (numValuesTrunc > 1) {
671  *truncatedMeanErr = sqrt(sumOfSquares / double(numValuesTrunc) - truncatedMeanTmp * truncatedMeanTmp) / double(
672  numValuesTrunc - 1);
673  } else {
674  *truncatedMeanErr = 0;
675  }
676 }
677 
678 void CDCDedxPIDModule::saveLookupLogl(double(&logl)[Const::ChargedStable::c_SetSize], double p, double dedx)
679 {
680  //all pdfs have the same dimensions
681  const TH2F* pdf = m_DBDedxPDFs->getCDCPDF(0, !m_useIndividualHits);
682  const Int_t binX = pdf->GetXaxis()->FindFixBin(p);
683  const Int_t binY = pdf->GetYaxis()->FindFixBin(dedx);
684 
685  for (unsigned int iPart = 0; iPart < Const::ChargedStable::c_SetSize; iPart++) {
686  pdf = m_DBDedxPDFs->getCDCPDF(iPart, !m_useIndividualHits);
687  if (pdf->GetEntries() == 0) { //might be NULL if m_ignoreMissingParticles is set
688  B2WARNING("NO CDC PDFS...");
689  continue;
690  }
691  double probability = 0.0;
692 
693  //check if this is still in the histogram, take overflow bin otherwise
694  if (binX < 1 or binX > pdf->GetNbinsX()
695  or binY < 1 or binY > pdf->GetNbinsY()) {
696  probability = pdf->GetBinContent(binX, binY);
697  } else {
698  //in normal histogram range. Of course ROOT has a bug that Interpolate()
699  //is not declared as const but it does not modify the internal state so
700  //fine, const_cast it is.
701  probability = const_cast<TH2F*>(pdf)->Interpolate(p, dedx);
702  }
703 
704  if (probability != probability)
705  B2ERROR("probability NAN for a track with p=" << p << " and dedx=" << dedx);
706 
707  //my pdfs aren't perfect...
708  if (probability == 0.0)
709  probability = m_useIndividualHits ? (1e-5) : (1e-3); //likelihoods for truncated mean are much higher
710  logl[iPart] += log(probability);
711  }
712 }
713 
714 double CDCDedxPIDModule::D2I(const double cosTheta, const double D) const
715 {
716  double absCosTheta = fabs(cosTheta);
717  double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
718  if (projection == 0) {
719  B2WARNING("Something wrong with dE/dx hadron constants!");
720  return D;
721  }
722 
723  double chargeDensity = D / projection;
724  double numerator = 1 + m_hadronpars[0] * chargeDensity;
725  double denominator = 1 + m_hadronpars[1] * chargeDensity;
726 
727  if (denominator == 0) {
728  B2WARNING("Something wrong with dE/dx hadron constants!");
729  return D;
730  }
731 
732  double I = D * m_hadronpars[4] * numerator / denominator;
733  return I;
734 }
735 
736 double CDCDedxPIDModule::I2D(const double cosTheta, const double I) const
737 {
738  double absCosTheta = fabs(cosTheta);
739  double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
740 
741  if (projection == 0 || m_hadronpars[4] == 0) {
742  B2WARNING("Something wrong with dE/dx hadron constants!");
743  return I;
744  }
745 
746  double a = m_hadronpars[0] / projection;
747  double b = 1 - m_hadronpars[1] / projection * (I / m_hadronpars[4]);
748  double c = -1.0 * I / m_hadronpars[4];
749 
750  if (b == 0 && a == 0) {
751  B2WARNING("both a and b coefficiants for hadron correction are 0");
752  return I;
753  }
754 
755  double D = (a != 0) ? (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a) : -c / b;
756  if (D < 0) {
757  B2WARNING("D is less 0! will try another solution");
758  D = (a != 0) ? (-b - sqrt(b * b + 4.0 * a * c)) / (2.0 * a) : -c / b;
759  if (D < 0) {
760  B2WARNING("D is still less 0! just return uncorrectecd value");
761  return I;
762  }
763  }
764 
765  return D;
766 }
767 
768 double CDCDedxPIDModule::meanCurve(double* x, double* par, int version) const
769 {
770  // calculate the predicted mean value as a function of beta-gamma (bg)
771  // this is done with a different function depending on the value of bg
772  double f = 0;
773 
774  if (version == 0) {
775  if (par[0] == 1)
776  f = par[1] * std::pow(std::sqrt(x[0] * x[0] + 1), par[3]) / std::pow(x[0], par[3]) *
777  (par[2] - par[5] * std::log(1 / x[0])) - par[4] + std::exp(par[6] + par[7] * x[0]);
778  else if (par[0] == 2)
779  f = par[1] * std::pow(x[0], 3) + par[2] * x[0] * x[0] + par[3] * x[0] + par[4];
780  else if (par[0] == 3)
781  f = -1.0 * par[1] * std::log(par[4] + std::pow(1 / x[0], par[2])) + par[3];
782  }
783 
784  return f;
785 }
786 
787 double CDCDedxPIDModule::getMean(double bg) const
788 {
789  // define the section of the mean to use
790  double A = 0, B = 0, C = 0;
791  if (bg < 4.5)
792  A = 1;
793  else if (bg < 10)
794  B = 1;
795  else
796  C = 1;
797 
798  double x[1]; x[0] = bg;
799  double parsA[9];
800  double parsB[5];
801  double parsC[5];
802 
803  parsA[0] = 1; parsB[0] = 2; parsC[0] = 3;
804  for (int i = 0; i < 15; ++i) {
805  if (i < 7) parsA[i + 1] = m_meanpars[i];
806  else if (i < 11) parsB[i % 7 + 1] = m_meanpars[i];
807  else parsC[i % 11 + 1] = m_meanpars[i];
808  }
809 
810  // calculate dE/dx from the Bethe-Bloch mean
811  double partA = meanCurve(x, parsA, 0);
812  double partB = meanCurve(x, parsB, 0);
813  double partC = meanCurve(x, parsC, 0);
814 
815  return (A * partA + B * partB + C * partC);
816 }
817 
818 double CDCDedxPIDModule::sigmaCurve(double* x, double* par, int version) const
819 {
820  // calculate the predicted mean value as a function of beta-gamma (bg)
821  // this is done with a different function depending dE/dx, nhit, and sin(theta)
822  double f = 0;
823 
824  if (version == 0) {
825  if (par[0] == 1) { // return dedx parameterization
826  f = par[1] + par[2] * x[0];
827  } else if (par[0] == 2) { // return nhit or sin(theta) parameterization
828  f = par[1] * std::pow(x[0], 4) + par[2] * std::pow(x[0], 3) +
829  par[3] * x[0] * x[0] + par[4] * x[0] + par[5];
830  }
831  }
832 
833  return f;
834 }
835 
836 
837 double CDCDedxPIDModule::getSigma(double dedx, double nhit, double sin) const
838 {
839  if (nhit < 5) nhit = 5;
840  if (sin > 0.99) sin = 0.99;
841 
842  double x[1];
843  double dedxpar[3];
844  double nhitpar[6];
845  double sinpar[6];
846 
847  dedxpar[0] = 1; nhitpar[0] = 2; sinpar[0] = 2;
848  for (int i = 0; i < 5; ++i) {
849  if (i < 2) dedxpar[i + 1] = m_sigmapars[i];
850  nhitpar[i + 1] = m_sigmapars[i + 2];
851  sinpar[i + 1] = m_sigmapars[i + 7];
852  }
853 
854  // determine sigma from the parameterization
855  x[0] = dedx;
856  double corDedx = sigmaCurve(x, dedxpar, 0);
857  x[0] = nhit;
858  double corNHit = sigmaCurve(x, nhitpar, 0);
859  if (nhit > 42) corNHit = 1.0;
860  x[0] = sin;
861  double corSin = sigmaCurve(x, sinpar, 0);
862 
863  return (corDedx * corSin * corNHit);
864 }
865 
867  double(&predmean)[Const::ChargedStable::c_SetSize], double(&predsigma)[Const::ChargedStable::c_SetSize], double p, double dedx,
868  double sin, int nhit) const
869 {
870  // determine a chi value for each particle type
872  for (const Const::ChargedStable& pdgIter : set) {
873  double bg = p / pdgIter.getMass();
874 
875  // determine the predicted mean and resolution
876  double mean = getMean(bg);
877  double sigma = getSigma(mean, nhit, sin);
878 
879  predmean[pdgIter.getIndex()] = mean;
880  predsigma[pdgIter.getIndex()] = sigma;
881 
882  // fill the chi value for this particle type
883  if (sigma != 0) chi[pdgIter.getIndex()] = ((dedx - mean) / (sigma));
884  }
885 }
genfit::Exception
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
Belle2::CDCDedxPIDModule
Extract CDC dE/dx information from fitted tracks.
Definition: CDCDedxPIDModule.h:74
Belle2::CDCHit::getISuperLayer
unsigned short getISuperLayer() const
Getter for iSuperLayer.
Definition: CDCHit.h:195
Belle2::Const::ChargedStable::c_SetSize
static const unsigned int c_SetSize
Number of elements (for use in array bounds etc.)
Definition: Const.h:491
Belle2::RecoTrack::getTrackFitStatus
const genfit::FitStatus * getTrackFitStatus(const genfit::AbsTrackRep *representation=nullptr) const
Return the track fit status for the given representation or for the cardinal one. You are not allowed...
Definition: RecoTrack.h:537
Belle2::WireID
Class to identify a wire inside the CDC.
Definition: WireID.h:44
Belle2::CDC::RealisticTDCCountTranslator::getDriftLengthResolution
double getDriftLengthResolution(double driftLength, const WireID &wireID=WireID(), bool leftRight=false, double z=0, double alpha=0, double=static_cast< double >(TMath::Pi()/2.)) override
Get position resolution^2 corresponding to the drift length from getDriftLength of this class.
Definition: RealisticTDCCountTranslator.cc:140
Belle2::B2Vector3::Perp
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:199
Belle2::CDCDedxTrack::m_mcmass
double m_mcmass
MC PID mass.
Definition: CDCDedxTrack.h:301
Belle2::CDCDedxTrack::m_scale
double m_scale
scale factor to make electrons ~1
Definition: CDCDedxTrack.h:308
Belle2::CDC::CDCGeometryPar::wireForwardPosition
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
Definition: CDCGeometryPar.cc:1625
Belle2::CDCDedxTrack::m_cosThetaTrue
double m_cosThetaTrue
MC true cos(theta)
Definition: CDCDedxTrack.h:304
genfit::MeasuredStateOnPlane
#StateOnPlane with additional covariance matrix.
Definition: MeasuredStateOnPlane.h:39
Belle2::CDC::RealisticTDCCountTranslator
Translator mirroring the realistic Digitization.
Definition: RealisticTDCCountTranslator.h:36
genfit::FitStatus::isTrackPruned
bool isTrackPruned() const
Has the track been pruned after the fit?
Definition: FitStatus.h:116
Belle2::CDCDedxLikelihood
Container for likelihoods obtained by the CDC dE/dx PID (CDCDedxPIDModule).
Definition: CDCDedxLikelihood.h:34
Belle2::CDC::CDCGeometryPar::innerRadiusWireLayer
const double * innerRadiusWireLayer() const
Returns an array of inner radius of wire layers.
Definition: CDCGeometryPar.cc:1709
Belle2::TrackFitResult::getMomentum
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Definition: TrackFitResult.h:116
genfit::AbsFitterInfo
This class collects all information needed and produced by a specific AbsFitter and is specific to on...
Definition: AbsFitterInfo.h:42
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::CDCDedxTrack::m_motherPDG
double m_motherPDG
MC PID of mother particle.
Definition: CDCDedxTrack.h:302
Belle2::CDCHit
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:51
Belle2::CDC::LinearGlobalADCCountTranslator
This class simply assumes a linear translation through (0,0)
Definition: LinearGlobalADCCountTranslator.h:31
Belle2::CDCDedxTrack::m_cosCor
double m_cosCor
calibration cosine correction
Definition: CDCDedxTrack.h:309
Belle2::CDCHit::getTDCCount
short getTDCCount() const
Getter for TDC count.
Definition: CDCHit.h:230
Belle2::CDCDedxTrack::m_cosEdgeCor
double m_cosEdgeCor
calibration cosine edge correction
Definition: CDCDedxTrack.h:310
Belle2::CDCDedxPIDModule::getMean
double getMean(double bg) const
calculate the predicted mean using the parameterized resolution
Definition: CDCDedxPIDModule.cc:787
Belle2::CDCDedxPIDModule::getSigma
double getSigma(double dedx, double nhit, double sin) const
calculate the predicted resolution using the parameterized resolution
Definition: CDCDedxPIDModule.cc:837
Belle2::Const::chargedStableSet
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:494
Belle2::Const::ParticleType::getPDGCode
int getPDGCode() const
PDG code.
Definition: Const.h:349
Belle2::CDCDedxPIDModule::saveLookupLogl
void saveLookupLogl(double(&logl)[Const::ChargedStable::c_SetSize], double p, double dedx)
for all particles, save log-likelihood values into 'logl'.
Definition: CDCDedxPIDModule.cc:678
Belle2::Const::ParticleSet
A set of ParticleType objects, with defined order.
Definition: Const.h:393
Belle2::RecoTrack::getRepresentations
const std::vector< genfit::AbsTrackRep * > & getRepresentations() const
Return a list of track representations. You are not allowed to modify or delete them!
Definition: RecoTrack.h:554
Belle2::CDCDedxTrack::addDedx
void addDedx(int nhitscombined, int wirelongesthit, int layer, double distance, double dedxValue)
add dE/dx information for a CDC layer
Definition: CDCDedxTrack.h:63
Belle2::CDCDedxPIDModule::terminate
virtual void terminate() override
End of the event processing.
Definition: CDCDedxPIDModule.cc:624
Belle2::CDCDedxPIDModule::event
virtual void event() override
This method is called for each event.
Definition: CDCDedxPIDModule.cc:173
Belle2::CDCDedxPIDModule::meanCurve
double meanCurve(double *x, double *par, int version) const
parameterized beta-gamma curve for predicted means
Definition: CDCDedxPIDModule.cc:768
Belle2::DedxPoint
A collection of classes that are useful for making a simple path length correction to the dE/dx measu...
Definition: LineHelper.h:39
Belle2::TrackFitResult
Values of the result of a track fit with a given particle hypothesis.
Definition: TrackFitResult.h:59
Belle2::CDCDedxTrack::m_dedxAvgTruncated
double m_dedxAvgTruncated
dE/dx truncated mean per track
Definition: CDCDedxTrack.h:320
Belle2::CDC::LinearGlobalADCCountTranslator::getCharge
float getCharge(unsigned short adcCount, const WireID &, bool, float, float)
just multiply with the conversion factor and return.
Definition: LinearGlobalADCCountTranslator.h:42
Belle2::CDCDedxTrack::m_dedxAvg
double m_dedxAvg
dE/dx mean value per track
Definition: CDCDedxTrack.h:319
Belle2::CDCRecoHit
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:43
Belle2::CDCHit::getADCCount
unsigned short getADCCount() const
Getter for integrated charge.
Definition: CDCHit.h:241
Belle2::B2Vector3< double >
Belle2::Const::kaon
static const ChargedStable kaon
charged kaon particle
Definition: Const.h:536
Belle2::RecoTrack::getHitPointsWithMeasurement
const std::vector< genfit::TrackPoint * > & getHitPointsWithMeasurement() const
Return a list of measurements and track points, which can be used e.g. to extrapolate....
Definition: RecoTrack.h:607
Belle2::CDCDedxTrack::m_cdcLogl
double m_cdcLogl[Const::ChargedStable::c_SetSize]
log likelihood for each particle, not including momentum prior
Definition: CDCDedxTrack.h:324
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::MCParticle::hasStatus
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:140
genfit::AbsMeasurement
Contains the measurement and covariance in raw detector coordinates.
Definition: AbsMeasurement.h:42
Belle2::TrackFitResult::getCotTheta
double getCotTheta() const
Getter for tanLambda with CDF naming convention.
Definition: TrackFitResult.h:209
Belle2::RecoTrack
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:78
Belle2::CDC::CDCGeometryPar
The Class for CDC Geometry Parameters.
Definition: CDCGeometryPar.h:75
Belle2::Const::pion
static const ChargedStable pion
charged pion particle
Definition: Const.h:535
Belle2::CDCDedxPIDModule::initialize
virtual void initialize() override
Initialize the module.
Definition: CDCDedxPIDModule.cc:114
Belle2::CDCRecoHit::getWireID
WireID getWireID() const
Getter for WireID object.
Definition: CDCRecoHit.h:60
genfit::KalmanFitterInfo
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
Definition: KalmanFitterInfo.h:44
Belle2::B2Vector3::Phi
DataType Phi() const
The azimuth angle.
Definition: B2Vector3.h:150
Belle2::CDC::CDCGeometryPar::wireBackwardPosition
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
Definition: CDCGeometryPar.cc:1662
Belle2::CDC::CDCGeometryPar::Instance
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Definition: CDCGeometryPar.cc:41
Belle2::RecoTrack::getRecoHitInformation
RecoHitInformation * getRecoHitInformation(HitType *hit) const
Return the reco hit information for a generic hit from the storeArray.
Definition: RecoTrack.h:309
Belle2::CDCHit::getILayer
unsigned short getILayer() const
Getter for iLayer.
Definition: CDCHit.h:183
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::CDCDedxTrack::m_pTrue
double m_pTrue
MC true momentum.
Definition: CDCDedxTrack.h:303
Belle2::CDCDedxPIDModule::D2I
double D2I(double cosTheta, double D) const
hadron saturation parameterization part 2
Definition: CDCDedxPIDModule.cc:714
Belle2::CDC::CDCGeometryPar::outerRadiusWireLayer
const double * outerRadiusWireLayer() const
Returns an array of outer radius of wire layers.
Definition: CDCGeometryPar.cc:1721
Belle2::CDCDedxTrack::m_pdg
double m_pdg
MC PID.
Definition: CDCDedxTrack.h:300
Belle2::Const::ParticleSet::at
const ParticleType & at(unsigned int index) const
Return particle at given index, or end() if out of range.
Definition: Const.h:425
Belle2::CDCDedxTrack::m_dedxAvgTruncatedErr
double m_dedxAvgTruncatedErr
standard deviation of m_dedxAvgTruncated
Definition: CDCDedxTrack.h:322
Belle2::CDCDedxPIDModule::~CDCDedxPIDModule
virtual ~CDCDedxPIDModule()
Destructor.
Definition: CDCDedxPIDModule.cc:74
Belle2::CDCDedxTrack::m_charge
int m_charge
particle charge from tracking (+1 or -1)
Definition: CDCDedxTrack.h:293
Belle2::CDCDedxTrack::m_cdcChi
double m_cdcChi[Const::ChargedStable::c_SetSize]
chi values for each particle type
Definition: CDCDedxTrack.h:323
Belle2::MCParticle::getPDG
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:123
Belle2::MCParticle::getMass
float getMass() const
Return the particle mass in GeV.
Definition: MCParticle.h:146
Belle2::MCParticle::getMother
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition: MCParticle.h:593
Belle2::CDC::RealisticTDCCountTranslator::getDriftLength
double getDriftLength(unsigned short tdcCount, const WireID &wireID=WireID(), double timeOfFlightEstimator=0, bool leftRight=false, double z=0, double alpha=0, double theta=static_cast< double >(TMath::Pi()/2.), unsigned short adcCount=0) override
Get Drift length.
Definition: RealisticTDCCountTranslator.cc:106
Belle2::CDCDedxTrack::m_p
double m_p
momentum at the IP
Definition: CDCDedxTrack.h:295
Belle2::RecoHitInformation
This class stores additional information to every CDC/SVD/PXD hit stored in a RecoTrack.
Definition: RecoHitInformation.h:48
Belle2::CDCRecoHit::getCDCHit
const CDCHit * getCDCHit() const
get the pointer to the CDCHit object that was used to create this CDCRecoHit object.
Definition: CDCRecoHit.h:123
Belle2::CDCDedxTrack::m_lDedx
std::vector< double > m_lDedx
extracted dE/dx (arb.
Definition: CDCDedxTrack.h:333
Belle2::CDCDedxTrack::m_dedxAvgTruncatedNoSat
double m_dedxAvgTruncatedNoSat
dE/dx truncated mean per track without the saturation correction
Definition: CDCDedxTrack.h:321
Belle2::DedxDriftCell
A class to hold the geometry of a cell.
Definition: LineHelper.h:196
Belle2::CDCDedxTrack::m_track
int m_track
ID number of the Track.
Definition: CDCDedxTrack.h:292
Belle2::CDCDedxPIDModule::calculateMeans
void calculateMeans(double *mean, double *truncatedMean, double *truncatedMeanErr, const std::vector< double > &dedx) const
Save arithmetic and truncated mean for the 'dedx' values.
Definition: CDCDedxPIDModule.cc:630
Belle2::Const::proton
static const ChargedStable proton
proton particle
Definition: Const.h:537
Belle2::CDCDedxPIDModule::saveChiValue
void saveChiValue(double(&chi)[Const::ChargedStable::c_SetSize], double(&predmean)[Const::ChargedStable::c_SetSize], double(&predres)[Const::ChargedStable::c_SetSize], double p, double dedx, double sin, int nhit) const
for all particles, save chi values into 'chi'.
Definition: CDCDedxPIDModule.cc:866
Belle2::CDC::CDCGeometryPar::nWiresInLayer
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
Definition: CDCGeometryPar.h:1211
Belle2::Const::ChargedStable
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:465
Belle2::CDCDedxTrack::m_cosTheta
double m_cosTheta
cos(theta) for the track
Definition: CDCDedxTrack.h:294
Belle2::MCParticle::getMomentum
TVector3 getMomentum() const
Return momentum.
Definition: MCParticle.h:209
Belle2::CDCDedxTrack::m_pCDC
double m_pCDC
momentum at the inner layer of the CDC
Definition: CDCDedxTrack.h:296
Belle2::CDCDedxTrack::m_predres
double m_predres[Const::ChargedStable::c_SetSize]
predicted dE/dx resolution
Definition: CDCDedxTrack.h:316
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
genfit::KalmanFitterInfo::getWeights
std::vector< double > getWeights() const
Get weights of measurements.
Definition: KalmanFitterInfo.cc:168
Belle2::CDCDedxTrack::addHit
void addHit(int lwire, int wire, int layer, double doca, double docaRS, double enta, double entaRS, int adcCount, int adcbaseCount, double dE, double path, double dedx, double cellHeight, double cellHalfWidth, int driftT, double driftD, double driftDRes, double wiregain, double twodcor, double onedcor, int foundByTrackFinder, double weightPionHypo, double weightKaonHypo, double weightProtHypo)
Add a single hit to the object.
Definition: CDCDedxTrack.h:75
Belle2::WireID::getIWire
unsigned short getIWire() const
Getter for wire within the layer.
Definition: WireID.h:155
Belle2::Unit
The Unit class.
Definition: Unit.h:50
Belle2::RecoHitInformation::getFoundByTrackFinder
OriginTrackFinder getFoundByTrackFinder() const
Get which track finder has found the track.
Definition: RecoHitInformation.h:212
Belle2::CDCDedxTrack::m_simDedx
double m_simDedx
track level MC dE/dx truncated mean
Definition: CDCDedxTrack.h:305
Belle2::CDCDedxTrack
Debug output for CDCDedxPID module.
Definition: CDCDedxTrack.h:36
Belle2::TrackFitResult::getChargeSign
short getChargeSign() const
Return track charge (1 or -1).
Definition: TrackFitResult.h:160
Belle2::MCParticle::c_PrimaryParticle
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:58
Belle2::CDCDedxTrack::m_runGain
double m_runGain
calibration run gain
Definition: CDCDedxTrack.h:311
Belle2::CDCDedxPIDModule::I2D
double I2D(double cosTheta, double I) const
hadron saturation parameterization part 1
Definition: CDCDedxPIDModule.cc:736
Belle2::CDCDedxPIDModule::sigmaCurve
double sigmaCurve(double *x, double *par, int version) const
parameterized resolution for predictions
Definition: CDCDedxPIDModule.cc:818
Belle2::CDCDedxTrack::m_predmean
double m_predmean[Const::ChargedStable::c_SetSize]
predicted dE/dx truncated mean
Definition: CDCDedxTrack.h:315
Belle2::CDCDedxPIDModule::checkPDFs
void checkPDFs()
Check the pdfs for consistency everytime they change in the database.
Definition: CDCDedxPIDModule.cc:76
Belle2::CDCDedxTrack::m_lNHitsUsed
int m_lNHitsUsed
number of hits on this track used for truncated mean
Definition: CDCDedxTrack.h:328