RdHyperbolicWavefrontFit.cc
Go to the documentation of this file.
1 // Author: Qader Dorosti
2 // email: qader.dorosti@kit.edu
3 
5 #include "DetectorGeometry.h"
6 #include <fwk/CentralConfig.h>
7 #include <det/VManager.h>
8 #include <det/Detector.h>
9 #include <rdet/RDetector.h>
10 #include <utl/Branch.h>
11 #include <utl/String.h>
12 #include <utl/RadioGeometryUtilities.h>
13 
14 #include <evt/Event.h>
15 #include <evt/ShowerSRecData.h>
16 #include <evt/ShowerRecData.h>
17 #include <evt/ShowerRRecData.h>
18 #include <evt/ShowerSimData.h>
19 
20 #include <revt/REvent.h>
21 #include <revt/Header.h>
22 #include <revt/StationConstants.h>
23 #include <revt/StationRecData.h>
24 #include <revt/StationConstants.h>
25 
26 #include <utl/TraceAlgorithm.h>
27 
28 #include <sstream>
29 #include <algorithm>
30 #include <TMinuit.h>
31 #include <TRandom.h>
32 
33 #include <math.h>
34 
35 using namespace std;
36 using namespace fwk;
37 using namespace det;
38 using namespace utl;
39 using namespace evt;
40 using namespace revt;
41 
42 
44 
45  // global variables
46  CoordinateSystemPtr RdHyperbolicWavefrontFit::fgLocalCS;
47  utl::Vector RdHyperbolicWavefrontFit::gSAxis;
49  REvent* RdHyperbolicWavefrontFit::fgCurrentREvent = nullptr;
50  Event RdHyperbolicWavefrontFit::fgCurrentEvent;
51  unsigned int RdHyperbolicWavefrontFit::nPar = 0;
52  double RdHyperbolicWavefrontFit::gTime0 = 0;
53  unsigned int RdHyperbolicWavefrontFit::gStation0Id = 0;
54 
55 
58  {
59  INFODebug("RdHyperbolicWavefrontFit::Init()");
60 
61  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RdHyperbolicWavefrontFit");
62  topBranch.GetChild("InfoLevel").GetData(fInfoLevel);
63  topBranch.GetChild("UsedCore").GetData(fUsedCore);
64  topBranch.GetChild("DoCoreSearch").GetData(fDoCoreSearch);
65 
66  return eSuccess;
67  }
68 
69 
70  bool
71  Sorter(const std::vector<double>& x, const std::vector<double>& y)
72  {
73  return x[7] < y[7];
74  }
75 
76 
77  bool
78  SorterSt(const pair<double, int>& x, const pair<double, int>& y)
79  {
80  return x.first < y.first;
81  }
82 
83 
85  RdHyperbolicWavefrontFit::Run(Event& event)
86  {
87  INFODebug("RdHyperbolicWavefrontFit::Run()");
88 
89  // Check if there are no events at all
90  if (!event.HasREvent()) {
91  WARNING("eContinueLoop, No radio event found!");
92  return eContinueLoop;
93  }
94 
95  fgCurrentEvent = event;
96  fgCurrentREvent = &event.GetREvent();
97 
98  if (!event.GetRecShower().HasRRecShower()) {
99  event.GetRecShower().MakeRRecShower();
100  }
101 
102  if (fUsedCore == "MC"){
103  ShowerSimData& MCShower = event.GetSimShower();
104  // fill the minute gloabal variables
105  gCore = MCShower.GetPosition();
106  gSAxis = MCShower.GetDirection();
108  }
109 
110  if (fUsedCore == "SD") {
111  ShowerSRecData& showerSdRec = event.GetRecShower().GetSRecShower();
112  // fill the minute gloabal variables
113  gCore = showerSdRec.GetCorePosition();
114  gSAxis = - showerSdRec.GetAxis();
116  }
117 
118  if (fUsedCore == "RD") {
119  ShowerRRecData& showerRdRec = event.GetRecShower().GetRRecShower();
120  // fill the minute gloabal variables
121  gCore = showerRdRec.GetCorePosition();
122  gSAxis = - showerRdRec.GetAxis();
124  }
125 
126  const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
127 
128  //vector to store the station to find the earliest hit
129  vector<pair<double, int> > stationvec;
130 
131  //loop to find the earliest station registering signal
132  //and use the station as the reference station
133  for (REvent::SignalStationIterator sIt = fgCurrentREvent->SignalStationsBegin();
134  sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
135  const double time = sIt->GetRecData().GetParameter(revt::eSignalTime);
136  stationvec.push_back(make_pair(time, sIt->GetId()));
137  }
138 
139  //skip event with zero stations
140  if (stationvec.size() == 0){
141  return eContinueLoop;
142  }
143 
144  sort(stationvec.begin(), stationvec.end(), SorterSt);
145 
146  gTime0 = stationvec[0].first;
147  gStation0Id = stationvec[0].second;
148 
149  //vector to store the station to find the closest one to the shower axis
150  vector<pair<double, int> > stationVector;
151 
152  //loop to find the nearest station to the shower axis
153  //and use the station as the reference station
154  for (REvent::SignalStationIterator sIt = fgCurrentREvent->SignalStationsBegin();
155  sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
156  const Point& stationPosition = rDetector.GetStation(*sIt).GetPosition();
157  const double distance = utl::RadioGeometryUtilities::GetDistanceToAxis(gSAxis, gCore, stationPosition);
158  stationVector.push_back(make_pair(distance, sIt->GetId()));
159  }
160 
161  sort(stationVector.begin(), stationVector.end(), SorterSt);
162 
163  const Point posSt = rDetector.GetStation(stationVector[0].second).GetPosition();
165 
166  // define the centre of the core search area
167  const Point core(gCore.GetX(refStCS), gCore.GetY(refStCS), 0, refStCS);
168  gCore = core;
170 
171  //generate random numbers
172  TRandom rnd;
173 
174  double r = 0;
175  int Ncores = 1;
176  //get the core uncertainities
177  if (fDoCoreSearch && fUsedCore == "SD") {
178  const ShowerSRecData& showerSdRec = event.GetRecShower().GetSRecShower();
179  const double CoreErr_X = showerSdRec.GetCoreError().GetX(fgLocalCS);
180  const double CoreErr_Y = showerSdRec.GetCoreError().GetY(fgLocalCS);
181  r = 2 * sqrt(CoreErr_X*CoreErr_X + CoreErr_Y*CoreErr_Y);
182  Ncores = 3000;
183  }
184 
185  //vector storing the intermediate results
186  std::vector<std::vector<double>> result;
187 
188  FitParameters fit;
189 
190  //if the SD core/direction is used,
191  //generate 3000 random cores
192  //and fit wavefront for each core
193  for (int i = 0; i < Ncores; ++i) {
194  const double phi = rnd. Uniform(0, TMath::TwoPi());
195  const double radius = sqrt(rnd.Uniform(0, r*r));
196  const double x = radius*TMath::Cos(phi);
197  const double y = radius*TMath::Sin(phi);
198 
199  const Point core(x, y, 0, FixedfgLocalCS);
200 
201  // initialise the fit parameters
202  fit.gamma = 100;
203  fit.t0 = 0;
204  fit.NDF = 0;
205  fit.u = gSAxis.GetTheta(fgLocalCS);
206  fit.v = gSAxis.GetPhi(fgLocalCS);
207 
208  //double NDF = 0;
209  double weight = 0;
210  for (REvent::SignalStationIterator sIt = fgCurrentREvent->SignalStationsBegin();
211  sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
212  ++fit.NDF;
213  const double sigma_time_snr_ = 20.5 * pow(sIt->GetRecData().GetParameter(revt::eSignalToNoise), -1.03/1.1);
214  const double sTimeSigma2 = sigma_time_snr_ * sigma_time_snr_;
215  weight += 2 * sqrt(1 + 1/sTimeSigma2 * 5/4) - 2;
216  }
217 
218  weight /= fit.NDF;
219 
220  nPar = 2;
221  if (fit.NDF > 4)
222  nPar = 4;
223 
224  // fit the data points
225  TMinuit minuit(nPar);
226  int errFlag = 0;
227  double argList[10];
228  argList[0] = -1;
229  minuit.SetPrintLevel(-1);
230 
231  minuit.SetFCN(RdHyperbolicWavefrontFit::RdHyperbolicWavefrontFnc);
232  argList[0] = 1; // chi2
233  minuit.mnexcm("SET ERRORDEF", argList, 1, errFlag);
234  minuit.mnparm(0, "gamma", fit.gamma, 0.001, 0, 0, errFlag);
235  minuit.mnparm(1, "t0", fit.t0, 0.001, 0, 0, errFlag);
236  if (nPar == 4) {
237  minuit.mnparm(2, "u", fit.u, 0.01, 0, 0, errFlag);
238  minuit.mnparm(3, "v", fit.v, 0.01, 0, 0, errFlag);
239  }
240  // init fnc
241  argList[0] = 1;
242  minuit.mnexcm("CALI", argList, 1, errFlag);
243 
244  argList[0] = 500;
245  minuit.mnexcm("MINIMIZE", argList, 1, errFlag);
246  if (errFlag) {
247  INFOIntermediate(" minuit minimize error: " + errFlag);
248  minuit.mnexcm("MINOS", argList, 0, errFlag);
249  if (errFlag) {
250  INFOIntermediate(" minuit minimize error: " + errFlag);
251  break;
252  }
253  }
254 
255  minuit.GetParameter(0, fit.gamma, fit.gammaError);
256  minuit.GetParameter(1, fit.t0, fit.t0Error);
257  if (nPar == 4) {
258  minuit.GetParameter(2, fit.u, fit.uError);
259  minuit.GetParameter(3, fit.v, fit.vError);
260  }
261 
262  double edm, errdef;
263  Int_t nvpar, nparx;
264  minuit.mnstat(fit.minChi, edm, errdef, nvpar, nparx, fit.status);
265 
266  //fill the vector with the intermediate results
267  const std::vector<double> vec({
268  fit.gamma, //gamma
269  fit.gammaError, // gamma error
270  fit.t0, // offset
271  fit.minChi/weight, // chi2
272  double(fit.NDF - nvpar), // NDF
273  gCore.GetX(FixedfgLocalCS), // x
274  gCore.GetY(FixedfgLocalCS), // y
275  fit.minChi / double(fit.NDF - nvpar) / weight, // decision parameter
276  fit.u, // u
277  fit.v // v
278  });
279 
280  result.push_back(vec);
281 
282  gCore = core;
283  fgLocalCS = fwk::LocalCoordinateSystem::Create(gCore);
284  }
285 
286  //find the best fit
287  sort(result.begin(), result.end(), Sorter);
288 
289  Point finalCore;
290  if (result.size() > 0) {
291  const auto& r0 = result.front();
292  fit.gamma = r0[0];
293  fit.gammaError = r0[1];
294  fit.minChi = r0[3];
295  fit.NDF = r0[4];
296  const Point core(r0[5], r0[6], 0, FixedfgLocalCS);
297  finalCore = core;
298  fit.u = r0[8];
299  fit.v = r0[9];
300  fit.t0 = r0[2];
301  }
302 
303  const utl::CoordinateSystemPtr referenceCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
304 
305  // store the fit results
306  if (!event.HasRecShower()) {
307  event.MakeRecShower();
308  }
309  if (!event.GetRecShower().HasRRecShower()) {
310  event.GetRecShower().MakeRRecShower();
311  }
312  ShowerRRecData& showerReco = event.GetRecShower().GetRRecShower();
313 
314  const CoordinateSystemPtr localCS = fwk::LocalCoordinateSystem::Create(finalCore);
315  utl::Vector axis(1, fit.u, fit.v, localCS, Vector::kSpherical);
316  axis = -axis;
317 
318  //calculates residuals and fill them in station rec
319  CalculateTimeResidual(axis, fit.gamma, fit.t0);
320 
321  showerReco.SetParameter(eFitSuccess, 1);
322  showerReco.SetParameter(eWaveFitNDF, fit.NDF);
323  showerReco.SetParameter(eWaveFitChi2, fit.minChi);
324  showerReco.SetParameter(eWaveFrontModel, ShowerRRecData::kHyperbolicWaveFit);
325 
326  //#warning TODO: Set covariances!!!
327 
328  showerReco.SetParameter(eCoreX, finalCore.GetX(referenceCS));
329  showerReco.SetParameter(eCoreY, finalCore.GetY(referenceCS));
330  showerReco.SetParameter(eCoreZ, finalCore.GetZ(referenceCS));
331  showerReco.SetParameter(eShowerAxisX, axis.GetX(referenceCS));
332  showerReco.SetParameter(eShowerAxisY, axis.GetY(referenceCS));
333  showerReco.SetParameter(eShowerAxisZ, axis.GetZ(referenceCS));
334  showerReco.SetParameter(eGammaHyperbolicParam, fit.gamma);
335  showerReco.SetParameterError(eGammaHyperbolicParam, fit.gammaError);
336  showerReco.SetParameter(eHyperbolicWfFitChi2, fit.minChi);
337  showerReco.SetParameter(eHyperbolicWfFitNDF, fit.NDF);
338  showerReco.SetParameter(eRecStage, ShowerRRecData::kHyperbolicWaveFit);
339 
340  return eSuccess;
341  }
342 
343 
345  RdHyperbolicWavefrontFit::Finish()
346  {
347  return eSuccess;
348  }
349 
350 
351  void
352  RdHyperbolicWavefrontFit::RdHyperbolicWavefrontFnc(int& nPar, double* const /*grad*/, double& value, double* const par,
353  const int /*flag*/)
354  {
355  //fit parameters
356  const double& gamma = par[0];
357  const double& t0 = par[1];
358  double theta = gSAxis.GetTheta(fgLocalCS);
359  double phi = gSAxis.GetPhi(fgLocalCS);
360  if (nPar == 4) {
361  theta = par[2];
362  phi = par[3];
363  }
364 
365  const utl::Vector axis(1, theta, phi, fgLocalCS, Vector::kSpherical);
366 
367  //M-estimator
368  double Mscore = 0;
369 
370  const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
371 
372  for (REvent::SignalStationIterator sIt = fgCurrentREvent->SignalStationsBegin();
373  sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) { //loop over signal stations
374 
375  //const StationRecData& sRec = sIt->GetRecData();
376  const double sigma_time_snr_ = 20.5 * pow(sIt->GetRecData().GetParameter(revt::eSignalToNoise), -1.03/1.1);
377  const double sTimeSigma2 = sigma_time_snr_ * sigma_time_snr_;
378 
379  // calculate Rd station distance to shower core
380  const Point& stationPosition = rDetector.GetStation(*sIt).GetPosition();
381  const Vector VecDistanceToCore = stationPosition - rDetector.GetStation(gStation0Id).GetPosition();
382  // project the vector on shower direction
383  const double projVec = axis * VecDistanceToCore;
384  // calculate pulse arrival time
385  const double relativePulseTime = projVec / (kSpeedOfLight / nanosecond);
386  //double planeTime = relativePulseTime;
387  const double signalTime = sIt->GetRecData().GetParameter(revt::eSignalTime);
388  const double projTime = signalTime - gTime0 - relativePulseTime;
389 
390  const Vector a = stationPosition - gCore;
391  const Vector b = (axis*a)*axis;
392  const Vector perp = a - b;
393 
394  const double expectedTime = sqrt(1 + perp.GetMag() * perp.GetMag() / (gamma * gamma) ) * 9 - 9 + t0;
395  const double A = 1;//sIt->GetRecData().GetParameter(revt::eSignal)/1.e-6;
396 
397  const double dt = projTime - expectedTime;
398  Mscore += 2 * sqrt(1 + A * dt*dt / (2 * sTimeSigma2)) - 2;
399 
400  }
401 
402  value = Mscore;
403  }
404 
405  void
406  RdHyperbolicWavefrontFit::CalculateTimeResidual(const utl::Vector& axis, const double gamma, const double t0) const
407  {
408  const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
409  for(REvent::SignalStationIterator sIt = fgCurrentREvent->SignalStationsBegin(); sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) { //loop over stations
410  StationRecData& sRec = sIt->GetRecData();
411  const double signal_time = sRec.GetParameter(eSignalTime);
412  const double sigma_signal_time = sRec.GetParameterError(eSignalTime);
413 
414  const Point& stationPosition = rDetector.GetStation(*sIt).GetPosition();
415  const Vector a = stationPosition - gCore;
416  const Vector b = (axis*a)*axis;
417  const Vector perp = a - b;
418  const double expectedTime = sqrt(1 + perp.GetMag() * perp.GetMag() / (gamma * gamma) ) * 9 - 9 + t0;
419 
420  sRec.SetParameter(eTimeResidual, signal_time - expectedTime);
421  sRec.SetParameterError(eTimeResidual, sigma_signal_time);
422  }
423  }
424 
425 }
Branch GetTopBranch() const
Definition: Branch.cc:63
Class to access station level reconstructed data.
void SetParameter(Parameter i, double value, bool lock=true)
utl::Vector GetAxis() const
Returns vector of the shower axis.
void SetParameterError(Parameter i, double value, bool lock=true)
Point object.
Definition: Point.h:32
static double GetDistanceToAxis(const utl::Vector &ShowerAxis, const utl::Point &CorePosition, const utl::Point &AntennaPosition)
computes the distance from the antenna position to the shower &quot;line&quot; defined by the core position and...
Interface class to access to the SD Reconstruction of a Shower.
bool HasRecShower() const
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
ShowerRecData & GetRecShower()
Interface class to access to the RD Reconstruction of a Shower.
double GetParameterError(const Parameter i) const
const utl::Vector & GetCoreError() const
void Init()
Initialise the registry.
revt::REvent & GetREvent()
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
bool HasREvent() const
double GetMag() const
Definition: Vector.h:58
bool Sorter(const std::vector< double > &x, const std::vector< double > &y)
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#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.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
constexpr double nanosecond
Definition: AugerUnits.h:143
const Data result[]
const utl::Point & GetPosition() const
Get the position of the shower core.
bool HasRRecShower() const
const double second
Definition: GalacticUnits.h:32
const utl::Vector & GetAxis() const
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
#define INFODebug(y)
Definition: VModule.h:163
bool SorterSt(const pair< double, int > &x, const pair< double, int > &y)
double GetParameter(const Parameter i) const
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
void SetParameterError(Parameter i, double value, bool lock=true)
void SetParameter(Parameter i, double value, bool lock=true)
Vector object.
Definition: Vector.h:30
const utl::Point & GetCorePosition() const
utl::Point GetCorePosition() const
returns pointer of the position vector of the core in the reference coor system
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
const int nPar
Definition: GeomAsym.h:37
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: RDetector.cc:141
boost::filter_iterator< SignalStationFilter, AllStationIterator > SignalStationIterator
Iterator over all signal stations.
Definition: REvent.h:109

, generated on Tue Sep 26 2023.