RdChannelNoisePulseCounter.cc
Go to the documentation of this file.
2 #include <utl/ErrorLogger.h>
3 
4 #include <evt/Event.h>
5 #include <revt/REvent.h>
6 #include <revt/Header.h>
7 #include <revt/Station.h>
8 #include <revt/Channel.h>
9 #include <revt/StationRecData.h>
10 
11 #include <utl/Point.h>
12 #include <utl/Trace.h>
13 #include <utl/TraceAlgorithm.h>
14 #include <utl/ErrorLogger.h>
15 #include <utl/Reader.h>
16 #include <utl/config.h>
17 #include <utl/AugerUnits.h>
18 #include <utl/RadioGeometryUtilities.h>
19 #include <fwk/CentralConfig.h>
20 
21 #include <det/Detector.h>
22 #include <rdet/RDetector.h>
23 
24 #include <math.h>
25 
26 #define INFO2(x,y) if ((x) <= fInfoLevel) INFO(y)
27 
28 using namespace std;
29 using namespace fwk;
30 
31 
33 
35  fInfoLevel(0),
36  fSNRThreshold(10),
37  fFirstEvent(true),
38  fNumberOfEvents(0),
39  fOutputPath("output"),
40  fOutputFilename("noisecounter"),
41  fMinimumStationId(100),
42  fMaximumStationId(124),
43  fMaximumNeighborDistance(200 * utl::meter)
44 { }
45 
46 
49 {
50  // Initialize your module here. This method
51  // is called once at the beginning of the run.
52  // The eSuccess flag indicates the method ended
53  // successfully. For other possible return types,
54  // see the VModule documentation.
55 
56  INFO("RdChannelNoisePulseCounter::Init()");
57  utl::Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdChannelNoisePulseCounter");
58  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
59  topBranch.GetChild("SNRThreshold").GetData(fSNRThreshold);
60  topBranch.GetChild("OutputPath").GetData(fOutputPath);
61  topBranch.GetChild("OutputFilename").GetData(fOutputFilename);
62  topBranch.GetChild("MinimumStationId").GetData(fMinimumStationId);
63  topBranch.GetChild("MaximumStationId").GetData(fMaximumStationId);
64  topBranch.GetChild("MaximumNeighborDistance").GetData(fMaximumNeighborDistance);
65 
66  return eSuccess;
67 }
68 
69 
70 double
71 RdChannelNoisePulseCounter::FindPulse(revt::Station& station)
72 {
73  double NoiseSearchWindowStart = station.GetRecData().GetParameter(revt::eNoiseWindowStart);
74  double NoiseSearchWindowStop = station.GetRecData().GetParameter(revt::eNoiseWindowStop);
75  double SignalSearchWindowStart = station.GetRecData().GetParameter(revt::eSignalSearchWindowStart);
76  double SignalSearchWindowStop = station.GetRecData().GetParameter(revt::eSignalSearchWindowStop);
77 
78  stringstream info;
79  // identify active channels
80  vector<revt::Station::ConstChannelIterator> usableChannels;
81  for (revt::Station::ConstChannelIterator cIt = station.ChannelsBegin(); cIt != station.ChannelsEnd();
82  ++cIt)
83  if (cIt->IsActive())
84  usableChannels.push_back(cIt);
85 
86  // remove station if it has no channels (no data) - should actually be done beforehand, but just to be sure
87  if (usableChannels.size() == 0) {
88  info.str("");
89  info << "Station ";
90  info << station.GetId();
91  info
92  << " does not have any channels, removing it! Should treat this case beforehand, e.g. in RdChannelSelector.";
93  WARNING(info.str());
94  // rEvent.RemoveStation(sIt);
95  return 0;
96  }
97 
98  if (usableChannels.size() != 2) {
99  if (usableChannels.size() == 3) {
100  info.str("");
101  info << "Station ";
102  info << station.GetId();
103  info
104  << " does have three active channels! The PreWaveFitter does only support two active channel for the moment. The first two active channels will be used.";
105  WARNING(info.str());
106  } else {
107  info.str("");
108  info << "Station ";
109  info << station.GetId();
110  info
111  << " does not have exactly two active channels! Have you forgotten to include the RdChannelSelector?";
112  ERROR(info.str());
114  "RdPreWaveFitter does not support stations with number of Channels != 2 or != 3.");
115  }
116  }
117 
118  const revt::Channel& channel1 = *usableChannels.at(0);
119  const revt::Channel& channel2 = *usableChannels.at(1);
120  const revt::ChannelTimeSeries& channelTrace1 = channel1.GetChannelTimeSeries();
121  const revt::ChannelTimeSeries& channelTrace2 = channel2.GetChannelTimeSeries();
122 
123  revt::ChannelTimeSeries channelTrace;
124  channelTrace.SetBinning(channelTrace1.GetBinning());
125  channelTrace.ClearTrace();
126 
127  for (unsigned int i = 0; i < channelTrace1.GetSize(); ++i) {
128  channelTrace.PushBack(
129  sqrt((channelTrace1[i] * channelTrace1[i]) + (channelTrace2[i] * channelTrace2[i])));
130  }
131 
132  unsigned int start = NoiseSearchWindowStart / channelTrace1.GetBinning();
133  unsigned int stop = NoiseSearchWindowStop / channelTrace1.GetBinning();
134  unsigned int startSignal = SignalSearchWindowStart / channelTrace1.GetBinning();
135  unsigned int stopSignal = SignalSearchWindowStop / channelTrace1.GetBinning();
136  double rms = utl::TraceAlgorithm::RootMeanSquare(channelTrace, start, stop - 1); // stop - 1 because RootMeanSquare function loops from i=start to i<=stop
137  double amplitude = utl::TraceAlgorithm::Max(channelTrace, startSignal, stopSignal);
138 // delete usableChannels;
139  return amplitude * amplitude / (rms * rms);
140 }
141 
142 VModule::ResultFlag RdChannelNoisePulseCounter::Run(evt::Event& event)
143 {
144 
145 
146  INFO("RdChannelNoisePulseCounter::Run()");
147  // Check if there are events at all
148  if (!event.HasREvent()) {
149  WARNING("RdChannelNoisePulseCounter::No radio event found!");
150  return eContinueLoop;
151  } else {
152  revt::REvent& rEvent = event.GetREvent();
153  // compute nearest neighbors
154  const det::Detector& detector = det::Detector::GetInstance();
155  const rdet::RDetector& rDetector = detector.GetRDetector();
156  const std::vector<int>& fullStationList = rDetector.GetFullStationList();
157  std::map<int, std::vector<int> > mNeighbors; // neighbors need to be recalculated each time as detector configuration might change
158  for (std::vector<int>::const_iterator sIt = fullStationList.begin(); sIt != fullStationList.end(); ++sIt) {
159  const int id = *sIt;
160  if( (id > fMaximumNeighborDistance) or (id < fMinimumStationId)) { // consider only specific detector setup
161  continue;
162  }
163  if (!mNeighbors.count(id)) {
164  std::vector<int> neighbors;
165  mNeighbors[id] = neighbors;
166  }
167  utl::Point currentPosition = rDetector.GetStation(id).GetPosition();
168  for (std::vector<int>::const_iterator sIt2 = fullStationList.begin(); sIt2 != fullStationList.end(); ++sIt2) {
169  const int id2 = *sIt2;
170  if(id2 == id) { // do not double count first station
171  continue;
172  }
173  if( (id > fMaximumNeighborDistance) or (id < fMinimumStationId)) { // consider only specific detector setup
174  continue;
175  }
176  utl::Point currentPosition2 = rDetector.GetStation(id2).GetPosition();
177  if ((currentPosition - currentPosition2).GetMag() < fMaximumNeighborDistance) {
178  mNeighbors[id].push_back(id2);
179  }
180  }
181  }
182  stringstream info;
183  for (std::map<int, std::vector<int> >::iterator it=mNeighbors.begin(); it!=mNeighbors.end(); ++it) {
184  info.str("");
185  info << "Station " << it->first << " has neighbors: ";
186  for(std::vector<int>::iterator itNeighbor = it->second.begin(); itNeighbor!=it->second.end(); ++itNeighbor) {
187  info << *itNeighbor << " ";
188  }
189  INFO2(eFinal, info.str());
190  }
191 
192  fNumberOfEvents++;
193  std::map<int, bool> pulseFoundMap;
194  // loop through stations
195  for (revt::REvent::StationIterator sIt = rEvent.StationsBegin(); sIt != rEvent.StationsEnd(); ++sIt) {
196  revt::Station& station = *sIt;
197  const int id = station.GetId();
198  double SNR = FindPulse(station);
199  if(SNR == 0) {
200  continue;
201  }
202  double SignalSearchWindowStart = station.GetRecData().GetParameter(revt::eSignalSearchWindowStart);
203  double SignalSearchWindowStop = station.GetRecData().GetParameter(revt::eSignalSearchWindowStop);
204  int GPSseconds = rEvent.GetHeader().GetTime().GetGPSSecond();
205 
206  if (SNR >= fSNRThreshold) {
207  fNoisePulseData.SNRs.push_back(SNR);
208  fNoisePulseData.GPSsecods.push_back(GPSseconds);
210  fStationNoisePulseData[id].SNRs.push_back(SNR);
211  fStationNoisePulseData[id].GPSsecods.push_back(GPSseconds);
212  fStationNoisePulseData[id].numberOfPulses++;
213  if( (id > fMaximumNeighborDistance) or (id < fMinimumStationId)) { // consider only specific detector setup
214  pulseFoundMap[id] = true;
215  }
216  } else {
217  if( (id > fMaximumNeighborDistance) or (id < fMinimumStationId)) { // consider only specific detector setup
218  pulseFoundMap[id] = false;
219  }
220  }
221  fNoisePulseData.totalSignalSerachWindow += (SignalSearchWindowStop - SignalSearchWindowStart);
223  fStationNoisePulseData[id].totalSignalSerachWindow += (SignalSearchWindowStop
224  - SignalSearchWindowStart);
225  fStationNoisePulseData[id].numberOfTraces++;
226  }
227 
228  // search for coincident noise pulses in multiple stations
229  std::map<int, int> coincidentPulses_tmp;
230  for (std::map<int, bool>::iterator it=pulseFoundMap.begin(); it!=pulseFoundMap.end(); ++it) {
231  if(it->second) {
232  int id = it->first;
233  int nCoincidences = 1;
234  for(std::vector<int>::iterator itNeighbor = mNeighbors[id].begin(); itNeighbor!=mNeighbors[id].end(); ++itNeighbor) {
235  if(pulseFoundMap[*itNeighbor]) {
236  nCoincidences++;
237  }
238  }
239  if (!coincidentPulses_tmp.count(nCoincidences)) {
240  coincidentPulses_tmp[nCoincidences] = 1;
241  } else {
242  coincidentPulses_tmp[nCoincidences]++;
243  }
244  }
245  }
246  // if any n station coincidence has been found, increase member variable by one. Multiple n station coincidences in one event are not considered, beacuse of double counting problems.
247  for (std::map<int, int>::iterator it = coincidentPulses_tmp.begin(); it != coincidentPulses_tmp.end(); ++it) {
248  if (!fCoincidentPulses.count(it->first)) {
249  fCoincidentPulses[it->first] = 1;
250  } else {
251  fCoincidentPulses[it->first]++;
252  }
253  }
254  }
255  return eSuccess;
256 }
257 
258 VModule::ResultFlag RdChannelNoisePulseCounter::Finish()
259 {
260  // Put any termination or cleanup code here.
261  // This method is called once at the end of the run.
262  INFO("RdChannelNoisePulseCounter::Finish()");
263 
264  std::ofstream ofs;
265  std::ofstream ofs_SNR;
266  std::ofstream ofs_GPS;
267 
268  std::string outputfilename = fOutputPath;
269  if(outputfilename.substr(outputfilename.size()-1, 1) != "/") {
270  outputfilename.append("/");
271  }
272  outputfilename.append(fOutputFilename);
273 
274  ofs_SNR.open ((outputfilename+"_SNRs.out").c_str(), std::ofstream::app);
275  ofs_SNR.precision(5);
276  for (std::vector<double>::iterator itSNR = fNoisePulseData.SNRs.begin(); itSNR!=fNoisePulseData.SNRs.end(); ++itSNR) {
277  ofs_SNR << "\t" << *itSNR;
278  }
279  ofs_SNR.close();
280  ofs_GPS.open ((outputfilename+"_GPSSeconds.out").c_str(), std::ofstream::app);
281  for (std::vector<int>::iterator itGPS = fNoisePulseData.GPSsecods.begin(); itGPS!=fNoisePulseData.GPSsecods.end(); ++itGPS) {
282  ofs_GPS << "\t" << *itGPS;
283  }
284  ofs_GPS.close();
285 
286  ofs.open ((outputfilename+".out").c_str(), std::ofstream::app);
287  ofs << "# nTraces\tnPulseFounds\ttotalSignalSerachWindow\n";
289  ofs.close();
290 
291  ofs.open ((outputfilename+"_stationwise.out").c_str(), std::ofstream::app);
292  ofs_SNR.open ((outputfilename+"_SNRs_stationwise.out").c_str(), std::ofstream::app);
293  ofs_GPS.open ((outputfilename+"_GPSSeconds_stationwise.out").c_str(), std::ofstream::app);
294  ofs_SNR.precision(5);
295  for (std::map<int, NoisePulseData>::iterator it=fStationNoisePulseData.begin(); it!=fStationNoisePulseData.end(); ++it) {
296  ofs << it->first << "\t" << it->second.numberOfTraces << "\t" << it->second.numberOfPulses << "\t" << it->second.totalSignalSerachWindow << endl;
297  ofs_SNR << it->first;
298  for (std::vector<double>::iterator itSNR = it->second.SNRs.begin(); itSNR!=it->second.SNRs.end(); ++itSNR) {
299  ofs_SNR << "\t" << *itSNR;
300  }
301  ofs_SNR << endl;
302 
303  ofs_GPS << it->first;
304  for (std::vector<int>::iterator itSNR = it->second.GPSsecods.begin(); itSNR!=it->second.GPSsecods.end(); ++itSNR) {
305  ofs_GPS << "\t" << *itSNR;
306  }
307  ofs_GPS << endl;
308  }
309  ofs_SNR.close();
310  ofs_GPS.close();
311  ofs.close();
312 
313  std::ofstream ofs_CoincidentPulses;
314  ofs_CoincidentPulses.open((outputfilename+"_spatial_coincidences.out").c_str(), std::ofstream::app);
315  for (std::map<int, int>::iterator it = fCoincidentPulses.begin(); it != fCoincidentPulses.end(); ++it) {
316  ofs_CoincidentPulses << it->first << "\t" << it->second << "\t" << fNumberOfEvents << endl;
317  }
318  ofs_CoincidentPulses.close();
319 
320  stringstream info;
321  info.str("");
322  info << "number of processed traces is " << fNoisePulseData.numberOfPulses << "/" << fNoisePulseData.numberOfTraces;
323  INFO2(eDebug, info.str());
324 
325  return eSuccess;
326 }
327 
328 }
Branch GetTopBranch() const
Definition: Branch.cc:63
static double Max(const Trace< T > &trace, const unsigned int bin1, const unsigned int bin2)
Evaluate the maximum of trace between bin1 and bin2.
Point object.
Definition: Point.h:32
Report success to RunController.
Definition: VModule.h:62
StationRecData & GetRecData()
Get station level reconstructed data.
boost::indirect_iterator< InternalConstChannelIterator, const Channel & > ConstChannelIterator
Iterator over station for read.
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
Skip remaining modules in the current loop and continue with next iteration of the loop...
Definition: VModule.h:68
utl::TimeStamp GetTime() const
Definition: REvent/Header.h:17
double GetBinning() const
size of one slot
Definition: Trace.h:138
const std::vector< int > & GetFullStationList() const
Get list of ID&#39;s for all stations available in the database or configuration file.
Definition: RDetector.cc:84
const double meter
Definition: GalacticUnits.h:29
#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.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
ChannelIterator ChannelsBegin()
begin Channel iterator for read/write
boost::filter_iterator< StationFilter, AllStationIterator > StationIterator
Iterator over all (non-exculded) stations.
Definition: REvent.h:125
bool HasREvent() const
ChannelTimeSeries & GetChannelTimeSeries()
retrieve Channel Time Series (write access, only use this if you intend to change the data) ...
ChannelIterator ChannelsEnd()
end Channel iterator for read/write
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
Class representing a document branch.
Definition: Branch.h:107
class to hold data at the radio Station level.
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
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
int GetId() const
Get the station Id.
static double RootMeanSquare(const Trace< T > &trace, const unsigned int bin1, const unsigned int bin2)
Evaluate the RootMeanSquare of trace between bin1 and bin2.
Base class for inconsistency/illogicality exceptions.
double GetParameter(const Parameter i) const
void SetBinning(const double binning)
Definition: Trace.h:139
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
Class that holds the data associated to an individual radio channel.
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
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
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: RDetector.cc:141
#define INFO2(x, y)

, generated on Tue Sep 26 2023.