CalcBeaconRefPhase.cc
Go to the documentation of this file.
1 #include "CalcBeaconRefPhase.h"
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/Reader.h>
15 #include <utl/config.h>
16 #include <utl/AugerUnits.h>
17 #include <utl/MathConstants.h>
18 #include <utl/TimeStamp.h>
19 #include <utl/TimeInterval.h>
20 #include <utl/FFTDataContainerAlgorithm.h>
21 #include <utl/AugerException.h>
22 
23 #include <det/Detector.h>
24 #include <rdet/RDetector.h>
25 
26 #include <complex>
27 #include <cmath>
28 #include <string>
29 #include <sstream>
30 #include <iostream>
31 #include <fstream>
32 #include <vector>
33 #include <map>
34 
35 #include <mysql/mysql.h>
36 
37 using namespace std;
38 using namespace utl;
39 using namespace fwk;
40 using namespace revt;
41 
42 
43 namespace CalcBeaconRefPhase {
44 
46  fBeaconFrequencies(vector<double>()),
47  fOutputRefPhaseFile(""),
48  fDBServer(""),
49  fReferenceStation(145),
50  fReferenceChannel(1),
51  fStationWithZeroPhase(101),
52  fConvergenceLimit(0.001),
53  fEventCounter(0),
54  fMaxNumberEvents(true),
55  fPhaseDifferences(std::map<double ,std::map<int ,vector<double> > >() )
56 {
57 }
58 
59 
60 CalcBeaconRefPhase::~CalcBeaconRefPhase()
61 {
62 }
63 
64 
67 {
68  // Initialize your module here. This method
69  // is called once at the beginning of the run.
70  // The eSuccess flag indicates the method ended
71  // successfully. For other possible return types,
72  // see the VModule documentation.
73 
74  INFO("CalcBeaconRefPhase::Init()");
75 
76  // Read in the configurations of the xml file
77  Branch topBranch =
78  CentralConfig::GetInstance()->GetTopBranch("CalcBeaconRefPhase");
79  topBranch.GetChild("infoLevel").GetData(fInfoLevel);
80  if (fInfoLevel < eNone || fInfoLevel > eDebug) {
81  ERROR("<infoLevel> out of bounds");
82  return eFailure;
83  }
84 
85  topBranch.GetChild("BeaconFrequencies").GetData(fBeaconFrequencies);
86  topBranch.GetChild("OutputRefPhaseFile").GetData(fOutputRefPhaseFile);
87  topBranch.GetChild("DBServer").GetData(fDBServer);
88  topBranch.GetChild("ReferenceStation").GetData(fReferenceStation);
89  topBranch.GetChild("ReferenceChannel").GetData(fReferenceChannel);
90  topBranch.GetChild("StationWithZeroPhase").GetData(fStationWithZeroPhase);
91  topBranch.GetChild("MaxNumberEvents").GetData(fMaxNumberEvents);
92 
93  return eSuccess;
94 }
95 
96 
98 CalcBeaconRefPhase::Run(evt::Event& event)
99 {
100  stringstream message;
101  message.str("CalcBeaconRefPhase::Run()");
102  INFO(message.str());
103 
104  // check if beacon frequencies have to be read from database, or are provided in XML file
105  // in the first case, fBeaconFrequencies is empty, i.e. size()==0
106  if(fBeaconFrequencies.size() < 1) {
107  fBeaconFrequencies = det::Detector::GetInstance().GetRDetector().GetBeaconFrequencies();
108  }
109 
110 
111  // obtain phases of event
112  std::map< double, std::map<int, double> > phases = map< double, map<int, double> >();
113 
114 
115  // Check if there are events at all
116  if(!event.HasREvent()) {
117  WARNING("PhaseFinder::No radio event found!");
118  return eContinueLoop;
119  }
120 
121  REvent& rEvent = event.GetREvent();
122 
123  // match time stamps of stations (if different)
124  // this functionalty should be moved to its own module later
125  matchStationTimeStamps(rEvent);
126 
127 
128  // get phases of reference station
129  map<double, double> refStationPhases = map<double, double> ();
131  const revt::ChannelFrequencySpectrum refSpectrum = refChannel.GetChannelFrequencySpectrum();
132 
133  // check if spectrum has the correct lenght, such that the frequency bins are at the expected values
134  // for which the beacon has been optimized
135  if ( ((refSpectrum.GetSize()-1) % 1024) != 0 ) {
136  message.str("");
137  message << "Trace of reference station " << fReferenceStation << " must consist of 2048 samples or an integer multiple of it!";
138  ERROR(message.str());
139  return eFailure;
140  }
141 
142  for (unsigned int beaconFreqN=0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN) {
143  // check if frequency is inside the range (take care that the order of the refSpectrum is unknown)
144  if( (fBeaconFrequencies[beaconFreqN] < min(refChannel.GetFrequencyOfBin(0),refChannel.GetFrequencyOfBin(refSpectrum.GetSize()-1)))
145  || (fBeaconFrequencies[beaconFreqN] > max(refChannel.GetFrequencyOfBin(0),refChannel.GetFrequencyOfBin(refSpectrum.GetSize()-1))) ) {
146  WARNING("Beacon frequency must be inside of the spectrum!");
147  return eContinueLoop;
148  }
149 
150  // find nearest frequency bin:
151  // bin = (f_beacon-f_0) * #lastBin / (f_1 - f_0)
152  double bin = (fBeaconFrequencies[beaconFreqN]-refChannel.GetFrequencyOfBin(0)) * (refSpectrum.GetSize()-1)
153  / (refChannel.GetFrequencyOfBin(refSpectrum.GetSize()-1) - refChannel.GetFrequencyOfBin(0));
154 
155  // get the phase
156  refStationPhases[ fBeaconFrequencies[beaconFreqN] ] = arg(refSpectrum[round(bin)]);
157  }
158 
159 
160  // loop through stations and for every station through every channel
162  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
163  Station& station = *sIt;
164 
165  // check, if this station is already present in the event counter and increase counter
166  if (fEventsPerStation.find(station.GetId())==fEventsPerStation.end()) {
167  fEventsPerStation[station.GetId()]=1;
168  } else {
169  ++fEventsPerStation[station.GetId()];
170  }
171 
172  Channel& channel = station.GetChannel(fReferenceChannel);
173 
174  if (fInfoLevel>=eObscure) {
175  message.str("");
176  message << "Calculating the phases of the beacon frequencies for channel "
177  << channel.GetId()
178  << " of station "
179  << channel.GetStationId()
180  << ".";
181  INFO(message.str());
182  }
183 
184  // Read the frequency spectrum of this channel
186 
187  if ( ((refSpectrum.GetSize()-1) % 1024) != 0 ) {
188  message.str("");
189  message << "Trace of station " << station.GetId() << " does not consist of 2048 samples or an integer multiple of it!"
190  << "It has " << (spectrum.GetSize()-1)*2 << " samples.";
191  WARNING(message.str());
192  //return eFailure;
193  }
194 
195 
196  // get the amplitude spectrum for SNR calculation
197  //Trace<double> amplitudeSpectrum;
198  //for (ChannelFrequencySpectrum::SizeType i = 0; i < spectrum.GetSize(); ++i)
199  // amplitudeSpectrum.PushBack(abs(spectrum[i]));
200 
201  // loop through beacon frequencies and find corresponding frequency in the spectrum
202  for (unsigned int beaconFreqN=0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN) {
203  if (fInfoLevel>=eDebug) {
204  message.str("");
205  message << "Beacon frequency: "
206  << fBeaconFrequencies[beaconFreqN]/megahertz
207  << " MHz";
208  INFO(message.str());
209 
210  message.str("");
211  message << "Spectrum reaches from "
212  << channel.GetFrequencyOfBin(0)/megahertz
213  << " MHz to "
214  << channel.GetFrequencyOfBin(spectrum.GetSize()-1)/megahertz
215  << " MHz, binning = "
216  << spectrum.GetBinning()/megahertz
217  << " MHz.";
218  INFO(message.str());
219  }
220 
221  // check if frequency is inside the range (take care that the order of the spectrum is unknown)
222  if( (fBeaconFrequencies[beaconFreqN] < min(channel.GetFrequencyOfBin(0),channel.GetFrequencyOfBin(spectrum.GetSize()-1)))
223  || (fBeaconFrequencies[beaconFreqN] > max(channel.GetFrequencyOfBin(0),channel.GetFrequencyOfBin(spectrum.GetSize()-1))) ) {
224  WARNING("Beacon frequency must be inside of the spectrum!");
225  return eContinueLoop;
226  }
227 
228  // find nearest frequency bin:
229  // bin = (f_beacon-f_0) * #lastBin / (f_1 - f_0)
230  double bin = (fBeaconFrequencies[beaconFreqN]-channel.GetFrequencyOfBin(0)) * (spectrum.GetSize()-1)
231  / (channel.GetFrequencyOfBin(spectrum.GetSize()-1) - channel.GetFrequencyOfBin(0));
232 
233  // get the phase
234  double phase = arg(spectrum[round(bin)]);
235 
236  if (fInfoLevel>=eDebug) {
237  message.str("");
238  message << "Looking at frequency: "
239  << channel.GetFrequencyOfBin(round(bin)) / megahertz
240  << " MHz "
241  << "Phase: " << phase;
242  INFO(message.str());
243  }
244 
245  // store phase
246  fPhaseDifferences[fBeaconFrequencies[beaconFreqN]][station.GetId()].push_back(phase - refStationPhases[fBeaconFrequencies[beaconFreqN]]);
247  }
248  }
249 
250  // check if maximum number of events was reached
251  ++fEventCounter;
253  return eBreakLoop;
254  }
255 
256  return eSuccess;
257 }
258 
259 
261 CalcBeaconRefPhase::Finish()
262 {
263  stringstream message;
264  // Put any termination or cleanup code here.
265  // This method is called once at the end of the run.
266 
267  INFO("CalcBeaconRefPhase::Finish()");
268  INFO("");
269  INFO("Calculating reference phases...");
270  INFO("");
271 
272  message.str("");
273  message << "\nPlease check manually, if the beacon frequency IDs are correct (i.e. the same as in the database):\n";
274  for (unsigned int beaconFreqN = 0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN)
275  message << beaconFreqN+1 << ": " << fBeaconFrequencies[beaconFreqN] << "\n";
276  message << endl;
277  WARNING(message.str());
278 
279  INFO("");
280 
281  // loop through beacon frequencies and calculate the reference phases
282  for (unsigned int beaconFreqN=0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN) {
283  // Calculate the reference phases iteratively by shifting the phases, until the mean becomes 0
284  // the total shift then corresponds to the reference phase
285  // In the map there are the reference phases and the corresponding RMS for each station
286  map<int, pair<double, double> > referencePhases = calculateReferencePhases(fPhaseDifferences[fBeaconFrequencies[beaconFreqN]]);
287 
288  // shift all reference phases such that the desired station has a reference phase of zero
289  if (referencePhases.find(fStationWithZeroPhase) == referencePhases.end()) {
290  message.str("");
291  message << "fStationWithZeroPhase (=" << fStationWithZeroPhase << ") not found in data!";
292  ERROR(message.str());
293  return eFailure;
294  }
295 
296  double zeroPhaseStationPhase = referencePhases[fStationWithZeroPhase].first;
297 
298  for (map<int, pair<double, double> >::iterator it = referencePhases.begin(); it != referencePhases.end() ; ++it) {
299  // substract phase of station which finally should have a reference phase of 0
300  it->second.first -= zeroPhaseStationPhase;
301  // confine phase between +/- pi
302  while ( it->second.first > kPi ) {
303  it->second.first -= kTwoPi;
304  }
305  while ( it->second.first < -kPi ) {
306  it->second.first += kTwoPi;
307  }
308 
309  // add all station IDs to the list of existing IDs at this occaision
310  fExistingStationIDs.insert( it->first);
311  //cout << "Result for station " << it->first << " \tRefPhase = " << it->second.first << " \tRMS = " << it->second.second << endl;
312  }
313 
314  // store reference phases in global map
315  fReferencePhases.push_back(referencePhases);
316  }
317 
318  // Write values to file, for debug output
319  if (fOutputRefPhaseFile != "") {
322  }
323 
324 
325  message.str("");
326  message << "Station ID \t #events";
327  for (vector<double>::iterator it=fBeaconFrequencies.begin(); it!=fBeaconFrequencies.end(); ++it) {
328  message << " \t" << *it/megahertz << " MHz";
329  }
330  INFO(message.str());
331 
332  // print number of events per frequency and station
333  for (set<unsigned int>::iterator it = fExistingStationIDs.begin(); it != fExistingStationIDs.end(); ++it) {
334  message.str("");
335  message << " " << *it << "\t " << fEventsPerStation[*it];
336 
337  for (unsigned int beaconFreqN=0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN) {
338  message << "\t " << fReferencePhases[beaconFreqN][*it].first << " +/- " << fReferencePhases[beaconFreqN][*it].second;
339  }
340  INFO(message.str());
341  }
342 
343  INFO("");
344 
345 
346 
347  return eSuccess;
348 }
349 
350 
351 void
352 CalcBeaconRefPhase::matchStationTimeStamps(revt::REvent& rEvent) const
353 {
354  // store time stamp of the first station as reference
355  double firstTimeStamp = rEvent.CandidateStationsBegin()->GetRecData().GetParameter(eTraceStartTime);
356  // loop through all stations:
357  // shift traces if the time stamp does not match the one of the first station
359  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
360  Station& station = *sIt;
361  double stationTimeStamp = station.GetRecData().GetParameter(eTraceStartTime);
362  cout << station.GetId() << ": \t" << stationTimeStamp << endl;
363  if (stationTimeStamp != firstTimeStamp) {
364  // correct for the difference and set new time stamp
365  for (Station::ChannelIterator cIt = station.ChannelsBegin();
366  cIt != station.ChannelsEnd(); ++cIt) {
367  Channel& channel = *cIt;
368 
369  FFTDataContainerAlgorithm::ShiftTimeSeries(channel.GetFFTDataContainer(), stationTimeStamp-firstTimeStamp);
370  }
371  station.GetRecData().SetParameter(eTraceStartTime,firstTimeStamp);
372  }
373  }
374 }
375 
376 
377 map<int, pair<double, double> >
378 CalcBeaconRefPhase::calculateReferencePhases(std::map<int,std::vector<double> > phaseDifferences)
379 {
380  map<int, pair<double, double> > referencePhases; // map to store results: reference phase and its RMS
381 
382  // loop through all stations
383  for(map<int, vector<double> >::iterator it=phaseDifferences.begin(); it!=phaseDifferences.end(); ++it) {
384  double mean = 0.;
385  double totalShift = 0.;
386  double rms = 0.;
387 
388  // shift all phase differences of each station, until the remaining mean is (almost) 0
389  // the total shift corresponds to the reference phase
390  // Taking directly the mean does not work, because the phase angles could extend over +/- pi.
391  do {
392  double phasesum = 0.;
393  double rmssum = 0.;
394 
395  // shift phases by mean of last iterationstep
396  // loop through all phase differences of the current station
397  for(vector<double>::iterator vpos=it->second.begin(); vpos!=it->second.end(); ++vpos) {
398  *vpos = *vpos - mean;
399  if ( *vpos > kPi ) {
400  *vpos -= kTwoPi;
401  } else if ( *vpos < -kPi ) {
402  *vpos += kTwoPi;
403  }
404  phasesum += *vpos;
405  rmssum += (*vpos * *vpos);
406  }
407  mean = phasesum/double(it->second.size());
408  rms = sqrt(rmssum/double(it->second.size()));
409 
410  totalShift += mean; //store the sum of shifts in the very first element of the vector
411  //cout << "Station " << it->first << " \tReference phase: " << totalShift << " \tRMS: " << rms << " \tMean: " << mean << endl;
412  } while ( abs(mean) >= fConvergenceLimit);
413 
414  // check if final result is inbetween +/- pi
415  while ( totalShift > kPi ) {
416  totalShift -= kTwoPi;
417  }
418  while ( totalShift < -kPi ) {
419  totalShift += kTwoPi;
420  }
421 
422  // store calculated reference phase and its RMS
423  referencePhases[it->first] = pair<double,double>(totalShift, rms);
424  }
425 
426  return referencePhases;
427 }
428 
429 
430 void
431 CalcBeaconRefPhase::writeFileForDatabase(void)
432 {
433  string startDate = "2012-08-15";
434 
435  // Create file name containing frequency
436  stringstream outFilenameStringStream;
437  outFilenameStringStream << fOutputRefPhaseFile << "_ScriptForDatabase";
438  string outFilename(outFilenameStringStream.str());
439 
440  stringstream message;
441  message.str("");
442  message << "\nWriting script for database to file: " << outFilename;
443  INFO(message.str());
444 
445  ofstream outFile;
446  outFile.open(outFilename.c_str());
447 
448  // loop through all station IDs and beacon frequencies
449  for (set<unsigned int>::iterator it = fExistingStationIDs.begin(); it != fExistingStationIDs.end(); ++it) {
450  for (unsigned int nBeaconFreq = 0; nBeaconFreq < fBeaconFrequencies.size(); ++nBeaconFreq) {
451  outFile << "update BeaconRefPhase set Stop='" << startDate << "' where BeaconFreq_id=" << nBeaconFreq+1
452  << " and RStationId=" << *it << " and Stop>'" << startDate << "';" << endl;
453  outFile << "INSERT INTO BeaconRefPhase (BeaconFreq_id, RStationId, RefPhase, Start) VALUES ('"
454  << nBeaconFreq+1 << "', '" << *it << "', '" << fReferencePhases[nBeaconFreq][*it].first
455  << "', '" << startDate << "' );" << endl;
456  }
457  outFile << endl;
458  }
459 
460  outFile.close();
461 }
462 
463 
464 void
465 CalcBeaconRefPhase::writeReferencePhasesFile(void)
466 {
467  // Create file name containing frequency
468  stringstream outFilenameStringStream;
469  outFilenameStringStream << fOutputRefPhaseFile;
470  string outFilename(outFilenameStringStream.str());
471 
472  stringstream message;
473  message.str("");
474  message << "\nWriting reference phases to file: " << outFilename;
475  INFO(message.str());
476 
477  ofstream outFile;
478  outFile.open(outFilename.c_str());
479 
480  // write file header
481  outFile << "Station";
482  for (unsigned int beaconFreqN = 0; beaconFreqN < fBeaconFrequencies.size(); ++beaconFreqN)
483  outFile << " RefPhase[rad]_for_" << fBeaconFrequencies[beaconFreqN]/megahertz << "MHz";
484  outFile << endl;
485 
486  // loop through all station IDs and beacon frequencies
487  for (set<unsigned int>::iterator it = fExistingStationIDs.begin(); it != fExistingStationIDs.end(); ++it) {
488  outFile << *it;
489  for (unsigned int nBeaconFreq = 0; nBeaconFreq < fBeaconFrequencies.size(); ++nBeaconFreq) {
490  outFile << " " << fReferencePhases[nBeaconFreq][*it].first;
491  }
492  outFile << endl;
493  }
494 
495  outFile.close();
496 }
497 
498 }
ChannelFFTDataContainer & GetFFTDataContainer()
retrieve Channel FFTDataContainer (write access)
Branch GetTopBranch() const
Definition: Branch.cc:63
std::vector< std::map< int, std::pair< double, double > > > fReferencePhases
Internal storage of reference phases: VectorCounter:,nBeaconFreq, Key: StationID, Value: RefPhase...
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
std::map< int, int > fEventsPerStation
Number of events read in for each station.
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
int fReferenceStation
ID of reference station.
std::map< int, std::pair< double, double > > calculateReferencePhases(std::map< int, std::vector< double > >)
Method for calculation of reference phase difference and the corresponding RMS for each station...
double GetBinning() const
size of one slot
Definition: Trace.h:138
double fConvergenceLimit
Convergence limit for iterative calculation of reference phases.
#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
ChannelIterator ChannelsBegin()
begin Channel iterator for read/write
bool HasREvent() const
std::string fDBServer
Name of the mysql db server.
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: REvent.h:190
int GetStationId() const
Return Id of the station to which this Channel belongs.
void writeReferencePhasesFile(void)
Write reference phases into ASCII file.
ChannelIterator ChannelsEnd()
end Channel iterator for read/write
void matchStationTimeStamps(revt::REvent &) const
#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.
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
unsigned int fMaxNumberEvents
maximum number of events, after which module sequence is stopped, and reference phases are calculated...
std::set< unsigned int > fExistingStationIDs
Set of all station IDs present in the reference phases.
constexpr double kTwoPi
Definition: MathConstants.h:27
std::map< double,std::map< int,std::vector< double > > > fPhaseDifferences
phase differences: BeaconFreq, Station, vector of individual phase differences (one per event) ...
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.
std::string fOutputRefPhaseFile
Name of file for ASCII output of phases (not needed for normal analysis)
int fReferenceChannel
Reference channel (ususally 1 = NS, high gain)
std::vector< double > fBeaconFrequencies
Vector of frequencies emitted by the beacon.
double GetParameter(const Parameter i) const
Channel & GetChannel(const int pmtId)
Retrieve a Channel by Id.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int fInfoLevel
xml settings: info level (verbosity)
ChannelFrequencySpectrum & GetChannelFrequencySpectrum()
retrieve Channel Frequency Spectrum (write access, only use this if you intend to change the data) ...
unsigned int fEventCounter
Counts &quot;successfull&quot; events usable for reference phases.
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
unsigned int fStationWithZeroPhase
Station which is set to a reference phase of 0 (exploits freedom of global constant) ...
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
void writeFileForDatabase(void)
Write script to transfer reference phases into database.

, generated on Tue Sep 26 2023.