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 // FIXME: Is there a difference between positrons and electrons wrt. NIEL?
260 // We fill neutronFluxBars with summary NIEL deposit for all kinds of particles by layer and component.
261 // Fluency plots are by component and are deposition histograms for a particular type of particle and compoonent.
262 // Special treatment of corrupt p's in TrueHits:
263 ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
264 hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
265 hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
266 hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
267 int pdg = abs(simhit->getPDGcode());
268 double kineticEnergy(0.0);
269 double nielWeight(0.0);
270 if (pdg == Const::neutron.getPDGCode()) {
271 double m0 = Const::neutronMass;
272 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
273 nielWeight = m_nielNeutrons->getNielFactor(kineticEnergy / Unit::MeV);
274 }
275 if (pdg == Const::proton.getPDGCode()) {
276 double m0 = Const::protonMass;
277 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
278 nielWeight = m_nielProtons->getNielFactor(kineticEnergy / Unit::MeV);
279 }
280 if (pdg == Const::pi0.getPDGCode() || pdg == Const::pion.getPDGCode()) {
281 double m0 = Const::pi0Mass;
282 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
283 nielWeight = m_nielPions->getNielFactor(kineticEnergy / Unit::MeV);
284 }
285 if (pdg == Const::electron.getPDGCode()) {
286 double m0 = Const::electronMass;
287 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
288 nielWeight = m_nielElectrons->getNielFactor(kineticEnergy / Unit::MeV);
289 }
290 if (pdg == Const::photon.getPDGCode()) {
291 double m0 = 0.0;
292 kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
293 }
294
295 // Only set weight for supported particles
296 nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
297 m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
298 currentComponentTime * c_smy;
299
300 // Store data in a SVDNeutronFluxEvent object
302 ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
303 const ROOT::Math::XYZVector globalPos = pointToGlobal(currentSensorID, localPos);
304 float globalPosXYZ[3];
305 globalPos.GetCoordinates(globalPosXYZ);
306 ROOT::Math::XYZVector localMom = hit.getMomentum();
307 const ROOT::Math::XYZVector globalMom = vectorToGlobal(currentSensorID, localMom);
308 float globalMomXYZ[3];
309 globalMom.GetCoordinates(globalMomXYZ);
310 storeNeutronFluxes.appendNew(
311 sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(),
312 simhit->getPDGcode(), simhit->getGlobalTime(),
313 hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
314 stepLength, nielWeight,
315 stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s),
316 nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s)
317 );
318 }
319 }
320 }
321
322 // Fired strips
324 B2DEBUG(100, "Fired strips");
325 currentSensorID.setID(0);
326 double currentSensorUCut = 0;
327 double currentSensorVCut = 0;
328 // Store fired strips: count number of digits over threshold
329 std::map<VxdID, std::multiset<unsigned short> > firedStrips;
330 for (const SVDShaperDigit& digit : storeDigits) {
331 // Filter out digits with signals below zero-suppression threshold
332 // ARE THRE SUCH DIGITS?
333 VxdID sensorID = digit.getSensorID();
334 if (sensorID != currentSensorID) {
335 currentSensorID = sensorID;
336 auto info = getInfo(sensorID);
337 currentSensorUCut = eToADU(3.0 * info.getElectronicNoiseU());
338 currentSensorVCut = eToADU(3.0 * info.getElectronicNoiseV());
339 }
340 B2DEBUG(30, "MaxCharge: " << digit.getMaxADCCounts() << " threshold: " << (digit.isUStrip() ? currentSensorUCut :
341 currentSensorVCut));
342 if (digit.getMaxADCCounts() < (digit.isUStrip() ? currentSensorUCut : currentSensorVCut)) continue;
343 B2DEBUG(30, "Passed.");
344 // Economize writing u- and v- strips by re-using the Segment field of VxdID
345 VxdID writeID(sensorID);
346 if (digit.isUStrip())
347 writeID.setSegmentNumber(0);
348 else
349 writeID.setSegmentNumber(1);
350 firedStrips[writeID].insert(digit.getCellID());
351 }
352 // Process the map
353 for (auto idAndSet : firedStrips) {
354 bool isUStrip = (idAndSet.first.getSegmentNumber() == 0);
355 VxdID sensorID = idAndSet.first;
356 sensorID.setSegmentNumber(0);
357 double sensorArea = getSensorArea(sensorID);
358 int nFired_APV = idAndSet.second.size();
359 int nFired = 0; // count unique keys
360 for (auto it = idAndSet.second.begin();
361 it != idAndSet.second.end();
362 it = idAndSet.second.upper_bound(*it)) nFired++;
363 double fired = nFired / (currentComponentTime / Unit::s) / sensorArea;
364 double fired_t = nFired_APV * c_APVCycleTime / (currentComponentTime / Unit::s) / sensorArea;
365 if (isUStrip) {
366 m_sensorData[sensorID].m_firedU += fired;
367 m_sensorData[sensorID].m_firedU_t += fired_t;
368 } else {
369 m_sensorData[sensorID].m_firedV += fired;
370 m_sensorData[sensorID].m_firedV_t += fired_t;
371 }
372 }
373
374 // Occupancy
375 //
376 // We assume a S/N dependent acceptance window of size
377 // W = 2 * acceptanceWidth * RMS(hit_time - trigger_time)
378 // that is used to keep most of signal hits.
379 // occupancy for a cluster with S/N = sn and size sz on sensor id =
380 // cluster_rate(sn,sz,id) * W * sz / #strips(id)
381 // Cluster rate is number of clusters / sample time, and as we expect
382 // clusters to be justly represented in the sample as to S/N, size, and
383 // sensor they appear on, we calculate occupancy on sensor id as
384 //
385 // occupancy(id) = Sum_over_clusters_in_id (
386 // W(sn) / t_simulation * sz / #strips(id)
387 // )
388 //
389 B2DEBUG(100, "Occupancy");
390 currentSensorID.setID(0);
391 double currentNoiseU = 0;
392 double currentNoiseV = 0;
393 int nStripsU = 0;
394 int nStripsV = 0;
395 for (auto cluster : storeClsuters) {
396 VxdID sensorID = cluster.getSensorID();
397 if (currentSensorID != sensorID) {
398 currentSensorID = sensorID;
399 auto info = getInfo(sensorID);
400 currentNoiseU = eToADU(info.getElectronicNoiseU());
401 currentNoiseV = eToADU(info.getElectronicNoiseV());
402 nStripsU = info.getUCells();
403 nStripsV = info.getVCells();
404 }
405 bool isU = cluster.isUCluster();
406 double snr = (isU) ? cluster.getCharge() / currentNoiseU : cluster.getCharge() / currentNoiseV;
407 int nStrips = (isU) ? nStripsU : nStripsV;
408 double tau_error = 45 / snr * Unit::ns;
409 tau_error = sqrt(m_triggerWidth * m_triggerWidth + tau_error * tau_error);
410 double tau_acceptance = 2 * m_acceptanceWidth * tau_error;
411 double w_acceptance = tau_acceptance / currentComponentTime;
412 double w_acceptance_APV = c_APVCycleTime / currentComponentTime;
413 double occupancy = 1.0 / nStrips * cluster.getSize();
414 if (isU) {
415 m_sensorData[sensorID].m_occupancyU += w_acceptance * occupancy;
416 m_sensorData[sensorID].m_occupancyU_APV += w_acceptance_APV * occupancy;
417 } else {
418 m_sensorData[sensorID].m_occupancyV += w_acceptance * occupancy;
419 m_sensorData[sensorID].m_occupancyV_APV += w_acceptance_APV * occupancy;
420 }
422 storeOccupancyEvents.appendNew(
423 sensorID.getLayerNumber(), sensorID.getLadderNumber(),
424 sensorID.getSensorNumber(), cluster.getClsTime(),
425 cluster.isUCluster(), cluster.getPosition(), cluster.getSize(),
426 cluster.getCharge(), snr, w_acceptance, w_acceptance * occupancy,
427 w_acceptance_APV * occupancy
428 );
429 }
430 }
431 }
432}
433
435{
436}
437
438
440{
441 // Write out m_data
442 ofstream outfile;
443 string outfileName(m_outputDirectoryName + m_componentName + "_summary.txt");
444 outfile.open(outfileName.c_str(), ios::out | ios::trunc);
445 outfile << "component_name\t"
446 << "component_time\t"
447 << "layer\t"
448 << "ladder\t"
449 << "sensor\t"
450 << "dose\t"
451 << "expo\t"
452 << "neutronFlux\t"
453 << "fired_u\t"
454 << "fired_v\t"
455 << "fired_u_t\t"
456 << "fired_v_t\t"
457 << "occupancy_u\t"
458 << "occupancy_v\t"
459 << "occupancy_u_APV\t"
460 << "occupancy_v_APV"
461 << endl;
462 double componentTime = m_componentTime / Unit::us;
463 for (auto vxdSensor : m_sensorData) {
464 outfile << m_componentName.c_str() << "\t"
465 << componentTime << "\t"
466 << vxdSensor.first.getLayerNumber() << "\t"
467 << vxdSensor.first.getLadderNumber() << "\t"
468 << vxdSensor.first.getSensorNumber() << "\t"
469 << vxdSensor.second.m_dose << "\t"
470 << vxdSensor.second.m_expo << "\t"
471 << vxdSensor.second.m_neutronFlux << "\t"
472 << vxdSensor.second.m_firedU << "\t"
473 << vxdSensor.second.m_firedV << "\t"
474 << vxdSensor.second.m_firedU_t << "\t"
475 << vxdSensor.second.m_firedV_t << "\t"
476 << vxdSensor.second.m_occupancyU << "\t"
477 << vxdSensor.second.m_occupancyV << "\t"
478 << vxdSensor.second.m_occupancyU_APV << "\t"
479 << vxdSensor.second.m_occupancyV_APV
480 << endl;
481 }
482 outfile << endl;
483}
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:96
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
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.