3 #include <fwk/CentralConfig.h>
4 #include <fwk/LocalCoordinateSystem.h>
6 #include <utl/ErrorLogger.h>
7 #include <utl/Reader.h>
8 #include <utl/config.h>
9 #include <utl/AugerUnits.h>
10 #include <utl/FFTDataContainerAlgorithm.h>
11 #include <utl/RadioGeometryUtilities.h>
13 #include <evt/Event.h>
14 #include <evt/ShowerRecData.h>
15 #include <evt/ShowerRRecData.h>
16 #include <evt/ShowerSimData.h>
18 #include <revt/REvent.h>
19 #include <revt/Header.h>
20 #include <revt/StationRecData.h>
22 #include <det/Detector.h>
23 #include <rdet/RDetector.h>
37 Branch topBranch = CentralConfig::GetInstance()->
GetTopBranch(
"RdStationEFieldVectorCalculator");
44 topBranch.
GetChild(
"ChargeExcessStrength").
GetData(fChargeExcessStrength);
55 WARNING(
"No radio event found!");
61 WARNING(
"Event does not have RRecShower, nothing will be done!");
67 REvent& rEvent =
event.GetREvent();
68 auto& rRecShower =
event.GetRecShower().GetRRecShower();
69 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
71 const Vector showerAxis =rRecShower.GetReferenceAxis(event);
72 const Point showerCore = rRecShower.GetReferenceCorePosition(event);
74 Vector magneticFieldAxis = rRecShower.GetMagneticFieldVector();
78 INFOFinal(
"Using magnetic field from simulated air shower.");
79 const double magFieldAzimuth =
event.GetSimShower().GetMagneticFieldAzimuth();
80 const double magFieldZenith =
event.GetSimShower().GetMagneticFieldZenith();
81 magneticFieldAxis =
Vector(1, magFieldZenith, magFieldAzimuth, coordinateSystem,
86 for (
auto& station : rEvent.StationsRange()) {
87 if (!station.HasRecData()) {
96 const auto& efieldData = station.GetFFTDataContainer();
97 const auto& stationtrace = efieldData.GetConstTimeSeries();
98 fPeakSearchWindow =
static_cast<int>(fPeakSearchWindowWidth / stationtrace.GetBinning());
101 info <<
"PeakSearchWindow = " << fPeakSearchWindowWidth <<
" ns = "
102 << fPeakSearchWindow <<
" bins";
107 if (!(station.GetRecData().HasParameter(ePeakAmplitudeEW)
108 && station.GetRecData().HasParameter(ePeakAmplitudeNS)
109 && station.GetRecData().HasParameter(ePeakAmplitudeV))) {
110 WARNING(
"ePeakAmplitude(EW,NS,V) was not set");
114 const array<double, 3> peakAmp = {recStation.
GetParameter(ePeakAmplitudeEW),
120 unsigned int maxPol = 0;
122 auto iteratorOfMax = max_element(peakAmp.begin(), peakAmp.end());
123 maxPol = distance(peakAmp.begin(), iteratorOfMax);
130 const double tPeakTimeEnvelope =
132 const long unsigned int tPeakPos = tPeakTimeEnvelope / stationtrace.GetBinning();
134 long unsigned int peakPos = 0;
136 if (fPeakSearch != 0) {
138 info <<
"Station " << station.GetId() <<
": fPeakSearch";
142 unsigned int tMaxPos = 0;
145 if (fPeakSearch == -1) {
146 for (
auto i = tPeakPos; i > (tPeakPos - fPeakSearchWindow); --i) {
147 if (fabs(stationtrace[i][maxPol]) > tMaxAmp) {
148 tMaxAmp = fabs(stationtrace[i][maxPol]);
155 info <<
"Station " << station.GetId() <<
": searching " << fPeakSearchWindow
156 <<
"ns before the maximum of the combo hilbert envelope. MaxCombo at "
157 << tPeakPos <<
"ns and max of polarization " << maxPol <<
" at " << peakPos;
162 if (fPeakSearch == 1) {
163 for (
auto i = tPeakPos; i < (tPeakPos + fPeakSearchWindow); ++i) {
164 if (fabs(stationtrace[i][maxPol]) > tMaxAmp) {
165 tMaxAmp = fabs(stationtrace[i][maxPol]);
172 info <<
"Station " << station.GetId() <<
": searching " << fPeakSearchWindow
173 <<
"ns after the maximum of the combo hilbert envelope. MaxCombo at "
174 << tPeakPos <<
"ns and max of polarization " << maxPol <<
" at " << peakPos;
180 info <<
"Station " << station.GetId() <<
": Found peak position at " << peakPos <<
" = "
181 << peakPos * stationtrace.GetBinning() <<
"ns in polarization " << maxPol;
186 array<double, 3> EVector = {0, 0, 0};
187 for (
unsigned int iPol = 0; iPol < 3; ++iPol) {
188 EVector[iPol] = stationtrace[peakPos][iPol];
192 double angleToLorentzForce = 0;
193 double angleToExpectedEField = 0;
195 if (fMeanEFieldVector) {
197 auto efieldEnvelope = station.GetFFTDataContainer();
198 FFTDataContainerAlgorithm::HilbertEnvelope(efieldEnvelope);
199 const auto& stationEnvelope = efieldEnvelope.GetConstTimeSeries();
202 const double maxSignal = recStation.
GetParameter(eSignal);
203 const pair<double, double> fwhm = GetFWHM(stationEnvelope, maxSignal, tPeakPos);
205 const TVector3 firstGuess(EVector[0], EVector[1], EVector[2]);
206 TVector3 meanEField = GetMeanEfieldInRange(stationtrace, fwhm, firstGuess);
208 const Vector vCurrentEField =
209 Normalized(
Vector(meanEField.x(), meanEField.y(), meanEField.z(), coordinateSystem));
211 const double meanAngleToLorentzForce =
212 RadioGeometryUtilities::GetAngleToLorentzVector(vCurrentEField, showerAxis, magneticFieldAxis);
214 const double meanAngleToExpectedEField = RadioGeometryUtilities::GetAngleToEFieldExpectation(
215 vCurrentEField, showerCore, showerAxis, stationPosition, magneticFieldAxis, fChargeExcessStrength);
218 meanEField.SetMag(maxSignal);
221 EVector[0] = meanEField.x();
222 EVector[1] = meanEField.y();
223 EVector[2] = meanEField.z();
224 angleToLorentzForce = NormalizeAngle(meanAngleToLorentzForce);
225 angleToExpectedEField = NormalizeAngle(meanAngleToExpectedEField);
229 info <<
"Station " << station.GetId() <<
": Calculated EFieldvector to ("
230 << EVector[0] <<
", " << EVector[1] <<
", " << EVector[2] <<
")";
237 const double angleToLorentzForceError =
238 GetAngleToLorentzForceError(recStation.
GetParameter(eSignalToNoise));
240 recStation.
SetParameter(eAngleToLorentzVector, angleToLorentzForce);
242 recStation.
SetParameter(eAngleToExpectedEFieldVector, angleToExpectedEField);
243 recStation.
SetParameterError(eAngleToExpectedEFieldVector, angleToLorentzForceError);
246 info <<
"Station " << station.GetId() <<
": "
247 <<
"Angle to Lorentz force vector " << round(angleToLorentzForce /
degree * 10.) / 10.
248 <<
" +/- " << round(angleToLorentzForceError /
degree * 10.) / 10. <<
" deg, "
249 <<
"Angle to expected eField vector " << round(angleToExpectedEField /
degree * 10.) / 10.
250 <<
" +/- " << round(angleToLorentzForceError /
degree * 10.) / 10. <<
" deg "
251 <<
"with a charge excess strength of " << fChargeExcessStrength;
260 RdStationEFieldVectorCalculator::Finish()
267 RdStationEFieldVectorCalculator::GetFWHM(
const StationTimeSeries& stationEnvelope,
const double maxSignal,
268 const double tPeakPos)
272 unsigned int FWHMPosLeft = 0;
273 for (
auto i = tPeakPos; i > 0; --i) {
274 if (stationEnvelope[i].GetMag() < maxSignal / 2) {
280 unsigned int FWHMPosRight = 0;
281 for (
auto i = tPeakPos; i < stationEnvelope.
GetSize(); ++i) {
282 if (stationEnvelope[i].GetMag() < maxSignal / 2) {
289 info <<
"FWHM: " << FWHMPosLeft <<
" = "
290 << FWHMPosLeft * stationEnvelope.
GetBinning() <<
"ns to " << FWHMPosRight
291 <<
" = " << FWHMPosRight * stationEnvelope.
GetBinning() <<
"ns";
294 return std::make_pair(FWHMPosLeft, FWHMPosRight);
300 const pair<double, double>& range,
301 const TVector3& firstGuess)
306 double FWHMPosLeft, FWHMPosRight;
307 tie(FWHMPosLeft, FWHMPosRight) = range;
310 TVector3 currentEField;
311 double sumOfWeights = 0;
314 for (
auto i = FWHMPosLeft; i < FWHMPosRight; ++i) {
315 currentEField = TVector3(stationTrace[i][0], stationTrace[i][1], stationTrace[i][2]);
317 if (currentEField.Angle(firstGuess) > 90 *
degree) {
319 info <<
"i = " << i <<
" = " << i * stationTrace.
GetBinning()
320 <<
"ns: vector flipped";
325 meanEField += currentEField;
326 sumOfWeights += currentEField.Mag();
328 meanEField *= 1. / sumOfWeights;
335 RdStationEFieldVectorCalculator::GetAngleToLorentzForceError(
double snr)
337 const double sigma1 = (23.6 /
sqrt(snr) - 4.3 / snr + 41.8 /
pow(snr, 1.5)) *
degree;
338 const double sigma2 = 1 *
deg;
344 RdStationEFieldVectorCalculator::NormalizeAngle(
const double x)
346 return (x >
kPi / 2) ?
kPi - x : x;
Branch GetTopBranch() const
Class to access station level reconstructed data.
void SetParameterError(Parameter i, double value, bool lock=true)
constexpr T Sqr(const T &x)
Interface class to access to the Radio part of an event.
ShowerRecData & GetRecShower()
bool HasSimShower() const
double GetBinning() const
size of one slot
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)
Detector description interface for RDetector-related data.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define INFOIntermediate(y)
Class representing a document branch.
bool HasRRecShower() const
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
AxialVector Normalized(const AxialVector &v)
double GetParameter(const Parameter i) const
ResultFlag
Flag returned by module methods to the RunController.
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)
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
const Station & GetStation(const int stationId) const
Get station by Station Id.