SdPMTSignalShapeQualityChecker.cc
Go to the documentation of this file.
1 
12 
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>
21 #include <sevt/PMT.h>
22 #include <sevt/PMTCalibData.h>
23 #include <sevt/PMTRecData.h>
24 #include <sevt/PMTQuality.h>
25 
26 using namespace std;
27 using namespace fwk;
28 using namespace det;
29 using namespace utl;
30 using namespace evt;
31 using namespace sevt;
32 
33 
35 
38  {
39  auto topB = CentralConfig::GetInstance()->GetTopBranch("SdPMTSignalShapeQualityChecker");
40 
41  topB.GetChild("verbose").GetData(fVerbose);
42 
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);
52 
53  return eSuccess;
54  }
55 
56 
57  // Checks traces itself for typical behaviour of oscilling baselines, afterpulses and long decay times
59  SdPMTSignalShapeQualityChecker::PMTTraceChecks(sevt::Station& currentStation)
60  {
61  vector<bool> thispmtusable;
62  double imbalancelg; // the imbalance of the 3 PMTs
63  double imbalancehg; // the imbalance of the 3 PMTs
64 
65  vector<unsigned int> workingPMTsIds;
66  for (const auto& pmt : currentStation.PMTsRange()) {
67  if (pmt.HasCalibData() && pmt.HasFADCTrace())
68  workingPMTsIds.push_back(pmt.GetId());
69  }
70  const int nPMTs = workingPMTsIds.size();
71 
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);
88 
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; // nr steps for the 3 PMTs in one Channel
98  double negstepafterdecohg2 = 0; // nr steps for the 3 PMTs in one Channel
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())
104  continue;
105  const auto& pmtCalibData = currPMT.GetCalibData();
106  const auto& thispmtvemtracelg = currPMT.GetRecData().GetVEMTrace();
107  const auto& thispmtvemtracehg = currPMT.GetRecData().GetVEMTrace();
108  const double pmtbaselinelg = pmtCalibData.GetBaseline(sdet::PMTConstants::eLowGain);
109  const double pmtbaselinehg = pmtCalibData.GetBaseline(sdet::PMTConstants::eHighGain);
110 
111  const auto& thispmtfadctracelg = currPMT.GetFADCTrace(sdet::PMTConstants::eLowGain, StationConstants::eTotal);
112  double negativeintegrallg = 0;
113  for (const auto& v : thispmtfadctracelg) {
114  if (v < 0)
115  negativeintegrallg += v;
116  }
117  negativeintegralveclg[iPMT] = negativeintegrallg;
118 
119  const auto& thispmtfadctracehg = currPMT.GetFADCTrace(sdet::PMTConstants::eHighGain, StationConstants::eTotal);
120  double negativeintegralhg = 0;
121  for (const auto& v : thispmtfadctracehg) {
122  if (v < 0)
123  negativeintegralhg += v;
124  }
125  negativeintegralvechg[iPMT] = negativeintegralhg;
126 
127  double pmttotalsignallg = 0;
128  double pmttotalsignalhg = 0;
129  double maxsiglg = 0;
130  double maxsighg = 0;
131  int maxposlg = 0;
132  int maxposhg = 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;
141  if (lg > maxsiglg) {
142  maxsiglg = lg;
143  maxposlg = i;
144  }
145  if (hg > maxsighg) {
146  maxsighg = hg;
147  maxposhg = i;
148  }
149  }
150  }
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();
159  pmtbaselinermslg = pmtRec.GetFADCBaselineError(sdet::PMTConstants::eLowGain);
160  pmtbaselinermshg = pmtRec.GetFADCBaselineError(sdet::PMTConstants::eHighGain);
161  } else {
162  pmtbaselinermslg = pmtCalibData.GetBaselineRMS(sdet::PMTConstants::eLowGain);
163  pmtbaselinermshg = pmtCalibData.GetBaselineRMS(sdet::PMTConstants::eHighGain);
164  }
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) {
170  if (!i)
171  trace_pmt_fadc_decolg.push_back(thispmtfadctracelg[i] - pmtbaselinelg); // first bin does not have to be deconvoluted
172  else {
173  trace_pmt_fadc_decolg.push_back(
174  (thispmtfadctracelg[i] - pmtbaselinelg - (thispmtfadctracelg[i-1] - pmtbaselinelg) * decayFact) / decayFact1
175  ); // calculate deconvolution of this bin
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) {
179  // Conditions for a step: negative step in normal trace &&
180  // negative step in deconvoluted trace &&
181  // second bin is at least 2 above baseline
182  ++negstepafterdecolg2; // count a step
183  }
184  }
185  }
186  decaystepsveclg[iPMT] = negstepafterdecolg2;
187  for (unsigned int i = 0, n = thispmtfadctracehg.GetSize(); i < n; ++i) {
188  if (!i)
189  trace_pmt_fadc_decohg.push_back(thispmtfadctracehg[i] - pmtbaselinehg); // first bin does not have to be deconvoluted
190  else {
191  trace_pmt_fadc_decohg.push_back(
192  (thispmtfadctracehg[i] - pmtbaselinehg - (thispmtfadctracehg[i-1] - pmtbaselinehg) * decayFact) / decayFact1
193  ); // calculate deconvolution of this bin
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) {
197  // Conditions for a step: negative step in normal trace &&
198  // negative step in deconvoluted trace &&
199  // second bin is at least 2 above baseline
200  ++negstepafterdecohg2; // count a step
201  }
202  }
203  }
204  decaystepsvechg[iPMT] = negstepafterdecohg2;
205  }
206 
207  // now about the imbalance
208 
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);
214  else {
215  thispmtusable.push_back(true);
216  ++nrpmtusable;
217  }
218  //currentStation.GetSignals();
219  }
220 
221  for (int iPMT = 0; iPMT < nPMTs; ++iPMT) {
222  if (!thispmtusable[iPMT])
223  continue;
224  for (int jPMT = 0; jPMT < nPMTs; ++jPMT) {
225  if (!thispmtusable[jPMT] || iPMT == jPMT)
226  continue;
227  decaystepsmeanofothersveclg[iPMT] += decaystepsveclg[jPMT];
228  decaystepsmeanofothersvechg[iPMT] += decaystepsvechg[jPMT];
229  }
230  if (nrpmtusable > 1) {
231  decaystepsmeanofothersveclg[iPMT] /= double(nrpmtusable - 1); // divide by nr of PMTs
232  decaystepsmeanofothersvechg[iPMT] /= double(nrpmtusable - 1); // divide by nr of PMTs
233  }
234  if (!decaystepsmeanofothersveclg[iPMT])
235  decaystepsmeanofothersveclg[iPMT] = 1;
236  if (!decaystepsmeanofothersvechg[iPMT])
237  decaystepsmeanofothersvechg[iPMT] = 1;
238  double uncertaintylg2 = 0; // uncertainty of the mean
239  double uncertaintyhg2 = 0; // uncertainty of the mean
240  // PMTs with 0 negative steps are treated as if they had one negative steps to avoid uncertainties of 0
241  // continue here!!!!!!meanofothernegstepafterdecohg2
242  for (int jPMT = 0; jPMT < nPMTs; ++jPMT) {
243  if (!thispmtusable[jPMT] || iPMT == jPMT)
244  continue;
245  uncertaintylg2 += std::max(1., double(decaystepsveclg[jPMT]));
246  uncertaintyhg2 += std::max(1., double(decaystepsvechg[jPMT]));
247  }
248  uncertaintylg2 = sqrt(uncertaintylg2) / nrpmtusable;
249  uncertaintyhg2 = sqrt(uncertaintyhg2) / nrpmtusable;
250  if (nrpmtusable <= 1)
251  uncertaintylg2 = 1000; // uncertainty of the mean
252  if (nrpmtusable <= 1)
253  uncertaintyhg2 = 1000; // uncertainty of the mean
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;
258 
259  bool latesignalextremelg = false;
260  bool latesignalextremehg = false;
261  for (int jPMT = 0; jPMT < nPMTs; ++jPMT) {
262  if (!thispmtusable[jPMT] || iPMT == jPMT)
263  continue;
264  if (pmtlatesignalwodllg > fLateSignalExtremeRatio * latesignalsveclg[jPMT])
265  latesignalextremelg = true;
266  if (pmtlatesignalwodlhg > fLateSignalExtremeRatio * latesignalsvechg[jPMT])
267  latesignalextremehg = true;
268  }
269  latesignalextremeveclg[iPMT] = latesignalextremelg;
270  latesignalextremevechg[iPMT] = latesignalextremehg;
271 
272  // MARK THIS PMT AS BAD
273  auto& currPMT = currentStation.GetPMT(workingPMTsIds[iPMT]);
274  //if (!currPMT.HasCalibData())
275  // currPMT.MakeCalibData();
276  auto& pmtCalib = currPMT.GetCalibData();
277 
278  if (decaystepsveclg[iPMT] >= fMaxNegStepsAfterDecoLowGain &&
279  decaystepsimbalanceveclg[iPMT] >= fMaxNegStepImbalanceAfterDecoLowGain) {
280  // if imbalance is at least 8.5 and there are at least 16 steps
281  pmtCalib.SetIsLowGainOk(false);
282  }
283  if (decaystepsvechg[iPMT] >= fMaxNegStepsAfterDecoHighGain &&
284  decaystepsimbalancevechg[iPMT] >= fMaxNegStepImbalanceAfterDecoHighGain) {
285  // if imbalance is at least 8.5 and there are at least 16 steps
286  pmtCalib.SetIsTubeOk(false);
287  }
288  if (baselinermsveclg[iPMT] > fMaxBaselineRMSLowGain ||
289  negativeintegralveclg[iPMT] > 200) {
290  pmtCalib.SetIsLowGainOk(false);
291  }
292  if (baselinermsvechg[iPMT] > fMaxBaselineRMSHighGain ||
293  negativeintegralvechg[iPMT] > 400) {
294  pmtCalib.SetIsTubeOk(false);
295  }
296 
297  if (latesignalsvechg[iPMT] > fMaxLateSignal &&
298  latesignalsvechg[iPMT] / totalsignalsvechg[iPMT] > fMaxLateSignalFraction &&
299  latesignalextremevechg[iPMT]) {
300  pmtCalib.SetIsTubeOk(false);
301  pmtCalib.SetIsLowGainOk(false);
302  }
303  }
304 
305  return eSuccess;
306  }
307 
308 
310  SdPMTSignalShapeQualityChecker::Run(Event& event)
311  {
312  if (fVerbose)
313  INFO("Applying PMT quality flags according to information in raw event ...!");
314 
315  if (!event.HasSEvent())
316  return eSuccess;
317 
318  PMTChecks(event);
319 
320  return eSuccess;
321  }
322 
323 
325  SdPMTSignalShapeQualityChecker::PMTChecks(evt::Event& event)
326  {
327  auto& sEvent = event.GetSEvent();
328 
329  set<int> badStations;
330 
331  for (auto& station : sEvent.StationsRange()) {
332 
333  PMTTraceChecks(station);
334 
335  const auto sId = station.GetId();
336  bool allbad = true;
337  int hasCalib = 0;
338 
339  for (const auto& pmt : station.PMTsRange()) {
340 
341  if (!pmt.HasCalibData())
342  continue;
343 
344  ++hasCalib;
345 
346  const auto& pmtCalib = pmt.GetCalibData();
347 
348  if (pmtCalib.IsTubeOk())
349  allbad = false;
350  }
351 
352  if (allbad && hasCalib > 0) {
353  badStations.insert(sId);
354  station.SetRejected(StationConstants::eAllPMTsBad);
355  }
356 
357  }
358 
359  if (fVerbose && !badStations.empty()) {
360  ostringstream info;
361  info << "Rejecting station" << String::Plural(badStations) << ' '
362  << String::OfSortedIds(badStations) << " because all PMTs are flagged as bad.";
363  INFO(info);
364  }
365 
366  return eSuccess;
367  }
368 
369 }
PMTCalibData & GetCalibData()
Get object containing PMT calibration data.
Definition: SEvent/PMT.h:56
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
const char * Plural(const T n)
Definition: String.h:104
#define max(a, b)
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
Definition: PMTCalibData.h:41
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
PMT & GetPMT(const unsigned int pmtId)
Retrive a PMT by Id.
void SetIsLowGainOk(const bool ok)
Definition: PMTCalibData.h:80
total (shower and background)
string OfSortedIds(vector< int > ids)
Definition: String.cc:65
bool HasSEvent() const

, generated on Tue Sep 26 2023.