RdStationSimPulseFinder.cc
Go to the documentation of this file.
2 
3 #include <fwk/CentralConfig.h>
4 #include <fwk/MagneticFieldModel.h>
5 
6 #include <utl/ErrorLogger.h>
7 #include <utl/Reader.h>
8 #include <utl/config.h>
9 #include <utl/RadioGeometryUtilities.h>
10 #include <utl/FFTDataContainer.h>
11 #include <utl/FFTDataContainerAlgorithm.h>
12 #include <utl/RadioTraceUtilities.h>
13 
14 #include <evt/Event.h>
15 #include <evt/ShowerRRecData.h>
16 #include <evt/ShowerRecData.h>
17 #include <evt/ShowerSRecData.h>
18 #include <evt/ShowerFRecData.h>
19 #include <evt/ShowerSimData.h>
20 
21 #include <revt/REvent.h>
22 #include <revt/Header.h>
23 #include <revt/Station.h>
24 #include <revt/Channel.h>
25 #include <revt/StationRecData.h>
26 #include <revt/StationSimData.h>
27 
28 #include <TVector3.h>
29 
30 
31 using namespace utl;
32 
33 
35 
38  {
39  Branch topBranch = fwk::CentralConfig::GetInstance()->GetTopBranch("RdStationSimPulseFinder");
40  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
41  topBranch.GetChild("LowerCutoffFrequency").GetData(fLowerCutoffFrequency);
42  topBranch.GetChild("UpperCutoffFrequency").GetData(fUpperCutoffFrequency);
43  topBranch.GetChild("ApplyBandpassFilter").GetData(fApplyBandpassFilter);
44  topBranch.GetChild("UseHilbertEnvelope").GetData(fUseHilbertEnvelope);
45  topBranch.GetChild("SignalIntegrationWindowSize").GetData(fSignalIntegrationWindowSize);
46  topBranch.GetChild("ReferenceShower").GetData(fReferenceShower);
47 
48  std::ostringstream info;
49  info << "\n\tApply bandpass filter: " << fApplyBandpassFilter
50  << " (" << fLowerCutoffFrequency / MHz << " - " << fUpperCutoffFrequency / MHz << ") MHz"
51  << "\n\tUse hilbert envelope: " << fUseHilbertEnvelope
52  << "\n\tSize of the signal integration window: " << fSignalIntegrationWindowSize / ns << " ns"
53  << "\n\tUse reference direction for coorindate transformation from: " << fReferenceShower << "\n";
54  INFOFinal(info);
55 
56  return eSuccess;
57  }
58 
59 
61  RdStationSimPulseFinder::Run(evt::Event& event)
62  {
63  auto& rEvent = event.GetREvent();
64  const TimeStamp& rEventTime = rEvent.GetHeader().GetTime();
65 
66  std::ostringstream info;
67 
68  for (auto& station : rEvent.StationsRange()) {
69  info.str("");
70  info << "Getting StationRecData for station " << station.GetId();
71  INFODebug(info);
72 
73  // create has sim data when not done yet
74  if (!station.HasSimData()) {
75  station.MakeSimData();
76  }
77 
78  auto& stationSimData = station.GetSimData();
79  auto efieldData = station.GetFFTDataContainer();
80  auto& spectrum = efieldData.GetFrequencySpectrum();
81 
82  // apply the bandpass filter
83  if (fApplyBandpassFilter) {
84  for (unsigned int i = 0; i < spectrum.GetSize(); ++i) {
85  if ((efieldData.GetFrequencyOfBin(i) < fLowerCutoffFrequency) ||
86  (efieldData.GetFrequencyOfBin(i) > fUpperCutoffFrequency)) {
87  spectrum[i][0] = std::complex<double>(0., 0.);
88  spectrum[i][1] = std::complex<double>(0., 0.);
89  spectrum[i][2] = std::complex<double>(0., 0.);
90  }
91  }
92  }
93 
94  // get trace without envelope
95  const revt::StationTimeSeries& stationTrace = efieldData.GetConstTimeSeries();
96 
97  // apply envelope
98  revt::StationTimeSeries stationTraceForPeakFinding;
99  if (fUseHilbertEnvelope) {
100  INFODebug("Applying Hilbert envelope");
101 
102  auto efieldDataEnvelope = efieldData;
103  FFTDataContainerAlgorithm::HilbertEnvelope(efieldDataEnvelope);
104  stationTraceForPeakFinding = efieldDataEnvelope.GetConstTimeSeries();
105  }
106  else {
107  stationTraceForPeakFinding = stationTrace;
108  }
109 
110  // searching for pulse
111  unsigned int peakInt = 0;
112  double peakAmplitude = 0;
113  double peakTime = 0;
114  double peakTimeError = 0;
115  const double windowstart = 0;
116  const double windowstop = stationTraceForPeakFinding.GetStop() * stationTraceForPeakFinding.GetBinning();
117  INFODebug("Finding pulse ...");
118  RadioTraceUtilities::Pulsefinder(stationTraceForPeakFinding, peakAmplitude, peakTime, peakTimeError,
119  windowstart, windowstop, peakInt);
120 
121  info.str("");
122  info << "Setting SimPulseTime of station " << station.GetId() << " to " << peakTime
123  << " (sample " << peakInt << ")" << " and SimPulseAmplitude to " << peakAmplitude;
124  INFOIntermediate(info);
125 
126  if (!peakAmplitude) {
127  info.str("");
128  info << "No sim pulse found for station " << station.GetId();
129  INFOIntermediate(info);
130  continue;
131  }
132 
133  const TimeInterval traceStartTime = station.GetRawTraceStartTime() - rEventTime;
134  stationSimData.SetParameter(revt::eTraceStartTime, traceStartTime);
135 
136  stationSimData.SetParameter(revt::eSignal, peakAmplitude);
137  stationSimData.SetParameter(revt::eSignalTime, peakTime + traceStartTime);
138 
139  // calculating E-field vector
140  double maxPeak = 0;
141  unsigned int maxPol = 0;
142  for (unsigned int j = 0; j <= 2; ++j) {
143  for (unsigned int i = 0; i < stationTrace.GetSize(); ++i) {
144  if (fabs(stationTrace[i][j]) > maxPeak) {
145  maxPeak = fabs(stationTrace[i][j]);
146  maxPol = j;
147  }
148  }
149  }
150 
151  double tMaxAmp = 0;
152  unsigned int tMaxPos = 0;
153  double peakSearchWindow = 20. * ns;
154  for (unsigned int i = peakInt + peakSearchWindow / stationTrace.GetBinning();
155  i > (peakInt - peakSearchWindow / stationTrace.GetBinning()); --i) {
156  if (fabs(stationTrace[i][maxPol]) > tMaxAmp) {
157  tMaxAmp = fabs(stationTrace[i][maxPol]);
158  tMaxPos = i;
159  }
160  }
161 
162  // first we calculated the FWHM
163  unsigned int FWHMlowerBound = 0;
164  unsigned int FWHMupperBound = 0;
165  for (unsigned int i = tMaxPos; i > 0; --i) {
166  if (stationTraceForPeakFinding[i].GetMag() < peakAmplitude * .5) {
167  FWHMlowerBound = i;
168  break;
169  }
170  }
171 
172  if (FWHMlowerBound == 0) {
173  INFODebug("FWHMLowerBound is 0. This may mean that something went wrong");
174  }
175 
176  for (unsigned int i = tMaxPos; i < stationTrace.GetSize(); ++i) {
177  if (stationTraceForPeakFinding[i].GetMag() < peakAmplitude * .5) {
178  FWHMupperBound = i;
179  break;
180  }
181  }
182 
183  if (FWHMupperBound == stationTrace.GetSize()) {
184  INFODebug("FWHMupperBound is the last entry in the station trace. This may mean that something went wrong");
185  }
186 
187  // now we know over which interval to integrate. Continue with calculating the average E-field vector
188  TVector3 initialGuess(stationTrace[peakInt][0], stationTrace[peakInt][1], stationTrace[peakInt][2]);
189  TVector3 meanEField(0, 0, 0);
190  for (unsigned int i = FWHMlowerBound; i < FWHMupperBound; ++i) {
191  TVector3 currentEField(stationTrace[i][0], stationTrace[i][1], stationTrace[i][2]);
192  if (currentEField.Angle(initialGuess) > 90. * degree) {
193  currentEField *= -1;
194  }
195  meanEField += currentEField;
196  }
197  meanEField.SetMag(peakAmplitude);
198 
199  info.str("");
200  info << "Sim E-field vector for this station is (" << meanEField[0] << ","
201  << meanEField[1] << "," << meanEField[2] << ").";
202  INFODebug(info);
203 
204  stationSimData.SetParameter(revt::eEFieldVectorEW, meanEField[0]);
205  stationSimData.SetParameter(revt::eEFieldVectorNS, meanEField[1]);
206  stationSimData.SetParameter(revt::eEFieldVectorV, meanEField[2]);
207 
208  // get reference geometry
209  Point coreSite;
210  Vector showerAxis;
211  if (fReferenceShower == "Reference") {
212  const evt::ShowerRRecData& recShower = event.GetRecShower().GetRRecShower();
213  coreSite = recShower.GetReferenceCorePosition(event);
214  showerAxis = recShower.GetReferenceAxis(event);
215  }
216  if (fReferenceShower == "SD") {
217  const evt::ShowerSRecData& recShower = event.GetRecShower().GetSRecShower();
218  coreSite = recShower.GetCorePosition();
219  showerAxis = recShower.GetAxis();
220  }
221  if (fReferenceShower == "FD") {
222  const evt::ShowerFRecData& recShower = event.GetRecShower().GetFRecShower();
223  coreSite = recShower.GetCorePosition();
224  showerAxis = recShower.GetAxis();
225  }
226  if (fReferenceShower == "MC") {
227  const evt::ShowerSimData& recShower = event.GetSimShower();
228  coreSite = recShower.GetPosition();
229  showerAxis = recShower.GetDirection();
230  }
231 
232  // init trace container
233  revt::ChannelTimeSeries stationChannel;
234  stationChannel.SetBinning(stationTrace.GetBinning());
235 
236  // transformation in vxB vxvxB system
237  const auto coreCS = fwk::LocalCoordinateSystem::Create(coreSite);
238  const auto localMagneticField = fwk::MagneticFieldModel::instance().GetMagneticFieldVector(
239  coreSite, rEventTime.GetGPSSecond());
240  const auto csTrans = RadioGeometryUtilities(showerAxis, coreCS, localMagneticField);
241  TraceV3D traceShowerPlane = csTrans.GetTraceInShowerPlaneVxB(stationTrace);
242 
243  // loop over polarisations
244  double integratedSignal = 0;
245  for (unsigned int i = 0; i <= 2; ++i) {
246  integratedSignal = 0;
247  stationChannel.Clear();
248 
249  if (i == 0) {
250  for (const auto& element : stationTrace) {
251  stationChannel.PushBack(element.GetMag());
252  }
253  } else {
254  for (revt::StationTimeSeries::SizeType j = 0; j < traceShowerPlane.GetSize(); ++j) {
255  stationChannel.PushBack(traceShowerPlane[j][i - 1]);
256  }
257  }
258 
259  // calculation of energy fluence
260  double integratedNoisePowerFixedWidthStartTime = 0;
261  double integratedNoisePowerFixedWidthStopTime = 0;
262  RadioTraceUtilities::PulseFixedWindowIntegrator(stationChannel, peakInt, fSignalIntegrationWindowSize,
263  integratedSignal, integratedNoisePowerFixedWidthStartTime, integratedNoisePowerFixedWidthStopTime, true);
264  const double energyFluence = integratedSignal * kConversionRadioSignalToEnergyFluence;
265 
266  if (i == 0) {
267  stationSimData.SetParameter(revt::eSignalEnergyFluenceMag, energyFluence);
268  } else if (i == 1) {
269  stationSimData.SetParameter(revt::eSignalEnergyFluenceVxB, energyFluence);
270  } else {
271  stationSimData.SetParameter(revt::eSignalEnergyFluenceVxVxB, energyFluence);
272  }
273  }
274  }
275 
276  return eSuccess;
277  }
278 
279 
281  RdStationSimPulseFinder::Finish()
282  {
283  return eSuccess;
284  }
285 
286 }
utl::Point GetReferenceCorePosition(const Event &event) const
Returning the reference core position depending on the corresponding flag.
Point object.
Definition: Point.h:32
static void PulseFixedWindowIntegrator(const utl::Trace< double > &channeltrace, unsigned int sample, double integrationTime, double &integratedSignal, double &signalWindowStart, double &signalWindowStop, const bool usePower)
static void HilbertEnvelope(FFTDataContainer< C, T, F > &container)
applies a HilbertEnvelope to the time series data
constexpr double MHz
Definition: AugerUnits.h:159
Interface class to access to the SD Reconstruction of a Shower.
SizeType GetStop() const
Get valid data stop bin.
Definition: Trace.h:148
Interface class to access to the RD Reconstruction of a Shower.
double GetBinning() const
size of one slot
Definition: Trace.h:138
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
#define INFOIntermediate(y)
Definition: VModule.h:162
Class representing a document branch.
Definition: Branch.h:107
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
std::vector< T >::size_type SizeType
Definition: Trace.h:58
static MagneticFieldModel & instance()
const utl::Point & GetPosition() const
Get the position of the shower core.
static utl::Vector GetMagneticFieldVector(const utl::Point &position, const utl::TimeStamp &time)
returns the magnetic field at a specific place at a specific time
constexpr double degree
static void Pulsefinder(const utl::Trace< double > &channeltrace, double &peakAmplitude, double &peakTime, double &peakTimeError, double signalSearchWindowStart, double signalSearchWindowStop, unsigned int &sample)
void Clear()
Definition: Trace.h:158
const utl::Vector & GetAxis() const
SizeType GetSize() const
Definition: Trace.h:156
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
#define INFODebug(y)
Definition: VModule.h:163
void SetBinning(const double binning)
Definition: Trace.h:139
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
Definition: Trace-fwd.h:19
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
const utl::Point & GetCorePosition() const
constexpr double kConversionRadioSignalToEnergyFluence
utl::Vector GetReferenceAxis(const Event &event) const
Returning the referencedirection depending on the corresponding flag.
constexpr double ns
Definition: AugerUnits.h:162
#define INFOFinal(y)
Definition: VModule.h:161
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
void PushBack(const T &value)
Insert a single value at the end.
Definition: Trace.h:119
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.

, generated on Tue Sep 26 2023.