RdChannelDebugWriter.cc
Go to the documentation of this file.
1 #include "RdChannelDebugWriter.h"
2 
3 #include <fwk/CentralConfig.h>
4 
5 #include <utl/ErrorLogger.h>
6 #include <utl/Reader.h>
7 #include <utl/config.h>
8 
9 #include <evt/Event.h>
10 #include <revt/REvent.h>
11 #include <revt/Header.h>
12 #include <revt/Station.h>
13 #include <revt/Channel.h>
14 
15 #include <TROOT.h>
16 #include <TH1F.h>
17 #include <TFile.h>
18 
19 
20 using namespace fwk;
21 using namespace utl;
22 using namespace revt;
23 using std::vector;
24 using std::set;
25 using std::string;
26 using std::ostringstream;
27 using std::ofstream;
28 using std::endl;
29 using std::ios;
30 
31 
33 
36  {
37  // Read in the configurations of the xml file
38  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdChannelDebugWriter");
39  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
40 
41  // read in the station list as vector, and then copy it to the set class variable
42  const vector<int> dummyStationIDlist = topBranch.GetChild("StationIds").Get<vector<int>>();
43  fStationIds = set<int>(dummyStationIDlist.begin(), dummyStationIDlist.end());
44 
45  // read in the channel list as vector, and then copy it to the set class variable
46  const vector<int> dummyChannelIDlist = topBranch.GetChild("ChannelIds").Get<vector<int>>();
47  fChannelIds = set<int>(dummyChannelIDlist.begin(), dummyChannelIDlist.end());
48 
49  topBranch.GetChild("EventFraction").GetData(fEventFraction);
50  topBranch.GetChild("AsciiSpectrumNameBase").GetData(fAsciiSpectrumNameBase);
51  topBranch.GetChild("RootFileNameBase").GetData(fRootFileNameBase);
52  topBranch.GetChild("AsciiSpectrumNameBase").GetData(fAsciiSpectrumNameBase);
53  topBranch.GetChild("AsciiTraceNameBase").GetData(fAsciiTraceNameBase);
54 
55  const string unitstr = topBranch.GetChild("UseUnits").Get<string>();
56  fUseUnits = (unitstr == "yes");
57 
58  ostringstream info;
59  info << "fRootFileNameBase = " << fRootFileNameBase;
60  INFODebug(info);
61 
62  if (!fUseUnits)
63  INFOFinal("The Module will not convert to physical unit\n"
64  " Be sure of what you are doing");
65 
66  return eSuccess;
67  }
68 
69 
71  RdChannelDebugWriter::Run(evt::Event& event)
72  {
73  // Check if there are events at all
74  if (!event.HasREvent()) {
75  WARNING("No radio event found!");
76  return eContinueLoop;
77  }
78 
79  const REvent& rEvent = event.GetREvent();
80 
81  // Check if it is the first call for this event
82  if (fLastEventID != rEvent.GetHeader().GetId()) {
83  ++fEventCounter;
84  fStepCounter = 0;
85  fLastEventID = rEvent.GetHeader().GetId();
86  fLastEventGPSsecond = rEvent.GetHeader().GetTime().GetGPSSecond();
87  } else {
88  ++fStepCounter;
89  }
90 
91  ostringstream info;
92  info << "Running RdChannelDebugWriter for event number "
93  << fEventCounter << " (ID = " << fLastEventID << ") - step "
94  << fStepCounter << " with GPS second " << fLastEventGPSsecond;
95  INFOIntermediate(info);
96 
97  if (fEventFraction > 0)
98  if (((fEventCounter - 1) % fEventFraction) != 0) {
99  info.str("");
100  info << "Skip event, because only every " << fEventFraction
101  << "th event is considered for debug output (as set in XML).";
102  INFOFinal(info);
103  return eSuccess;
104  }
105 
106  // write debug output into root file, if requested
107  if (!fRootFileNameBase.empty())
108  writeRootOutput(rEvent);
109 
110  // write spectra into ASCII file, if requested
111  if (!fAsciiSpectrumNameBase.empty())
112  writeAsciiSpectrum(rEvent);
113 
114  // write traces into ASCII file, if requested
115  if (!fAsciiTraceNameBase.empty())
116  writeAsciiTrace(rEvent);
117 
118  return eSuccess;
119  }
120 
121 
122  void
123  RdChannelDebugWriter::writeRootOutput(const REvent& rEvent)
124  const
125  {
126  ostringstream count;
127  count << '_' << fLastEventGPSsecond << "_Step-" << fStepCounter;
128  TFile OutputFile((fRootFileNameBase + count.str() + ".root").c_str(), "recreate");
129 
130  float unitmuv = 1;
131  float unitmuvpermhz = 1;
132  if (fUseUnits) {
133  unitmuv = micro * volt;
134  unitmuvpermhz = micro * volt / megahertz;
135  }
136 
137  for (const auto& station : rEvent.StationsRange()) {
138 
139  // check if this station should be considered, otherwise continue
140  if (!fStationIds.empty() && fStationIds.find(station.GetId()) == fStationIds.end())
141  continue;
142 
143  ostringstream stat;
144  stat << "Station_" << station.GetId();
145 
146  for (const auto& channel : station.ChannelsRange()) {
147 
148  if (!channel.IsActive())
149  continue;
150 
151  // check if this channel should be considered, otherwise continue
152  if (!fChannelIds.empty() && fChannelIds.find(channel.GetId()) == fChannelIds.end())
153  continue;
154 
155  // Work on the frequency spectrum and time series of this channel
156  const auto& spectrum = channel.GetChannelFrequencySpectrum();
157  const auto& trace = channel.GetChannelTimeSeries();
158 
159  ostringstream chan;
160  chan << "_Ch." << channel.GetId();
161 
162  // Time Series histo
163  const double tsSize = trace.GetSize();
164  const double tsStart = trace.GetStart() / nanosecond;
165  const double tsStop = (trace.GetSize() - 1) / nanosecond;
166  TH1F HistTS(
167  (stat.str() + chan.str() + "_TimeSeries" + count.str()).c_str(),
168  (stat.str() + chan.str() + "_TimeSeries" + count.str()).c_str(),
169  tsSize, tsStart, tsStop
170  );
171 
172  /* Phase and absolute histos (Is taken into account the different conventions,
173  i.e. the karlsrhue data where the Spectrum reaches from 80 MHz to 40 MHz
174  instead of 0 MHz to 200 MHz) */
175  const double binFreqSize = spectrum.GetSize();
176  const double binFreqBegin = std::min(
177  channel.GetFrequencyOfBin(0),
178  channel.GetFrequencyOfBin(spectrum.GetSize() - 1)
179  ) / megahertz;
180  const double binFreqEnd = std::max(
181  channel.GetFrequencyOfBin(0),
182  channel.GetFrequencyOfBin(spectrum.GetSize() - 1)
183  ) / megahertz;
184 
185  TH1F HistPh(
186  (stat.str() + chan.str() + "_Phase" + count.str()).c_str(),
187  (stat.str() + chan.str() + "_Phase" + count.str()).c_str(),
188  binFreqSize, binFreqBegin, binFreqEnd
189  );
190  TH1F HistAbs(
191  (stat.str() + chan.str() + "_Abs" + count.str()).c_str(),
192  (stat.str() + chan.str() + "_Abs" + count.str()).c_str(),
193  binFreqSize, binFreqBegin, binFreqEnd
194  );
195 
196  int w = 0;
197  for (const auto& el : trace)
198  HistTS.SetBinContent(w++, el / unitmuv);
199 
200  int k = 0;
201  for (const auto& el : spectrum) {
202  HistPh.SetBinContent(k, std::arg(el) / deg);
203  HistAbs.SetBinContent(k++, abs(el) / unitmuvpermhz);
204  }
205 
206  HistTS.SetXTitle("ns");
207  HistTS.SetYTitle("microvolt");
208  HistPh.SetXTitle("MHz");
209  HistPh.SetYTitle("degrees");
210  HistAbs.SetXTitle("MHz");
211  HistAbs.SetYTitle("microvolt/MHz");
212  HistTS.Write();
213  HistPh.Write();
214  HistAbs.Write();
215  }
216  }
217  OutputFile.Close();
218  }
219 
220 
221  void
222  RdChannelDebugWriter::writeAsciiSpectrum(const REvent& rEvent)
223  const
224  {
225  float unitmuvpermhz = 1;
226  if (fUseUnits)
227  unitmuvpermhz = micro * volt / megahertz;
228 
229  for (const auto& station : rEvent.StationsRange()) {
230 
231  // check if this station should be considered, otherwise continue
232  if (!fStationIds.empty() && fStationIds.find(station.GetId()) == fStationIds.end())
233  continue;
234 
235  for (const auto& channel : station.ChannelsRange()) {
236 
237  if (!channel.IsActive())
238  continue;
239 
240  // check if this channel should be considered, otherwise continue
241  if (!fChannelIds.empty() && fChannelIds.find(channel.GetId()) == fChannelIds.end())
242  continue;
243 
244  const auto& spectrum = channel.GetChannelFrequencySpectrum();
245 
246  // write spectrum to file
247  ostringstream filename;
248  filename << fAsciiSpectrumNameBase
249  << '_' << fLastEventGPSsecond
250  << "_s" << channel.GetStationId()
251  << "_c" << channel.GetId()
252  << "_Step-" << fStepCounter
253  << ".dat";
254  ofstream outfile(filename.str().c_str());
255 
256  // write the frequency axis, the amplitude, and the phase of the spectrum to the file
257  for (ChannelFrequencySpectrum::SizeType i = 0; i < spectrum.GetSize(); ++i)
258  outfile << channel.GetFrequencyOfBin(i) / megahertz
259  << ' ' << abs(spectrum[i]) / unitmuvpermhz
260  << ' ' << arg(spectrum[i]) / deg << '\n';
261  }
262  }
263  }
264 
265 
266  void
267  RdChannelDebugWriter::writeAsciiTrace(const REvent& rEvent)
268  const
269  {
270  float unitmuv = 1;
271  if (fUseUnits)
272  unitmuv = micro * volt;
273 
274  for (const auto& station : rEvent.StationsRange()) {
275 
276  // check if this station should be considered, otherwise continue
277  if (!fStationIds.empty() && fStationIds.find(station.GetId()) == fStationIds.end())
278  continue;
279 
280  for (const auto& channel : station.ChannelsRange()) {
281 
282  if (!channel.IsActive())
283  continue;
284 
285  // check if this channel should be considered, otherwise continue
286  if (!fChannelIds.empty() && fChannelIds.find(channel.GetId()) == fChannelIds.end())
287  continue;
288 
289  const auto& trace = channel.GetChannelTimeSeries();
290 
291  // write trace to file
292  ostringstream filename;
293  filename << fAsciiTraceNameBase
294  << '_' << fLastEventGPSsecond
295  << "_s" << channel.GetStationId()
296  << "_c" << channel.GetId()
297  << "_Step-" << fStepCounter
298  << ".dat";
299  ofstream outfile(filename.str().c_str());
300 
301  // write the time axis and the amplitude to the file
302  for (ChannelTimeSeries::SizeType i = 0; i < trace.GetSize(); ++i)
303  outfile << trace.GetBinning() * i / nanosecond
304  << ' ' << trace[i] / unitmuv << '\n';
305  }
306  }
307  }
308 
309 }
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
utl::TimeStamp GetTime() const
Definition: REvent/Header.h:17
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
constexpr double deg
Definition: AugerUnits.h:140
T Get() const
Definition: Branch.h:271
#define INFOIntermediate(y)
Definition: VModule.h:162
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
std::vector< std::complex< double > >::size_type SizeType
Definition: Trace.h:58
constexpr double nanosecond
Definition: AugerUnits.h:143
double abs(const SVector< n, T > &v)
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
constexpr double megahertz
Definition: AugerUnits.h:155
#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
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
constexpr double micro
Definition: AugerUnits.h:65
char * filename
Definition: dump1090.h:266
#define INFOFinal(y)
Definition: VModule.h:161
int GetId() const
Definition: REvent/Header.h:21
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const double volt
Definition: GalacticUnits.h:38

, generated on Tue Sep 26 2023.