Belle II Software  release-08-01-10
VXDDedxPIDModule.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 <reconstruction/modules/VXDDedxPID/VXDDedxPIDModule.h>
10 #include <reconstruction/modules/VXDDedxPID/HelixHelper.h>
11 
12 #include <framework/gearbox/Const.h>
13 
14 #include <vxd/geometry/GeoCache.h>
15 
16 #include <genfit/MaterialEffects.h>
17 
18 #include <Math/VectorUtil.h>
19 #include <TH2F.h>
20 
21 #include <memory>
22 #include <cassert>
23 #include <cmath>
24 #include <algorithm>
25 
26 using namespace Belle2;
27 using namespace Dedx;
28 
29 REG_MODULE(VXDDedxPID);
30 
32 {
34 
35  //Set module properties
36  setDescription("Extract dE/dx and corresponding log-likelihood from fitted tracks and hits in the SVD and PXD.");
37 
38  //Parameter definitions
39  addParam("useIndividualHits", m_useIndividualHits,
40  "Include PDF value for each hit in likelihood. If false, the truncated mean of dedx values for the detectors will be used.", false);
41  // no need to define highest and lowest truncated value as we always remove higest two dE/dx value from the 8 dE/dx value
42  addParam("onlyPrimaryParticles", m_onlyPrimaryParticles, "Only save data for primary particles (as determined by MC truth)", false);
43  addParam("usePXD", m_usePXD, "Use PXDClusters for dE/dx calculation", false);
44  addParam("useSVD", m_useSVD, "Use SVDClusters for dE/dx calculation", true);
45  addParam("trackDistanceThreshold", m_trackDistanceThreshhold,
46  "Use a faster helix parametrisation, with corrections as soon as the approximation is more than ... cm off.", double(4.0));
47  addParam("ignoreMissingParticles", m_ignoreMissingParticles, "Ignore particles for which no PDFs are found", false);
48 
49  m_eventID = -1;
50  m_trackID = 0;
51 }
52 
54 
56 {
57  //load dedx:momentum PDFs
58  if (!m_DBDedxPDFs) B2FATAL("No VXD Dedx PDFS available");
59  int nBinsXPXD, nBinsYPXD;
60  double xMinPXD, xMaxPXD, yMinPXD, yMaxPXD;
61  nBinsXPXD = nBinsYPXD = -1;
62  xMinPXD = xMaxPXD = yMinPXD = yMaxPXD = 0.0;
63 
64  int nBinsXSVD, nBinsYSVD;
65  double xMinSVD, xMaxSVD, yMinSVD, yMaxSVD;
66  nBinsXSVD = nBinsYSVD = -1;
67  xMinSVD = xMaxSVD = yMinSVD = yMaxSVD = 0.0;
68 
69  for (unsigned int iPart = 0; iPart < 6; iPart++) {
70  const int pdgCode = Const::chargedStableSet.at(iPart).getPDGCode();
71  const TH2F* svd_pdf = m_DBDedxPDFs->getSVDPDF(iPart, !m_useIndividualHits);
72  const TH2F* pxd_pdf = m_DBDedxPDFs->getPXDPDF(iPart, !m_useIndividualHits);
73 
74  if (pxd_pdf->GetEntries() == 0 || svd_pdf->GetEntries() == 0) {
76  continue;
77  B2FATAL("Couldn't find PDF for PDG " << pdgCode);
78  }
79 
80  //check that PXD PDFs have the same dimensions and same binning
81  const double epsFactor = 1e-5;
82  if (nBinsXPXD == -1 and nBinsYPXD == -1) {
83  nBinsXPXD = pxd_pdf->GetNbinsX();
84  nBinsYPXD = pxd_pdf->GetNbinsY();
85  xMinPXD = pxd_pdf->GetXaxis()->GetXmin();
86  xMaxPXD = pxd_pdf->GetXaxis()->GetXmax();
87  yMinPXD = pxd_pdf->GetYaxis()->GetXmin();
88  yMaxPXD = pxd_pdf->GetYaxis()->GetXmax();
89  } else if (nBinsXPXD != pxd_pdf->GetNbinsX()
90  or nBinsYPXD != pxd_pdf->GetNbinsY()
91  or fabs(xMinPXD - pxd_pdf->GetXaxis()->GetXmin()) > epsFactor * xMaxPXD
92  or fabs(xMaxPXD - pxd_pdf->GetXaxis()->GetXmax()) > epsFactor * xMaxPXD
93  or fabs(yMinPXD - pxd_pdf->GetYaxis()->GetXmin()) > epsFactor * yMaxPXD
94  or fabs(yMaxPXD - pxd_pdf->GetYaxis()->GetXmax()) > epsFactor * yMaxPXD) {
95  B2FATAL("PDF for PDG " << pdgCode << ", PXD has binning/dimensions differing from previous PDF.");
96  }
97 
98  //check that SVD PDFs have the same dimensions and same binning
99  if (nBinsXSVD == -1 and nBinsYSVD == -1) {
100  nBinsXSVD = svd_pdf->GetNbinsX();
101  nBinsYSVD = svd_pdf->GetNbinsY();
102  xMinSVD = svd_pdf->GetXaxis()->GetXmin();
103  xMaxSVD = svd_pdf->GetXaxis()->GetXmax();
104  yMinSVD = svd_pdf->GetYaxis()->GetXmin();
105  yMaxSVD = svd_pdf->GetYaxis()->GetXmax();
106  } else if (nBinsXSVD != svd_pdf->GetNbinsX()
107  or nBinsYSVD != svd_pdf->GetNbinsY()
108  or fabs(xMinSVD - svd_pdf->GetXaxis()->GetXmin()) > epsFactor * xMaxSVD
109  or fabs(xMaxSVD - svd_pdf->GetXaxis()->GetXmax()) > epsFactor * xMaxSVD
110  or fabs(yMinSVD - svd_pdf->GetYaxis()->GetXmin()) > epsFactor * yMaxSVD
111  or fabs(yMaxSVD - svd_pdf->GetYaxis()->GetXmax()) > epsFactor * yMaxSVD) {
112  B2FATAL("PDF for PDG " << pdgCode << ", PXD has binning/dimensions differing from previous PDF.");
113  }
114  }
115 }
116 
118 {
119 
120  // required inputs
121  m_tracks.isRequired();
123 
124  //optional inputs
126  m_tracks.optionalRelationTo(m_mcparticles);
127 
128  if (m_useSVD)
130  else
132  if (m_usePXD)
134  else
136 
137  // register dE/dx data points
138  m_dedxTracks.registerInDataStore();
139  m_tracks.registerRelationTo(m_dedxTracks);
140 
141  // register likelihoods
142  m_dedxLikelihoods.registerInDataStore();
143  m_tracks.registerRelationTo(m_dedxLikelihoods);
144 
145  m_DBDedxPDFs.addCallback([this]() {checkPDFs();});
146  checkPDFs();
147 
148 
149  // create instances here to not confuse profiling
151 
152  if (!genfit::MaterialEffects::getInstance()->isInitialized()) {
153  B2FATAL("Need to have SetupGenfitExtrapolationModule in path before this one.");
154  }
155 }
156 
158 {
159  // go through Tracks
160  // get fitresult and gftrack and do extrapolations, save corresponding dE/dx and likelihood values
161  // get genfit::TrackCand through genfit::Track::getCand()
162  // get hit indices through genfit::TrackCand::getHit(...)
163  // create one VXDDedxTrack per fitresult/gftrack
164  //create one DedkLikelihood per Track (plus rel)
165  m_eventID++;
166 
167  // inputs
168  const int numMCParticles = m_mcparticles.getEntries();
169 
170  // **************************************************
171  //
172  // LOOP OVER TRACKS
173  //
174  // **************************************************
175 
176  for (const auto& track : m_tracks) {
177  m_trackID++;
178 
179  std::shared_ptr<VXDDedxTrack> dedxTrack = std::make_shared<VXDDedxTrack>();
180  dedxTrack->m_eventID = m_eventID;
181  dedxTrack->m_trackID = m_trackID;
182 
183  // load the pion fit hypothesis or the hypothesis which is the closest in mass to a pion
184  // the tracking will not always successfully fit with a pion hypothesis
185  const TrackFitResult* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
186  if (!fitResult) {
187  B2WARNING("No related fit for track ...");
188  continue;
189  }
190 
191  if (numMCParticles != 0) {
192  // find MCParticle corresponding to this track
193  const MCParticle* mcpart = track.getRelatedTo<MCParticle>();
194 
195  if (mcpart) {
197  continue; //not a primary particle, ignore
198  }
199 
200  //add some MC truths to VXDDedxTrack object
201  dedxTrack->m_pdg = mcpart->getPDG();
202  const MCParticle* mother = mcpart->getMother();
203  dedxTrack->m_motherPDG = mother ? mother->getPDG() : 0;
204 
205  const ROOT::Math::XYZVector trueMomentum = mcpart->getMomentum();
206  dedxTrack->m_pTrue = trueMomentum.R();
207  }
208  }
209 
210  // get momentum (at origin) from fit result
211  const ROOT::Math::XYZVector& trackPos = fitResult->getPosition();
212  const ROOT::Math::XYZVector& trackMom = fitResult->getMomentum();
213  dedxTrack->m_p = trackMom.R();
214  dedxTrack->m_cosTheta = cos(trackMom.Theta());
215  dedxTrack->m_charge = fitResult->getChargeSign();
216 
217  // dE/dx values will be calculated using associated RecoTrack
218  const RecoTrack* recoTrack = track.getRelatedTo<RecoTrack>();
219  if (!recoTrack) {
220  B2WARNING("No related track for this fit...");
221  continue;
222  }
223 
224  // Check to see if the track is pruned. We use the cardinal representation for this, as we do not expect that one
225  // representation is pruned whereas the other is not.
226  if (recoTrack->getTrackFitStatus()->isTrackPruned()) {
227  B2ERROR("GFTrack is pruned, please run VXDDedxPID only on unpruned tracks! Skipping this track.");
228  continue;
229  }
230 
231  //used for PXD/SVD hits
232  const HelixHelper helixAtOrigin(trackPos, trackMom, dedxTrack->m_charge);
233 
234  if (m_usePXD) {
235  const std::vector<PXDCluster*>& pxdClusters = recoTrack->getPXDHitList();
236  saveSiHits(dedxTrack.get(), helixAtOrigin, pxdClusters);
237  }
238 
239  if (m_useSVD) {
240  const std::vector<SVDCluster*>& svdClusters = recoTrack->getSVDHitList();
241  saveSiHits(dedxTrack.get(), helixAtOrigin, svdClusters);
242  }
243 
244  if (dedxTrack->dedx.empty()) {
245  B2DEBUG(50, "Found track with no hits, ignoring.");
246  continue;
247  }
248 
249  // calculate likelihoods for truncated mean
250  if (!m_useIndividualHits) {
251  for (int detector = 0; detector <= c_SVD; detector++) {
252  if (!detectorEnabled(static_cast<Detector>(detector)))
253  continue; //unwanted detector
254 
255  if (detector == 0) savePXDLogLikelihood(dedxTrack->m_vxdLogl, dedxTrack->m_p, dedxTrack->m_dedxAvgTruncated[detector]);
256  else if (detector == 1) saveSVDLogLikelihood(dedxTrack->m_vxdLogl, dedxTrack->m_p, dedxTrack->m_dedxAvgTruncated[detector]);
257  }
258  }
259 
260  // add a few last things to the VXDDedxTrack
261  const int numDedx = dedxTrack->dedx.size();
262  dedxTrack->m_nHits = numDedx;
263  // no need to define lowedgetruncated and highedgetruncated as we always remove the highest 2 dE/dx values from 8 dE/dx value
264  dedxTrack->m_nHitsUsed = numDedx - 2;
265 
266  // now book the information for this track
267  VXDDedxTrack* newVXDDedxTrack = m_dedxTracks.appendNew(*dedxTrack);
268  track.addRelationTo(newVXDDedxTrack);
269 
270  // save VXDDedxLikelihood
271  VXDDedxLikelihood* likelihoodObj = m_dedxLikelihoods.appendNew(dedxTrack->m_vxdLogl);
272  track.addRelationTo(likelihoodObj);
273 
274  } // end of loop over tracks
275 }
276 
278 {
279 
280  B2DEBUG(50, "VXDDedxPIDModule exiting after processing " << m_trackID <<
281  " tracks in " << m_eventID + 1 << " events.");
282 }
283 // calculateMeans need some change as we always remove highest 2 dE/dx values
284 void VXDDedxPIDModule::calculateMeans(double* mean, double* truncatedMean, double* truncatedMeanErr,
285  const std::vector<double>& dedx) const
286 {
287  // Calculate the truncated average by skipping only highest two value
288  std::vector<double> sortedDedx = dedx;
289  std::sort(sortedDedx.begin(), sortedDedx.end());
290 
291  double truncatedMeanTmp = 0.0;
292  double meanTmp = 0.0;
293  double sumOfSquares = 0.0;
294  const int numDedx = sortedDedx.size();
295 
296 
297  for (int i = 0; i < numDedx; i++) {
298  meanTmp += sortedDedx[i];
299  }
300  if (numDedx != 0) {
301  meanTmp /= numDedx;
302  }
303 
304  for (int i = 0; i < numDedx - 2; i++) {
305  truncatedMeanTmp += sortedDedx[i];
306  sumOfSquares += sortedDedx[i] * sortedDedx[i];
307  }
308  if (numDedx - 2 != 0) {
309  truncatedMeanTmp /= numDedx - 2;
310  }
311 
312  *mean = meanTmp;
313  *truncatedMean = truncatedMeanTmp;
314 
315  if (numDedx - 2 > 1) {
316  *truncatedMeanErr = sqrt(sumOfSquares / double(numDedx - 2) - truncatedMeanTmp * truncatedMeanTmp) / double(
317  (numDedx - 2) - 1);
318  } else {
319  *truncatedMeanErr = 0;
320  }
321 }
322 
324 {
326  const VXD::SensorInfoBase& sensor = geo.get(hit->getSensorID());
327 
328  const ROOT::Math::XYZVector localPos(hit->getU(), hit->getV(), 0.0); //z-component is height over the center of the detector plane
329  const ROOT::Math::XYZVector& globalPos = sensor.pointToGlobal(localPos);
330  const ROOT::Math::XYZVector& localMomentum = helix->momentum(helix->pathLengthToPoint(globalPos));
331 
332  const ROOT::Math::XYZVector& sensorNormal = sensor.vectorToGlobal(ROOT::Math::XYZVector(0.0, 0.0, 1.0));
333  const double angle = ROOT::Math::VectorUtil::Angle(sensorNormal, localMomentum); //includes theta and phi components
334 
335  //I'm assuming there's only one hit per sensor, there are _very_ rare exceptions to that (most likely curlers)
336  return TMath::Min(sensor.getWidth(), sensor.getThickness() / fabs(cos(angle)));
337 }
338 
339 
341 {
343  const VXD::SensorInfoBase& sensor = geo.get(hit->getSensorID());
344 
345  ROOT::Math::XYZVector a, b;
346  if (hit->isUCluster()) {
347  const float u = hit->getPosition();
348  a = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
349  b = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
350  } else {
351  const float v = hit->getPosition();
352  a = sensor.pointToGlobal(ROOT::Math::XYZVector(-0.5 * sensor.getWidth(v), v, 0.0));
353  b = sensor.pointToGlobal(ROOT::Math::XYZVector(+0.5 * sensor.getWidth(v), v, 0.0));
354  }
355  const double pathLength = helix->pathLengthToLine(ROOT::Math::XYZVector(a), ROOT::Math::XYZVector(b));
356  const ROOT::Math::XYZVector& localMomentum = helix->momentum(pathLength);
357 
358  const ROOT::Math::XYZVector& sensorNormal = sensor.vectorToGlobal(ROOT::Math::XYZVector(0.0, 0.0, 1.0));
359  const double angle = ROOT::Math::VectorUtil::Angle(sensorNormal, localMomentum); //includes theta and phi components
360 
361  return TMath::Min(sensor.getWidth(), sensor.getThickness() / fabs(cos(angle)));
362 }
363 
364 
365 template <class HitClass> void VXDDedxPIDModule::saveSiHits(VXDDedxTrack* track, const HelixHelper& helix,
366  const std::vector<HitClass*>& hits) const
367 {
368  const int numHits = hits.size();
369  if (numHits == 0)
370  return;
371 
373 
374  //figure out which detector to assign hits to
375  const int currentDetector = geo.get(hits.front()->getSensorID()).getType();
376  assert(currentDetector == VXD::SensorInfoBase::PXD or currentDetector == VXD::SensorInfoBase::SVD);
377  assert(currentDetector <= 1); //used as array index
378 
379  std::vector<double> siliconDedx; //used for averages
380  siliconDedx.reserve(numHits);
381 
382  VxdID prevSensor;
383  for (int i = 0; i < numHits; i++) {
384  const HitClass* hit = hits[i];
385  if (!hit) {
386  B2ERROR("Added hit is a null pointer!");
387  continue;
388  }
389  const VxdID& currentSensor = hit->getSensorID();
390  int layer = -currentSensor.getLayerNumber();
391  assert(layer >= -6 && layer < 0);
392 
393  //active medium traversed, in cm (can traverse one sensor at most)
394  //assumption: Si detectors are close enough to the origin that helix is still accurate
395  const double totalDistance = getTraversedLength(hit, &helix);
396  const float charge = hit->getCharge();
397  const float dedx = charge / totalDistance;
398  if (dedx <= 0) {
399  B2WARNING("dE/dx is " << dedx << " in layer " << layer);
400  } else if (i == 0 or prevSensor != currentSensor) { //only save once per sensor (u and v hits share charge!)
401  prevSensor = currentSensor;
402  //store data
403  siliconDedx.push_back(dedx);
404  track->m_dedxAvg[currentDetector] += dedx;
405  track->addDedx(layer, totalDistance, dedx);
406  if (m_useIndividualHits) {
407  if (currentDetector == 0) savePXDLogLikelihood(track->m_vxdLogl, track->m_p, dedx);
408  else if (currentDetector == 1) saveSVDLogLikelihood(track->m_vxdLogl, track->m_p, dedx);
409  }
410  }
411 
412  track->addHit(currentSensor, layer, charge, totalDistance, dedx);
413  }
414 
415  //save averages
416  calculateMeans(&(track->m_dedxAvg[currentDetector]),
417  &(track->m_dedxAvgTruncated[currentDetector]),
418  &(track->m_dedxAvgTruncatedErr[currentDetector]),
419  siliconDedx);
420 }
421 
422 void VXDDedxPIDModule::savePXDLogLikelihood(double(&logl)[Const::ChargedStable::c_SetSize], double p, float dedx) const
423 {
424  //all pdfs have the same dimensions
425  const TH2F* pdf = m_DBDedxPDFs->getPXDPDF(0, !m_useIndividualHits);
426  const Int_t binX = pdf->GetXaxis()->FindFixBin(p);
427  const Int_t binY = pdf->GetYaxis()->FindFixBin(dedx);
428 
429  for (unsigned int iPart = 0; iPart < Const::ChargedStable::c_SetSize; iPart++) {
430  pdf = m_DBDedxPDFs->getPXDPDF(iPart, !m_useIndividualHits);
431  if (pdf->GetEntries() == 0) //might be NULL if m_ignoreMissingParticles is set
432  continue;
433  double probability = 0.0;
434 
435  //check if this is still in the histogram, take overflow bin otherwise
436  if (binX < 1 or binX > pdf->GetNbinsX()
437  or binY < 1 or binY > pdf->GetNbinsY()) {
438  probability = pdf->GetBinContent(binX, binY);
439  } else {
440  //in normal histogram range. Of course ROOT has a bug that Interpolate()
441  //is not declared as const but it does not modify the internal state so
442  //fine, const_cast it is.
443  probability = const_cast<TH2F*>(pdf)->Interpolate(p, dedx);
444  }
445 
446  if (probability != probability)
447  B2ERROR("probability NAN for a track with p=" << p << " and dedx=" << dedx);
448 
449  //my pdfs aren't perfect...
450  if (probability == 0.0)
451  probability = m_useIndividualHits ? (1e-5) : (1e-3); //likelihoods for truncated mean are much higher
452 
453  logl[iPart] += log(probability);
454  }
455 }
456 
457 void VXDDedxPIDModule::saveSVDLogLikelihood(double(&logl)[Const::ChargedStable::c_SetSize], double p, float dedx) const
458 {
459  //all pdfs have the same dimensions
460  const TH2F* pdf = m_DBDedxPDFs->getSVDPDF(0, !m_useIndividualHits);
461  const Int_t binX = pdf->GetXaxis()->FindFixBin(p);
462  const Int_t binY = pdf->GetYaxis()->FindFixBin(dedx);
463 
464  for (unsigned int iPart = 0; iPart < Const::ChargedStable::c_SetSize; iPart++) {
465  pdf = m_DBDedxPDFs->getSVDPDF(iPart, !m_useIndividualHits);
466  if (pdf->GetEntries() == 0) //might be NULL if m_ignoreMissingParticles is set
467  continue;
468  double probability = 0.0;
469 
470  //check if this is still in the histogram, take overflow bin otherwise
471  if (binX < 1 or binX > pdf->GetNbinsX()
472  or binY < 1 or binY > pdf->GetNbinsY()) {
473  probability = pdf->GetBinContent(binX, binY);
474  } else {
475  //in normal histogram range. Of course ROOT has a bug that Interpolate()
476  //is not declared as const but it does not modify the internal state so
477  //fine, const_cast it is.
478  probability = const_cast<TH2F*>(pdf)->Interpolate(p, dedx);
479  }
480 
481  if (probability != probability)
482  B2ERROR("probability NAN for a track with p=" << p << " and dedx=" << dedx);
483 
484  //my pdfs aren't perfect...
485  if (probability == 0.0)
486  probability = m_useIndividualHits ? (1e-5) : (1e-3); //likelihoods for truncated mean are much higher
487 
488  logl[iPart] += log(probability);
489  }
490 }
static const unsigned int c_SetSize
Number of elements (for use in array bounds etc.)
Definition: Const.h:606
const ParticleType & at(unsigned int index) const
Return particle at given index, or end() if out of range.
Definition: Const.h:540
int getPDGCode() const
PDG code.
Definition: Const.h:464
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:609
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
Helper class representing a helical track.
Definition: HelixHelper.h:28
double pathLengthToPoint(const ROOT::Math::XYZVector &p) const
returns the path length (along the helix) to the helix point closest to p.
Definition: HelixHelper.h:68
ROOT::Math::XYZVector momentum(double s=0) const
momentum of the particle, at the helix point corresponding to a flown path length s (from poca).
Definition: HelixHelper.h:109
double pathLengthToLine(const ROOT::Math::XYZVector &a, const ROOT::Math::XYZVector &b) const
returns the path length (along the helix) to the helix point closest to the line going through points...
Definition: HelixHelper.h:87
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
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:129
int m_pdg
PDG-Code of the particle.
Definition: MCParticle.h:541
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
ROOT::Math::XYZVector getMomentum() const
Return momentum.
Definition: MCParticle.h:198
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
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:621
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
Definition: RecoTrack.h:452
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
Definition: RecoTrack.h:449
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
Values of the result of a track fit with a given particle hypothesis.
short getChargeSign() const
Return track charge (1 or -1).
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.
Container for likelihoods obtained by the VXD dE/dx PID (VXDDedxPIDModule).
void saveSVDLogLikelihood(double(&logl)[Const::ChargedStable::c_SetSize], double p, float dedx) const
for all particles in the SVD, save log-likelihood values into 'logl'.
int m_trackID
counter for tracks in this event
virtual void initialize() override
Initialize the module.
StoreArray< SVDCluster > m_svdClusters
Optional array of SVDClusters.
bool m_usePXD
use PXD hits for likelihood
virtual void event() override
This method is called for each event.
StoreArray< MCParticle > m_mcparticles
Optional array of MCParticles.
StoreArray< VXDDedxLikelihood > m_dedxLikelihoods
Output array of VXDDedxLikelihoods.
void checkPDFs()
Check the pdfs for consistency everytime they change in the database.
virtual void terminate() override
End of the event processing.
void saveSiHits(VXDDedxTrack *track, const HelixHelper &helix, const std::vector< HitClass * > &hits) const
save energy loss and hit information from SVD/PXDHits to track
void calculateMeans(double *mean, double *truncatedMean, double *truncatedMeanErr, const std::vector< double > &dedx) const
Save arithmetic and truncated mean for the 'dedx' values.
StoreArray< VXDDedxTrack > m_dedxTracks
Output array of VXDDedxTracks.
virtual ~VXDDedxPIDModule()
Destructor.
int m_eventID
counter for events
bool m_useSVD
use SVD hits for likelihood
bool detectorEnabled(Dedx::Detector d) const
should info from this detector be included in likelihood?
bool m_ignoreMissingParticles
Ignore particles for which no PDFs are found.
StoreArray< Track > m_tracks
Required array of Tracks.
bool m_onlyPrimaryParticles
Only save data for primary particles (as determined by MC truth)
StoreArray< PXDCluster > m_pxdClusters
Optional array of PXDClusters.
static double getTraversedLength(const PXDCluster *hit, const HelixHelper *helix)
returns traversed length through active medium of given PXDCluster.
StoreArray< RecoTrack > m_recoTracks
Required array of input RecoTracks.
bool m_useIndividualHits
Include PDF value for each hit in likelihood.
VXDDedxPIDModule()
Default constructor.
double m_trackDistanceThreshhold
Use a faster helix parametrisation, with corrections as soon as the approximation is more than ....
void savePXDLogLikelihood(double(&logl)[Const::ChargedStable::c_SetSize], double p, float dedx) const
for all particles in the PXD, save log-likelihood values into 'logl'.
DBObjPtr< DedxPDFs > m_DBDedxPDFs
DB object for dedx:momentum PDFs.
Debug output for VXDDedxPID module.
Definition: VXDDedxTrack.h:27
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
Base class to provide Sensor Information for PXD and SVD.
SensorType getType() const
Return the Type of the Sensor.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
bool isTrackPruned() const
Has the track been pruned after the fit?
Definition: FitStatus.h:116
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
MCParticle * getMother() const
Returns a pointer to the mother particle.
Definition: MCParticle.h:600
Abstract base class for different kinds of events.