3 #include <fwk/CentralConfig.h>
4 #include <fwk/LocalCoordinateSystem.h>
5 #include <fwk/CoordinateSystemRegistry.h>
7 #include <det/Detector.h>
8 #include <rdet/RDetector.h>
10 #include <utl/ErrorLogger.h>
11 #include <utl/Reader.h>
12 #include <utl/config.h>
13 #include <utl/PhysicalConstants.h>
14 #include <utl/AxialVector.h>
16 #include <utl/ErrorLogger.h>
17 #include <utl/AnalyticCoordinateTransformator.h>
19 #include <evt/Event.h>
20 #include <evt/ShowerRecData.h>
21 #include <evt/ShowerRRecData.h>
22 #include <evt/ShowerRRecDataQuantities.h>
24 #include <revt/REvent.h>
25 #include <revt/Station.h>
26 #include <revt/Header.h>
27 #include <revt/StationRecData.h>
29 #include <CLHEP/Matrix/Matrix.h>
30 #include <CLHEP/Matrix/Vector.h>
41 using CLHEP::HepMatrix;
42 using CLHEP::HepVector;
48 REvent* RdPlaneFit::fgCurrentREvent;
49 Point RdPlaneFit::fgBarycenter;
52 Point RdPlaneFit::fgCoordinateOrigin;
53 double RdPlaneFit::fgMeanEventTime;
62 os <<
'(' << g.GetX(cs) /
meter <<
", " << g.GetY(cs) /
meter <<
", " << g.GetZ(cs) /
meter <<
") [m]";
74 fMinuitOutput = (fInfoLevel >= eInfoDebug) ?
true :
false;
76 topBranch.
GetChild(
"minNumberOfStations").
GetData(fMinNumberOfStations);
77 topBranch.
GetChild(
"allowUnphysicalCosines").
GetData(fAllowUnphysicalCosines);
79 const string yesnostr = topBranch.
GetChild(
"allowMultipleCalls").
Get<
string>();
80 fLockParameterStorage = (yesnostr ==
"no");
97 const Vector approx_axis = (reuseFit ?
Vector(fit.
u, fit.
v, fit.
w, fgLocalCS) : Vector());
98 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
112 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
113 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
115 const double x = sPos.
GetX(fgLocalCS);
116 const double y = sPos.
GetY(fgLocalCS);
119 const double t = sRec.
GetParameter(eSignalTime) - fgMeanEventTime;
123 const double x_s = x * invSigma2;
128 const double y_s = y * invSigma2;
157 INFO(
"Matrix inversion failed.");
167 const HepVector
p = mat * k;
168 double w2 = 1 -
Sqr(p[0]) -
Sqr(p[1]);
171 WARNING(
"Unphysical direction cosines");
172 if (fAllowUnphysicalCosines) {
173 WARNING(
"Setting z-compenent of the shower axis to 0");
201 return eContinueLoop;
204 fgCurrentREvent = &
event.GetREvent();
205 const REvent& rEvent = *fgCurrentREvent;
207 const det::Detector& detector = det::Detector::GetInstance();
214 ShowerRRecData& showerrrec =
event.GetRecShower().GetRRecShower();
218 fgLocalCS = LocalCoordinateSystem::Create(fgCoordinateOrigin);
221 err <<
"Problem when getting coordinate origin \n";
222 err <<
"Did you call the RdEventInitializer ? \n";
223 err <<
" Caught utl::NonExistentComponentException : " << e.
what();
224 err <<
"\n Will Break loop \n";
232 Vector barySum(0, 0, 0, fgLocalCS);
234 double weightSum = 0;
236 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
237 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
242 barySum += weight * (dStation.
GetPosition() - fgCoordinateOrigin);
248 info <<
"Number of signal stations = " << nStations;
252 if (nStations < fMinNumberOfStations) {
254 info <<
"eContinueLoop: Not enough stations." << endl;
257 event.GetRecShower().GetRRecShower().SetParameter(eFitSuccess, 0, fLockParameterStorage);
258 info <<
"Set FitSuccess to false.";
262 return eContinueLoop;
267 info <<
"eContinueLoop: sum of weights = 0" << endl;
270 event.GetRecShower().GetRRecShower().SetParameter(eFitSuccess, 0, fLockParameterStorage);
271 info <<
"Set FitSuccess to false.";
275 return eContinueLoop;
278 barySum /= weightSum;
279 timeSum /= weightSum;
280 fgMeanEventTime = timeSum;
281 fgBarycenter = barySum + fgCoordinateOrigin;
282 fgBaryTime = eventTime + timeSum;
289 info <<
"barycenter = " <<
ToString(fgBarycenter, siteCS) <<
" (site)" << std::endl
290 <<
"bary time = " << timeSum /
nanosecond <<
" [ns] (to event time)\n"
291 <<
"local/site zenith angle diff. = "
304 event.GetRecShower().GetRRecShower().SetParameter(eFitSuccess, 0, fLockParameterStorage);
308 return eContinueLoop;
317 bool nonLinearFitUsed =
false;
320 if (PlaneFit3DDriver(fitNonlin) ==
eSuccess) {
322 info <<
"\n\tStage " << fitLin.
stage <<
": linear plane fit"
323 <<
"\n\taxis = (" << fitLin.
u <<
", " << fitLin.
v <<
", " << fitLin.
w <<
") (bary)"
324 <<
"\n\ttheta = " << acos(fitLin.
w) /
degree
325 <<
"\n\tphi = " << atan2(fitLin.
v, fitLin.
u) /
degree
326 <<
"\n\tct0 = " << fitLin.
ct0 /
meter <<
" [m]";
327 nonLinearFitUsed =
true;
328 finalFitResult = fitNonlin;
330 info <<
" Nonlinear fit failed, using linear approximation.";
331 finalFitResult = fitLin;
337 const Vector axis(finalFitResult.
u, finalFitResult.
v, finalFitResult.
w, fgLocalCS);
338 showerrrec.
SetParameter(eShowerAxisX, axis.
GetX(fgLocalCS), fLockParameterStorage);
339 showerrrec.
SetParameter(eShowerAxisY, axis.
GetY(fgLocalCS), fLockParameterStorage);
340 showerrrec.
SetParameter(eShowerAxisZ, axis.
GetZ(fgLocalCS), fLockParameterStorage);
345 double thetaPhiCorrelation;
348 thetaError, phiError, thetaPhiCorrelation);
350 double theta = acos(finalFitResult.
w);
351 double phi = atan2(finalFitResult.
v, finalFitResult.
u);
355 double c11 = thetaError * thetaError;
356 double c22 = phiError * phiError;
357 double c12 = thetaPhiCorrelation * thetaError * phiError;
360 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(0, 0, r, theta, phi, c00, c11, c22, c01, c02, c12);
363 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(1, 1, r, theta, phi, c00, c11, c22, c01, c02, c12);
366 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(2, 2, r, theta, phi, c00, c11, c22, c01, c02, c12);
369 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(0, 1, r, theta, phi, c00, c11, c22, c01, c02, c12);
372 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(0, 2, r, theta, phi, c00, c11, c22, c01, c02, c12);
375 AnalyticCoordinateTransformator::GetCartesianCovarianceFromSpherical(1, 2, r, theta, phi, c00, c11, c22, c01, c02, c12);
385 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
386 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
395 CalculateTimeResidual(axis, finalFitResult.
ct0, chi2);
397 const int angleNDOF = nStations - 3;
398 showerrrec.
SetParameter(eWaveFitNDF, angleNDOF, fLockParameterStorage);
399 showerrrec.
SetParameter(eWaveFitChi2, chi2, fLockParameterStorage);
400 showerrrec.
SetParameter(eFitSuccess, 1, fLockParameterStorage);
403 info <<
"\n\tStage " << finalFitResult.
stage <<
": " << (nonLinearFitUsed ?
"3d" :
"linear") <<
" plane fit"
404 <<
"\n\taxis = (" << finalFitResult.
u <<
", " << finalFitResult.
v <<
", " << finalFitResult.
w <<
") (bary)"
405 <<
"\n\ttheta = " << acos(finalFitResult.
w) /
degree <<
" +/- "
407 <<
"\n\tphi = " << atan2(finalFitResult.
v, finalFitResult.
u) /
degree <<
" +/- "
409 <<
"\n\tct0 = " << finalFitResult.
ct0 /
meter <<
" [m]";
424 if (!fMinuitOutput) {
425 minuit.mnexcm(
"SET PRINTOUT", argList, 1, errFlag);
426 minuit.mnexcm(
"SET NOWARNINGS", argList, 0, errFlag);
427 minuit.SetPrintLevel(-1);
430 if (fAllowUnphysicalCosines) {
431 minuit.SetFCN(RdPlaneFit::PlaneFit3DHorizonFnc);
433 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
434 minuit.mnparm(0,
"theta", acos(fit.
w), 0.01, 0, 0, errFlag);
435 minuit.mnparm(1,
"phi", atan2(fit.
v, fit.
u), 0.01, 0, 0, errFlag);
436 minuit.mnparm(2,
"ct0", fit.
ct0, 10 *
meter, 0, 0, errFlag);
438 minuit.SetFCN(RdPlaneFit::PlaneFit3DFnc);
440 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
441 minuit.mnparm(0,
"u", fit.
u, 0.01, 0, 0, errFlag);
442 minuit.mnparm(1,
"v", fit.
v, 0.01, 0, 0, errFlag);
443 minuit.mnparm(2,
"ct0", fit.
ct0, 10 *
meter, 0, 0, errFlag);
450 minuit.mnexcm(
"CALI", argList, 1, errFlag);
453 minuit.mnexcm(
"MINIMIZE", argList, 1, errFlag);
456 info <<
"minuit minimize error: " << errFlag <<
'\n';
459 minuit.mnexcm(
"MINOS", argList, 0, errFlag);
462 info <<
"minuit minos error: " << errFlag <<
'\n';
474 minuit.GetParameter(0, par1, foo);
475 minuit.GetParameter(1, par2, foo);
477 if (fAllowUnphysicalCosines) {
478 fit.
u = sin(par1) * cos(par2);
479 fit.
v = sin(par1) * sin(par2);
484 double w2 = 1 -
Sqr(fit.
u) -
Sqr(fit.
v);
487 info <<
"eFailure: Fit failed due to unphysical angle cosines";
495 minuit.GetParameter(2, fit.
ct0, foo);
499 minuit.mnemat(&emat[0][0], 3);
518 RdPlaneFit::PlaneFit3DFnc(
int& ,
double*
const ,
double& value,
double*
const par,
const int flag)
520 const double& u = par[0];
521 const double& v = par[1];
522 const double& ct0 = par[2];
523 static int nStations = 0;
524 static vector<double> sTiming;
525 static vector<double> sSignal;
526 static vector<Vector> sPosition;
527 static vector<double> sTimeSigma2;
537 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
539 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
540 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
549 nStations = sTiming.size();
555 const double w2 = 1 -
Sqr(u) -
Sqr(v);
562 const double w =
sqrt(w2);
564 const Vector axis(u, v, w, fgLocalCS);
568 for (
int i = 0; i < nStations; ++i)
569 chi2 +=
Sqr(sTiming[i] - ct0 + axis * sPosition[i]) / sTimeSigma2[i];
576 RdPlaneFit::PlaneFit3DHorizonFnc(
int& ,
double*
const ,
double& value,
577 double*
const par,
const int flag)
579 const double& theta = par[0];
580 const double& phi = par[1];
581 const double& ct0 = par[2];
582 static int nStations = 0;
583 static vector<double> sTiming;
584 static vector<double> sSignal;
585 static vector<Vector> sPosition;
586 static vector<double> sTimeSigma2;
596 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
598 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
599 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
607 nStations = sTiming.size();
613 const Vector axis(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta), fgLocalCS);
617 for (
int i = 0; i < nStations; ++i)
618 chi2 +=
Sqr(sTiming[i] - ct0 + axis * sPosition[i]) / sTimeSigma2[i];
625 RdPlaneFit::CalculateTimeResidual(
const utl::Vector& axis,
const double ct0,
double& chi2)
629 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
631 for (
auto sIt = fgCurrentREvent->SignalStationsBegin();
632 sIt != fgCurrentREvent->SignalStationsEnd(); ++sIt) {
635 const double t = (sRec.
GetParameter(eSignalTime) - fgMeanEventTime);
637 double timeResidual = t - t0 + (stLoc_c * axis);
638 sRec.
SetParameter(eTimeResidual, timeResidual, fLockParameterStorage);
640 chi2 +=
pow(timeResidual / sigma_t,2);
Branch GetTopBranch() const
Class to access station level reconstructed data.
void SetParameter(Parameter i, double value, bool lock=true)
void SetParameterError(Parameter i, double value, bool lock=true)
double GetZenithError() const
returns the error of the zenith angle (from the wave fit)
constexpr T Sqr(const T &x)
Detector description interface for Station-related data.
StationRecData & GetRecData()
Get station level reconstructed data.
bool HasRecShower() const
Interface class to access to the Radio part of an event.
ShowerRecData & GetRecShower()
Interface class to access to the RD Reconstruction of a Shower.
double GetParameterError(const Parameter i) const
#define INFO(message)
Macro for logging informational messages.
string ToString(const G &g, const CoordinateSystemPtr cs)
void Init()
Initialise the registry.
Base class for exceptions trying to access non-existing components.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
utl::CoordinateSystemPtr GetSiteCoordinateSystem() const
Get the coordinate system for the site.
double pow(const double x, const unsigned int i)
double GetAzimuthError() const
returns the error of the azimuth angle (from the wave fit)
A TimeStamp holds GPS second and nanosecond for some event.
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.
boost::tuple< double, double, double > Triple
Coordinate triple for easy getting or setting of coordinates.
utl::Point GetCoordinateOrigin() const
void PropagateAxisErrors(const Vector::Triple &u_v_w, const Vector::Triple &sigma_u2_uv_v2, double &thetaError, double &phiError, double &thetaPhiCorrelation)
class to hold data at the radio Station level.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
constexpr double nanosecond
bool HasRRecShower() const
Header & GetHeader()
access to REvent Header
Top of the hierarchy of the detector description interface.
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
double GetParameter(const Parameter i) const
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.
void SetParameterError(Parameter i, double value, bool lock=true)
utl::CoordinateSystemPtr GetReferenceCoordinateSystem() const
Get the reference coordinate system used for analysis (usually PampaAmarilla for Auger) ...
void SetParameter(Parameter i, double value, bool lock=true)
const rdet::RDetector & GetRDetector() const
constexpr double kSpeedOfLight2
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void LinearFit(const vector< double > &x, const vector< double > &y, const vector< double > &ey, double &a0, double &a1, double &chi2)
Do a linear fit and return coefficients and chi2.
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
#define ERROR(message)
Macro for logging error messages.
const Station & GetStation(const int stationId) const
Get station by Station Id.
void SetParameterCovariance(Parameter i1, Parameter i2, double value, bool lock=true)
const char * what() const
std::exception will print this on crash