9 #include <reconstruction/modules/CDCDedxPID/CDCDedxPIDModule.h>
11 #include <reconstruction/dataobjects/DedxConstants.h>
12 #include <reconstruction/modules/CDCDedxPID/LineHelper.h>
14 #include <framework/gearbox/Const.h>
16 #include <cdc/dataobjects/CDCHit.h>
17 #include <cdc/dataobjects/CDCRecoHit.h>
19 #include <cdc/translators/LinearGlobalADCCountTranslator.h>
20 #include <cdc/translators/RealisticTDCCountTranslator.h>
22 #include <cdc/geometry/CDCGeometryPar.h>
23 #include <tracking/dataobjects/RecoHitInformation.h>
25 #include <genfit/AbsTrackRep.h>
26 #include <genfit/Exception.h>
27 #include <genfit/MaterialEffects.h>
28 #include <genfit/KalmanFitterInfo.h>
45 setPropertyFlags(c_ParallelProcessingCertified);
48 setDescription(
"Extract dE/dx and corresponding log-likelihood from fitted tracks and hits in the CDC.");
51 addParam(
"usePrediction", m_usePrediction,
52 "Use parameterized means and resolutions to determine PID values. If false, lookup table PDFs are used.",
true);
53 addParam(
"removeLowest", m_removeLowest,
54 "Portion of events with low dE/dx that should be discarded",
double(0.05));
55 addParam(
"removeHighest", m_removeHighest,
56 "Portion of events with high dE/dx that should be discarded",
double(0.25));
57 addParam(
"useBackHalfCurlers", m_backHalfCurlers,
58 "Whether to use the back half of curlers",
false);
59 addParam(
"enableDebugOutput", m_enableDebugOutput,
60 "Option to write out debugging information to CDCDedxTracks (DataStore objects).",
true);
61 addParam(
"useIndividualHits", m_useIndividualHits,
62 "If using lookup table PDFs, include PDF value for each hit in likelihood. If false, the truncated mean of dedx values will be used.",
64 addParam(
"ignoreMissingParticles", m_ignoreMissingParticles,
65 "Ignore particles for which no PDFs are found",
false);
66 addParam(
"trackLevel", m_trackLevel,
67 "ONLY USEFUL FOR MC: Use track-level MC. If false, use hit-level MC",
true);
68 addParam(
"onlyPrimaryParticles", m_onlyPrimaryParticles,
69 "ONLY USEFUL FOR MC: Only save data for primary particles",
false);
76 if (!m_DBDedxPDFs) B2FATAL(
"No Dedx pdfs found in database");
79 double xMin, xMax, yMin, yMax;
81 xMin = xMax = yMin = yMax = 0.0;
82 for (
unsigned int iPart = 0; iPart < 6; iPart++) {
84 const TH2F* pdf = m_DBDedxPDFs->getCDCPDF(iPart, !m_useIndividualHits);
86 if (pdf->GetEntries() == 0) {
87 if (m_ignoreMissingParticles)
89 B2FATAL(
"Couldn't find PDF for PDG " << pdgCode);
93 const double epsFactor = 1e-5;
94 if (nBinsX == -1 and nBinsY == -1) {
95 nBinsX = pdf->GetNbinsX();
96 nBinsY = pdf->GetNbinsY();
97 xMin = pdf->GetXaxis()->GetXmin();
98 xMax = pdf->GetXaxis()->GetXmax();
99 yMin = pdf->GetYaxis()->GetXmin();
100 yMax = pdf->GetYaxis()->GetXmax();
101 }
else if (nBinsX != pdf->GetNbinsX()
102 or nBinsY != pdf->GetNbinsY()
103 or fabs(xMin - pdf->GetXaxis()->GetXmin()) > epsFactor * xMax
104 or fabs(xMax - pdf->GetXaxis()->GetXmax()) > epsFactor * xMax
105 or fabs(yMin - pdf->GetYaxis()->GetXmin()) > epsFactor * yMax
106 or fabs(yMax - pdf->GetYaxis()->GetXmax()) > epsFactor * yMax) {
107 B2FATAL(
"PDF for PDG " << pdgCode <<
" has binning/dimensions differing from previous PDF.");
116 m_tracks.isRequired();
117 m_recoTracks.isRequired();
120 m_mcparticles.isOptional();
121 m_tracks.optionalRelationTo(m_mcparticles);
124 if (m_enableDebugOutput) {
125 m_dedxTracks.registerInDataStore();
126 m_tracks.registerRelationTo(m_dedxTracks);
130 m_dedxLikelihoods.registerInDataStore();
131 m_tracks.registerRelationTo(m_dedxLikelihoods);
133 m_DBDedxPDFs.addCallback([
this]() { checkPDFs(); });
137 m_nLayerWires[0] = 1280;
138 for (
int i = 1; i < 9; ++i) {
139 m_nLayerWires[i] = m_nLayerWires[i - 1] + 6 * (160 + (i - 1) * 32);
143 if (!m_DBMeanPars || m_DBMeanPars->getSize() == 0) {
144 B2WARNING(
"No dE/dx mean parameters!");
145 for (
int i = 0; i < 15; ++i)
146 m_meanpars.push_back(1.0);
147 }
else m_meanpars = m_DBMeanPars->getMeanPars();
149 if (!m_DBSigmaPars || m_DBSigmaPars->getSize() == 0) {
150 B2WARNING(
"No dE/dx sigma parameters!");
151 for (
int i = 0; i < 12; ++i)
152 m_sigmapars.push_back(1.0);
153 }
else m_sigmapars = m_DBSigmaPars->getSigmaPars();
156 if (!m_DBHadronCor || m_DBHadronCor->getSize() == 0) {
157 B2WARNING(
"No hadron correction parameters!");
158 for (
int i = 0; i < 4; ++i)
159 m_hadronpars.push_back(0.0);
160 m_hadronpars.push_back(1.0);
161 }
else m_hadronpars = m_DBHadronCor->getHadronPars();
166 if (!genfit::MaterialEffects::getInstance()->isInitialized()) {
167 B2FATAL(
"Need to have SetupGenfitExtrapolationModule in path before this one.");
180 const int numMCParticles = m_mcparticles.getEntries();
191 m_dedxTracks.clear();
192 m_dedxLikelihoods.clear();
195 for (
const auto& track : m_tracks) {
196 std::shared_ptr<CDCDedxTrack> dedxTrack = std::make_shared<CDCDedxTrack>();
197 dedxTrack->m_track = mtrack++;
203 B2WARNING(
"No related fit for track ...");
207 if ((m_enableDebugOutput or m_onlyPrimaryParticles) and numMCParticles != 0) {
218 dedxTrack->m_mcmass = mcpart->
getMass();
220 dedxTrack->m_motherPDG = mother ? mother->getPDG() : 0;
222 const TVector3 trueMomentum = mcpart->
getMomentum();
223 dedxTrack->m_pTrue = trueMomentum.Mag();
224 dedxTrack->m_cosThetaTrue = trueMomentum.CosTheta();
227 dedxTrack->m_pdg = -999;
231 const TVector3& trackMom = fitResult->
getMomentum();
232 dedxTrack->m_p = trackMom.Mag();
233 bool nomom = (dedxTrack->m_p != dedxTrack->m_p);
234 double costh = std::cos(std::atan(1 / fitResult->
getCotTheta()));
237 costh = trackMom.CosTheta();
240 dedxTrack->m_cosTheta = costh;
241 dedxTrack->m_charge = charge;
246 B2WARNING(
"No related track for this fit...");
252 B2ERROR(
"GFTrack is pruned, please run CDCDedxPID only on unpruned tracks! Skipping this track.");
257 dedxTrack->m_scale = (m_DBScaleFactor) ? m_DBScaleFactor->getScaleFactor() : 1.0;
260 dedxTrack->m_runGain = (m_DBRunGain && m_usePrediction && numMCParticles == 0) ? m_DBRunGain->getRunGain() : 1.0;
263 dedxTrack->m_cosCor = (m_DBCosineCor && m_usePrediction && numMCParticles == 0) ? m_DBCosineCor->getMean(costh) : 1.0;
267 if ((abs(costh + 0.860) < 0.010) || (abs(costh - 0.955) <= 0.005))isEdge =
true;
268 dedxTrack->m_cosEdgeCor = (m_DBCosEdgeCor && m_usePrediction && numMCParticles == 0
269 && isEdge) ? m_DBCosEdgeCor->getMean(costh) : 1.0;
272 double layerdE = 0.0;
273 double layerdx = 0.0;
275 int nhitscombined = 0;
276 int wirelongesthit = 0;
277 double longesthit = 0;
283 const std::vector< genfit::AbsTrackRep* >& gftrackRepresentations = recoTrack->
getRepresentations();
285 for (std::vector< genfit::TrackPoint* >::const_iterator tp = gftrackPoints.begin();
286 tp != gftrackPoints.end(); ++tp) {
292 if (!cdcRecoHit)
continue;
294 if (!cdcHit)
continue;
300 B2DEBUG(29,
"No fitter info, skipping...");
311 int foundByTrackFinder = 0;
316 double weightPionHypo = 0;
317 double weightProtHypo = 0;
318 double weightKaonHypo = 0;
320 for (std::vector<genfit::AbsTrackRep* >::const_iterator trep = gftrackRepresentations.begin();
321 trep != gftrackRepresentations.end(); ++trep) {
322 const int pdgCode = TMath::Abs((*trep)->getPDG());
328 if (kalmanFitterInfo == NULL) {
334 std::vector<double> weights = kalmanFitterInfo->
getWeights();
335 const double maxWeight = weights[0] > weights[1] ? weights[0] : weights[1];
336 if (pdgCode ==
Const::pion.getPDGCode()) weightPionHypo = maxWeight;
337 else if (pdgCode ==
Const::kaon.getPDGCode()) weightKaonHypo = maxWeight;
338 else if (pdgCode ==
Const::proton.getPDGCode()) weightProtHypo = maxWeight;
343 int currentLayer = (superlayer == 0) ? layer : (8 + (superlayer - 1) * 6 + layer);
344 int nextLayer = currentLayer;
347 const int iwire = (superlayer == 0) ? 160 * layer + wire : m_nLayerWires[superlayer - 1] + (160 + 32 *
348 (superlayer - 1)) * layer + wire;
351 const bool lastHit = (tp + 1 == gftrackPoints.end());
352 bool lastHitInCurrentLayer = lastHit;
358 if (!nextcdcRecoHit || !(cdcRecoHit->
getCDCHit()) || !((*(tp + 1))->getFitterInfo())) {
359 lastHitInCurrentLayer =
true;
363 const int nextILayer = nextcdcHit->
getILayer();
365 nextLayer = (nextSuperlayer == 0) ? nextILayer : (8 + (nextSuperlayer - 1) * 6 + nextILayer);
366 lastHitInCurrentLayer = (nextLayer != currentLayer);
372 const TVector3 wireDir = (wirePosB - wirePosF).
Unit();
380 double topHeight = outer - wirePosF.Perp();
381 double bottomHeight = wirePosF.Perp() - inner;
382 double cellHeight = topHeight + bottomHeight;
383 double topHalfWidth = M_PI * outer / nWires;
384 double bottomHalfWidth = M_PI * inner / nWires;
385 double cellHalfWidth = M_PI * wirePosF.Perp() / nWires;
400 const TVector3& pocaMom = mop.getMom();
401 if (tp == gftrackPoints.begin() || cdcMom == 0) {
402 cdcMom = pocaMom.Mag();
403 dedxTrack->m_pCDC = cdcMom;
406 dedxTrack->m_p = cdcMom;
415 B2Vector3D pocaOnWire = mop.getPlane()->getO();
418 B2Vector3D B2WireDoca = fittedPoca - pocaOnWire;
421 double doca = B2WireDoca.
Perp();
422 double phidiff = fittedPoca.
Phi() - pocaOnWire.
Phi();
425 if (phidiff > -3.1416 && (phidiff < 0 || phidiff > 3.1416)) doca *= -1;
428 const double px = pocaMom.x();
429 const double py = pocaMom.y();
430 const double wx = pocaOnWire.
x();
431 const double wy = pocaOnWire.
y();
432 const double cross = wx * py - wy * px;
433 const double dot = wx * px + wy * py;
434 double entAng = atan2(cross, dot);
437 double cellR = 2 * cellHalfWidth / cellHeight;
439 if (std::abs(2 * atan(1) - std::abs(entAng)) < 0.01)tana = 100 * (entAng / std::abs(entAng));
440 else tana = std::tan(entAng);
441 double docaRS = doca * std::sqrt((1 + cellR * cellR * tana * tana) / (1 + tana * tana));
442 double entAngRS = std::atan(tana / cellR);
446 int adcCount = (m_DBNonlADC && m_usePrediction
447 && numMCParticles == 0) ? m_DBNonlADC->getCorrectedADC(adcbaseCount, currentLayer) : adcbaseCount;
449 double hitCharge = translator.
getCharge(adcCount, wireID,
false, pocaOnWire.
Z(), pocaMom.Phi());
453 double dadcCount = 1.0 * adcCount;
454 if (dedxTrack->m_scale != 0) dadcCount /= dedxTrack->m_scale;
457 double driftDRealistic = realistictdc.
getDriftLength(driftT, wireID, 0,
true, pocaOnWire.
Z(), pocaMom.Phi(), pocaMom.Theta());
458 double driftDRealisticRes = realistictdc.
getDriftLengthResolution(driftDRealistic, wireID,
true, pocaOnWire.
Z(), pocaMom.Phi(),
462 double celldx = c.dx(doca, entAng);
465 double wiregain = (m_DBWireGains && m_usePrediction && numMCParticles == 0) ? m_DBWireGains->getWireGain(iwire) : 1.0;
468 double normDocaRS = docaRS / cellHalfWidth;
469 double twodcor = (m_DB2DCell && m_usePrediction
470 && numMCParticles == 0) ? m_DB2DCell->getMean(currentLayer, normDocaRS, entAngRS) : 1.0;
473 double onedcor = (m_DB1DCell && m_usePrediction && numMCParticles == 0) ? m_DB1DCell->getMean(currentLayer, entAngRS) : 1.0;
478 double correction = dedxTrack->m_runGain * dedxTrack->m_cosCor * dedxTrack->m_cosEdgeCor * wiregain * twodcor * onedcor;
483 if (correction != 0) dadcCount = dadcCount / correction;
486 double cellDedx = (dadcCount / celldx);
489 if (nomom) cellDedx *= std::sin(std::atan(1 / fitResult->
getCotTheta()));
490 else cellDedx *= std::sin(trackMom.Theta());
492 if (m_enableDebugOutput)
493 dedxTrack->addHit(wire, iwire, currentLayer, doca, docaRS, entAng, entAngRS,
494 adcCount, adcbaseCount, hitCharge, celldx, cellDedx, cellHeight, cellHalfWidth, driftT,
495 driftDRealistic, driftDRealisticRes, wiregain, twodcor, onedcor,
496 foundByTrackFinder, weightPionHypo, weightKaonHypo, weightProtHypo);
501 if (correction != 0) {
503 layerdE += dadcCount;
506 if (celldx > longesthit) {
508 wirelongesthit = iwire;
514 B2WARNING(
"Track: " << mtrack <<
": genfit::MeasuredStateOnPlane exception...");
519 if (lastHitInCurrentLayer) {
521 double totalDistance;
522 if (nomom) totalDistance = layerdx / std::sin(std::atan(1 / fitResult->
getCotTheta()));
523 else totalDistance = layerdx / std::sin(trackMom.Theta());
524 double layerDedx = layerdE / totalDistance;
528 dedxTrack->addDedx(nhitscombined, wirelongesthit, currentLayer, totalDistance, layerDedx);
530 if (m_useIndividualHits) {
532 saveLookupLogl(dedxTrack->m_cdcLogl, dedxTrack->m_pCDC, layerDedx);
537 if (!m_backHalfCurlers && nextLayer < currentLayer)
break;
549 if (dedxTrack->m_lDedx.empty()) {
550 B2DEBUG(29,
"Found track with no hits, ignoring.");
554 const int numDedx = dedxTrack->m_lDedx.size();
556 const int lowEdgeTrunc = int(numDedx * m_removeLowest + 0.51);
557 const int highEdgeTrunc = int(numDedx * (1 - m_removeHighest) + 0.51);
558 dedxTrack->m_lNHitsUsed = highEdgeTrunc - lowEdgeTrunc;
566 if (!m_useIndividualHits or m_enableDebugOutput) {
567 calculateMeans(&(dedxTrack->m_dedxAvg),
568 &(dedxTrack->m_dedxAvgTruncatedNoSat),
569 &(dedxTrack->m_dedxAvgTruncatedErr),
573 if (numMCParticles == 0)
574 dedxTrack->m_dedxAvgTruncated = D2I(costh, I2D(costh, 1.00) / 1.00 * dedxTrack->m_dedxAvgTruncatedNoSat);
575 else dedxTrack->m_dedxAvgTruncated = dedxTrack->m_dedxAvgTruncatedNoSat;
579 if (numMCParticles != 0 && dedxTrack->m_mcmass > 0 && dedxTrack->m_pTrue != 0) {
581 double mean = getMean(dedxTrack->m_pCDC / dedxTrack->m_mcmass);
582 double sigma = getSigma(mean, dedxTrack->m_lNHitsUsed, std::sqrt(1 - dedxTrack->m_cosTheta * dedxTrack->m_cosTheta));
583 dedxTrack->m_simDedx = gRandom->Gaus(mean, sigma);
584 while (dedxTrack->m_simDedx < 0)
585 dedxTrack->m_simDedx = gRandom->Gaus(mean, sigma);
587 dedxTrack->m_dedxAvgTruncated = dedxTrack->m_simDedx;
591 saveChiValue(dedxTrack->m_cdcChi, dedxTrack->m_predmean, dedxTrack->m_predres, dedxTrack->m_pCDC, dedxTrack->m_dedxAvgTruncated,
592 std::sqrt(1 - dedxTrack->m_cosTheta * dedxTrack->m_cosTheta), dedxTrack->m_lNHitsUsed);
593 if (!m_useIndividualHits)
594 saveLookupLogl(dedxTrack->m_cdcLogl, dedxTrack->m_pCDC, dedxTrack->m_dedxAvgTruncated);
600 if (m_usePrediction) {
602 pidvalues[pdgIter.getIndex()] = -0.5 * dedxTrack->m_cdcChi[pdgIter.getIndex()] * dedxTrack->m_cdcChi[pdgIter.getIndex()];
606 pidvalues[pdgIter.getIndex()] = dedxTrack->m_cdcLogl[pdgIter.getIndex()];
611 track.addRelationTo(likelihoodObj);
613 if (m_enableDebugOutput) {
615 CDCDedxTrack* newCDCDedxTrack = m_dedxTracks.appendNew(*dedxTrack);
616 track.addRelationTo(newCDCDedxTrack);
625 B2DEBUG(29,
"CDCDedxPIDModule exiting");
629 const std::vector<double>& dedx)
const
633 std::vector<double> sortedDedx = dedx;
634 std::sort(sortedDedx.begin(), sortedDedx.end());
635 sortedDedx.erase(std::remove(sortedDedx.begin(), sortedDedx.end(), 0), sortedDedx.end());
636 sortedDedx.shrink_to_fit();
638 double truncatedMeanTmp = 0.0;
639 double meanTmp = 0.0;
640 double sumOfSquares = 0.0;
641 int numValuesTrunc = 0;
642 const int numDedx = sortedDedx.size();
645 const int lowEdgeTrunc = int(numDedx * m_removeLowest + 0.51);
646 const int highEdgeTrunc = int(numDedx * (1 - m_removeHighest) + 0.51);
647 for (
int i = 0; i < numDedx; i++) {
648 meanTmp += sortedDedx[i];
649 if (i >= lowEdgeTrunc and i < highEdgeTrunc) {
650 truncatedMeanTmp += sortedDedx[i];
651 sumOfSquares += sortedDedx[i] * sortedDedx[i];
659 if (numValuesTrunc != 0) {
660 truncatedMeanTmp /= numValuesTrunc;
662 truncatedMeanTmp = meanTmp;
666 *truncatedMean = truncatedMeanTmp;
668 if (numValuesTrunc > 1) {
669 *truncatedMeanErr = sqrt(sumOfSquares /
double(numValuesTrunc) - truncatedMeanTmp * truncatedMeanTmp) / double(
672 *truncatedMeanErr = 0;
679 const TH2F* pdf = m_DBDedxPDFs->getCDCPDF(0, !m_useIndividualHits);
680 const Int_t binX = pdf->GetXaxis()->FindFixBin(p);
681 const Int_t binY = pdf->GetYaxis()->FindFixBin(dedx);
684 pdf = m_DBDedxPDFs->getCDCPDF(iPart, !m_useIndividualHits);
685 if (pdf->GetEntries() == 0) {
686 B2WARNING(
"NO CDC PDFS...");
689 double probability = 0.0;
692 if (binX < 1 or binX > pdf->GetNbinsX()
693 or binY < 1 or binY > pdf->GetNbinsY()) {
694 probability = pdf->GetBinContent(binX, binY);
699 probability =
const_cast<TH2F*
>(pdf)->Interpolate(p, dedx);
702 if (probability != probability)
703 B2ERROR(
"probability NAN for a track with p=" << p <<
" and dedx=" << dedx);
706 if (probability == 0.0)
707 probability = m_useIndividualHits ? (1e-5) : (1e-3);
708 logl[iPart] += log(probability);
714 double absCosTheta = fabs(cosTheta);
715 double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
716 if (projection == 0) {
717 B2WARNING(
"Something wrong with dE/dx hadron constants!");
721 double chargeDensity = D / projection;
722 double numerator = 1 + m_hadronpars[0] * chargeDensity;
723 double denominator = 1 + m_hadronpars[1] * chargeDensity;
725 if (denominator == 0) {
726 B2WARNING(
"Something wrong with dE/dx hadron constants!");
730 double I = D * m_hadronpars[4] * numerator / denominator;
736 double absCosTheta = fabs(cosTheta);
737 double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
739 if (projection == 0 || m_hadronpars[4] == 0) {
740 B2WARNING(
"Something wrong with dE/dx hadron constants!");
744 double a = m_hadronpars[0] / projection;
745 double b = 1 - m_hadronpars[1] / projection * (I / m_hadronpars[4]);
746 double c = -1.0 * I / m_hadronpars[4];
748 if (b == 0 && a == 0) {
749 B2WARNING(
"both a and b coefficiants for hadron correction are 0");
753 double D = (a != 0) ? (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a) : -c / b;
755 B2WARNING(
"D is less 0! will try another solution");
756 D = (a != 0) ? (-b - sqrt(b * b + 4.0 * a * c)) / (2.0 * a) : -c / b;
758 B2WARNING(
"D is still less 0! just return uncorrectecd value");
774 f = par[1] * std::pow(std::sqrt(x[0] * x[0] + 1), par[3]) / std::pow(x[0], par[3]) *
775 (par[2] - par[5] * std::log(1 / x[0])) - par[4] + std::exp(par[6] + par[7] * x[0]);
776 else if (par[0] == 2)
777 f = par[1] * std::pow(x[0], 3) + par[2] * x[0] * x[0] + par[3] * x[0] + par[4];
778 else if (par[0] == 3)
779 f = -1.0 * par[1] * std::log(par[4] + std::pow(1 / x[0], par[2])) + par[3];
788 double A = 0, B = 0, C = 0;
796 double x[1]; x[0] = bg;
801 parsA[0] = 1; parsB[0] = 2; parsC[0] = 3;
802 for (
int i = 0; i < 15; ++i) {
803 if (i < 7) parsA[i + 1] = m_meanpars[i];
804 else if (i < 11) parsB[i % 7 + 1] = m_meanpars[i];
805 else parsC[i % 11 + 1] = m_meanpars[i];
809 double partA = meanCurve(x, parsA, 0);
810 double partB = meanCurve(x, parsB, 0);
811 double partC = meanCurve(x, parsC, 0);
813 return (A * partA + B * partB + C * partC);
824 f = par[1] + par[2] * x[0];
825 }
else if (par[0] == 2) {
826 f = par[1] * std::pow(x[0], 4) + par[2] * std::pow(x[0], 3) +
827 par[3] * x[0] * x[0] + par[4] * x[0] + par[5];
837 if (nhit < 5) nhit = 5;
838 if (sin > 0.99) sin = 0.99;
845 dedxpar[0] = 1; nhitpar[0] = 2; sinpar[0] = 2;
846 for (
int i = 0; i < 5; ++i) {
847 if (i < 2) dedxpar[i + 1] = m_sigmapars[i];
848 nhitpar[i + 1] = m_sigmapars[i + 2];
849 sinpar[i + 1] = m_sigmapars[i + 7];
854 double corDedx = sigmaCurve(x, dedxpar, 0);
856 double corNHit = sigmaCurve(x, nhitpar, 0);
857 if (nhit > 42) corNHit = 1.0;
859 double corSin = sigmaCurve(x, sinpar, 0);
861 return (corDedx * corSin * corNHit);
866 double sin,
int nhit)
const
871 double bg = p / pdgIter.getMass();
874 double mean = getMean(bg);
875 double sigma = getSigma(mean, nhit, sin);
877 predmean[pdgIter.getIndex()] = mean;
878 predsigma[pdgIter.getIndex()] = sigma;
881 if (sigma != 0) chi[pdgIter.getIndex()] = ((dedx - mean) / (sigma));
DataType Phi() const
The azimuth angle.
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType y() const
access variable Y (= .at(1) without boundary check)
DataType x() const
access variable X (= .at(0) without boundary check)
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Container for likelihoods obtained by the CDC dE/dx PID (CDCDedxPIDModule).
Extract CDC dE/dx information from fitted tracks.
double I2D(double cosTheta, double I) const
hadron saturation parameterization part 1
double getSigma(double dedx, double nhit, double sin) const
calculate the predicted resolution using the parameterized resolution
double D2I(double cosTheta, double D) const
hadron saturation parameterization part 2
double getMean(double bg) const
calculate the predicted mean using the parameterized resolution
virtual ~CDCDedxPIDModule()
Destructor.
virtual void initialize() override
Initialize the module.
virtual void event() override
This method is called for each event.
void saveLookupLogl(double(&logl)[Const::ChargedStable::c_SetSize], double p, double dedx)
for all particles, save log-likelihood values into 'logl'.
void checkPDFs()
Check the pdfs for consistency everytime they change in the database.
virtual void terminate() override
End of the event processing.
double meanCurve(double *x, double *par, int version) const
parameterized beta-gamma curve for predicted means
void calculateMeans(double *mean, double *truncatedMean, double *truncatedMeanErr, const std::vector< double > &dedx) const
Save arithmetic and truncated mean for the 'dedx' values.
double sigmaCurve(double *x, double *par, int version) const
parameterized resolution for predictions
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'.
Debug output for CDCDedxPID module.
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
short getTDCCount() const
Getter for TDC count.
unsigned short getADCCount() const
Getter for integrated charge.
unsigned short getISuperLayer() const
Getter for iSuperLayer.
unsigned short getILayer() const
Getter for iLayer.
This class is used to transfer CDC information to the track fit.
const CDCHit * getCDCHit() const
get the pointer to the CDCHit object that was used to create this CDCRecoHit object.
WireID getWireID() const
Getter for WireID object.
The Class for CDC Geometry Parameters.
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
const double * innerRadiusWireLayer() const
Returns an array of inner radius of wire layers.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
const double * outerRadiusWireLayer() const
Returns an array of outer radius of wire layers.
This class simply assumes a linear translation through (0,0)
float getCharge(unsigned short adcCount, const WireID &, bool, float, float)
just multiply with the conversion factor and return.
Translator mirroring the realistic Digitization.
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.
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.
Provides a type-safe way to pass members of the chargedStableSet set.
static const unsigned int c_SetSize
Number of elements (for use in array bounds etc.)
A set of ParticleType objects, with defined order.
const ParticleType & at(unsigned int index) const
Return particle at given index, or end() if out of range.
int getPDGCode() const
PDG code.
static const ParticleSet chargedStableSet
set of charged stable particles
static const ChargedStable pion
charged pion particle
static const ChargedStable proton
proton particle
static const ChargedStable kaon
charged kaon particle
A class to hold the geometry of a cell.
A collection of classes that are useful for making a simple path length correction to the dE/dx measu...
A Class to store the Monte Carlo particle information.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
float getMass() const
Return the particle mass in GeV.
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
TVector3 getMomentum() const
Return momentum.
int m_pdg
PDG-Code of the particle.
int getPDG() const
Return PDG code of particle.
This is the Reconstruction Event-Data Model Track.
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...
const std::vector< genfit::TrackPoint * > & getHitPointsWithMeasurement() const
Return a list of measurements and track points, which can be used e.g. to extrapolate....
const std::vector< genfit::AbsTrackRep * > & getRepresentations() const
Return a list of track representations. You are not allowed to modify or delete them!
RecoHitInformation * getRecoHitInformation(HitType *hit) const
Return the reco hit information for a generic hit from the storeArray.
Values of the result of a track fit with a given particle hypothesis.
short getChargeSign() const
Return track charge (1 or -1).
double getCotTheta() const
Getter for tanLambda with CDF naming convention.
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Class to identify a wire inside the CDC.
unsigned short getIWire() const
Getter for wire within the layer.
This class collects all information needed and produced by a specific AbsFitter and is specific to on...
Contains the measurement and covariance in raw detector coordinates.
Exception class for error handling in GENFIT (provides storage for diagnostic information)
bool isTrackPruned() const
Has the track been pruned after the fit?
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
std::vector< double > getWeights() const
Get weights of measurements.
#StateOnPlane with additional covariance matrix.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
MCParticle * getMother() const
Returns a pointer to the mother particle.
Abstract base class for different kinds of events.