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>
35using namespace std::placeholders;
47double tree_signal[20];
87 "Zero suppression cut in sigmas of strip noise",
m_SNAdjacent);
89 "FADC mode: if True, ZS cut is rounded to nearest ADU ",
m_roundZS);
91 "Keep digit if numberOfSamples or more samples are over ZS threshold",
100 "Interval between ADC samples in ns, if = -1 taken from HardwareClockSettings payload (default).",
m_samplingTime);
102 "Start of the sampling window, in ns. Used to tune the SVD latency.",
m_startSampling);
106 "Left edge of event time randomization window, ns",
m_minTimeFrame);
108 "Right edge of event time randomization window, ns",
m_maxTimeFrame);
113 "ROOT Filename for statistics generation. If filename is empty, no statistics will be produced",
118 "Store signals (time/charge/tau) in a tab-delimited file",
163 "SVDDigitizer parameters (in default system units, *=cannot be set directly):");
164 B2DEBUG(29,
" DATASTORE COLLECTIONS:");
177 B2DEBUG(29,
" PHYSICS: ");
179 B2DEBUG(29,
" NOISE: ");
180 B2DEBUG(29,
" --> Add Poisson noise " << (
m_applyPoisson ?
"true" :
"false"));
181 B2DEBUG(29,
" --> Zero suppression cut" <<
m_SNAdjacent);
182 B2DEBUG(29,
" --> Round ZS cut: " << (
m_roundZS ?
"true" :
"false"));
185 B2DEBUG(29,
" TIMING: ");
189 B2DEBUG(29,
" REPORTING: ");
201 " 'Diffusion' distance, u", 100, -200, 200);
207 "Lorentz angle, electrons", 100, -0.002, 0.002);
210 "Strip signals vs. TrueHits, holes", 100, -400, 400);
211 m_signalDist_u->GetXaxis()->SetTitle(
"U strip position - TrueHit u [um]");
213 "Strip signals vs. TrueHits, electrons", 100, -400, 400);
214 m_signalDist_v->GetXaxis()->SetTitle(
"V strip position - TrueHit v [um]");
235 30, -0.002, -0.0004);
249 200, -100, 100, 4, -0.5, 3.5);
254 m_waveTree =
new TTree(
"waveTree",
"SVD waveforms");
255 m_waveTree->Branch(
"sensor", &tree_vxdID,
"sensor/I");
256 m_waveTree->Branch(
"u_or_v", &tree_uv,
"u_or_v/I");
257 m_waveTree->Branch(
"strip", &tree_strip,
"strip/I");
258 m_waveTree->Branch(
"signal", tree_signal,
"signal[20]/D");
291 B2WARNING(
"No valid SVDFADCMaskedStrip for the requested IoV -> no strips masked");
293 B2WARNING(
"No valid channel mapping -> all APVs will be enabled");
303 SVDModeByte modeByte = storeSVDEvtInfo->getModeByte();
308 const double systemClockPeriod = 1. /
m_hwClock->getGlobalClockFrequency();
333 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
334 sensorWaveforms.second.first.clear();
335 sensorWaveforms.second.second.clear();
350 unsigned int nSimHits = storeSimHits.
getEntries();
356 for (
unsigned int i = 0; i < nSimHits; ++i) {
372 "Could not find MCParticle which produced SVDSimhit " << i);
378 if (trueRel && trueRel->
weight > 0) {
390 "Sensor Information for Sensor " << sensorID <<
" not found, make sure that the geometry is set up correctly");
397 "Sensor Parameters for Sensor " << sensorID <<
": " << endl
410 "Processing hit " << i <<
" in Sensor " << sensorID <<
", related to MCParticle " <<
m_currentParticle);
434 const ROOT::Math::XYZVector& startPoint =
m_currentHit->getPosIn();
435 const ROOT::Math::XYZVector& stopPoint =
m_currentHit->getPosOut();
436 ROOT::Math::XYZVector direction = stopPoint - startPoint;
437 double trackLength = direction.R();
447 double lastFraction {0};
448 double lastElectrons {0};
450 for (
auto& segment : segments) {
453 const double f = (segment.first + lastFraction) / 2;
454 const double e = segment.second - lastElectrons;
456 std::tie(lastFraction, lastElectrons) = segment;
459 const ROOT::Math::XYZVector position = startPoint + f * direction;
460 driftCharge(position, e, SVD::SensorInfo::electron);
470 bool have_electrons = (carrierType == SVD::SensorInfo::electron);
472 string carrierName = (have_electrons) ?
"electron" :
"hole";
474 "Drifting " << carriers <<
" " << carrierName <<
"s at position (" << position.X() <<
", " << position.Y() <<
", " << position.Z()
476 B2DEBUG(29,
"@@@ driftCharge: drifting " << carriers <<
" " << carrierName <<
"s at position (" << position.X() <<
", " <<
477 position.Y() <<
", " << position.Z()
484 double distanceToPlane = (have_electrons) ?
493 ROOT::Math::XYZVector mean_pos(position.X(), position.Y(), position.Z() + 0.5 * distanceToPlane);
496 ROOT::Math::XYZVector v = info.getVelocity(carrierType, mean_pos);
500 double driftTime = distanceToPlane / v.Z();
504 ROOT::Math::XYZVector center = position + driftTime * v;
505 double mobility = (have_electrons) ?
506 info.getElectronMobility(info.getEField(mean_pos).R()) :
507 info.getHoleMobility(info.getEField(mean_pos).R());
513 double sigma = std::max(1.0e-4,
sqrt(2.0 * D * driftTime));
514 double tanLorentz = (!have_electrons) ? v.X() / v.Z() : v.Y() / v.Z();
517 B2DEBUG(29,
"D = " << D <<
", driftTime = " << driftTime /
Unit::ns <<
" ns");
518 B2DEBUG(29,
"sigma = " << sigma /
Unit::um <<
" um");
519 B2DEBUG(29,
"tan Lorentz = " << tanLorentz);
521 sigma *=
sqrt(1.0 + tanLorentz * tanLorentz);
526 int vID = info.getVCellID(center.Y(),
true);
527 int uID = info.getUCellID(center.X(), center.Y(),
true);
528 int seedStrip = (!have_electrons) ? uID : vID;
529 double seedPos = (!have_electrons) ?
530 info.getUCellPosition(seedStrip, vID) :
531 info.getVCellPosition(seedStrip);
532 double geomPitch = (!have_electrons) ? 0.5 * info.getUPitch(center.Y()) : 0.5 * info.getVPitch();
533 int nCells = (!have_electrons) ? info.getUCells() : info.getVCells();
534 std::deque<double> stripCharges;
535 std::deque<double> strips;
536#define NORMAL_CDF(z) 0.5 * std::erfc( - (z) * 0.707107)
537 double current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
538 double current_strip = seedStrip;
539 double cdf_low = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
540 double cdf_high = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
541 double charge = carriers * (cdf_high - cdf_low);
543 B2DEBUG(29,
"geomPitch = " << geomPitch /
Unit::um <<
" um");
544 B2DEBUG(29,
"charge = " << charge <<
" = " << carriers <<
"(carriers) * (" << cdf_high <<
"(cdf_high) - " << cdf_low <<
547 stripCharges.push_back(charge);
548 strips.push_back(current_strip);
549 while (cdf_low > 1.0e-5) {
550 current_pos -= geomPitch;
551 current_strip -= 0.5;
552 double cdf_current = NORMAL_CDF((current_pos - 0.5 * geomPitch) / sigma);
553 charge = carriers * (cdf_low - cdf_current);
554 stripCharges.push_front(charge);
555 strips.push_front(current_strip);
556 cdf_low = cdf_current;
558 current_pos = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
559 current_strip = seedStrip;
560 while (cdf_high < 1.0 - 1.0e-5) {
561 current_pos += geomPitch;
562 current_strip += 0.5;
563 double cdf_current = NORMAL_CDF((current_pos + 0.5 * geomPitch) / sigma);
564 charge = carriers * (cdf_current - cdf_high);
565 stripCharges.push_back(charge);
566 strips.push_back(current_strip);
567 cdf_high = cdf_current;
572 int npads = (strips.front() - floor(strips.front()) == 0) ? 5 : 4;
573 for (
int i = 0; i < npads; ++i) {
574 strips.push_front(strips.front() - 0.5);
575 stripCharges.push_front(0);
577 npads = (strips.back() - floor(strips.back()) == 0) ? 5 : 4;
578 for (
int i = 0; i < npads; ++i) {
579 strips.push_back(strips.back() + 0.5);
580 stripCharges.push_back(0);
583 B2DEBUG(29,
" --> charge sharing simulation, # strips = " << strips.size());
584 std::deque<double> readoutCharges;
585 std::deque<int> readoutStrips;
587 for (std::size_t index = 3; index < strips.size() - 3; index += 2) {
588 B2DEBUG(29,
" index = " << index <<
", strip = " << strips[index] <<
", stripCharge = " << stripCharges[index]);
589 int currentStrip =
static_cast<int>(strips[index]);
591 double c0 =
m_ChargeSimCal.getCouplingConstant(currentSensorID, !have_electrons,
"C0");
592 double c1 =
m_ChargeSimCal.getCouplingConstant(currentSensorID, !have_electrons,
"C1");
593 double c2 =
m_ChargeSimCal.getCouplingConstant(currentSensorID, !have_electrons,
"C2");
594 double c3 =
m_ChargeSimCal.getCouplingConstant(currentSensorID, !have_electrons,
"C3");
596 B2DEBUG(29,
" current strip = " << currentStrip);
597 B2DEBUG(29,
" index-3 = " << index - 3 <<
", strip = " << strips[index - 3] <<
", stripCharge = " << stripCharges[index - 3]);
598 B2DEBUG(29,
" index-2 = " << index - 2 <<
", strip = " << strips[index - 2] <<
", stripCharge = " << stripCharges[index - 2]);
599 B2DEBUG(29,
" index-1 = " << index - 1 <<
", strip = " << strips[index - 1] <<
", stripCharge = " << stripCharges[index - 1]);
600 B2DEBUG(29,
" index = " << index <<
", strip = " << strips[index] <<
", stripCharge = " << stripCharges[index]);
601 B2DEBUG(29,
" index+1 = " << index + 1 <<
", strip = " << strips[index + 1] <<
", stripCharge = " << stripCharges[index + 1]);
602 B2DEBUG(29,
" index+2 = " << index + 2 <<
", strip = " << strips[index + 2] <<
", stripCharge = " << stripCharges[index + 2]);
603 B2DEBUG(29,
" index+3 = " << index + 3 <<
", strip = " << strips[index + 3] <<
", stripCharge = " << stripCharges[index + 3]);
605 readoutCharges.push_back(c3 * stripCharges[index - 3]
606 + c2 * stripCharges[index - 2]
607 + c1 * stripCharges[index - 1]
608 + c0 * stripCharges[index]
609 + c1 * stripCharges[index + 1]
610 + c2 * stripCharges[index + 2]
611 + c3 * stripCharges[index + 3]
613 readoutStrips.push_back(currentStrip);
614 B2DEBUG(29,
" post simulation: " << index <<
", strip = " << currentStrip <<
", readoutCharge = " <<
615 readoutCharges[readoutCharges.size() - 1]);
619 while (readoutStrips.size() > 0 && readoutStrips.front() < 0) {
620 readoutStrips.pop_front();
621 tail += readoutCharges.front();
622 readoutCharges.pop_front();
624 readoutCharges.front() += tail;
626 while (readoutStrips.size() > 0 && readoutStrips.back() > nCells - 1) {
627 readoutStrips.pop_back();
628 tail += readoutCharges.back();
629 readoutCharges.pop_back();
631 readoutCharges.back() += tail;
634 for (
auto& c : readoutCharges)
635 c = (c <= 0) ? 0 : std::max(0.0, gRandom->Gaus(c, std::sqrt(info.c_fanoFactorSi * c)));
640 double d = (!have_electrons) ? seedPos - center.X() : seedPos - center.Y();
641 for (std::size_t index = 0; index < readoutStrips.size(); ++ index) {
642 double dist = d + (readoutStrips[index] - seedStrip) * 2 * geomPitch;
643 histo->Fill(dist /
Unit::um, readoutCharges[index]);
649 SVDModeByte modeByte = storeSVDEvtInfo->getModeByte();
661 double apvCoupling =
m_ChargeSimCal.getCouplingConstant(currentSensorID, !have_electrons,
"APVCoupling");
664 double recoveredCharge = 0;
665 for (std::size_t index = 0; index < readoutStrips.size(); index ++) {
668 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, readoutCharges[index],
672 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, apvCoupling * readoutCharges[index - 1],
675 if (index < readoutStrips.size() - 1)
676 waveforms[readoutStrips[index]].add(
m_currentTime + 0.5 * driftTime, apvCoupling * readoutCharges[index + 1],
678 recoveredCharge += readoutCharges[index];
679 B2DEBUG(29,
"strip: " << readoutStrips[index] <<
" charge: " << readoutCharges[index]);
681 B2DEBUG(29,
"Digitized " << recoveredCharge <<
" of " << carriers <<
" original carriers.");
686 charge += gRandom->Gaus(0., noise);
696 RelationArray relShaperDigitMCParticle(storeShaperDigits, storeMCParticles,
698 RelationArray relShaperDigitTrueHit(storeShaperDigits, storeTrueHits,
707 vector<pair<unsigned int, float> > digit_weights;
710 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
711 int sensorID = sensorWaveforms.first;
715 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
716 short int iStrip = stripWaveform.first;
719 vector<double> samples;
721 digit_weights.clear();
724 double elNoise =
m_NoiseCal.getNoiseInElectrons(sensorID,
true, iStrip);
725 double gain = 1 /
m_PulseShapeCal.getChargeFromADC(sensorID,
true, iStrip, 1);
726 double electronWeight =
m_ChargeSimCal.getElectronWeight(sensorID,
true);
729 B2DEBUG(25,
"start sampling at " <<
m_initTime);
731 samples.push_back(
addNoise(electronWeight * s(t), elNoise));
742 std::transform(samples.begin(), samples.end(), rawSamples.begin(),
743 [&](
double x)->SVDShaperDigit::APVRawSampleType {
744 return SVDShaperDigit::trimToSampleRange(x * gain);
749 if (
m_roundZS) rawThreshold = round(rawThreshold);
750 auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
751 std::bind(std::greater<double>(), _1, rawThreshold)
756 if (
m_MaskedStr.isMasked(sensorID,
true, iStrip))
continue;
759 if (!
m_map->isAPVinMap(sensorID,
true, iStrip))
continue;
770 n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
771 std::bind(std::greater<double>(), _1, rawThreshold)
778 int digIndex = storeShaperDigits.
getEntries();
779 storeShaperDigits.
appendNew(sensorID,
true, iStrip, rawSamples, 0);
782 if (particles.size() > 0) {
783 relShaperDigitMCParticle.
add(digIndex, particles.begin(), particles.end());
786 if (truehits.size() > 0) {
787 relShaperDigitTrueHit.
add(digIndex, truehits.begin(), truehits.end());
795 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
796 short int iStrip = stripWaveform.first;
799 vector<double> samples;
801 digit_weights.clear();
804 double elNoise =
m_NoiseCal.getNoiseInElectrons(sensorID,
false, iStrip);
805 double gain = 1 /
m_PulseShapeCal.getChargeFromADC(sensorID,
false, iStrip, 1);
806 double electronWeight =
m_ChargeSimCal.getElectronWeight(sensorID,
false);
810 samples.push_back(
addNoise(electronWeight * s(t), elNoise));
820 std::transform(samples.begin(), samples.end(), rawSamples.begin(),
821 [&](
double x)->SVDShaperDigit::APVRawSampleType {
822 return SVDShaperDigit::trimToSampleRange(x * gain);
827 if (
m_roundZS) rawThreshold = round(rawThreshold);
828 auto n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
829 std::bind(std::greater<double>(), _1, rawThreshold)
834 if (
m_MaskedStr.isMasked(sensorID,
false, iStrip))
continue;
837 if (!
m_map->isAPVinMap(sensorID,
false, iStrip))
continue;
848 n_over = std::count_if(rawSamples.begin(), rawSamples.end(),
849 std::bind(std::greater<double>(), _1, rawThreshold)
855 int digIndex = storeShaperDigits.
getEntries();
856 storeShaperDigits.
appendNew(sensorID,
false, iStrip, rawSamples, 0);
859 if (particles.size() > 0) {
860 relShaperDigitMCParticle.
add(digIndex, particles.begin(), particles.end());
863 if (truehits.size() > 0) {
864 relShaperDigitTrueHit.
add(digIndex, truehits.begin(), truehits.end());
872 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
873 tree_vxdID = sensorWaveforms.first;
879 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
880 tree_strip = stripWaveform.first;
883 if (s.getCharge() < thresholdU)
885 for (
int iTime = 0; iTime < 20; ++iTime) {
886 tree_signal[iTime] = s(10 * iTime);
892 double thresholdV = 3.0 * info.getElectronicNoiseV();
893 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
894 tree_strip = stripWaveform.first;
897 if (s.getCharge() < thresholdV)
899 for (
int iTime = 0; iTime < 20; ++iTime) {
900 tree_signal[iTime] = s(10. * iTime);
910 static size_t recordNo = 0;
911 static const string header(
"Event\tSensor\tSide\tStrip\tContrib\tTime\tCharge\tTau");
912 regex startLine(
"^|\n");
914 if (recordNo == 0) outfile << header << endl;
915 for (Waveforms::value_type& sensorWaveforms :
m_waveforms) {
916 VxdID sensorID(sensorWaveforms.first);
922 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.first) {
923 size_t strip = stripWaveform.first;
926 if (s.getCharge() < thresholdU)
929 ostringstream preamble;
931 preamble <<
"$&" << recordNo <<
'\t' << sensorID <<
'\t' << isU <<
'\t' << strip <<
'\t';
932 string signalString = s.toString();
933 signalString.pop_back();
934 string tableString = regex_replace(signalString, startLine, preamble.str());
935 outfile << tableString << endl;
939 double thresholdV = 3.0 * info.getElectronicNoiseV();
940 for (StripWaveforms::value_type& stripWaveform : sensorWaveforms.second.second) {
941 size_t strip = stripWaveform.first;
944 if (s.getCharge() < thresholdV)
947 ostringstream preamble;
949 preamble <<
"$&" << recordNo <<
'\t' << sensorID <<
'\t' << isU <<
'\t' << strip <<
'\t';
950 string signalString = s.toString();
951 signalString.pop_back();
952 string tableString = regex_replace(signalString, startLine, preamble.str());
953 outfile << tableString << endl;
970 int nTriggerClocks = triggerBin + relativeShift;
971 return floor(nTriggerClocks / 4);
static const double kBoltzmann
Boltzmann constant in GeV/K.
static const ParticleType photon
photon particle
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.
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
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...
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.
RelationIndexContainer< FROM, TO >::Element Element
Struct representing a single element in the index.
Class to store SVD mode information.
baseType getTriggerBin() const
Get the triggerBin id.
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.
SVDDigitizerModule()
Constructor.
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?
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 getElectronicNoiseU() const
Return electronic noise in e- for u (long) strips.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
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].
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
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.
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
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.
double w_adjacentU(double t)
Adjacent-channel waveform U-side.
double w_betaprime(double t)
Beta-prime waveform shape, x^alpha/(1+x)^beta.
std::pair< StripWaveforms, StripWaveforms > SensorWaveforms
Waveforms of u- and v- channels in one sensor.
std::function< double(double)> WaveformShape
WaveformShape type.
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.
RelationElement::index_type indexFrom
index of the element from which the relation points.
RelationElement::weight_type weight
weight of the relation.