Belle II Software  release-05-02-19
SVDDigitizerModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2011 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Zbynek Drasal, Martin Ritter, Peter Kvasnicka *
7  * *
8  **************************************************************************/
9 
10 #include <svd/modules/svdSimulation/SVDDigitizerModule.h>
11 #include <vxd/geometry/GeoCache.h>
12 
13 #include <framework/dataobjects/EventMetaData.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/gearbox/Unit.h>
16 #include <framework/gearbox/Const.h>
17 #include <framework/datastore/DataStore.h>
18 #include <framework/datastore/StoreArray.h>
19 #include <framework/datastore/StoreObjPtr.h>
20 #include <framework/datastore/RelationArray.h>
21 #include <framework/datastore/RelationIndex.h>
22 #include <mdst/dataobjects/MCParticle.h>
23 #include <svd/dataobjects/SVDTrueHit.h>
24 #include <svd/dataobjects/SVDShaperDigit.h>
25 #include <svd/dataobjects/SVDModeByte.h>
26 #include <svd/dataobjects/SVDEventInfo.h>
27 #include <fstream>
28 #include <sstream>
29 #include <regex>
30 #include <algorithm>
31 #include <deque>
32 #include <cmath>
33 #include <root/TMath.h>
34 #include <root/TRandom.h>
35 
36 using namespace std;
37 using namespace Belle2;
38 using namespace Belle2::SVD;
39 
40 //-----------------------------------------------------------------
41 // Auxiliaries for waveform storage
42 //-----------------------------------------------------------------
43 // FIXME: I believe this is wrong, these things must be created separately for
44 // each instance of the digitizer, otherwise it can crash in parallel mode.
45 int tree_vxdID = 0; // VXD ID of a sensor
46 int tree_uv = 0; // U or V coordinate
47 int tree_strip = 0; // number of strip
48 double tree_signal[20]; // array for 20 samples of 10 ns
49 
50 //-----------------------------------------------------------------
51 // Register the Module
52 //-----------------------------------------------------------------
53 REG_MODULE(SVDDigitizer)
54 
55 //-----------------------------------------------------------------
56 // Implementation
57 //-----------------------------------------------------------------
58 
59 std::string Belle2::SVD::SVDDigitizerModule::m_xmlFileName = std::string("SVDChannelMapping.xml");
60 SVDDigitizerModule::SVDDigitizerModule() : Module(),
61  m_mapping(m_xmlFileName)
62 {
63  //Set module properties
64  setDescription("Create SVDShaperDigits from SVDSimHits");
66 
67  // Define module parameters
68 
69  // 1. Collections
70  addParam("MCParticles", m_storeMCParticlesName,
71  "MCParticle collection name", m_storeMCParticlesName);
72  addParam("SimHits", m_storeSimHitsName, "SimHit collection name",
74  addParam("TrueHits", m_storeTrueHitsName, "TrueHit collection name",
76  addParam("ShaperDigits", m_storeShaperDigitsName, "ShaperDigits collection name", m_storeShaperDigitsName);
77  addParam("SVDEventInfo", m_svdEventInfoName, "SVDEventInfo name", m_svdEventInfoName);
78 
79  // 2. Physics
80  addParam("SegmentLength", m_segmentLength,
81  "Maximum segment length (in millimeters)", m_segmentLength);
82  addParam("WidthOfDiffusCloud", m_widthOfDiffusCloud,
83  "Integration range of charge cloud in sigmas", m_widthOfDiffusCloud);
84 
85  // 3. Noise
86  addParam("PoissonSmearing", m_applyPoisson,
87  "Apply Poisson smearing on chargelets", m_applyPoisson);
88  addParam("ElectronicEffects", m_applyNoise, "Generate noise digits",
89  m_applyNoise);
90  addParam("ZeroSuppressionCut", m_SNAdjacent,
91  "Zero suppression cut in sigmas of strip noise", m_SNAdjacent);
92  addParam("FADCmode", m_roundZS,
93  "FADC mode: if true, ZS cut is rounded to nearest ADU ", m_roundZS);
94  addParam("numberOfSamples", m_nSamplesOverZS,
95  "Keep digit if numberOfSamples or more samples are over ZS threshold",
97 
98  // 4. Timing
99  addParam("APVShapingTime", m_shapingTime, "APV25 shpaing time in ns",
100  m_shapingTime);
101  addParam("ADCSamplingTime", m_samplingTime,
102  "Interval between ADC samples in ns", m_samplingTime);
103  addParam("StartSampling", m_startSampling,
104  "Start of the sampling window, in ns", m_startSampling);
105  addParam("RandomizeEventTimes", m_randomizeEventTimes,
106  "Randomize event times over a frame interval", m_randomizeEventTimes);
107  addParam("TimeFrameLow", m_minTimeFrame,
108  "Left edge of event time randomization window, ns", m_minTimeFrame);
109  addParam("TimeFrameHigh", m_maxTimeFrame,
110  "Right edge of event time randomization window, ns", m_maxTimeFrame);
111 
112  // 5. Reporting
113  addParam("statisticsFilename", m_rootFilename,
114  "ROOT Filename for statistics generation. If filename is empty, no statistics will be produced",
116  addParam("storeWaveforms", m_storeWaveforms,
117  "Store waveforms in a TTree in the statistics file.", m_storeWaveforms);
118  addParam("signalsList", m_signalsList,
119  "Store signals (time/charge/tau) in a tab-delimited file",
120  m_signalsList);
121 }
122 
124 {
125  //Register all required collections
127 
129 
131  storeShaperDigits.registerInDataStore();
132  storeShaperDigits.registerRelationTo(storeMCParticles);
133  storeShaperDigits.registerRelationTo(storeTrueHits);
134 
136  DataStore::arrayName<SVDShaperDigit>(m_storeShaperDigitsName),
137  DataStore::arrayName<MCParticle>(m_storeMCParticlesName));
139  DataStore::arrayName<SVDShaperDigit>(m_storeShaperDigitsName),
140  DataStore::arrayName<SVDTrueHit>(m_storeTrueHitsName));
141 
143  StoreObjPtr<EventMetaData> storeEvents;
144 
145  //Set names in case default was used. We need the names to initialize the RelationIndices.
147  DataStore::arrayName<MCParticle>(m_storeMCParticlesName),
148  DataStore::arrayName<SVDSimHit>(m_storeSimHitsName));
150  DataStore::arrayName<SVDTrueHit>(m_storeTrueHitsName),
151  DataStore::arrayName<SVDSimHit>(m_storeSimHitsName));
152 
153  // Convert parameters to correct units
155  m_noiseFraction = TMath::Freq(m_SNAdjacent); // 0.9... !
160 
161  B2DEBUG(1,
162  "SVDDigitizer parameters (in default system units, *=cannot be set directly):");
163  B2DEBUG(1, " DATASTORE COLLECTIONS:");
164  B2DEBUG(1,
165  " --> MCParticles: " << DataStore::arrayName<MCParticle>(m_storeMCParticlesName));
166  B2DEBUG(1,
167  " --> Digits: " << DataStore::arrayName<SVDShaperDigit>(m_storeShaperDigitsName));
168  B2DEBUG(1,
169  " --> SimHits: " << DataStore::arrayName<SVDSimHit>(m_storeSimHitsName));
170  B2DEBUG(1,
171  " --> TrueHits: " << DataStore::arrayName<SVDTrueHit>(m_storeTrueHitsName));
172  B2DEBUG(1, " --> MCSimHitRel: " << m_relMCParticleSimHitName);
173  B2DEBUG(1, " --> DigitMCRel: " << m_relShaperDigitMCParticleName);
174  B2DEBUG(1, " --> TrueSimRel: " << m_relTrueHitSimHitName);
175  B2DEBUG(1, " --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
176  B2DEBUG(1, " PHYSICS: ");
177  B2DEBUG(1, " --> SegmentLength: " << m_segmentLength);
178  B2DEBUG(1, " --> Charge int. range: " << m_widthOfDiffusCloud);
179  B2DEBUG(1, " NOISE: ");
180  B2DEBUG(1, " --> Add Poisson noise " << (m_applyPoisson ? "true" : "false"));
181  B2DEBUG(1, " --> Add Gaussian noise: " << (m_applyNoise ? "true" : "false"));
182  B2DEBUG(1, " --> Zero suppression cut" << m_SNAdjacent);
183  B2DEBUG(1, " --> Round ZS cut: " << (m_roundZS ? "true" : "false"));
184  B2DEBUG(1, " --> Samples over ZS cut:" << m_nSamplesOverZS);
185  B2DEBUG(1, " --> Noise fraction*: " << 1.0 - m_noiseFraction);
186  B2DEBUG(1, " TIMING: ");
187  B2DEBUG(1, " --> APV25 shaping time: " << m_shapingTime);
188  B2DEBUG(1, " --> Sampling time: " << m_samplingTime);
189  B2DEBUG(1, " --> Start of int. wind.:" << m_startSampling);
190  B2DEBUG(1, " --> Random event times. " << (m_randomizeEventTimes ? "true" : "false"));
191  B2DEBUG(1, " REPORTING: ");
192  B2DEBUG(1, " --> statisticsFilename: " << m_rootFilename);
193  B2DEBUG(1,
194  " --> storeWaveforms: " << (m_storeWaveforms ? "true" : "false"));
195 
196  if (!m_rootFilename.empty()) {
197  m_rootFile = new TFile(m_rootFilename.c_str(), "RECREATE");
198  m_rootFile->cd();
199  m_histChargeSharing_v = new TH1D("h_Diffusion_v", " 'Diffusion' distance, v",
200  200, -500, 500);
201  m_histChargeSharing_v->GetXaxis()->SetTitle(" distance v [um]");
202  m_histChargeSharing_u = new TH1D("h_Diffusion_u",
203  " 'Diffusion' distance, u", 100, -200, 200);
204  m_histChargeSharing_u->GetXaxis()->SetTitle("distance u [um]");
205  m_histLorentz_u = new TH1D("h_LorentzAngle_u", "Lorentz angle, holes",
206  100, -0.08, 0);
207  m_histLorentz_u->GetXaxis()->SetTitle("Lorentz angle");
208  m_histLorentz_v = new TH1D("h_LorentzAngle_v",
209  "Lorentz angle, electrons", 100, -0.002, 0.002);
210  m_histLorentz_v->GetXaxis()->SetTitle("Lorentz angle");
211  m_signalDist_u = new TH1D("h_signalDist_u",
212  "Strip signals vs. TrueHits, holes", 100, -400, 400);
213  m_signalDist_u->GetXaxis()->SetTitle("U strip position - TrueHit u [um]");
214  m_signalDist_v = new TH1D("h_signalDist_v",
215  "Strip signals vs. TrueHits, electrons", 100, -400, 400);
216  m_signalDist_v->GetXaxis()->SetTitle("V strip position - TrueHit v [um]");
217 
218  m_histMobility_e = new TH1D("h_elecMobility", "electron Mobility",
219  30, 900, 1200);
220  m_histMobility_e->GetXaxis()->SetTitle("Electron Mobility");
221  m_histMobility_h = new TH1D("h_holeMobility", "hole Mobility",
222  30, 400, 500);
223  m_histMobility_h->GetXaxis()->SetTitle("Holes Mobility");
224 
225  m_histDistanceToPlane_e = new TH1D("h_elecDistToPlane", "electron Distance to Plane",
226  50, -0.05, 0.05);
227  m_histDistanceToPlane_e->GetXaxis()->SetTitle("Electron Distance To Plane [cm]");
228  m_histDistanceToPlane_h = new TH1D("h_holeDistToPlane", "holes Distance to Plane",
229  50, -0.05, 0.05);
230  m_histDistanceToPlane_h->GetXaxis()->SetTitle("Holes Distance To Plane [cm]");
231 
232  m_histVelocity_e = new TH1D("h_elecVelocity", "electrons Velocity (z)",
233  100, 0.001, 0.01);
234 
235  m_histVelocity_e->GetXaxis()->SetTitle("Electron Velocity [cm/s]");
236  m_histVelocity_h = new TH1D("h_holeVelocity", "holes Velocity (z)",
237  30, -0.002, -0.0004);
238  m_histVelocity_h->GetXaxis()->SetTitle("holes Velocity [cm/s]");
239 
240  m_histDriftTime_e = new TH1D("h_elecDriftTime", "electron Drift Time",
241  30, 0, 30);
242  m_histDriftTime_e->GetXaxis()->SetTitle("Electron Drift Time");
243  m_histDriftTime_h = new TH1D("h_holeDriftTime", "hole Drift Time",
244  30, 0, 30);
245  m_histDriftTime_h->GetXaxis()->SetTitle("Hole Drift Time");
246 
247  if (m_storeWaveforms) {
248  m_waveTree = new TTree("waveTree", "SVD waveforms");
249  m_waveTree->Branch("sensor", &tree_vxdID, "sensor/I");
250  m_waveTree->Branch("u_or_v", &tree_uv, "u_or_v/I");
251  m_waveTree->Branch("strip", &tree_strip, "strip/I");
252  m_waveTree->Branch("signal", tree_signal, "signal[20]/D");
253  }
254  } else {
255  // No waveforms can be stored if there is no statistics file.
256  m_storeWaveforms = false;
257  }
258 }
259 
261 {
262 
263  if (m_mapping.hasChanged()) { m_map = std::make_unique<SVDOnlineToOfflineMap>(m_mapping->getFileName()); }
264 
265  //Fill map with all possible sensors This is too slow to be done every event so
266  //we fill it once and only clear the content of the sensors per event, not
267  //the whole map
268  m_sensors.clear();
270  for (VxdID layer : geo.getLayers(SensorInfo::SVD)) {
271  for (VxdID ladder : geo.getLadders(layer)) {
272  for (VxdID sensor : geo.getSensors(ladder)) {
273  m_sensors[sensor] = Sensor();
274  }
275  }
276  }
277 
278  if (!m_MaskedStr.isValid())
279  B2WARNING("No valid SVDFADCMaskedStrip for the requested IoV -> no strips masked");
280  if (!m_map)
281  B2WARNING("No valid channel mapping -> all APVs will be enabled");
282 
283 }
284 
286 {
287  // Generate current event time
288  if (m_randomizeEventTimes) {
289  StoreObjPtr<EventMetaData> storeEvent;
290  m_currentEventTime = gRandom->Uniform(m_minTimeFrame, m_maxTimeFrame);
291  // We have negative event times, so we have to encode!
292  storeEvent->setTime(static_cast<unsigned long>(1000 + m_currentEventTime));
293  } else
294  m_currentEventTime = 0.0;
295 
296  //Clear sensors and process SimHits
297  for (Sensors::value_type& sensor : m_sensors) {
298  sensor.second.first.clear(); // u strips
299  sensor.second.second.clear(); // v strips
300  }
301  // m_currentSensor = 0;
302  //m_currentSensorInfo = 0;
303 
307 
308  RelationArray mcParticlesToSimHits(storeMCParticles, storeSimHits, m_relMCParticleSimHitName);
309  RelationArray trueHitsToSimHits(storeTrueHits, storeSimHits, m_relTrueHitSimHitName);
310 
311  RelationIndex<MCParticle, SVDSimHit> relMCParticleSimHit(storeMCParticles, storeSimHits, m_relMCParticleSimHitName);
312  RelationIndex<SVDTrueHit, SVDSimHit> relTrueHitSimHit(storeTrueHits, storeSimHits, m_relTrueHitSimHitName);
313 
314  unsigned int nSimHits = storeSimHits.getEntries();
315  if (nSimHits == 0)
316  return;
317 
318  //Check sensor info and set pointers to current sensor
319  for (unsigned int i = 0; i < nSimHits; ++i) {
320  m_currentHit = storeSimHits[i];
322  relMCParticleSimHit.getFirstElementTo(m_currentHit);
323  if (mcRel) {
324  m_currentParticle = mcRel->indexFrom;
325  if (mcRel->weight < 0) {
326  //This simhit is from a particle which was not saved by the simulation
327  //so we do not take it into account for relations. Otherwise we might
328  //end up adding positive and negative weights together
329  m_currentParticle = -1;
330  }
331  } else {
332  // Don't bother with warnings for background SimHits
334  B2WARNING(
335  "Could not find MCParticle which produced SVDSimhit " << i);
336  m_currentParticle = -1;
337  }
339  relTrueHitSimHit.getFirstElementTo(m_currentHit);
340  //We only care about true hits from particles which have not been ignored
341  if (trueRel && trueRel->weight > 0) {
342  m_currentTrueHit = trueRel->indexFrom;
343  } else {
344  m_currentTrueHit = -1;
345  }
346 
347  VxdID sensorID = m_currentHit->getSensorID();
348  if (!m_currentSensorInfo || sensorID != m_currentSensorInfo->getID()) {
350  dynamic_cast<const SensorInfo*>(&VXD::GeoCache::get(sensorID));
351  if (!m_currentSensorInfo)
352  B2FATAL(
353  "Sensor Information for Sensor " << sensorID << " not found, make sure that the geometry is set up correctly");
354 
355  const SensorInfo& info = *m_currentSensorInfo;
356  // Publish some useful data
357  m_sensorThickness = info.getThickness();
358  m_depletionVoltage = info.getDepletionVoltage();
359  m_biasVoltage = info.getBiasVoltage();
360  m_backplaneCapacitanceU = info.getBackplaneCapacitanceU();
361  m_interstripCapacitanceU = info.getInterstripCapacitanceU();
362  m_couplingCapacitanceU = info.getCouplingCapacitanceU();
363  m_backplaneCapacitanceV = info.getBackplaneCapacitanceV();
364  m_interstripCapacitanceV = info.getInterstripCapacitanceV();
365  m_couplingCapacitanceV = info.getCouplingCapacitanceV();
366  m_elNoiseU = info.getElectronicNoiseU();
367  m_elNoiseV = info.getElectronicNoiseV();
368 
369  m_currentSensor = &m_sensors[sensorID];
370  B2DEBUG(20,
371  "Sensor Parameters for Sensor " << sensorID << ": " << endl
372  << " --> Width: " << m_currentSensorInfo->getWidth() << endl
373  << " --> Length: " << m_currentSensorInfo->getLength() << endl
374  << " --> uPitch: " << m_currentSensorInfo->getUPitch() << endl
375  << " --> vPitch: " << m_currentSensorInfo->getVPitch(-m_currentSensorInfo->getLength() / 2.0)
376  << ", " << m_currentSensorInfo->getVPitch(m_currentSensorInfo->getLength() / 2.0) << endl
377  << " --> Thickness: " << m_currentSensorInfo->getThickness() << endl
378  << " --> Deplet. voltage:" << m_currentSensorInfo->getDepletionVoltage() << endl
379  << " --> Bias voltage: " << m_currentSensorInfo->getBiasVoltage() << endl
380  << " --> Backplane cap.U: " << m_currentSensorInfo->getBackplaneCapacitanceU() << endl
381  << " --> Interstrip cap.U:" << m_currentSensorInfo->getInterstripCapacitanceU() << endl
382  << " --> Coupling cap.U: " << m_currentSensorInfo->getCouplingCapacitanceU() << endl
383  << " --> Backplane cap.V: " << m_currentSensorInfo->getBackplaneCapacitanceV() << endl
384  << " --> Interstrip cap.V:" << m_currentSensorInfo->getInterstripCapacitanceV() << endl
385  << " --> Coupling cap.V: " << m_currentSensorInfo->getCouplingCapacitanceV() << endl
386  << " --> El. noise U: " << m_currentSensorInfo->getElectronicNoiseU() << endl
387  << " --> El. noise V: " << m_currentSensorInfo->getElectronicNoiseV() << endl
388  );
389 
390  }
391  B2DEBUG(10,
392  "Processing hit " << i << " in Sensor " << sensorID << ", related to MCParticle " << m_currentParticle);
393  processHit();
394  }
395  // If storage of waveforms is required, store them in the statistics file.
396  if (m_storeWaveforms) {
397  m_rootFile->cd();
398  saveWaveforms();
399  }
400  if (m_signalsList != "")
401  saveSignals();
402 
403  saveDigits();
404 }
405 
407 {
408  // Set time of the hit
410 
411  //Get Steplength and direction
412  const TVector3& startPoint = m_currentHit->getPosIn();
413  const TVector3& stopPoint = m_currentHit->getPosOut();
414  TVector3 direction = stopPoint - startPoint;
415  double trackLength = direction.Mag();
416 
417  if (m_currentHit->getPDGcode() == 22 || trackLength < 0.1 * Unit::um) {
418  //Photons deposit energy at the end of their step
419  driftCharge(stopPoint, m_currentHit->getElectrons(), SVD::SensorInfo::electron);
421  } else {
422  //Otherwise, split into segments of (default) max. 5µm and
423  //drift the charges from the center of each segment
425  double lastFraction {0};
426  double lastElectrons {0};
427 
428  for (auto& segment : segments) {
429  //Simhit returns step fraction and cumulative electrons. We want the
430  //center of these steps and electrons in this step
431  const double f = (segment.first + lastFraction) / 2;
432  const double e = segment.second - lastElectrons;
433  //Update last values
434  std::tie(lastFraction, lastElectrons) = segment;
435 
436  //And drift charge from that position
437  const TVector3 position = startPoint + f * direction;
438  driftCharge(position, e, SVD::SensorInfo::electron);
439  driftCharge(position, e, SVD::SensorInfo::hole);
440  }
441  }
442 }
443 
444 
445 void SVDDigitizerModule::driftCharge(const TVector3& position, double carriers, SVD::SensorInfo::CarrierType carrierType)
446 {
447  bool have_electrons = (carrierType == SVD::SensorInfo::electron);
448 
449  string carrierName = (have_electrons) ? "electron" : "hole";
450  B2DEBUG(30,
451  "Drifting " << carriers << " " << carrierName << "s at position (" << position.x() << ", " << position.y() << ", " << position.z()
452  << ").");
453  B2DEBUG(30, "@@@ driftCharge: drifting " << carriers << " " << carrierName << "s at position (" << position.x() << ", " <<
454  position.y() << ", " << position.z()
455  << ").");
456 
457  //Get references to current sensor/info for ease of use
458  const SensorInfo& info = *m_currentSensorInfo;
459  StripSignals& digits = (!have_electrons) ? m_currentSensor->first : m_currentSensor->second;
460 
461  double distanceToPlane = (have_electrons) ?
462  0.5 * m_sensorThickness - position.Z() :
463  -0.5 * m_sensorThickness - position.Z(); //cm
464 
465  if (m_histDistanceToPlane_e && have_electrons) m_histDistanceToPlane_e->Fill(distanceToPlane);
466  if (m_histDistanceToPlane_h && !have_electrons) m_histDistanceToPlane_h->Fill(distanceToPlane);
467 
468  // Approximation: calculate drift velocity at the point halfway towards
469  // the respective sensor surface.
470  TVector3 mean_pos(position.X(), position.Y(), position.Z() + 0.5 * distanceToPlane);
471 
472  // Calculate drift times and widths of charge clouds.
473  TVector3 v = info.getVelocity(carrierType, mean_pos);
474  if (m_histVelocity_e && have_electrons) m_histVelocity_e->Fill(v.Z()); //Unit::cm/Unit::cm*Unit::eV/Unit::e*Unit::s);
475  if (m_histVelocity_h && !have_electrons) m_histVelocity_h->Fill(v.Z()); //Unit::cm/Unit::cm*Unit::eV/Unit::e*Unit::s);
476 
477  double driftTime = distanceToPlane / v.Z(); //ns
478  if (m_histDriftTime_e && have_electrons) m_histDriftTime_e->Fill(driftTime); //ns
479  if (m_histDriftTime_h && !have_electrons) m_histDriftTime_h->Fill(driftTime); //ns
480 
481  TVector3 center = position + driftTime * v; //cm
482  double mobility = (have_electrons) ?
483  info.getElectronMobility(info.getEField(mean_pos).Mag()) :
484  info.getHoleMobility(info.getEField(mean_pos).Mag());
485 
486  if (m_histMobility_e && have_electrons) m_histMobility_e->Fill(mobility); //cm2/V/ns
487  if (m_histMobility_h && !have_electrons) m_histMobility_h->Fill(mobility); //cm2/V/ns
488 
489  double D = Const::kBoltzmann * info.getTemperature() / Unit::e * mobility;
490  double sigma = std::max(1.0e-4, sqrt(2.0 * D * driftTime));
491  double tanLorentz = (!have_electrons) ? v.X() / v.Z() : v.Y() / v.Z();
492 
493  B2DEBUG(30, "velocity (" << v.X() / Unit::um << ", " << v.Y() / Unit::um << ", " << v.Z() / Unit::um << ") um/ns");
494  B2DEBUG(30, "D = " << D << ", driftTime = " << driftTime / Unit::ns << " ns");
495  B2DEBUG(30, "sigma = " << sigma / Unit::um << " um");
496  B2DEBUG(30, "tan Lorentz = " << tanLorentz);
497 
498  sigma *= sqrt(1.0 + tanLorentz * tanLorentz);
499  if (m_histLorentz_u && !have_electrons) m_histLorentz_u->Fill(tanLorentz);
500  if (m_histLorentz_v && have_electrons) m_histLorentz_v->Fill(tanLorentz);
501 
502  //Distribute carrier cloud on strips
503  int vID = info.getVCellID(center.Y(), true);
504  int uID = info.getUCellID(center.X(), center.Y(), true);
505  int seedStrip = (!have_electrons) ? uID : vID;
506  double seedPos = (!have_electrons) ?
507  info.getUCellPosition(seedStrip, vID) :
508  info.getVCellPosition(seedStrip);
509  double geomPitch = (!have_electrons) ? 0.5 * info.getUPitch(center.Y()) : 0.5 * info.getVPitch();
510  int nCells = (!have_electrons) ? info.getUCells() : info.getVCells();
511  std::deque<double> stripCharges;
512  std::deque<double> strips; // intermediate strips will be half-integers, like 2.5.
513 #define NORMAL_CDF(z) 0.5 * std::erfc( - (z) * 0.707107)
514  double current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
515  double current_strip = seedStrip;
516  double cdf_low = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
517  double cdf_high = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
518  double charge = carriers * (cdf_high - cdf_low);
519 
520  B2DEBUG(30, "geomPitch = " << geomPitch / Unit::um << " um");
521  B2DEBUG(30, "charge = " << charge << " = " << carriers << "(carriers) * (" << cdf_high << "(cdf_high) - " << cdf_low <<
522  "(cdf_low));");
523 
524  stripCharges.push_back(charge);
525  strips.push_back(current_strip);
526  while (cdf_low > 1.0e-5) {
527  current_pos -= geomPitch;
528  current_strip -= 0.5;
529  double cdf_current = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
530  charge = carriers * (cdf_low - cdf_current);
531  stripCharges.push_front(charge);
532  strips.push_front(current_strip);
533  cdf_low = cdf_current;
534  }
535  current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
536  current_strip = seedStrip;
537  while (cdf_high < 1.0 - 1.0e-5) {
538  current_pos += geomPitch;
539  current_strip += 0.5;
540  double cdf_current = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
541  charge = carriers * (cdf_current - cdf_high);
542  stripCharges.push_back(charge);
543  strips.push_back(current_strip);
544  cdf_high = cdf_current;
545  }
546 #undef NORMAL_CDF
547 
548  // Pad with zeros for smoothing
549  int npads = (strips.front() - floor(strips.front()) == 0) ? 4 : 3;
550  for (int i = 0; i < npads; ++i) {
551  strips.push_front(strips.front() - 0.5);
552  stripCharges.push_front(0);
553  }
554  npads = (strips.back() - floor(strips.back()) == 0) ? 4 : 3;
555  for (int i = 0; i < npads; ++i) {
556  strips.push_back(strips.back() + 0.5);
557  stripCharges.push_back(0);
558  }
559  // Cross-talk
560  B2DEBUG(30, " --> charge sharing simulation, # strips = " << strips.size());
561  std::deque<double> readoutCharges;
562  std::deque<int> readoutStrips;
563  for (std::size_t index = 2; index < strips.size() - 2; index += 2) {
564  B2DEBUG(30, " index = " << index << ", strip = " << strips[index] << ", stripCharge = " << stripCharges[index]);
565  int currentStrip = static_cast<int>(strips[index]);
566  double Cc = (!have_electrons) ? info.getCouplingCapacitanceU(currentStrip) :
567  info.getCouplingCapacitanceV(currentStrip);
568  double Ci = (!have_electrons) ? info.getInterstripCapacitanceU(currentStrip) :
569  info.getInterstripCapacitanceV(currentStrip);
570  double Cb = (!have_electrons) ? info.getBackplaneCapacitanceU(currentStrip) :
571  info.getBackplaneCapacitanceV(currentStrip);
572 
573  double cNeighbour2 = 0.5 * Ci / (Ci + Cb + Cc);
574  double cNeighbour1 = Ci / (2 * Ci + Cb);
575  double cSelf = Cc / (Ci + Cb + Cc);
576 
577  B2DEBUG(30, " current strip = " << currentStrip);
578  B2DEBUG(30, " index-2 = " << index - 2 << ", strip = " << strips[index - 2] << ", stripCharge = " << stripCharges[index - 2]);
579  B2DEBUG(30, " index-1 = " << index - 1 << ", strip = " << strips[index - 1] << ", stripCharge = " << stripCharges[index - 1]);
580  B2DEBUG(30, " index = " << index << ", strip = " << strips[index] << ", stripCharge = " << stripCharges[index]);
581  B2DEBUG(30, " index+1 = " << index + 1 << ", strip = " << strips[index + 1] << ", stripCharge = " << stripCharges[index + 1]);
582  B2DEBUG(30, " index+2 = " << index + 2 << ", strip = " << strips[index + 2] << ", stripCharge = " << stripCharges[index + 2]);
583  //se index e' di readout va bene
584  readoutCharges.push_back(cSelf * (
585  cNeighbour2 * stripCharges[index - 2]
586  + cNeighbour1 * stripCharges[index - 1]
587  + stripCharges[index]
588  + cNeighbour1 * stripCharges[index + 1]
589  + cNeighbour2 * stripCharges[index + 2]
590  ));
591  readoutStrips.push_back(currentStrip);
592  B2DEBUG(30, " post simulation: " << index << ", strip = " << currentStrip << ", readoutCharge = " <<
593  readoutCharges[readoutCharges.size() - 1]);
594  }
595  // Trim at sensor edges
596  double tail = 0;
597  while (readoutStrips.size() > 0 && readoutStrips.front() < 0) {
598  readoutStrips.pop_front();
599  tail += readoutCharges.front();
600  readoutCharges.pop_front();
601  }
602  readoutCharges.front() += tail;
603  tail = 0;
604  while (readoutStrips.size() > 0 && readoutStrips.back() > nCells - 1) {
605  readoutStrips.pop_back();
606  tail += readoutCharges.back();
607  readoutCharges.pop_back();
608  }
609  readoutCharges.back() += tail;
610  // Poisson smearing - Gaussian approximation
611  if (m_applyPoisson)
612  for (auto& c : readoutCharges)
613  c = (c <= 0) ? 0 : std::max(0.0, gRandom->Gaus(c, std::sqrt(info.c_fanoFactorSi * c)));
614 
615  // Fill diagnostic charts
617  TH1D* histo = (!have_electrons) ? m_histChargeSharing_u : m_histChargeSharing_v;
618  double d = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
619  for (std::size_t index = 0; index < readoutStrips.size(); ++ index) {
620  double dist = d + (readoutStrips[index] - seedStrip) * 2 * geomPitch;
621  histo->Fill(dist / Unit::um, readoutCharges[index]);
622  }
623  }
624  // Store
625  double recoveredCharge = 0;
626  for (std::size_t index = 0; index < readoutStrips.size(); index ++) {
627  // NB> To first approximation, we assign to the signal 1/2*driftTime.
628  // This doesn't change the charge collection, only charge collection timing.
629  digits[readoutStrips[index]].add(m_currentTime + 0.5 * driftTime, readoutCharges[index],
631  recoveredCharge += readoutCharges[index];
632  B2DEBUG(30, "strip: " << readoutStrips[index] << " charge: " << readoutCharges[index]);
633  }
634  B2DEBUG(30, "Digitized " << recoveredCharge << " of " << carriers << " original carriers.");
635 }
636 
637 double SVDDigitizerModule::addNoise(double charge, double noise)
638 {
639  if (charge < 0) {
640  //Noise digit, add noise to exceed Noise Threshold;
641  double p = gRandom->Uniform(m_noiseFraction, 1.0);
642  charge = TMath::NormQuantile(p) * noise;
643  } else {
644  charge += gRandom->Gaus(0., noise);
645  }
646  return charge;
647 }
648 
650 {
652  SVDModeByte modeByte = storeSVDEvtInfo->getModeByte();
653 
657  RelationArray relShaperDigitMCParticle(storeShaperDigits, storeMCParticles,
659  RelationArray relShaperDigitTrueHit(storeShaperDigits, storeTrueHits,
661 
662  //Get time of the first sample
663  const double bunchTimeSep = 2 * 1.96516; //in ns
664  int triggerBin = modeByte.getTriggerBin();
665  int bunchXingsSinceAPVstart = 2 * triggerBin + gRandom->Integer(2);
666  double initTime = m_startSampling - bunchTimeSep * bunchXingsSinceAPVstart;
667 
668  //Get SVD config from SVDEventInfo
669  // int runType = (int) modeByte.getRunType();
670  // int eventType = (int) modeByte.getEventType();
671  int daqMode = (int) modeByte.getDAQMode();
672 
673  int nAPV25Samples = 0;
674  if (daqMode == 2)
675  nAPV25Samples = 6;
676  else if (daqMode == 1)
677  nAPV25Samples = 3;
678  else if (daqMode == 0)
679  nAPV25Samples = 1;
680  else
681  B2ERROR("daqMode not recongized, check SVDEventInfoSetter parameters");
682 
683  // ... to store digit-digit relations
684  vector<pair<unsigned int, float> > digit_weights;
685 
686  // Take samples at the desired times, add noise, zero-suppress and save digits.
687 
688  for (Sensors::value_type& sensor : m_sensors) {
689  int sensorID = sensor.first;
690  const SensorInfo& info =
691  dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(sensorID));
692  // u-side digits:
693  double elNoiseU = info.getElectronicNoiseU();
694  double aduEquivalentU = info.getAduEquivalentU();
695  double charge_thresholdU = m_SNAdjacent * elNoiseU;
696  // Add noisy digits
697  if (m_applyNoise) {
698  double fraction = 1.0 - m_noiseFraction;
699  int nU = info.getUCells();
700  int uNoisyStrips = gRandom->Poisson(fraction * nU);
701  for (short ns = 0; ns < uNoisyStrips; ++ns) {
702  short iStrip = gRandom->Integer(nU);
703  sensor.second.first[iStrip].add(0, -1, 0, 0, 0);
704  } // for ns
705  } // Add noise digits
706  // Cycle through signals and generate samples
707  for (StripSignals::value_type& stripSignal : sensor.second.first) {
708  short int iStrip = stripSignal.first;
709  SVDSignal& s = stripSignal.second;
710  // Now generate samples in time and save as digits.
711  vector<double> samples;
712  // ... to store digit-digit relations
713  digit_weights.clear();
714  digit_weights.reserve(SVDShaperDigit::c_nAPVSamples);
715  // For noise digits, just generate random variates on randomly selected samples
716  if (s.isNoise()) {
717  double pSelect = 1.0 / nAPV25Samples;
718  for (int iSample = 0; iSample < nAPV25Samples; iSample++) {
719  if (gRandom->Uniform() < pSelect)
720  samples.push_back(addNoise(-1, elNoiseU));
721  else
722  samples.push_back(gRandom->Gaus(0, elNoiseU));
723  }
724  } else {
725  double t = initTime;
726  for (int iSample = 0; iSample < nAPV25Samples; iSample ++) {
727  samples.push_back(addNoise(s(t), elNoiseU));
728  t += m_samplingTime;
729  }
730  }
731 
732  SVDSignal::relations_map particles = s.getMCParticleRelations();
733  SVDSignal::relations_map truehits = s.getTrueHitRelations();
734 
735  // Save SVDShaperDigits
736  // 1. Convert to ADU
738  std::transform(samples.begin(), samples.end(), rawSamples.begin(),
739  [&](double x)->SVDShaperDigit::APVRawSampleType {
740  return SVDShaperDigit::trimToSampleRange(x / aduEquivalentU);
741  });
742  // 2.a Check if over threshold
743  auto rawThreshold = charge_thresholdU / aduEquivalentU;
744  if (m_roundZS) rawThreshold = round(rawThreshold);
745  auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
746  std::bind2nd(std::greater<double>(), rawThreshold)
747  );
748  if (n_over < m_nSamplesOverZS) continue;
749 
750  // 2.b check if the strip is masked
751  if (m_MaskedStr.isMasked(sensorID, true, iStrip)) continue;
752 
753  // 2.c check if the APV is disabled
754  if (!m_map->isAPVinMap(sensorID, true, iStrip)) continue;
755 
756  // 3. Save as a new digit
757  int digIndex = storeShaperDigits.getEntries();
758  storeShaperDigits.appendNew(SVDShaperDigit(sensorID, true, iStrip, rawSamples, 0, modeByte));
759 
760  //If the digit has any relations to MCParticles, add the Relation
761  if (particles.size() > 0) {
762  relShaperDigitMCParticle.add(digIndex, particles.begin(), particles.end());
763  }
764  //If the digit has any relations to truehits, add the Relations.
765  if (truehits.size() > 0) {
766  relShaperDigitTrueHit.add(digIndex, truehits.begin(), truehits.end());
767  }
768  // generate SVDShaperDigits
769  } // for stripSignals
770 
771  // v-side digits:
772  double elNoiseV = info.getElectronicNoiseV();
773  double aduEquivalentV = info.getAduEquivalentV();
774  double charge_thresholdV = m_SNAdjacent * elNoiseV;
775  // Add noise digits
776  if (m_applyNoise) {
777  double fraction = 1.0 - m_noiseFraction;
778  int nV = info.getVCells();
779  int vNoisyStrips = gRandom->Poisson(fraction * nV);
780  for (short ns = 0; ns < vNoisyStrips; ++ns) {
781  short iStrip = gRandom->Integer(nV);
782  sensor.second.second[iStrip].add(0, -1, 0, 0, 0);
783  } // for ns
784  } // Add noise digits
785  // Cycle through signals and generate samples
786  for (StripSignals::value_type& stripSignal : sensor.second.second) {
787  short int iStrip = stripSignal.first;
788  SVDSignal& s = stripSignal.second;
789  // Now generate samples in time and save as digits.
790  vector<double> samples;
791  // ... to store digit-digit relations
792  digit_weights.clear();
793  digit_weights.reserve(SVDShaperDigit::c_nAPVSamples);
794  // For noise digits, just generate random variates on randomly selected samples
795  if (s.isNoise()) {
796  double pSelect = 1.0 / nAPV25Samples;
797  for (int iSample = 0; iSample < nAPV25Samples; iSample++) {
798  if (gRandom->Uniform() < pSelect)
799  samples.push_back(addNoise(-1, elNoiseV));
800  else
801  samples.push_back(gRandom->Gaus(0, elNoiseV));
802  }
803  } else {
804  double t = initTime;
805  for (int iSample = 0; iSample < nAPV25Samples; iSample ++) {
806  samples.push_back(addNoise(s(t), elNoiseV));
807  t += m_samplingTime;
808  }
809  }
810 
811  SVDSignal::relations_map particles = s.getMCParticleRelations();
812  SVDSignal::relations_map truehits = s.getTrueHitRelations();
813 
814  // Save SVDShaperDigits
815  // 1. Convert to ADU
817  std::transform(samples.begin(), samples.end(), rawSamples.begin(),
818  [&](double x)->SVDShaperDigit::APVRawSampleType {
819  return SVDShaperDigit::trimToSampleRange(x / aduEquivalentV);
820  });
821  // 2.a Check if over threshold
822  auto rawThreshold = charge_thresholdV / aduEquivalentV;
823  if (m_roundZS) rawThreshold = round(rawThreshold);
824  auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
825  std::bind2nd(std::greater<double>(), rawThreshold)
826  );
827  if (n_over < m_nSamplesOverZS) continue;
828 
829  // 2.b check if the strip is masked
830  if (m_MaskedStr.isMasked(sensorID, false, iStrip)) continue;
831 
832  // 2.c check if the APV is disabled
833  if (!m_map->isAPVinMap(sensorID, false, iStrip)) continue;
834 
835  // 3. Save as a new digit
836  int digIndex = storeShaperDigits.getEntries();
837  storeShaperDigits.appendNew(SVDShaperDigit(sensorID, false, iStrip, rawSamples, 0, modeByte));
838 
839  //If the digit has any relations to MCParticles, add the Relation
840  if (particles.size() > 0) {
841  relShaperDigitMCParticle.add(digIndex, particles.begin(), particles.end());
842  }
843  //If the digit has any relations to truehits, add the Relations.
844  if (truehits.size() > 0) {
845  relShaperDigitTrueHit.add(digIndex, truehits.begin(), truehits.end());
846  }
847  } // for stripSignals
848  } // FOREACH sensor
849 }
850 
852 {
853  for (Sensors::value_type& sensor : m_sensors) {
854  tree_vxdID = sensor.first;
855  const SensorInfo& info =
856  dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(sensor.first));
857  // u-side digits:
858  tree_uv = 1;
859  double thresholdU = 3.0 * info.getElectronicNoiseU();
860  for (StripSignals::value_type& stripSignal : sensor.second.first) {
861  tree_strip = stripSignal.first;
862  SVDSignal& s = stripSignal.second;
863  // Read the value only if the signal is large enough.
864  if (s.getCharge() < thresholdU)
865  continue;
866  for (int iTime = 0; iTime < 20; ++iTime) {
867  tree_signal[iTime] = s(10 * iTime);
868  }
869  m_waveTree->Fill();
870  } // FOREACH stripSignal
871  // v-side digits:
872  tree_uv = 0;
873  double thresholdV = 3.0 * info.getElectronicNoiseV();
874  for (StripSignals::value_type& stripSignal : sensor.second.second) {
875  tree_strip = stripSignal.first;
876  SVDSignal& s = stripSignal.second;
877  // Read the values only if the signal is large enough
878  if (s.getCharge() < thresholdV)
879  continue;
880  for (int iTime = 0; iTime < 20; ++iTime) {
881  tree_signal[iTime] = s(10. * iTime);
882  }
883  m_waveTree->Fill();
884  } // FOREACH stripSignal
885  } // FOREACH sensor
886  m_rootFile->Flush();
887 }
888 
890 {
891  static size_t recordNo = 0;
892  static const string header("Event\tSensor\tSide\tStrip\tContrib\tTime\tCharge\tTau");
893  regex startLine("^|\n"); // for inserting event/sensor/etc info
894  ofstream outfile(m_signalsList, ios::out | ios::app);
895  if (recordNo == 0) outfile << header << endl;
896  for (Sensors::value_type& sensor : m_sensors) {
897  VxdID sensorID(sensor.first);
898  const SensorInfo& info =
899  dynamic_cast<const SensorInfo&>(VXD::GeoCache::get(sensor.first));
900  // u-side digits:
901  size_t isU = 1;
902  double thresholdU = 3.0 * info.getElectronicNoiseU();
903  for (StripSignals::value_type& stripSignal : sensor.second.first) {
904  size_t strip = stripSignal.first;
905  SVDSignal& s = stripSignal.second;
906  // Read the value only if the signal is large enough.
907  if (s.getCharge() < thresholdU)
908  continue;
909  // Else print to a string
910  ostringstream preamble;
911  // We don't have eventNo, but we don't care about event boundaries.
912  preamble << "$&" << recordNo << '\t' << sensorID << '\t' << isU << '\t' << strip << '\t';
913  string signalString = s.toString();
914  signalString.pop_back(); // remove the last newline!!!
915  string tableString = regex_replace(signalString, startLine, preamble.str());
916  outfile << tableString << endl; // now we have to add the newline back.
917  } // FOREACH stripSignal
918  // x-side digits:
919  isU = 0;
920  double thresholdV = 3.0 * info.getElectronicNoiseV();
921  for (StripSignals::value_type& stripSignal : sensor.second.second) {
922  size_t strip = stripSignal.first;
923  SVDSignal& s = stripSignal.second;
924  // Read the value only if the signal is large enough.
925  if (s.getCharge() < thresholdV)
926  continue;
927  // Else print to a string
928  ostringstream preamble;
929  // We don't have eventNo, but we don't care about event boundaries.
930  preamble << "$&" << recordNo << '\t' << sensorID << '\t' << isU << '\t' << strip << '\t';
931  string signalString = s.toString();
932  signalString.pop_back(); // remove the last newline!!!
933  string tableString = regex_replace(signalString, startLine, preamble.str());
934  outfile << tableString << endl; // now we have to add the newline back.
935  } // FOREACH stripSignal
936  } // for sensors
937  outfile.close();
938  recordNo++;
939 }
940 
942 {
943  if (m_rootFile) {
944  m_rootFile->Write();
945  m_rootFile->Close();
946  }
947 }
948 
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::DBAccessorBase::hasChanged
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
Definition: DBAccessorBase.h:92
Belle2::SVD::SVDDigitizerModule::m_relShaperDigitMCParticleName
std::string m_relShaperDigitMCParticleName
Name of the relation between SVDShaperDigits and MCParticles.
Definition: SVDDigitizerModule.h:124
Belle2::SVD::SVDDigitizerModule::m_currentTime
double m_currentTime
Time of the current SimHit.
Definition: SVDDigitizerModule.h:199
Belle2::RelationIndexContainer::Element::weight
RelationElement::weight_type weight
weight of the relation.
Definition: RelationIndexContainer.h:82
Belle2::SVD::SVDDigitizerModule::m_histDistanceToPlane_h
TH1D * m_histDistanceToPlane_h
Histogram showing the distance to plane for h.
Definition: SVDDigitizerModule.h:252
Belle2::SVD::SVDDigitizerModule::m_map
std::unique_ptr< SVDOnlineToOfflineMap > m_map
channel mapping map
Definition: SVDDigitizerModule.h:231
Belle2::SVD::SVDDigitizerModule::m_sensors
Sensors m_sensors
Structure containing signals in all existing sensors.
Definition: SVDDigitizerModule.h:186
Belle2::SVD::SVDDigitizerModule::m_backplaneCapacitanceU
double m_backplaneCapacitanceU
The backplane capacitanceU wrt.
Definition: SVDDigitizerModule.h:207
Belle2::SVD::SVDDigitizerModule::m_backplaneCapacitanceV
double m_backplaneCapacitanceV
The backplane capacitanceV wrt.
Definition: SVDDigitizerModule.h:213
Belle2::RelationArray
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:72
Belle2::SVD::SVDDigitizerModule::m_segmentLength
double m_segmentLength
Max.
Definition: SVDDigitizerModule.h:132
Belle2::SVD::SVDDigitizerModule::m_mapping
DBObjPtr< PayloadFile > m_mapping
channel mapping payload
Definition: SVDDigitizerModule.h:230
Belle2::SVD::SVDDigitizerModule::m_applyPoisson
bool m_applyPoisson
Whether or not to apply poisson fluctuation of charge.
Definition: SVDDigitizerModule.h:138
Belle2::SVD::SVDDigitizerModule::m_storeWaveforms
bool m_storeWaveforms
Store waveform data in the reporting file?
Definition: SVDDigitizerModule.h:179
Belle2::SVD::SVDDigitizerModule::addNoise
double addNoise(double charge, double noise)
Calculate the noise contribution to one strip with given charge.
Definition: SVDDigitizerModule.cc:637
Belle2::SVD::SVDDigitizerModule::m_relMCParticleSimHitName
std::string m_relMCParticleSimHitName
Name of the relation between MCParticles and SVDSimHits.
Definition: SVDDigitizerModule.h:118
Belle2::SVDFADCMaskedStrips::isMasked
float isMasked(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This is the method for getting the comprehensive list of masked strips at FADC level.
Definition: SVDFADCMaskedStrips.h:72
Belle2::SVD::SVDDigitizerModule::saveSignals
void saveSignals()
Save signals to a root-delimited file (to be analyzed in Python).
Definition: SVDDigitizerModule.cc:889
Belle2::SVD::Sensor
std::pair< StripSignals, StripSignals > Sensor
Signals of u- and v- strips in one sensor.
Definition: SVDDigitizerModule.h:46
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::Unit::ns
static const double ns
Standard of [time].
Definition: Unit.h:58
Belle2::StoreArray::registerRelationTo
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:150
Belle2::SVD::SVDDigitizerModule::m_roundZS
bool m_roundZS
Round ZS cut to nearest ADU.
Definition: SVDDigitizerModule.h:144
Belle2::SVD::SVDDigitizerModule::m_interstripCapacitanceV
double m_interstripCapacitanceV
The interstrip capacitanceV for the sensor.
Definition: SVDDigitizerModule.h:215
Belle2::RelationIndex::getFirstElementTo
const Element * getFirstElementTo(const TO &to) const
Return a pointer to the first relation Element of the given object.
Definition: RelationIndex.h:222
Belle2::SVD::SVDDigitizerModule::m_currentSensorInfo
const SensorInfo * m_currentSensorInfo
Pointer to the SensorInfo of the current sensor.
Definition: SVDDigitizerModule.h:197
Belle2::SVDModeByte::getTriggerBin
baseType getTriggerBin() const
Get the triggerBin id.
Definition: SVDModeByte.h:150
Belle2::Module::setDescription
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:216
Belle2::SVD::SVDDigitizerModule::m_histDriftTime_e
TH1D * m_histDriftTime_e
Histogram showing the drift time of e.
Definition: SVDDigitizerModule.h:254
Belle2::SVD::SVDDigitizerModule::saveWaveforms
void saveWaveforms()
Save waveforms to the statistics file.
Definition: SVDDigitizerModule.cc:851
Belle2::VXD::GeoCache::get
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:141
Belle2::SVD::SVDDigitizerModule::event
virtual void event() override
Digitize one event.
Definition: SVDDigitizerModule.cc:285
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Module::c_ParallelProcessingCertified
@ 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:82
Belle2::SVD::SVDDigitizerModule::m_rootFilename
std::string m_rootFilename
Name of the ROOT filename to output statistics.
Definition: SVDDigitizerModule.h:177
Belle2::SVD::SVDDigitizerModule::m_samplingTime
double m_samplingTime
Interval between two waveform samples (30 ns).
Definition: SVDDigitizerModule.h:154
Belle2::SVD::SVDDigitizerModule::m_relShaperDigitTrueHitName
std::string m_relShaperDigitTrueHitName
Name of the relation between SVDShaperDigits and SVDTrueHits.
Definition: SVDDigitizerModule.h:126
Belle2::SVD::SVDDigitizerModule::m_randomizeEventTimes
bool m_randomizeEventTimes
Randomize event times? If set to true, event times will be randomized uniformly from m_minTimeFrame t...
Definition: SVDDigitizerModule.h:159
Belle2::SVD::SVDDigitizerModule::m_histLorentz_u
TH1D * m_histLorentz_u
Histogram showing the Lorentz angles in u (r-phi).
Definition: SVDDigitizerModule.h:259
Belle2::RelationIndexContainer::Element::indexFrom
RelationElement::index_type indexFrom
index of the element from which the relation points.
Definition: RelationIndexContainer.h:70
Belle2::Const::kBoltzmann
static const double kBoltzmann
Boltzmann constant in GeV/K.
Definition: Const.h:569
Belle2::SVD::SensorInfo::getBackplaneCapacitanceV
double getBackplaneCapacitanceV(int vID=0) const
Return the backplane capacitanceV for the sensor's v strips (short).
Definition: SensorInfo.h:320
Belle2::RelationIndex
Provides access to fast ( O(log n) ) bi-directional lookups on a specified relation.
Definition: RelationIndex.h:84
Belle2::SVD::SVDDigitizerModule::m_signalDist_u
TH1D * m_signalDist_u
Histogram showing the distribution of digit signals in u (r-phi).
Definition: SVDDigitizerModule.h:263
Belle2::SVD::SensorInfo::getCouplingCapacitanceU
double getCouplingCapacitanceU(int uID=0) const
Return the coupling capacitanceU of the sensor's u strips (long)
Definition: SensorInfo.h:315
Belle2::SVD::SVDDigitizerModule::m_interstripCapacitanceU
double m_interstripCapacitanceU
The interstrip capacitanceU for the sensor.
Definition: SVDDigitizerModule.h:209
Belle2::SVD::SVDDigitizerModule::m_waveTree
TTree * m_waveTree
Tree for waveform storage.
Definition: SVDDigitizerModule.h:267
Belle2::VXDSimHit::getElectrons
float getElectrons() const
Return the number of created electrons.
Definition: VXDSimhit.cc:17
Belle2::SVDModeByte
Class to store SVD mode information.
Definition: SVDModeByte.h:79
Belle2::SVD::SVDDigitizerModule::saveDigits
void saveDigits()
Save digits to the DataStore Saves samples of generated waveforms.
Definition: SVDDigitizerModule.cc:649
Belle2::SVD::SensorInfo
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
Definition: SensorInfo.h:35
Belle2::SVD::SVDDigitizerModule::m_noiseFraction
double m_noiseFraction
(derived from SNAdjacent) Fraction of noisy strips per sensor.
Definition: SVDDigitizerModule.h:148
Belle2::SVD::SVDDigitizerModule::driftCharge
void driftCharge(const TVector3 &position, double carriers, SVD::SensorInfo::CarrierType carrierType)
Drift the charge inside the silicon.
Definition: SVDDigitizerModule.cc:445
Belle2::SVDModeByte::getDAQMode
baseType getDAQMode() const
Get the daqMode id.
Definition: SVDModeByte.h:152
Belle2::VXD::GeoCache::getLayers
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
Definition: GeoCache.cc:177
Belle2::VXD::SensorInfoBase::getWidth
double getWidth(double v=0) const
Return the width of the sensor.
Definition: SensorInfoBase.h:91
Belle2::VXD::SensorInfoBase::getID
VxdID getID() const
Return the ID of the Sensor.
Definition: SensorInfoBase.h:85
Belle2::SVD::SVDDigitizerModule::m_rootFile
TFile * m_rootFile
Pointer to the ROOT filename for statistics.
Definition: SVDDigitizerModule.h:235
Belle2::SVD::SVDDigitizerModule::m_relTrueHitSimHitName
std::string m_relTrueHitSimHitName
Name of the relation between SVDTrueHits and SVDSimHits.
Definition: SVDDigitizerModule.h:120
Belle2::SVD::SVDDigitizerModule::m_sensorThickness
double m_sensorThickness
Thickness of current sensor (read from m_currentSensorInfo).
Definition: SVDDigitizerModule.h:201
Belle2::SVD::SVDDigitizerModule::m_currentEventTime
float m_currentEventTime
Current event time.
Definition: SVDDigitizerModule.h:167
Belle2::SVD::SVDDigitizerModule::m_svdEventInfoName
std::string m_svdEventInfoName
Name of the SVDEventInfo object.
Definition: SVDDigitizerModule.h:128
Belle2::SVD::SVDDigitizerModule::m_storeSimHitsName
std::string m_storeSimHitsName
Name of the collection for the SVDSimhits.
Definition: SVDDigitizerModule.h:114
Belle2::VXD::SensorInfoBase::getVPitch
double getVPitch(double v=0) const
Return the pitch of the sensor.
Definition: SensorInfoBase.h:150
Belle2::SVD::StripSignals
std::map< short int, SVDSignal > StripSignals
Map of all signals in one sensor.
Definition: SVDDigitizerModule.h:43
Belle2::SVDShaperDigit
The SVD ShaperDigit class.
Definition: SVDShaperDigit.h:46
Belle2::VXD::GeoCache::getSensors
const std::set< Belle2::VxdID > & getSensors(Belle2::VxdID ladder) const
Return a set of all sensor IDs belonging to a given ladder.
Definition: GeoCache.cc:205
Belle2::SVD::SVDDigitizerModule::m_histDriftTime_h
TH1D * m_histDriftTime_h
Histogram showing the drift time of h.
Definition: SVDDigitizerModule.h:256
Belle2::SVD::SVDDigitizerModule::m_MaskedStr
SVDFADCMaskedStrips m_MaskedStr
FADC masked strip payload.
Definition: SVDDigitizerModule.h:228
Belle2::SVD::SensorInfo::getInterstripCapacitanceV
double getInterstripCapacitanceV(int vID=0) const
Return the interstrip capacitanceV for the sensor's v strips (short).
Definition: SensorInfo.h:325
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::SVD::SVDDigitizerModule::m_elNoiseV
double m_elNoiseV
Electronic noise for v-strips.
Definition: SVDDigitizerModule.h:225
Belle2::RelationIndexContainer::Element
Element type for the index.
Definition: RelationIndexContainer.h:62
Belle2::Module::setPropertyFlags
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:210
Belle2::SVD::SVDDigitizerModule::m_elNoiseU
double m_elNoiseU
ADU equivalent charge for u-strips.
Definition: SVDDigitizerModule.h:223
Belle2::SVD::SVDDigitizerModule::m_histLorentz_v
TH1D * m_histLorentz_v
Histogram showing the Lorentz angles in v (z).
Definition: SVDDigitizerModule.h:261
Belle2::VXD::SensorInfoBase::getLength
double getLength() const
Return the length of the sensor.
Definition: SensorInfoBase.h:116
Belle2::SVD::SVDDigitizerModule::m_xmlFileName
static std::string m_xmlFileName
< channel mapping xml filename
Definition: SVDDigitizerModule.h:229
Belle2::VXDSimHit::getPosOut
TVector3 getPosOut() const
Return the end point of the electron deposition in local coordinates.
Definition: VXDSimHit.h:74
Belle2::SVD::SVDDigitizerModule::m_storeShaperDigitsName
std::string m_storeShaperDigitsName
Name of the collection for the SVDShaperDigits.
Definition: SVDDigitizerModule.h:122
Belle2::SVD::SVDDigitizerModule::m_histMobility_e
TH1D * m_histMobility_e
Histogram showing the mobility of e-.
Definition: SVDDigitizerModule.h:242
Belle2::SVD::SVDDigitizerModule::m_couplingCapacitanceU
double m_couplingCapacitanceU
The coupling capacitanceU for the sensor.
Definition: SVDDigitizerModule.h:211
Belle2::SVD::SVDDigitizerModule::initialize
virtual void initialize() override
Initialize the module and check module parameters.
Definition: SVDDigitizerModule.cc:123
Belle2::VXD::GeoCache::getInstance
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:215
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::VXD::SensorInfoBase::getThickness
double getThickness() const
Return the thickness of the sensor.
Definition: SensorInfoBase.h:121
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::SVD::SVDDigitizerModule::m_histChargeSharing_v
TH1D * m_histChargeSharing_v
Histogram showing the charge sharing + diffusion in v (z).
Definition: SVDDigitizerModule.h:239
Belle2::SVD::SensorInfo::getBackplaneCapacitanceU
double getBackplaneCapacitanceU(int uID=0) const
Return the backplane capacitanceU for the sensor's u strips (long).
Definition: SensorInfo.h:305
Belle2::VXDSimHit::getPosIn
TVector3 getPosIn() const
Return the start point of the electron deposition in local coordinates.
Definition: VXDSimHit.h:72
Belle2::SVD
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
Definition: GeoSVDCreator.h:35
Belle2::SVD::SVDDigitizerModule::m_storeMCParticlesName
std::string m_storeMCParticlesName
Name of the collection for the MCParticles.
Definition: SVDDigitizerModule.h:112
Belle2::RelationArray::add
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
Definition: RelationArray.h:291
Belle2::SVD::SVDDigitizerModule::m_currentHit
const SVDSimHit * m_currentHit
Pointer to the SVDSimhit currently digitized.
Definition: SVDDigitizerModule.h:189
Belle2::SVD::SVDDigitizerModule::m_histDistanceToPlane_e
TH1D * m_histDistanceToPlane_e
Histogram showing the distance to plane for e.
Definition: SVDDigitizerModule.h:250
Belle2::SVD::SVDDigitizerModule::beginRun
virtual void beginRun() override
Initialize the list of existing SVD Sensors.
Definition: SVDDigitizerModule.cc:260
Belle2::VXDSimHit::getGlobalTime
float getGlobalTime() const override
Return the time of the electron deposition.
Definition: VXDSimHit.h:80
Belle2::SVD::SensorInfo::getCouplingCapacitanceV
double getCouplingCapacitanceV(int vID=0) const
Return the coupling capacitanceV of the sensor's v strips (short).
Definition: SensorInfo.h:330
Belle2::VXD::SensorInfoBase::SVD
@ SVD
SVD Sensor.
Definition: SensorInfoBase.h:45
Belle2::SVD::SVDDigitizerModule::m_signalsList
std::string m_signalsList
Name of the tab-delimited listing of signals.
Definition: SVDDigitizerModule.h:181
Belle2::VXDSimHit::getSensorID
VxdID getSensorID() const
Return the sensorID of the sensor the electron was deposited in.
Definition: VXDSimHit.h:68
Belle2::SVD::SVDDigitizerModule::m_startSampling
double m_startSampling
Time window start.
Definition: SVDDigitizerModule.h:173
Belle2::BackgroundMetaData::bg_none
@ bg_none
No background.
Definition: BackgroundMetaData.h:41
Belle2::VXD::SensorInfoBase::getUPitch
double getUPitch(double v=0) const
Return the pitch of the sensor.
Definition: SensorInfoBase.h:143
Belle2::SVD::SVDDigitizerModule::m_currentSensor
Sensor * m_currentSensor
Pointer to the sensor in which the current hit occurred.
Definition: SVDDigitizerModule.h:195
Belle2::SVD::SVDDigitizerModule::m_SNAdjacent
double m_SNAdjacent
Zero-suppression cut.
Definition: SVDDigitizerModule.h:142
Belle2::SVD::SVDDigitizerModule::m_signalDist_v
TH1D * m_signalDist_v
Histogram showing the distribution of digit signals in v (z).
Definition: SVDDigitizerModule.h:265
Belle2::SVD::SVDDigitizerModule::m_currentParticle
int m_currentParticle
Index of the particle which caused the current hit.
Definition: SVDDigitizerModule.h:191
Belle2::SVD::SVDDigitizerModule::m_histMobility_h
TH1D * m_histMobility_h
Histogram showing the mobility of h.
Definition: SVDDigitizerModule.h:244
Belle2::SVD::SensorInfo::hole
@ hole
electrons
Definition: SensorInfo.h:50
Belle2::DataStore::relationName
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition: DataStore.h:182
Belle2::SVD::SensorInfo::getBiasVoltage
double getBiasVoltage() const
Return the bias voltage on the sensor.
Definition: SensorInfo.h:162
Belle2::Module::addParam
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:562
Belle2::Unit::mm
static const double mm
[millimeters]
Definition: Unit.h:80
Belle2::VXD::GeoCache
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:41
Belle2::SVD::SVDDigitizerModule::m_histVelocity_h
TH1D * m_histVelocity_h
Histogram showing the velocity of h.
Definition: SVDDigitizerModule.h:248
Belle2::SVD::SVDDigitizerModule::m_shapingTime
double m_shapingTime
Shaping time of the APV25 shapers.
Definition: SVDDigitizerModule.h:152
Belle2::SVDShaperDigit::c_nAPVSamples
static const std::size_t c_nAPVSamples
Number of APV samples stored.
Definition: SVDShaperDigit.h:51
Belle2::SVD::SVDDigitizerModule::m_maxTimeFrame
float m_maxTimeFrame
High edge of randomization time frame.
Definition: SVDDigitizerModule.h:163
Belle2::SVD::SVDDigitizerModule::m_currentTrueHit
int m_currentTrueHit
Index of the TrueHit the current hit belongs to.
Definition: SVDDigitizerModule.h:193
Belle2::SimHitBase::getBackgroundTag
virtual unsigned short getBackgroundTag() const
Get background tag.
Definition: SimHitBase.h:56
Belle2::SVDShaperDigit::APVRawSamples
std::array< APVRawSampleType, c_nAPVSamples > APVRawSamples
array of APVRawSamplesType objects
Definition: SVDShaperDigit.h:58
Belle2::SVD::SVDDigitizerModule::m_nSamplesOverZS
unsigned short m_nSamplesOverZS
Keek digit if at least m_nSamplesOverZS are over threshold.
Definition: SVDDigitizerModule.h:146
Belle2::SVD::SVDDigitizerModule::m_histVelocity_e
TH1D * m_histVelocity_e
Histogram showing the velocity of e-.
Definition: SVDDigitizerModule.h:246
Belle2::SVD::SensorInfo::getElectronicNoiseV
double getElectronicNoiseV() const
Return electronic noise in e- for v (short) strips.
Definition: SensorInfo.h:359
Belle2::SVD::SVDDigitizerModule::m_biasVoltage
double m_biasVoltage
The bias voltage on the sensor.
Definition: SVDDigitizerModule.h:205
Belle2::SVD::SensorInfo::getDepletionVoltage
double getDepletionVoltage() const
Return the depletion voltage of the sensor.
Definition: SensorInfo.h:160
Belle2::SVDFADCMaskedStrips::isValid
bool isValid()
returns true if the m_aDBObtPtr is valid in the requested IoV
Definition: SVDFADCMaskedStrips.h:84
Belle2::SVD::SVDSignal::relations_map
std::map< RelationElement::index_type, RelationElement::weight_type > relations_map
Type to store contributions to strip signal by different particles on output of SVDSignal.
Definition: SVDSignal.h:92
Belle2::StoreArray< MCParticle >
Belle2::SVD::SVDDigitizerModule::m_applyNoise
bool m_applyNoise
Whether or not to apply Gaussian noise.
Definition: SVDDigitizerModule.h:140
Belle2::SVD::SVDDigitizerModule::m_minTimeFrame
float m_minTimeFrame
Low edge of randomization time frame.
Definition: SVDDigitizerModule.h:161
Belle2::VXDSimHit::getPDGcode
int getPDGcode() const
Return the PDG code of the particle causing the electron deposition.
Definition: VXDSimHit.h:70
Belle2::VXDSimHit::getElectronsConstantDistance
std::vector< std::pair< float, float > > getElectronsConstantDistance(double length) const
Get the electron deposition along constant stepsize.
Definition: VXDSimhit.cc:34
Belle2::VXD::GeoCache::getLadders
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
Definition: GeoCache.cc:194
Belle2::Unit::e
static const double e
Standard of [electric charge].
Definition: Unit.h:63
Belle2::SVD::SensorInfo::CarrierType
CarrierType
Enum to flag charge carriers.
Definition: SensorInfo.h:48
Belle2::SVD::SVDDigitizerModule::processHit
void processHit()
Process one SVDSimHit by dividing the step in smaller steps and drifting the charge.
Definition: SVDDigitizerModule.cc:406
Belle2::SVD::SVDDigitizerModule::m_storeTrueHitsName
std::string m_storeTrueHitsName
Name of the collection for the SVDTrueHits.
Definition: SVDDigitizerModule.h:116
Belle2::StoreArray::getEntries
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:226
Belle2::SVD::SVDDigitizerModule::terminate
virtual void terminate() override
Terminate the module.
Definition: SVDDigitizerModule.cc:941
Belle2::SVD::SVDSignal
The SVD signal class.
Definition: SVDSignal.h:52
Belle2::SVD::SVDDigitizerModule::m_histChargeSharing_u
TH1D * m_histChargeSharing_u
Histogram showing the charge sharing + diffusion in u (r-phi).
Definition: SVDDigitizerModule.h:237
Belle2::SVD::SensorInfo::getElectronicNoiseU
double getElectronicNoiseU() const
Return electronic noise in e- for u (long) strips.
Definition: SensorInfo.h:351
Belle2::SVD::SVDDigitizerModule::m_widthOfDiffusCloud
double m_widthOfDiffusCloud
Width of diffusion cloud for simple drift model (in sigmas)
Definition: SVDDigitizerModule.h:134
Belle2::SVD::SVDDigitizerModule::m_couplingCapacitanceV
double m_couplingCapacitanceV
The coupling capacitanceV for the sensor.
Definition: SVDDigitizerModule.h:217
Belle2::SVD::SensorInfo::getInterstripCapacitanceU
double getInterstripCapacitanceU(int uID=0) const
Return the interstrip capacitanceU for the sensor's u strips (long).
Definition: SensorInfo.h:310
Belle2::Unit::um
static const double um
[micrometers]
Definition: Unit.h:81
Belle2::SVD::SVDDigitizerModule::m_depletionVoltage
double m_depletionVoltage
The depletion voltage of the Silicon sensor.
Definition: SVDDigitizerModule.h:203