Belle II Software  release-08-01-10
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 
34 using namespace std;
35 using boost::format;
36 using namespace Belle2;
37 using namespace Belle2::SVD;
38 
39 //-----------------------------------------------------------------
40 // A small helper function to convert between electons and ADU
41 // ----------------------------------------------------------------
42 double 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 //-----------------------------------------------------------------
53 REG_MODULE(SVDBackground);
54 
55 
56 //-----------------------------------------------------------------
57 // Implementation
58 //-----------------------------------------------------------------
59 
60 SVDBackgroundModule::SVDBackgroundModule() :
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 
89 const 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 
98 const 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 currentSensorMass(0);
190  double currentSensorArea(0);
191 
192  // Exposition and dose
194  B2DEBUG(100, "Expo and dose");
195  currentSensorID.setID(0);
196  for (const SVDSimHit& hit : storeSimHits) {
197  // Update if we have a new sensor
198  VxdID sensorID = hit.getSensorID();
199  if (sensorID != currentSensorID) {
200  currentSensorID = sensorID;
201  currentSensorThickness = getSensorThickness(currentSensorID);
202  currentSensorMass = getSensorMass(currentSensorID);
203  currentSensorArea = getSensorArea(currentSensorID);
204  }
205  double hitEnergy = hit.getElectrons() * Const::ehEnergy;
206  // Dose in Gy/smy, normalize by sensor mass
207  m_sensorData[currentSensorID].m_dose +=
208  (hitEnergy / Unit::J) / (currentSensorMass / 1000) * (c_smy / currentComponentTime);
209  // Exposition in GeV/cm2/s
210  m_sensorData[currentSensorID].m_expo += hitEnergy / currentSensorArea / (currentComponentTime / Unit::s);
212  const ROOT::Math::XYZVector localPos = hit.getPosIn();
213  const ROOT::Math::XYZVector globalPos = pointToGlobal(currentSensorID, localPos);
214  float globalPosXYZ[3];
215  globalPos.GetCoordinates(globalPosXYZ);
216  storeEnergyDeposits.appendNew(
217  sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(),
218  hit.getPDGcode(), hit.getGlobalTime(),
219  localPos.X(), localPos.Y(), globalPosXYZ, hitEnergy,
220  (hitEnergy / Unit::J) / (currentSensorMass / 1000) / (currentComponentTime / Unit::s),
221  (hitEnergy / Unit::J) / currentSensorArea / (currentComponentTime / Unit::s)
222  );
223  }
224  }
225  }
226 
227  // Neutron flux
229  B2DEBUG(100, "Neutron flux");
230  currentSensorID.setID(0);
231  for (const SVDTrueHit& hit : storeTrueHits) {
232  VxdID sensorID = hit.getSensorID();
233  // Update if we are on a new sensor
234  if (sensorID != currentSensorID) {
235  currentSensorID = sensorID;
236  currentSensorThickness = getSensorThickness(currentSensorID);
237  currentSensorMass = getSensorMass(currentSensorID);
238  currentSensorArea = getSensorArea(currentSensorID);
239  }
240  // J(TrueHit) = abs(step)/thickness * correctionFactor;
241  ROOT::Math::XYZVector entryPos(hit.getEntryU(), hit.getEntryV(), hit.getEntryW());
242  ROOT::Math::XYZVector exitPos(hit.getExitU(), hit.getExitV(), hit.getExitW());
243  double stepLength = (exitPos - entryPos).R();
244  // Identify what particle we've got. We need type and kinetic energy.
245  // TODO: TrueHit must carry pdg or SimHit must carry energy.
246  // NOTE: MCParticles may get remapped, then SimHits still carry correct pdg.
247  const SVDSimHit* simhit = hit.getRelatedTo<SVDSimHit>();
248  if (!simhit) { //either something is very wrong, or we just don't have the relation. Try to find an appropriate SimHit manually.
249  double minDistance = 1.0e10;
250  for (const SVDSimHit& related : storeSimHits) {
251  double distance = (entryPos - related.getPosIn()).R();
252  if (distance < minDistance) {
253  minDistance = distance;
254  simhit = &related;
255  }
256  }
257  }
258  // FIXME: Is there a difference between positrons and electrons wrt. NIEL?
259  // We fill neutronFluxBars with summary NIEL deposit for all kinds of particles by layer and component.
260  // Fluency plots are by component and are deposition histograms for a particular type of particle and compoonent.
261  // Special treatment of corrupt p's in TrueHits:
262  ROOT::Math::XYZVector hitMomentum(hit.getMomentum());
263  hitMomentum.SetX(std::isfinite(hitMomentum.X()) ? hitMomentum.X() : 0.0);
264  hitMomentum.SetY(std::isfinite(hitMomentum.Y()) ? hitMomentum.Y() : 0.0);
265  hitMomentum.SetZ(std::isfinite(hitMomentum.Z()) ? hitMomentum.Z() : 0.0);
266  int pdg = abs(simhit->getPDGcode());
267  double kineticEnergy(0.0);
268  double nielWeight(0.0);
269  if (pdg == Const::neutron.getPDGCode()) {
270  double m0 = Const::neutronMass;
271  kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
272  nielWeight = m_nielNeutrons->getNielFactor(kineticEnergy / Unit::MeV);
273  }
274  if (pdg == Const::proton.getPDGCode()) {
275  double m0 = Const::protonMass;
276  kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
277  nielWeight = m_nielProtons->getNielFactor(kineticEnergy / Unit::MeV);
278  }
279  if (pdg == Const::pi0.getPDGCode() || pdg == Const::pion.getPDGCode()) {
280  double m0 = Const::pi0Mass;
281  kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
282  nielWeight = m_nielPions->getNielFactor(kineticEnergy / Unit::MeV);
283  }
284  if (pdg == Const::electron.getPDGCode()) {
285  double m0 = Const::electronMass;
286  kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
287  nielWeight = m_nielElectrons->getNielFactor(kineticEnergy / Unit::MeV);
288  }
289  if (pdg == Const::photon.getPDGCode()) {
290  double m0 = 0.0;
291  kineticEnergy = sqrt(hitMomentum.Mag2() + m0 * m0) - m0;
292  }
293 
294  // Only set weight for supported particles
295  nielWeight = std::isfinite(nielWeight) ? nielWeight : 0.0;
296  m_sensorData[currentSensorID].m_neutronFlux += nielWeight * stepLength / currentSensorThickness / currentSensorArea /
297  currentComponentTime * c_smy;
298 
299  // Store data in a SVDNeutronFluxEvent object
301  ROOT::Math::XYZVector localPos(hit.getU(), hit.getV(), hit.getW());
302  const ROOT::Math::XYZVector globalPos = pointToGlobal(currentSensorID, localPos);
303  float globalPosXYZ[3];
304  globalPos.GetCoordinates(globalPosXYZ);
305  ROOT::Math::XYZVector localMom = hit.getMomentum();
306  const ROOT::Math::XYZVector globalMom = vectorToGlobal(currentSensorID, localMom);
307  float globalMomXYZ[3];
308  globalMom.GetCoordinates(globalMomXYZ);
309  storeNeutronFluxes.appendNew(
310  sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(),
311  simhit->getPDGcode(), simhit->getGlobalTime(),
312  hit.getU(), hit.getV(), globalPosXYZ, globalMomXYZ, kineticEnergy,
313  stepLength, nielWeight,
314  stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s),
315  nielWeight * stepLength / currentSensorThickness / currentSensorArea / (currentComponentTime / Unit::s)
316  );
317  }
318  }
319  }
320 
321  // Fired strips
323  B2DEBUG(100, "Fired strips");
324  currentSensorID.setID(0);
325  double currentSensorUCut = 0;
326  double currentSensorVCut = 0;
327  // Store fired strips: count number of digits over threshold
328  std::map<VxdID, std::multiset<unsigned short> > firedStrips;
329  for (const SVDShaperDigit& digit : storeDigits) {
330  // Filter out digits with signals below zero-suppression threshold
331  // ARE THRE SUCH DIGITS?
332  VxdID sensorID = digit.getSensorID();
333  if (sensorID != currentSensorID) {
334  currentSensorID = sensorID;
335  auto info = getInfo(sensorID);
336  currentSensorUCut = eToADU(3.0 * info.getElectronicNoiseU());
337  currentSensorVCut = eToADU(3.0 * info.getElectronicNoiseV());
338  }
339  B2DEBUG(30, "MaxCharge: " << digit.getMaxADCCounts() << " threshold: " << (digit.isUStrip() ? currentSensorUCut :
340  currentSensorVCut));
341  if (digit.getMaxADCCounts() < (digit.isUStrip() ? currentSensorUCut : currentSensorVCut)) continue;
342  B2DEBUG(30, "Passed.");
343  // Economize writing u- and v- strips by re-using the Segment field of VxdID
344  VxdID writeID(sensorID);
345  if (digit.isUStrip())
346  writeID.setSegmentNumber(0);
347  else
348  writeID.setSegmentNumber(1);
349  firedStrips[writeID].insert(digit.getCellID());
350  }
351  // Process the map
352  for (auto idAndSet : firedStrips) {
353  bool isUStrip = (idAndSet.first.getSegmentNumber() == 0);
354  VxdID sensorID = idAndSet.first;
355  sensorID.setSegmentNumber(0);
356  double sensorArea = getSensorArea(sensorID);
357  int nFired_APV = idAndSet.second.size();
358  int nFired = 0; // count unique keys
359  for (auto it = idAndSet.second.begin();
360  it != idAndSet.second.end();
361  it = idAndSet.second.upper_bound(*it)) nFired++;
362  double fired = nFired / (currentComponentTime / Unit::s) / sensorArea;
363  double fired_t = nFired_APV * c_APVCycleTime / (currentComponentTime / Unit::s) / sensorArea;
364  if (isUStrip) {
365  m_sensorData[sensorID].m_firedU += fired;
366  m_sensorData[sensorID].m_firedU_t += fired_t;
367  } else {
368  m_sensorData[sensorID].m_firedV += fired;
369  m_sensorData[sensorID].m_firedV_t += fired_t;
370  }
371  }
372 
373  // Occupancy
374  //
375  // We assume a S/N dependent acceptance window of size
376  // W = 2 * acceptanceWidth * RMS(hit_time - trigger_time)
377  // that is used to keep most of signal hits.
378  // occupancy for a cluster with S/N = sn and size sz on sensor id =
379  // cluster_rate(sn,sz,id) * W * sz / #strips(id)
380  // Cluster rate is number of clusters / sample time, and as we expect
381  // clusters to be justly represented in the sample as to S/N, size, and
382  // sensor they appear on, we calculate occupancy on sensor id as
383  //
384  // occupancy(id) = Sum_over_clusters_in_id (
385  // W(sn) / t_simulation * sz / #strips(id)
386  // )
387  //
388  B2DEBUG(100, "Occupancy");
389  currentSensorID.setID(0);
390  double currentNoiseU = 0;
391  double currentNoiseV = 0;
392  int nStripsU = 0;
393  int nStripsV = 0;
394  for (auto cluster : storeClsuters) {
395  VxdID sensorID = cluster.getSensorID();
396  if (currentSensorID != sensorID) {
397  currentSensorID = sensorID;
398  auto info = getInfo(sensorID);
399  currentNoiseU = eToADU(info.getElectronicNoiseU());
400  currentNoiseV = eToADU(info.getElectronicNoiseV());
401  nStripsU = info.getUCells();
402  nStripsV = info.getVCells();
403  }
404  bool isU = cluster.isUCluster();
405  double snr = (isU) ? cluster.getCharge() / currentNoiseU : cluster.getCharge() / currentNoiseV;
406  int nStrips = (isU) ? nStripsU : nStripsV;
407  double tau_error = 45 / snr * Unit::ns;
408  tau_error = sqrt(m_triggerWidth * m_triggerWidth + tau_error * tau_error);
409  double tau_acceptance = 2 * m_acceptanceWidth * tau_error;
410  double w_acceptance = tau_acceptance / currentComponentTime;
411  double w_acceptance_APV = c_APVCycleTime / currentComponentTime;
412  double occupancy = 1.0 / nStrips * cluster.getSize();
413  if (isU) {
414  m_sensorData[sensorID].m_occupancyU += w_acceptance * occupancy;
415  m_sensorData[sensorID].m_occupancyU_APV += w_acceptance_APV * occupancy;
416  } else {
417  m_sensorData[sensorID].m_occupancyV += w_acceptance * occupancy;
418  m_sensorData[sensorID].m_occupancyV_APV += w_acceptance_APV * occupancy;
419  }
421  storeOccupancyEvents.appendNew(
422  sensorID.getLayerNumber(), sensorID.getLadderNumber(),
423  sensorID.getSensorNumber(), cluster.getClsTime(),
424  cluster.isUCluster(), cluster.getPosition(), cluster.getSize(),
425  cluster.getCharge(), snr, w_acceptance, w_acceptance * occupancy,
426  w_acceptance_APV * occupancy
427  );
428  }
429  }
430  }
431 }
432 
434 {
435 }
436 
437 
439 {
440  // Write out m_data
441  ofstream outfile;
442  string outfileName(m_outputDirectoryName + m_componentName + "_summary.txt");
443  outfile.open(outfileName.c_str(), ios::out | ios::trunc);
444  outfile << "component_name\t"
445  << "component_time\t"
446  << "layer\t"
447  << "ladder\t"
448  << "sensor\t"
449  << "dose\t"
450  << "expo\t"
451  << "neutronFlux\t"
452  << "fired_u\t"
453  << "fired_v\t"
454  << "fired_u_t\t"
455  << "fired_v_t\t"
456  << "occupancy_u\t"
457  << "occupancy_v\t"
458  << "occupancy_u_APV\t"
459  << "occupancy_v_APV"
460  << endl;
461  double componentTime = m_componentTime / Unit::us;
462  for (auto vxdSensor : m_sensorData) {
463  outfile << m_componentName.c_str() << "\t"
464  << componentTime << "\t"
465  << vxdSensor.first.getLayerNumber() << "\t"
466  << vxdSensor.first.getLadderNumber() << "\t"
467  << vxdSensor.first.getSensorNumber() << "\t"
468  << vxdSensor.second.m_dose << "\t"
469  << vxdSensor.second.m_expo << "\t"
470  << vxdSensor.second.m_neutronFlux << "\t"
471  << vxdSensor.second.m_firedU << "\t"
472  << vxdSensor.second.m_firedV << "\t"
473  << vxdSensor.second.m_firedU_t << "\t"
474  << vxdSensor.second.m_firedV_t << "\t"
475  << vxdSensor.second.m_occupancyU << "\t"
476  << vxdSensor.second.m_occupancyV << "\t"
477  << vxdSensor.second.m_occupancyU_APV << "\t"
478  << vxdSensor.second.m_occupancyV_APV
479  << endl;
480  }
481  outfile << endl;
482 }
double R
typedef autogenerated by FFTW
static const ParticleType neutron
neutron particle
Definition: Const.h:666
static const ParticleType pi0
neutral pion particle
Definition: Const.h:665
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
static const double electronMass
electron mass
Definition: Const.h:676
static const double neutronMass
neutron mass
Definition: Const.h:683
static const ChargedStable proton
proton particle
Definition: Const.h:654
static const double ehEnergy
Energy needed to create an electron-hole pair in Si at std.
Definition: Const.h:688
static const double protonMass
proton mass
Definition: Const.h:680
static const ParticleType photon
photon particle
Definition: Const.h:664
static const double pi0Mass
neutral pion mass
Definition: Const.h:682
static const ChargedStable electron
electron particle
Definition: Const.h:650
@ 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.
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.