Belle II Software development
SVDBackgroundModule.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#include <svd/modules/svdBackground/SVDBackgroundModule.h>
9
10#include <framework/datastore/DataStore.h>
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/datastore/StoreArray.h>
13#include <framework/datastore/RelationArray.h>
14
15#include <framework/dataobjects/FileMetaData.h>
16#include <framework/dataobjects/BackgroundMetaData.h>
17#include <framework/gearbox/Const.h>
18#include <mdst/dataobjects/MCParticle.h>
19#include <svd/dataobjects/SVDSimHit.h>
20#include <svd/dataobjects/SVDTrueHit.h>
21#include <svd/dataobjects/SVDShaperDigit.h>
22#include <svd/dataobjects/SVDCluster.h>
23#include <svd/dataobjects/SVDEnergyDepositionEvent.h>
24#include <svd/dataobjects/SVDNeutronFluxEvent.h>
25#include <svd/dataobjects/SVDOccupancyEvent.h>
26#include <cmath>
27#include <fstream>
28#include <set>
29#include <algorithm>
30#include <boost/format.hpp>
31
32#include <Math/Vector3D.h>
33
34using namespace std;
35using boost::format;
36using namespace Belle2;
37using namespace Belle2::SVD;
38
39//-----------------------------------------------------------------
40// A small helper function to convert between electons and ADU
41// ----------------------------------------------------------------
42double eToADU(double charge)
43{
44 double minADC = -96000;
45 double maxADC = 288000;
46 double unitADC = (maxADC - minADC) / 1024.0;
47 return round(std::min(maxADC, std::max(minADC, charge)) / unitADC);
48}
49
50//-----------------------------------------------------------------
51// Register the Module
52//-----------------------------------------------------------------
53REG_MODULE(SVDBackground);
54
55
56//-----------------------------------------------------------------
57// Implementation
58//-----------------------------------------------------------------
59
61 Module(), m_outputDirectoryName(""),
62 m_doseReportingLevel(c_reportNTuple),
63 m_nfluxReportingLevel(c_reportNTuple),
64 m_occupancyReportingLevel(c_reportNTuple),
65 m_componentName(""), m_componentTime(0),
66 m_triggerWidth(5), m_acceptanceWidth(2.5), // keeps 99%
67 m_nielNeutrons(new TNiel(c_niel_neutronFile)),
68 m_nielProtons(new TNiel(c_niel_protonFile)),
69 m_nielPions(new TNiel(c_niel_pionFile)),
70 m_nielElectrons(new TNiel(c_niel_electronFile))
71{
72 //Set module properties
73 setDescription("SVD background module");
74 setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
75 // FIXME: This information can in principle be extracted from bg files, though not trivially.
76 addParam("componentName", m_componentName, "Background component name to process", m_componentName);
77 addParam("componentTime", m_componentTime, "Background component time", m_componentTime);
78 addParam("triggerWidth", m_triggerWidth, "RMS of trigger time estimate in ns", m_triggerWidth);
79 addParam("acceptanceWidth", m_acceptanceWidth,
80 "A hit is accepted if arrived within +/- accpetanceWidth * RMS(hit time - trigger time) of trigger; in ns", m_acceptanceWidth);
81 addParam("doseReportingLevel", m_doseReportingLevel, "0 - no data, 1 - summary only, 2 - summary + ntuple", m_doseReportingLevel);
82 addParam("nfluxReportingLevel", m_nfluxReportingLevel, "0 - no data, 1 - summary only, 2 - summary + ntuple",
84 addParam("occupancyReportingLevel", m_occupancyReportingLevel, "0 - no data, 1 - summary only, 2 - summary + ntuple",
86 addParam("outputDirectory", m_outputDirectoryName, "Name of output directory", m_outputDirectoryName);
87}
88
89const ROOT::Math::XYZVector& SVDBackgroundModule::pointToGlobal(VxdID sensorID, const ROOT::Math::XYZVector& local)
90{
91 static ROOT::Math::XYZVector result(0, 0, 0);
92
93 const SVD::SensorInfo& info = getInfo(sensorID);
94 result = info.pointToGlobal(local);
95 return result;
96}
97
98const ROOT::Math::XYZVector& SVDBackgroundModule::vectorToGlobal(VxdID sensorID, const ROOT::Math::XYZVector& local)
99{
100 static ROOT::Math::XYZVector result(0, 0, 0);
101
102 const SVD::SensorInfo& info = getInfo(sensorID);
103 result = info.vectorToGlobal(local);
104 return result;
105}
106
108{
109}
110
112{
113 //Register collections
121
122 RelationArray relDigitsMCParticles(storeDigits, storeMCParticles);
123 RelationArray relDigitsTrueHits(storeDigits, storeTrueHits);
124 RelationArray relMCParticlesTrueHits(storeMCParticles, storeTrueHits);
125 RelationArray relTrueHitsSimHits(storeTrueHits, storeSimHits);
126
127 // Add two new StoreArrays
129 storeEnergyDeposits.registerInDataStore();
131 storeNeutronFluxes.registerInDataStore();
133 storeOccupancyEvents.registerInDataStore();
134
135 //Store names to speed up creation later
136 m_storeFileMetaDataName = storeFileMetaData.getName();
137 m_storeBgMetaDataName = storeBgMetaData.getName();
138 m_storeMCParticlesName = storeMCParticles.getName();
139 m_storeSimHitsName = storeSimHits.getName();
140 m_storeTrueHitsName = storeTrueHits.getName();
141 m_storeDigitsName = storeDigits.getName();
142 m_relDigitsMCParticlesName = relDigitsMCParticles.getName();
143 m_relDigitsTrueHitsName = relDigitsTrueHits.getName();
144 m_relParticlesTrueHitsName = relMCParticlesTrueHits.getName();
145 m_relTrueHitsSimHitsName = relTrueHitsSimHits.getName();
146 m_storeEnergyDepositsName = storeEnergyDeposits.getName();
147 m_storeNeutronFluxesName = storeNeutronFluxes.getName();
148
152}
153
155{
156}
157
159{
160 //Register collections
163 const StoreArray<MCParticle> storeMCParticles(m_storeMCParticlesName);
164 const StoreArray<SVDSimHit> storeSimHits(m_storeSimHitsName);
165 const StoreArray<SVDTrueHit> storeTrueHits(m_storeTrueHitsName);
167 const StoreArray<SVDCluster> storeClsuters(m_storeClustersName);
168
169 // Add two new StoreArrays
173
174 // Relations
175 RelationArray relDigitsMCParticles(storeDigits, storeMCParticles, m_relDigitsMCParticlesName);
176 RelationArray relDigitsTrueHits(storeDigits, storeTrueHits, m_relDigitsTrueHitsName);
177 RelationArray relTrueHitsSimHits(storeTrueHits, storeSimHits, m_relTrueHitsSimHitsName);
178 RelationArray relTrueHitsMCParticles(storeMCParticles, storeTrueHits, m_relParticlesTrueHitsName);
179
180 // unsigned long numberOfEvents = storeFileMetaData->getNEvents();
181 double currentComponentTime = storeBgMetaData->getRealTime();
182 if (currentComponentTime != m_componentTime)
183 B2FATAL("Mismatch in component times:\n"
184 << "Steering file: " << m_componentTime << "\n"
185 << "Background file: " << currentComponentTime);
186
187 VxdID currentSensorID(0);
188 double currentSensorThickness(0);
189 double currentSensorArea(0);
190
191 // Exposition and dose
193 B2DEBUG(100, "Expo and dose");
194 currentSensorID.setID(0);
195 double currentSensorMass(0);
196
197 for (const SVDSimHit& hit : storeSimHits) {
198 // Update if we have a new sensor
199 VxdID sensorID = hit.getSensorID();
200 if (sensorID != currentSensorID) {
201 currentSensorID = sensorID;
202 currentSensorThickness = getSensorThickness(currentSensorID);
203 currentSensorMass = getSensorMass(currentSensorID);
204 currentSensorArea = getSensorArea(currentSensorID);
205 }
206 double hitEnergy = hit.getElectrons() * Const::ehEnergy;
207 // Dose in Gy/smy, normalize by sensor mass
208 m_sensorData[currentSensorID].m_dose +=
209 (hitEnergy / Unit::J) / (currentSensorMass / 1000) * (c_smy / currentComponentTime);
210 // Exposition in GeV/cm2/s
211 m_sensorData[currentSensorID].m_expo += hitEnergy / currentSensorArea / (currentComponentTime / Unit::s);
213 const ROOT::Math::XYZVector localPos = hit.getPosIn();
214 const ROOT::Math::XYZVector globalPos = pointToGlobal(currentSensorID, localPos);
215 float globalPosXYZ[3];
216 globalPos.GetCoordinates(globalPosXYZ);
217 storeEnergyDeposits.appendNew(
218 sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(),
219 hit.getPDGcode(), hit.getGlobalTime(),
220 localPos.X(), localPos.Y(), globalPosXYZ, hitEnergy,
221 (hitEnergy / Unit::J) / (currentSensorMass / 1000) / (currentComponentTime / Unit::s),
222 (hitEnergy / Unit::J) / currentSensorArea / (currentComponentTime / Unit::s)
223 );
224 }
225 }
226 }
227
228 // Neutron flux
230 B2DEBUG(100, "Neutron flux");
231 currentSensorID.setID(0);
232 for (const SVDTrueHit& hit : storeTrueHits) {
233 VxdID sensorID = hit.getSensorID();
234 // Update if we are on a new sensor
235 if (sensorID != currentSensorID) {
236 currentSensorID = sensorID;
237 currentSensorThickness = getSensorThickness(currentSensorID);
238 //currentSensorMass = getSensorMass(currentSensorID);
239 currentSensorArea = getSensorArea(currentSensorID);
240 }
241 // J(TrueHit) = abs(step)/thickness * correctionFactor;
242 ROOT::Math::XYZVector entryPos(hit.getEntryU(), hit.getEntryV(), hit.getEntryW());
243 ROOT::Math::XYZVector exitPos(hit.getExitU(), hit.getExitV(), hit.getExitW());
244 double stepLength = (exitPos - entryPos).R();
245 // Identify what particle we've got. We need type and kinetic energy.
246 // TODO: TrueHit must carry pdg or SimHit must carry energy.
247 // NOTE: MCParticles may get remapped, then SimHits still carry correct pdg.
248 const SVDSimHit* simhit = hit.getRelatedTo<SVDSimHit>();
249 if (!simhit) { //either something is very wrong, or we just don't have the relation. Try to find an appropriate SimHit manually.
250 double minDistance = 1.0e10;
251 for (const SVDSimHit& related : storeSimHits) {
252 double distance = (entryPos - related.getPosIn()).R();
253 if (distance < minDistance) {
254 minDistance = distance;
255 simhit = &related;
256 }
257 }
258 }
259 if (!simhit) {
260 B2WARNING("No related SVDSimHit found");
261 continue; //skip this true hit if the simhit is null
262 }
263 // FIXME: Is there a difference between positrons and electrons wrt. NIEL?
264 // We fill neutronFluxBars with summary NIEL deposit for all kinds of particles by layer and component.
265 // Fluency plots are by component and are deposition histograms for a particular type of particle and compoonent.
266 // Special treatment of corrupt p's in TrueHits:
267 ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
268 hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
269 hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
270 hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
271 int pdg = abs(simhit->getPDGcode());
272 double kineticEnergy(0.0);
273 double nielWeight(0.0);
274 if (pdg == Const::neutron.getPDGCode()) {
275 double m0 = Const::neutronMass;
276 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
277 nielWeight = m_nielNeutrons->getNielFactor(kineticEnergy / Unit::MeV);
278 }
279 if (pdg == Const::proton.getPDGCode()) {
280 double m0 = Const::protonMass;
281 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
282 nielWeight = m_nielProtons->getNielFactor(kineticEnergy / Unit::MeV);
283 }
284 if (pdg == Const::pi0.getPDGCode() || pdg == Const::pion.getPDGCode()) {
285 double m0 = Const::pi0Mass;
286 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
287 nielWeight = m_nielPions->getNielFactor(kineticEnergy / Unit::MeV);
288 }
289 if (pdg == Const::electron.getPDGCode()) {
290 double m0 = Const::electronMass;
291 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
292 nielWeight = m_nielElectrons->getNielFactor(kineticEnergy / Unit::MeV);
293 }
294 if (pdg == Const::photon.getPDGCode()) {
295 double m0 = 0.0;
296 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
297 }
298
299 // Only set weight for supported particles
300 nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
301 m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
302 currentComponentTime * c_smy;
303
304 // Store data in a SVDNeutronFluxEvent object
306 ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
307 const ROOT::Math::XYZVector globalPos = pointToGlobal(currentSensorID, localPos);
308 float globalPosXYZ[3];
309 globalPos.GetCoordinates(globalPosXYZ);
310 ROOT::Math::XYZVector localMom = hit.getMomentum();
311 const ROOT::Math::XYZVector globalMom = vectorToGlobal(currentSensorID, localMom);
312 float globalMomXYZ[3];
313 globalMom.GetCoordinates(globalMomXYZ);
314 storeNeutronFluxes.appendNew(
315 sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(),
316 simhit->getPDGcode(), simhit->getGlobalTime(),
317 hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
318 stepLength, nielWeight,
319 stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s),
320 nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s)
321 );
322 }
323 }
324 }
325
326 // Fired strips
328 B2DEBUG(100, "Fired strips");
329 currentSensorID.setID(0);
330 double currentSensorUCut = 0;
331 double currentSensorVCut = 0;
332 // Store fired strips: count number of digits over threshold
333 std::map<VxdID, std::multiset<unsigned short> > firedStrips;
334 for (const SVDShaperDigit& digit : storeDigits) {
335 // Filter out digits with signals below zero-suppression threshold
336 // ARE THERE SUCH DIGITS?
337 VxdID sensorID = digit.getSensorID();
338 if (sensorID != currentSensorID) {
339 currentSensorID = sensorID;
340 auto info = getInfo(sensorID);
341 currentSensorUCut = eToADU(3.0 * info.getElectronicNoiseU());
342 currentSensorVCut = eToADU(3.0 * info.getElectronicNoiseV());
343 }
344 B2DEBUG(30, "MaxCharge: " << digit.getMaxADCCounts() << " threshold: " << (digit.isUStrip() ? currentSensorUCut :
345 currentSensorVCut));
346 if (digit.getMaxADCCounts() < (digit.isUStrip() ? currentSensorUCut : currentSensorVCut)) continue;
347 B2DEBUG(30, "Passed.");
348 // Economize writing u- and v- strips by re-using the Segment field of VxdID
349 VxdID writeID(sensorID);
350 if (digit.isUStrip())
351 writeID.setSegmentNumber(0);
352 else
353 writeID.setSegmentNumber(1);
354 firedStrips[writeID].insert(digit.getCellID());
355 }
356 // Process the map
357 for (auto idAndSet : firedStrips) {
358 bool isUStrip = (idAndSet.first.getSegmentNumber() == 0);
359 VxdID sensorID = idAndSet.first;
360 sensorID.setSegmentNumber(0);
361 double sensorArea = getSensorArea(sensorID);
362 int nFired_APV = idAndSet.second.size();
363 int nFired = 0; // count unique keys
364 for (auto it = idAndSet.second.begin();
365 it != idAndSet.second.end();
366 it = idAndSet.second.upper_bound(*it)) nFired++;
367 double fired = nFired / (currentComponentTime / Unit::s) / sensorArea;
368 double fired_t = nFired_APV * c_APVCycleTime / (currentComponentTime / Unit::s) / sensorArea;
369 if (isUStrip) {
370 m_sensorData[sensorID].m_firedU += fired;
371 m_sensorData[sensorID].m_firedU_t += fired_t;
372 } else {
373 m_sensorData[sensorID].m_firedV += fired;
374 m_sensorData[sensorID].m_firedV_t += fired_t;
375 }
376 }
377
378 // Occupancy
379 //
380 // We assume a S/N dependent acceptance window of size
381 // W = 2 * acceptanceWidth * RMS(hit_time - trigger_time)
382 // that is used to keep most of signal hits.
383 // occupancy for a cluster with S/N = sn and size sz on sensor id =
384 // cluster_rate(sn,sz,id) * W * sz / #strips(id)
385 // Cluster rate is number of clusters / sample time, and as we expect
386 // clusters to be justly represented in the sample as to S/N, size, and
387 // sensor they appear on, we calculate occupancy on sensor id as
388 //
389 // occupancy(id) = Sum_over_clusters_in_id (
390 // W(sn) / t_simulation * sz / #strips(id)
391 // )
392 //
393 B2DEBUG(100, "Occupancy");
394 currentSensorID.setID(0);
395 double currentNoiseU = 0;
396 double currentNoiseV = 0;
397 int nStripsU = 0;
398 int nStripsV = 0;
399 for (auto cluster : storeClsuters) {
400 VxdID sensorID = cluster.getSensorID();
401 if (currentSensorID != sensorID) {
402 currentSensorID = sensorID;
403 auto info = getInfo(sensorID);
404 currentNoiseU = eToADU(info.getElectronicNoiseU());
405 currentNoiseV = eToADU(info.getElectronicNoiseV());
406 nStripsU = info.getUCells();
407 nStripsV = info.getVCells();
408 }
409 bool isU = cluster.isUCluster();
410 double snr = (isU) ? cluster.getCharge() / currentNoiseU : cluster.getCharge() / currentNoiseV;
411 int nStrips = (isU) ? nStripsU : nStripsV;
412 double tau_error = 45 / snr * Unit::ns;
413 tau_error = sqrt(m_triggerWidth * m_triggerWidth + tau_error * tau_error);
414 double tau_acceptance = 2 * m_acceptanceWidth * tau_error;
415 double w_acceptance = tau_acceptance / currentComponentTime;
416 double w_acceptance_APV = c_APVCycleTime / currentComponentTime;
417 double occupancy = 1.0 / nStrips * cluster.getSize();
418 if (isU) {
419 m_sensorData[sensorID].m_occupancyU += w_acceptance * occupancy;
420 m_sensorData[sensorID].m_occupancyU_APV += w_acceptance_APV * occupancy;
421 } else {
422 m_sensorData[sensorID].m_occupancyV += w_acceptance * occupancy;
423 m_sensorData[sensorID].m_occupancyV_APV += w_acceptance_APV * occupancy;
424 }
426 storeOccupancyEvents.appendNew(
427 sensorID.getLayerNumber(), sensorID.getLadderNumber(),
428 sensorID.getSensorNumber(), cluster.getClsTime(),
429 cluster.isUCluster(), cluster.getPosition(), cluster.getSize(),
430 cluster.getCharge(), snr, w_acceptance, w_acceptance * occupancy,
431 w_acceptance_APV * occupancy
432 );
433 }
434 }
435 }
436}
437
439{
440}
441
442
444{
445 // Write out m_data
446 ofstream outfile;
447 string outfileName(m_outputDirectoryName + m_componentName + "_summary.txt");
448 outfile.open(outfileName.c_str(), ios::out | ios::trunc);
449 outfile << "component_name\t"
450 << "component_time\t"
451 << "layer\t"
452 << "ladder\t"
453 << "sensor\t"
454 << "dose\t"
455 << "expo\t"
456 << "neutronFlux\t"
457 << "fired_u\t"
458 << "fired_v\t"
459 << "fired_u_t\t"
460 << "fired_v_t\t"
461 << "occupancy_u\t"
462 << "occupancy_v\t"
463 << "occupancy_u_APV\t"
464 << "occupancy_v_APV"
465 << endl;
466 double componentTime = m_componentTime / Unit::us;
467 for (auto vxdSensor : m_sensorData) {
468 outfile << m_componentName.c_str() << "\t"
469 << componentTime << "\t"
470 << vxdSensor.first.getLayerNumber() << "\t"
471 << vxdSensor.first.getLadderNumber() << "\t"
472 << vxdSensor.first.getSensorNumber() << "\t"
473 << vxdSensor.second.m_dose << "\t"
474 << vxdSensor.second.m_expo << "\t"
475 << vxdSensor.second.m_neutronFlux << "\t"
476 << vxdSensor.second.m_firedU << "\t"
477 << vxdSensor.second.m_firedV << "\t"
478 << vxdSensor.second.m_firedU_t << "\t"
479 << vxdSensor.second.m_firedV_t << "\t"
480 << vxdSensor.second.m_occupancyU << "\t"
481 << vxdSensor.second.m_occupancyV << "\t"
482 << vxdSensor.second.m_occupancyU_APV << "\t"
483 << vxdSensor.second.m_occupancyV_APV
484 << endl;
485 }
486 outfile << endl;
487}
double R
typedef autogenerated by FFTW
static const ParticleType neutron
neutron particle
Definition: Const.h:675
static const ParticleType pi0
neutral pion particle
Definition: Const.h:674
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
static const double electronMass
electron mass
Definition: Const.h:685
static const double neutronMass
neutron mass
Definition: Const.h:692
static const ChargedStable proton
proton particle
Definition: Const.h:663
static const double ehEnergy
Energy needed to create an electron-hole pair in Si at std.
Definition: Const.h:697
static const double protonMass
proton mass
Definition: Const.h:689
static const ParticleType photon
photon particle
Definition: Const.h:673
static const double pi0Mass
neutral pion mass
Definition: Const.h:691
static const ChargedStable electron
electron particle
Definition: Const.h:659
@ c_Persistent
Object is available during entire execution time.
Definition: DataStore.h:60
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
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:62
The SVD ShaperDigit class.
Class SVDSimHit - Geant4 simulated hit for the SVD.
Definition: SVDSimHit.h:26
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: SVDTrueHit.h:33
static const unsigned short c_reportNTuple
Summary and NTuple.
std::string m_storeFileMetaDataName
Name of the persistent FileMetaData object.
double m_triggerWidth
RMS of trigger time measurement.
unsigned short m_nfluxReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
const ROOT::Math::XYZVector & vectorToGlobal(VxdID sensorID, const ROOT::Math::XYZVector &local)
Convert local vector coordinates to global.
const ROOT::Math::XYZVector & pointToGlobal(VxdID sensorID, const ROOT::Math::XYZVector &local)
Convert local sensor coordinates to global.
std::string m_storeEnergyDepositsName
SVDEnergyDepositEvents StoreArray name.
const double c_smy
Seconds in snowmass year.
const SVD::SensorInfo & getInfo(VxdID sensorID) const
This is a shortcut to getting SVD::SensorInfo from the GeoCache.
unsigned short m_doseReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
std::string m_storeOccupancyEventsName
SVDOccupancyEvents StoreArray name.
std::map< VxdID, SensorData > m_sensorData
Struct to hold sensor-wise background data.
virtual void initialize() override
Initialize module.
std::string m_relTrueHitsSimHitsName
SVDTrueHitsToSVDSimHits RelationArray name.
std::string m_relDigitsMCParticlesName
StoreArray name of SVDDigits to MCParticles relation.
double m_acceptanceWidth
A hit is accepted if arrived within +/- m_acceptanceWidth * RMS(hit time - trigger time).
virtual void event() override
Event processing.
double getSensorMass(VxdID sensorID) const
Return mass of the sensor with the given sensor ID.
static const unsigned short c_reportNone
No reporting.
virtual void endRun() override
End-of-run tasks.
std::string m_storeNeutronFluxesName
SVDNeutronFluxEvents StoreArray name.
std::string m_storeTrueHitsName
SVDTrueHits StoreArray name.
virtual void terminate() override
Final summary and cleanup.
std::unique_ptr< TNiel > m_nielNeutrons
Pointer to Niel table for neutrons.
std::string m_storeMCParticlesName
MCParticles StoreArray name.
std::unique_ptr< TNiel > m_nielProtons
Pointer to Niel table for protons.
double getSensorThickness(VxdID sensorID) const
Return thickness of the sensor with the given sensor ID.
std::unique_ptr< TNiel > m_nielPions
Pointer to Niel table for pions.
virtual void beginRun() override
Start-of-run initializations.
std::string m_storeBgMetaDataName
Name of the persistent BackgroundMetaDta object.
double getSensorArea(VxdID sensorID) const
Return area of the sensor with the given sensor ID.
std::string m_outputDirectoryName
Path to directory where output data will be stored.
std::string m_storeDigitsName
SVDDigits StoreArray name.
std::string m_storeClustersName
SVDClusters StoreArray name.
std::unique_ptr< TNiel > m_nielElectrons
Pointer to Niel table for electrons.
const double c_APVCycleTime
APV cycle time.
std::string m_relParticlesTrueHitsName
MCParticlesToSVDTrueHits RelationArray name.
std::string m_componentName
Name of the current component.
double m_componentTime
Time of current component.
unsigned short m_occupancyReportingLevel
0 - no data, 1 - summary only, 2 - ntuple
std::string m_storeSimHitsName
SVDSimHits StoreArray name.
std::string m_relDigitsTrueHitsName
StoreArray name of SVDDigits to SVDTrueHits relation.
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
Definition: SensorInfo.h:25
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
static const double us
[microsecond]
Definition: Unit.h:97
static const double J
[joule]
Definition: Unit.h:116
static const double MeV
[megaelectronvolt]
Definition: Unit.h:114
static const double ns
Standard of [time].
Definition: Unit.h:48
static const double s
[second]
Definition: Unit.h:95
float getGlobalTime() const override
Return the time of the electron deposition.
Definition: VXDSimHit.h:78
int getPDGcode() const
Return the PDG code of the particle causing the electron deposition.
Definition: VXDSimHit.h:68
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
void setSegmentNumber(baseType segment)
Set the sensor segment.
Definition: VxdID.h:113
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
void setID(baseType id)
Set the unique id.
Definition: VxdID.h:105
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
TNiel - the class providing values for NIEL factors.
Definition: niel_fun.h:17
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Definition: GeoSVDCreator.h:23
Abstract base class for different kinds of events.
STL namespace.