2 #include <fwk/CentralConfig.h>
3 #include <fwk/VModule.h>
5 #include <rdet/RDetector.h>
6 #include <rdet/Station.h>
7 #include <utl/CoordinateSystem.h>
9 #include <evt/RadioSimulation.h>
10 #include <utl/TimeStamp.h>
11 #include <utl/TimeInterval.h>
12 #include <utl/UTCDateTime.h>
13 #include <utl/Trace.h>
14 #include <utl/AugerUnits.h>
15 #include <evt/Event.h>
16 #include <evt/ShowerSimData.h>
17 #include <revt/REvent.h>
18 #include <revt/EventTrigger.h>
19 #include <revt/Station.h>
20 #include <revt/Header.h>
21 #include <revt/StationTriggerData.h>
22 #include <revt/StationSimData.h>
23 #include <utl/StringCompare.h>
27 #include <utl/FFTDataContainer.h>
29 #include <evt/SimRadioPulse.h>
30 #include <utl/MathConstants.h>
37 #include <boost/utility.hpp>
39 #include <boost/algorithm/string.hpp>
41 #include <rdet/Channel.h>
51 #define OUT(x) if ((x) <= fInfoLevel) cerr << " "
56 typedef multimap<double, const SimRadioPulse&>
PulseMMap;
57 typedef pair<double, const SimRadioPulse&>
PulsePair;
61 fMaximumDistance(5.*
meter),
64 fEventRate(0.0001*
hertz),
65 fEventTimeOffset(0.0),
66 fUseRateTiming(false),
73 RdStationInterpolator::~RdStationInterpolator()
80 OUT(
eFinal) <<
"RdStationInterpolator::Init()" << endl;
82 Branch topBranch = CentralConfig::GetInstance()->
GetTopBranch(
"RdStationInterpolator");
96 info <<
"\n Ignoring event times provided by simulations! Using rate timing instead.\n"
100 info <<
"\n Padding time series data at front by "
102 <<
" ns and at end to a total length of at least "
116 INFO(
"I am a deprecated module. Please update me!");
123 Detector& Det = Detector::GetInstance();
132 WARNING(
"RdStationInterpolator: Event time of RadioSimulation is not available. Aborting ...");
145 WARNING(
"RdStationInterpolator: No SimRadioPulse in RadioSimulation. Aborting ...");
173 mm_simpulse_x.insert(
PulsePair(xcoord,srpulse));
174 double ycoord = (srpulse.
GetLocation()).GetY(corsys);
175 mm_simpulse_y.insert(
PulsePair(ycoord,srpulse));
178 vector<double> sPosition(3, 0.);
179 vector<double> distanceBetweenSimloc(3, 0.);
180 vector<double> distanceToStation(3, 0.);
181 vector<revt::StationFFTDataContainer> v_simFFTDataContainer(3);
182 vector<double> starttime(3, 0.);
183 vector<double> binning(3, 0.);
184 vector<double> areaWeight(4, 0.);
188 const int statID = rdIt->GetId();
194 OUT(
eObscure) <<
" -> not interpolated as it is in the exclude list." << endl;
201 OUT(
eObscure) <<
" -> station not interpolated as it is not in the include list." << endl;
208 if (mm_pulse.empty())
211 PulseMMap::const_iterator mmpiter = mm_pulse.begin();
214 areaWeight[1] = mmpiter->first;
216 starttime[0] = mmpiter->second.GetStartTime();
217 binning[0] = mmpiter->second.GetEfieldTimeSeries().GetBinning();
219 v_simFFTDataContainer[0].GetTimeSeries() =
PadTimeSeries(mmpiter->second);
223 areaWeight[2] = mmpiter->first;
224 starttime[1] = mmpiter->second.GetStartTime();
225 binning[1] = mmpiter->second.GetEfieldTimeSeries().GetBinning();
226 v_simFFTDataContainer[1].GetTimeSeries() =
PadTimeSeries(mmpiter->second);
230 areaWeight[3] = mmpiter->first;
231 starttime[2] = mmpiter->second.GetStartTime();
232 binning[2] = mmpiter->second.GetEfieldTimeSeries().GetBinning();
233 v_simFFTDataContainer[2].GetTimeSeries() =
PadTimeSeries(mmpiter->second);
235 areaWeight[0] = areaWeight[1] + areaWeight[2] + areaWeight[3];
238 if ((fabs(binning[0] - binning[1])/binning[0]) > 1e-5 || (fabs(binning[0] - binning[2])/binning[0]) > 1e-5) {
239 WARNING(
"RdStationInterpolator: simtimeseries don't have the same binning. Aborting ...");
244 double designLowerFreq = 0;
245 double designLowerFreqFirstCh = 0;
246 double designUpperFreq = 0;
247 double designUpperFreqFirstCh = 0;
252 if (cIt == rdIt->ChannelsBegin()) {
253 designLowerFreqFirstCh = designLowerFreq;
254 designUpperFreqFirstCh = designUpperFreq;
256 if (designLowerFreq != designLowerFreqFirstCh || designUpperFreq != designUpperFreqFirstCh) {
257 WARNING(
"RdStationInterpolator: design frequency different for different channels");
264 for (
unsigned int i = 0; i <= v_simFFTDataContainer.size(); ++i) {
265 if (v_simFFTDataContainer[i].GetNyquistZone() != 1) {
266 WARNING(
"RdStationInterpolator: simtimeseries not in first Nyquist zone.");
271 if (v_simFFTDataContainer[0].GetConstFrequencySpectrum().GetSize() != v_simFFTDataContainer[1].GetConstFrequencySpectrum().GetSize() ||
272 v_simFFTDataContainer[0].GetConstFrequencySpectrum().GetSize() != v_simFFTDataContainer[2].GetConstFrequencySpectrum().GetSize()) {
273 WARNING(
"RdStationInterpolator: simtimeseries don't have the same length.");
292 if (StatTimeSeries.
GetSize()) {
293 WARNING(
"RDStationInterpolator: StatTimeSeries not empty!" );
294 StatTimeSeries.ClearTrace();
316 RdStationInterpolator::Finish()
332 PulseMMap::const_iterator iterx = mm_srpulse_x.lower_bound(pt.
GetX(coord));
335 if (iterx == mm_srpulse_x.end() || iterx == mm_srpulse_x.begin()) {
343 if (m_surroundingsrpulse.empty()) {
345 PulseMMap::const_iterator itery = mm_srpulse_y.lower_bound(pt.
GetY(coord));
347 if (itery == mm_srpulse_y.end() || itery == mm_srpulse_y.begin()) {
353 if (m_surroundingsrpulse.empty()) {
359 vector<utl::Point> simloc_triangle;
360 vector<double> areaWeight;
363 bool surrTrianglefound =
false;
364 PulseMMap::iterator it = m_surroundingsrpulse.begin();
365 for (
unsigned int i = 0; i < 2; ++i, ++it) {
367 for (
unsigned int j = i + 1; j < 3; ++j, ++secIt) {
368 unsigned int k = j + 1;
369 for (PulseMMap::iterator thirdIt =
boost::next(secIt); thirdIt != m_surroundingsrpulse.end(); ++thirdIt, ++k) {
370 simloc_triangle.clear();
371 simloc_triangle.push_back(it->second.GetLocation());
372 simloc_triangle.push_back(secIt->second.GetLocation());
373 simloc_triangle.push_back(thirdIt->second.GetLocation());
376 if (fabs(areaWeight[1] + areaWeight[2] + areaWeight[3] - areaWeight[0]) >= 1e-5)
378 if (surrTrianglefound && minarea <= areaWeight[0])
380 minarea = areaWeight[0];
383 mm_triangle.insert(
PulsePair(areaWeight[2], it->second));
384 mm_triangle.insert(
PulsePair(areaWeight[3], secIt->second));
385 mm_triangle.insert(
PulsePair(areaWeight[1], thirdIt->second));
386 surrTrianglefound =
true;
402 PulseMMap::const_iterator itera = inverse ?
403 mm_simradiopulse.lower_bound(pt.
GetY(coord)) :
404 mm_simradiopulse.lower_bound(pt.
GetX(coord));
407 const double uppera = itera->first;
409 const double lowera = itera->first;
412 typedef PulseMMap::const_iterator PulseIterator;
413 typedef pair<PulseIterator, PulseIterator> PulseIteratorPair;
414 PulseIteratorPair upperb_range = mm_simradiopulse.equal_range(uppera);
415 PulseIteratorPair lowerb_range = mm_simradiopulse.equal_range(lowera);
419 for (PulseIterator upperb_iter = upperb_range.first;
420 upperb_iter != upperb_range.second; ++upperb_iter) {
421 const double b = inverse ?
422 upperb_iter->second.GetLocation().GetX(coord) :
423 upperb_iter->second.GetLocation().GetY(coord);
424 m_upperb.insert(
PulsePair(b, upperb_iter->second));
427 for (PulseIterator lowerb_iter = lowerb_range.first;
428 lowerb_iter != lowerb_range.second; ++lowerb_iter) {
429 const double b = inverse ?
430 lowerb_iter->second.GetLocation().GetX(coord) :
431 lowerb_iter->second.GetLocation().GetY(coord);
432 m_lowerb.insert(
PulsePair(b, lowerb_iter->second));
440 itu_b = m_upperb.lower_bound(pt.
GetY(coord));
441 itl_b = m_lowerb.lower_bound(pt.
GetY(coord));
443 itu_b = m_upperb.lower_bound(pt.
GetX(coord));
444 itl_b = m_lowerb.lower_bound(pt.
GetX(coord));
447 if (itu_b == m_upperb.end() || itu_b == m_upperb.begin() || itl_b == m_lowerb.end() || itl_b == m_lowerb.begin()) {
448 return m_surroundingsrpulse;
451 m_surroundingsrpulse.insert(
PulsePair(itu_b->first, itu_b->second));
452 m_surroundingsrpulse.insert(
PulsePair(itl_b->first, itl_b->second));
455 m_surroundingsrpulse.insert(
PulsePair(itu_b->first, itu_b->second));
456 m_surroundingsrpulse.insert(
PulsePair(itl_b->first, itl_b->second));
458 return m_surroundingsrpulse;
469 vector<double> distStation;
470 for (
int i = 0; i < 3; ++i) {
471 double distx = stationpos.
GetX(coord) - v_simloc[i].GetX(coord);
472 double disty = stationpos.
GetY(coord) - v_simloc[i].GetY(coord);
473 distStation.push_back(
sqrt(
pow(distx, 2) +
pow(disty, 2)));
477 vector<double> distSim;
478 distSim.push_back((v_simloc[1] - v_simloc[0]).GetR(coord));
479 distSim.push_back((v_simloc[2] - v_simloc[1]).GetR(coord));
480 distSim.push_back((v_simloc[0] - v_simloc[2]).GetR(coord));
486 s.push_back((distSim[0] + distSim[1] + distSim[2])/2);
487 area.push_back(
sqrt(s[0] * (s[0] - distSim[0])*(s[0] - distSim[1])*(s[0] - distSim[2])));
488 s.push_back((distSim[0] + distStation[0] + distStation[1])/2);
489 area.push_back(
sqrt(s[1] * (s[1] - distSim[0])*(s[1] - distStation[0])*(s[1] - distStation[1])));
490 s.push_back((distSim[1] + distStation[1] + distStation[2])/2);
491 area.push_back(
sqrt(s[2] * (s[2] - distSim[1])*(s[2] - distStation[1])*(s[2] - distStation[2])));
492 s.push_back((distSim[2] + distStation[2] + distStation[0])/2);
493 area.push_back(
sqrt(s[3] * (s[3] - distSim[2])*(s[3] - distStation[2])*(s[3] - distStation[0])));
508 V3DZero = 0.0, 0.0, 0.0;
510 double padbinning = simtimeseries.
GetBinning();
515 for (
long i = 0; i < numpaddedsamples; ++i)
530 return PaddedTimeSeries;
537 RdStationInterpolator::InterpolateInTwoD(
const std::vector<revt::StationFFTDataContainer>& simData,
538 const std::vector<double>& area,
const double designlowerfreq,
const double designupperfreq)
541 const double specbinningOne = simData[0].GetConstFrequencySpectrum().GetBinning();
561 jumps1 = 0.0, 0.0, 0.0;
563 jumps2 = 0.0, 0.0, 0.0;
565 jumps3 = 0.0, 0.0, 0.0;
568 for(
unsigned int j = 0; j < 3; ++j) {
569 if (i >= designlowerfreq/specbinningOne && i <= designupperfreq/specbinningOne) {
571 double interamplitude = (
abs(freq1[i][j])*area[1] +
abs(freq2[i][j])*area[2] +
abs(freq3[i][j])*area[3])/area[0];
576 if (arg(freq1[i][j]) < arg(freq1[i-1][j]) && jumps1[j] >= 0) {
577 if (fabs(arg(freq1[i][j])-arg(freq1[i-1][j])) > fabs(arg(freq1[i][j]) +
utl::kPi - arg(freq1[i-1][j]))) {
581 if (fabs(arg(freq1[i][j])-arg(freq1[i-1][j])) > fabs(arg(freq1[i][j]) -
utl::kPi - arg(freq1[i-1][j]))) {
586 if (arg(freq2[i][j]) < arg(freq2[i-1][j]) && jumps2[j] >= 0) {
587 if (fabs(arg(freq2[i][j]) - arg(freq2[i-1][j])) > fabs(arg(freq2[i][j]) +
utl::kPi - arg(freq2[i-1][j]))) {
591 if (fabs(arg(freq2[i][j]) - arg(freq2[i-1][j])) > fabs(arg(freq2[i][j]) -
utl::kPi - arg(freq2[i-1][j]))) {
596 if (arg(freq3[i][j]) < arg(freq3[i-1][j]) && jumps3[j] >= 0) {
597 if (fabs(arg(freq3[i][j]) - arg(freq3[i-1][j])) > fabs(arg(freq3[i][j]) +
utl::kPi - arg(freq3[i-1][j]))) {
601 if (fabs(arg(freq3[i][j]) - arg(freq3[i-1][j])) > fabs(arg(freq3[i][j]) -
utl::kPi - arg(freq3[i-1][j]))) {
608 phaseElementOne[j] = arg(freq1[i][j]) + jumps1[j]*2*
utl::kPi;
609 phaseElementTwo[j] = arg(freq2[i][j]) + jumps2[j]*2*
utl::kPi;
610 phaseElementThree[j] = arg(freq3[i][j]) + jumps3[j]*2*
utl::kPi;
613 phaseElementInter[j] = (phaseElementOne[j]*area[1] + phaseElementTwo[j]*area[2] + phaseElementThree[j]*area[3])/area[0];
616 element[j] = polar(interamplitude, phaseElementInter[j]);
629 return interpolatedFFTDataContainer;
Branch GetTopBranch() const
boost::transform_iterator< InternalStationFunctor, InternalStationIterator, const Station & > StationIterator
StationIterator returns a pointer to a station.
void Update(const utl::TimeStamp &time, const bool invData=true, const bool invComp=true, const bool forceRadio=false)
Update detector: deletes currently constructed stations and sets new time.
double GetBinning() const
Get the sampling time scale.
Report success to RunController.
double GetDesignUpperFreq() const
Get design value of the freq-band.
int GetEventNumber() const
Get the event number of the RadioSimulation.
Interface class to access to the Radio part of an event.
void BuildSimShower(evt::ShowerSimData &theshower, const utl::CoordinateSystemPtr &coord)
BuildSimShower---------------------------------------------------------------------------------------...
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
void MakeSimData()
Make station simulated data object.
double fMinimumTraceLength
Data structure for simulated Radio pulses.
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
double GetDesignLowerFreq() const
Get design value of the freq-band.
EventTrigger & GetTrigger()
Get the object with central trigger data, throw if n.a.
Data structure for a radio simulation (including several SimRadioPulses)
#define INFO(message)
Macro for logging informational messages.
utl::Point GetLocation() const
void Init()
Initialise the registry.
revt::REvent & GetREvent()
Detector description interface for Channel-related data.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
revt::StationFFTDataContainer InterpolateInTwoD(const std::vector< revt::StationFFTDataContainer > &simData, const std::vector< double > &area, const double designLowerFreq, const double designUpperFreq) const
interpolation between closest pulses -> station signal
double pow(const double x, const unsigned int i)
double fTracePaddingAtFront
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
StationTimeSeries & GetStationTimeSeries()
retrieve Station Time Series (write access, only use this if you intend to change the data) ...
bool StringEquivalent(const std::string &a, const std::string &b, Predicate p)
Utility to compare strings for equivalence. It takes a predicate to determine the equivalence of indi...
std::vector< T >::const_iterator ConstIterator
A TimeStamp holds GPS second and nanosecond for some event.
bool HasPosition() const
Check initialization of shower geometry.
Detector description interface for RDetector-related data.
void MakeGPSData()
Make GPS data object.
void MakeTriggerData()
Make trigger data object.
void SetExternalTrigger(const bool trig)
Set if Event was externally triggered.
Interface class to access Shower Simulated parameters.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Iterator next(Iterator it)
Class representing a document branch.
class to hold data at the radio Station level.
utl::TimeStamp fFirstEventTime
void SetRawTraceStartTime(const utl::TimeStamp &time)
Set absolute start time of the station-level trace as originally provided in raw data, for reconstructions use eTraceStartTime in StationRecData!
C< F > & GetFrequencySpectrum()
read out the frequency spectrum (write access)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
std::vector< T >::size_type SizeType
void MakeTrigger()
Create the central trigger object.
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
constexpr double nanosecond
double abs(const SVector< n, T > &v)
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
get local coordinate system anchored at the core position
Header & GetHeader()
access to REvent Header
Top of the hierarchy of the detector description interface.
std::vector< double > GetAreaOfTriangles(const utl::Point &stationpos, const std::vector< utl::Point > &v_simloc, const utl::CoordinateSystemPtr &coord) const
weight of the simradiopulses in for interpolation
ShowerSimData & GetSimShower()
pair< double, const SimRadioPulse & > PulsePair
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
boost::indirect_iterator< InternalChannelIterator, const Channel & > ChannelIterator
ChannelIterator returns a pointer to a Channel.
PulseMMap FindSurroundingNN(const PulseMMap &mm_simradiopulse, const utl::Point &pt, const utl::CoordinateSystemPtr &coord, const bool inverse) const
find the surrounding four nearest neighbors
void SetBinning(const double binning)
const SimRadioPulse & GetNextSimRadioPulse(bool &ok)
const utl::TimeStamp & GetEventTime() const
Get the event time of the RadioSimulation.
utl::TimeInterval fEventTimeOffset
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Template class for a data container that offers and takes both time series and corresponding frequenc...
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
bool GoToFirstSimRadioPulse()
Jump to the first SimRadioPulse, returns false if the vector is empty.
std::vector< int > fExcludedStationIds
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
PulseMMap FindClosestSimPulsesToStation(const utl::Point &pt, const utl::CoordinateSystemPtr &coord, const PulseMMap &mm_srpulse_x, const PulseMMap &mm_srpulse_y) const
find distances of SimPulses to station
void MakeGeometry(const utl::Point &pointOnShowerAxis)
initialize the shower geometry. Pos is a point on the shower axis, but not necessarily the core ...
std::multimap< double, const evt::SimRadioPulse & > PulseMMap
Report failure to RunController, causing RunController to terminate execution.
void MakeTimeStamp(const utl::TimeStamp &ts)
Make the TimeStamp of the shower.
int GetRunNumber() const
Get the run number of the RadioSimulation.
const rdet::RDetector & GetRDetector() const
void PushBack(const T &value)
Insert a single value at the end.
const Station & GetStation(const int stationId) const
Get station by Station Id.
multimap< double, const SimRadioPulse & > PulseMMap
std::vector< int > fIncludedStationIds
const utl::TraceV3D & GetEfieldTimeSeries() const
Get the Trace of the simulated electric field.
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
revt::StationTimeSeries PadTimeSeries(const evt::SimRadioPulse &simtimeseries) const
padding of zeros to the end of the simtimeseries