RdSimulationRadioTrigger.cc
Go to the documentation of this file.
2 
3 #include <fwk/CentralConfig.h>
4 
5 #include <utl/config.h>
6 #include <utl/AugerUnits.h>
7 #include <utl/ErrorLogger.h>
8 #include <utl/Reader.h>
9 #include <utl/TraceAlgorithm.h>
10 #include <utl/String.h>
11 #include <utl/Math.h>
12 
13 #include <evt/Event.h>
14 
15 #include <revt/Header.h>
16 #include <revt/REvent.h>
17 #include <revt/Station.h>
18 #include <revt/Channel.h>
19 #include <revt/StationRecData.h>
20 #include <revt/StationTriggerData.h>
21 
22 #include <rdet/RDetector.h>
23 
24 #include <sevt/SEvent.h>
25 #include <sevt/Station.h>
26 #include <sevt/StationSimData.h>
27 #include <sevt/StationTriggerData.h>
28 
29 #include <sdet/SDetector.h>
30 #include <sdet/Station.h>
31 #include <sdet/StationTriggerUtil.h>
32 
33 
34 using namespace std;
35 using namespace revt;
36 using namespace fwk;
37 using namespace utl;
38 using namespace det;
39 using namespace sdet::Trigger;
40 
41 
43 
46  {
47  Branch topBranch =
48  CentralConfig::GetInstance()->GetTopBranch("RdSimulationRadioTrigger");
49  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
50  topBranch.GetChild("ThresholdMethod").GetData(fThresholdMethod);
51  topBranch.GetChild("RadioT2Threshold").GetData(fRadioT2Threshold);
52  topBranch.GetChild("RejectRFIThreshold").GetData(fRejectRFIThreshold);
53  topBranch.GetChild("RejectRFIMultiplicity").GetData(fRejectRFIMultiplicity);
54 
55  ostringstream info;
56  info << "\n\tUsing "<< (fThresholdMethod ? "Geometric sum" : "Maximum channel") << " as RD trigger method \n"
57  << "\tThreshold for a radio T2 trigger: "<< fRadioT2Threshold << " ADC counts";
58  INFOFinal(info);
59 
60  return eSuccess;
61  }
62 
63 
65  RdSimulationRadioTrigger::Run(evt::Event& event)
66  {
67  // Check if there are events at all
68  if(!event.HasREvent()) {
69  WARNING("No radio event found!");
70  return eContinueLoop;
71  }
72 
73  ostringstream msg;
74 
75  vector<int> RDT2Stations;
76  REvent& rEvent = event.GetREvent();
77  const auto& eventTime = event.GetHeader().GetTime();
78 
79  if(!event.HasSEvent()) {
80  event.MakeSEvent();
81  }
82 
83  sevt::SEvent& sEvent = event.GetSEvent();
84 
85  const Detector& Det = Detector::GetInstance();
86  const rdet::RDetector& radioDet = Det.GetRDetector();
87 
88  // loop through stations and for every station through every channel
89  for (auto& rStation : rEvent.StationsRange()) {
90 
91  std::pair<ChannelTimeSeries, ChannelTimeSeries> channelAdcTrace;
92 
93  for (const auto& channel : rStation.ChannelsRange()) {
94 
95  const unsigned int channelID = channel.GetId();
96 
97  // Checking if the channel of the processed station contribute to the event.
98  // If not, continue with the next channel.
99  if (!rStation.HasChannel(channelID) || !channel.IsActive())
100  continue;
101 
102  if (channelID == 0)
103  GetTraceWithoutDCOffset(channelAdcTrace.first, channel);
104  else
105  GetTraceWithoutDCOffset(channelAdcTrace.second, channel);
106  }
107 
108  if (channelAdcTrace.first.GetSize() != channelAdcTrace.second.GetSize() ) {
109  msg.str("");
110  msg << "Station " << rStation.GetId()
111  << " is rejected as its channel traces do not have the same length!";
112  WARNING(msg);
113 
114  rStation.SetExcludedReason(eHardwareMismatch);
115  continue;
116  }
117 
118  // binning should be the same for both channels, just take Ch1
119  const int binning = rStation.GetChannel(1).GetChannelADCTimeSeries().GetBinning();
120 
121  double peakAmplitude = 0;
122  double peakTime = 0;
123  int sample = 0;
124 
125  std::vector<unsigned int> t2Bins;
126  std::vector<unsigned int> rfiBins;
127  bool signalT2 = false;
128 
129  // calculate geometric sum of both channels for threshold trigger
130  std::vector<double> finalAdcTrace;
131 
132  const int maxCh0 = *max_element(channelAdcTrace.first.Begin(),
133  channelAdcTrace.first.End(), AbsValue);
134  const int maxCh1 = *max_element(channelAdcTrace.second.Begin(),
135  channelAdcTrace.second.End(), AbsValue);
136 
137  if (fThresholdMethod == 0) { // maximum of both channels
138  if (maxCh0 > maxCh1)
139  std::copy(channelAdcTrace.first.Begin(), channelAdcTrace.first.End(),
140  std::back_inserter(finalAdcTrace));
141  else
142  std::copy(channelAdcTrace.second.Begin(), channelAdcTrace.second.End(),
143  std::back_inserter(finalAdcTrace));
144  } else if (fThresholdMethod == 1) { // geometric sum
145  for (unsigned int i = 0; i < channelAdcTrace.first.GetSize() ; ++i) {
146  finalAdcTrace.push_back(sqrt(Sqr(channelAdcTrace.first[i]) + Sqr(channelAdcTrace.second[i])));
147  }
148  } else {
149  ERROR("Threshold method not existent.");
150  return eFailure;
151  }
152 
153  for (unsigned int i = 0; i < finalAdcTrace.size(); ++i) {
154  if (std::abs(finalAdcTrace[i]) > fRadioT2Threshold)
155  t2Bins.push_back(i);
156  if (std::abs(finalAdcTrace[i]) > fRejectRFIThreshold)
157  rfiBins.push_back(i);
158  }
159 
160  // if no trigger just move on with next station
161  if (t2Bins.empty()) {
162  msg.str("");
163  msg << "Station " << rStation.GetId()
164  << " has no T2 trigger (not above threshold).";
165  INFODebug(msg);
166  continue;
167  }
168 
169  /* see if it is really a signal T2 or likely RFI.
170  For that check that there are not too many bins over some threshold within 500ns
171  after 1mus after the trigger */
172  for (auto const& t2bin: t2Bins) {
173  const int cnt = std::count_if(std::begin(rfiBins), std::end(rfiBins),
174  [&t2bin](unsigned int rfibin){return (rfibin >= t2bin+25 && rfibin <= t2bin+275);});
175  if (cnt <= fRejectRFIMultiplicity) {
176  peakAmplitude = finalAdcTrace[t2bin];
177  peakTime = t2bin * binning / 1000;
178  sample = t2bin;
179  signalT2 = true;
180  break;
181  }
182  }
183 
184  if (!signalT2) {
185  msg.str("");
186  msg << "Station " << rStation.GetId()
187  << " is rejected as it is a RFI trace!";
188  WARNING(msg);
189 
190  rStation.SetRejectedReason(eNoisy);
191  continue;
192  }
193 
194  // here comes the SEvent part. Pushing it to the SEvent and make WCD traces
195  const int sStID = rStation.GetId() - radioDet.GetRdSdStationIdLink();
196  RDT2Stations.push_back(sStID);
197 
198  if (!sEvent.HasStation(sStID))
199  sEvent.MakeStation(sStID);
200 
201  sevt::Station& sStation = sEvent.GetStation(sStID);
202 
203  if (!sStation.HasSimData())
204  sStation.MakeSimData();
205 
206  // okay now pushing some stuff into RD
207  // this is ugly, I know, but until now we do not know where the time difference
208  // between particles and radio comes from (electronics, physics or both) and how it behaves
209  // in simulations vs data. When we investigated that, we should change this. But it works here
210  rStation.GetTriggerData().SetSelfTriggerTime(
211  (peakTime + rStation.GetRecData().GetParameter(eTraceStartTime)/1000 + 13.2) * 1000 * nanosecond);
212  rStation.GetTriggerData().SetTriggerSource(StationTriggerData::eSelf);
213  rStation.GetTriggerData().SetSelfTriggerType(StationTriggerData::eT2Threshold);
214  rStation.GetTriggerData().SetSelfTriggerBin(sample);
215  rStation.GetTriggerData().SetSelfTriggerAmp(peakAmplitude);
216 
217  vector<const TimeDistributionI*> traces;
218 
219  int startBin = 0;
220  int stopBin = 0;
221  PrepareTraces(sStation, startBin, stopBin, traces);
222 
223  if (traces.size() < 3)
225 
226  const auto& dStation = Detector::GetInstance().GetSDetector().GetStation(sStation);
227  const int WCDTrigBin = rStation.GetTriggerData().GetSelfTriggerTime() / dStation.GetFADCBinSize();
228  const int traceStart = std::max(WCDTrigBin - (int)dStation.GetFADCTraceLength(), startBin);
230  traceStart, WCDTrigBin);
231  }
232 
233  if (!RDT2Stations.empty()) {
234  ostringstream info;
235  info << "\nAdding stations:" << '\n' << String::OfSortedIds(RDT2Stations) << " as RD T2s";
236  INFO(info);
237  }
238 
239  return eSuccess;
240  }
241 
242 
244  RdSimulationRadioTrigger::Finish()
245  {
246  ostringstream info;
247  info << "\n\tThere were " << fNbOfSaturatedChannels << " saturated channels!";
248  INFO(info);
249 
250  return eSuccess;
251  }
252 
253 
254  void
255  RdSimulationRadioTrigger::GetTraceWithoutDCOffset(ChannelTimeSeries& currTrace, const Channel& channel)
256  {
257  const auto adcTrace = channel.GetChannelADCTimeSeries();
258  const double mean = TraceAlgorithm::Mean(adcTrace, 0, adcTrace.GetSize() - 1);
259  for (auto& adcSignal : adcTrace)
260  currTrace.PushBack((double)adcSignal - mean);
261  }
262 
263 
264  bool
265  RdSimulationRadioTrigger::AbsValue(double a , double b)
266  {
267  return abs(a) < abs(b);
268  }
269 
270 }
271 
Branch GetTopBranch() const
Definition: Branch.cc:63
constexpr T Sqr(const T &x)
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
void MakeSimData()
Make station simulated data object.
void PrepareTraces(const sevt::Station &station, int &startBin, int &stopBin, std::vector< const TimeDistributionI * > &traces)
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
utl::TimeStamp GetTime() const
Definition: REvent/Header.h:17
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
bool HasREvent() const
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
int GetRdSdStationIdLink() const
Get Rd - Sd Station Id link.
Definition: RDetector.h:127
class to hold data at Station level
bool HasSimData() const
Check whether station simulated data exists.
void SetRejected(const int reason)
Set rejected station flag.
constexpr double nanosecond
Definition: AugerUnits.h:143
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
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
Definition: SEvent.cc:65
#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
#define INFODebug(y)
Definition: VModule.h:163
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: SEvent.h:116
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
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
double Mean(const std::vector< double > &v)
Definition: Functions.h:31
void Buffer(sevt::Station &station, const TimeStamp &eventTime, const StationTriggerData::Algorithm algorithm, const int pldBits, const int start, const int stop)
string OfSortedIds(vector< int > ids)
Definition: String.cc:65
#define INFOFinal(y)
Definition: VModule.h:161
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
bool HasSEvent() const

, generated on Tue Sep 26 2023.