5 #include <fwk/CentralConfig.h>
6 #include <fwk/LocalCoordinateSystem.h>
7 #include <fwk/CoordinateSystemRegistry.h>
9 #include <det/Detector.h>
10 #include <rdet/RDetector.h>
12 #include <utl/ErrorLogger.h>
13 #include <utl/Reader.h>
14 #include <utl/config.h>
15 #include <utl/PhysicalConstants.h>
16 #include <utl/AxialVector.h>
18 #include <utl/ErrorLogger.h>
20 #include <evt/Event.h>
21 #include <evt/ShowerRecData.h>
22 #include <evt/ShowerRRecData.h>
23 #include <evt/ShowerRRecDataQuantities.h>
25 #include <revt/REvent.h>
26 #include <revt/Station.h>
27 #include <revt/Header.h>
28 #include <revt/StationRecData.h>
29 #include <revt/StationRRecDataQuantities.h>
31 #include <CLHEP/Matrix/Matrix.h>
32 #include <CLHEP/Matrix/Vector.h>
42 #define OUT(x) if ((x) <= fInfoLevel) cerr << " "
45 using CLHEP::HepMatrix;
46 using CLHEP::HepVector;
50 REvent* RdScintPlaneFit::fgCurrentREvent;
51 Point RdScintPlaneFit::fgBarycenter;
54 Point RdScintPlaneFit::fgCoordinateOrigin;
55 double RdScintPlaneFit::fgMeanEventTime(0);
61 os <<
'(' << g.GetX(cs) /
meter <<
", " << g.GetY(cs) /
meter <<
", " << g.GetZ(cs) /
meter <<
") [m]";
73 INFO(
"RdScintPlaneFit::Init()");
80 fMinuitOutput = (fInfoLevel >= eMinuit) ?
true :
false;
82 topBranch.
GetChild(
"minNumberOfStations").
GetData(fMinNumberOfStations);
83 topBranch.
GetChild(
"allowUnphysicalCosines").
GetData(fAllowUnphysicalCosines);
96 const Vector approx_axis = (reuseFit ?
Vector(fit.
u, fit.
v, fit.
w, fgLocalCS) : Vector());
98 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
115 for(
REvent::StationIterator sIt = fgCurrentREvent->StationsBegin(); sIt != fgCurrentREvent->StationsEnd(); ++sIt) {
120 const double x = sPos.
GetX(fgLocalCS);
122 const double y = sPos.
GetY(fgLocalCS);
127 const double t = sRec.
GetParameter(eAERAScintStationSignalTime) - fgMeanEventTime;
128 const double invSigma2 = 1. / (5 * 5);
130 const double x_s = x * invSigma2;
135 const double y_s = y * invSigma2;
164 INFO(
"Matrix inversion failed.");
174 const HepVector
p = mat * k;
175 double w2 = 1 -
Sqr(p[0]) -
Sqr(p[1]);
178 WARNING(
"Unphysical direction cosines");
179 if(fAllowUnphysicalCosines) {
180 WARNING(
"Setting z-compenent of the shower axis to 0");
209 <<
"eContinueLoop: No REvent, so no reconstruction"
211 return eContinueLoop;
214 fgCurrentREvent = &
event.GetREvent();
217 const det::Detector& detector = det::Detector::GetInstance();
224 int nStations = rShower.
GetParameter(eNumberOfAERAScintStationWithPulseFound);
227 if(nStations < fMinNumberOfStations) {
228 OUT(eFinal) <<
"eContinueLoop: Not enough stations."
231 return eContinueLoop;
240 for(
REvent::StationIterator sIt = fgCurrentREvent->StationsBegin(); sIt != fgCurrentREvent->StationsEnd(); ++sIt) {
246 const double weight =
sqrt(sRec.
GetParameter(eAERAScintStationSignalHeight));
249 timeSum += weight * sRec.
GetParameter(eAERAScintStationSignalTime);
254 timeSum /= weightSum;
256 fgMeanEventTime= rShower.
GetParameter(eBaryTimeAERAScint);
257 fgBaryTime = rShower.
GetParameter(eBaryTimeAERAScint) + timeSum;
264 fgLocalCS = LocalCoordinateSystem::Create(fgBarycenter);
266 OUT(eIntermediate) <<
"# candidate stations = "
267 << nStations << endl;
271 OUT(eFinal) <<
"eContinueLoop: Not Bary Data available!."
274 return eContinueLoop;
278 OUT(eIntermediate) <<
"barycenter = "
279 <<
ToString(fgBarycenter, siteCS) <<
" (site)" <<
NL
281 << timeSum /
nanosecond <<
" [ns] (to event time)" << endl;
283 OUT(eObscure) <<
"local/site zenith angle diff. = "
284 << acos(
Vector(0, 0, 1, fgLocalCS) *
Vector(0, 0, 1, siteCS)) /
degree <<
" [deg]" << endl;
294 <<
"eContinueLoop: Linear fit was not succesfull"
296 return eContinueLoop;
304 bool useNonLinearFit(
false);
306 if(PlaneFit3DDriver(fitNonlin) ==
eSuccess) {
307 OUT(eIntermediate) <<
"Stage "
308 << fitLin.
stage <<
": linear plane fit" <<
NL
310 << fitLin.
u <<
", " << fitLin.
v <<
", " << fitLin.
w <<
") (bary)" <<
NL
316 << fitLin.
ct0 /
meter <<
" [m]" << endl;
317 useNonLinearFit =
true;
318 finalFitResult = fitNonlin;
322 <<
" Nonlinear fit failed, using linear approximation."
324 finalFitResult = fitLin;
328 const Vector axis(finalFitResult.
u, finalFitResult.
v, finalFitResult.
w, fgLocalCS);
336 CalculateTimeResidual(axis, finalFitResult.
ct0, chi2);
338 const int angleNDOF = nStations - 3;
342 OUT(eFinal) <<
"Stage "
343 << finalFitResult.
stage <<
": " << (useNonLinearFit ?
"3d" :
"linear") <<
" plane fit" <<
NL
345 << finalFitResult.
u <<
", " << finalFitResult.
v <<
", " << finalFitResult.
w <<
") (bary)" <<
NL
347 << acos(finalFitResult.
w) /
degree <<
" +/- " <<
NL
348 <<
" phi = " << atan2(finalFitResult.
v, finalFitResult.
u) /
degree <<
" +/- " <<
NL
349 <<
" ct0 = " << finalFitResult.
ct0 /
meter <<
" [m]" <<
NL
362 minuit.mnexcm(
"SET PRINTOUT", argList, 1, errFlag);
363 minuit.mnexcm(
"SET NOWARNINGS", argList, 0, errFlag);
364 minuit.SetPrintLevel(-1);
367 if(fAllowUnphysicalCosines) {
368 minuit.SetFCN(RdScintPlaneFit::PlaneFit3DHorizonFnc);
370 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
371 minuit.mnparm(0,
"theta", acos(fit.
w), 0.01, 0, 0, errFlag);
372 minuit.mnparm(1,
"phi", atan2(fit.
v, fit.
u), 0.01, 0, 0, errFlag);
373 minuit.mnparm(2,
"ct0", fit.
ct0, 10 *
meter, 0, 0, errFlag);
375 minuit.SetFCN(RdScintPlaneFit::PlaneFit3DFnc);
377 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
378 minuit.mnparm(0,
"u", fit.
u, 0.01, 0, 0, errFlag);
379 minuit.mnparm(1,
"v", fit.
v, 0.01, 0, 0, errFlag);
380 minuit.mnparm(2,
"ct0", fit.
ct0, 10 *
meter, 0, 0, errFlag);
385 minuit.mnexcm(
"CALI", argList, 1, errFlag);
388 minuit.mnexcm(
"MINIMIZE", argList, 1, errFlag);
391 <<
" minuit minimize error: "
393 minuit.mnexcm(
"MINOS", argList, 0, errFlag);
396 <<
" minuit minos error: "
407 minuit.GetParameter(0, par1, foo);
408 minuit.GetParameter(1, par2, foo);
410 if(fAllowUnphysicalCosines) {
411 fit.
u = sin(par1) * cos(par2);
412 fit.
v = sin(par1) * sin(par2);
417 double w2 = 1 -
Sqr(fit.
u) -
Sqr(fit.
v);
419 OUT(eIntermediate) <<
" eFailure: Fit failed due to unphysical angle cosines."
426 minuit.GetParameter(2, fit.
ct0, foo);
430 minuit.mnemat(&emat[0][0], 3);
443 INFO(
"RdPlaneFit::Finish()");
447 void RdScintPlaneFit::PlaneFit3DFnc(
int& ,
double*
const ,
double& value,
double*
const par,
const int flag)
449 const double& u = par[0];
450 const double& v = par[1];
451 const double& ct0 = par[2];
452 static int nStations = 0;
453 static vector<double> sTiming;
454 static vector<double> sSignal;
455 static vector<Vector> sPosition;
456 static vector<double> sTimeSigma2;
465 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
467 for(
REvent::StationIterator sIt = fgCurrentREvent->StationsBegin(); sIt != fgCurrentREvent->StationsEnd(); ++sIt) {
476 sSignal.push_back(sRec.
GetParameter(eAERAScintStationSignalHeight));
482 nStations = sTiming.size();
486 const double w2 = 1 -
Sqr(u) -
Sqr(v);
493 const double w =
sqrt(w2);
495 const Vector axis(u, v, w, fgLocalCS);
499 for(
int i = 0; i < nStations; ++i)
500 chi2 +=
Sqr(sTiming[i] - ct0 + axis * sPosition[i]) / sTimeSigma2[i];
505 void RdScintPlaneFit::PlaneFit3DHorizonFnc(
int& ,
double*
const ,
double& value,
double*
const par,
const int flag)
507 const double& theta = par[0];
508 const double& phi = par[1];
509 const double& ct0 = par[2];
510 static int nStations = 0;
511 static vector<double> sTiming;
512 static vector<double> sSignal;
513 static vector<Vector> sPosition;
514 static vector<double> sTimeSigma2;
524 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
526 for(
REvent::StationIterator sIt = fgCurrentREvent->StationsBegin(); sIt != fgCurrentREvent->StationsEnd(); ++sIt) {
531 sSignal.push_back(sRec.
GetParameter(eAERAScintStationSignalHeight));
537 nStations = sTiming.size();
541 const Vector axis(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta), fgLocalCS);
545 for(
int i = 0; i < nStations; ++i)
546 chi2 +=
Sqr(sTiming[i] - ct0 + axis * sPosition[i]) / sTimeSigma2[i];
552 RdScintPlaneFit::CalculateTimeResidual(
const utl::Vector& axis,
const double ct0,
double& chi2)
const
556 const rdet::RDetector& rDetector = det::Detector::GetInstance().GetRDetector();
558 for(
REvent::StationIterator sIt = fgCurrentREvent->StationsBegin(); sIt != fgCurrentREvent->StationsEnd(); ++sIt) {
562 const double t = (sRec.
GetParameter(eAERAScintStationSignalTime) - fgMeanEventTime);
564 double timeResidual = t - t0 + (stLoc_c * axis);
565 sRec.
SetParameter(eAERAScintStationTimeResidual, timeResidual);
567 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)
bool HasParameter(const Parameter i) const
void SetParameterError(Parameter i, double value, bool lock=true)
constexpr T Sqr(const T &x)
Interface class to access Shower Reconstructed parameters.
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
#define INFO(message)
Macro for logging informational messages.
string ToString(const G &g, const CoordinateSystemPtr cs)
void Init()
Initialise the registry.
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)
boost::filter_iterator< StationFilter, AllStationIterator > StationIterator
Iterator over all (non-exculded) stations.
ShowerRRecData & GetRRecShower()
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.
Class representing a document branch.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
constexpr double nanosecond
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.
bool HasParameter(const Parameter i) const
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)
double GetParameter(const Parameter i) 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.
const Station & GetStation(const int stationId) const
Get station by Station Id.