9 #include <svd/modules/svdSimulation/SVDDigitizerModule.h>
10 #include <vxd/geometry/GeoCache.h>
12 #include <framework/dataobjects/EventMetaData.h>
13 #include <framework/logging/Logger.h>
14 #include <framework/gearbox/Unit.h>
15 #include <framework/gearbox/Const.h>
16 #include <framework/datastore/DataStore.h>
17 #include <framework/datastore/StoreArray.h>
18 #include <framework/datastore/StoreObjPtr.h>
19 #include <framework/datastore/RelationArray.h>
20 #include <framework/datastore/RelationIndex.h>
21 #include <mdst/dataobjects/MCParticle.h>
22 #include <svd/dataobjects/SVDTrueHit.h>
23 #include <svd/dataobjects/SVDShaperDigit.h>
24 #include <svd/dataobjects/SVDEventInfo.h>
31 #include <root/TMath.h>
32 #include <root/TRandom.h>
46 double tree_signal[20];
58 SVDDigitizerModule::SVDDigitizerModule() :
Module(),
59 m_currentSensorWaveforms(nullptr),
60 m_mapping(m_xmlFileName)
86 "Zero suppression cut in sigmas of strip noise",
m_SNAdjacent);
88 "FADC mode: if True, ZS cut is rounded to nearest ADU ",
m_roundZS);
90 "Keep digit if numberOfSamples or more samples are over ZS threshold",
99 "Interval between ADC samples in ns, if = -1 taken from HardwareClockSettings payload (default).",
m_samplingTime);
101 "Start of the sampling window, in ns. Used to tune the SVD latency.",
m_startSampling);
105 "Left edge of event time randomization window, ns",
m_minTimeFrame);
107 "Right edge of event time randomization window, ns",
m_maxTimeFrame);
112 "ROOT Filename for statistics generation. If filename is empty, no statistics will be produced",
117 "Store signals (time/charge/tau) in a tab-delimited file",
162 "SVDDigitizer parameters (in default system units, *=cannot be set directly):");
163 B2DEBUG(29,
" DATASTORE COLLECTIONS:");
176 B2DEBUG(29,
" PHYSICS: ");
178 B2DEBUG(29,
" NOISE: ");
179 B2DEBUG(29,
" --> Add Poisson noise " << (
m_applyPoisson ?
"true" :
"false"));
180 B2DEBUG(29,
" --> Zero suppression cut" <<
m_SNAdjacent);
181 B2DEBUG(29,
" --> Round ZS cut: " << (
m_roundZS ?
"true" :
"false"));
184 B2DEBUG(29,
" TIMING: ");
188 B2DEBUG(29,
" REPORTING: ");
200 " 'Diffusion' distance, u", 100, -200, 200);
206 "Lorentz angle, electrons", 100, -0.002, 0.002);
209 "Strip signals vs. TrueHits, holes", 100, -400, 400);
210 m_signalDist_u->GetXaxis()->SetTitle(
"U strip position - TrueHit u [um]");
212 "Strip signals vs. TrueHits, electrons", 100, -400, 400);
213 m_signalDist_v->GetXaxis()->SetTitle(
"V strip position - TrueHit v [um]");
234 30, -0.002, -0.0004);
248 200, -100, 100, 4, -0.5, 3.5);
253 m_waveTree =
new TTree(
"waveTree",
"SVD waveforms");
254 m_waveTree->Branch(
"sensor", &tree_vxdID,
"sensor/I");
255 m_waveTree->Branch(
"u_or_v", &tree_uv,
"u_or_v/I");
256 m_waveTree->Branch(
"strip", &tree_strip,
"strip/I");
257 m_waveTree->Branch(
"signal", tree_signal,
"signal[20]/D");
290 B2WARNING(
"No valid SVDFADCMaskedStrip for the requested IoV -> no strips masked");
292 B2WARNING(
"No valid channel mapping -> all APVs will be enabled");
302 SVDModeByte modeByte = storeSVDEvtInfo->getModeByte();
307 const double systemClockPeriod = 1. /
m_hwClock->getGlobalClockFrequency();
332 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
333 sensorWaveforms.second.first.clear();
334 sensorWaveforms.second.second.clear();
349 unsigned int nSimHits = storeSimHits.
getEntries();
355 for (
unsigned int i = 0; i < nSimHits; ++i) {
371 "Could not find MCParticle which produced SVDSimhit " << i);
377 if (trueRel && trueRel->
weight > 0) {
389 "Sensor Information for Sensor " << sensorID <<
" not found, make sure that the geometry is set up correctly");
396 "Sensor Parameters for Sensor " << sensorID <<
": " << endl
409 "Processing hit " << i <<
" in Sensor " << sensorID <<
", related to MCParticle " <<
m_currentParticle);
435 ROOT::Math::XYZVector direction = stopPoint - startPoint;
436 double trackLength = direction.R();
446 double lastFraction {0};
447 double lastElectrons {0};
449 for (
auto& segment : segments) {
452 const double f = (segment.first + lastFraction) / 2;
453 const double e = segment.second - lastElectrons;
455 std::tie(lastFraction, lastElectrons) = segment;
458 const ROOT::Math::XYZVector position = startPoint + f * direction;
459 driftCharge(position, e, SVD::SensorInfo::electron);
469 bool have_electrons = (carrierType == SVD::SensorInfo::electron);
471 string carrierName = (have_electrons) ?
"electron" :
"hole";
473 "Drifting " << carriers <<
" " << carrierName <<
"s at position (" << position.X() <<
", " << position.Y() <<
", " << position.Z()
475 B2DEBUG(29,
"@@@ driftCharge: drifting " << carriers <<
" " << carrierName <<
"s at position (" << position.X() <<
", " <<
476 position.Y() <<
", " << position.Z()
483 double distanceToPlane = (have_electrons) ?
492 ROOT::Math::XYZVector mean_pos(position.X(), position.Y(), position.Z() + 0.5 * distanceToPlane);
495 ROOT::Math::XYZVector v = info.getVelocity(carrierType, mean_pos);
499 double driftTime = distanceToPlane / v.Z();
503 ROOT::Math::XYZVector center = position + driftTime * v;
504 double mobility = (have_electrons) ?
505 info.getElectronMobility(info.getEField(mean_pos).R()) :
506 info.getHoleMobility(info.getEField(mean_pos).R());
512 double sigma = std::max(1.0e-4,
sqrt(2.0 * D * driftTime));
513 double tanLorentz = (!have_electrons) ? v.X() / v.Z() : v.Y() / v.Z();
516 B2DEBUG(29,
"D = " << D <<
", driftTime = " << driftTime /
Unit::ns <<
" ns");
517 B2DEBUG(29,
"sigma = " << sigma /
Unit::um <<
" um");
518 B2DEBUG(29,
"tan Lorentz = " << tanLorentz);
520 sigma *=
sqrt(1.0 + tanLorentz * tanLorentz);
525 int vID = info.getVCellID(center.Y(),
true);
526 int uID = info.getUCellID(center.X(), center.Y(),
true);
527 int seedStrip = (!have_electrons) ? uID : vID;
528 double seedPos = (!have_electrons) ?
529 info.getUCellPosition(seedStrip, vID) :
530 info.getVCellPosition(seedStrip);
531 double geomPitch = (!have_electrons) ? 0.5 * info.getUPitch(center.Y()) : 0.5 * info.getVPitch();
532 int nCells = (!have_electrons) ? info.getUCells() : info.getVCells();
533 std::deque<double> stripCharges;
534 std::deque<double> strips;
535 #define NORMAL_CDF(z) 0.5 * std::erfc( - (z) * 0.707107)
536 double current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
537 double current_strip = seedStrip;
538 double cdf_low = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
539 double cdf_high = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
540 double charge = carriers * (cdf_high - cdf_low);
542 B2DEBUG(29,
"geomPitch = " << geomPitch /
Unit::um <<
" um");
543 B2DEBUG(29,
"charge = " << charge <<
" = " << carriers <<
"(carriers) * (" << cdf_high <<
"(cdf_high) - " << cdf_low <<
546 stripCharges.push_back(charge);
547 strips.push_back(current_strip);
548 while (cdf_low > 1.0e-5) {
549 current_pos -= geomPitch;
550 current_strip -= 0.5;
551 double cdf_current = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
552 charge = carriers * (cdf_low - cdf_current);
553 stripCharges.push_front(charge);
554 strips.push_front(current_strip);
555 cdf_low = cdf_current;
557 current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
558 current_strip = seedStrip;
559 while (cdf_high < 1.0 - 1.0e-5) {
560 current_pos += geomPitch;
561 current_strip += 0.5;
562 double cdf_current = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
563 charge = carriers * (cdf_current - cdf_high);
564 stripCharges.push_back(charge);
565 strips.push_back(current_strip);
566 cdf_high = cdf_current;
571 int npads = (strips.front() - floor(strips.front()) == 0) ? 5 : 4;
572 for (
int i = 0; i < npads; ++i) {
573 strips.push_front(strips.front() - 0.5);
574 stripCharges.push_front(0);
576 npads = (strips.back() - floor(strips.back()) == 0) ? 5 : 4;
577 for (
int i = 0; i < npads; ++i) {
578 strips.push_back(strips.back() + 0.5);
579 stripCharges.push_back(0);
582 B2DEBUG(29,
" --> charge sharing simulation, # strips = " << strips.size());
583 std::deque<double> readoutCharges;
584 std::deque<int> readoutStrips;
586 for (std::size_t index = 3; index < strips.size() - 3; index += 2) {
587 B2DEBUG(29,
" index = " << index <<
", strip = " << strips[index] <<
", stripCharge = " << stripCharges[index]);
588 int currentStrip =
static_cast<int>(strips[index]);
595 B2DEBUG(29,
" current strip = " << currentStrip);
596 B2DEBUG(29,
" index-3 = " << index - 3 <<
", strip = " << strips[index - 3] <<
", stripCharge = " << stripCharges[index - 3]);
597 B2DEBUG(29,
" index-2 = " << index - 2 <<
", strip = " << strips[index - 2] <<
", stripCharge = " << stripCharges[index - 2]);
598 B2DEBUG(29,
" index-1 = " << index - 1 <<
", strip = " << strips[index - 1] <<
", stripCharge = " << stripCharges[index - 1]);
599 B2DEBUG(29,
" index = " << index <<
", strip = " << strips[index] <<
", stripCharge = " << stripCharges[index]);
600 B2DEBUG(29,
" index+1 = " << index + 1 <<
", strip = " << strips[index + 1] <<
", stripCharge = " << stripCharges[index + 1]);
601 B2DEBUG(29,
" index+2 = " << index + 2 <<
", strip = " << strips[index + 2] <<
", stripCharge = " << stripCharges[index + 2]);
602 B2DEBUG(29,
" index+3 = " << index + 3 <<
", strip = " << strips[index + 3] <<
", stripCharge = " << stripCharges[index + 3]);
604 readoutCharges.push_back(c3 * stripCharges[index - 3]
605 + c2 * stripCharges[index - 2]
606 + c1 * stripCharges[index - 1]
607 + c0 * stripCharges[index]
608 + c1 * stripCharges[index + 1]
609 + c2 * stripCharges[index + 2]
610 + c3 * stripCharges[index + 3]
612 readoutStrips.push_back(currentStrip);
613 B2DEBUG(29,
" post simulation: " << index <<
", strip = " << currentStrip <<
", readoutCharge = " <<
614 readoutCharges[readoutCharges.size() - 1]);
618 while (readoutStrips.size() > 0 && readoutStrips.front() < 0) {
619 readoutStrips.pop_front();
620 tail += readoutCharges.front();
621 readoutCharges.pop_front();
623 readoutCharges.front() += tail;
625 while (readoutStrips.size() > 0 && readoutStrips.back() > nCells - 1) {
626 readoutStrips.pop_back();
627 tail += readoutCharges.back();
628 readoutCharges.pop_back();
630 readoutCharges.back() += tail;
633 for (
auto& c : readoutCharges)
634 c = (c <= 0) ? 0 : std::max(0.0, gRandom->Gaus(c,
std::sqrt(info.c_fanoFactorSi * c)));
639 double d = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
640 for (std::size_t index = 0; index < readoutStrips.size(); ++ index) {
641 double dist = d + (readoutStrips[index] - seedStrip) * 2 * geomPitch;
642 histo->Fill(dist /
Unit::um, readoutCharges[index]);
648 SVDModeByte modeByte = storeSVDEvtInfo->getModeByte();
663 double recoveredCharge = 0;
664 for (std::size_t index = 0; index < readoutStrips.size(); index ++) {
667 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, readoutCharges[index],
671 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, apvCoupling * readoutCharges[index - 1],
674 if (index < readoutStrips.size() - 1)
675 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, apvCoupling * readoutCharges[index + 1],
677 recoveredCharge += readoutCharges[index];
678 B2DEBUG(29,
"strip: " << readoutStrips[index] <<
" charge: " << readoutCharges[index]);
680 B2DEBUG(29,
"Digitized " << recoveredCharge <<
" of " << carriers <<
" original carriers.");
685 charge += gRandom->Gaus(0., noise);
695 RelationArray relShaperDigitMCParticle(storeShaperDigits, storeMCParticles,
697 RelationArray relShaperDigitTrueHit(storeShaperDigits, storeTrueHits,
706 vector<pair<unsigned int, float> > digit_weights;
709 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
710 int sensorID = sensorWaveforms.first;
714 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
715 short int iStrip = stripWaveform.first;
718 vector<double> samples;
720 digit_weights.clear();
728 B2DEBUG(25,
"start sampling at " <<
m_initTime);
730 samples.push_back(
addNoise(electronWeight * s(t), elNoise));
741 std::transform(samples.begin(), samples.end(), rawSamples.begin(),
742 [&](
double x)->SVDShaperDigit::APVRawSampleType {
743 return SVDShaperDigit::trimToSampleRange(x * gain);
748 if (
m_roundZS) rawThreshold = round(rawThreshold);
749 auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
750 std::bind2nd(std::greater<double>(), rawThreshold)
758 if (!
m_map->isAPVinMap(sensorID,
true, iStrip))
continue;
769 n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
770 std::bind2nd(std::greater<double>(), rawThreshold)
777 int digIndex = storeShaperDigits.
getEntries();
778 storeShaperDigits.
appendNew(sensorID,
true, iStrip, rawSamples, 0);
781 if (particles.size() > 0) {
782 relShaperDigitMCParticle.
add(digIndex, particles.begin(), particles.end());
785 if (truehits.size() > 0) {
786 relShaperDigitTrueHit.
add(digIndex, truehits.begin(), truehits.end());
794 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
795 short int iStrip = stripWaveform.first;
798 vector<double> samples;
800 digit_weights.clear();
809 samples.push_back(
addNoise(electronWeight * s(t), elNoise));
819 std::transform(samples.begin(), samples.end(), rawSamples.begin(),
820 [&](
double x)->SVDShaperDigit::APVRawSampleType {
821 return SVDShaperDigit::trimToSampleRange(x * gain);
826 if (
m_roundZS) rawThreshold = round(rawThreshold);
827 auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
828 std::bind2nd(std::greater<double>(), rawThreshold)
836 if (!
m_map->isAPVinMap(sensorID,
false, iStrip))
continue;
847 n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
848 std::bind2nd(std::greater<double>(), rawThreshold)
854 int digIndex = storeShaperDigits.
getEntries();
855 storeShaperDigits.
appendNew(sensorID,
false, iStrip, rawSamples, 0);
858 if (particles.size() > 0) {
859 relShaperDigitMCParticle.
add(digIndex, particles.begin(), particles.end());
862 if (truehits.size() > 0) {
863 relShaperDigitTrueHit.
add(digIndex, truehits.begin(), truehits.end());
871 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
872 tree_vxdID = sensorWaveforms.first;
877 double thresholdU = 3.0 * info.getElectronicNoiseU();
878 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
879 tree_strip = stripWaveform.first;
882 if (s.getCharge() < thresholdU)
884 for (
int iTime = 0; iTime < 20; ++iTime) {
885 tree_signal[iTime] = s(10 * iTime);
891 double thresholdV = 3.0 * info.getElectronicNoiseV();
892 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
893 tree_strip = stripWaveform.first;
896 if (s.getCharge() < thresholdV)
898 for (
int iTime = 0; iTime < 20; ++iTime) {
899 tree_signal[iTime] = s(10. * iTime);
909 static size_t recordNo = 0;
910 static const string header(
"Event\tSensor\tSide\tStrip\tContrib\tTime\tCharge\tTau");
911 regex startLine(
"^|\n");
913 if (recordNo == 0) outfile << header << endl;
914 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
915 VxdID sensorID(sensorWaveforms.first);
920 double thresholdU = 3.0 * info.getElectronicNoiseU();
921 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
922 size_t strip = stripWaveform.first;
925 if (s.getCharge() < thresholdU)
928 ostringstream preamble;
930 preamble <<
"$&" << recordNo <<
'\t' << sensorID <<
'\t' << isU <<
'\t' << strip <<
'\t';
931 string signalString = s.toString();
932 signalString.pop_back();
933 string tableString = regex_replace(signalString, startLine, preamble.str());
934 outfile << tableString << endl;
938 double thresholdV = 3.0 * info.getElectronicNoiseV();
939 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
940 size_t strip = stripWaveform.first;
943 if (s.getCharge() < thresholdV)
946 ostringstream preamble;
948 preamble <<
"$&" << recordNo <<
'\t' << sensorID <<
'\t' << isU <<
'\t' << strip <<
'\t';
949 string signalString = s.toString();
950 signalString.pop_back();
951 string tableString = regex_replace(signalString, startLine, preamble.str());
952 outfile << tableString << endl;
969 int nTriggerClocks = triggerBin + relativeShift;
970 return floor(nTriggerClocks / 4);
int getPDGCode() const
PDG code.
static const double kBoltzmann
Boltzmann constant in GeV/K.
static const ParticleType photon
photon particle
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
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.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
std::string getFileName() const
Get the name of the downloaded payload file.
Low-level class to create/modify relations between StoreArrays.
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
Provides access to fast ( O(log n) ) bi-directional lookups on a specified relation.
const Element * getFirstElementTo(const TO &to) const
Return a pointer to the first relation Element of the given object.
float getCouplingConstant(const VxdID &sensorID, const bool &isU, const std::string &couplingName) const
Return coupling constant.
float getElectronWeight(const VxdID &sensorID, const bool &isU) const
Return Geant4 electron weight.
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.
bool isValid()
returns true if the m_aDBObtPtr is valid in the requested IoV
Class to store SVD mode information.
baseType getTriggerBin() const
Get the triggerBin id.
float getNoiseInElectrons(const VxdID &sensorID, const bool &isU, const unsigned short &strip) const
This method provides the correct noise conversion into electrons, taking into account that the noise ...
double getChargeFromADC(const Belle2::VxdID &sensorID, const bool &isU, const unsigned short &strip, const double &pulseADC) const
Return the charge (number of electrons/holes) collected on a specific strip, given the number of ADC ...
static void setAPVMode(size_t mode, size_t firstSample)
set APV mode for the event
static const std::size_t c_nAPVSamples
Number of APV samples stored.
std::array< APVRawSampleType, c_nAPVSamples > APVRawSamples
array of APVRawSamplesType objects
double m_startSampling
Time window start, excluding trigger bin effect.
TH1D * m_histHitTime
Histogram showing the hit time.
TH1D * m_histDistanceToPlane_e
Histogram showing the distance to plane for e.
TH1D * m_histChargeSharing_u
Histogram showing the charge sharing + diffusion in u (r-phi).
double m_sensorThickness
Thickness of current sensor (read from m_currentSensorInfo).
void processHit()
Process one SVDSimHit by dividing the step in smaller steps and drifting the charge.
TH1D * m_histVelocity_h
Histogram showing the velocity of h.
SVDFADCMaskedStrips m_MaskedStr
FADC masked strip payload.
TH1D * m_histVelocity_e
Histogram showing the velocity of e-.
Waveforms m_waveforms
Structure containing waveforms in all existing sensors.
double m_samplingTime
Interval between two waveform samples, by default taken from HardwareClockSettings.
std::string m_relTrueHitSimHitName
Name of the relation between SVDTrueHits and SVDSimHits.
TH1D * m_histLorentz_v
Histogram showing the Lorentz angles in v (z).
void saveDigits()
Save digits to the DataStore Saves samples of generated waveforms.
bool m_randomizeEventTimes
Randomize event times? If set to true, event times will be randomized uniformly from m_minTimeFrame t...
int getFirstSample(int triggerBin, int relativShift)
return the starting sample
int m_startingSample
Starting sample for the selection of 3 samples in 3-mixed-6.
int m_currentParticle
Index of the particle which caused the current hit.
std::string m_relShaperDigitMCParticleName
Name of the relation between SVDShaperDigits and MCParticles.
int m_nSamplesOverZS
Keep digit if at least m_nSamplesOverZS are over threshold.
TH1D * m_histChargeSharing_v
Histogram showing the charge sharing + diffusion in v (z).
TH1D * m_histMobility_h
Histogram showing the mobility of h.
virtual void initialize() override
Initialize the module and check module parameters.
bool m_roundZS
Round ZS cut to nearest ADU.
std::string m_storeShaperDigitsName
Name of the collection for the SVDShaperDigits.
virtual void event() override
Digitize one event.
bool m_is3sampleEvent
True if the event should be simulated with 3 sample.
double m_SNAdjacent
Zero-suppression cut.
double m_currentTime
Time of the current SimHit.
TFile * m_rootFile
Pointer to the ROOT filename for statistics.
SVDNoiseCalibrations m_NoiseCal
SVDNoise calibrations db object.
SensorWaveforms * m_currentSensorWaveforms
Pointer to the sensor in which the current hit occurred.
std::string m_storeTrueHitsName
Name of the collection for the SVDTrueHits.
TH1D * m_signalDist_u
Histogram showing the distribution of digit signals in u (r-phi).
DBObjPtr< PayloadFile > m_mapping
channel mapping payload
virtual void terminate() override
Terminate the module.
void saveSignals()
Save signals to a root-delimited file (to be analyzed in Python).
std::string m_storeMCParticlesName
Name of the collection for the MCParticles.
TH1D * m_signalDist_v
Histogram showing the distribution of digit signals in v (z).
double m_noiseFraction
(derived from SNAdjacent) Fraction of noisy strips per sensor.
static std::string m_xmlFileName
< channel mapping xml filename
double m_betaPrimeDecayTimeU
Decay time of betaprime waveform U-side.
SVDPulseShapeCalibrations m_PulseShapeCal
SVDPulseShapeCalibrations calibrations db object.
TH1D * m_histMobility_e
Histogram showing the mobility of e-.
std::string m_relShaperDigitTrueHitName
Name of the relation between SVDShaperDigits and SVDTrueHits.
SVDChargeSimulationCalibrations m_ChargeSimCal
SVDChargeSimulationCalibrations calibrations db object.
int m_nAPV25Samples
number of digitized samples read from SVDEventInfo
TTree * m_waveTree
Tree for waveform storage.
bool m_applyPoisson
Whether or not to apply poisson fluctuation of charge (Fano factor)
virtual void beginRun() override
Initialize the list of existing SVD Sensors.
TH1D * m_histDistanceToPlane_h
Histogram showing the distance to plane for h.
TH1D * m_histDriftTime_e
Histogram showing the drift time of e.
DBObjPtr< HardwareClockSettings > m_hwClock
Hardware Clocks.
std::string m_svdEventInfoName
Name of the SVDEventInfo object.
std::string m_signalsList
Name of the tab-delimited listing of waveforms.
double addNoise(double charge, double noise)
Calculate the noise contribution to one strip with given charge.
const SensorInfo * m_currentSensorInfo
Pointer to the SensorInfo of the current sensor.
TH1D * m_histLorentz_u
Histogram showing the Lorentz angles in u (r-phi).
int m_relativeShift
relative shift in SVDEventInfo obj
TH2F * m_histHitTimeTB
Histogram showing the hit time vs TB.
bool m_storeWaveforms
Store waveform data in the reporting file?
void driftCharge(const ROOT::Math::XYZVector &position, double carriers, SVD::SensorInfo::CarrierType carrierType)
Drift the charge inside the silicon.
void saveWaveforms()
Save waveforms to the statistics file.
std::unique_ptr< SVDOnlineToOfflineMap > m_map
channel mapping map
float m_maxTimeFrame
High edge of randomization time frame.
TH1D * m_histDriftTime_h
Histogram showing the drift time of h.
double m_initTime
Time window start, including the triggerBin effect.
int m_currentTrueHit
Index of the TrueHit the current hit belongs to.
float m_minTimeFrame
Low edge of randomization time frame.
const SVDSimHit * m_currentHit
Pointer to the SVDSimhit currently digitized.
std::string m_relMCParticleSimHitName
Name of the relation between MCParticles and SVDSimHits.
double m_betaPrimeDecayTimeV
Decay time of betaprime waveform V-side.
double m_segmentLength
Max.
std::string m_rootFilename
Name of the ROOT filename to output statistics.
std::string m_storeSimHitsName
Name of the collection for the SVDSimhits.
float m_currentEventTime
Current event time.
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
CarrierType
Enum to flag charge carriers.
double getBiasVoltage() const
Return the bias voltage on the sensor.
double getDepletionVoltage() const
Return the depletion voltage of the sensor.
virtual unsigned short getBackgroundTag() const
Get background tag.
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.
int getEntries() const
Get the number of objects in the array.
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.
Type-safe access to single objects in the data store.
static const double mm
[millimeters]
static const double e
Standard of [electric charge].
static const double um
[micrometers]
static const double ns
Standard of [time].
float getGlobalTime() const override
Return the time of the electron deposition.
int getPDGcode() const
Return the PDG code of the particle causing the electron deposition.
ROOT::Math::XYZVector getPosOut() const
Return the end point of the electron deposition in local coordinates.
std::vector< std::pair< float, float > > getElectronsConstantDistance(double length) const
Get the electron deposition along constant stepsize.
float getElectrons() const
Return the number of created electrons.
ROOT::Math::XYZVector getPosIn() const
Return the start point of the electron deposition in local coordinates.
VxdID getSensorID() const
Return the sensorID of the sensor the electron was deposited in.
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
const std::set< Belle2::VxdID > & getSensors(Belle2::VxdID ladder) const
Return a set of all sensor IDs belonging to a given ladder.
static GeoCache & getInstance()
Return a reference to the singleton instance.
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
double getUPitch(double v=0) const
Return the pitch of the sensor.
double getWidth(double v=0) const
Return the width of the sensor.
VxdID getID() const
Return the ID of the Sensor.
double getVPitch(double v=0) const
Return the pitch of the sensor.
double getThickness() const
Return the thickness of the sensor.
double getLength() const
Return the length of the sensor.
Class to uniquely identify a any structure of the PXD and SVD.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
std::pair< StripWaveforms, StripWaveforms > SensorWaveforms
Waveforms of u- and v- channels in one sensor.
std::function< double(double)> WaveformShape
WaveformShape type.
double w_adjacentU(double t)
Adjacent-channel waveform U-side.
double w_betaprime(double t)
Beta-prime waveform shape, x^alpha/(1+x)^beta.
double w_adjacentV(double t)
Adjacent-channel waveform V-side.
std::map< short int, SVDWaveform > StripWaveforms
Map of all channels' waveforms in one sensor side.
Abstract base class for different kinds of events.
Element type for the index.
RelationElement::index_type indexFrom
index of the element from which the relation points.
RelationElement::weight_type weight
weight of the relation.