RdTimeCalibration.cc
Go to the documentation of this file.
1 #include "RdTimeCalibration.h"
2 #include <fwk/VModule.h>
3 #include <fwk/CoordinateSystemRegistry.h>
4 #include <fwk/CentralConfig.h>
5 #include <utl/ErrorLogger.h>
6 
7 #include <evt/Event.h>
8 #include <revt/REvent.h>
9 #include <revt/Header.h>
10 #include <revt/Station.h>
11 #include <revt/Channel.h>
12 #include <revt/StationRecData.h>
13 
14 #include <det/Detector.h>
15 #include <rdet/RDetector.h>
16 #include <rdet/Station.h>
17 
18 #include <utl/Trace.h>
19 #include <utl/TraceAlgorithm.h>
20 #include <utl/ErrorLogger.h>
21 #include <utl/Reader.h>
22 #include <utl/config.h>
23 #include <utl/AugerUnits.h>
24 #include <utl/MathConstants.h>
25 #include <utl/PhysicalConstants.h>
26 #include <utl/TimeStamp.h>
27 #include <utl/TimeInterval.h>
28 #include <utl/FFTDataContainerAlgorithm.h>
29 #include <utl/AugerException.h>
30 #include <utl/CoordinateSystem.h>
31 #include <utl/Point.h>
32 #include <utl/Vector.h>
33 //#include <utl/UTCDateTime.h>
34 
35 #include <complex>
36 #include <cmath>
37 #include <string>
38 #include <sstream>
39 #include <iostream>
40 #include <fstream>
41 #include <vector>
42 #include <map>
43 #include <set>
44 #include <fstream>
45 
46 using namespace std;
47 using namespace utl;
48 using namespace fwk;
49 using namespace revt;
50 
51 const double speedOfLight = kSpeedOfLight / 1.00025; // for adjusting refractive index
52 
53 namespace RdTimeCalibration {
54 
56  fInfoLevel(eDebug),
57  //fRunTimeExpectation(map<int, vector<double> >()),
58  //fSourcePosition(vector<double>()),
59  fReferenceAntennaID(145),
60  fReferenceChannel(1),
61  fAdjustTime(false),
62  fFirstRun(true),
63  fZone(19),
64  fBand('H'),
65  fEllipsoidName("WGS84")
66  { }
67 
68 
71  {
72  // Initialize your module here. This method
73  // is called once at the beginning of the run.
74  // The eSuccess flag indicates the method ended
75  // successfully. For other possible return types,
76  // see the VModule documentation.
77 
78  INFO("RdTimeCalibration::Init()");
79 
80  // Read in the configurations of the xml file
81  Branch topBranch =
82  CentralConfig::GetInstance()->GetTopBranch("RdTimeCalibration");
83  topBranch.GetChild("infoLevel").GetData(fInfoLevel);
84  if (fInfoLevel < eNone || fInfoLevel > eDebug) {
85  ERROR("<infoLevel> out of bounds");
86  return eFailure;
87  }
88 
89  topBranch.GetChild("SourcePosition").GetData(fSourcePosition);
90  topBranch.GetChild("ReferenceChannel").GetData(fReferenceChannel);
91  topBranch.GetChild("ReferenceAntennaID").GetData(fReferenceAntennaID);
92  topBranch.GetChild("AdjustTime").GetData(fAdjustTime);
93 
94  //check if the SourcePosition has the right format
95  if (fSourcePosition.size() < 3) {
96  WARNING("Incorrect choice of position: One or more coordinates are missing!");
97  return eBreakLoop;
98  }
99  cout << fSourcePosition[1] << endl;
100 
101  // get reference coordinate system of detector (usually PampaAmarilla)
102  const utl::CoordinateSystemPtr referenceCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
103 
104  const ReferenceEllipsoid::EllipsoidID ellipsoid = ReferenceEllipsoid::GetEllipsoidIDFromString(fEllipsoidName);
105  const Point posSource(fSourcePosition[0], fSourcePosition[1], fSourcePosition[2], referenceCS);
106  const UTMPoint utmPosSource(posSource, ellipsoid);
107  ostringstream message;
108  message << "Position of source in UTM: "
109  "Easting " << utmPosSource.GetEasting() << ", "
110  "Northing " << utmPosSource.GetNorthing() << ", "
111  "Height" << utmPosSource.GetHeight();
112  INFO(message);
113 
114  return eSuccess;
115  }
116 
117 
119  RdTimeCalibration::Run(evt::Event& event)
120  {
121  ofstream ofile;
122  INFO("RdTimeCalibration::Run()");
123  ostringstream message;
124 
125  // Check if there are events at all
126  if (!event.HasREvent()) {
127  WARNING("RdTimeCalibration::No radio event found!");
128  return eContinueLoop;
129  }
130 
131  REvent& rEvent = event.GetREvent();
132 
133  //only take events if RefAnt is in
134  if (!rEvent.HasStation(fReferenceAntennaID)) {
135  WARNING("RdTimeCalibration::Reference Antenne is not in this event!");
136  return eContinueLoop;
137  }
138  //get the detector description
139  det::Detector& det = det::Detector::GetInstance();
140  const rdet::RDetector& radioDet = det.GetRDetector();
141 
142  // get reference coordinate system of detector (usually PampaAmarilla)
143  const CoordinateSystemPtr referenceCS = det.GetReferenceCoordinateSystem();
144 
145  if (fFirstRun) {
146  if (fInfoLevel == eDebug) {
147  INFO("Entering branch for 'first run'.");
148  }
149  //get data of the chosen Reference Antenna
150  const rdet::Station& referenceAntenna = radioDet.GetStation(fReferenceAntennaID);
151  const utl::Point position = referenceAntenna.GetPosition();
152  const Point sourcePosition(fSourcePosition[0], fSourcePosition[1], fSourcePosition[2], referenceCS);
153 
154  const double referenceDelay = (position - sourcePosition).GetMag() / speedOfLight;
155 
156  //calculate the distance, delay and relative delay
157  for (rdet::RDetector::StationIterator rdIt = radioDet.StationsBegin();
158  rdIt != radioDet.StationsEnd(); ++rdIt) {
159 
160  //position of stations
161  const Point position = rdIt->GetPosition();
162 
163  vector<double> distanceDelayRelativeDelay;
164  distanceDelayRelativeDelay.reserve(3);
165  distanceDelayRelativeDelay.push_back((position - sourcePosition).GetMag());
166  distanceDelayRelativeDelay.push_back(distanceDelayRelativeDelay[0] / speedOfLight);
167  distanceDelayRelativeDelay.push_back(distanceDelayRelativeDelay[1] - referenceDelay);
168 
169  fRunTimeExpectation[rdIt->GetId()] = distanceDelayRelativeDelay;
170  }
171  fFirstRun = false;
172  }
173  // match time stamps of stations (if different)
174  // this functionalty should be moved to its own module later
175  MatchStationTimeStamps(rEvent);
176 
177  //cross correlation
178  map<int, double> constTimeOffset;
180  const ChannelTimeSeries& timeSeriesRef = channelRef.GetChannelTimeSeries();
181  const ChannelTimeSeries::SizeType referenceSampleLength = channelRef.GetChannelTimeSeries().GetSize();
182  const double binSize = channelRef.GetChannelTimeSeries().GetBinning();
183 
184  //Begin and End of the Sum for the crosscorrelation
185  const unsigned int sumIndex[2] = { (unsigned int)((0.5 - 0.15)*referenceSampleLength), (unsigned int)((0.5 + 0.15)*referenceSampleLength) };
186 
187  if (fInfoLevel == eDebug) {
188  INFO("Iterating over stations");
189  }
191  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
192  Station& station = *sIt;
193 
194  //building the name for debug output files (file for every Station, name is Station ID)
195  /*string s = boost::lexical_cast<string>(sIt->GetId());
196  ofile.open(s.c_str(), ios::app);
197  */
198 
199  //cout << "Station " << station.GetId() << " channel" << flush;
200 
201  for (Station::ConstChannelIterator cIt = station.ChannelsBegin();
202  cIt != station.ChannelsEnd(); ++cIt) {
203  const Channel& channel = *cIt;
204  if (channel.GetId() != fReferenceChannel)
205  continue;
206 
207  //cout << ' ' << channel.GetId() << endl;
208 
209  const ChannelTimeSeries& timeSeries = channel.GetChannelTimeSeries();
210 
212  /*ofile << "Event-Zeit: " << (UTCDateTime(event.GetHeader().GetTime())).GetInAugerFormat()
213  <<" For Station " << station.GetId()
214  << "(Expected: " << fRunTimeExpectation[station.GetId()][2] << ")";
215  */
216 
217  const int offsetStart = round(fRunTimeExpectation[station.GetId()][2] / binSize) - round(1500. / binSize);
218  const int offsetStop = round(fRunTimeExpectation[station.GetId()][2] / binSize) + round(1500. / binSize);
219  double offsetOfMax = 0;
220  double max = 0;
221 
222  //cout << "offsetStart = " << offsetStart << " \t offsetStop = " << offsetStop << endl;
223  //cout << "Size of timeSeries: " << timeSeries.GetSize() << "\t lowest sample needed = " << offsetStart + sumIndex[0] << "\t highest sample needed = " << offsetStop + sumIndex[1] << endl;
224 
225  if ((offsetStop + sumIndex[1]) >= timeSeries.GetSize()) {
226  station.SetRejected(eBeaconCorrectionFailed);
227  message.str("");
228  message << "Trace of station " << station.GetId() << " has only "
229  << timeSeries.GetSize() << " samples, but a mimimum of "
230  << offsetStop + sumIndex[1] + 1 << " samples required - station rejected!";
231  WARNING(message);
232  continue;
233  }
234 
235  if ((offsetStart < 0) && (std::abs(offsetStart) > sumIndex[0])) {
236  ERROR("Trace to short!");
237  return eBreakLoop;
238  }
239 
240  for (int offset = offsetStart; offset <= offsetStop; ++offset) {
241  double cc = 0;
242  //double refNorm = 0;
243  //double norm = 0;
244  for (unsigned int j = sumIndex[0]; j <= sumIndex[1]; ++j) {
245  cc += timeSeriesRef[j] * timeSeries[std::abs(int(j) + offset)];
246  //only necessary if you want calculate the normalized CC for debugging
247  /*refNorm += pow((channelRef.GetChannelTimeSeries()[j] / (micro*volt/meter)), 2);
248  norm += pow((channel.GetChannelTimeSeries()[j + offset] / (micro*volt/meter)), 2);
249  */
250  }
251 
252  if (cc > max &&
253  offset > offsetStart + round(1100.0 / binSize) &&
254  offset < offsetStop - round(1100.0 / binSize)) {
255  max = cc;
256  //normalized CC for debugging
257  //NCC = CC/sqrt(RefNorm * Norm);
258  offsetOfMax = offset * binSize;
259  //cout << "Set new maximum for offset * binSize = " << offset << " * " << binSize << endl;
260  }
261  }
262  //uncomment this for debugging output
263  /*ofile << OffsetOfMax << " " << NCC << " "
264  << OffsetOfMax - fRunTimeExpectation[sIt->GetId()][2] << endl << endl;
265  */
266  constTimeOffset[station.GetId()] = offsetOfMax - fRunTimeExpectation[sIt->GetId()][2];
267  //cout << "Calculation for station " << station.GetId() << " (offsetOfMax - fRunTimeExpectation[sIt->GetId()][2] = constTimeOffset): "
268  // << offsetOfMax << " - " << fRunTimeExpectation[sIt->GetId()][2] << " = " << constTimeOffset[station.GetId()] << endl;
269  //ofile.close();
270  }
271  }
272 
273  //shift the start time of station by the constant Offset
274  if (fAdjustTime) {
275  //move to a own function?
277  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
278  Station& station = *sIt;
279  station.GetRecData().SetParameter(
280  eTraceStartTime,
281  station.GetRecData().GetParameter(eTraceStartTime) - constTimeOffset[station.GetId()]
282  );
283 
284  message.str("");
285  message << "Shifted trace start time of Station " << station.GetId() << " by "
286  << constTimeOffset[station.GetId()] << " ns";
287  INFO(message);
288  }
289  }
290 
291  return eSuccess;
292  }
293 
294 
296  RdTimeCalibration::Finish()
297  {
298  // Put any termination or cleanup code here.
299  // This method is called once at the end of the run.
300 
301  INFO("RdTimeCalibration::Finish()");
302 
303  return eSuccess;
304  }
305 
306 
307  void
308  RdTimeCalibration::MatchStationTimeStamps(revt::REvent& rEvent)
309  const
310  {
311  if (fInfoLevel == eDebug) {
312  INFO("Matching station time stamps");
313  }
314  // store time stamp of the first station as reference
315  const double firstTimeStamp = rEvent.CandidateStationsBegin()->GetRecData().GetParameter(eTraceStartTime);
316  // loop through all stations:
317  // shift traces if the time stamp does not match the one of the first station
319  sIt != rEvent.CandidateStationsEnd(); ++sIt) {
320  Station& station = *sIt;
321  const double stationTimeStamp = station.GetRecData().GetParameter(eTraceStartTime);
322 
323  if (stationTimeStamp != firstTimeStamp) {
324  // correct for the difference and set new time stamp
325  for (Station::ChannelIterator cIt = station.ChannelsBegin();
326  cIt != station.ChannelsEnd(); ++cIt) {
327  Channel& channel = *cIt;
328 
329  FFTDataContainerAlgorithm::ShiftTimeSeries(channel.GetFFTDataContainer(), stationTimeStamp-firstTimeStamp);
330  //cout << "RdTimeCalibration: Station " << channel.GetStationId() << " channel " << channel.GetId() << " shifted by " << stationTimeStamp-firstTimeStamp << "ns." << endl;
331  }
332  station.GetRecData().SetParameter(eTraceStartTime, firstTimeStamp);
333  }
334  }
335  }
336 
337 }
ChannelFFTDataContainer & GetFFTDataContainer()
retrieve Channel FFTDataContainer (write access)
Branch GetTopBranch() const
Definition: Branch.cc:63
boost::transform_iterator< InternalStationFunctor, InternalStationIterator, const Station & > StationIterator
StationIterator returns a pointer to a station.
Definition: RDetector.h:61
Point object.
Definition: Point.h:32
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
Detector description interface for Station-related data.
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
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
Definition: RDetector.h:68
Skip remaining modules in the current loop and continue with next iteration of the loop...
Definition: VModule.h:68
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
Definition: RDetector.h:64
double GetBinning() const
size of one slot
Definition: Trace.h:138
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
const double speedOfLight
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
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: REvent.h:190
double GetNorthing() const
Get the northing.
Definition: UTMPoint.h:206
ChannelTimeSeries & GetChannelTimeSeries()
retrieve Channel Time Series (write access, only use this if you intend to change the data) ...
ChannelIterator ChannelsEnd()
end Channel iterator for read/write
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
void MatchStationTimeStamps(revt::REvent &) const
int fReferenceChannel
Reference channel (ususally 1 = NS, high gain)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#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.
double GetHeight() const
Get the height.
Definition: UTMPoint.h:212
std::vector< double >::size_type SizeType
Definition: Trace.h:58
double abs(const SVector< n, T > &v)
bool fFirstRun
flag, that the expectation is calculated just once
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
std::map< int, std::vector< double > > fRunTimeExpectation
map of the expected runtime
double GetEasting() const
Get the easting.
Definition: UTMPoint.h:209
CandidateStationIterator CandidateStationsBegin()
Definition: REvent.h:144
int fReferenceAntennaID
Reference Antenna (ususally 113)
bool fAdjustTime
adjust time yes or no (usually no = 0)
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
Channel & GetChannel(const int pmtId)
Retrieve a Channel by Id.
constexpr double kSpeedOfLight
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
std::vector< double > fSourcePosition
Postion of the calibration source.
utl::CoordinateSystemPtr GetReferenceCoordinateSystem() const
Get the reference coordinate system used for analysis (usually PampaAmarilla for Auger) ...
Definition: Detector.h:141
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
const rdet::RDetector & GetRDetector() const
Definition: Detector.cc:143
bool HasStation(const int stationId) const
Check whether station exists.
Definition: REvent.cc:132
EllipsoidID
ID&#39;s of known reference ellipsoid&#39;s.
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
int fInfoLevel
xml settings: info level (verbosity)
#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

, generated on Tue Sep 26 2023.