RdMonitoring.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <complex>
3 #include <sstream>
4 #include <bitset>
5 
6 #include "RdMonitoring.h"
7 #include <TROOT.h>
8 
9 #include <TMinuit.h>
10 
11 #include <TMath.h>
12 #include <cstdio>
13 #include <cstdlib>
14 
15 #include <fwk/CentralConfig.h>
16 #include <fwk/LocalCoordinateSystem.h>
17 #include <fwk/CoordinateSystemRegistry.h>
18 
19 #include <evt/Event.h>
20 #include <revt/Header.h>
21 #include <revt/EventTrigger.h>
22 
23 #include <det/Detector.h>
24 #include <rdet/RDetector.h>
25 #include <rdet/Channel.h>
26 #include <rdet/Station.h>
27 
28 #include <utl/Trace.h>
29 #include <utl/TimeStamp.h>
30 #include <utl/LeapSeconds.h>
31 #include <utl/TraceAlgorithm.h>
32 #include <utl/ErrorLogger.h>
33 #include <utl/Reader.h>
34 #include <utl/FFTDataContainerAlgorithm.h>
35 #include <utl/config.h>
36 #include <utl/AugerUnits.h>
37 #include <utl/ErrorLogger.h>
38 #include <utl/StringCompare.h>
39 #include <utl/UTCDateTime.h>
40 
41 #include <utl/PhysicalConstants.h>
42 #include <utl/AxialVector.h>
43 #include <utl/Math.h>
44 
45 #include <evt/Event.h>
46 #include <evt/ShowerRecData.h>
47 #include <evt/ShowerRRecData.h>
48 #include <revt/REvent.h>
49 #include <revt/Station.h>
50 #include <revt/Header.h>
51 #include <revt/StationRecData.h>
52 
53 #include <CLHEP/Matrix/Matrix.h>
54 #include <CLHEP/Matrix/Vector.h>
55 
56 using namespace std;
57 using namespace utl;
58 using namespace fwk;
59 using namespace revt;
60 using namespace evt;
61 
62 namespace RdMonitoring {
63 
64  REvent* RdMonitoring::fgCurrentREvent;
65 
67  fCurRunId(0),
68  fCurEventId(0),
69  fCurStationId(0),
70  fCurChannelId(0),
71  fCurGPSSecond(0),
72  fPrevGPSSecond(0),
73  fDownsample10sTriggers(true),
74  fPathToStoreOutput(""),
75  fMinFrequency(0),
76  fMaxFrequency(0),
77  fOutputFileName(""),
78  fBeaconFrequencies(vector<double>()),
79  fSpectrumNoiseFilterSize(31),
80  fSpectrumPeakFilterSize(9),
81  fSpectrumMinPeakSNR(0),
82  fSpectrumFractionToSearch(0.01),
83  fTraceNSigmaRMS(5)
84  { }
85 
88  {
89  INFO("RdMonitoring::Init()");
90  string tmpstring;
91 
93  Branch topBranch =
94  CentralConfig::GetInstance()->GetTopBranch("RdMonitoring");
95  topBranch.GetChild("Downsample10sTriggers").GetData(tmpstring);
96  fDownsample10sTriggers = StringEquivalent(tmpstring, "yes");
97  topBranch.GetChild("pathToStoreOutput").GetData(fPathToStoreOutput);
98  topBranch.GetChild("minFrequency").GetData(fMinFrequency);
99  topBranch.GetChild("maxFrequency").GetData(fMaxFrequency);
100  topBranch.GetChild("OutputFileName").GetData(fOutputFileName);
101  topBranch.GetChild("BeaconFrequencies").GetData(fBeaconFrequencies);
102 
103  topBranch.GetChild("SpectrumNoiseFilterSize").GetData(fSpectrumNoiseFilterSize);
104  topBranch.GetChild("SpectrumPeakFilterSize").GetData(fSpectrumPeakFilterSize);
105  topBranch.GetChild("SpectrumMinPeakSNR").GetData(fSpectrumMinPeakSNR);
106  topBranch.GetChild("SpectrumFractionToSearch").GetData(fSpectrumFractionToSearch);
107 
108  topBranch.GetChild("TraceNSigmaRMS").GetData(fTraceNSigmaRMS);
109 
110  // read in the debug station list as vector, and then copy it to the set class variable
111  vector<int> dummyStationIDlist;
112  topBranch.GetChild("DebugStationIds").GetData(dummyStationIDlist);
113  fDebugStationIds = set<int>(dummyStationIDlist.begin(), dummyStationIDlist.end());
114 
115  fMinFrequency *=1000; //to MHz
116  fMaxFrequency *=1000; //to MHz
117 
118  // check xml settings for criteria
119  if (fMinFrequency < 0 || fMinFrequency > 100) {
120  WARNING("MinFrequency is negative or larger than 100 MHz! Set it to 0 MHz! \n");
121  fMinFrequency = 0;
122  }
123  if (fMinFrequency >= fMaxFrequency) {
124  WARNING("MinFrequency is not smaller than MaxFrequency! Set MinFrequency to 0 MHz and MaxFrequency to 100 MHz.\n");
125  fMinFrequency = 0;
126  fMaxFrequency = 100;
127  }
128  if (fMaxFrequency > 100) {
129  WARNING("MaxFrequency is larger than 100 MHz! Set it to 100 MHz! \n");
130  fMaxFrequency = 100;
131  }
132 
134  ostringstream info;
135  info << "Output files will be written as: \n" << fOutputFileName << '\n';
136  INFO(info.str());
137 
139  std::ofstream mysqloutputfile;
140  mysqloutputfile.open (fPathToStoreOutput+"mysql_"+fOutputFileName+".txt",std::ofstream::out | std::ofstream::trunc);
141  mysqloutputfile.close();
142 
143  return eSuccess;
144  }
145 
147  RdMonitoring::Run(evt::Event& event)
148  {
149  if (!event.HasREvent()) {
150  ERROR("Read event without radio part");
151  return eFailure;
152  }
153 
155  // General event properties
156  REvent& rEvent = event.GetREvent();
157  fgCurrentREvent = &event.GetREvent();
158  fCurRunId = rEvent.GetHeader().GetRunNumber();
159  fCurEventId = rEvent.GetHeader().GetId();
161  //
163 
165  // following condition also allows for 5s inaccuracy in the timing of the 100 second trigger
166  // If you want to use all data then set Downsample10sTriggers to false in the XML.
168 
169  // check if beacon frequencies have to be read from database, or are provided in XML file
170  // in the first case, fBeaconFrequencies is empty, i.e. size()==0
171  // get Detector
172  const det::Detector& Det = det::Detector::GetInstance();
173  const rdet::RDetector& RDetector = Det.GetRDetector();
174 
175  std::vector<double> beaconFrequencies(fBeaconFrequencies);
176  if(beaconFrequencies.size() < 1) {
177  try {
178  beaconFrequencies = RDetector.GetBeaconFrequencies(); // for example for 2013 returns: 0.058887 0.071191 0.068555 0.061523
179  } catch (utl::DataNotFoundInDBException& err) {
180  ERROR ("Error reading Beacon frequencies from database");
181  return eFailure;
182  }
183  }
184 
186  if (beaconFrequencies.size() > 100) {
187  cout << "Too many active beacon frequencies extracted from the database!? Exiting... " << endl;
188  return eFailure;
189  }
190  if (beaconFrequencies.size() < 1) {
191  cout << "Can not read any active beacon frequencies from the database! Exiting ..." << endl;
192  return eFailure;
193  }
194  //
196 
198  // Loop over stations
199  for (REvent::StationIterator sIt = rEvent.StationsBegin(); sIt != rEvent.StationsEnd(); ++sIt) {
200  fCurStationId = sIt->GetId();
201 
203  // Loop over channels
204  for (Station::ChannelIterator cIt = sIt->ChannelsBegin(); cIt != sIt->ChannelsEnd(); ++cIt) {
206  if (!cIt->IsActive()) {
207  continue;
208  }
209 
211  if (rEvent.GetTrigger().IsPeriodicTrigger() ) {
212  fCurChannelId=cIt->GetId();
213 
215  // Start calculating properties
217  const revt::ChannelTimeSeries trace = cIt->GetChannelTimeSeries();
218  const revt::ChannelFrequencySpectrum spectrum = cIt->GetChannelFrequencySpectrum();
219 
220 
222  // TRACE:
223  // * Mean
224  // * Mean-subtracted RMS
225  // * Min
226  // * Max
227  double traceMean= TraceAlgorithm::Mean(trace, 0, trace.GetSize()-1) ;
228  double traceRMS = TraceAlgorithm::StandardDeviation(trace, 0, trace.GetSize()-1) ; //StandardDeviation() subtracts mean. RootMeanSquare() doesn't
229  //double traceRMS = TraceAlgorithm::RootMeanSquare(trace, 0, trace.GetSize()-1) ;
230  double traceMax = TraceAlgorithm::Max(trace, 0, trace.GetSize()-1) ;
231  double traceMin = TraceAlgorithm::Min(trace, 0, trace.GetSize()-1) ;
232  //
234 
235 
237  for (set<int>::iterator it=fDebugStationIds.begin(); it != fDebugStationIds.end(); ++it) {
238  if (*it==fCurStationId){
239  std::ofstream mysqltraceoutputfile;
240  mysqltraceoutputfile.open (fPathToStoreOutput+"trace_r"+std::to_string(fCurRunId)+"_e"+std::to_string(fCurEventId)+"_st"+std::to_string(fCurStationId)+"_ch"+std::to_string(fCurChannelId)+"_t"+std::to_string(fCurGPSSecond)+".txt",std::ios_base::app);
241  cout << "\tStoring trace for "
242  << "\tst " << fCurStationId
243  << "\tch " << fCurChannelId
244  << "\tGPSSec=" << fCurGPSSecond
245  << "\tN_samples="<< trace.GetSize() << endl;
246  float timeBinning = trace.GetBinning();
247  for (unsigned int j = trace.GetStart(); j < trace.GetSize(); ++j) {
248  mysqltraceoutputfile << j*timeBinning<< "\t" << trace[j] << endl;
249  }
250  mysqltraceoutputfile.close();
251  } // end if
252  } // end for
254 
256  // SPECTRUM:
257  // * Power at [28,33,38,43,51,58,69,80] MHz: corresponding to the frequencies that drop in amplitude when a dipole antenna breaks
258  // * PowerInBand : sum(spectrum amplitudes in band)*binsize (range set in xml file)
259  // * PowerOutsideBand
260  // * TraceOutliers
261  // * SpectrumNarrowBandPeaks (calculated in beacon section below)
262 
264  double PowerInBand = 0;
265  double PowerOutsideBand = 0;
266  list<float> freqList = {28,33,38,43,51,58,69,80}; //In MHz
267  float PowerAt[8] = { 0. };
268  int i_freqList = 0;
269 
271  for (float f : freqList) {
272  PowerAt[i_freqList] = abs(spectrum[ round((f-cIt->GetFrequencyOfBin(0)/megahertz)/(spectrum.GetBinning()*1000)) ]);
273  i_freqList++;
274  }
275 
277  for (set<int>::iterator it=fDebugStationIds.begin(); it != fDebugStationIds.end(); ++it) {
278  if (*it==fCurStationId){
279  std::ofstream mysqlspectrumoutputfile;
280  mysqlspectrumoutputfile.open (fPathToStoreOutput+"spectrum_r"+std::to_string(fCurRunId)+"_e"+std::to_string(fCurEventId)+"_st"+std::to_string(fCurStationId)+"_ch"+std::to_string(fCurChannelId)+"_t"+std::to_string(fCurGPSSecond)+".txt",std::ios_base::app);
281  cout << "\tStoring spectrum for: "
282  << "\tst " << fCurStationId
283  << "\tch " << fCurChannelId
284  << "\tGPSSec=" << fCurGPSSecond
285  << "\tN_samples="<< spectrum.GetSize() << endl;
286  for (unsigned int j = spectrum.GetStart(); j < spectrum.GetSize(); ++j) {
287  mysqlspectrumoutputfile << cIt->GetFrequencyOfBin(j)/megahertz << "\t" << abs(spectrum[j]) << endl;
288  }
289  mysqlspectrumoutputfile.close();
290  } //end if
291  } //end for
293 
295  for (unsigned int j = spectrum.GetStart()+1; j < spectrum.GetSize(); ++j) {
296  if (cIt->GetFrequencyOfBin(j)/megahertz > fMinFrequency && cIt->GetFrequencyOfBin(j)/megahertz < fMaxFrequency){
297  PowerInBand += abs(spectrum[j]);
298  }
299  else {
300  PowerOutsideBand += abs(spectrum[j]);
301  }
302  }
303  PowerOutsideBand*=spectrum.GetBinning()*1000; // PowerInBand[ADC*MHz]=SUM(spectrum amplitudes)*binsize
304  PowerInBand *=spectrum.GetBinning()*1000;
305  //
307 
308 
310  // BEACON
311  // * BeaconDetected
312  // * BeaconSNR: set noise window size around beacon in xml
313  // * (SpectrumNarrowBandPeaks: (used on channel level) amount of narrow-band peaks in the spectrum (excluding identified beacon lines))
314 
316  float f_step = spectrum.GetBinning()*1000; // in Mhz
317 
319  Trace<double> amplitudeSpectrum;
320  for (ChannelFrequencySpectrum::SizeType i = 0; i < spectrum.GetSize(); ++i)
321  amplitudeSpectrum.PushBack(abs(spectrum[i]));
322 
324  // WRITE BEACON INFO TO OUTPUT
325  //
326 
327  std::ofstream mysqloutputfile;
328  mysqloutputfile.open (fPathToStoreOutput+"mysql_"+fOutputFileName+".txt",std::ios_base::app);
329 
330  //
331  // CONTINUES IN NEXT PART
333 
335  // RFI peak & beacon finding
336  // 1) take highest value in spectrum --> peak candidate.
337  // 2) calculate snr around peak.
338  // 3) add bins around peak to SpectrumRejectedPositions to account for width of this already found peak so they are not identified on each bin.
339  // 4) take next highest value and repeat untill all highest values exhausted
340 
341 
343  unsigned int SpectrumSize=spectrum.GetSize()-1; // max size is spectrum.GetSize()-1
344  unsigned int SpectrumBinsToSearch=ceil(SpectrumSize*fSpectrumFractionToSearch);
345 
346  // create simple vectors of trace and spectum
347  std::vector<float> UnsortedSpectrum;
348  for (ChannelFrequencySpectrum::SizeType i = 0; i < SpectrumSize; ++i){
349  UnsortedSpectrum.push_back(abs(spectrum[i+1])); //skipping bin one as it is not part of the spectrum values.
350  }
351 
353  std::vector<int> SpectrumSortedIndices;
354  for(size_t i = 0; i < SpectrumSize; ++i) {
355  SpectrumSortedIndices.push_back(i); //indices will still start at zero!
356  }
357  std::sort(SpectrumSortedIndices.begin(),SpectrumSortedIndices.end(), [&](int i1, int i2) { return UnsortedSpectrum[i1] > UnsortedSpectrum[i2]; } );
358 
360  std::vector<int> _SpectrumPeakPos;
361  std::vector<float> _SpectrumPeakHeight;
362  for(size_t i = 0; i < SpectrumBinsToSearch; ++i){
363  _SpectrumPeakPos.push_back(SpectrumSortedIndices[i]);
364  _SpectrumPeakHeight.push_back(UnsortedSpectrum[SpectrumSortedIndices[i]]);
365  }
366 
367 
368  int SpectrumNarrowBandPeaks=0;
369 
370  std::string tempString="";
371  std::vector<int> SpectrumRejectedPos;
372 
374  for(size_t i = 0; i < SpectrumBinsToSearch; ++i){
376  if ( _SpectrumPeakPos[i]> trunc(fSpectrumNoiseFilterSize/2.0) && _SpectrumPeakPos[i]< SpectrumSize -ceil(fSpectrumNoiseFilterSize/2.0) ) {
378  if (( std::find(SpectrumRejectedPos.begin(), SpectrumRejectedPos.end(), _SpectrumPeakPos[i]) != SpectrumRejectedPos.end() )==false){
380  double noise = TraceAlgorithm::Median(amplitudeSpectrum,
381  1+_SpectrumPeakPos[i]-trunc(fSpectrumNoiseFilterSize/2.0),
382  1+_SpectrumPeakPos[i]+ceil(fSpectrumNoiseFilterSize/2.0)-1.); //amplitudeSpectrum starts at bin 0. for PeakPos bin 0 was ignored before. needs compensation now.
383  double snr = (_SpectrumPeakHeight[i]*_SpectrumPeakHeight[i])/(noise*noise) ;
384 
386  if (snr>fSpectrumMinPeakSNR){
387  SpectrumNarrowBandPeaks++;
388  }
389 
391  double CurrentFrequency=cIt->GetFrequencyOfBin(_SpectrumPeakPos[i]+1)*1000;
392 
393  for (unsigned int BqIt = 0; BqIt < beaconFrequencies.size(); ++BqIt) {
394  if (TMath::Abs(CurrentFrequency - beaconFrequencies[BqIt]*1000.) < f_step) {
395  if (snr>fSpectrumMinPeakSNR){
396  SpectrumNarrowBandPeaks-=1; // do not count as NarrowBandPeak if it is a beacon
397  }
399  tempString+="INSERT INTO RdMonitoringBeacon (RdMonitoringChannel_id,BeaconFreq,BeaconSNR) VALUES (LAST_INSERT_ID(),"+std::to_string(beaconFrequencies[BqIt]*1000)+","+std::to_string(snr)+");\n";
400  break;
401  }
402  }
403 
405  for (size_t j=_SpectrumPeakPos[i]-trunc(fSpectrumPeakFilterSize/2.0); j < _SpectrumPeakPos[i]+ceil(fSpectrumPeakFilterSize/2.0) ; j++){
406  SpectrumRejectedPos.push_back(j);
407  }
408 
409  }// end if non-rejected
410  }// end if not near edge
411  }// end peak candidate loop
412 
414  int TraceOutliers=0;
415  for (unsigned int j = trace.GetStart(); j < trace.GetSize(); ++j) {
416  if (TMath::Abs(trace[j]-traceMean) > traceRMS*fTraceNSigmaRMS) {
417  TraceOutliers++;
418  }
419  }
420  //timedomainoutputfile.close();
421 
422  //
424  //
426 
427 
429  // WRITE CHANNEL INFO TO OUTPUT
430  mysqloutputfile << "INSERT INTO RdMonitoringChannel (" <<
431  "RunId, " <<
432  "StationId, " <<
433  "ChannelId, " <<
434  "GPSSecond, " <<
435  "traceMean, " <<
436  "traceRMS, " <<
437  "traceMin, " <<
438  "traceMax, " <<
439  "PowerAt28MHz, " <<
440  "PowerAt33MHz, " <<
441  "PowerAt38MHz, " <<
442  "PowerAt43MHz, " <<
443  "PowerAt51MHz, " <<
444  "PowerAt58MHz, " <<
445  "PowerAt69MHz, " <<
446  "PowerAt80MHz," <<
447  "PowerInBand," <<
448  "PowerOutsideband," <<
449  "TraceOutliers," <<
450  "SpectrumNarrowBandPeaks," <<
451  "BadPeriodFlag" << //initial flag=0: in post-processing the flag is set
452  ") Values (" <<
453  fCurRunId << ","<<
454  fCurStationId << "," <<
455  fCurChannelId << "," <<
456  fCurGPSSecond << "," <<
457  traceMean << "," <<
458  traceRMS << "," <<
459  traceMin << "," <<
460  traceMax << "," <<
461  PowerAt[0] << "," <<
462  PowerAt[1] << "," <<
463  PowerAt[2] << "," <<
464  PowerAt[3] << "," <<
465  PowerAt[4] << "," <<
466  PowerAt[5] << "," <<
467  PowerAt[6] << "," <<
468  PowerAt[7] << "," <<
469  PowerInBand << "," <<
470  PowerOutsideBand << "," <<
471  TraceOutliers << "," <<
472  SpectrumNarrowBandPeaks << "," <<
473  0 << ");\n";
474  mysqloutputfile << tempString.c_str() ;
475  mysqloutputfile.close();
476  //
478 
479 
480  } // end if periodic
481  } // end channel loop
482  } // end station loop
483 
486  } // end if periodic event
487  return eSuccess;
488  } // end event
489 
490 
492  RdMonitoring::Finish()
493  {
494  INFO("Finish");
495  return eSuccess;
496  }
497 
498 }
Branch GetTopBranch() const
Definition: Branch.cc:63
double StandardDeviation(const std::vector< double > &v, const double mean)
Definition: Functions.cc:26
std::set< int > fDebugStationIds
List of station IDs which will be included into debugging file.
Definition: RdMonitoring.h:84
Report success to RunController.
Definition: VModule.h:62
bool IsPeriodicTrigger() const
Check if Event comes from PERIODIC trigger.
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
utl::TimeStamp GetTime() const
Definition: REvent/Header.h:17
EventTrigger & GetTrigger()
Get the object with central trigger data, throw if n.a.
Definition: REvent.h:229
std::vector< double > fBeaconFrequencies
Definition: RdMonitoring.h:77
double GetBinning() const
size of one slot
Definition: Trace.h:138
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
StationIterator StationsEnd()
Definition: REvent.h:130
StationIterator StationsBegin()
Definition: REvent.h:128
void Init()
Initialise the registry.
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
boost::filter_iterator< StationFilter, AllStationIterator > StationIterator
Iterator over all (non-exculded) stations.
Definition: REvent.h:125
bool HasREvent() const
bool StringEquivalent(const std::string &a, const std::string &b, Predicate p)
Utility to compare strings for equivalence. It takes a predicate to determine the equivalence of indi...
Definition: StringCompare.h:38
const std::vector< double > & GetBeaconFrequencies() const
Get vector of Beacon Frequencies for given detector-time from Manager.
Definition: RDetector.cc:183
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
Class representing a document branch.
Definition: Branch.h:107
Exception to use in case requested data not found in the database with detailed printout.
std::vector< std::complex< double > >::size_type SizeType
Definition: Trace.h:58
double abs(const SVector< n, T > &v)
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
constexpr double megahertz
Definition: AugerUnits.h:155
SizeType GetSize() const
Definition: Trace.h:156
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int GetRunNumber() const
Event id in the run (Start at zero at the beginning of each run) /provided by the daq...
Definition: REvent/Header.h:22
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
SizeType GetStart() const
Get valid data start bin.
Definition: Trace.h:142
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
std::string fPathToStoreOutput
Definition: RdMonitoring.h:73
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
double Mean(const std::vector< double > &v)
Definition: Functions.h:31
void PushBack(const T &value)
Insert a single value at the end.
Definition: Trace.h:119
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
int GetId() const
Definition: REvent/Header.h:21
static revt::REvent * fgCurrentREvent
Definition: RdMonitoring.h:86

, generated on Tue Sep 26 2023.