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.
 
virtual ~CDCDedxHitSaverModule ()
 Destructor.
 
virtual void initialize () override
 Initialize the module.
 
virtual void event () override
 This method is called for each event.
 
 CDCDedxPIDCreatorModule ()
 Default constructor.
 
virtual ~CDCDedxPIDCreatorModule ()
 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 double cosCor = isData ? m_DBCosineCor->getMean(cosTheta) : 1.0;
145 bool isEdge = std::abs(cosTheta + 0.860) < 0.010 or std::abs(cosTheta - 0.955) <= 0.005;
146 double cosEdgeCor = (isData and isEdge) ? m_DBCosEdgeCor->getMean(cosTheta) : 1.0;
147
148 // MC particle
149 const auto* mcParticle = isData ? nullptr : track.getRelated<MCParticle>();
150
151 // debug output
152 CDCDedxTrack* dedxTrack = m_dedxTracks.appendNew();
153 if (dedxTrack) {
154 dedxTrack->m_track = track.getArrayIndex();
155 dedxTrack->m_charge = fitResult->getChargeSign();
156 dedxTrack->m_cosTheta = cosTheta;
157 dedxTrack->m_p = trackMom.R();
158 if (isData and m_TTDInfo.isValid() and m_TTDInfo->hasInjection()) {
159 dedxTrack->m_injring = m_TTDInfo->isHER();
160 dedxTrack->m_injtime = m_TTDInfo->getTimeSinceLastInjectionInMicroSeconds();
161 }
162 if (mcParticle) {
163 dedxTrack->m_pdg = mcParticle->getPDG();
164 dedxTrack->m_mcmass = mcParticle->getMass();
165 const auto* mother = mcParticle->getMother();
166 dedxTrack->m_motherPDG = mother ? mother->getPDG() : 0;
167 const auto& trueMom = mcParticle->getMomentum();
168 dedxTrack->m_pTrue = trueMom.R();
169 dedxTrack->m_cosThetaTrue = std::cos(trueMom.Theta());
170 }
171 dedxTrack->m_scale = scale;
172 dedxTrack->m_cosCor = cosCor;
173 dedxTrack->m_cosEdgeCor = cosEdgeCor;
174 dedxTrack->m_runGain = runGain;
175 dedxTrack->m_timeGain = timeGain;
176 dedxTrack->m_timeReso = timeReso;
177 }
178
179 // loop over hits
180 int lastLayer = -1;
181 double pCDC = 0;
182 std::map<int, DEDX> dedxWires;
183 for (const auto& hit : hits) {
184 // wire numbering: layer and superlayer
185 const auto& wireID = hit.getWireID();
186 int layer = wireID.getILayer(); // layer within superlayer
187 int superlayer = wireID.getISuperLayer();
188 int currentLayer = (superlayer == 0) ? layer : (8 + (superlayer - 1) * 6 + layer); // continuous layer number
189 if (not m_useBackHalfCurlers and currentLayer < lastLayer) break;
190 lastLayer = currentLayer;
191
192 // track momentum at the first hit
193 if (pCDC == 0) pCDC = hit.getPOCAMomentum().R();
194
195 // drift cell
196 double innerRadius = cdcgeo.innerRadiusWireLayer()[currentLayer];
197 double outerRadius = cdcgeo.outerRadiusWireLayer()[currentLayer];
198 const ROOT::Math::XYZVector& wirePosF = cdcgeo.wireForwardPosition(wireID, CDCGeometryPar::c_Aligned);
199 double wireRadius = wirePosF.Rho();
200 int nWires = cdcgeo.nWiresInLayer(currentLayer);
201 double topHeight = outerRadius - wireRadius;
202 double bottomHeight = wireRadius - innerRadius;
203 double topHalfWidth = M_PI * outerRadius / nWires;
204 double bottomHalfWidth = M_PI * innerRadius / nWires;
205 DedxDriftCell cell(DedxPoint(-topHalfWidth, topHeight),
206 DedxPoint(topHalfWidth, topHeight),
207 DedxPoint(bottomHalfWidth, -bottomHeight),
208 DedxPoint(-bottomHalfWidth, -bottomHeight));
209
210 // length of a track within the drift cell
211 double doca = hit.getSignedDOCAXY();
212 double entAng = hit.getEntranceAngle();
213 double celldx = cell.dx(doca, entAng) / sinTheta; // length of a track in the cell
214 if (not cell.isValid()) continue;
215
216 // wire gain calibration (iwire is a continuous wire number)
217 int wire = wireID.getIWire();
218 int iwire = (superlayer == 0) ? 160 * layer + wire : m_nLayerWires[superlayer - 1] + (160 + 32 * (superlayer - 1)) * layer + wire;
219 double wiregain = isData ? m_DBWireGains->getWireGain(iwire) : 1.0;
220
221 // re-scaled (RS) doca and entAng variable: map to square cell
222 double cellHalfWidth = M_PI * wireRadius / nWires;
223 double cellHeight = topHeight + bottomHeight;
224 double cellR = 2 * cellHalfWidth / cellHeight;
225 double tana = std::max(std::min(std::tan(entAng), 1e10), -1e10); // this fixes bug in CDCDedxPIDModule near +-pi/2
226 double docaRS = doca * std::sqrt((1 + cellR * cellR * tana * tana) / (1 + tana * tana));
227 double normDocaRS = docaRS / cellHalfWidth;
228 double entAngRS = std::atan(tana / cellR);
229
230 // one and two dimensional corrections
231 double onedcor = isData ? m_DB1DCell->getMean(currentLayer, entAngRS) : 1.0;
232 double twodcor = isData ? m_DB2DCell->getMean(currentLayer, normDocaRS, entAngRS) : 1.0;
233
234 // total correction
235 double correction = runGain * cosCor * cosEdgeCor * timeGain * wiregain * twodcor * onedcor;
236
237 // calibrated ADC count
238 double adcCount = isData ? m_DBNonlADC->getCorrectedADC(hit.getADCCount(), currentLayer) : hit.getADCCount();
239 double adcCalibrated = correction != 0 ? adcCount / scale / correction : 0;
240
241 // merge dEdx measurements on single wires; take active wires only
242 if (correction != 0) dedxWires[iwire].add(hit, iwire, currentLayer, celldx, adcCalibrated);
243
244 // debug output
245 if (dedxTrack) {
246 dedxTrack->m_pCDC = pCDC;
247 const auto& pocaMom = hit.getPOCAMomentum();
248 double pocaPhi = pocaMom.Phi();
249 double pocaTheta = pocaMom.Theta();
250 double pocaZ = hit.getPOCAOnWire().Z();
251 double hitCharge = adcTranslator.getCharge(adcCount, wireID, false, pocaZ, pocaPhi);
252 double driftDRealistic = tdcTranslator.getDriftLength(hit.getTDCCount(), wireID, 0, true, pocaZ, pocaPhi, pocaTheta);
253 double driftDRealisticRes = tdcTranslator.getDriftLengthResolution(driftDRealistic, wireID, true, pocaZ, pocaPhi, pocaTheta);
254 double cellDedx = adcCalibrated / celldx;
255
256 dedxTrack->addHit(wire, iwire, currentLayer, doca, docaRS, entAng, entAngRS,
257 adcCount, hit.getADCCount(), hitCharge, celldx * sinTheta, cellDedx, cellHeight, cellHalfWidth,
258 hit.getTDCCount(), driftDRealistic, driftDRealisticRes, wiregain, twodcor, onedcor,
259 hit.getFoundByTrackFinder(), hit.getWeightPionHypo(), hit.getWeightKaonHypo(), hit.getWeightProtonHypo());
260 }
261
262 } // end of loop over hits
263
264 // merge dEdx measurements in layers
265 std::map<int, DEDX> dedxLayers;
266 for (const auto& dedxWire : dedxWires) {
267 const auto& dedx = dedxWire.second;
268 dedxLayers[dedx.cLayer].add(dedx);
269 }
270
271 // push dEdx values to a vector
272 std::vector<double> dedxValues;
273 for (const auto& dedxLayer : dedxLayers) {
274 const auto& dedx = dedxLayer.second;
275 if (dedx.dx > 0 and dedx.dE > 0) {
276 dedxValues.push_back(dedx.dE / dedx.dx);
277 // debug output
278 if (dedxTrack) dedxTrack->addDedx(dedx.nhits, dedx.cWire, dedx.cLayer, dedx.dx, dedxValues.back());
279 }
280 }
281 if (dedxValues.empty()) continue;
282
283 // sort dEdx values
284 std::sort(dedxValues.begin(), dedxValues.end());
285
286 // calculate mean
287 double mean = 0;
288 for (auto x : dedxValues) mean += x;
289 mean /= dedxValues.size();
290
291 // calculate truncated mean and error
292 int lowEdgeTrunc = int(dedxValues.size() * m_removeLowest + 0.51);
293 int highEdgeTrunc = int(dedxValues.size() * (1 - m_removeHighest) + 0.51);
294 double truncatedMean = 0;
295 double sumOfSquares = 0;
296 int numValues = 0;
297 for (int i = lowEdgeTrunc; i < highEdgeTrunc; i++) {
298 double x = dedxValues[i];
299 truncatedMean += x;
300 sumOfSquares += x * x;
301 numValues++;
302 }
303 if (numValues > 0) {
304 truncatedMean /= numValues;
305 } else {
306 truncatedMean = mean;
307 numValues = dedxValues.size();
308 }
309 double truncatedError = numValues > 1 ? std::sqrt(sumOfSquares / numValues - truncatedMean * truncatedMean) / (numValues - 1) : 0;
310
311 // apply the saturation correction only to data (the so called "hadron correction")
312 double correctedMean = isData ? m_DBHadronCor->getCorrectedMean(truncatedMean, cosTheta) : truncatedMean;
313
314 // track level MC (e.g. replacing truncated mean with a generated one)
315 if (m_trackLevel and mcParticle) {
316 double mass = mcParticle->getMass();
317 if (mass > 0) {
318 double mcMean = m_DBMeanPars->getMean(pCDC / mass);
319 double mcSigma = m_DBSigmaPars->getSigma(mcMean, numValues, cosTheta, timeReso);
320 correctedMean = gRandom->Gaus(mcMean, mcSigma);
321 while (correctedMean < 0) correctedMean = gRandom->Gaus(mcMean, mcSigma);
322 // debug output
323 if (dedxTrack) dedxTrack->m_simDedx = correctedMean;
324 }
325 }
326
327 // calculate log likelihoods
328 double cdcLogL[Const::ChargedStable::c_SetSize] = {0};
329 for (const auto& chargedStable : Const::chargedStableSet) {
330 double betagamma = pCDC / chargedStable.getMass();
331 double predictedMean = m_DBMeanPars->getMean(betagamma);
332 double predictedSigma = m_DBSigmaPars->getSigma(predictedMean, numValues, cosTheta, timeReso);
333 if (predictedSigma <= 0) B2ERROR("Predicted sigma is not positive for PDG = " << chargedStable.getPDGCode());
334 double chi = (correctedMean - predictedMean) / predictedSigma;
335 int index = chargedStable.getIndex();
336 cdcLogL[index] = -0.5 * chi * chi;
337 // debug output
338 if (dedxTrack) {
339 dedxTrack->m_predmean[index] = predictedMean;
340 dedxTrack->m_predres[index] = predictedSigma;
341 dedxTrack->m_cdcChi[index] = chi;
342 dedxTrack->m_cdcLogl[index] = cdcLogL[index];
343 }
344 }
345
346 // save log likelihoods
347 auto* likelihoods = m_likelihoods.appendNew(cdcLogL);
348 track.addRelationTo(likelihoods);
349
350 // debug output
351 if (dedxTrack) {
352 double fullLength = 0;
353 for (const auto& dedxLayer : dedxLayers) fullLength += dedxLayer.second.dx;
354 dedxTrack->m_length = fullLength;
355 dedxTrack->m_dedxAvg = mean;
356 dedxTrack->m_dedxAvgTruncatedNoSat = truncatedMean;
357 dedxTrack->m_dedxAvgTruncatedErr = truncatedError;
358 dedxTrack->m_dedxAvgTruncated = correctedMean;
359 dedxTrack->m_lNHitsUsed = numValues;
360 track.addRelationTo(dedxTrack);
361 }
362
363 } // end of loop over tracks
364
365 }

◆ 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 ( )
virtual

Destructor.

Definition at line 41 of file CDCDedxHitSaverModule.cc.

42 {
43 }

◆ ~CDCDedxPIDCreatorModule()

Destructor.

Definition at line 60 of file CDCDedxPIDCreatorModule.cc.

61 {
62 }