13 #include <fwk/CentralConfig.h>
14 #include <det/VManager.h>
15 #include <utl/Branch.h>
16 #include <evt/Event.h>
17 #include <sevt/SEvent.h>
18 #include <sevt/Station.h>
19 #include <utl/TimeStamp.h>
20 #include <utl/String.h>
22 #include <sevt/PMTCalibData.h>
23 #include <sevt/PMTRecData.h>
24 #include <sevt/PMTQuality.h>
39 auto topB = CentralConfig::GetInstance()->GetTopBranch(
"SdPMTSignalShapeQualityChecker");
41 topB.GetChild(
"verbose").GetData(fVerbose);
43 topB.GetChild(
"maxNegStepsAfterDecoLowGain").GetData(fMaxNegStepsAfterDecoLowGain);
44 topB.GetChild(
"maxNegStepsAfterDecoHighGain").GetData(fMaxNegStepsAfterDecoHighGain);
45 topB.GetChild(
"maxNegStepImbalanceAfterDecoLowGain").GetData(fMaxNegStepImbalanceAfterDecoLowGain);
46 topB.GetChild(
"maxNegStepImbalanceAfterDecoHighGain").GetData(fMaxNegStepImbalanceAfterDecoHighGain);
47 topB.GetChild(
"maxBaselineRMSLowGain").GetData(fMaxBaselineRMSLowGain);
48 topB.GetChild(
"maxBaselineRMSHighGain").GetData(fMaxBaselineRMSHighGain);
49 topB.GetChild(
"maxLateSignal").GetData(fMaxLateSignal);
50 topB.GetChild(
"maxLateSignalFraction").GetData(fMaxLateSignalFraction);
51 topB.GetChild(
"lateSignalExtremeRatio").GetData(fLateSignalExtremeRatio);
59 SdPMTSignalShapeQualityChecker::PMTTraceChecks(
sevt::Station& currentStation)
61 vector<bool> thispmtusable;
65 vector<unsigned int> workingPMTsIds;
66 for (
const auto& pmt : currentStation.PMTsRange()) {
67 if (pmt.HasCalibData() && pmt.HasFADCTrace())
68 workingPMTsIds.push_back(pmt.GetId());
70 const int nPMTs = workingPMTsIds.size();
72 vector<unsigned int> decaystepsmeanofothersveclg(nPMTs);
73 vector<unsigned int> decaystepsmeanofothersvechg(nPMTs);
74 vector<double> baselinermsveclg(nPMTs);
75 vector<double> baselinermsvechg(nPMTs);
76 vector<double> latesignalsveclg(nPMTs);
77 vector<double> latesignalsvechg(nPMTs);
78 vector<unsigned int> decaystepsveclg(nPMTs);
79 vector<unsigned int> decaystepsvechg(nPMTs);
80 vector<double> decaystepsimbalanceveclg(nPMTs);
81 vector<double> decaystepsimbalancevechg(nPMTs);
82 vector<double> latesignalextremeveclg(nPMTs);
83 vector<double> latesignalextremevechg(nPMTs);
84 vector<double> totalsignalsveclg(nPMTs);
85 vector<double> totalsignalsvechg(nPMTs);
86 vector<double> negativeintegralveclg(nPMTs);
87 vector<double> negativeintegralvechg(nPMTs);
89 double pmtlatesignalwodllg = 0;
90 double pmtlatesignalwodlhg = 0;
91 std::vector<double> trace_pmt_fadc_decolg;
92 std::vector<double> trace_pmt_fadc_decohg;
93 for (
int iPMT = 0; iPMT < nPMTs; ++iPMT) {
94 const auto& currPMT = currentStation.
GetPMT(workingPMTsIds[iPMT]);
95 trace_pmt_fadc_decolg.clear();
96 trace_pmt_fadc_decohg.clear();
97 double negstepafterdecolg2 = 0;
98 double negstepafterdecohg2 = 0;
99 double pmtbaselinermslg = 0;
100 double pmtbaselinermshg = 0;
101 double pmtlatesignalwodllg = 0;
102 double pmtlatesignalwodlhg = 0;
103 if (!currPMT.HasCalibData() || !currPMT.HasFADCTrace() || !currPMT.HasRecData() || !currPMT.GetRecData().HasVEMTrace())
106 const auto& thispmtvemtracelg = currPMT.GetRecData().GetVEMTrace();
107 const auto& thispmtvemtracehg = currPMT.GetRecData().GetVEMTrace();
112 double negativeintegrallg = 0;
113 for (
const auto& v : thispmtfadctracelg) {
115 negativeintegrallg += v;
117 negativeintegralveclg[iPMT] = negativeintegrallg;
120 double negativeintegralhg = 0;
121 for (
const auto& v : thispmtfadctracehg) {
123 negativeintegralhg += v;
125 negativeintegralvechg[iPMT] = negativeintegralhg;
127 double pmttotalsignallg = 0;
128 double pmttotalsignalhg = 0;
133 for (
unsigned int i = 0, n = thispmtvemtracelg.GetSize(); i < n; ++i) {
134 const auto lg = thispmtvemtracelg[i];
135 const auto hg = thispmtvemtracehg[i];
136 pmttotalsignallg += lg;
137 pmttotalsignalhg += hg;
138 if (350 <= i && i < 600) {
139 pmtlatesignalwodllg += lg;
140 pmtlatesignalwodlhg += hg;
151 totalsignalsveclg[iPMT] = pmttotalsignallg;
152 totalsignalsvechg[iPMT] = pmttotalsignalhg;
153 pmtlatesignalwodllg -= maxsiglg + thispmtvemtracelg[maxposlg-1] + thispmtvemtracelg[maxposlg+1];
154 pmtlatesignalwodlhg -= maxsighg + thispmtvemtracehg[maxposhg-1] + thispmtvemtracehg[maxposhg+1];
155 latesignalsveclg[iPMT] = pmtlatesignalwodllg;
156 latesignalsvechg[iPMT] = pmtlatesignalwodlhg;
157 if (currPMT.HasRecData()) {
158 const auto& pmtRec = currPMT.GetRecData();
165 baselinermsveclg[iPMT] = pmtbaselinermslg;
166 baselinermsvechg[iPMT] = pmtbaselinermshg;
167 const double decayFact = std::exp(-25/70.);
168 const double decayFact1 = 1 - decayFact;
169 for (
unsigned int i = 0, n = thispmtfadctracelg.GetSize(); i < n; ++i) {
171 trace_pmt_fadc_decolg.push_back(thispmtfadctracelg[i] - pmtbaselinelg);
173 trace_pmt_fadc_decolg.push_back(
174 (thispmtfadctracelg[i] - pmtbaselinelg - (thispmtfadctracelg[i-1] - pmtbaselinelg) * decayFact) / decayFact1
176 if (thispmtfadctracelg[i] < thispmtfadctracelg[i-1] &&
177 trace_pmt_fadc_decolg[i] < trace_pmt_fadc_decolg[i-1] &&
178 trace_pmt_fadc_decolg[i] >= 2) {
182 ++negstepafterdecolg2;
186 decaystepsveclg[iPMT] = negstepafterdecolg2;
187 for (
unsigned int i = 0, n = thispmtfadctracehg.GetSize(); i < n; ++i) {
189 trace_pmt_fadc_decohg.push_back(thispmtfadctracehg[i] - pmtbaselinehg);
191 trace_pmt_fadc_decohg.push_back(
192 (thispmtfadctracehg[i] - pmtbaselinehg - (thispmtfadctracehg[i-1] - pmtbaselinehg) * decayFact) / decayFact1
194 if (thispmtfadctracehg[i] < thispmtfadctracehg[i-1] &&
195 trace_pmt_fadc_decohg[i] < trace_pmt_fadc_decohg[i-1] &&
196 trace_pmt_fadc_decohg[i] >= 2) {
200 ++negstepafterdecohg2;
204 decaystepsvechg[iPMT] = negstepafterdecohg2;
209 unsigned int nrpmtusable = 0;
210 for (
int iPMT = 0; iPMT < nPMTs; ++iPMT) {
211 const auto& currPMT = currentStation.
GetPMT(workingPMTsIds[iPMT]);
212 if (!currPMT.HasRecData() || currPMT.GetRecData().GetTotalCharge() < 6 || currPMT.GetRecData().GetTotalCharge() > 2000)
213 thispmtusable.push_back(
false);
215 thispmtusable.push_back(
true);
221 for (
int iPMT = 0; iPMT < nPMTs; ++iPMT) {
222 if (!thispmtusable[iPMT])
224 for (
int jPMT = 0; jPMT < nPMTs; ++jPMT) {
225 if (!thispmtusable[jPMT] || iPMT == jPMT)
227 decaystepsmeanofothersveclg[iPMT] += decaystepsveclg[jPMT];
228 decaystepsmeanofothersvechg[iPMT] += decaystepsvechg[jPMT];
230 if (nrpmtusable > 1) {
231 decaystepsmeanofothersveclg[iPMT] /= double(nrpmtusable - 1);
232 decaystepsmeanofothersvechg[iPMT] /= double(nrpmtusable - 1);
234 if (!decaystepsmeanofothersveclg[iPMT])
235 decaystepsmeanofothersveclg[iPMT] = 1;
236 if (!decaystepsmeanofothersvechg[iPMT])
237 decaystepsmeanofothersvechg[iPMT] = 1;
238 double uncertaintylg2 = 0;
239 double uncertaintyhg2 = 0;
242 for (
int jPMT = 0; jPMT < nPMTs; ++jPMT) {
243 if (!thispmtusable[jPMT] || iPMT == jPMT)
245 uncertaintylg2 +=
std::max(1.,
double(decaystepsveclg[jPMT]));
246 uncertaintyhg2 +=
std::max(1.,
double(decaystepsvechg[jPMT]));
248 uncertaintylg2 =
sqrt(uncertaintylg2) / nrpmtusable;
249 uncertaintyhg2 =
sqrt(uncertaintyhg2) / nrpmtusable;
250 if (nrpmtusable <= 1)
251 uncertaintylg2 = 1000;
252 if (nrpmtusable <= 1)
253 uncertaintyhg2 = 1000;
254 imbalancelg =
std::abs(
double(decaystepsveclg[iPMT]) -
double(decaystepsmeanofothersveclg[iPMT])) / uncertaintylg2;
255 imbalancehg =
std::abs(
double(decaystepsvechg[iPMT]) -
double(decaystepsmeanofothersvechg[iPMT])) / uncertaintyhg2;
256 decaystepsimbalanceveclg[iPMT] = imbalancelg;
257 decaystepsimbalancevechg[iPMT] = imbalancehg;
259 bool latesignalextremelg =
false;
260 bool latesignalextremehg =
false;
261 for (
int jPMT = 0; jPMT < nPMTs; ++jPMT) {
262 if (!thispmtusable[jPMT] || iPMT == jPMT)
264 if (pmtlatesignalwodllg > fLateSignalExtremeRatio * latesignalsveclg[jPMT])
265 latesignalextremelg =
true;
266 if (pmtlatesignalwodlhg > fLateSignalExtremeRatio * latesignalsvechg[jPMT])
267 latesignalextremehg =
true;
269 latesignalextremeveclg[iPMT] = latesignalextremelg;
270 latesignalextremevechg[iPMT] = latesignalextremehg;
273 auto& currPMT = currentStation.
GetPMT(workingPMTsIds[iPMT]);
278 if (decaystepsveclg[iPMT] >= fMaxNegStepsAfterDecoLowGain &&
279 decaystepsimbalanceveclg[iPMT] >= fMaxNegStepImbalanceAfterDecoLowGain) {
283 if (decaystepsvechg[iPMT] >= fMaxNegStepsAfterDecoHighGain &&
284 decaystepsimbalancevechg[iPMT] >= fMaxNegStepImbalanceAfterDecoHighGain) {
286 pmtCalib.SetIsTubeOk(
false);
288 if (baselinermsveclg[iPMT] > fMaxBaselineRMSLowGain ||
289 negativeintegralveclg[iPMT] > 200) {
290 pmtCalib.SetIsLowGainOk(
false);
292 if (baselinermsvechg[iPMT] > fMaxBaselineRMSHighGain ||
293 negativeintegralvechg[iPMT] > 400) {
294 pmtCalib.SetIsTubeOk(
false);
297 if (latesignalsvechg[iPMT] > fMaxLateSignal &&
298 latesignalsvechg[iPMT] / totalsignalsvechg[iPMT] > fMaxLateSignalFraction &&
299 latesignalextremevechg[iPMT]) {
300 pmtCalib.SetIsTubeOk(
false);
301 pmtCalib.SetIsLowGainOk(
false);
310 SdPMTSignalShapeQualityChecker::Run(
Event& event)
313 INFO(
"Applying PMT quality flags according to information in raw event ...!");
327 auto& sEvent =
event.GetSEvent();
329 set<int> badStations;
331 for (
auto& station : sEvent.StationsRange()) {
333 PMTTraceChecks(station);
335 const auto sId = station.GetId();
339 for (
const auto& pmt : station.PMTsRange()) {
341 if (!pmt.HasCalibData())
346 const auto& pmtCalib = pmt.GetCalibData();
348 if (pmtCalib.IsTubeOk())
352 if (allbad && hasCalib > 0) {
353 badStations.insert(sId);
359 if (fVerbose && !badStations.empty()) {
PMTCalibData & GetCalibData()
Get object containing PMT calibration data.
#define INFO(message)
Macro for logging informational messages.
void Init()
Initialise the registry.
const char * Plural(const T n)
class to hold data at Station level
double abs(const SVector< n, T > &v)
double GetBaseline(const sdet::PMTConstants::PMTGain gain=sdet::PMTConstants::eHighGain) const
ResultFlag
Flag returned by module methods to the RunController.
PMT & GetPMT(const unsigned int pmtId)
Retrive a PMT by Id.
void SetIsLowGainOk(const bool ok)
total (shower and background)
string OfSortedIds(vector< int > ids)