RdVirtualStationNoiseImporter.cc
Go to the documentation of this file.
2 
3 #include <evt/Event.h>
4 #include <evt/RadioSimulation.h>
5 #include <evt/ShowerSimData.h>
6 
7 #include <revt/REvent.h>
8 #include <revt/Header.h>
9 #include <revt/Station.h>
10 #include <revt/Channel.h>
11 
12 #include <det/Detector.h>
13 #include <rdet/RDetector.h>
14 #include <rdet/Station.h>
15 #include <rdet/Channel.h>
16 
17 #include <utl/Trace.h>
18 #include <utl/TraceAlgorithm.h>
19 #include <utl/ErrorLogger.h>
20 #include <utl/Reader.h>
21 #include <utl/config.h>
22 #include <utl/RandomEngine.h>
23 #include <utl/UTCDateTime.h>
24 #include <utl/TimeStamp.h>
25 
26 #include <fwk/RandomEngineRegistry.h>
27 #include <fwk/CentralConfig.h>
28 
29 #include <vector>
30 #include <string>
31 #include <iostream>
32 #include <fstream>
33 
34 #include <TKey.h>
35 #include <TFile.h>
36 #include <TTree.h>
37 #include <TBranch.h>
38 
39 #include <RadioFileIO.h>
40 
41 #include <CLHEP/Random/RandFlat.h>
42 
43 using namespace std;
44 using namespace evt;
45 using namespace det;
46 using namespace fwk;
47 using namespace revt;
48 
50 
53 {
54 
55  utl::Branch topBranch = fwk::CentralConfig::GetInstance()->GetTopBranch("RdVirtualStationNoiseImporter");
56  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
57  INFODebug("");
58 
59  topBranch.GetChild("NoiseFileSelection").GetData(fNoiseFileSelection);
60  topBranch.GetChild("NoiseFilePath").GetData(fNoiseFilePath);
61  topBranch.GetChild("FilenamePrefix").GetData(fFilenamePrefix);
62  topBranch.GetChild("FilenameSuffix").GetData(fFilenameSuffix);
63  topBranch.GetChild("ExpectSubDirectories").GetData(fExpectSubDirectories);
64  topBranch.GetChild("StationIDList").GetData(fStationIDList);
65  topBranch.GetChild("RandomNoiseTimeIntervalStart").GetData(fRandomNoiseTimeIntervalStart);
66  topBranch.GetChild("RandomNoiseTimeIntervalStop").GetData(fRandomNoiseTimeIntervalStop);
67  topBranch.GetChild("CheckTimeWindow").GetData(fCheckTimeWindow);
68  topBranch.GetChild("TimeWindow").GetData(fMaxTimeDifference);
69  topBranch.GetChild("AllowTraceShifting").GetData(fTraceShifting);
70  topBranch.GetChild("GainFactor").GetData(fGainFactor);
71 
72  topBranch.GetChild("ReplaceDataWithNoise").GetData(fReplaceDataWithNoise);
73 
74  topBranch.GetChild("TimeIntervalInFile").GetData(fTimeIntervalInFile);
75 
76  fRandomEngine =
77  &fwk::RandomEngineRegistry::GetInstance().Get(fwk::RandomEngineRegistry::eDetector).GetEngine();
78 
79  ostringstream msg;
80  if (fStationIDList.empty()) {
81  ERROR("Station list is empty, no noise can be added!");
82  } else {
83  msg << "\n\tNoise from the following stations is added: ";
84  for (auto& id : fStationIDList)
85  msg << id + 100 << " ";
86  msg << std::endl;
87  INFOFinal(msg);
88  }
89 
90 
91  // read in _additional_ bad period entries
92  msg.str("");
93  msg << "Additional Bad Period entries:";
94  for (utl::Branch b = topBranch.GetFirstChild(); b; b = b.GetNextSibling()) {
95  if (b.GetName() != "BadStation")
96  continue;
97  const size_t stationId = det::VManager::FindComponent<size_t>("id", b.GetAttributes());
98  const string reason = det::VManager::FindComponent<string>("reason", b.GetAttributes());
99 
100  vector<utl::TimeStamp> range;
101  b.GetData(range);
102  fRejectMap.insert(make_pair(range[0], make_pair(range[1], stationId)));
103  msg << "\n\tregistered: id = " << stationId << " [" << range[0] << ", " << range[1] << "]";
104 
105  }
106  INFOFinal(msg);
107 
108  return eSuccess;
109 }
110 
111 
113 RdVirtualStationNoiseImporter::Run(evt::Event& event)
114 {
115  // Check if there are events at all
116  if (!event.HasREvent()) {
117  WARNING("RdVirtualStationNoiseImporter::No radio event found!");
118  return eContinueLoop;
119  }
120 
121  utl::UTCDateTime eventTime(event.GetHeader().GetTime());
122  const utl::TimeStamp origTimeStamp = event.GetHeader().GetTime();
123 
124  Detector& det = det::Detector::GetInstance();
125  REvent& rEvent = event.GetREvent();
126  const rdet::RDetector& rDetector = det.GetRDetector();
127 
128  ostringstream infostr;
129  ostringstream warnstr;
130  ostringstream debugstr;
131 
132  string NoiseImportfilename;
133  utl::TimeStamp noiseTimeStamp;
134  utl::UTCDateTime noiseUTCDateTime;
135  utl::UTCDateTime noiseFileStartingDay;
136  long noiseTimeGPSSecond;
137 
138  // If the noise file is given explicitly in the init-file:
139  if (fNoiseFileSelection == "Manually")
140  NoiseImportfilename = fNoiseFilePath;
141 
142  // Reading in a noise-event and checking if requested stations are present.
143  bool fileOK = false;
144  RadioFileIO* RadioFileIORead = nullptr;
145  TFile* Readfile = nullptr;
146  TTree* IOLibTree = nullptr;
147  TBranch* IObranch = nullptr;
148  // TBranch* evtSecBranch;
149  vector<int> closeEventIds;
150  vector<pair<int,vector<int>>> EventListWithStations;
151  int tries = 0;
152  while (!fileOK) {
153  tries += 1;
154 
155  if (tries > 1 && fNoiseFileSelection == "Manually") {
156  ERROR("Manually file sleection do not try a second time... aborting!");
157  return eFailure;
158  }
159 
160  // If the Noise file is selected based on a random event time
161  if (fNoiseFileSelection == "Randomly") {
162  const long noiseTimeIntervalStartGPSSecond = fRandomNoiseTimeIntervalStart.GetGPSSecond();
163  const long noiseTimeIntervalStopGPSSecond = fRandomNoiseTimeIntervalStop.GetGPSSecond();
164  noiseTimeGPSSecond =
165  CLHEP::RandFlat::shootInt(fRandomEngine, noiseTimeIntervalStartGPSSecond, noiseTimeIntervalStopGPSSecond);
166 
167  const unsigned long secondsPerDay = 24 * 60 * 60;
168  noiseTimeStamp = utl::TimeStamp(noiseTimeGPSSecond);
169 
170  // already here check with BP DB so that on does not have to open the file.
171  det.Update(noiseTimeStamp); // update for BadPeriod DP
172  TimeRangeMap::IdCollection badIds = fRejectMap.GetBadStations(noiseTimeStamp); // manual BP
173  debugstr.str("");
174  bool dont_skip = false;
175  for (auto it = fStationIDList.begin() ; it != fStationIDList.end(); ++it) {
176  if (!rDetector.GetBadStationReason(*it) && !(std::find(badIds.begin(), badIds.end(), *it) != badIds.end()))
177  dont_skip = true; // if at least one station is not in BP Database.
178  }
179  if (!dont_skip) {
180  INFOIntermediate("Random time stamp for noise import is rejected, because of Bad Period. "
181  "Look for next file... ");
182  continue;
183  }
184 
185  noiseUTCDateTime = utl::UTCDateTime(noiseTimeStamp);
186  const utl::TimeStamp noiseTimeStampMinus24h = utl::TimeStamp(noiseTimeGPSSecond - secondsPerDay);
187  const utl::UTCDateTime noiseUTCDateTimeMinus24h = utl::UTCDateTime(noiseTimeStampMinus24h);
188  noiseFileStartingDay = (noiseUTCDateTime.GetHour() < 12) ? noiseUTCDateTimeMinus24h : noiseUTCDateTime;
189 
190  if (!GetNoiseFileNameAtTime(noiseUTCDateTime, noiseFileStartingDay, NoiseImportfilename)) {
191  if (tries > 9) {
192  ERROR("Failed to fetch noise file too many times. Continue loop...");
193  return eContinueLoop;
194  }
195  infostr.str("");
196  infostr << "Attempt " << tries << ": Failed to import noise from file " << NoiseImportfilename;
197  infostr << ". please check if the path and suffix/prefix are set properly.\nTrying next random time";
198  INFOFinal(infostr);
199  continue;
200  }
201  infostr << "Importing noise from file " << NoiseImportfilename;
202  INFOIntermediate(infostr);
203  }
204 
205  RadioFileIORead = new RadioFileIO();
206  Readfile = new TFile(NoiseImportfilename.c_str(), "READ");
207  IOLibTree = (TTree*)Readfile->Get("AERAIOTree");
208  IObranch = IOLibTree->GetBranch("AERAIO");
209  // evtSecBranch = IOLibTree->GetBranch("vAERAevents.EVseconds");
210  IObranch->SetAddress(&RadioFileIORead);
211 
212  unsigned int NumberEvents = IOLibTree->GetEntries();
213 
214  // Search in a given interval around event time, noise-event is randomly selected from candidates
215  // get list of event numbers that are within the allowed time interval
216  vector<int> notBadStations;
217  unsigned int stationsInTotal = 0;
218  vector<int> infoList;
219  EventListWithStations.clear();
220  debugstr << "Number of events: " << NumberEvents << endl
221  << "TimeStamp:" << noiseTimeStamp << endl;
222  INFODebug(debugstr);
223 
224  // determine number of traces which are needed
225  evt::ShowerSimData& simshow = event.GetSimShower();
226  evt::RadioSimulation& rsim = simshow.GetRadioSimulation();
227 
228  // Number of requiered noise traces, reduces when allow to shift traces
229  unsigned int requiered_number = rsim.GetNumPulses();
230  if (fTraceShifting)
231  requiered_number = (unsigned int)requiered_number / 6 + 1;
232 
233  // loop over all events in selected file
234  int idx = -1;
235  // if fCheckTimeWindow is false only ask 5 events for data within one file
236  // if no stations where found go the next file.
237  unsigned int n_tried_events_in_file = 0;
238  do {
239  ++idx;
240 
241  debugstr.str("");
242  warnstr.str("");
243 
244  // find the index to get the event
245  int used_index = 0;
246  if (fCheckTimeWindow) {
247  used_index = idx; // here could be a smarter code, such that it is not iterated to much
248  } else {
249  // this is done so that not always the same time (beginning of file) is used for fCheckTimeWindow = 0
250  used_index = CLHEP::RandFlat::shootInt(fRandomEngine, 0, NumberEvents - 1);
251  n_tried_events_in_file++;
252  if (n_tried_events_in_file > 5 && stationsInTotal == 0)
253  break;
254  }
255 
256  // get event
257  IOLibTree->GetEntry(used_index);
258  AERAevent* const aeraevent = RadioFileIORead->getAeraRadioFileEvent();
259  if (!aeraevent->getAeraEventTriggerIsPeriodic())
260  continue;
261 
262  if (fCheckTimeWindow) {
263  utl::TimeStamp probeTimeStamp = utl::TimeStamp(aeraevent->getAeraEventSeconds());
264  if (noiseTimeStamp < probeTimeStamp
265  || std::abs(probeTimeStamp - noiseTimeStamp) > fMaxTimeDifference){
266  debugstr << "Event " << used_index << ": (" << probeTimeStamp << ") is NOT in the specified range. continue. ";
267  INFODebug(debugstr);
268  continue;
269  }
270 
271  debugstr << "event " << used_index << " is in the specified range. "
272  << "Now check how many stations are found (also check BP database). ";
273  INFODebug(debugstr);
274  }
275 
276  if (EventHasStations(fStationIDList, aeraevent, rDetector).size() == 0) {
277  INFODebug("No matched stations in event.. try next");
278  continue;
279  }
280 
281  //check for bad period (again, for specific time)
282  notBadStations.clear();
283  TimeRangeMap::IdCollection badIds = fRejectMap.GetBadStations(noiseTimeStamp); // manual BP
284  debugstr.str("");
285  for (auto it = fStationIDList.begin() ; it != fStationIDList.end(); ++it) {
286  auto reason = rDetector.GetBadStationReason(*it); // from DB
287  if (reason) {
288  debugstr << "\n\tStation rejceted: " << *it << ", reason: " << reason;
289  continue; // skip if station is in BP Database.
290  }
291  if(!(std::find(badIds.begin(), badIds.end(), *it) != badIds.end())) {
292  notBadStations.push_back(*it);
293  debugstr << "\n\tStation accepted: " << *it;
294  }
295  }
296  INFODebug(debugstr);
297 
298  // check
299  if (notBadStations.empty()) {
300  INFOFinal("all stations in event are bad.. try next");
301  continue;
302  }
303 
304  vector<int> matchedIDs = EventHasStations(notBadStations, aeraevent, rDetector);
305  if (matchedIDs.size() == 0) {
306  INFODebug("No matched good stations in event.. try next");
307  continue;
308  }
309 
310  closeEventIds.push_back(used_index);
311  EventListWithStations.emplace_back(used_index, matchedIDs);
312  stationsInTotal += matchedIDs.size();
313 
314  } while (stationsInTotal < requiered_number and (unsigned int)idx < NumberEvents); // still stop after one full iteration
315 
316  // check for existing noise trace
317  if (closeEventIds.size() == 0 || stationsInTotal < requiered_number) {
318  warnstr << "To few stations found within " << fMaxTimeDifference / utl::minute
319  << " minutes has been found. (Checked time: " << fCheckTimeWindow << ")" << endl
320  << "Or no stations were found (in total: "
321  << stationsInTotal << "). File will be skipped";
322  delete Readfile;
323  delete RadioFileIORead;
324  if (fNoiseFileSelection == "Manually") {
325  ERROR("The manually selected noise file doesn't contain the defined stations...aborting!");
326  return eFailure;
327  }
328  WARNING(warnstr);
329  continue;
330  }
331 
332  infostr.str("");
333  infostr << "Found " << stationsInTotal << " stations in " << closeEventIds.size()
334  << " events. (If Shifting is used, each trace is used 6 times)";
335  INFOFinal(infostr);
336 
337  fileOK = true;
338  }
339 
340  // Mapping the indices of the noise event stations within the root container
341  // to their station number for later use.
342  unsigned int iterationCounter = 0;
343  unsigned int internalStationCounter = 0;
344  // Adding noise to the data, depending on if the station exists in both: noise-file and data.
345  for (auto sIt = rEvent.StationsBegin(); sIt != rEvent.StationsEnd(); ++sIt) {
346  revt::Station& station = *sIt;
347  const int stationID = station.GetId();
348  unsigned int rootID = 0;
349  unsigned int eventsRead = fTraceShifting ? (int)iterationCounter / 6 : iterationCounter;
350  unsigned int nTimesUsed = fTraceShifting ? iterationCounter % 6: iterationCounter;
351 
352  // Fetching the whole selected noise-event from the root-file
353  IOLibTree->GetEntry(EventListWithStations[eventsRead].first);
354  AERAevent* const aeraevent = RadioFileIORead->getAeraRadioFileEvent();
355 
356  debugstr.str("");
357  debugstr << "\n\tIteration " << iterationCounter << ", Event: " << eventsRead
358  << " (is event no. " << closeEventIds[eventsRead] << ")"
359  << " Traces were used " << nTimesUsed << " times."
360  << "\n\tImporting Noise for station " << stationID
361  << ", fetching aera event " << EventListWithStations[eventsRead].first;
362  INFODebug(debugstr);
363 
364  // Printing some general information
365  // std::ostringstream generalInfo;
366  // generalInfo << "General info concerning the noise-event selection:\n"
367  // "\tGPSSecond of the chosen noise-event: " << aeraevent->getAeraEventSeconds() << "\n"
368  // "\tGPSSecond of the processed event : " << eventTime.GetTimeStamp().GetGPSSecond() << '\n';
369  // INFOIntermediate(generalInfo);
370 
371  // get stations
372  vector<int> stationsInEvent = EventListWithStations[eventsRead].second;
373 
374  // this array stores the channel association of the replacement station. This is necessary as numbering of the
375  // channels might not be the same. However, in most cases channel 1 of the current station corresponds also to
376  // channel 1 of the replacement station
377  short replacementChannelId[4] = { -1, -1, -1, -1 };
378  debugstr.str("");
379  const int tmpRootID = stationsInEvent[internalStationCounter];
380  debugstr << "\n\tevent station counter " << internalStationCounter << " (index) of " << stationsInEvent.size() << " (size)"
381  << "\n\tEvent: " << eventsRead << " of " << EventListWithStations.size();
382  INFODebug(debugstr);
383 
384 
385  aerarootiostation::Station* const rootIoReplacementStation = aeraevent->getAeraEventStation(tmpRootID);
386  const int tmpReplacementStationID = rootIoReplacementStation->getAeraStationLsID() + 100; //FIXME: Station Ids in RadioFile and RDetector differ by 100. Do not compare station Ids but rather station names (AERA_XXX).
387 
388  debugstr << "\n\tChecking station " << tmpReplacementStationID
389  << " if it is a suitable replacement (this corresponds to station number "
390  << tmpRootID << " in rootio file)";
391  INFODebug(debugstr);
392 
393  // for next iteration
394  if (stationsInEvent.size() > internalStationCounter + 1) { // next stations
395  internalStationCounter += 1;
396  }
397  else { // next event (resp. same event shifted)
398  internalStationCounter = 0;
399  iterationCounter += 1;
400  }
401 
402  if (eventsRead > EventListWithStations.size()-2) {
403  WARNING("Repeat loop ...");
404  iterationCounter = 0; //repeat if not enough stations are present....
405  }
406 
407  // first check if station present in the data is also available in the detector description
408  const std::vector<int> stationIdVector = rDetector.GetFullStationList();
409  if (std::find(stationIdVector.begin(), stationIdVector.end(), tmpReplacementStationID) == stationIdVector.end()) {
410  infostr.str("");
411  infostr << "Station " << tmpReplacementStationID
412  << " is present in data but not in the detector description";
413  INFOIntermediate(infostr);
414  continue;
415  }
416 
417  const rdet::Station& replacementStation = rDetector.GetStation(tmpReplacementStationID);
418  bool stationIsSuitable = true;
419 
420  // loop through the channels of the station and check if the station in the noise file has the same properties
421  for (rdet::Station::ChannelIterator chIt = rDetector.GetStation(station.GetId()).ChannelsBegin();
422  chIt != rDetector.GetStation(station.GetId()).ChannelsEnd(); ++chIt) {
423  debugstr.str("");
424  debugstr << "checking channel " << chIt->GetId();
425  INFODebug(debugstr);
426  if (!station.HasChannel(chIt->GetId())) { // if channel is not present in data, skip to next channel
427  continue;
428  }
429  const revt::Channel& channel = station.GetChannel(chIt->GetId());
430  if (!channel.IsActive()) {
431  debugstr.str("");
432  debugstr << "channel " << chIt->GetId() << " is not active, continue with next channel";
433  INFODebug(debugstr);
434  continue;
435  }
436 
437  const rdet::Channel& detChannel = *chIt;
438  bool similarChannelFound = false; //used to break the loop when we found a channel
439  for (rdet::Station::ChannelIterator replacementChIt = replacementStation.ChannelsBegin();
440  (replacementChIt != replacementStation.ChannelsEnd()) && !similarChannelFound;
441  ++replacementChIt) {
442  const rdet::Channel& replacementChannel = *replacementChIt;
443  // check if orientation of the channel is the same
444  if (std::abs(detChannel.GetOrientationZenith() - replacementChannel.GetOrientationZenith()) < 3*utl::degree &&
445  std::abs(detChannel.GetOrientationAzimuth() - replacementChannel.GetOrientationAzimuth()) < 3*utl::degree) {
446  // check is channel and antenna type are the same
447  if ((detChannel.GetChannelType() == replacementChannel.GetChannelType()) &&
448  (detChannel.GetAntennaTypeName() == replacementChannel.GetAntennaTypeName())) {
449  // check if sampling frequency is the same
450  if (std::abs(detChannel.GetSamplingFrequency() - replacementChannel.GetSamplingFrequency()) < 0.01) {
451  // check if ADC is the same
452  if (detChannel.GetBitDepth() == replacementChannel.GetBitDepth()) {
453  similarChannelFound = true;
454  replacementChannelId[chIt->GetId() - 1] = replacementChannel.GetId();
455  infostr.str("");
456  infostr << "found replacement for channel " << chIt->GetId()
457  << ": it is channel " << replacementChannel.GetId() << " of station "
458  << replacementStation.GetId() << " (" << tmpReplacementStationID << ")";
459  INFOIntermediate(infostr);
460  }
461  }
462  }
463  }
464  }
465 
466  if (!similarChannelFound) {
467  stationIsSuitable = false;
468  }
469  }
470 
471  if (stationIsSuitable) {
472  infostr.str("");
473  infostr << "Suitable noise station was found for station " << stationID
474  << ". Will use station " << tmpReplacementStationID << " in the noise file";
475  INFOIntermediate(infostr);
476  rootID = tmpRootID;
477  } else {
478  debugstr.str("");
479  debugstr << "Station " << tmpReplacementStationID
480  << " is not a suitable replacement for station " << stationID
481  << " I think this shouldn't have happened... ";
482  INFODebug(debugstr);
483  continue;
484  }
485  // end looking for replacement station
486 
487  // Storing which channels of the station contribute to the noise-event.
488  const int noiseChMask = aeraevent->getAeraEventStation(rootID)->getAeraStationChannelMask();
489  const bool noiseChannelExists[4] = {
490  bool(noiseChMask & 1),
491  bool(noiseChMask & 2),
492  bool(noiseChMask & 4),
493  bool(noiseChMask & 8)
494  };
495 
496 
497  /* the channel numbering of the replacement station might be different
498  * -> resort the */
499 // bool tmpNoiseChannelExists[4] = noiseChannelExists;
500 // noiseChannelExists[replacementChannelId[0]-1] = tmpNoiseChannelExists[0];
501 // noiseChannelExists[replacementChannelId[1]-1] = tmpNoiseChannelExists[1];
502 // noiseChannelExists[replacementChannelId[2]-1] = tmpNoiseChannelExists[2];
503 // noiseChannelExists[replacementChannelId[3]-1] = tmpNoiseChannelExists[3];
504 
505  std::ostringstream debug;
506  debug << "ChannelMask from noise-station" << noiseChMask << ":" << noiseChannelExists[0]
507  << noiseChannelExists[1] << noiseChannelExists[2] << noiseChannelExists[3];
508  INFODebug(debug);
509 
510  //if (!usingReplacementStation) {
511  for (revt::Station::ChannelIterator cIt = station.ChannelsBegin(); cIt != station.ChannelsEnd(); ++cIt) {
512 
513  revt::Channel& channel = *cIt;
514  revt::ChannelADCTimeSeries& timeSeries = channel.GetChannelADCTimeSeries();
515 
516  // Checking if the channel of the processed station contribute to the event.
517  // If not, continue with the next channel.
518  if (!station.HasChannel(cIt->GetId()) || !channel.IsActive())
519  continue;
520 
521  // Get number of adc counts from RDetector
522  const short bitDepth =
523  det.GetRDetector().GetStation(station.GetId()).GetChannel(channel.GetId()).GetBitDepth();
524  const short numberOfADCCounts = pow(2., bitDepth) - 1;
525 
526  // Checking if the noise of this channel can be added to the event. If not, reject channel.
527  unsigned int noiseSeriesLength = 0;
528  int channelIdInNoiseFile = cIt->GetId();
529  channelIdInNoiseFile = replacementChannelId[cIt->GetId() - 1];
530  debug.str("");
531  debug << "original channel id " << cIt->GetId() << " cooresponds to channel id "
532  << channelIdInNoiseFile << " in noise file";
533  INFODebug(debug);
534 
535  if (!noiseChannelExists[channelIdInNoiseFile - 1]) {
536  cIt->SetNotActive();
537  infostr.str("");
538  infostr << "The channel " << cIt->GetId() << " of station " << stationID
539  << " exists for data but not for noise. ---> Setting channel not active!";
540  INFOIntermediate(infostr);
541  continue;
542  }
543 
544  noiseSeriesLength = aeraevent->getAeraEventStation(rootID)->getAeraStationADC(channelIdInNoiseFile - 1)->GetADCValuesSize();
545  if (noiseSeriesLength <= timeSeries.GetSize()) {
546  cIt->SetNotActive();
547  warnstr.str("");
548  warnstr << "The length " << noiseSeriesLength << " of the noise timeseries in channel "
549  << cIt->GetId() << " is shorter then the length " << timeSeries.GetSize()
550  << " of data timeseries in station " << stationID << "---> Setting channel not active!";
551  WARNING(warnstr);
552  continue;
553  }
554 
555  // Finally adding the noise event to the processed pedestal free event.
556  const revt::ChannelADCTimeSeries timeSeriesOrig = timeSeries;
557  revt::ChannelADCTimeSeries pedestalFree = timeSeries;
558  for (unsigned int i = 0; i < timeSeries.GetSize(); ++i) {
559  //Removing pedestal of event time-series, in order to add the pedestal-free event to a noise-trace.
560  RemovePedestal(pedestalFree);
561 
562  // get (shifted) adc count
563  unsigned int j = fTraceShifting ? (i + nTimesUsed * noiseSeriesLength / 6) % noiseSeriesLength : i;
564  const int tmpADCValue =
565  aeraevent->getAeraEventStation(rootID)->getAeraStationADC(channelIdInNoiseFile - 1)->GetADCValues(j);
566 
567  // account for gain correction (if wanted)
568  const double mean = utl::TraceAlgorithm::Mean(timeSeriesOrig, 0, timeSeriesOrig.GetSize() - 1);
569  const int int_mean = int(std::abs(mean));
570 
571  const int noiseADCValue = int(tmpADCValue * pow(10.0, fGainFactor / 20) + int_mean * (1 - pow(10.0, fGainFactor/ 20)));
572 
573  // Decide if noise should be added to simulated data or replace it to create pure noise events
574  int val = fReplaceDataWithNoise ? noiseADCValue : pedestalFree[i] + noiseADCValue;
575 
576  // Need to be done correctly, and info should be taken from detector geometry
577  // WHY, it seems to be done properly??
578  if (val > numberOfADCCounts) {
579  warnstr.str("");
580  warnstr << "ADC overflow (ADC = " << val << ", \tbin " << i << " , (shifted-> bin is actually: " << j << ").\tstation "
581  << cIt->GetStationId() << ")\tnoise = " << noiseADCValue << "\tsignal = "
582  << timeSeries[i] << "\tsignal without pedestal = " << pedestalFree[i];
583  WARNING(warnstr);
584  val = numberOfADCCounts;
585  }
586 
587  if (val < 0) {
588  warnstr.str("");
589  warnstr << "ADC underflow (ADC = " << val << ", \tbin " << i << " , (shifted-> bin is actually: " << j << ".\tstation "
590  << cIt->GetStationId() << ")\tnoise = " << noiseADCValue << "\tsignal = "
591  << timeSeries[i] << "\tsignal without pedestal = " << pedestalFree[i];
592  WARNING(warnstr);
593  val = 0;
594  }
595  timeSeries[i] = val;
596 
597  }
598  } // for Channel
599 
600  if (fTraceShifting)
601  nTimesUsed += 1;
602 
603  int NotActiveChannels = 0;
604  for (revt::Station::ChannelIterator cIt = station.ChannelsBegin(); cIt != station.ChannelsEnd(); ++cIt) {
605  revt::Channel& channel = *cIt;
606  if (!station.HasChannel(cIt->GetId()) || !channel.IsActive()) {
607  ++NotActiveChannels;
608  }
609  }
610 
611  if (NotActiveChannels > 2) {
612  warnstr.str("");
613  warnstr << "Station " << stationID << " has more than two not active channels "
614  << "---> Rejecting whole station!";
615  WARNING(warnstr);
617  }
618  } // for Station
619 
620  // Some clean up:
621  delete Readfile;
622  delete RadioFileIORead;
623 
624  // in case we changed the detector time when adding the noise
625  // we now change it back to its original value
626  det.Update(origTimeStamp);
627 
628 
629  return eSuccess;
630 }
631 
632 
634 RdVirtualStationNoiseImporter::Finish()
635 {
636  std::ostringstream out;
637  out << "\n\tNumber of stations rejected due to missing noise: " << fNumberOfRejectedStationsWithoutNoise;
638 
639  INFO(out);
640 
641  return eSuccess;
642 }
643 
644 
645 void
646 RdVirtualStationNoiseImporter::RemovePedestal(revt::ChannelADCTimeSeries& timeSeries)
647 {
648  const double mean = utl::TraceAlgorithm::Mean(timeSeries, 0, timeSeries.GetSize() - 1);
649  const int int_mean = int(std::abs(mean));
650  for (revt::ChannelADCTimeSeries::Iterator it = timeSeries.Begin(); it != timeSeries.End(); ++it)
651  *it -= int_mean;
652 }
653 
654 
655 void
656 RdVirtualStationNoiseImporter::RemovePedestal(std::vector<int>& timeSeries)
657 {
658  double mean = 0;
659  unsigned int N = 0;
660  for (std::vector<int>::iterator it = timeSeries.begin(); it != timeSeries.end(); ++it) {
661  mean += *it;
662  ++N;
663  }
664  mean /= N;
665  const int int_mean = int(std::abs(mean));
666  for (std::vector<int>::iterator it = timeSeries.begin(); it != timeSeries.end(); ++it)
667  *it -= int_mean;
668 }
669 
670 
671 bool
672 RdVirtualStationNoiseImporter::GetNoiseFileNameAtTime(const utl::UTCDateTime& dateTime,
673  const utl::UTCDateTime& startingDay,
674  std::string& NoiseImportfilename)
675 {
676  std::ostringstream filename;
677  std::ostringstream subdirectory;
678 
679  if (fExpectSubDirectories) {
680 
681  subdirectory << startingDay.GetYear() << std::setfill('0') << "/" << std::setw(2)
682  << startingDay.GetMonth() << "/";
683  if ((fTimeIntervalInFile == "Hour")) {
684  subdirectory << std::setfill('0') << std::setw(2) << startingDay.GetDay() << "/";
685  }
686 
687  }
688  filename << fFilenamePrefix;
689  filename << startingDay.GetYear() << "_" << std::setfill('0') << std::setw(2)
690  << startingDay.GetMonth() << "_" << std::setfill('0') << std::setw(2)
691  << startingDay.GetDay();
692  if ((fTimeIntervalInFile == "Hour")) {
693  filename << "_" << std::setfill('0') << std::setw(2) << dateTime.GetHour();
694  }
695  if (fFilenameSuffix != "0")
696  filename << fFilenameSuffix;
697  filename << ".root";
698  NoiseImportfilename = fNoiseFilePath + subdirectory.str() + filename.str();
699 
700  // Checking if the noise-file exists.
701  std::ifstream checkfile(NoiseImportfilename.c_str());
702  if (!checkfile) {
703  std::ostringstream warning;
704  warning << "Cannot find the corresponding noise-file to the event from " << dateTime.GetYear()
705  << std::setfill('0') << std::setw(2) << dateTime.GetMonth() << std::setfill('0')
706  << std::setw(2) << dateTime.GetDay() << " at " << NoiseImportfilename << "."
707  << std::endl
708  << "Check if the desired file exists at the path specified by the variable "
709  "\"NoiseFilePath\" in the initfile!";
710  WARNING(warning);
711  return false;
712  } else {
713  std::ostringstream info;
714  info << "Reading from noise-file " << NoiseImportfilename << "." << std::endl;
715  INFOFinal(info);
716  }
717  return true;
718 }
719 
720 vector<int>
721 RdVirtualStationNoiseImporter::EventHasStations(vector<int> stationID, AERAevent* const aeraevent, const rdet::RDetector& rDetector)
722 {
723  ostringstream debugstr;
724  std::vector<int> matchedID;
725 
726  // loop over all LS (stations)
727  for (int i = 0; i < aeraevent->getAeraEventLsCount(); ++i) {
728  const int tmpRootID = i;
729  aerarootiostation::Station* const rootIoReplacementStation = aeraevent->getAeraEventStation(tmpRootID);
730 
731  //FIXME: Station Ids in RadioFile and RDetector differ by 100.
732  //Do not compare station Ids but rather station names (AERA_XXX).
733  const int tmpReplacementStationID = rootIoReplacementStation->getAeraStationLsID() + 100;
734 
735  for (std::vector<int>::iterator matchedIdIt = stationID.begin(); matchedIdIt != stationID.end(); ++matchedIdIt) {
736  // match
737  if (*matchedIdIt == tmpReplacementStationID - 100) {
738 
739  //check
740  if (rootIoReplacementStation->getNumberOfAvailableAERAStationADCs() == 0
741  || rootIoReplacementStation->getAeraStationStatus() == 0) {
742  debugstr.str("");
743  debugstr << "number of ADS is " << rootIoReplacementStation->getNumberOfAvailableAERAStationADCs()
744  << "\nStation Status is " << rootIoReplacementStation->getAeraStationStatus() << " --> skip " << endl;
745  INFODebug(debugstr);
746  continue;
747  }
748 
749  /*
750  cout << "matched ID: " << *matchedIdIt << endl;
751  cout << "station in Ev.: " << tmpRootID << endl;
752  cout << "station trigger is periodic = " << rootIoReplacementStation->getAeraStationTriggerIsPeriodic() << endl;
753  cout << "station status = " << rootIoReplacementStation->getAeraStationStatus() << endl;
754  cout << "station message ADCcount = " << rootIoReplacementStation->getAeraStationMessageADCcount() << endl;
755  cout << "# ADCs: " << rootIoReplacementStation->getNumberOfAvailableAERAStationADCs() << endl;
756  cout << "ADC values ch 0: " << rootIoReplacementStation->getAeraStationADC(0)->GetADCValuesSize() << endl;
757  cout << "ADC values ch 1: " << rootIoReplacementStation->getAeraStationADC(1)->GetADCValuesSize() << endl;
758  cout << "ADC values ch 2: " << rootIoReplacementStation->getAeraStationADC(2)->GetADCValuesSize() << endl;
759  cout << "ADC values ch 3: " << rootIoReplacementStation->getAeraStationADC(3)->GetADCValuesSize() << endl;
760  cout << "now checking compatibitlity of stations..." << endl;
761  */
762 
763  // first check if station present in the data is also available in the detector description
764  const std::vector<int> stationIdVector = rDetector.GetFullStationList();
765  if (std::find(stationIdVector.begin(), stationIdVector.end(), tmpReplacementStationID) == stationIdVector.end()) {
766  debugstr.str("");
767  debugstr << "Station " << tmpReplacementStationID << " is present in data but not in the detector description";
768  INFODebug(debugstr);
769  continue;
770  }
771 
772  debugstr << "Matched station "<< tmpReplacementStationID << " (root id: " << tmpRootID << ")";
773 
774  // const rdet::Station& replacementStation = rDetector.GetStation(tmpReplacementStationID);
775  // if (stationIsCompatible(testStation, replacementStation)) {
776  // if (!rootIoReplacementStation->getAeraStationStatus()) {
777  // cout << "station has no active channel... skip! " << endl;
778  // continue;
779  // }
780  // matchedID.push_back(tmpRootID);
781  // }
782 
783  INFODebug(debugstr);
784  matchedID.push_back(tmpRootID);
785  }
786  }
787  }
788  return matchedID;
789 }
790 
791 /*
792 bool
793 RdVirtualStationNoiseImporter::IsCompatible(const revt::Station& testStation, const rdet::Station& replacementStation)
794 {
795  std::ostringstream infostr;
796  short replacementChannelId[4] = { -1, -1, -1, -1 };
797 
798  for (rdet::Station::ChannelIterator chIt = replacementStation.ChannelsBegin();
799  chIt != replacementStation.ChannelsEnd(); ++chIt) {
800  infostr.str("");
801  infostr << "checking channel " << chIt->GetId();
802  INFODebug(infostr);
803  if (!testStation.HasChannel(chIt->GetId())) { // if channel is not present in data, skip to next channel
804  continue;
805  }
806  const revt::Channel& channel = testStation.GetChannel(chIt->GetId());
807  if (!channel.IsActive()) {
808  infostr.str("");
809  infostr << "channel " << chIt->GetId() << " is not active, continue with next channel";
810  INFODebug(infostr);
811  continue;
812  }
813  const rdet::Channel& detChannel = *chIt;
814  bool similarChannelFound = false; //used to break the loop when we found a channel
815  for (rdet::Station::ChannelIterator replacementChIt = replacementStation.ChannelsBegin();
816  (replacementChIt != replacementStation.ChannelsEnd()) && !similarChannelFound;
817  ++replacementChIt) {
818  const rdet::Channel& replacementChannel = *replacementChIt;
819  // check if orientation of the channel is the same
820  if (std::abs(detChannel.GetOrientationZenith() - replacementChannel.GetOrientationZenith()) < 3*utl::degree &&
821  std::abs(detChannel.GetOrientationAzimuth() - replacementChannel.GetOrientationAzimuth()) < 3*utl::degree) {
822  // check is channel and antenna type are the same
823  if ((detChannel.GetChannelType() == replacementChannel.GetChannelType()) &&
824  (detChannel.GetAntennaTypeName() == replacementChannel.GetAntennaTypeName())) {
825  // check if sampling frequency is the same
826  if (std::abs(detChannel.GetSamplingFrequency() - replacementChannel.GetSamplingFrequency()) < 0.01) {
827  // check if ADC is the same
828  if (detChannel.GetBitDepth() == replacementChannel.GetBitDepth()) {
829  similarChannelFound = true;
830  replacementChannelId[chIt->GetId() - 1] = replacementChannel.GetId();
831  infostr.str("");
832  infostr << "found replacement for channel " << chIt->GetId()
833  << ": it is channel " << replacementChannel.GetId() << " of station "
834  << replacementStation.GetId() << endl;
835  INFOIntermediate(infostr);
836  }
837  }
838  }
839  }
840  }
841 
842  }
843 }
844 */
845 
846 }
int GetBitDepth() const
Get number of bits of ADC.
void Update(const utl::TimeStamp &time, const bool invData=true, const bool invComp=true, const bool forceRadio=false)
Update detector: deletes currently constructed stations and sets new time.
Definition: Detector.cc:179
bool IsActive() const
int GetId() const
Return Id of the Channel.
Detector description interface for Station-related data.
boost::indirect_iterator< InternalChannelIterator, Channel & > ChannelIterator
Iterator over station for read/write.
ChannelIterator ChannelsEnd() const
End of the collection of pointers to Channels.
evt::Header & GetHeader()
int GetHour() const
Definition: UTCDateTime.h:54
int GetId() const
return ID of the Channel
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
static double Mean(const Trace< T > &trace, const unsigned int bin1, const unsigned int bin2)
Evaluate the mean of trace between bin1 and bin2.
Data structure for a radio simulation (including several SimRadioPulses)
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
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
StationIterator StationsEnd()
Definition: REvent.h:130
StationIterator StationsBegin()
Definition: REvent.h:128
int debug
Definition: dump1090.h:276
void Init()
Initialise the registry.
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
Detector description interface for Channel-related data.
double GetOrientationZenith() const
Get zenith-direction of Antenna for this Channel.
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
unsigned long long int GetBadStationReason(const int stationId) const
Definition: RDetector.cc:217
double pow(const double x, const unsigned int i)
bool HasREvent() const
int GetYear() const
Definition: UTCDate.h:44
ChannelIterator ChannelsEnd()
end Channel iterator for read/write
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
const utl::TimeStamp & GetTime() const
Definition: Event/Header.h:33
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
Iterator Begin()
Definition: Trace.h:75
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
bool HasChannel(const int pmtId) const
Check if a particular Channel object exists.
const std::string & GetChannelType() const
Get description of Channel Type.
#define INFOIntermediate(y)
Definition: VModule.h:162
Class representing a document branch.
Definition: Branch.h:107
class to hold data at the radio Station level.
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
double abs(const SVector< n, T > &v)
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
constexpr double degree
int GetId() const
Station ID.
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
void SetRejectedReason(const unsigned long long int reason)
int GetId() const
Get the station Id.
constexpr double minute
Definition: AugerUnits.h:149
#define INFODebug(y)
Definition: VModule.h:163
boost::indirect_iterator< InternalChannelIterator, const Channel & > ChannelIterator
ChannelIterator returns a pointer to a Channel.
int GetMonth() const
Definition: UTCDate.h:46
Channel & GetChannel(const int pmtId)
Retrieve a Channel by Id.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int GetDay() const
Definition: UTCDate.h:48
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
const std::string & GetAntennaTypeName() const
Get description of Antenna-Type.
ChannelADCTimeSeries & GetChannelADCTimeSeries()
Get Channel ADC trace (write access, only use this if you intend to change the data) ...
Class that holds the data associated to an individual radio channel.
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
long GetNumPulses() const
Get the number of radio pulses contained in the RadioSimulation.
char * filename
Definition: dump1090.h:266
double GetSamplingFrequency() const
Get sampling Frequency of ADC (unit?)
#define INFOFinal(y)
Definition: VModule.h:161
ChannelIterator ChannelsBegin() const
Beginning of the collection of pointers to Channels.
Iterator End()
Definition: Trace.h:76
#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
std::vector< int >::iterator Iterator
Definition: Trace.h:59
double GetOrientationAzimuth() const
Get azimuth-direction of Antenna for this Channel.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)

, generated on Tue Sep 26 2023.