DoublePeakDetector.cc
Go to the documentation of this file.
1 #include "DoublePeakDetector.h"
2 
3 // Offline header
4 #include <fwk/CentralConfig.h>
5 
6 #include <det/Detector.h>
7 #include <sdet/SDetector.h>
8 #include <sdet/Station.h>
9 
10 #include <evt/Event.h>
11 
12 #include <sevt/EventTrigger.h>
13 #include <sevt/Header.h>
14 #include <sevt/SEvent.h>
15 #include <sevt/Station.h>
16 #include <sevt/PMT.h>
17 #include <sevt/PMTCalibData.h>
18 #include <sevt/PMTRecData.h>
19 #include <sevt/StationRecData.h>
20 #include <sevt/StationTriggerData.h>
21 #include <sevt/StationCalibData.h>
22 
23 #include <utl/Trace.h>
24 #include <utl/TraceAlgorithm.h>
25 #include <utl/Reader.h>
26 #include <utl/ErrorLogger.h>
27 #include <utl/Math.h>
28 #include <utl/String.h>
29 
30 
31 #include <iostream>
32 #include <sstream>
33 #include <algorithm>
34 
35 
36 #include <config.h>
37 
38 #include <AugerEvent.h>
39 #include <IoSdData.h>
40 
41 using namespace fwk;
42 using namespace evt;
43 using namespace sevt;
44 using namespace utl;
45 using namespace std;
46 
47 using namespace DoublePeakDetectorNS;
48 
49 const double kBinSize = 25;
50 const double kBinThr = 0.02;
51 const double kPeakThr = 3;
52 const int kPeakWind = 10;
53 const int kGapWind = 15;
54 const double kMinScoreDiff = 0.15;
55 
56 int DoublePeakDetector::FindPeaks(const TraceD &trace, vector<signalBlock_t> &signalBlocks, const int nTraceBins)
57 {
58  for (int i = 0; i < nTraceBins - kPeakWind; i++)
59  {
60  double binValue = trace[i];
61  if (binValue < kBinThr) continue;
62 
63  double winSum = binValue;
64  double winPeak = binValue;
65  int nBinsOverThr = 0;
66  int blockStart = i - 1;
67  int blockEnd = i;
68  int coreBlockEnd = i;
69  bool blockFound = false;
70 
71  for (int j = i + 1; j < i + kPeakWind; j++) {
72  binValue = trace[j];
73  if (binValue < kBinThr) continue;
74  winSum += binValue;
75  nBinsOverThr++;
76 
77  if (winPeak < binValue) winPeak = binValue;
78 
79  if (winSum > kPeakThr) {
80  coreBlockEnd = j;
81  blockFound = true;
82  break;
83  }
84  }
85  if (nBinsOverThr == kPeakWind) {
86  coreBlockEnd = i + kPeakWind - 1;
87  blockFound = true;
88  }
89 
90  if (!blockFound) continue;
91 
92  blockEnd = coreBlockEnd;
93  signalBlock_t sigBlock;
94  sigBlock.start = blockStart * kBinSize;
95  // Add bins to the block
96  int nEmptyBins = 0;
97  for (int j = coreBlockEnd + 1; j < coreBlockEnd + nTraceBins; j++)
98  {
99  binValue = trace[j];
100 
101  if (binValue < kBinThr) {
102  nEmptyBins++;
103  if (nEmptyBins == kGapWind) {
104  break;
105  }
106  }
107  else {
108  nEmptyBins = 0;
109  blockEnd = j;
110  nBinsOverThr++;
111  winSum += binValue;
112  }
113  }
114 
115  sigBlock.end = blockEnd * kBinSize;
116 
117  sigBlock.score = winSum * nBinsOverThr;
118  signalBlocks.push_back(sigBlock);
119 
120  i = blockEnd;
121  }
122 
123  return signalBlocks.size();
124 }
125 
126 bool DoublePeakDetector::ComputeIsMultiple(const vector<signalBlock_t> &signalBlocks)
127 {
128 
129  unsigned int nBlocks = signalBlocks.size();
130  if (nBlocks < 2) return false;
131 
132  double maxScore = -1;
133  for (unsigned int i = 0; i < nBlocks; i++) {
134  double score = signalBlocks[i].score;
135  if (maxScore < score) {
136  maxScore = score;
137  }
138  }
139 
140  if (maxScore < 0) {
141  std::ostringstream error;
142  error << "\nError in trace!\n\n";
143  ERROR(error);
144  // throw -1000;
145  //return eFailure;
146  }
147 
148  unsigned int nSimilar = 0;
149  for (unsigned int i = 0; i < nBlocks; i++) {
150  double score = signalBlocks[i].score;
151  if (score / maxScore > kMinScoreDiff) {
152  nSimilar++;
153  if (nSimilar == 2)
154  {
155  return true;
156  }
157  }
158  }
159 
160  return false;
161 }
162 
164 {
165  Branch topB = CentralConfig::GetInstance()->GetTopBranch("DoublePeakDetector");
166  // TFile outFile("traceHistos.root","RECREATE");
167  // outFile.Close();
168  return eSuccess;
169 }
170 
171 VModule::ResultFlag DoublePeakDetector::Run(evt::Event &event)
172 {
173 
174  const auto& sDet = det::Detector::GetInstance().GetSDetector();
175  sevt::SEvent &sEvent = event.GetSEvent();
176 
177  // TFile outFile("traceHistos.root","UPDATE");
178  for (auto& sStation : sEvent.StationsRange()) {
179  if (sStation.IsCandidate() && sDet.GetStation(sStation.GetId()).IsInGrid()) {
180  const StationRecData &stRec = sStation.GetRecData();
181  const TraceD &trace = sStation.GetVEMTrace();
182  ostringstream os;
183  os << "Event:" << sEvent.GetHeader().GetId() << " Station: " << sStation.GetId();
184 
185  vector<signalBlock_t> signalBlocks;
186  double binning = trace.GetBinning();
187  int start = stRec.GetSignalStartSlot();
188  int end = stRec.GetSignalEndSlot() + 1;
189  const int traceLength = end - start;
190  const int nTraceBins = traceLength * binning;
191 
192  FindPeaks(trace, signalBlocks, nTraceBins);
193  bool isMultiple = ComputeIsMultiple(signalBlocks);
194 
195  if (isMultiple)
196  {
197  std::ostringstream info;
198  info << "Deleting: " << os.str() << "\n";
199  INFO(info);
200  StationTriggerData &trig = sStation.GetTriggerData();
202  sStation.SetRejected(StationConstants::eRandom);
203  trig.SetErrorCode(5001);
204  }
205 
206 
208  // Yann: I don't know where to select that a station has at least 2 active PMTs
209  // I put it here but I should ask.
210  // This should be something done by default
212  int pmtCounter = 0;
213  for (auto& pmt : sStation.PMTsRange()) {
214  if (pmt.HasCalibData() && pmt.GetCalibData().IsTubeOk()) {
215  pmtCounter++;
216  }
217  }
218  if (pmtCounter < 2) {
219  std::ostringstream info;
220  info << "Deleting: " << os.str() << "\n"
221  << "Too few PMTs"<< "\n";
222  INFO(info);
223  StationTriggerData &trig = sStation.GetTriggerData();
225  sStation.SetRejected(StationConstants::eRandom);
226  trig.SetErrorCode(5001);
227  }
228  else if (pmtCounter == 2 || pmtCounter == 3){}
229  else {
230  return eFailure;
231  }
233  }
234  }
235 
236  // outFile.Close();
237 
238  return eSuccess;
239 }
240 
241 VModule::ResultFlag DoublePeakDetector::Finish()
242 {
243  return eSuccess;
244 }
245 
246 // Configure (x)emacs for this file ...
247 // Local Variables:
248 // mode: c++
249 // compile-command: "make -C .. DoublePeakDetector/DoublePeakDetector.o -k"
250 // End:
Class to access station level reconstructed data.
const double kMinScoreDiff
const double kBinThr
const int kPeakWind
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetBinning() const
size of one slot
Definition: Trace.h:138
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
int GetId() const
Definition: SEvent/Header.h:20
void Init()
Initialise the registry.
Class representing a document branch.
Definition: Branch.h:107
unsigned int GetSignalStartSlot() const
Start time of the signal in time slots from beginning of trace.
const double kPeakThr
unsigned int GetSignalEndSlot() const
End time of the signal in time slots from beginning of trace.
const double kBinSize
const int kGapWind
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Station Trigger Data description
sevt::Header & GetHeader()
Definition: SEvent.h:155
void SetAlgorithm(const Algorithm algo)
std::vector< std::vector< double > > FindPeaks(const std::vector< double > &input, const double totalThreshold)
Definition: UnivTools.cc:9
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
void SetErrorCode(const int errorCode)
To exclude stations if there are multiple peaks close in time in the trace as explained and used in G...
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)

, generated on Tue Sep 26 2023.