2 #include <fwk/CentralConfig.h>
4 #include <sdet/SDetector.h>
5 #include <sevt/SEvent.h>
6 #include <sevt/EventTrigger.h>
25 return isUUB ? 90: 30;
34 return isUUB ? 600 : 200;
41 template<
typename T1,
typename T2>
44 operator<<(ostream& os, const pair<T1, T2>&
p)
46 return os <<
'[' <<
p.first <<
", " <<
p.second <<
']';
54 Get(
const bool first,
const pair<T, T>&
p)
56 return first ? p.first : p.second;
68 auto ubParametersB = topB.GetChild(
"ubParameters");
69 ubParametersB.GetChild(
"baselineEstimationLengths").GetData(fUbBaselineEstimationLengths);
70 ubParametersB.GetChild(
"minimumPeakSize").GetData(fUbMinimumPeakSize);
71 ubParametersB.GetChild(
"negativeSignalFactors").GetData(fUbNegativeSignalFactors);
73 auto ubSigmaLimitsB = ubParametersB.GetChild(
"sigmaLimits");
74 ubSigmaLimitsB.GetChild(
"upperSigma").GetData(fUbUpperSigma);
75 ubSigmaLimitsB.GetChild(
"lowerSigma").GetData(fUbLowerSigma);
76 ubSigmaLimitsB.GetChild(
"truncationSigma").GetData(fUbTruncationSigma);
78 auto uubParametersB = topB.GetChild(
"uubParameters");
79 uubParametersB.GetChild(
"baselineEstimationLengths").GetData(fUubBaselineEstimationLengths);
80 uubParametersB.GetChild(
"minimumPeakSize").GetData(fUubMinimumPeakSize);
81 uubParametersB.GetChild(
"negativeSignalFactors").GetData(fUubNegativeSignalFactors);
82 uubParametersB.GetChild(
"decayConstant").GetData(fUubDecayConstant);
84 auto uubSigmaLimitsB = uubParametersB.GetChild(
"sigmaLimits");
85 uubSigmaLimitsB.GetChild(
"upperSigma").GetData(fUubUpperSigma);
86 uubSigmaLimitsB.GetChild(
"lowerSigma").GetData(fUubLowerSigma);
87 uubSigmaLimitsB.GetChild(
"truncationSigma").GetData(fUubTruncationSigma);
90 info <<
"Parameters:\n"
92 " baselineEstimationLengths: " << fUbBaselineEstimationLengths <<
"\n"
93 " minimumPeakSize: " << fUbMinimumPeakSize <<
"\n"
94 " negativeSignalFactors: " << fUbNegativeSignalFactors <<
"\n"
96 " upperSigma: " << fUbUpperSigma <<
"\n"
97 " lowerSigma: " << fUbLowerSigma <<
"\n"
98 " truncationSigma: " << fUbTruncationSigma <<
"\n"
100 " baselineEstimationLengths: " << fUubBaselineEstimationLengths <<
"\n"
101 " minimumPeakSize: " << fUubMinimumPeakSize <<
"\n"
102 " negativeSignalFactors: " << fUubNegativeSignalFactors <<
"\n"
103 " decayConstant: " << fUubDecayConstant <<
"\n"
105 " upperSigma: " << fUubUpperSigma <<
"\n"
106 " lowerSigma: " << fUubLowerSigma <<
"\n"
107 " truncationSigma: " << fUubTruncationSigma;
119 auto& sEvent =
event.GetSEvent();
121 for (
auto& station : sEvent.StationsRange()) {
123 if (!station.HasTriggerData() ||
124 !station.HasCalibData() ||
125 !station.HasGPSData())
128 const auto& trig = station.GetTriggerData();
129 if (trig.IsRandom() ||
130 (trig.GetErrorCode() & 0xff) ||
131 station.GetCalibData().GetVersion() > 32000)
135 if (sEvent.HasTrigger()) {
136 const int trigSecond = sEvent.GetTrigger().GetTime().GetGPSSecond();
137 const int timeDiff = int(station.GetGPSData().GetSecond()) - trigSecond;
138 if (
abs(timeDiff) > 1)
142 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
143 const bool isUUB = dStation.IsUUB();
145 fBaselineEstimationLengths = isUUB ? fUubBaselineEstimationLengths : fUbBaselineEstimationLengths;
146 fNegativeSignalFactors = isUUB ? fUubNegativeSignalFactors : fUbNegativeSignalFactors;
147 fMinimumPeakSize = isUUB ? fUubMinimumPeakSize : fUbMinimumPeakSize;
148 fUpperSigma = isUUB ? fUubUpperSigma : fUbUpperSigma;
149 fLowerSigma = isUUB ? fUubLowerSigma : fUbLowerSigma;
150 fTruncationSigma = isUUB ? fUubTruncationSigma : fUbTruncationSigma;
152 if (!ComputeBaselines(station)) {
164 SdBaselineFinderKG::ComputeBaselines(
Station& station)
177 SdBaselineFinderKG::ComputeBaseline(
const Station& station,
193 if (!pmtRec.HasFADCBaseline(gain))
196 const bool isUUB = station.
IsUUB();
197 const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
199 auto& baseline = pmtRec.GetFADCBaseline(gain);
201 int traceLength = trace.
GetSize();
206 traceLength == int(dStation.GetFADCTraceLength())) {
207 const int cyclonBoardOffset = 8;
208 for (
int i = traceLength - cyclonBoardOffset; i < traceLength; ++i)
209 baseline[i] = trace[i];
210 traceLength -= cyclonBoardOffset;
213 const int baselineEstimationLength =
215 const double negativeSignalFactor =
220 const int endTracePoint = traceLength - baselineEstimationLength;
221 const int saturationValue = dStation.GetSaturationValue();
224 for (
int i = 0; i < traceLength; ++i) {
225 if (trace[i] >= saturationValue) {
226 pmtRec.SetFADCSaturatedBins(-1, gain);
232 const auto frontEstimates = ComputeBaselineEstimates(isUUB, trace, 0, baselineEstimationLength);
233 const auto endEstimates = ComputeBaselineEstimates(isUUB, trace, endTracePoint, baselineEstimationLength);
237 if (frontEstimates[2] < minLen || endEstimates[2] < minLen) {
239 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
241 "Trace too noisy, no baseline estimate possible.";
251 const double deltaB = endEstimates[0] - frontEstimates[0];
252 const double sigmaDelta =
sqrt(
Sqr(frontEstimates[1]) +
Sqr(endEstimates[1]));
254 const auto first = &trace[0];
255 const auto from = &trace[baselineEstimationLength];
256 const auto to = &trace[endTracePoint];
259 if (deltaB >= upperSigma * sigmaDelta) {
262 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
264 "Anomalous baseline fluctuation, end estimate is larger than front estimate.";
271 }
else if (deltaB >= 0 && deltaB < upperSigma * sigmaDelta) {
273 const auto robustConstant = ComputeBaselineEstimates(isUUB, trace, 0, traceLength);
274 for (
int i = 0; i < traceLength; ++i)
275 baseline[i] = robustConstant[0];
276 }
else if (deltaB >= -fLowerSigma * sigmaDelta && deltaB < 0) {
278 const int maxPointPosition = max_element(from, to) - first;
279 for (
int i = 0; i < traceLength; ++i)
280 baseline[i] = (i < maxPointPosition) ? frontEstimates[0] : endEstimates[0];
283 const int maxPoint = *std::max_element(from, to);
285 if (maxPoint - frontEstimates[0] > fMinimumPeakSize) {
287 for (
int i = 0; i < baselineEstimationLength; ++i)
288 baseline[i] = frontEstimates[0];
289 const double db = deltaB / (endTracePoint - baselineEstimationLength);
290 for (
int i = baselineEstimationLength; i < endTracePoint; ++i)
291 baseline[i] = frontEstimates[0] + (i - baselineEstimationLength) * db;
292 for (
int i = endTracePoint; i < traceLength; ++i)
293 baseline[i] = endEstimates[0];
296 const double decayFactor = std::exp(-trace.GetBinning() / decayConstant);
297 for (
int k = 0; k < fNumberOfIterations; ++k) {
299 double totalCharge = 0;
300 for (
int i = baselineEstimationLength; i < endTracePoint; ++i)
301 totalCharge += trace[i] - baseline[i];
302 if (totalCharge < 0) {
304 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
306 "Failed to determine baseline, negative total charge detected.";
318 for (
int i = baselineEstimationLength; i < endTracePoint; ++i) {
319 charge += trace[i] - baseline[i];
320 const double w = charge / totalCharge;
321 baseline[i] = frontEstimates[0] * (1 - w) + endEstimates[0] * w;
325 std::vector<double> cumulativeCharge;
326 cumulativeCharge.reserve(traceLength);
328 for (
int i = baselineEstimationLength; i < traceLength; ++i) {
329 charge = trace[i] - baseline[i] + decayFactor * charge;
330 cumulativeCharge.push_back(charge);
333 const double referenceCharge = cumulativeCharge[traceLength - 1.5 * baselineEstimationLength];
334 for (
int i = baselineEstimationLength; i < traceLength; ++i) {
335 const double w = cumulativeCharge[i - baselineEstimationLength] / referenceCharge;
336 baseline[i] = frontEstimates[0] + deltaB * w;
342 const int maxPointPosition = max_element(from, to) - first;
343 for (
int i = 0; i < traceLength; ++i)
344 baseline[i] = (i < maxPointPosition) ? frontEstimates[0] : endEstimates[0];
349 double negativeCharge = 0;
350 for (
int i = baselineEstimationLength; i < endTracePoint; ++i) {
351 const auto sig = trace[i] - baseline[i];
353 negativeCharge += sig;
356 const int interpolatedTraceLenght = traceLength - 2 * baselineEstimationLength;
357 if (negativeCharge < -negativeSignalFactor * interpolatedTraceLenght) {
359 warn <<
"Station " << station.
GetId() <<
", PMT " << pmt.
GetId() <<
", "
361 "Too much negative charge detected, trace might be anomalous.";
377 SdBaselineFinderKG::ComputeBaselineEstimates(
const bool isUUB,
378 const TraceI& trace,
const int start,
const int baselineLength)
381 const int stop = start + baselineLength;
383 std::map<int, int> histogram;
385 for (
int i = start; i < stop; ++i) {
386 const int val = trace[i];
387 const int cnt = ++histogram[val];
392 for (
auto element : histogram) {
393 if (element.second == maxCount)
394 mode = element.first;
398 double standardDeviation = 0;
399 double baselineMean = 0;
400 double deltaExcludedBins = 10;
401 double usedBaselineLength = baselineLength + 1;
405 while (deltaExcludedBins > 0) {
407 double currentMean = 0;
409 int currentBaselineLength = 0;
411 for (
int i = start; i < stop; ++i) {
412 const auto& ti = trace[i];
413 if (
Is(ti).InRange(lowerLimit, upperLimit)) {
415 ++currentBaselineLength;
423 currentMean /= currentBaselineLength;
426 for (
int i = start; i < stop; ++i) {
427 const auto& ti = trace[i];
428 if (
Is(ti).InRange(lowerLimit, upperLimit))
429 variance +=
Sqr(ti - currentMean);
432 variance /= currentBaselineLength - 1;
436 deltaExcludedBins = usedBaselineLength - currentBaselineLength;
437 usedBaselineLength = currentBaselineLength;
440 const double d = fTruncationSigma * standardDeviation;
441 upperLimit = std::ceil(mode + d);
442 lowerLimit = std::floor(mode - d);
443 baselineMean = currentMean;
448 const double errorOfMean =
std::sqrt(
Sqr(standardDeviation) / usedBaselineLength);
449 const double minimalError = 0.5 /
std::sqrt(usedBaselineLength);
450 const double baselineError = (errorOfMean > minimalError) ? errorOfMean : minimalError;
452 return {baselineMean, baselineError, usedBaselineLength};
int GetId() const
Get the station Id.
bool HasRecData() const
Check for existenc of PMT reconstructed data object.
constexpr T Sqr(const T &x)
class to hold data at PMT level
IsProxy< T > Is(const T &x)
PMTCalibData & GetCalibData()
Get object containing PMT calibration data.
sdet::PMTConstants::PMTType GetType() const
PMTRecData & GetRecData()
Get object containing PMT reconstructed data.
bool HasCalibData() const
Check for existence of PMT calibration data object.
#define INFO(message)
Macro for logging informational messages.
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
void MakeFADCBaseline(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain)
unsigned int GetId() const
Return Id of the PMT.
void MakeRecData()
Make PMT reconstructed data object.
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.
constexpr int MinLength(const bool isUUB)
double abs(const SVector< n, T > &v)
constexpr unsigned int UsefulBins(const bool isUUB)
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
utl::TraceI & GetFADCTrace(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain, const StationConstants::SignalComponent source=StationConstants::eTotal)
ResultFlag
Flag returned by module methods to the RunController.
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
void SetIsLowGainOk(const bool ok)
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
void SetIsTubeOk(const bool ok)
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)