RdChannelBeaconSignalExtractor.cc
Go to the documentation of this file.
2 #include <fwk/CentralConfig.h>
3 #include <utl/ErrorLogger.h>
4 
5 #include <evt/Event.h>
6 #include <revt/REvent.h>
7 #include <revt/Header.h>
8 #include <revt/Station.h>
9 #include <revt/Channel.h>
10 #include <revt/StationRecData.h>
11 
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/MathConstants.h>
19 #include <utl/TimeStamp.h>
20 #include <utl/TimeInterval.h>
21 #include <utl/FFTDataContainerAlgorithm.h>
22 #include <utl/AugerException.h>
23 
24 #include <det/Detector.h>
25 #include <rdet/RDetector.h>
26 
27 #include <complex>
28 #include <cmath>
29 #include <string>
30 #include <sstream>
31 #include <iostream>
32 #include <fstream>
33 #include <vector>
34 #include <map>
35 
36 using namespace std;
37 
38 
39 using namespace std;
40 using namespace utl;
41 using namespace fwk;
42 using namespace revt;
43 
44 
46 
48  fInfoLevel(eDebug),
49  fBeaconFrequencies(vector<double>()),
50  fReferenceChannel(1)
51  {
52  }
53 
54 
55  RdChannelBeaconSignalExtractor::~RdChannelBeaconSignalExtractor()
56  {
57  }
58 
59 
62  {
63  // Initialize your module here. This method
64  // is called once at the beginning of the run.
65  // The eSuccess flag indicates the method ended
66  // successfully. For other possible return types,
67  // see the VModule documentation.
68 
69  INFO("RdChannelBeaconSignalExtractor::Init()");
70 
71  // Read in the configurations of the xml file
72  Branch topBranch =
73  CentralConfig::GetInstance()->GetTopBranch("RdChannelBeaconSignalExtractor");
74  topBranch.GetChild("infoLevel").GetData(fInfoLevel);
75  if (fInfoLevel < eNone || fInfoLevel > eDebug) {
76  ERROR("<infoLevel> out of bounds");
77  return eFailure;
78  }
79 
80  topBranch.GetChild("BeaconFrequencies").GetData(fBeaconFrequencies);
81  topBranch.GetChild("ReferenceChannel").GetData(fReferenceChannel);
82 
83  return eSuccess;
84  }
85 
86 
88  RdChannelBeaconSignalExtractor::Run(evt::Event& event)
89  {
90  INFO("RdChannelBeaconSignalExtractor::Run()");
91 
92  // Check if there are events at all
93  if(!event.HasREvent()) {
94  WARNING("RdChannelBeaconSignalExtractor::No radio event found!");
95  return eContinueLoop;
96  }
97 
98  // check if beacon frequencies have to be read from database, or are provided in XML file
99  // in the first case, fBeaconFrequencies is empty, i.e. size()==0
100  if(fBeaconFrequencies.size() < 1) {
101  fBeaconFrequencies = det::Detector::GetInstance().GetRDetector().GetBeaconFrequencies();
102  }
103 
104  // Check if any frequencies are provided
105  stringstream fMessage;
106  fMessage.str("");
107  fMessage << "Number of beacon frequencies to look at: "
108  << fBeaconFrequencies.size();
109  INFO(fMessage.str());
110 
111  if(fBeaconFrequencies.size() < 1) {
112  WARNING("You must provide at least one frequency!");
113  return eBreakLoop;
114  }
115 
116 
117  REvent& rEvent = event.GetREvent();
118 
119  // match time stamps of stations (if different)
120  // this functionalty should be moved to its own module later
121  matchStationTimeStamps(rEvent);
122 
123  double referenceAmplitude = 0; // amplitude of first beacon frequency, of first station
124 
125  // loop through stations and for every station through every channel
127  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
128  Station& station = *sIt;
129 
130  for (Station::ChannelIterator cIt = station.ChannelsBegin();
131  cIt != station.ChannelsEnd(); ++cIt) {
132  Channel& channel = *cIt;
133 
134  // ignore all channels, but the reference channel (usually channel 1 = NS, high gain)
135  if (channel.GetId()!=fReferenceChannel)
136  continue;
137 
138  if (fInfoLevel>=eDebug) {
139  fMessage.str("");
140  fMessage << "Reading data from station "
141  << channel.GetStationId()
142  << ", channel "
143  << channel.GetId()
144  << ".";
145  INFO(fMessage.str());
146  }
147 
148  // Read the frequency spectrum of this channel
150  channel.GetChannelFrequencySpectrum();
151 
152  set<int> beaconFrequencyBins; // can be different for each station because of different electronics and sampling frequencies
153 
154  // loop through beacon frequencies and find corresponding frequency bins in the spectrum
155  for (ChannelTimeSeries::SizeType i=0; i < fBeaconFrequencies.size(); ++i) {
156  if (fInfoLevel>=eDebug) {
157  fMessage.str("");
158  fMessage << "Beacon frequency: "
160  << " MHz";
161  INFO(fMessage.str());
162 
163  fMessage.str("");
164  fMessage << "Spectrum reaches from "
165  << channel.GetFrequencyOfBin(0)/megahertz
166  << " MHz to "
167  << channel.GetFrequencyOfBin(spectrum.GetSize()-1)/megahertz
168  << " MHz, binning = "
169  << spectrum.GetBinning()/megahertz
170  << " MHz.";
171  INFO(fMessage.str());
172  }
173 
174  // check if spectrum has the correct lenght, such that the frequency bins are at the expected values
175  // for which the beacon has been optimized
176  if ( ((spectrum.GetSize()-1) % 1024) != 0 ) {
177  fMessage.str("");
178  fMessage << "Trace of station " << station.GetId() << " does not consist of 2048 samples or an integer multiple of it! "
179  << "It has " << (spectrum.GetSize()-1)*2 << " samples.";
180  WARNING(fMessage.str());
181  //return eFailure;
182  }
183 
184  // check if frequency is inside the range (take care that the order of the spectrum is unknown)
185  if( (fBeaconFrequencies[i] < min(channel.GetFrequencyOfBin(0),channel.GetFrequencyOfBin(spectrum.GetSize()-1)))
186  || (fBeaconFrequencies[i] > max(channel.GetFrequencyOfBin(0),channel.GetFrequencyOfBin(spectrum.GetSize()-1))) ) {
187  WARNING("Beacon frequency must be inside of the spectrum!");
188  return eContinueLoop;
189  }
190 
191  // find nearest frequency bin:
192  // bin = (f_beacon-f_0) * #lastBin / (f_1 - f_0)
193  double bin = (fBeaconFrequencies[i]-channel.GetFrequencyOfBin(0)) * (spectrum.GetSize()-1)
194  / (channel.GetFrequencyOfBin(spectrum.GetSize()-1) - channel.GetFrequencyOfBin(0));
195  beaconFrequencyBins.insert(round(bin));
196 
197  // get the phase
198  double phase = 0;
199 
200  phase = arg(spectrum[round(bin)]);
201  if (fInfoLevel>=eDebug) {
202  fMessage.str("");
203  fMessage << "Looking at frequency: "
204  << channel.GetFrequencyOfBin(round(bin)) / megahertz
205  << " MHz "
206  << "Phase: " << phase;
207  INFO(fMessage.str());
208  }
209 
210  if ((i==0) && (referenceAmplitude == 0))
211  referenceAmplitude = abs(spectrum[round(bin)]);
212 
213  }
214 
215  if (fInfoLevel>=eDebug) {
216  fMessage.str("");
217  fMessage << "Found: "
218  << beaconFrequencyBins.size()
219  << " beacon frequency bins.";
220  INFO(fMessage.str());
221  }
222  if(beaconFrequencyBins.size() != fBeaconFrequencies.size()) {
223  WARNING("Number of found beacon frequency bins differs from number of provided beacon frequencies.");
224  return eBreakLoop;
225  }
226 
227  // suppress spectrum outside of beacon frequencies,
228  // and normalize amplitude of beacon frequencies to amplitude of first beacon frequency
229  for (unsigned int i=0; i < spectrum.GetSize(); ++i) {
230  if ( beaconFrequencyBins.find(i) == beaconFrequencyBins.end() ) {
231  spectrum[i] *= 1.e-3;
232  } else {
233  spectrum[i] *= referenceAmplitude / abs(spectrum[i]);
234  //cout << "Station " << channel.GetStationId() << " - Spectrum value at beacon freq # " << i+1 << " = " << spectrum[i] << endl;
235  }
236  }
237  }
238  }
239 
240  return eSuccess;
241  }
242 
243 
245  RdChannelBeaconSignalExtractor::Finish()
246  {
247  stringstream fMessage;
248  // Put any termination or cleanup code here.
249  // This method is called once at the end of the run.
250 
251  INFO("RdChannelBeaconSignalExtractor::Finish()");
252 
253  return eSuccess;
254  }
255 
256  void
257  RdChannelBeaconSignalExtractor::matchStationTimeStamps(revt::REvent& rEvent) const
258  {
259  // store time stamp of the first station as reference
260  double firstTimeStamp = rEvent.CandidateStationsBegin()->GetRecData().GetParameter(eTraceStartTime);
261  // loop through all stations:
262  // shift traces if the time stamp does not match the one of the first station
264  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
265  Station& station = *sIt;
266  double stationTimeStamp = station.GetRecData().GetParameter(eTraceStartTime);
267 
268  if (stationTimeStamp != firstTimeStamp) {
269  // correct for the difference and set new time stamp
270  for (Station::ChannelIterator cIt = station.ChannelsBegin();
271  cIt != station.ChannelsEnd(); ++cIt){
272  Channel& channel = *cIt;
273 
274  FFTDataContainerAlgorithm::ShiftTimeSeries(channel.GetFFTDataContainer(), stationTimeStamp-firstTimeStamp);
275  }
276  station.GetRecData().SetParameter(eTraceStartTime,firstTimeStamp);
277  }
278  }
279  }
280 
281 }
std::vector< double > fBeaconFrequencies
Vector of frequencies emitted by the beacon.
ChannelFFTDataContainer & GetFFTDataContainer()
retrieve Channel FFTDataContainer (write access)
Branch GetTopBranch() const
Definition: Branch.cc:63
boost::filter_iterator< CandidateStationFilter, AllStationIterator > CandidateStationIterator
Iterator over all CandidateStations (i.e., HasSignal, HasNoSignal)
Definition: REvent.h:141
int GetId() const
Return Id of the Channel.
Report success to RunController.
Definition: VModule.h:62
StationRecData & GetRecData()
Get station level reconstructed data.
CandidateStationIterator CandidateStationsEnd()
Definition: REvent.h:146
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
double GetBinning() const
size of one slot
Definition: Trace.h:138
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
int fReferenceChannel
Reference channel (ususally 1 = NS, high gain)
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
bool HasREvent() const
int GetStationId() const
Return Id of the station to which this Channel belongs.
ChannelIterator ChannelsEnd()
end Channel iterator for read/write
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Break current loop. It works for nested loops too!
Definition: VModule.h:66
class to hold data at the radio Station level.
std::vector< double >::size_type SizeType
Definition: Trace.h:58
double abs(const SVector< n, T > &v)
CandidateStationIterator CandidateStationsBegin()
Definition: REvent.h:144
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
int GetId() const
Get the station Id.
double GetParameter(const Parameter i) const
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
ChannelFrequencySpectrum & GetChannelFrequencySpectrum()
retrieve Channel Frequency Spectrum (write access, only use this if you intend to change the data) ...
double GetFrequencyOfBin(const ChannelFrequencySpectrum::SizeType bin) const
Get the frequency corresponding to a bin of the frequency spectrum.
void SetParameter(Parameter i, double value, bool lock=true)
Class that holds the data associated to an individual radio channel.
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.