1 #include <fwk/CentralConfig.h>
2 #include <fwk/RunController.h>
4 #include <det/Detector.h>
5 #include <sdet/SDetector.h>
6 #include <sdet/Station.h>
7 #include <sdet/StationTriggerAlgorithm.h>
8 #include <sdet/PMTConstants.h>
10 #include <evt/Event.h>
12 #include <sevt/EventTrigger.h>
13 #include <sevt/Header.h>
14 #include <sevt/SEvent.h>
15 #include <sevt/Station.h>
16 #include <sevt/Scintillator.h>
18 #include <sevt/PMTCalibData.h>
19 #include <sevt/SmallPMTData.h>
20 #include <sevt/SmallPMTCalibData.h>
21 #include <sevt/PMTRecData.h>
22 #include <sevt/StationGPSData.h>
23 #include <sevt/StationRecData.h>
24 #include <sevt/ScintillatorRecData.h>
25 #include <sevt/StationTriggerData.h>
26 #include <sevt/StationCalibData.h>
27 #include <sevt/SignalSegment.h>
29 #include <utl/TimeStamp.h>
30 #include <utl/TimeInterval.h>
31 #include <utl/Trace.h>
32 #include <utl/TraceAlgorithm.h>
33 #include <utl/Reader.h>
34 #include <utl/ErrorLogger.h>
37 #include <utl/QuadraticFitter.h>
38 #include <utl/ExponentialFitter.h>
39 #include <utl/String.h>
40 #include <utl/ShadowPtr.h>
41 #include <utl/TabularStream.h>
50 #define USE_SPMT_SIGNAL_AS_TOTAL 0
61 namespace SdCalibratorOG {
70 template<
typename T1,
typename T2>
72 operator<<(ostream& os, pair<T1, T2>&
p)
74 return os <<
'[' <<
p.first <<
", " <<
p.second <<
']';
80 IsInRange(
const pair<double, double>& r,
const double a,
const double b)
82 return r.first <= r.second && a <= r.first && r.second <=
b;
93 topB.GetChild(
"peakFitRange").GetData(fPeakFitRange);
94 topB.GetChild(
"peakFitChi2Accept").GetData(fPeakFitChi2Accept);
95 topB.GetChild(
"peakOnlineToVEMFactor").GetData(fPeakOnlineToVEMFactor);
96 topB.GetChild(
"peakHistogramToVEMFactor").GetData(fPeakHistogramToVEMFactor);
97 topB.GetChild(
"peakOnlineToMIPFactor").GetData(fPeakOnlineToMIPFactor);
98 topB.GetChild(
"peakHistogramToMIPFactor").GetData(fPeakHistogramToMIPFactor);
99 topB.GetChild(
"chargeFitShoulderHeadRatio").GetData(fChargeFitShoulderHeadRatio);
100 topB.GetChild(
"chargeFitChi2Accept").GetData(fChargeFitChi2Accept);
101 topB.GetChild(
"chargeOnlineToVEMFactor").GetData(fChargeOnlineToVEMFactor);
102 topB.GetChild(
"chargeHistogramToVEMFactor").GetData(fChargeHistogramToVEMFactor);
103 topB.GetChild(
"chargeOnlineToMIPFactor").GetData(fChargeOnlineToMIPFactor);
104 topB.GetChild(
"chargeHistogramToMIPFactor").GetData(fChargeHistogramToMIPFactor);
106 auto shapeFitB = topB.GetChild(
"shapeFitRange");
107 shapeFitB.GetChild(
"beforeCalibrationVersion12").GetData(fShapeFitRangeBefore12);
108 shapeFitB.GetChild(
"sinceCalibrationVersion12").GetData(fShapeFitRangeSince12);
110 topB.GetChild(
"riseTimeFractions").GetData(fRiseTimeFractions);
111 topB.GetChild(
"fallTimeFractions").GetData(fFallTimeFractions);
113 ERROR(
"Rise/fall time fractions must be ascending and within [0, 1]");
117 const auto testStations = topB.GetChild(
"testStations").Get<vector<int>>();
118 fTestStations = set<int>(testStations.begin(), testStations.end());
120 auto fsB = topB.GetChild(
"findSignal");
121 fsB.GetChild(
"threshold").GetData(fFindSignalThreshold);
122 fsB.GetChild(
"binsAboveThreshold").GetData(fFindSignalBinsAboveThreshold);
124 fTreatHGLGEqualInSignalSearch = bool(topB.GetChild(
"treatHGLGEqualInSignalSearch"));
126 fApplyBackwardFlatPieceCheck = bool(topB.GetChild(
"applyBackwardFlatPieceCheck"));
128 fDecreaseLGFlatPieceTolerance = bool(topB.GetChild(
"decreaseLGFlatPieceTolerance"));
130 fIncludeWaterCherenkovDetectorInScintillatorStartStopDetermination =
131 topB.GetChild(
"includeWaterCherenkovDetectorInScintillatorStartStopDetermination").Get<
bool>();
133 topB.GetChild(
"binsBeforeStartForSPMT").GetData(fBinsBeforeStartForSPMT);
136 info <<
"Parameters:\n"
137 "pmtSummationCutoff: " << fPMTSummationCutoff <<
"\n"
138 "peakFitRange: " << fPeakFitRange <<
"\n"
139 "peakFitChi2Accept: " << fPeakFitChi2Accept <<
"\n"
140 "peakOnlineToVEMFactor: " << fPeakOnlineToVEMFactor <<
"\n"
141 "peakHistogramToVEMFactor: " << fPeakHistogramToVEMFactor <<
"\n"
142 "peakOnlineToMIPFactor: " << fPeakOnlineToMIPFactor <<
"\n"
143 "peakHistogramToMIPFactor: " << fPeakHistogramToMIPFactor <<
"\n"
144 "chargeFitShoulderHeadRatio: " << fChargeFitShoulderHeadRatio <<
"\n"
145 "chargeFitChi2Accept: " << fChargeFitChi2Accept <<
"\n"
146 "chargeOnlineToVEMFactor: " << fChargeOnlineToVEMFactor <<
"\n"
147 "chargeHistogramToVEMFactor: " << fChargeHistogramToVEMFactor <<
"\n"
148 "chargeOnlineToMIPFactor: " << fChargeOnlineToMIPFactor <<
"\n"
149 "chargeHistogramToMIPFactor: " << fChargeHistogramToMIPFactor <<
"\n"
151 " beforeCalibrationVersion12: " << fShapeFitRangeBefore12 <<
"\n"
152 " sinceCalibrationVersion12: " << fShapeFitRangeSince12 <<
"\n"
153 "riseTimeFractions: " << fRiseTimeFractions <<
"\n"
154 "fallTimeFractions: " << fFallTimeFractions <<
"\n"
155 "testStations: " <<
Join(
" ", fTestStations) <<
"\n"
157 " threshold: " << fFindSignalThreshold <<
"\n"
158 " binsAboveThreshold: " << fFindSignalBinsAboveThreshold <<
"\n"
159 "treatHGLGEqualInSignalSearch: " << fTreatHGLGEqualInSignalSearch <<
"\n"
160 "applyBackwardFlatPieceCheck: " << fApplyBackwardFlatPieceCheck <<
"\n"
161 "decreaseLGFlatPieceTolerance: " << fDecreaseLGFlatPieceTolerance;
173 auto& sEvent =
event.GetSEvent();
176 fToldYaCharge =
false;
177 fToldYaShape =
false;
179 vector<int> noVEMStations;
180 vector<int> randomTrigger;
181 vector<int> badCompression;
184 if (sEvent.StationsBegin() != sEvent.StationsEnd())
185 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"SdCalibrator/CalibratedEvents"];
187 const bool isCommsCrisis = kCommsCrisis.IsInRange(det::Detector::GetInstance().GetTime());
191 for (
auto& station : sEvent.StationsRange()) {
193 if (!station.HasTriggerData()) {
200 if (!station.IsT2Life())
202 if (isCommsCrisis && !station.IsT2Life120())
205 const auto& trig = station.GetTriggerData();
206 if (trig.GetErrorCode() & 0xff) {
207 if (trig.IsSilent() && !station.IsRejected())
214 if (trig.IsRandom()) {
215 randomTrigger.push_back(station.GetId());
220 if (!station.HasCalibData()) {
226 if (station.GetCalibData().GetVersion() > 32000) {
228 warn <<
"Station " << station.GetId() <<
" has LS calibration version "
229 << station.GetCalibData().GetVersion() <<
'!';
235 if (!station.HasGPSData()) {
242 if (sEvent.HasTrigger()) {
243 const int trigSecond = sEvent.GetTrigger().GetTime().GetGPSSecond();
244 const int timeDiff = int(station.GetGPSData().GetSecond()) - trigSecond;
245 if (
abs(timeDiff) > 1) {
248 const int sId = station.GetId();
249 badCompression.push_back(sId);
251 info <<
"Bad compress data: station " << sId <<
" has " << timeDiff
252 <<
" sec of time difference to event trigger.";
258 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
259 fIsUUB = dStation.IsUUB();
261 CalculatePeakAndCharge(station);
263 if (fIsUUB && station.HasSmallPMTData()) {
264 if (CopySmallPMTCalibData(station)) {
265 station.GetSmallPMTData().SetIsTubeOk();
267 station.GetSmallPMTData().SetIsTubeOk(
false);
268 station.GetSmallPMT().GetCalibData().SetIsTubeOk(
false);
270 warn <<
"Station " << station.GetId() <<
": No valid SmallPMT calibration. "
271 "Setting IsTubeOk as false for SmallPMT.";
276 if (!ComputeBaselines(station) ||
277 !BuildSignals(station) ||
278 !MergeSignals(station) ||
279 !SelectSignal(station)) {
293 sEvent.SetNErrorZeroStations(nErrorZero);
295 String::StationIdListWithMessage(noVEMStations,
"without VEM trace rejected.");
296 String::StationIdListWithMessage(randomTrigger,
"with random trigger rejected.");
297 String::StationIdListWithMessage(badCompression,
"with bad compression data rejected.");
302 << String::OfIds(badCompression) <<
" without trigger data rejected.";
333 const unsigned int tick = gps.
GetTick();
334 const int currentST = gps.GetCurrentST();
335 const int next100 = gps.GetNext100();
336 const int nextST = gps.GetNextST();
339 const unsigned int tickFall = gps.GetTickFall();
340 const int offset = gps.GetOffset();
343 (
unsigned int)((tick * (1e9 + nextST - currentST) / next100) + currentST +
344 0.01 * short(offset & 0xffff)) - 100 * (tickFall == tick);
346 const unsigned int nanosecond =
347 (
unsigned int)((tick * (1e9 + nextST - currentST) / next100) + currentST);
350 gps.SetCorrectedNanosecond(nanosecond);
355 SdCalibrator::CopySmallPMTCalibData(
Station& station)
359 if (!spmt.HasCalibData())
364 if (!spmtCalib.IsTubeOk())
369 if (!pmt.HasCalibData())
374 if (!pmtCalib.IsTubeOk())
377 if (!pmt.HasRecData())
379 auto& pmtRec = pmt.GetRecData();
381 const double spmtVemCharge = 1 / (spmtCalib.GetBeta() * spmtCalib.GetCorrectionFactor());
382 const double spmtVemChargeErr =
383 spmtCalib.GetBetaError() * spmtCalib.GetCorrectionFactor() *
Sqr(spmtVemCharge);
385 if (std::isnan(spmtVemCharge) || std::isinf(spmtVemCharge) ||
386 spmtVemCharge <= 0 || spmtVemChargeErr <= 0)
389 pmtRec.SetVEMCharge(spmtVemCharge, spmtVemChargeErr);
392 double muonAreaOverPeak = 0;
393 for (
const auto& lpmt : station.PMTsRange()) {
394 if (lpmt.HasCalibData() && lpmt.GetCalibData().IsTubeOk() && lpmt.HasRecData()) {
395 const auto& rec = lpmt.GetRecData();
396 const auto peak = rec.GetVEMPeak();
398 muonAreaOverPeak += rec.GetVEMCharge() / peak;
401 if (muonAreaOverPeak > 0)
402 pmtRec.SetVEMPeak(spmtVemCharge / muonAreaOverPeak, 0);
405 warn <<
"Station " << station.
GetId()
406 <<
": Cannot calculate properly SmallPMT VEMpeak. Using default value = 1/3";
408 pmtRec.SetVEMPeak(1./3, 0);
412 info <<
"SmallPMT calibration for station " << station.
GetId() <<
"\n"
413 <<
" beta = " << spmtCalib.GetBeta() <<
" +- " << spmtCalib.GetBetaError()
414 <<
" ---> VEMcharge = " << pmtRec.GetVEMCharge() <<
" +- " << pmtRec.GetVEMChargeError()
415 <<
" (VEMpeak = " << pmtRec.GetVEMPeak() <<
")";
418 pmtRec.SetIsVEMChargeFromHistogram(
false);
419 pmtRec.SetIsVEMPeakFromHistogram(
false);
421 pmtRec.SetMuonChargeSlope(0);
422 pmtRec.SetMuonPulseDecayTime(0, 0);
423 pmtRec.SetGainRatio(1);
430 SdCalibrator::CalculatePeakAndCharge(
Station& station)
434 const auto calibVersion = stationCalib.
GetVersion();
435 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
442 const auto type = pmt.GetType();
450 if (!pmt.HasCalibData())
453 const auto& pmtCalib = pmt.GetCalibData();
455 if (!pmtCalib.IsTubeOk())
458 if (!pmt.HasRecData())
460 auto& pmtRec = pmt.GetRecData();
463 double gainRatio = pmtCalib.GetGainRatio();
464 if (calibVersion == 12)
467 const int pmtId = pmt.GetId();
469 warn <<
"Gain ratio zero encountered for PMT " << pmtId <<
"; replacing it with the nominal value.";
471 gainRatio = dStation.GetPMT(pmtId).GetGainRatio();
473 pmtRec.SetGainRatio(gainRatio);
476 if (!pmtRec.GetVEMPeak()) {
478 const double onlineFactor =
480 double vemPeak = pmtCalib.GetOnlinePeak() * onlineFactor;
481 double vemPeakErr = 0;
482 pmtRec.SetOnlineVEMPeak(vemPeak, vemPeakErr);
485 bool vemPeakFromHisto =
false;
488 if (calibVersion > 8) {
489 const auto& peakHistoBinning = dStation.GetMuonPeakHistogramBinning<
short>(type, calibVersion);
490 const int muonPeakHistoSize = pmtCalib.GetMuonPeakHisto().size();
491 if (!muonPeakHistoSize ||
int(peakHistoBinning.size())-1 != muonPeakHistoSize) {
493 WARNING(
"According to the LS calibration version there should be a muon peak histogram... Will not tell you again!");
497 const CalibHistogram peakHisto(peakHistoBinning, pmtCalib.GetMuonPeakHisto());
498 const double histoFactor =
500 const double predictedHistoPeak = vemPeak / histoFactor;
501 if (predictedHistoPeak > 0 && peakHisto.GetMaximum() > 200) {
502 const double baseEstimate = pmtCalib.GetBaseline() - pmtCalib.GetMuonPeakHistoOffset();
503 const double base = (fabs(baseEstimate) < 20) ? baseEstimate : 0;
504 const double peakLow = fPeakFitRange.first * predictedHistoPeak;
505 const double peakHigh = fPeakFitRange.second * predictedHistoPeak;
507 if (peakHigh - peakLow >= 5) {
513 pmtRec.GetMuonPeakFitData() = qf;
516 if (peakLow <= fittedPeak && fittedPeak <= peakHigh &&
518 vemPeak = fittedPeak * histoFactor;
520 pmtRec.SetHistogramVEMPeak(vemPeak, vemPeakErr);
521 vemPeakFromHisto =
true;
530 pmtRec.SetVEMPeak(vemPeak, vemPeakErr);
531 pmtRec.SetIsVEMPeakFromHistogram(vemPeakFromHisto);
534 if (!pmtRec.GetVEMCharge()) {
539 const double onlineFactor =
541 double vemCharge = pmtCalib.GetOnlineCharge() * onlineFactor;
542 double vemChargeErr = 20 * onlineFactor;
543 pmtRec.SetOnlineVEMCharge(vemCharge, vemChargeErr);
544 bool vemChargeFromHisto =
false;
545 double muChargeSlope = 0;
548 if (calibVersion > 8) {
549 const auto& chargeHistoBinning = dStation.GetMuonChargeHistogramBinning<
double>(type, calibVersion);
550 const auto& calibChargeHisto = pmtCalib.GetMuonChargeHisto();
551 const int chargeHistoSize = calibChargeHisto.size();
553 if (!chargeHistoSize ||
int(chargeHistoBinning.size()) - 1 != chargeHistoSize) {
554 if (!fToldYaCharge) {
555 WARNING(
"According to the LS calibration version there should be a muon charge histogram... Will not tell you again!");
556 fToldYaCharge =
true;
559 const CalibHistogramD chargeHisto(chargeHistoBinning, pmtCalib.GetMuonChargeHisto());
561 const double baseEstimate = pmtCalib.GetBaseline() *
562 (calibVersion == 13 ? 19 : 20) - pmtCalib.GetMuonChargeHistoOffset();
563 const double base = (fabs(baseEstimate) < 20) ? baseEstimate : 0;
565 if (chargeHisto.GetMaximum() > 500) {
568 const int size = chargeHisto.GetNBins();
569 int start = (size - 1) - 5;
573 for ( ; start >= 2 && chargeHisto.GetBinAverage(start) < small; --start)
582 double maxValue = chargeHisto.GetBinAverage(start);
585 double value = chargeHisto.GetBinAverage(start - 1);
586 double value1 = chargeHisto.GetBinAverage(start - 2);
587 for (
int pos = start - 1; pos >= 2; --pos) {
588 if (maxValue < value) {
592 const double reducedMax = maxValue * fChargeFitShoulderHeadRatio;
595 const double value2 = chargeHisto.GetBinAverage(pos - 2);
596 if (value <= reducedMax && value1 <= reducedMax && value2 <= reducedMax) {
606 const double reducedMax = maxValue * fChargeFitShoulderHeadRatio;
607 const int size2 = size - 2;
609 int shoulderHigh = 0;
611 double value = chargeHisto.GetBinAverage(maxBin + 1);
612 double value1 = chargeHisto.GetBinAverage(maxBin + 2);
613 for (
int pos = maxBin + 1; pos < size2; ++pos) {
614 const double value2 = chargeHisto.GetBinAverage(pos+2);
615 if (value <= reducedMax && value1 <= reducedMax && value2 <= reducedMax) {
625 const double chargeLow = chargeHisto.GetBinCenter(shoulderLow);
626 const double chargeHigh = chargeHisto.GetBinCenter(shoulderHigh);
627 const double histoFactor =
629 const double predictedHistoCharge = vemCharge / histoFactor;
630 if (chargeLow <= predictedHistoCharge && predictedHistoCharge <= chargeHigh) {
635 pmtRec.GetMuonChargeFitData() = qf;
639 if (chargeLow <= fittedCharge && fittedCharge <= chargeHigh &&
641 vemCharge = fittedCharge * histoFactor;
643 pmtRec.SetHistogramVEMCharge(vemCharge, vemChargeErr);
644 vemChargeFromHisto =
true;
649 "Quadratic fit between bins " << chargeLow <<
" and " << chargeHigh
650 <<
" failed on this charge histogram:\n";
651 for (
unsigned int i = 0, n = chargeHisto.GetNBins(); i < n; ++i)
652 warn << chargeHisto.GetBinCenter(i) <<
' ' << chargeHisto.GetBinAverage(i) <<
'\n';
659 const double start = chargeHigh + 10;
660 const double stop = min(2*start, 950.);
661 if (start+10 < stop) {
663 pmtRec.GetMuonChargeSlopeFitData() = ef;
665 const double slope = vemCharge * ef.
GetSlope();
668 muChargeSlope = slope;
679 pmtRec.SetVEMCharge(vemCharge, vemChargeErr);
680 pmtRec.SetIsVEMChargeFromHistogram(vemChargeFromHisto);
681 pmtRec.SetMuonChargeSlope(muChargeSlope);
685 double muDecayTime = 0;
686 double muDecayTimeErr = 0;
687 if (calibVersion > 8) {
689 if (pmtCalib.GetMuonShapeHisto().empty()) {
691 WARNING(
"According to the LS calibration version there should be a muon shape histogram... Will not tell you again!");
695 const auto& muShapeHisto = pmtCalib.GetMuonShapeHisto();
696 const unsigned int size = muShapeHisto.size();
702 const auto& shapeHistoBinning = dStation.GetMuonShapeHistogramBinning(calibVersion);
703 const double subtract = muShapeHisto[0];
705 ShapeHistogram(shapeHistoBinning, muShapeHisto),
706 calibVersion < 12 ? fShapeFitRangeBefore12 : fShapeFitRangeSince12
707 ).GetFit(ef, subtract);
708 pmtRec.GetMuonShapeFitData() = ef;
714 const double decayTime = -1 / slope;
715 if (0 <= decayTime && decayTime < 1000*
nanosecond) {
716 muDecayTime = decayTime;
717 muDecayTimeErr = slopeErr /
Sqr(slope);
726 pmtRec.SetMuonPulseDecayTime(muDecayTime, muDecayTimeErr);
735 const double binTiming,
736 const unsigned int startBin,
737 const unsigned int startIntegration,
738 const unsigned int endIntegration,
739 const double traceIntegral)
745 if (traceIntegral <= 0)
748 const double riseStartSentry = fRiseTimeFractions.first * traceIntegral;
749 const double riseEndSentry = fRiseTimeFractions.second * traceIntegral;
750 const double fallStartSentry = fFallTimeFractions.first * traceIntegral;
751 const double fallEndSentry = fFallTimeFractions.second * traceIntegral;
752 const unsigned int shapeSentry = startIntegration + (
unsigned int)(600*
nanosecond / binTiming);
753 const double t40Sentry = 0.4 * traceIntegral;
754 const double t50Sentry = 0.5 * traceIntegral;
755 double riseStartBin = 0;
756 double riseEndBin = 0;
757 double fallStartBin = 0;
758 double fallEndBin = 0;
763 double peakAmplitude = 0;
764 double runningSum = 0;
769 for (
unsigned int i = startIntegration; i < endIntegration; ++i) {
771 const double binValue = trace[i];
772 runningSum += binValue;
774 if (peakAmplitude < binValue)
775 peakAmplitude = binValue;
777 if (!sumEarly && i >= shapeSentry)
780 if (!riseStartBin && runningSum > riseStartSentry)
781 riseStartBin = i - (runningSum - riseStartSentry) / (runningSum - oldSum);
783 if (!riseEndBin && runningSum > riseEndSentry)
784 riseEndBin = i - (runningSum - riseEndSentry) / (runningSum - oldSum);
786 if (!fallStartBin && runningSum > fallStartSentry)
787 fallStartBin = i - (runningSum - fallStartSentry) / (runningSum - oldSum);
789 if (!fallEndBin && runningSum > fallEndSentry)
790 fallEndBin = i - (runningSum - fallEndSentry) / (runningSum - oldSum);
792 if (!t40Bin && runningSum > t40Sentry)
793 t40Bin = i - (runningSum - t40Sentry) / (runningSum - oldSum);
795 if (!t50Bin && runningSum > t50Sentry)
796 t50Bin = i - (runningSum - t50Sentry) / (runningSum - oldSum);
803 pmtRec.
SetRiseTime(binTiming * (riseEndBin - riseStartBin), 0);
804 pmtRec.
SetFallTime(binTiming * (fallEndBin - fallStartBin), 0);
805 pmtRec.
SetT40(binTiming * (t40Bin - startBin));
806 pmtRec.
SetT50(binTiming * (t50Bin - startBin));
807 if (shapeSentry < endIntegration) {
808 const double sumLate = runningSum - sumEarly;
816 SdCalibrator::SumPMTComponents(
Station& station)
822 vector<const TraceD*> compTrace;
824 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
833 for (
const auto& pmt : station.PMTsRange())
834 if (pmt.HasRecData()) {
835 const auto& pmtRec = pmt.GetRecData();
836 if (pmtRec.HasVEMTrace(component))
837 compTrace.push_back(&pmtRec.GetVEMTrace(component));
840 const unsigned int nPMTs = compTrace.size();
844 const unsigned int fadcTraceLength = dStation.GetFADCTraceLength();
846 TraceD sumTrace(fadcTraceLength, dStation.GetFADCBinSize());
848 for (
unsigned int pos = 0; pos < fadcTraceLength; ++pos) {
850 double& sum = sumTrace[pos];
854 for (
unsigned int pmtIndex = 0; pmtIndex < nPMTs; ++pmtIndex) {
855 const double value = (*compTrace[pmtIndex])[pos];
856 if (value > fPMTSummationCutoff) {
881 if (!pmtRec.HasFADCBaseline(gain))
883 auto& baseline = pmtRec.GetFADCBaseline(gain);
885 const int n = baseline.GetSize();
886 for (
int i = 0; i < n; ++i)
887 baseline[i] = onlineBaseline;
892 SdCalibrator::ComputeBaselines(
Station& station)
909 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
918 const int traceLength = trace.
GetSize();
929 const int saturationValue = dStation.GetSaturationValue();
932 bool seenSaturation =
false;
933 bool hitsZero =
false;
943 const int startValue = trace[startBin];
946 while (stopBin < traceLength) {
947 if (
abs(startValue - trace[stopBin]) > sigma)
952 if (startValue >= saturationValue) {
953 if (!startBin && stopBin == traceLength) {
956 seenSaturation =
true;
958 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
960 <<
" gain (saturated): Whole trace saturated.";
969 seenSaturation =
true;
972 if (!startValue && seenSaturation) {
975 startBin = stopBin = traceLength;
978 if (stopBin-startBin < minLength) {
985 if (fApplyBackwardFlatPieceCheck) {
987 const int reverseStartValue =
988 accumulate(&trace[startBin], &trace[stopBin], 0) / (stopBin - startBin);
989 int reverseBin = stopBin - 1;
990 while (reverseBin > startBin) {
991 if (
abs(reverseStartValue - trace[reverseBin]) > sigma)
996 if (reverseBin == startBin) {
1011 }
while (stopBin < traceLength);
1014 if (!flatPieces.empty() &&
1021 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
1023 "No useful baseline found in the first "
1028 }
while (flatPieces.empty() && sigma <= saturationValue);
1030 if (flatPieces.empty()) {
1031 MakeFlatBaseline(pmt, gain);
1033 pmtRec.SetFADCSaturatedBins(-1, gain);
1035 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
1037 << (seenSaturation ?
" (saturated):" :
":")
1038 <<
"No baseline found; using LS value.";
1044 vector<double> flatPieceMean;
1045 flatPieceMean.reserve(flatPieces.size());
1046 double meanErrorMaxPiece = 0;
1047 int maxPieceLength = 0;
1048 for (
const auto& fp : flatPieces) {
1049 const auto sigma = for_each(&trace[fp.first], &trace[fp.second], Accumulator::SampleStandardDeviation());
1050 flatPieceMean.push_back(sigma.GetAverage());
1051 if (sigma.GetN() > maxPieceLength) {
1052 maxPieceLength = sigma.GetN();
1053 meanErrorMaxPiece = sigma.GetStandardDeviation();
1058 flatPieceMean.back() = 0;
1060 pmtRec.SetFADCBaselineError(meanErrorMaxPiece, gain);
1062 if (sigma > 3 && !seenSaturation) {
1064 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
1066 "Noisy baseline, sigma = " << sigma <<
", RMS = " << meanErrorMaxPiece;
1070 pmtRec.SetFADCBaselineWindow(sigma, gain);
1072 if (!pmtRec.HasFADCBaseline(gain))
1073 pmtRec.MakeFADCBaseline(gain);
1074 auto& baseline = pmtRec.GetFADCBaseline(gain);
1078 const double recoveryFactor = 0.000158;
1080 double previousBaseline = flatPieceMean[0];
1085 for (
int i = flatPieces[0].first - 1; i >= 0; --i) {
1086 const double signal = trace[i] - previousBaseline;
1089 baseline[i] = previousBaseline + charge * recoveryFactor;
1094 for (
unsigned int i = flatPieces[0].first; i < flatPieces[0].second; ++i)
1095 baseline[i] = previousBaseline;
1098 const unsigned int nPieces = flatPieces.size();
1099 for (
unsigned int p = 1;
p < nPieces; ++
p) {
1100 const double nextBaseline = flatPieceMean[
p];
1101 const int start = flatPieces[
p-1].second;
1102 const int stop = flatPieces[
p].first;
1103 const int holeLength = stop - start;
1104 const double deltaBaselinePerBin =
1105 (nextBaseline - previousBaseline) / holeLength;
1108 for (
int i = start ; i < stop; ++i) {
1109 const double base = previousBaseline + (i - start) * deltaBaselinePerBin;
1110 const double signal = trace[i] - base;
1114 const double totalCharge = charge;
1115 if (totalCharge / holeLength < 2) {
1117 for (
int i = start ; i < stop; ++i)
1118 baseline[i] = previousBaseline + (i - start) * deltaBaselinePerBin;
1120 const double deltaBaselinePerCharge =
1121 (nextBaseline - previousBaseline) / totalCharge;
1124 for (
int i = start ; i < stop; ++i) {
1125 const double base = previousBaseline + (i - start) * deltaBaselinePerBin;
1126 const double signal = trace[i] - base;
1128 charge += trace[i] - base;
1129 baseline[i] = previousBaseline + charge * deltaBaselinePerCharge;
1133 for (
unsigned int i = stop; i < flatPieces[
p].second; ++i)
1134 baseline[i] = nextBaseline;
1135 previousBaseline = nextBaseline;
1141 for (
int i = flatPieces[nPieces-1].
second; i < traceLength; ++i) {
1142 const double signal = trace[i] - previousBaseline;
1145 baseline[i] = previousBaseline - charge * recoveryFactor;
1150 pmtRec.SetFADCSaturatedBins(-1, gain);
1155 if (IsTestStation(station.
GetId()) &&
1156 (traceLength ==
int(dStation.GetFADCTraceLength()))) {
1157 const int registersStart = int(dStation.GetFADCTraceLength()) - 8;
1158 for (
int i = registersStart; i < int(dStation.GetFADCTraceLength()); ++i)
1159 baseline[i] = trace[i];
1166 SdCalibrator::MakeComponentVEMTraces(
PMT& pmt)
1171 const double vemFactor =
1174 if (multiFADCTrace.GetNLabels() < 2)
1177 bool didComponents =
false;
1178 for (
const auto& component : multiFADCTrace) {
1184 if (!pmtRec.HasVEMTrace(comp))
1185 pmtRec.MakeVEMTrace(comp);
1186 auto& vemTrace = pmtRec.GetVEMTrace(comp);
1190 const int n = fadcTrace.
GetSize();
1191 const auto& baseline = pmtRec.GetFADCBaseline(gainUsed);
1196 const auto& fadcTrace = pmt.
GetFADCTrace(gainUsed, comp);
1197 const int n2 = fadcTrace.
GetSize();
1199 for (
int i = 0; i < n2; ++i)
1200 vemTrace[i] = (fadcTrace[i] - baseline[i]) * vemFactor;
1202 for (
int i = 0; i < n; ++i)
1203 vemTrace[i] = fadcTrace[i] * vemFactor;
1205 didComponents =
true;
1208 return didComponents;
1216 vector<const PMT*> validPMTs;
1218 bool didComponents =
false;
1220 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
1224 if (pmt.HasCalibData() && pmt.GetCalibData().IsTubeOk() && pmt.HasFADCTrace()) {
1226 if (BuildSignals(pmt, dStation.GetFADCTraceLength(), dStation.GetSaturationValue()) && pmt.HasRecData()) {
1229 validPMTs.push_back(&(pmt));
1232 if (!scintillator.HasMIPTrace())
1235 scintillator.GetMIPTrace().ResetAll();
1236 auto& mipTrace = scintillator.GetMIPTrace();
1237 const int traceLength = mipTrace.GetSize();
1238 const auto& pmtTrace = pmt.GetRecData().GetVEMTrace();
1239 for (
int i = 0; i < traceLength; ++i)
1240 mipTrace[i] = pmtTrace[i];
1244 if (pmt.HasSimData() && MakeComponentVEMTraces(pmt))
1245 didComponents =
true;
1249 if (!validPMTs.empty()) {
1250 const int nPMTs = validPMTs.size();
1258 const int traceLength = vemTrace.
GetSize();
1259 for (
const auto& pmt : validPMTs) {
1260 const auto& pmtTrace = (pmt)->GetRecData().GetVEMTrace();
1261 for (
int i = 0; i < traceLength; ++i)
1262 vemTrace[i] += pmtTrace[i] / nPMTs;
1267 SumPMTComponents(station);
1269 return validPMTs.size();
1274 SdCalibrator::BuildSignals(
PMT& pmt,
const unsigned int traceLength,
const int saturationValue)
1280 int highGainSaturatedBins = 0;
1281 for (
unsigned int i = 0; i < traceLength; ++i)
1282 if (highGainTrace[i] >= saturationValue)
1283 ++highGainSaturatedBins;
1296 int lowGainSaturatedBins = 0;
1297 for (
unsigned int i = 0; i < traceLength; ++i)
1298 if (lowGainTrace[i] >= saturationValue)
1299 ++lowGainSaturatedBins;
1305 if (lowGainSaturatedBins > maxBins) {
1306 pmtCalib.SetIsTubeOk(
false);
1310 if (highGainSaturatedBins > maxBins || lowGainSaturatedBins > maxBins ||
1311 (lowGainSaturatedBins && !highGainSaturatedBins)) {
1315 pmtCalib.SetIsTubeOk(
false);
1321 if (highGainSaturatedBins || isSPMT) {
1322 pmtCalib.SetIsTubeOk(
false);
1327 const auto gainUsed =
1329 pmtRec.SetGainUsed(gainUsed);
1331 if (!pmtRec.HasVEMTrace())
1332 pmtRec.MakeVEMTrace();
1333 auto& vemTrace = pmtRec.GetVEMTrace();
1336 auto& rawSignals = pmtRec.GetRawSignals();
1339 const double vemChargeFactor = pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
1341 bool isTubeOK =
true;
1343 const double gainFactor =
1345 const double gainPeakFactor = gainFactor / pmtRec.GetVEMPeak();
1348 const auto& baseline = pmtRec.GetFADCBaseline(gainUsed);
1351 const auto findSignalThresholdMultiplier =
1355 int binsWithLargeSignal = 0;
1356 int binsWithSignal = 0;
1357 int binsOverThresh = 0;
1361 for (
int i = 0; i < int(traceLength); ++i) {
1362 const int fadc = trace[i];
1363 if (fadc > largeFADCThreshold)
1364 ++binsWithLargeSignal;
1365 const double fadcSignal = fadc - baseline[i];
1369 if (fadcSignal > minFADCValue)
1371 const double signal = fadcSignal * gainPeakFactor;
1372 vemTrace[i] = signal;
1375 const double testSignal =
1376 fTreatHGLGEqualInSignalSearch ? fadcSignal : highGainTrace[i] - highGainBaseline[i];
1377 if (testSignal > findSignalThresholdMultiplier * fFindSignalThreshold) {
1379 if (!binsOverThresh)
1387 if (binsOverThresh >= findSignalThresholdMultiplier * fFindSignalBinsAboveThreshold)
1388 rawSignals.push_back(
SignalSegment(start, i, binsOverThresh, charge * vemChargeFactor, max));
1395 if (binsOverThresh >= findSignalThresholdMultiplier * fFindSignalBinsAboveThreshold) {
1396 rawSignals.push_back(
SignalSegment(start, traceLength, binsOverThresh, charge * vemChargeFactor, max));
1402 if (!isTubeOK && !fIsUUB) {
1403 pmtCalib.SetIsTubeOk(
false);
1408 auto rawIt = rawSignals.begin();
1409 if (rawIt != rawSignals.end()) {
1411 auto& signals = pmtRec.GetSignals();
1414 signals.push_back(*rawIt);
1416 for (++rawIt; rawIt != rawSignals.end(); ++rawIt) {
1417 auto& current = signals.back();
1418 const int dist = rawIt->fStart - current.fStop;
1419 const int maxDist = signalMaxDist + current.fBinsOverThresh;
1421 if (dist >= maxDist ||
1422 (0.3*rawIt->fCharge >= current.fCharge && rawIt->fMaxValue >= 5) ||
1424 signals.push_back(*rawIt);
1427 const double addCharge =
1428 accumulate(&vemTrace[current.fStop], &vemTrace[rawIt->fStart], rawIt->fCharge);
1429 current.fCharge += addCharge * vemChargeFactor;
1430 current.fStop = rawIt->fStop;
1431 current.fBinsOverThresh += rawIt->fBinsOverThresh;
1432 if (current.fMaxValue < rawIt->fMaxValue)
1433 current.fMaxValue = rawIt->fMaxValue;
1442 template<
typename T1,
typename T2>
1448 {
return this->
second < interval.first; }
1451 {
return interval.second > this->first && interval.first < this->
second; }
1456 if (interval.first < this->first)
1457 this->first = interval.first;
1458 if (interval.second > this->second)
1459 this->
second = interval.second;
1468 vector<PMT*> validPMTs;
1469 typedef set<Interval<int, int>> Sections;
1472 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
1474 for (
auto& pmt : station.PMTsRange()) {
1476 if (pmt.HasCalibData() &&
1477 pmt.GetCalibData().IsTubeOk() &&
1480 validPMTs.push_back(&pmt);
1482 auto& signals = pmt.GetRecData().GetSignals();
1484 for (
const auto& sig : signals) {
1488 for (pair<Sections::iterator, bool> where; ; ) {
1489 where = sections.insert(newSection);
1490 if (!where.second) {
1492 newSection.
Merge(*where.first);
1493 sections.erase(where.first);
1504 const int nPMTs = validPMTs.size();
1508 const int traceLength = dStation.GetFADCTraceLength();
1509 const auto findSignalThresholdMultiplier =
1511 auto nextSectionIt = sections.begin();
1512 auto currentSectionIt = nextSectionIt;
1513 while (currentSectionIt != sections.end()) {
1515 int newStop = currentSectionIt->second + 10;
1516 if (newStop > traceLength)
1517 newStop = traceLength;
1519 if (nextSectionIt != sections.end() && newStop > nextSectionIt->first)
1520 newStop = nextSectionIt->first;
1521 const int start = currentSectionIt->first;
1525 int binsOverThresh = 0;
1527 for (
const auto& pmtp : validPMTs) {
1528 const auto& pmt = *pmtp;
1529 const auto& pmtRec = pmt.GetRecData();
1530 const auto gainUsed = pmtRec.GetGainUsed();
1534 const auto& baseline =
1535 pmtRec.GetFADCBaseline(fTreatHGLGEqualInSignalSearch ? gainUsed : sdet::PMTConstants::eHighGain);
1538 for (
int i = start; i < newStop; ++i) {
1539 if (trace[i] - baseline[i] >= findSignalThresholdMultiplier * fFindSignalThreshold)
1541 vemSum += vemTrace[i];
1543 const double factor = pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
1544 charge += vemSum * factor;
1546 stationSignals.emplace_back(start, newStop,
double(binsOverThresh)/nPMTs, charge/nPMTs);
1554 if (station.HasScintillator()) {
1555 const auto& pmt = station.GetScintillatorPMT();
1556 if (pmt.HasRecData()) {
1557 const auto& pmtSignals = station.GetScintillatorPMT().GetRecData().GetSignals();
1558 auto& scintillatorSignals = station.GetScintillator().GetSignals();
1559 scintillatorSignals.clear();
1560 for (
auto const signal : pmtSignals)
1561 scintillatorSignals.push_back(signal);
1573 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
1576 const unsigned int nSignals = signals.size();
1581 for (
auto& pmt : station.PMTsRange()) {
1582 if (pmt.HasRecData() &&
1583 pmt.HasCalibData() && pmt.GetCalibData().IsTubeOk()) {
1584 const auto& pmtRec = pmt.GetRecData();
1594 int maxSignalIndex = 0;
1595 double maxSignal = signals[0].fCharge;
1596 for (
unsigned int i = 1; i < nSignals; ++i) {
1597 if (maxSignal < signals[i].fCharge) {
1599 maxSignal = signals[i].fCharge;
1603 const int start = signals[maxSignalIndex].fStart;
1604 const int stop = signals[maxSignalIndex].fStop;
1612 stRec.SetSignalEndSlot(stop - 1);
1616 int scintillatorStart = 0;
1617 int scintillatorStop = 0;
1620 const auto& scintillatorSignals = scintillator.
GetSignals();
1622 const int length = dStation.GetFADCTraceLength();
1624 if (scintillatorSignals.empty() ||
1625 fIncludeWaterCherenkovDetectorInScintillatorStartStopDetermination) {
1626 const double timeOffset = dStation.GetScintillatorPMT().GetTimeOffset();
1627 const int traceBinOffset = floor(timeOffset / dStation.GetFADCBinSize());
1628 scintillatorStart = min(start + traceBinOffset, length);
1629 scintillatorStop = min(stop + traceBinOffset, length);
1632 if (!scintillatorSignals.empty()) {
1637 double maxCharge = scintillatorSignals[0].fCharge;
1638 for (
unsigned int i = 1, n = scintillatorSignals.size(); i < n; ++i) {
1639 if (maxCharge < scintillatorSignals[i].fCharge) {
1641 maxCharge = scintillatorSignals[i].fCharge;
1645 const auto& maxSignal = scintillatorSignals[maxIndex];
1646 if (scintillatorStart && scintillatorStop) {
1647 scintillatorStart =
max(0, min(scintillatorStart, maxSignal.fStart));
1648 scintillatorStop = min(length,
max(scintillatorStop, maxSignal.fStop));
1650 scintillatorStart =
max(0, maxSignal.fStart);
1651 scintillatorStop = min(length, maxSignal.fStop);
1655 if (!scintillator.HasRecData())
1656 scintillator.MakeRecData();
1657 auto& scintillatorRec = scintillator.GetRecData();
1659 scintillatorRec.SetSignalStartSlot(scintillatorStart);
1661 scintillatorRec.SetSignalEndSlot(scintillatorStop - 1);
1667 const auto peak = for_each(&vemTrace[start+1], &vemTrace[stop], Accumulator::Max<double>(vemTrace[start]));
1668 stRec.SetPeakAmplitude(peak.GetMax());
1671 bool highGainSaturation =
false;
1672 bool lowGainSaturation =
false;
1674 double totalCharge = 0;
1675 double spmtCharge = 0;
1676 double spmtChargeErr = 0;
1678 Accumulator::SampleStandardDeviationN shapeStat;
1679 Accumulator::SampleStandardDeviationN riseStat;
1680 Accumulator::SampleStandardDeviationN fallStat;
1681 Accumulator::SampleStandardDeviationN t40Stat;
1682 Accumulator::SampleStandardDeviationN t50Stat;
1685 if (pmt.HasCalibData() && pmt.GetCalibData().IsTubeOk()) {
1686 auto& pmtRec = pmt.GetRecData();
1691 highGainSaturation =
true;
1693 lowGainSaturation =
true;
1695 const auto& vemTrace = pmtRec.GetVEMTrace();
1697 double charge = accumulate(&vemTrace[start], &vemTrace[stop], 0.);
1699 ComputeShapeRiseFallPeak(pmtRec, dStation.GetFADCBinSize(), start, start, stop, charge);
1700 charge *= pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
1701 pmtRec.SetTotalCharge(charge);
1702 totalCharge += charge;
1703 shapeStat(pmtRec.GetShapeParameter());
1704 riseStat(pmtRec.GetRiseTime());
1705 fallStat(pmtRec.GetFallTime());
1706 t40Stat(pmtRec.GetT40());
1707 t50Stat(pmtRec.GetT50());
1708 const double peak = pmtRec.GetPeakAmplitude();
1710 pmtRec.SetAreaOverPeak(charge / peak);
1717 if (!scintillator.HasMIPTrace())
1720 if (!scintillator.HasRecData())
1721 scintillator.MakeRecData();
1722 auto& scinRec = scintillator.GetRecData();
1724 const unsigned int scintillatorStart = scinRec.GetSignalStartSlot();
1725 const unsigned int scintillatorStop = scinRec.GetSignalEndSlot() + 1;
1727 const auto& mipTrace = scintillator.GetMIPTrace();
1730 scintillator.SetHighGainSaturation();
1732 scintillator.SetLowGainSaturation();
1734 double charge = accumulate(&mipTrace[scintillatorStart], &mipTrace[scintillatorStop], 0.);
1735 ComputeShapeRiseFallPeak(pmtRec, dStation.GetFADCBinSize(), scintillatorStart, scintillatorStart, scintillatorStop, charge);
1736 charge *= pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
1737 pmtRec.SetTotalCharge(charge);
1740 scinRec.SetTotalSignal(charge, 0);
1741 scinRec.SetRiseTime(pmtRec.GetRiseTime(), 0);
1751 const int spmtStart =
max(0, start - fBinsBeforeStartForSPMT);
1753 if (pmtRec.HasVEMTrace()) {
1754 const auto& vemTrace = pmtRec.GetVEMTrace();
1755 charge = accumulate(&vemTrace[spmtStart], &vemTrace[stop], 0.);
1756 ComputeShapeRiseFallPeak(pmtRec, dStation.GetFADCBinSize(), spmtStart, spmtStart, stop, charge);
1757 charge *= pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
1758 peak = pmtRec.GetPeakAmplitude();
1760 spmtCharge = charge;
1761 spmtChargeErr = charge * pmtRec.GetVEMChargeError() / pmtRec.GetVEMCharge();
1763 pmtRec.SetTotalCharge(spmtCharge, spmtChargeErr);
1765 pmtRec.SetAreaOverPeak(charge / peak);
1772 totalCharge /= nPMTs;
1773 stRec.SetTotalSignal(totalCharge);
1775 if (highGainSaturation)
1778 if (lowGainSaturation) {
1780 #if USE_SPMT_SIGNAL_AS_TOTAL
1784 if (spmtCharge > 0 && spmtChargeErr > 0)
1785 stRec.SetTotalSignal(spmtCharge, spmtChargeErr);
1789 warn <<
"Station " << station.
GetId() <<
": zero SmallPMT signal after successful calibration!";
1796 if (totalCharge <= 0)
1800 stRec.SetShapeParameter(shapeStat.GetAverage(nPMTs), 0);
1801 stRec.SetRiseTime(riseStat.GetAverage(nPMTs), 0);
1802 stRec.SetFallTime(fallStat.GetAverage(nPMTs), 0);
1803 stRec.SetT40(t40Stat.GetAverage(nPMTs), 0);
1804 stRec.SetT50(t50Stat.GetAverage(nPMTs), 0);
1806 stRec.SetShapeParameter(shapeStat.GetAverage(nPMTs),
1807 shapeStat.GetStandardDeviation(nPMTs));
1808 stRec.SetRiseTime(riseStat.GetAverage(nPMTs),
1809 riseStat.GetStandardDeviation(nPMTs));
1810 stRec.SetFallTime(fallStat.GetAverage(nPMTs),
1811 fallStat.GetStandardDeviation(nPMTs));
1812 stRec.SetT40(t40Stat.GetAverage(nPMTs),
1813 t40Stat.GetStandardDeviation(nPMTs));
1814 stRec.SetT50(t50Stat.GetAverage(nPMTs),
1815 t50Stat.GetStandardDeviation(nPMTs));
1821 const TimeStamp gpsTime(gps.GetSecond(), gps.GetCorrectedNanosecond());
1823 const double fadcBinSize = dStation.GetFADCBinSize();
1828 const TimeStamp traceTime = gpsTime + pldTimeOffset -
1829 TimeInterval(dStation.GetFADCTraceLength() * fadcBinSize);
1834 stRec.SetSignalStartTime(signalTime);
1839 if (scintillator.HasRecData()) {
1841 const TimeStamp scinSignalTime = traceTime + TimeInterval((scinRec.GetSignalStartSlot() - 0.5) * fadcBinSize);
1842 scinRec.SetSignalStartTime(scinSignalTime);
constexpr int GetChargeHistogramSmallThreshold(const bool isUub)
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Traces calibrated in VEM Peak.
int GetId() const
Get the station Id.
bool HasRecData() const
Check for existenc of PMT reconstructed data object.
constexpr T Sqr(const T &x)
Holds result of the quadratic fit.
class to hold data at PMT level
total (shower and background)
constexpr int GetBinsWithSignalThreshold(const bool isUub)
void SetSignalStartSlot(const unsigned int slot)
Start time of the signal in time slots from beginning of trace.
constexpr int GetSaturatedBinsMaximum(const bool isUub)
constexpr int GetLargeFADCThreshold(const bool isUub)
PMTCalibData & GetCalibData()
Get object containing PMT calibration data.
constexpr int GetBinsWithLargeSignalThreshold(const bool isUub)
sdet::PMTConstants::PMTType GetType() const
double GetExtremePositionError() const
void SetShapeParameter(const double shape)
PMTRecData & GetRecData()
Get object containing PMT reconstructed data.
SignalSegmentCollection & GetSignals()
void SetFallTime(const double fallTime, const double rms)
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
ScintillatorRecData & GetRecData()
Get object containing scintillator reconstructed data.
#define INFO(message)
Macro for logging informational messages.
void SetTraceStartTime(const utl::TimeStamp &Time)
Set absolute start time of the VEM trace.
void Init()
Initialise the registry.
constexpr int GetFindSignalThresholdMultiplier(const bool isUub)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
void SetIsTubeOk(const bool ok=true)
void MakeFADCBaseline(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain)
unsigned int GetId() const
Return Id of the PMT.
void ApplyTimeCorrection(StationGPSData &gpsData)
constexpr double GetNominalVEMPeak(const bool isUub)
bool HasSmallPMTData() const
void MakeRecData()
Make PMT reconstructed data object.
A TimeStamp holds GPS second and nanosecond for some event.
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
signal trace calibrated in [VEM charge]
Exception for reporting variable out of valid range.
SmallPMTCalibData & GetCalibData()
void SetPeakAmplitude(const double peak)
const char * Plural(const T n)
unsigned int GetTick() const
FlatPieceCollection & GetBaselineFlatPieces(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain)
oss<< "0b";oss<< ((x >> i)&1);return oss.str();}template< class S, class V > std::string Join(const S &sep, const V &v)
void SetFADCSaturatedBins(const int num, const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain)
class to hold data at Station level
bool HasFADCTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if a FADC trace exists. Trace source may be specified.
void SetLowGainSaturation(const bool sat=true)
total FADC trace, with no saturation applied by FADC/baseline simulator
class to hold reconstructed data at PMT level
void SetT40(const double t40)
ExponentialFitter< Histogram > MakeExponentialFitter(const Histogram &histogram, const T &start, const T &stop)
constexpr double nanosecond
double abs(const SVector< n, T > &v)
SmallPMTData & GetSmallPMTData()
constexpr int GetSignalMaxDist(const bool isUub)
constexpr int GetMinLength(const bool isUub)
void MakeVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Make a VEM trace object.
sevt::StationGPSData & GetGPSData()
Get GPS data for the station.
bool HasVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check whether VEM trace exists.
utl::TraceD & GetFADCTraceD(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain, const StationConstants::SignalComponent source=StationConstants::eTotal)
Scintillator & GetScintillator()
#define WARNING(message)
Macro for logging warning messages.
QuadraticFitter< Histogram, ErrorPolicy > MakeQuadraticFitter(const Histogram &h, const ErrorPolicy)
void GetData(bool &b) const
Overloads of the GetData member template function.
Holds information characterizing portions of traces with signals.
sevt::StationCalibData & GetCalibData()
Get calibration data for the station.
utl::TraceI & GetFADCTrace(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain, const StationConstants::SignalComponent source=StationConstants::eTotal)
double GetBaseline(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
bool operator<(const Interval &interval) const
Interval(const pair< T1, T2 > &p)
void Merge(const Interval &interval)
const utl::MultiTraceI & GetMultiFADCTrace(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
constexpr int GetMinFADCValue(const bool isUub)
void MakeRecData()
Make station reconstructed data object.
void ResetAll(const T &value=T())
int GetPLDTimeOffset() const
void MakeMIPTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Make a VEM trace object.
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
sdet::PMTConstants::PMTGain GetGainUsed() const
bool HasRecData() const
Check whether station reconstructed data exists.
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
bool operator==(const Interval &interval) const
double GetExtremePosition() const
total (shower and background)
bool HasScintillator() const
void SetT50(const double t50)
int GetVersion() const
version of the onboard calibration
constexpr unsigned int GetUsefulBins(const bool isUub)
void SetSmallPMTSaturation(const bool sat=true)
bool IsInRange(const double x, const vector< double > &r)
sevt::StationTriggerData & GetTriggerData()
Get Trigger data for the station.
void SetRiseTime(const double riseTime, const double rms)
SignalSegmentCollection & GetSignals()
void SetHighGainSaturation(const bool sat=true)
#define ERROR(message)
Macro for logging error messages.
std::pair< unsigned int, unsigned int > Piece
pieces of relative FADC flatnes in format [first, second)
double GetSlopeError() const
const std::string & GetMessage() const
Retrieve the message from the exception.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)