Belle II Software development
cdc modules

Namespaces

namespace  Belle2::CDC
 

Classes

class  CDCCosmicSelectorModule
 The Class for. More...
 
class  CDCCosmicSelectorAfterFullSimModule
 The Class for. More...
 
class  CDCCrossTalkAdderModule
 The Class for overlaying signal-induced asic cross-talk. More...
 
class  CDCDedxCorrectionModule
 This module may be used to apply the corrections to dE/dx per the calibration constants. More...
 
class  CDCDedxDQMModule
 This module to design collect CDC dEdx monitoring for DQM and only minimal information are stored. More...
 
class  CDCDedxElectronCollectorModule
 A collector module for CDC dE/dx electron calibrations. More...
 
class  CDCDedxHadronCollectorModule
 A collector module for CDC dE/dx hadron calibrations. More...
 
class  CDCDedxHitSaverModule
 Module that stores CDC hit information needed for dedx. More...
 
class  CDCDedxPIDCreatorModule
 Module that creates PID likelihoods from CDC hit information stored in CDCDedxHits using parameterized means and resolutions. More...
 
class  CDCDedxPIDModule
 Extract CDC dE/dx information from fitted tracks. More...
 
class  CDCDedxScanModule
 This class performs the same function as CDCDedxPIDModule, but does so without using real objects from basf2. More...
 
class  DedxPoint
 A collection of classes that are useful for making a simple path length correction to the dE/dx measurement for each hit in a CDC cell. More...
 
class  DedxLine
 A class to hold the endpoints and slope of a line. More...
 
class  DedxDriftCell
 A class to hold the geometry of a cell. More...
 
class  CDCDedxSkimModule
 This module may be used to skim a data sample according to a specific set of cuts. More...
 
class  CDCDedxSkimCDSTModule
 Extracts dE/dx information for calibration testing. More...
 
class  CDCDedxValidationModule
 First version committed on Feb 21 2019 Extracts dE/dx information for validation and writes a ROOT file. More...
 
class  ElectronValCollectorModule
 A collector module for CDC dE/dx electron calibrations. More...
 
class  CDCDigitizerModule
 The Class for Detailed Digitization of CDC. More...
 
class  cdcDQM7Module
 The module for Data Quality Monitor. More...
 
class  CDCDQMModule
 Make summary of data quality from reconstruction. More...
 
class  ScanCDCGeoModule
 Test module to save CDC geometry information to ntuple file. More...
 
class  CDCInitialT0DeterminationModule
 determine crude t0. More...
 
class  CDCJobCntlParModifierModule
 The Class for Detailed Digitization of CDC. More...
 
class  CDCCosmicTrackMergerModule
 Module use to select two cosmic tracks event and merger these two tracks become one. More...
 
class  HitLevelInfoWriterModule
 Extracts dE/dx information for calibration testing. More...
 

Functions

 REG_MODULE (CDCDedxHitSaver)
 Register module.
 
 REG_MODULE (CDCDedxPIDCreator)
 Register module.
 
 CDCDedxHitSaverModule ()
 Default constructor.
 
 ~CDCDedxHitSaverModule () override
 Destructor.
 
virtual void initialize () override
 Initialize the module.
 
virtual void event () override
 This method is called for each event.
 
 CDCDedxPIDCreatorModule ()
 Default constructor.
 
 ~CDCDedxPIDCreatorModule () override
 Destructor.
 
virtual void initialize () override
 Initialize the module.
 
virtual void event () override
 This method is called for each event.
 

Detailed Description

Function Documentation

◆ CDCDedxHitSaverModule()

Default constructor.

Definition at line 33 of file CDCDedxHitSaverModule.cc.

33 : Module()
34
35 {
36 // set module description
37 setDescription("Module that stores CDC hit information from recoTracks, which is needed for dedx.");
38 setPropertyFlags(c_ParallelProcessingCertified);
39 }

◆ CDCDedxPIDCreatorModule()

Default constructor.

Definition at line 41 of file CDCDedxPIDCreatorModule.cc.

41 : Module()
42
43 {
44 // set module description
45 setDescription("Module that creates PID likelihoods from CDC hit information stored in CDCDedxHits "
46 "using parameterized means and resolutions.");
47 setPropertyFlags(c_ParallelProcessingCertified);
48
49 addParam("removeLowest", m_removeLowest,
50 "Portion of events with low dE/dx that should be discarded", double(0.05));
51 addParam("removeHighest", m_removeHighest,
52 "Portion of events with high dE/dx that should be discarded", double(0.25));
53 addParam("useBackHalfCurlers", m_useBackHalfCurlers,
54 "Whether to use the back half of curlers", false);
55 addParam("trackLevel", m_trackLevel,
56 "ONLY USEFUL FOR MC: Use track-level MC (generate truncated mean from predicted mean and sigma using MC truth). "
57 "If false, use hit-level MC (use truncated mean determined from hits)", true);
58 }

◆ event() [1/2]

void event ( void )
overridevirtual

This method is called for each event.

All processing of the event takes place in this method.

Reimplemented from Module.

Definition at line 58 of file CDCDedxHitSaverModule.cc.

59 {
60 // clear output collection
61 m_hits.clear();
62
63 // loop over tracks and save CDC hits stored in recoTracks
64 for (const auto& track : m_tracks) {
65
66 const RecoTrack* recoTrack = track.getRelatedTo<RecoTrack>();
67
68 if (not recoTrack) {
69 B2WARNING("No related recoTrack for this track");
70 continue;
71 }
72
73 if (recoTrack->hasTrackFitStatus()) {
74 if (recoTrack->getTrackFitStatus()->isTrackPruned()) {
75 B2ERROR("GFTrack is pruned, please run CDCDedxHitSaver only on unpruned tracks! Skipping this track.");
76 continue;
77 }
78 } else // The RecoTrack might not have a fit status for reasons: let's skip it
79 continue;
80
81 // loop over hits of this track
82 for (const auto& hitPoint : recoTrack->getHitPointsWithMeasurement()) {
83 // get CDCHit
84 const auto* rawMeasurement = hitPoint->getRawMeasurement(0);
85 if (not rawMeasurement) continue;
86 const auto* cdcRecoHit = dynamic_cast<const CDCRecoHit*>(rawMeasurement);
87 if (not cdcRecoHit) continue;
88 const auto* cdcHit = cdcRecoHit->getCDCHit();
89 if (not cdcHit) continue;
90
91 // make sure the fitter info exists
92 const auto* fitterInfo = hitPoint->getFitterInfo();
93 if (not fitterInfo) continue;
94
95 // check which algorithm found this hit
96 const RecoHitInformation* hitInfo = recoTrack->getRecoHitInformation(cdcHit);
97 int foundByTrackFinder = hitInfo ? hitInfo->getFoundByTrackFinder() : RecoHitInformation::c_undefinedTrackFinder;
98
99 // get weights
100 std::map<int, double> weights;
101 for (const auto& rep : recoTrack->getRepresentations()) {
102 const auto* kalmanFitterInfo = hitPoint->getKalmanFitterInfo(rep);
103 if (not kalmanFitterInfo) continue;
104 auto wts = kalmanFitterInfo->getWeights();
105 double wt = 0;
106 for (double w : wts) if (w > wt) wt = w; // take the largest one (there should be always two, but safer to do in this way)
107 weights[std::abs(rep->getPDG())] = wt;
108 }
109
110 // get needed vectors, save the hit and add relation to track
111 try {
112 const genfit::MeasuredStateOnPlane& mop = fitterInfo->getFittedState();
113 auto pocaMom = ROOT::Math::XYZVector(mop.getMom());
114 auto pocaOnTrack = ROOT::Math::XYZVector(mop.getPos());
115 auto pocaOnWire = ROOT::Math::XYZVector(mop.getPlane()->getO());
116
117 auto* hit = m_hits.appendNew(cdcRecoHit->getWireID(), cdcHit->getTDCCount(), cdcHit->getADCCount(),
118 pocaMom, pocaOnTrack, pocaOnWire, foundByTrackFinder,
119 weights[211], weights[321], weights[2212]);
120 track.addRelationTo(hit);
121 } catch (genfit::Exception&) {
122 B2WARNING("Track: " << track.getArrayIndex() << ": genfit::MeasuredStateOnPlane exception occurred");
123 continue;
124 }
125
126 }
127 }
128
129 }

◆ event() [2/2]

void event ( void )
overridevirtual

This method is called for each event.

All processing of the event takes place in this method.

Reimplemented from Module.

Definition at line 85 of file CDCDedxPIDCreatorModule.cc.

86 {
87 // check if CDCDedxHits are present; return if not.
88 if (not m_hits.isValid()) {
89 m_warnCount++;
90 if (m_warnCount < 10) {
91 B2WARNING("StoreArray 'CDCDedxHits' does not exist, returning. Probably running on old cdst.");
92 } else if (m_warnCount == 10) {
93 B2WARNING("StoreArray 'CDCDedxHits' does not exist, returning. ...message will be suppressed now.");
94 }
95 return;
96 }
97
98 // clear output collections
99 m_likelihoods.clear();
100 m_dedxTracks.clear();
101
102 // CDC geometry parameters and translators
103 const auto& cdcgeo = CDCGeometryPar::Instance();
104 LinearGlobalADCCountTranslator adcTranslator;
105 RealisticTDCCountTranslator tdcTranslator;
106
107 // is data or MC ?
108 bool isData = not Environment::Instance().isMC();
109
110 // track independent calibration constants
111 double runGain = isData ? m_DBRunGain->getRunGain() : 1.0;
112 double timeGain = 1;
113 double timeReso = 1; // this is multiplicative constant
114 if (isData and m_TTDInfo.isValid() and m_TTDInfo->hasInjection()) {
115 timeGain = m_DBInjectTime->getCorrection("mean", m_TTDInfo->isHER(), m_TTDInfo->getTimeSinceLastInjectionInMicroSeconds());
116 timeReso = m_DBInjectTime->getCorrection("reso", m_TTDInfo->isHER(), m_TTDInfo->getTimeSinceLastInjectionInMicroSeconds());
117 }
118 double scale = m_DBScaleFactor->getScaleFactor(); // scale factor to make electron dE/dx ~ 1
119 if (scale == 0) {
120 B2ERROR("Scale factor from DB is zero! Will be set to one");
121 scale = 1;
122 }
123
124 // loop over tracks
125 for (const auto& track : m_tracks) {
126 // track fit result
127 const auto* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
128 if (not fitResult) {
129 B2WARNING("No related fit for track, skip it.");
130 continue;
131 }
132
133 // hits of this track
134 const auto hits = track.getRelationsTo<CDCDedxHit>();
135 if (hits.size() == 0) continue;
136
137 // track momentum
138 const auto& trackMom = fitResult->getMomentum();
139 double theta = trackMom.Theta();
140 double cosTheta = std::cos(theta);
141 double sinTheta = std::sin(theta);
142
143 // track dependent calibration constants
144 bool isEdge = std::abs(cosTheta + 0.860) < 0.010 or std::abs(cosTheta - 0.955) <= 0.005;
145 double cosEdgeCor = (isData and isEdge) ? m_DBCosEdgeCor->getMean(cosTheta) : 1.0;
146
147 // MC particle
148 const auto* mcParticle = isData ? nullptr : track.getRelated<MCParticle>();
149
150 // debug output
151 CDCDedxTrack* dedxTrack = m_dedxTracks.appendNew();
152 if (dedxTrack) {
153 dedxTrack->m_track = track.getArrayIndex();
154 dedxTrack->m_charge = fitResult->getChargeSign();
155 dedxTrack->m_cosTheta = cosTheta;
156 dedxTrack->m_p = trackMom.R();
157 if (isData and m_TTDInfo.isValid() and m_TTDInfo->hasInjection()) {
158 dedxTrack->m_injring = m_TTDInfo->isHER();
159 dedxTrack->m_injtime = m_TTDInfo->getTimeSinceLastInjectionInMicroSeconds();
160 }
161 if (mcParticle) {
162 dedxTrack->m_pdg = mcParticle->getPDG();
163 dedxTrack->m_mcmass = mcParticle->getMass();
164 const auto* mother = mcParticle->getMother();
165 dedxTrack->m_motherPDG = mother ? mother->getPDG() : 0;
166 const auto& trueMom = mcParticle->getMomentum();
167 dedxTrack->m_pTrue = trueMom.R();
168 dedxTrack->m_cosThetaTrue = std::cos(trueMom.Theta());
169 }
170 dedxTrack->m_scale = scale;
171 dedxTrack->m_cosEdgeCor = cosEdgeCor;
172 dedxTrack->m_runGain = runGain;
173 dedxTrack->m_timeGain = timeGain;
174 dedxTrack->m_timeReso = timeReso;
175 }
176
177 // loop over hits
178 int lastLayer = -1;
179 double pCDC = 0;
180 std::map<int, DEDX> dedxWires;
181 for (const auto& hit : hits) {
182 // wire numbering: layer and superlayer
183 const auto& wireID = hit.getWireID();
184 int layer = wireID.getILayer(); // layer within superlayer
185 unsigned int superlayer = wireID.getISuperLayer();
186 int currentLayer = (superlayer == 0) ? layer : (8 + (superlayer - 1) * 6 + layer); // continuous layer number
187 if (not m_useBackHalfCurlers and currentLayer < lastLayer) break;
188 lastLayer = currentLayer;
189
190 // track momentum at the first hit
191 if (pCDC == 0) pCDC = hit.getPOCAMomentum().R();
192
193 // drift cell
194 double innerRadius = cdcgeo.innerRadiusWireLayer()[currentLayer];
195 double outerRadius = cdcgeo.outerRadiusWireLayer()[currentLayer];
196 const ROOT::Math::XYZVector& wirePosF = cdcgeo.wireForwardPosition(wireID, CDCGeometryPar::c_Aligned);
197 double wireRadius = wirePosF.Rho();
198 int nWires = cdcgeo.nWiresInLayer(currentLayer);
199 double topHeight = outerRadius - wireRadius;
200 double bottomHeight = wireRadius - innerRadius;
201 double topHalfWidth = M_PI * outerRadius / nWires;
202 double bottomHalfWidth = M_PI * innerRadius / nWires;
203 DedxDriftCell cell(DedxPoint(-topHalfWidth, topHeight),
204 DedxPoint(topHalfWidth, topHeight),
205 DedxPoint(bottomHalfWidth, -bottomHeight),
206 DedxPoint(-bottomHalfWidth, -bottomHeight));
207
208 // length of a track within the drift cell
209 double doca = hit.getSignedDOCAXY();
210 double entAng = hit.getEntranceAngle();
211 double celldx = cell.dx(doca, entAng) / sinTheta; // length of a track in the cell
212 if (not cell.isValid()) continue;
213
214 //cos correction
215 double cosCor = isData ? m_DBCosineCor->getMean(currentLayer, cosTheta) : 1.0;
216
217 // wire gain calibration (iwire is a continuous wire number)
218 int wire = wireID.getIWire();
219 int iwire = (superlayer == 0) ? 160 * layer + wire : m_nLayerWires[superlayer - 1] + (160 + 32 * (superlayer - 1)) * layer + wire;
220 double wiregain = isData ? m_DBWireGains->getWireGain(iwire) : 1.0;
221
222 // re-scaled (RS) doca and entAng variable: map to square cell
223 double cellHalfWidth = M_PI * wireRadius / nWires;
224 double cellHeight = topHeight + bottomHeight;
225 double cellR = 2 * cellHalfWidth / cellHeight;
226 double tana = std::max(std::min(std::tan(entAng), 1e10), -1e10); // this fixes bug in CDCDedxPIDModule near +-pi/2
227 double docaRS = doca * std::sqrt((1 + cellR * cellR * tana * tana) / (1 + tana * tana));
228 double normDocaRS = docaRS / cellHalfWidth;
229 double entAngRS = std::atan(tana / cellR);
230
231 // one and two dimensional corrections
232 double onedcor = isData ? m_DB1DCell->getMean(currentLayer, entAngRS) : 1.0;
233 double twodcor = isData ? m_DB2DCell->getMean(currentLayer, normDocaRS, entAngRS) : 1.0;
234
235 // total correction
236 double correction = runGain * cosCor * cosEdgeCor * timeGain * wiregain * twodcor * onedcor;
237
238 // calibrated ADC count
239 double adcCount = isData ? m_DBNonlADC->getCorrectedADC(hit.getADCCount(), currentLayer) : hit.getADCCount();
240 double adcCalibrated = correction != 0 ? adcCount / scale / correction : 0;
241
242 // merge dEdx measurements on single wires; take active wires only
243 if (correction != 0) dedxWires[iwire].add(hit, iwire, currentLayer, celldx, adcCalibrated);
244
245 // debug output
246 if (dedxTrack) {
247 dedxTrack->m_pCDC = pCDC;
248 const auto& pocaMom = hit.getPOCAMomentum();
249 double pocaPhi = pocaMom.Phi();
250 double pocaTheta = pocaMom.Theta();
251 double pocaZ = hit.getPOCAOnWire().Z();
252 double hitCharge = adcTranslator.getCharge(adcCount, wireID, false, pocaZ, pocaPhi);
253 double driftDRealistic = tdcTranslator.getDriftLength(hit.getTDCCount(), wireID, 0, true, pocaZ, pocaPhi, pocaTheta);
254 double driftDRealisticRes = tdcTranslator.getDriftLengthResolution(driftDRealistic, wireID, true, pocaZ, pocaPhi, pocaTheta);
255 double cellDedx = adcCalibrated / celldx;
256
257 dedxTrack->addHit(wire, iwire, currentLayer, doca, docaRS, entAng, entAngRS,
258 adcCount, hit.getADCCount(), hitCharge, celldx * sinTheta, cellDedx, cellHeight, cellHalfWidth,
259 hit.getTDCCount(), driftDRealistic, driftDRealisticRes, cosCor, wiregain, twodcor, onedcor,
260 hit.getFoundByTrackFinder(), hit.getWeightPionHypo(), hit.getWeightKaonHypo(), hit.getWeightProtonHypo());
261 }
262
263 } // end of loop over hits
264
265 // merge dEdx measurements in layers
266 std::map<int, DEDX> dedxLayers;
267 for (const auto& dedxWire : dedxWires) {
268 const auto& dedx = dedxWire.second;
269 dedxLayers[dedx.cLayer].add(dedx);
270 }
271
272 // push dEdx values to a vector
273 std::vector<double> dedxValues;
274 for (const auto& dedxLayer : dedxLayers) {
275 const auto& dedx = dedxLayer.second;
276 if (dedx.dx > 0 and dedx.dE > 0) {
277 dedxValues.push_back(dedx.dE / dedx.dx);
278 // debug output
279 if (dedxTrack) dedxTrack->addDedx(dedx.nhits, dedx.cWire, dedx.cLayer, dedx.dx, dedxValues.back());
280 }
281 }
282 if (dedxValues.empty()) continue;
283
284 // sort dEdx values
285 std::sort(dedxValues.begin(), dedxValues.end());
286
287 // calculate mean
288 double mean = 0;
289 for (auto x : dedxValues) mean += x;
290 mean /= dedxValues.size();
291
292 // calculate truncated mean and error
293 int lowEdgeTrunc = int(dedxValues.size() * m_removeLowest + 0.51);
294 int highEdgeTrunc = int(dedxValues.size() * (1 - m_removeHighest) + 0.51);
295 double truncatedMean = 0;
296 double sumOfSquares = 0;
297 int numValues = 0;
298 for (int i = lowEdgeTrunc; i < highEdgeTrunc; i++) {
299 double x = dedxValues[i];
300 truncatedMean += x;
301 sumOfSquares += x * x;
302 numValues++;
303 }
304 if (numValues > 0) {
305 truncatedMean /= numValues;
306 } else {
307 truncatedMean = mean;
308 numValues = dedxValues.size();
309 }
310 double truncatedError = numValues > 1 ? std::sqrt(sumOfSquares / numValues - truncatedMean * truncatedMean) / (numValues - 1) : 0;
311
312 // apply the saturation correction only to data (the so called "hadron correction")
313 double correctedMean = isData ? m_DBHadronCor->getCorrectedMean(truncatedMean, cosTheta) : truncatedMean;
314
315 // track level MC (e.g. replacing truncated mean with a generated one)
316 if (m_trackLevel and mcParticle) {
317 double mass = mcParticle->getMass();
318 if (mass > 0) {
319 double mcMean = m_DBMeanPars->getMean(pCDC / mass);
320 double mcSigma = m_DBSigmaPars->getSigma(mcMean, numValues, cosTheta, timeReso);
321 correctedMean = gRandom->Gaus(mcMean, mcSigma);
322 while (correctedMean < 0) correctedMean = gRandom->Gaus(mcMean, mcSigma);
323 // debug output
324 if (dedxTrack) dedxTrack->m_simDedx = correctedMean;
325 }
326 }
327
328 // calculate log likelihoods
329 double cdcLogL[Const::ChargedStable::c_SetSize] = {0};
330 for (const auto& chargedStable : Const::chargedStableSet) {
331 double betagamma = pCDC / chargedStable.getMass();
332 double predictedMean = m_DBMeanPars->getMean(betagamma);
333 double predictedSigma = m_DBSigmaPars->getSigma(predictedMean, numValues, cosTheta, timeReso);
334 if (predictedSigma <= 0) B2ERROR("Predicted sigma is not positive for PDG = " << chargedStable.getPDGCode());
335 double chi = (correctedMean - predictedMean) / predictedSigma;
336 int index = chargedStable.getIndex();
337 cdcLogL[index] = -0.5 * chi * chi;
338 // debug output
339 if (dedxTrack) {
340 dedxTrack->m_predmean[index] = predictedMean;
341 dedxTrack->m_predres[index] = predictedSigma;
342 dedxTrack->m_cdcChi[index] = chi;
343 dedxTrack->m_cdcLogl[index] = cdcLogL[index];
344 }
345 }
346
347 // save log likelihoods
348 auto* likelihoods = m_likelihoods.appendNew(cdcLogL);
349 track.addRelationTo(likelihoods);
350
351 // debug output
352 if (dedxTrack) {
353 double fullLength = 0;
354 for (const auto& dedxLayer : dedxLayers) fullLength += dedxLayer.second.dx;
355 dedxTrack->m_length = fullLength;
356 dedxTrack->m_dedxAvg = mean;
357 dedxTrack->m_dedxAvgTruncatedNoSat = truncatedMean;
358 dedxTrack->m_dedxAvgTruncatedErr = truncatedError;
359 dedxTrack->m_dedxAvgTruncated = correctedMean;
360 dedxTrack->m_lNHitsUsed = numValues;
361 track.addRelationTo(dedxTrack);
362 }
363
364 } // end of loop over tracks
365
366 }

◆ initialize() [1/2]

void initialize ( void )
overridevirtual

Initialize the module.

Reimplemented from Module.

Definition at line 45 of file CDCDedxHitSaverModule.cc.

46 {
47 m_tracks.isRequired();
48 m_recoTracks.isRequired();
49 m_hits.registerInDataStore();
50 m_tracks.registerRelationTo(m_hits);
51
52 if (not genfit::MaterialEffects::getInstance()->isInitialized()) {
53 B2FATAL("Need to have SetupGenfitExtrapolationModule in path before this one.");
54 }
55
56 }

◆ initialize() [2/2]

void initialize ( void )
overridevirtual

Initialize the module.

Reimplemented from Module.

Definition at line 64 of file CDCDedxPIDCreatorModule.cc.

65 {
66 m_tracks.isRequired();
67 m_hits.isOptional(); // in order to run also with old cdst's where this collection doesn't exist
68 m_mcParticles.isOptional();
69 m_TTDInfo.isOptional();
70 m_likelihoods.registerInDataStore();
71 m_tracks.registerRelationTo(m_likelihoods);
72 m_dedxTracks.registerInDataStore();
73 m_tracks.registerRelationTo(m_dedxTracks);
74
75 m_nLayerWires[0] = 1280;
76 for (int i = 1; i < 9; ++i) {
77 m_nLayerWires[i] = m_nLayerWires[i - 1] + 6 * (160 + (i - 1) * 32);
78 }
79
80 if (not m_trackLevel)
81 B2WARNING("Hit-level MC still needs a precise calibration to perform well! Until then please use track-level MC.");
82
83 }

◆ ~CDCDedxHitSaverModule()

~CDCDedxHitSaverModule ( )
override

Destructor.

Definition at line 41 of file CDCDedxHitSaverModule.cc.

42 {
43 }

◆ ~CDCDedxPIDCreatorModule()

~CDCDedxPIDCreatorModule ( )
override

Destructor.

Definition at line 60 of file CDCDedxPIDCreatorModule.cc.

61 {
62 }