3 #include <det/Detector.h>
5 #include <sdet/SDetector.h>
6 #include <sdet/Station.h>
7 #include <sdet/PMTConstants.h>
8 #include <sdet/UUBDownsampleFilter.h>
10 #include <evt/Event.h>
12 #include <fwk/CentralConfig.h>
14 #include <sevt/SEvent.h>
15 #include <sevt/Station.h>
16 #include <sevt/StationSimData.h>
17 #include <sevt/StationCalibData.h>
18 #include <sevt/PMTCalibData.h>
19 #include <sevt/PMTSimData.h>
22 #include <utl/AugerUnits.h>
23 #include <utl/MathConstants.h>
24 #include <utl/Particle.h>
25 #include <utl/PhysicalConstants.h>
26 #include <utl/TimeStamp.h>
27 #include <utl/ErrorLogger.h>
28 #include <utl/Point.h>
29 #include <utl/Vector.h>
30 #include <utl/Reader.h>
31 #include <utl/TimeDistribution.h>
32 #include <utl/TimeDistributionAlgorithm.h>
33 #include <utl/TabularStream.h>
35 #include <fwk/RunController.h>
47 namespace SdSimulationCalibratorOG {
52 auto topBranch = CentralConfig::GetInstance()->GetTopBranch(
"SdSimulationCalibrator");
54 topBranch.GetChild(
"singleTankId").GetData(fSingleTankId);
56 const auto hardwareType = topBranch.GetChild(
"hardware").Get<
string>();
58 auto dumpTraces = topBranch.GetChild(
"dumpTraces").Get<
bool>();
60 if (hardwareType ==
"wcdLarge")
62 else if (hardwareType ==
"wcdSmall")
64 else if (hardwareType ==
"ssd")
66 else if (hardwareType ==
"all")
69 ERROR(
"Hardware type not recognized or supported!");
73 const bool isUUB = det::Detector::GetInstance().GetSDetector().GetStation(fSingleTankId).IsUUB();
74 auto g4SimBranch = CentralConfig::GetInstance()->GetTopBranch(
"G4StationSimulator");
75 const auto fullTrackMode = g4SimBranch.GetChild(
"fullTrackMode").Get<
string>();
76 const auto fastMode = g4SimBranch.GetChild(
"fastMode").Get<
string>();
79 std::string(isUUB ?
"uub" :
"ub") +
80 "-hw_" + hardwareType +
81 "-full_" + fullTrackMode +
84 const auto chargePeakFilename =
"dump_charge_peak-" + basename +
".dat";
85 fDumpFile.open(chargePeakFilename);
86 if (!fDumpFile.is_open()) {
87 ERROR(
"Cannot open charge/peak dump file!");
90 fDumpFile <<
"# pmtId phase peak charge compatPeak\n";
93 const auto traceFilename =
"dump_trace-" + basename +
".dat";
94 fDumpTraceFile =
new std::ofstream(traceFilename);
95 if (!fDumpTraceFile->is_open()) {
96 ERROR(
"Cannot open trace dump file!");
99 *fDumpTraceFile <<
"# baseline begin end num_particles <whole_trace>\n";
107 SdSimulationCalibrator::Run(
Event& event)
110 ERROR(
"Non-existent SEvent.");
114 auto& sEvent =
event.GetSEvent();
116 if (!sEvent.HasStation(fSingleTankId)) {
118 err <<
"Non-existent station " << fSingleTankId;
123 auto& station = sEvent.GetStation(fSingleTankId);
124 const auto& dStation = Detector::GetInstance().GetSDetector().GetStation(fSingleTankId);
126 fSignature = station.GetSimData().GetSimulatorSignature();
127 fIsUUB = dStation.IsUUB();
129 ProcessStation(station, dStation);
136 SdSimulationCalibrator::Finish()
140 <<
"Err<>" <<
endc <<
"StdDev" <<
endc <<
"<Charge>" <<
endc <<
"Err<>"
143 unsigned int numRuns = 0;
144 for (
const auto& peakCharge : fPeakCharge) {
145 const auto& peak = peakCharge.first;
147 const auto& charge = peakCharge.second;
149 << peak.GetN() <<
endc
150 << fNParticles <<
endc
151 << peak.GetAverage() <<
endc
152 << peak.GetAverageError() <<
endc
153 << peak.GetStandardDeviation() <<
endc
154 << charge.GetAverage() <<
endc
155 << charge.GetAverageError() <<
endc
156 << charge.GetStandardDeviation() <<
endr;
157 numRuns = peak.GetN();
165 auto injB = CentralConfig::GetInstance()->GetTopBranch(
"ParticleInjector");
166 const double muEnergy = injB.GetChild(
"Energy").GetChild(
"Discrete").GetChild(
"x").Get<
double>();
169 info <<
"The simulated calibration constants were set as follows:\n\n"
171 "The following XML snipped should be pasted into "
172 "Framework/SDetector/SdSimCalibrationConstants.xml.in "
173 "with the other PMT calibrations from the same simModule:\n\n"
174 " <!-- " << fSignature <<
" tank sim, " << numRuns <<
" runs, " << fNParticles <<
" particle(s) per run, "
175 "energy = " << muEnergy /
GeV <<
" GeV -->\n"
176 " <simModule name='" << fSignature <<
"'>\n"
177 " <electronics isUUB='" << fIsUUB <<
"'>\n";
179 for (
int i = 1, n = fPeakCharge.size(); i < n; ++i) {
180 const bool isWCD = (1 <= i && i <= 3);
181 const auto& peakCharge = isWCD ? fWCDPeakCharge : fPeakCharge[i];
182 const auto& peak = peakCharge.first;
185 info <<
" <PMT id='" << i <<
"'>" << (isWCD ?
"<!-- note: all WCD PMTs are averaged together -->" :
"") <<
'\n';
186 const auto& charge = peakCharge.second;
187 info <<
" <peak> " << peak.GetAverage() <<
" </peak> "
188 "<!-- err=" << peak.GetAverageError() <<
" std=" << peak.GetStandardDeviation();
190 info <<
" pmt" << i <<
'=' << fPeakCharge[i].first.GetAverage();
192 " <charge> " << charge.GetAverage() <<
" </charge> "
193 "<!-- err=" << charge.GetAverageError() <<
" std=" << charge.GetStandardDeviation();
195 info <<
" pmt" << i <<
'=' << fPeakCharge[i].second.GetAverage();
197 if (fIsUUB && isWCD) {
198 const auto& compatPeak = fWCDCompatibilityPeak;
199 const auto& peakRatio = fWCDPeakRatio;
200 info <<
" <compatibilityPeak> " << compatPeak.GetAverage() <<
" </compatibilityPeak> "
201 "<!-- err=" << compatPeak.GetAverageError() <<
" std=" << compatPeak.GetStandardDeviation()
202 <<
" pmt" << i <<
'=' << fCompatibilityPeak[i].GetAverage() <<
" -->\n"
203 " <!-- FBW/compatibility peak ratio=" << peakRatio.GetAverage() <<
" err=" << peakRatio.GetAverageError() <<
" "
204 "std=" << peakRatio.GetStandardDeviation() <<
" pmt" << i <<
'=' << fPeakRatio[i].GetAverage() <<
" -->\n";
208 info <<
" </electronics>\n"
222 const double trigger = baseline + threshold;
226 for (begin = a; begin <
b; ++begin)
227 if (trace.
At(begin) >= trigger)
231 return make_pair(0, 0);
233 for (end = begin + 1; end <
b; ++end)
234 if (trace.
At(end) < trigger)
236 return make_pair(begin, end);
242 const int nParticles)
244 const double val = trace.
At(begin) - baseline;
247 for (
int i = begin+1; i < end; ++i) {
248 const double val = trace.
At(i) - baseline;
254 return make_pair(peak, charge / nParticles);
261 const TimeDistributionI& trace,
const int begin,
const int end,
const double baseline,
262 const int nParticles)
268 *file << baseline <<
' ' << begin-start <<
' ' << end-start <<
' ' << nParticles;
269 for (
int i = start, n = trace.
GetStop()+1; i < n; ++i)
270 *file <<
' ' << trace.
At(i);
280 if (fNParticles <= 0)
284 ERROR(
"Simulation calibrator is throwing more than one particle. Only use with smallPMT!");
289 const double signalThreshold = 30;
290 const int beforeSignal = fIsUUB ? 20 : 1;
291 const int afterSignal = fIsUUB ? 49 : 19;
292 const int uubTimeFactor = 3;
296 if (!pmt.HasSimData())
308 if (!pmt.HasCalibData())
310 const auto& pmtCalib = pmt.GetCalibData();
312 const auto index = pmt.
GetId();
320 const auto beginEnd =
FindSignal(trace, baseline, signalThreshold);
321 const auto begin = beginEnd.first;
322 const auto end = beginEnd.second;
326 const int signalBegin =
max(begin - beforeSignal, trace.GetStart());
327 const int signalEnd = min(begin + afterSignal, trace.GetStop()+1);
329 DumpTrace(fDumpTraceFile, trace, signalBegin, signalEnd, baseline, fNParticles);
331 const auto peakCharge =
ProcessTrace(trace, signalBegin, signalEnd, baseline, fNParticles);
332 const auto& peak = peakCharge.first;
333 const auto& charge = peakCharge.second;
334 ResizeArrays(index + 1);
335 fPeakCharge[index].first(peak);
336 fPeakCharge[index].second(charge);
338 fWCDPeakCharge.first(peak);
339 fWCDPeakCharge.second(charge);
342 if (!fIsUUB || !isWCD) {
343 fDumpFile << index <<
" -1 " << peak <<
' ' << charge <<
" -1\n";
347 for (
int phase = 0; phase < 3; ++phase) {
349 const auto compatPeakCharge =
350 ProcessTrace(compatTrace, signalBegin/uubTimeFactor, signalEnd/uubTimeFactor, baseline, fNParticles);
351 const auto& compatPeak = compatPeakCharge.first;
352 fCompatibilityPeak[index](compatPeak);
353 fPeakRatio[index](peak/compatPeak);
354 fWCDCompatibilityPeak(compatPeak);
355 fWCDPeakRatio(peak/compatPeak);
356 fDumpFile << index <<
' ' << phase <<
' ' << peak <<
' ' << charge <<
' ' << compatPeak <<
'\n';
365 SdSimulationCalibrator::ResizeArrays(
const unsigned int n)
367 if (n > fPeakCharge.size()) {
368 fPeakCharge.resize(n);
369 fCompatibilityPeak.resize(n);
370 fPeakRatio.resize(n);
376 SdSimulationCalibrator::Clear()
379 fCompatibilityPeak.clear();
381 fWCDPeakCharge.first.Clear();
382 fWCDPeakCharge.second.Clear();
383 fWCDCompatibilityPeak.Clear();
384 fWCDPeakRatio.Clear();
T At(const double time) const
int GetStart() const
First slot with data.
Detector description interface for Station-related data.
Detector description interface for PMT-related data.
Histogram class for time distributions with suppressed empty bins.
int GetId() const
return ID of the PMT
#define INFO(message)
Macro for logging informational messages.
const PMT & GetPMT(const int id) const
Get specified PMT by id.
void Init()
Initialise the registry.
bool HasFADCTrace(StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if FADC trace (prior to local trigger simulation) exists.
sdet::PMTConstants::PMTType GetType() const
pair< int, int > FindSignal(const TimeDistributionI &trace, const double baseline, const double threshold)
class to hold data at Station level
pair< double, double > ProcessTrace(const TimeDistributionI &trace, const int begin, const int end, const double baseline, const int nParticles)
utl::TraceI UUBDownsampleFilter(const utl::TraceI &trace, const int phase=1)
int GetStop() const
Last slot with data (1 less than First slot if no data)
void DumpTrace(std::ofstream *const file, const TimeDistributionI &trace, const int begin, const int end, const double baseline, const int nParticles)
class to format data in tabular form
ResultFlag
Flag returned by module methods to the RunController.
Class to hold simulated data at PMT level.
sevt::StationSimData & GetSimData()
Get simulated data at station level.
unsigned int GetNParticles() const
utl::TimeDistributionI & GetFADCTrace(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain, const StationConstants::SignalComponent source=StationConstants::eTotal)
Get FADC trace by gain and source.
#define ERROR(message)
Macro for logging error messages.