3 #include <fwk/CentralConfig.h>
5 #include <utl/AugerUnits.h>
6 #include <utl/CoordinateSystem.h>
8 #include <utl/PhysicalConstants.h>
10 #include <utl/RadioGeometryUtilities.h>
11 #include <utl/ReferenceEllipsoid.h>
12 #include <utl/TimeStamp.h>
13 #include <utl/TimeInterval.h>
14 #include <utl/Trace.h>
15 #include <utl/UTMPoint.h>
16 #include <utl/TraceAlgorithm.h>
18 #include <rdet/RDetector.h>
19 #include <rdet/Station.h>
20 #include <rdet/Channel.h>
21 #include <rdet/RStationListManager.h>
22 #include <rdet/RSimulationStationListManager.h>
24 #include <evt/RadioSimulation.h>
25 #include <evt/Event.h>
26 #include <evt/ShowerSimData.h>
28 #include <revt/REvent.h>
29 #include <revt/EventTrigger.h>
30 #include <revt/Station.h>
31 #include <revt/Header.h>
32 #include <revt/StationTriggerData.h>
33 #include <revt/StationSimData.h>
35 #include <sevt/SEvent.h>
36 #include <sevt/StationTriggerData.h>
55 topBranch.
GetChild(
"ExtrapolateTheTailOfThePulses").
GetData(fExtrapolateTheTailOfThePulses);
57 topBranch.
GetChild(
"TracePaddingAtFront").
GetData(fTracePaddingAtFront);
61 topBranch.
GetChild(
"AddNoSignalStations").
GetData(fAddNoSignalStations);
62 topBranch.
GetChild(
"AddEmptyTriggeredRDStations").
GetData(fAddEmptyTriggeredRDStations);
63 topBranch.
GetChild(
"MaximumDistanceOfNoSignalStations").
GetData(fMaximumDistanceOfNoSignalStations);
64 topBranch.
GetChild(
"CreateAllSDStationsWithRDTrace").
GetData(fCreateAllSDStationsWithRDTrace);
67 info <<
"\n\tMaximum allowed distance "<< fMaximumDistance/
meter <<
" m\n"
68 <<
"\tAdding time series data at front by " << fTracePaddingAtFront /
nanosecond
69 <<
" ns and at end to a total length of at least " << fMinimumTraceLength /
nanosecond <<
" ns.\n"
70 <<
"\tAdd virtual stations: " << fAddVirtualStations <<
"(" << fFirstStationId <<
")\n";
72 if (fAddNoSignalStations) {
73 if (fAddEmptyTriggeredRDStations)
74 info <<
"\tAdd empty traces for triggered but not simulated RD stations\n";
76 info <<
"\tAdd empty traces for all stations within " << fMaximumDistanceOfNoSignalStations /
utl::km
77 <<
" km around the shower axis.\n";
87 RdStationAssociator::Run(
Event& theevent)
91 if (fAddEmptyTriggeredRDStations && !theevent.
HasSEvent()) {
92 ERROR(
"SEvent not available but required!");
99 auto pulsecorsys = rsim.GetLocalCoordinateSystem();
101 const auto& eventtime = simshow.GetTimeStamp();
102 const auto& det = Detector::GetInstance();
103 const auto& radioDet = det.GetRDetector();
106 if (fAddVirtualStations) {
107 RdStationAssociator::AddVirtualStations(theevent, pulsecorsys);
112 WARNING(
"RdStationAssociator: Event time is not available. Event is skipped!");
113 return eContinueLoop;
121 if (!rsim.GoToFirstSimRadioPulse()) {
122 WARNING(
"RdStationAssociator: No SimRadioPulse in RadioSimulation. Event is skipped!");
123 return eContinueLoop;
137 if (fInfoLevel >= eInfoDebug) {
139 for (
const auto& detStation : radioDet.StationsRange()) {
140 auto position = detStation.GetPosition();
141 out <<
"Station " << detStation.GetId() <<
": " << position.GetX(corsys) <<
", "
142 << position.GetY(corsys) <<
", " << position.GetZ(corsys) << endl;
150 const SimRadioPulse& srpulse = rsim.GetNextSimRadioPulse(ok);
160 const int statID = FindClosestStationFromPoint(loc, radioDet, 1);
164 out <<
"associated station " << statID <<
" ("
165 << (radioDet.GetStation(statID).GetPosition() - loc).GetMag() /
meter <<
" m)";
169 out <<
"Did not find any station at position ("
170 << loc.
GetX(corsys) <<
", " << loc.
GetY(corsys) <<
", " << loc.
GetZ(corsys) <<
")";
179 if (!fExcludedStationIds.empty())
180 if (find(fExcludedStationIds.begin(), fExcludedStationIds.end(), statID) != fExcludedStationIds.end()) {
182 out <<
"Station " << statID <<
" not associated as it is in the exclude list.";
188 if (!fIncludedStationIds.empty()) {
189 if (find(fIncludedStationIds.begin(), fIncludedStationIds.end(), statID) == fIncludedStationIds.end()) {
191 out <<
"Station " << statID <<
" not associated as it is not in the include list.";
200 const auto& station = radioDet.GetStation(statID);
201 const unsigned int numberOfValidConfiguredChannel = count_if(station.ChannelsBegin(), station.ChannelsEnd(),
202 [&](
auto const& channel) {
return channel.GetChannelType() ==
"AntennaHighGain"; }
205 if (numberOfValidConfiguredChannel < 2) {
207 out <<
"Station " << statID <<
" is not associated with a pulse as"
208 <<
" its description is incomplete! (Does not has two channel with type: \"AntennaHighGain\"";
215 if (fCreateAllSDStationsWithRDTrace) {
216 const int sStID = statID - radioDet.GetRdSdStationIdLink();
231 stat.MakeTriggerData();
237 auto& statTimeSeries = stat.GetStationTimeSeries();
240 stat.GetSimData().SetSimulatedTrace(simtimeseries);
244 v3DZero = 0.0, 0.0, 0.0;
246 const double binning = simtimeseries.GetBinning();
247 statTimeSeries.SetBinning(binning);
248 long numpaddedsamples =
static_cast<long>(fTracePaddingAtFront / binning + 0.5);
255 for (
long i = 0; i < numpaddedsamples; ++i)
256 statTimeSeries.PushBack(v3DZero);
259 out <<
"sim time series has size " << simtimeseries.
GetSize();
263 for (
const auto& el : simtimeseries)
264 statTimeSeries.PushBack(el);
270 if (fExtrapolateTheTailOfThePulses) {
271 unsigned int fitRangeStart = statTimeSeries.GetSize() - int((50 *
utl::ns) / binning);
273 vector<double> vPowerOrig{0, 0, 0};
274 vector<vector<double>> extraPulse;
276 for (
unsigned int pol = 0; pol < 3; pol++) {
277 vector<pair<double, double>> fitData;
279 for (
unsigned int sample = 0; sample < statTimeSeries.GetSize(); ++sample) {
280 vPowerOrig.at(pol) +=
Sqr(statTimeSeries[sample][pol]);
281 if (sample >= fitRangeStart)
282 fitData.emplace_back(sample * binning, move(statTimeSeries[sample][pol]));
286 vector<utl::Minou::ParameterDef> parameters;
288 parameters.emplace_back(
"a", fitData[0].
second, 1e-6, -1, 1,
false);
289 parameters.emplace_back(
"b", -5e-3, 1e-3, -1, -1e-3,
false);
292 eT.
Setx0(fitRangeStart * binning);
297 const auto result = min.GetParameters();
298 if (
result.at(1) >= -1.00001e-3)
299 ERROR(
"Extrapolating the radio pulse, slope at bondary");
301 vector<double> extraPulsePol;
302 for (
int sample = 0; sample < int(2000 *
utl::ns / binning); ++sample) {
303 double time = (statTimeSeries.GetSize() + sample) * binning;
304 extraPulsePol.push_back(eT.
GetY(time,
result));
306 extraPulse.push_back(extraPulsePol);
310 for (
int sample = 0; sample < int(2000 *
utl::ns / binning); ++sample) {
311 v3D = extraPulse.at(0).at(sample), extraPulse.at(1).at(sample), extraPulse.at(2).at(sample);
312 statTimeSeries.PushBack(v3D);
315 for (
unsigned int pol = 0; pol < 3; pol++) {
317 for (
const auto& el : statTimeSeries)
318 powerExt +=
Sqr(el[pol]);
320 if ((fabs(powerExt / vPowerOrig.at(pol) - 1) > 0.1) &&
323 out <<
"Due to the extrapolation of the pulse tail, the power (i.e., sum over squared amplitudes) "
324 <<
"changed by more than 10%. Please be cautious. Station: "
325 << statID <<
", Polarisation: " << pol <<
": (extrapolated/original) "
326 << powerExt <<
" / " << vPowerOrig.at(pol) <<
" = " << powerExt / vPowerOrig.at(pol);
335 statTimeSeriesMag.
SetBinning(statTimeSeries.GetBinning());
336 for (
const auto& el : statTimeSeries)
337 statTimeSeriesMag.
PushBack(el.GetMag());
339 const double noiseRMS = TraceAlgorithm::RootMeanSquare(statTimeSeriesMag,
344 <<
" muV/m in the last 20ns of the simulated pulse. "
345 <<
"Such a cutoff might introduces a second pulse. "
346 <<
"Condider using fExtrapolateTheTailOfThePulses";
351 out <<
"station time series has size " << statTimeSeries.GetSize();
355 while ((fMinimumTraceLength - statTimeSeries.GetSize() * binning) > 1e-6)
356 statTimeSeries.PushBack(v3DZero);
360 if (statTimeSeries.GetSize() % 2 == 1)
361 statTimeSeries.PushBack(v3DZero);
367 if (fAddNoSignalStations) {
368 unsigned numberOfEmptyButTriggeredRDStations = 0;
370 for (
const auto& station : radioDet.StationsRange()) {
371 const unsigned int rdId = station.GetId();
373 if (!fExcludedStationIds.empty()) {
374 if (find(fExcludedStationIds.begin(), fExcludedStationIds.end(), station.GetId()) != fExcludedStationIds.end())
379 utl::Point positionStat = station.GetPosition();
381 const Point& mcCore = simshow.GetPosition();
383 const double dist = RadioGeometryUtilities::GetDistanceToAxis(
384 mcAxis, mcCore, positionStat);
386 if (fAddEmptyTriggeredRDStations) {
387 const int sStID = rdId - radioDet.GetRdSdStationIdLink();
394 if (!trig.IsT2() && !trig.IsT1())
399 numberOfEmptyButTriggeredRDStations++;
402 if (dist > fMaximumDistanceOfNoSignalStations)
418 v3DZero = 0.0, 0.0, 0.0;
421 const double binning = 1 *
utl::ns;
422 statTimeSeries.SetBinning(binning);
425 out <<
"adding zero trace to station " << rdId;
428 for(
unsigned int i=0; i < (fMinimumTraceLength / binning); ++i) {
429 statTimeSeries.PushBack(v3DZero);
434 if (statTimeSeries.GetSize() % 2 == 1) {
435 statTimeSeries.PushBack(v3DZero);
443 const Vector VecDistanceToSdCore = positionStat - mcCore;
446 const double projVec = -mcAxis.
GetX(coreCS) * VecDistanceToSdCore.
GetX(coreCS)
447 - mcAxis.
GetY(coreCS) * VecDistanceToSdCore.
GetY(coreCS)
448 - mcAxis.
GetZ(coreCS) * VecDistanceToSdCore.
GetZ(coreCS);
454 out <<
"Set relative pulse time of noSignalStation to " << relativePulseTime
455 <<
" relative to rd event time";
462 out <<
"created empty trace with " << statTimeSeries.GetSize() <<
" samples";
469 if (numberOfEmptyButTriggeredRDStations) {
471 out << numberOfEmptyButTriggeredRDStations
472 <<
" empty traces have been add for triggered but not simulated RD stations.";
483 RdStationAssociator::Finish()
490 RdStationAssociator::FindClosestStationFromPoint(
const utl::Point& pt,
492 double maxDistanceFactor)
495 double foundmindist = fMaximumDistance * maxDistanceFactor;
498 for (
const auto& station : rDet.StationsRange()) {
499 const utl::Point Position = station.GetPosition();
501 dist = (Position - pt).GetMag();
502 if (dist < foundmindist) {
503 stid = station.GetId();
517 INFODebug(
"Use RdStationAssociator to create generic (starshaped) stations.");
520 Detector& det = Detector::GetInstance();
527 const string err =
"Attempt to generate radio array with starshaped pattern failed because "
528 "no simulated shower is present in the event.";
532 const string fEllipsoid_string =
"WGS84";
533 const string fBand =
"H";
534 const int fZone = 19;
537 ReferenceEllipsoid::GetEllipsoidIDFromString(fEllipsoid_string));
541 unsigned int nstat = 0;
543 for (
int stationId = fFirstStationId; stationId < fFirstStationId + numberOfAntennas; stationId++) {
548 station.
fId = stationId;
555 station.
fBand = fBand;
556 station.
fZone = fZone;
563 const int pulseIndex = stationId - fFirstStationId;
570 const UTMPoint stationUTM(pos, ellipsoid);
580 ERROR(
"Something went wrong during reading of virtual stations");
589 out <<
"Initialized " << nstat <<
" virtual stations.";
Branch GetTopBranch() const
std::string fDecommissionTime
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.
ManagerRegister & GetRManagerRegister() const
constexpr T Sqr(const T &x)
bool HasStation(const int stationId) const
Check whether station exists.
double GetY(double x, const std::vector< double > &p) const
void MakeSimData()
Make station simulated data object.
const SimRadioPulse & GetSimPulseByIndex(const int index)
Interface class to access to the Radio part of an event.
Interface class to access to the SD part of an event.
std::string GetAntennaName() const
Get the name of simulated antenna related to pulse.
utl::TimeStamp GetTime() const
Get time pertaining to the detector description.
Class to hold and convert a point in geodetic coordinates.
void MakeSimData()
Make station simulated data object.
bool HasTriggerData() const
Check whether trigger data object exists.
Data structure for simulated Radio pulses.
EventTrigger & GetTrigger()
Get the object with central trigger data, throw if n.a.
bool HasSimShower() const
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()
vector< t2list > out
output of the algorithm: a list of clusters
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
double GetNorthing() const
Get the northing.
StationTimeSeries & GetStationTimeSeries()
retrieve Station Time Series (write access, only use this if you intend to change the data) ...
A TimeStamp holds GPS second and nanosecond for some event.
Detector description interface for RDetector-related data.
void MakeGPSData()
Make GPS data object.
void MakeTriggerData()
Make trigger data object.
void SetLocalCoordinateSystem(utl::CoordinateSystemPtr localCS) const
void SetExternalTrigger(const bool trig)
Set if Event was externally triggered.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define INFOIntermediate(y)
Class representing a document branch.
class to hold data at the radio Station level.
Reference ellipsoids for UTM transformations.
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!
double GetHeight() const
Get the height.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
void AddVirtualStation(RStationListManager::StationData &station)
void MakeTrigger()
Create the central trigger object.
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
constexpr double nanosecond
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.
ShowerSimData & GetSimShower()
double GetEasting() const
Get the easting.
static std::size_t GetSize()
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
constexpr double microvolt
Manager for RD description in SQL or XML station lists.
const VManager & GetManager(const std::string &managerName) const
Get a specific manager by name.
void SetData(std::vector< std::pair< double, double >> data)
void SetBinning(const double binning)
Base class for exceptions arising because required info not present in the Event. ...
double GetY(const CoordinateSystemPtr &coordinateSystem) const
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
int Minimize(const int n=500)
bool HasSimPulseByIndex(const int index)
constexpr double kConversionRadioSignalToEnergyFluence
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
sevt::StationTriggerData & GetTriggerData()
Get Trigger data for the station.
long GetNumPulses() const
Get the number of radio pulses contained in the RadioSimulation.
bool HasStation(const int stationId) const
Check whether station exists.
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
std::string fCommissionTime
void PushBack(const T &value)
Insert a single value at the end.
#define ERROR(message)
Macro for logging error messages.
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
sevt::SEvent & GetSEvent()
double GetStartTime() const
Get the timestamp of the first sample.