3 #include <fwk/CentralConfig.h>
4 #include <fwk/LocalCoordinateSystem.h>
6 #include <utl/ErrorLogger.h>
8 #include <utl/AugerUnits.h>
9 #include <utl/FFTDataContainerAlgorithm.h>
10 #include <utl/RadioGeometryUtilities.h>
11 #include <utl/RadioTraceUtilities.h>
12 #include <utl/PhysicalConstants.h>
14 #include <evt/Event.h>
15 #include <evt/ShowerRecData.h>
16 #include <evt/ShowerRRecData.h>
18 #include <revt/REvent.h>
19 #include <revt/Station.h>
20 #include <revt/StationRecData.h>
21 #include <revt/StationTriggerData.h>
22 #include <revt/Channel.h>
24 #include <det/Detector.h>
25 #include <rdet/RDetector.h>
26 #include <rdet/Station.h>
27 #include <rdet/Channel.h>
29 #include <boost/algorithm/string/case_conv.hpp>
45 Branch topBranch = CentralConfig::GetInstance()->
GetTopBranch(
"RdStationSignalReconstructor");
50 topBranch.
GetChild(
"SignalIntegrationWindowSize").
GetData(fSignalIntegrationWindowSize);
51 topBranch.
GetChild(
"AddNoiseToUncertainty").
GetData(fAddNoiseToUncertainty);
55 topBranch.
GetChild(
"AdjustSignalAmplitude").
GetData(fAdjustSignalAmplitude);
57 topBranch.
GetChild(
"AmplitudeUncertainty").
GetData(fAmplitudeUncertainty);
58 topBranch.
GetChild(
"DefaultAntennaUncertainty").
GetData(fDefaultAntennaUncertainty);
59 topBranch.
GetChild(
"ButterflyAntennaUncertainty").
GetData(fButterflyAntennaUncertainty);
60 topBranch.
GetChild(
"BlackSpiderAntennaUncertainty").
GetData(fBlackSpiderAntennaUncertainty);
61 topBranch.
GetChild(
"SallaRDAntennaUncertainty").
GetData(fSallaRDAntennaUncertainty);
63 const string yesnostr = topBranch.
GetChild(
"allowMultipleCalls").
Get<
string>();
64 fLockParameterStorage = (yesnostr ==
"no");
67 info <<
"\n\t Vectorial component : " << fVectorialComponent
68 <<
"\n\t Use Envelope : " << fUseEnvelope
69 <<
"\n\t Min. SNR : " << fMinSignalToNoise
70 <<
"\n\t Signal inegration window : " << fSignalIntegrationWindowSize <<
"ns"
71 <<
"\n\t Add Noise to uncertainty : " << fAddNoiseToUncertainty
72 <<
"\n\t Ampl. uncertainty / % : " << fAmplitudeUncertainty
73 <<
"\n\t Rel. antenna pattern uncertainty / %"
74 <<
"\n\t (LPDA / BF / Salla_RD / Default): (" << fBlackSpiderAntennaUncertainty
75 <<
" / " << fButterflyAntennaUncertainty
76 <<
" / " << fSallaRDAntennaUncertainty
77 <<
" / " << fDefaultAntennaUncertainty <<
")\n";
85 RdStationSignalReconstructor::Run(
evt::Event& event)
89 WARNING(
"No radio event found!");
93 REvent& rEvent =
event.GetREvent();
96 int numberOfStationsWithPulseFound = 0;
99 for (
auto& station : rEvent.StationsRange()) {
102 if (!station.HasRecData()) {
103 WARNING(
"Station has no RecData! Please call RdEventInitializer first!");
108 const double signalSearchWindowStart = recStation.
GetParameter(eSignalSearchWindowStart);
109 const double signalSearchWindowStop = recStation.
GetParameter(eSignalSearchWindowStop);
112 info <<
"Signal search window: " << signalSearchWindowStart <<
" to " << signalSearchWindowStop;
117 info <<
"Station " << station.GetId() <<
" has invalid signal search window from "
118 << signalSearchWindowStart <<
" to " << signalSearchWindowStop
119 <<
". Skipping station.";
126 const double relTime = recStation.
GetParameter(eTraceStartTime);
129 info <<
"Apply pulse finder on station " << station.GetId();
136 FFTDataContainerAlgorithm::HilbertEnvelope(efieldData);
139 info <<
"size of efield trace = " << efieldData.GetConstTimeSeries().GetSize();
144 const StationTimeSeries& stationTraceNoEnvelope = station.GetFFTDataContainer().GetConstTimeSeries();
153 double noiseWindowStart = recStation.
GetParameter(eNoiseWindowStart);
154 double noiseWindowStop = recStation.
GetParameter(eNoiseWindowStop);
156 const double signalIntegrationWindowSize = fSignalIntegrationWindowSize;
157 recStation.
SetParameter(eSignalIntegrationTime, fSignalIntegrationWindowSize, fLockParameterStorage);
159 bool pulseFound =
false;
161 double signalWindowStart = 0;
162 double signalWindowStop = 0;
164 double noiseMean = 0;
167 unsigned int peakBin = 0;
168 unsigned int sample = 0;
170 double peakAmplitude = 0;
172 double peakTimeError = 0;
182 const unsigned int numComponents = 7;
183 for (
unsigned int iterator = 0; iterator < numComponents; ++iterator) {
185 const unsigned int component = (iterator + fVectorialComponent) % numComponents;
189 channeltrace.
Clear();
190 channelTraceNoEnvelope.
Clear();
193 if (component == 0) {
195 channeltrace.
PushBack(stationtrace[i].GetMag());
196 channelTraceNoEnvelope.
PushBack(stationTraceNoEnvelope[i].GetMag());
198 if (isnan(stationtrace[i].GetMag()) || isnan(stationTraceNoEnvelope[i].GetMag())) {
200 info <<
"sample " << i <<
" of efield trace is nan";
204 }
else if (component == 1 || component == 2 || component == 3) {
207 channeltrace.
PushBack(
abs(stationtrace[i][component - 1]));
208 channelTraceNoEnvelope.
PushBack(
abs(stationTraceNoEnvelope[i][component - 1]));
210 }
else if (component == 4) {
214 channelTraceNoEnvelope.
PushBack(
sqrt(
Sqr(stationTraceNoEnvelope[i][0]) +
215 Sqr(stationTraceNoEnvelope[i][1])));
217 }
else if (component == 5 || component == 6) {
222 WARNING(
"Reference direction or core position not set. "
223 "The electric-field can not be rotated into the vxB, vx(vxB) system. "
224 "The calculation will be skipped");
239 for (
unsigned int i = 0; i < traceShowerPlane.GetSize(); ++i) {
240 channeltrace.
PushBack(traceShowerPlane[i][component - 5]);
241 channelTraceNoEnvelope.
PushBack(traceShowerPlaneNoEnvelope[i][component - 5]);
245 ERROR(
"This component does not exist!");
250 const double traceStop = (channeltrace.
GetSize() - 1) * channeltrace.
GetBinning();
251 noiseWindowStart = min(
max(0., noiseWindowStart), traceStop);
252 noiseWindowStop =
max(min(noiseWindowStop, traceStop), noiseWindowStart);
255 RadioTraceUtilities::Noisefinder(channeltrace, noiseRMS, noiseMean, noiseWindowStart, noiseWindowStop);
256 RadioTraceUtilities::Pulsefinder(channeltrace, peakAmplitude, peakTime, peakTimeError,
257 signalSearchWindowStart, signalSearchWindowStop, sample);
259 if (component == fVectorialComponent)
263 double signalEnergyFluence = 0;
264 RadioTraceUtilities::PulseFixedWindowIntegrator(channelTraceNoEnvelope, peakBin, signalIntegrationWindowSize,
265 signalEnergyFluence, signalWindowStart, signalWindowStop,
true);
268 double noiseEnergyFluence = 0;
269 double integratedNoisePowerFixedWidthStartTime = 0;
270 double integratedNoisePowerFixedWidthStopTime = 0;
271 const double noiseWindowSize = noiseWindowStop - noiseWindowStart;
272 const unsigned int meanNoiseSample = (noiseWindowStart + noiseWindowSize * 0.5) / channelTraceNoEnvelope.
GetBinning();
273 RadioTraceUtilities::PulseFixedWindowIntegrator(channelTraceNoEnvelope, meanNoiseSample, noiseWindowSize,
274 noiseEnergyFluence, integratedNoisePowerFixedWidthStartTime,
275 integratedNoisePowerFixedWidthStopTime,
true);
278 noiseEnergyFluence *= signalIntegrationWindowSize / noiseWindowSize;
279 signalEnergyFluence = signalEnergyFluence - noiseEnergyFluence;
281 double signalEnergyFluenceError =
sqrt(
283 (2 *
abs(signalEnergyFluence) + signalIntegrationWindowSize *
Sqr(noiseRMS))
291 const double antennaToAntennaUncertainty = GetAntennaToAntennaUncertainty(station);
294 info <<
"Station " << station.GetId() <<
" component " << component <<
" signaltime (sample) "
295 << peakTime <<
"(" << sample <<
") Integrating f around sample " << peakBin
296 <<
" f = " << signalEnergyFluence <<
" f noise = " << noiseEnergyFluence
297 <<
" sigma_f = " << signalEnergyFluenceError
298 <<
" AmplitudeUncertainty = " << fAmplitudeUncertainty
299 <<
" antennaToAntennaUncertainty = " << antennaToAntennaUncertainty;
303 signalEnergyFluenceError =
sqrt(
304 Sqr(signalEnergyFluenceError) +
305 Sqr(fAmplitudeUncertainty * 2 * signalEnergyFluence) +
306 Sqr(antennaToAntennaUncertainty * 2 * signalEnergyFluence)
310 double signalToNoise = nan(
"");
312 signalToNoise = peakAmplitude / noiseRMS;
315 if (component == fVectorialComponent) {
317 info <<
"Pulsefinder startsample = " << signalWindowStart <<
" lastsample = " << signalWindowStop;
320 const auto signalToNoise2 =
Sqr(signalToNoise);
322 peakTimeError =
sqrt(
Sqr(peakTimeError) +
Sqr(GetSignalTimeUncertainty(signalToNoise2)));
324 recStation.
SetParameter(eSignalTime, relTime + peakTime, fLockParameterStorage);
327 fLockParameterStorage
330 if (fAdjustSignalAmplitude)
331 peakAmplitude = GetAdjustedSignalAmplitude(peakAmplitude, signalToNoise2);
333 const auto sigUnc = GetSignalUncertainty(peakAmplitude, signalToNoise2);
335 info <<
"SNR = " << signalToNoise2 <<
"\t"
336 "signal amplitude = " << peakAmplitude <<
"\t"
337 "Uncertainty of SignalAmplitude = " << sigUnc;
340 const double tempUncertainty =
sqrt(
342 Sqr(peakAmplitude * fAmplitudeUncertainty) +
343 Sqr(peakAmplitude * antennaToAntennaUncertainty)
346 recStation.
SetParameter(eSignalToNoise, signalToNoise2, fLockParameterStorage);
347 recStation.
SetParameter(eNoise, noiseRMS, fLockParameterStorage);
348 recStation.
SetParameter(eSignal, peakAmplitude, fLockParameterStorage);
352 recStation.
SetParameter(eSignalWindowStart, signalWindowStart, fLockParameterStorage);
353 recStation.
SetParameter(eSignalWindowStop, signalWindowStop, fLockParameterStorage);
354 recStation.
SetParameter(eMinSignal, fMinSignal, fLockParameterStorage);
355 recStation.
SetParameter(eMinSignalToNoise, fMinSignalToNoise, fLockParameterStorage);
361 if (fAddNoiseToUncertainty)
362 signalEnergyFluenceError =
sqrt(
Sqr(signalEnergyFluenceError) +
Sqr(noiseEnergyFluence));
365 if (component == 0) {
366 recStation.
SetParameter(ePeakAmplitudeMag, peakAmplitude, fLockParameterStorage);
367 recStation.
SetParameter(ePeakTimeMag, relTime + peakTime, fLockParameterStorage);
368 recStation.
SetParameter(eNoiseRmsMag, noiseRMS, fLockParameterStorage);
369 recStation.
SetParameter(eNoiseMeanMag, noiseMean, fLockParameterStorage);
370 recStation.
SetParameter(eSignalEnergyFluenceMag, signalEnergyFluence, fLockParameterStorage);
371 recStation.
SetParameterError(eSignalEnergyFluenceMag, signalEnergyFluenceError, fLockParameterStorage);
372 recStation.
SetParameter(eNoiseEnergyFluenceMag, noiseEnergyFluence, fLockParameterStorage);
373 }
else if (component == 1) {
374 recStation.
SetParameter(ePeakAmplitudeEW, peakAmplitude, fLockParameterStorage);
375 recStation.
SetParameter(ePeakTimeEW, relTime + peakTime, fLockParameterStorage);
376 recStation.
SetParameter(eNoiseRmsEW, noiseRMS, fLockParameterStorage);
377 recStation.
SetParameter(eNoiseMeanEW, noiseMean, fLockParameterStorage);
378 recStation.
SetParameter(eSignalEnergyFluenceEW, signalEnergyFluence, fLockParameterStorage);
379 recStation.
SetParameterError(eSignalEnergyFluenceEW, signalEnergyFluenceError, fLockParameterStorage);
380 recStation.
SetParameter(eNoiseEnergyFluenceEW, noiseEnergyFluence, fLockParameterStorage);
381 }
else if (component == 2) {
382 recStation.
SetParameter(ePeakAmplitudeNS, peakAmplitude, fLockParameterStorage);
383 recStation.
SetParameter(ePeakTimeNS, relTime + peakTime, fLockParameterStorage);
384 recStation.
SetParameter(eNoiseRmsNS, noiseRMS, fLockParameterStorage);
385 recStation.
SetParameter(eNoiseMeanNS, noiseMean, fLockParameterStorage);
386 recStation.
SetParameter(eSignalEnergyFluenceNS, signalEnergyFluence, fLockParameterStorage);
387 recStation.
SetParameterError(eSignalEnergyFluenceNS, signalEnergyFluenceError, fLockParameterStorage);
388 recStation.
SetParameter(eNoiseEnergyFluenceNS, noiseEnergyFluence, fLockParameterStorage);
389 }
else if (component == 3) {
390 recStation.
SetParameter(ePeakAmplitudeV, peakAmplitude, fLockParameterStorage);
391 recStation.
SetParameter(ePeakTimeV, relTime + peakTime, fLockParameterStorage);
392 recStation.
SetParameter(eNoiseRmsV, noiseRMS, fLockParameterStorage);
393 recStation.
SetParameter(eNoiseMeanV, noiseMean, fLockParameterStorage);
394 recStation.
SetParameter(eSignalEnergyFluenceV, signalEnergyFluence, fLockParameterStorage);
395 recStation.
SetParameterError(eSignalEnergyFluenceV, signalEnergyFluenceError, fLockParameterStorage);
396 recStation.
SetParameter(eNoiseEnergyFluenceV, noiseEnergyFluence, fLockParameterStorage);
397 }
else if (component == 4) {
398 recStation.
SetParameter(ePeakAmplitudeNSEWPlane, peakAmplitude, fLockParameterStorage);
399 recStation.
SetParameter(ePeakTimeNSEWPlane, relTime + peakTime, fLockParameterStorage);
400 recStation.
SetParameter(eNoiseRmsNSEWPlane, noiseRMS, fLockParameterStorage);
401 recStation.
SetParameter(eNoiseMeanNSEWPlane, noiseMean, fLockParameterStorage);
402 recStation.
SetParameter(eSignalEnergyFluenceNSEWPlane, signalEnergyFluence, fLockParameterStorage);
403 recStation.
SetParameterError(eSignalEnergyFluenceNSEWPlane, signalEnergyFluenceError, fLockParameterStorage);
404 recStation.
SetParameter(eNoiseEnergyFluenceNSEWPLane, noiseEnergyFluence, fLockParameterStorage);
405 }
else if (component == 5) {
406 recStation.
SetParameter(ePeakAmplitudeVxB, peakAmplitude, fLockParameterStorage);
407 recStation.
SetParameter(ePeakTimeVxB, relTime + peakTime, fLockParameterStorage);
408 recStation.
SetParameter(eNoiseRmsVxB, noiseRMS, fLockParameterStorage);
409 recStation.
SetParameter(eNoiseMeanVxB, noiseMean, fLockParameterStorage);
410 recStation.
SetParameter(eSignalEnergyFluenceVxB, signalEnergyFluence, fLockParameterStorage);
411 recStation.
SetParameterError(eSignalEnergyFluenceVxB, signalEnergyFluenceError, fLockParameterStorage);
412 recStation.
SetParameter(eNoiseEnergyFluenceVxB, noiseEnergyFluence, fLockParameterStorage);
413 recStation.
SetParameter(eSignalToNoiseVxB, signalToNoise, fLockParameterStorage);
414 }
else if (component == 6) {
415 recStation.
SetParameter(ePeakAmplitudeVxVxB, peakAmplitude, fLockParameterStorage);
416 recStation.
SetParameter(ePeakTimeVxVxB, relTime + peakTime, fLockParameterStorage);
417 recStation.
SetParameter(eNoiseRmsVxVxB, noiseRMS, fLockParameterStorage);
418 recStation.
SetParameter(eNoiseMeanVxVxB, noiseMean, fLockParameterStorage);
419 recStation.
SetParameter(eSignalEnergyFluenceVxVxB, signalEnergyFluence, fLockParameterStorage);
420 recStation.
SetParameterError(eSignalEnergyFluenceVxVxB, signalEnergyFluenceError, fLockParameterStorage);
421 recStation.
SetParameter(eNoiseEnergyFluenceVxVxB, noiseEnergyFluence, fLockParameterStorage);
422 recStation.
SetParameter(eSignalToNoiseVxVxB, signalToNoise, fLockParameterStorage);
425 if (component == fVectorialComponent) {
428 if ((recStation.
GetParameter(eSignalToNoise) > fMinSignalToNoise ||
430 !fSelfTriggeredSNcut)) &&
433 info <<
"pulse found for station " << station.GetId();
434 ++numberOfStationsWithPulseFound;
438 if (station.IsRejected()) {
439 info <<
", but station is already rejected.";
441 info <<
", setting station to signal station";
445 info <<
"no pulse found for station " << station.GetId();
447 station.SetNoSignal();
464 info <<
"Found " << numberOfStationsWithPulseFound <<
" stations with signal pulse";
467 if (fLockParameterStorage)
468 fNumberOfStationsInEvents[numberOfStationsWithPulseFound]++;
475 RdStationSignalReconstructor::Finish()
479 const auto totalEvents =
480 accumulate(fNumberOfStationsInEvents.begin(), fNumberOfStationsInEvents.end(), 0,
481 [](
const size_t sum,
const auto&
p){
return sum +
p.second; });
483 info <<
"Event statistics:\n\t" << totalEvents <<
" event(s) total:";
486 info <<
"\nNo events stored in the map. "
487 "This can happen if the parameter storage is kept unlocked, "
488 "e.g. for the iterative geometry reconstruction";
490 if (fInfoLevel == eInfoFinal) {
491 const auto eventsMoreThanFiveStations = totalEvents -
492 fNumberOfStationsInEvents[0] - fNumberOfStationsInEvents[1] -
493 fNumberOfStationsInEvents[2] - fNumberOfStationsInEvents[3] -
494 fNumberOfStationsInEvents[4] - fNumberOfStationsInEvents[5];
496 info <<
"\n\t" << fNumberOfStationsInEvents[1] <<
" event(s) with 1 signal station"
497 <<
"\n\t" << fNumberOfStationsInEvents[2] <<
" event(s) with 2 signal stations"
498 <<
"\n\t" << fNumberOfStationsInEvents[3] <<
" event(s) with 3 signal stations"
499 <<
"\n\t" << fNumberOfStationsInEvents[4] <<
" event(s) with 4 signal stations"
500 <<
"\n\t" << fNumberOfStationsInEvents[5] <<
" event(s) with 5 signal stations"
501 <<
"\n\t" << eventsMoreThanFiveStations <<
" events with more than 5 signal stations";
504 if (fInfoLevel == eInfoIntermediate) {
505 for (
const auto& sn : fNumberOfStationsInEvents)
506 info <<
"\n\t" << sn.second <<
" event(s) with " << sn.first <<
" station(s)";
517 RdStationSignalReconstructor::GetAdjustedSignalAmplitude(
const double signalAmpitude,
const double snr)
520 const double factor = 1 / (1 + 1.55 /
pow(snr, 2.43/2));
522 info <<
"adjusting signal amplitude with a factor of " << factor;
525 return signalAmpitude * factor;
530 RdStationSignalReconstructor::GetSignalUncertainty(
const double signalAmplitude,
const double snr)
533 return (0.423 /
sqrt(snr) - 0.501 / snr + 3.395 /
pow(snr, 1.5)) * signalAmplitude;
538 RdStationSignalReconstructor::GetSignalTimeUncertainty(
const double snr)
541 return 11.7*
ns *
pow(snr, -0.71);
546 RdStationSignalReconstructor::GetAntennaToAntennaUncertainty(
const Station& station)
549 double antennaToAntennaUncertainty = 0;
550 const auto& rDet = det::Detector::GetInstance().GetRDetector();
551 for (
const auto& channel : station.ChannelsRange()) {
552 const auto cid = channel.GetId();
553 const auto& antennaName = rDet.GetStation(station).GetChannel(cid).GetAntennaTypeName();
554 const auto& an = boost::algorithm::to_lower_copy(antennaName);
555 if (an.find(
"butterfly") != string::npos) {
556 if (antennaToAntennaUncertainty < fButterflyAntennaUncertainty)
557 antennaToAntennaUncertainty = fButterflyAntennaUncertainty;
558 }
else if (an.find(
"blackspider") != string::npos) {
559 if (antennaToAntennaUncertainty < fBlackSpiderAntennaUncertainty)
560 antennaToAntennaUncertainty = fBlackSpiderAntennaUncertainty;
561 }
else if (an.find(
"salla_rd") != string::npos) {
562 if (antennaToAntennaUncertainty < fSallaRDAntennaUncertainty)
563 antennaToAntennaUncertainty = fSallaRDAntennaUncertainty;
565 if (antennaToAntennaUncertainty < fDefaultAntennaUncertainty)
566 antennaToAntennaUncertainty = fDefaultAntennaUncertainty;
569 return antennaToAntennaUncertainty;
Branch GetTopBranch() const
Class to access station level reconstructed data.
void SetParameterError(Parameter i, double value, bool lock=true)
utl::Point GetReferenceCorePosition(const Event &event) const
Returning the reference core position depending on the corresponding flag.
constexpr T Sqr(const T &x)
void SetPulseFound(const bool pulsefound)
Interface class to access Shower Reconstructed parameters.
bool HasRecShower() const
Interface class to access to the Radio part of an event.
Interface class to access to the RD Reconstruction of a Shower.
double GetParameterError(const Parameter i) const
bool HasReferenceAxis(const Event &event) const
Return always true for SD and FD if RecShower exsist, asking for min. rec stage could fix this...
double GetBinning() const
size of one slot
#define INFO(message)
Macro for logging informational messages.
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
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.
std::vector< T >::size_type SizeType
double abs(const SVector< n, T > &v)
bool HasRRecShower() const
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
PulseFinder searches for maximum in the trace. Choose vectorial component in the xml file...
double GetParameter(const Parameter i) const
void SetBinning(const double binning)
Template class for a data container that offers and takes both time series and corresponding frequenc...
ResultFlag
Flag returned by module methods to the RunController.
bool HasReferenceCorePosition(const Event &event) const
Return always true for SD and FD if RecShower exsist, asking for min. rec stage could fix this...
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
void SetParameter(Parameter i, double value, bool lock=true)
constexpr double kConversionRadioSignalToEnergyFluence
utl::Vector GetReferenceAxis(const Event &event) const
Returning the referencedirection depending on the corresponding flag.
void PushBack(const T &value)
Insert a single value at the end.
utl::Vector GetMagneticFieldVector() const
returns the magnetic field vector from the components stored in the parameter storage ...
#define ERROR(message)
Macro for logging error messages.
utl::TraceV3D GetTraceInShowerPlaneVxB(const utl::TraceV3D &trace) const