1 #include <utl/config.h>
4 #include <adst/RecEvent.h>
6 #include <utl/AugerUnits.h>
7 #include <utl/MathConstants.h>
8 #include <utl/PhysicalConstants.h>
9 #include <utl/AugerException.h>
10 #include <utl/ErrorLogger.h>
11 #include <utl/Transformation.h>
12 #include <utl/ReferenceEllipsoid.h>
13 #include <utl/PhysicalFunctions.h>
15 #include <fwk/CoordinateSystemRegistry.h>
17 #include <det/Detector.h>
18 #include <fdet/FDetector.h>
20 #include <fdet/Telescope.h>
21 #include <fdet/Camera.h>
22 #include <fdet/Pixel.h>
23 #include <fdet/Channel.h>
25 #include <atm/ProfileResult.h>
26 #include <atm/AttenuationResult.h>
27 #include <atm/InclinedAtmosphericProfile.h>
29 #include <utl/Point.h>
30 #include <utl/Vector.h>
31 #include <utl/AxialVector.h>
32 #include <utl/ReferenceEllipsoid.h>
34 #include <evt/Event.h>
35 #include <evt/GaisserHillas4Parameter.h>
36 #include <evt/ShowerFRecData.h>
37 #include "evt/ShowerRecData.h"
70 AverageErr(
const double x0,
const double x1,
const double x2)
72 const double e1 = x1 - x0;
73 const double e2 = x0 - x2;
81 SpaceAngle(
const double angularLength,
const FDEvent& fdEvent)
83 const double refAngle = 30*
degree;
85 const FdRecGeometry& fdRecGeometry = fdEvent.GetFdRecGeometry();
88 if (fdEvent.IsHybridEvent()) {
89 const double par = 0.213 *
degree;
90 const double alpha = 2.1;
91 const double offset = 0.185 *
degree;
92 return offset + par *
pow(refAngle/angularLength, alpha);
96 if (fdRecGeometry.HasPCGFData()) {
97 const double par = 0.266 *
degree;
98 const double alpha = 0.515;
99 const double offset = 0.265 *
degree;
100 return offset + par *
pow(refAngle/angularLength, alpha);
103 return std::numeric_limits<double>::infinity();
108 LongitudinalXmaxScanner::EstimateXmaxErrors(
const RecEvent& theRecEvent)
110 fLongitudinalScan.clear();
111 fErrorAtXmax.clear();
113 for (
auto iEye = theRecEvent.EyesBegin(); iEye != theRecEvent.EyesEnd(); ++iEye) {
115 fCalorimetricEnergy = iEye->GetFdRecShower().GetCalorimetricEnergy() *
eV;
116 if (fCalorimetricEnergy > 0) {
118 GetTelescopeProperties(iEye->GetEyeId());
120 if (FillLightFactors(*iEye)) {
121 CalculateXmaxUncertainties(*iEye);
135 LongitudinalXmaxScanner::FillLightFactors(
const FDEvent& fdEvent)
138 fGeomVariance.clear();
140 fViewingAngle.clear();
143 fPhotoElectronFactor.clear();
144 fNoiseVariance.clear();
145 fCloseToBoundary.clear();
146 fOutsideTelescope.clear();
151 const FdRecPixel& recPixel = fdEvent.GetFdRecPixel();
152 const double maxRMS = 60;
153 const int nAverageZetaPix = 2;
154 const double averagePhotonVariance =
155 pow(fmin(maxRMS, recPixel.GetMeanPixelRMS()), 2) * nAverageZetaPix;
156 const double averagePhotoElectronVariance =
157 averagePhotonVariance *
pow(fPhotonToPhotoElectron, 2);
158 fPhotoElectronBGRMS =
sqrt(averagePhotoElectronVariance/nAverageZetaPix);
160 const unsigned int eyeId = fdEvent.GetEyeId();
161 const FdRecShower& recShower = fdEvent.GetFdRecShower();
162 double zeta = fdEvent.GetFdRecApertureLight().GetZeta();
164 INFO(
"zeta not filled!!!");
167 const TVector3& adstCore = recShower.GetCoreSiteCS();
168 const TVector3& adstAxis = recShower.GetAxisSiteCS();
169 const Vector axis(adstAxis.X(), adstAxis.Y(), adstAxis.Z(), referenceCS);
170 const Point core(adstCore.X()*
m, adstCore.Y()*
m, adstCore.Z()*
m, referenceCS);
172 const Point& eyePos = detEye.GetPosition();
173 const Vector coreEyeVec = core - eyePos;
175 const FdRecGeometry& theGeometry = fdEvent.GetFdRecGeometry();
176 const double t0 = theGeometry.GetT0();
177 const double chi0 = theGeometry.GetChi0();
178 const double rp = theGeometry.GetRp();
189 const double maxDepth = distVsSlantDepth.
MaxX();
190 const double minDepth = distVsSlantDepth.
MinX();
192 const double xLow = recShower.GetXFOVMin() *
g/
cm2;
193 const double xUp = recShower.GetXFOVMax() *
g/
cm2;
195 const int nBins = int((xUp - xLow) / fDepthBinWidth);
196 const double dX = (xUp - xLow) / nBins;
199 for (
int i = 0; i < nBins+1; ++i) {
201 fDepth.push_back(currX);
203 const double thisX = currX - 0.5*dX;
204 const double nextX = currX + 0.5*dX;
206 if (thisX >= minDepth && thisX <= maxDepth &&
207 nextX >= minDepth && nextX <= maxDepth) {
209 const Point thisPoint = core - axis * distVsSlantDepth.
Y(thisX);
210 const Point nextPoint = core - axis * distVsSlantDepth.
Y(nextX);
211 const Point currPoint = core - axis * distVsSlantDepth.
Y(currX);
212 const Vector thisVec = thisPoint - eyePos;
213 const Vector nextVec = nextPoint - eyePos;
214 const Vector currVec = currPoint - eyePos;
215 const double chi_i =
Angle(currVec, coreEyeVec);
216 const double t_i = t0 + rp/
kSpeedOfLight * std::tan(0.5*(chi0 - chi_i));
217 fTime.push_back(t_i);
218 fViewingAngle.push_back(chi0 - chi_i);
219 const double chi_1 =
Angle(thisVec, coreEyeVec);
220 const double chi_2 =
Angle(nextVec, coreEyeVec);
221 const double t_1 = t0 + rp/
kSpeedOfLight * std::tan(0.5*(chi0 - chi_1));
222 const double t_2 = t0 + rp/
kSpeedOfLight * std::tan(0.5*(chi0 - chi_2));
223 fDeltaAngle.push_back(fabs(chi_1 - chi_2));
224 fDeltaTime.push_back(fabs(t_1 - t_2));
226 const double lightFactor =
227 CalculateLightFactor(thisPoint, nextPoint, eyeId);
228 const double timeLength =
229 CalculateTimeLength(thisPoint, nextPoint, eyeId);
230 const auto telAndPixId = GetTelescopeAndPixelId(currVec, eyeId);
231 const auto telId = telAndPixId[0];
233 fCloseToBoundary.push_back(IsNearBorder(currVec, eyeId, telId, zeta));
234 fOutsideTelescope.push_back(
false);
235 const double area = detEye.GetTelescope(telId).GetDiaphragmArea();
236 const double photoElectronFactor =
237 lightFactor * area * fPhotonToPhotoElectron;
238 fPhotoElectronFactor.push_back(photoElectronFactor);
244 const double calConst =
246 const double photonVar = adcVar *
pow(calConst, 2);
247 const double var =
pow(fPhotonToPhotoElectron, 2) * photonVar;
249 const double nTimeBins = timeLength / timeBin;
250 fNoiseVariance.push_back(nTimeBins * var);
261 fNoiseVariance.push_back(timeLength/timeBin *
262 averagePhotoElectronVariance);
265 fCloseToBoundary.push_back(
true);
266 fOutsideTelescope.push_back(
true);
267 fPhotoElectronFactor.push_back(0);
268 fNoiseVariance.push_back(0);
271 fPhotoElectronFactor.push_back(-1);
273 fViewingAngle.push_back(-1);
274 fDeltaAngle.push_back(-1);
275 fDeltaTime.push_back(-1);
276 fNoiseVariance.push_back(999);
277 fCloseToBoundary.push_back(
true);
278 fOutsideTelescope.push_back(
true);
289 LongitudinalXmaxScanner::GetChangedDepth(
const FDEvent& fdEvent,
291 const double nSigChi0,
293 const double nSigPhi,
294 const double nSigTheta)
296 const unsigned int eyeId = fdEvent.GetEyeId();
297 const det::Detector& detector = det::Detector::GetInstance();
301 const FdRecGeometry& theGeometry = fdEvent.GetFdRecGeometry();
303 const double t0 = theGeometry.GetT0() + nSigT0 * theGeometry.GetT0Error();
304 const double chi0 = theGeometry.GetChi0() + nSigChi0 * theGeometry.GetChi0Error();
305 const double rp = theGeometry.GetRp() + nSigRp * theGeometry.GetRpError();
309 const double sdpTheta = theGeometry.GetSDPTheta() + nSigTheta * theGeometry.GetSDPThetaError();
310 const double sdpPhi = theGeometry.GetSDPPhi() + nSigPhi * theGeometry.GetSDPPhiError();
311 const Vector sdp =
Vector(1, sdpTheta, sdpPhi, eyeCS, Vector::kSpherical);
313 const Vector vertical(0,0,1, eyeCS);
316 const Transformation rot(Transformation::Rotation(-chi0, sdp, eyeCS));
317 const Vector axis(rot * horizontalInSDP);
318 const Vector coreEyeVec = rp / sin(
kPi - chi0) * horizontalInSDP;
327 return vector<double>();
330 const double minDistance = slantDepthProfile->
MinX();
331 const double maxDistance = slantDepthProfile->
MaxX();
333 vector<double> depthVec;
334 for (
unsigned int i = 0; i < fTime.size(); ++i) {
335 const double t_i = fTime[i];
336 double depth = -1*
g/
cm2;
338 const double chi_i = chi0 - 2*atan(
kSpeedOfLight / rp * (t_i - t0));
339 const double distance = -coreEyeVec.
GetMag() * sin(chi_i) / sin(chi0 - chi_i);
340 if (distance > minDistance && distance < maxDistance)
341 depth = slantDepthProfile->
Y(distance);
343 depthVec.push_back(depth);
351 LongitudinalXmaxScanner::PropagateGeometryUncertainty(
const FDEvent& fdEvent)
355 vector<double> depthDefault = GetChangedDepth(fdEvent,0,0,0,0,0);
356 vector<double> depthRp1 = GetChangedDepth(fdEvent,1,0,0,0,0);
357 vector<double> depthRp2 = GetChangedDepth(fdEvent,-1,0,0,0,0);
358 vector<double> depthChi1 = GetChangedDepth(fdEvent,0,1,0,0,0);
359 vector<double> depthChi2 = GetChangedDepth(fdEvent,0,-1,0,0,0);
360 vector<double> depthT01 = GetChangedDepth(fdEvent,0,0,1,0,0);
361 vector<double> depthT02 = GetChangedDepth(fdEvent,0,0,-1,0,0);
362 vector<double> depthPhi1 = GetChangedDepth(fdEvent,0,0,0,1,0);
363 vector<double> depthPhi2 = GetChangedDepth(fdEvent,0,0,0,-1,0);
364 vector<double> depthTheta1 = GetChangedDepth(fdEvent,0,0,0,0,1);
365 vector<double> depthTheta2 = GetChangedDepth(fdEvent,0,0,0,0,-1);
368 const unsigned int nDepth = fDepth.size();
369 bool allValid = (depthDefault.size() == nDepth &&
370 depthRp1.size() == nDepth &&
371 depthRp2.size() == nDepth &&
372 depthChi1.size() == nDepth &&
373 depthChi2.size() == nDepth &&
374 depthT01.size() == nDepth &&
375 depthT02.size() == nDepth &&
376 depthPhi1.size() == nDepth &&
377 depthPhi2.size() == nDepth &&
378 depthTheta1.size() == nDepth &&
379 depthTheta2.size() == nDepth);
382 INFO(
" GetChangedDepth failed!");
383 for (
unsigned int i = 0; i < nDepth; ++i)
389 const FdRecGeometry& theGeometry = fdEvent.GetFdRecGeometry();
390 const double rhoRT = theGeometry.GetRpT0Correlation();
391 const double rhoRC = theGeometry.GetChi0RpCorrelation();
392 const double rhoCT = theGeometry.GetChi0T0Correlation();
393 const double rhoPT = theGeometry.GetSDPThetaPhiCorrelation();
395 for (
unsigned int i = 0; i < nDepth; ++i) {
398 const double rpErr =
AverageErr(depthDefault[i],
401 const double t0Err =
AverageErr(depthDefault[i],
405 const double chi0Err =
AverageErr(depthDefault[i],
409 const double phiErr =
AverageErr(depthDefault[i],
413 const double thetaErr =
AverageErr(depthDefault[i],
417 const double timeFitVariance =
pow(rpErr,2)
420 + 2 * rpErr * t0Err * rhoRT
421 + 2 * rpErr * chi0Err * rhoRC
422 + 2 * t0Err * chi0Err * rhoCT;
424 const double sdpFitVariance =
pow(phiErr,2) +
pow(thetaErr,2)
425 + 2 * phiErr * thetaErr * rhoPT;
428 const double scaleFac =
429 theGeometry.GetTimeFitChi2() / theGeometry.GetTimeFitNdof();
430 fGeomVariance.push_back(scaleFac*timeFitVariance + sdpFitVariance);
441 const double xLow = fDepth[0];
442 const double xUp = fDepth[nDepth-1];
443 const double xMax = fXmax;
444 const double dX = (xUp - xLow) / (nDepth - 1);
445 const int index = int((xMax - xLow) / dX);
446 if (index >= 0 && index <
int(nDepth) - 1) {
447 const double deltaX = xMax - xLow - index*dX;
448 const double z1 = fGeomVariance[index];
449 const double z2 = fGeomVariance[index+1];
450 fXmaxGeomVar = z1 + deltaX*(z2 - z1)/dX;
451 }
else if (index ==
int(nDepth) - 1)
452 fXmaxGeomVar = fGeomVariance[index];
457 LongitudinalXmaxScanner::CalculateXmaxUncertainties(
const FDEvent& fdEvent)
459 const FdRecShower& theShower = fdEvent.GetFdRecShower();
460 const FdRecApertureLight& theAp = fdEvent.GetFdRecApertureLight();
461 fXmax = theShower.GetXmax()*
g/
cm2;
462 fShowerAngularLength = theAp.GetMaxAngle() - theAp.GetMinAngle();
465 PropagateGeometryUncertainty(fdEvent);
468 fXmaxProfVar = PropagateProfileUncertainty(fdEvent,fXmax);
469 fXmaxAngularLength = fAngularLength;
470 fXmaxTotErr = CalculateTotalError(fXmaxGeomVar,fXmaxProfVar,fdEvent);
473 PrintCurrentVariables(fdEvent);
476 for (
unsigned int i = 0; i < fDepth.size(); ++i) {
478 const double X = fDepth[i];
479 const double geomVar = fGeomVariance[i];
480 const double profVar = PropagateProfileUncertainty(fdEvent, X);
481 const double totErr = CalculateTotalError(geomVar, profVar, fdEvent);
486 cout <<
" X= " << X/
gcm2 <<
' '
488 <<
sqrt(fGeomVarScaleFac*geomVar)/
gcm2 <<
' '
489 << totErr/
gcm2 <<
' ' << theShower.GetXmaxError() <<
' '
494 fLongitudinalScan.push_back(longScan);
495 fErrorAtXmax.push_back(fXmaxTotErr);
500 LongitudinalXmaxScanner::PropagateProfileUncertainty(
const FDEvent& fdEvent,
503 const FdRecShower& theShower = fdEvent.GetFdRecShower();
506 const double scaleFac = theShower.GetGHChi2()/theShower.GetGHNdf();
513 const double ghIntegral = ghFunction.
GetIntegral();
514 const double dEdXmax = fCalorimetricEnergy/ghIntegral;
516 vector<double> npeVec;
517 vector<double> ghFunc;
518 vector<double> dEdXErr;
520 for (
unsigned int i = 0; i < fDepth.size(); ++i) {
522 const double dEdX = dEdXmax * ghFunction.
Eval(fDepth[i]);
523 const double npe = dEdX * fPhotoElectronFactor[i];
524 const double variance = npe*(1 + fGainVariance) + fNoiseVariance[i];
525 const double dEdX_Err =
sqrt(variance) / fPhotoElectronFactor[i];
526 dEdXErr.push_back(dEdX_Err);
527 ghFunc.push_back(dEdX);
528 npeVec.push_back(npe);
532 vector<unsigned short> triggerVec = CalculatePixelTrigger(npeVec);
538 fMinViewingAngle = 0;
543 for (
unsigned int i = 0; i < fDepth.size(); ++i) {
545 if (!triggerVec[i] || fCloseToBoundary[i] || fOutsideTelescope[i])
546 dEdXErr[i] = ghFunc[i]*100;
548 if (!fBins || fDepth[i] < fTrackMin)
549 fTrackMin = fDepth[i];
550 if (!fBins || fDepth[i] > fTrackMax)
551 fTrackMax = fDepth[i];
552 if (!fBins || fMinViewingAngle > fViewingAngle[i])
553 fMinViewingAngle = fViewingAngle[i];
554 angSum += fDeltaAngle[i];
559 fAngularLength = angSum;
562 if (fBins > 0 && angSum > 0) {
564 profVar = EstimateXmaxVariance(fDepth, ghFunc, dEdXErr,
570 if (fVerbosity > 0) {
572 for (
unsigned int i = 0; i < fDepth.size(); ++i) {
573 cout <<
"-- X=" << fDepth[i]/
g*
cm2
574 <<
" dEdX=" << ghFunc[i]/(
PeV/
g*
cm2)
575 <<
" s(dEdX)=" << dEdXErr[i]/(
PeV/
g*
cm2)
576 <<
" relErr=" << dEdXErr[i]/ghFunc[i]
577 <<
" trig=" << triggerVec[i]
578 <<
" telBound=" << fCloseToBoundary[i]
579 <<
" isInTelescope=" << !fOutsideTelescope[i]
580 <<
" dAng=" << fDeltaAngle[i]/
degree
581 <<
" dT=" << fDeltaTime[i]/(100*
ns)
582 <<
" viewAngle= " << fViewingAngle[i]/
degree
594 LongitudinalXmaxScanner::PrintCurrentVariables(
const FDEvent& fdEvent)
597 const FdRecShower& theShower = fdEvent.GetFdRecShower();
598 const FdRecApertureLight& theAp = fdEvent.GetFdRecApertureLight();
600 << fdEvent.GetEyeId() <<
' '
601 << fdEvent.GetRunId() <<
' '
602 << fdEvent.GetEventId() <<
' '
604 << log10(theShower.GetEnergy()) <<
' '
605 << fXmax/
g*
cm2 <<
' '
606 << theShower.GetXmaxError() <<
' '
607 <<
sqrt(fXmaxGeomVar+fXmaxProfVar)/
g*
cm2 <<
' '
610 << fTrackMin/
g*
cm2 <<
' '
611 << fTrackMax/
g*
cm2 <<
' '
612 << theShower.GetXTrackMin() <<
' '
613 << theShower.GetXTrackMax() <<
' '
614 << fAngularLength/
degree <<
' '
615 << fMinViewingAngle/
degree <<
' '
616 << theAp.GetMinAngle()/
degree <<
' '
617 << fGeomVarScaleFac << endl;
623 LongitudinalXmaxScanner::CalculateLightFactor(
const Point& pos1,
625 const unsigned int eyeId)
633 const Point meanPos = pos1 - 0.5*(pos1 - pos2);
634 const Vector Mpos = 0.5*(pos1 - pos2);
639 const double lambdaEffMin = eff.
GetX(0);
641 const double epsilonRef = eff.
Y(lambdaRef);
643 const vector<double>& fluoLambda =
661 double effYTsum_F = 0;
662 for (
unsigned int i = 0; i < fluoLambda.size(); ++i) {
663 if (fluoLambda[i] >= lambdaEffMin &&
664 fluoLambda[i] <= lambdaEffMax) {
665 const double lambda = fluoLambda[i];
666 const double T_i = mieAtt.
GetY(i) * rayAtt.
GetY(i);
667 const double Y_i = fluoyield_tab.
Y(lambda);
668 effYTsum_F += eff.
Y(lambda) / epsilonRef * Y_i * T_i;
674 const vector<double>& cherLambda =
704 const double electronEnergyThreshold = 1*
MeV;
713 for (
unsigned int i = 0; i < cherLambda.size(); ++i) {
714 if (cherLambda[i] >= lambdaEffMin &&
715 cherLambda[i] <= lambdaEffMax) {
725 const double deltaL = (pos1 - pos2).GetMag();
726 const double fourPi = 4*
kPi;
728 const double rSquared = r.
GetMag2();
741 const double dEdX0 = atmo.
GetdEdX0();
742 const double totalsum = effYTsum_F;
743 const double lightFac = totalsum * deltaL / (fourPi * rSquared * dEdX0);
750 LongitudinalXmaxScanner::GetTelescopeProperties(
unsigned int eyeId)
752 const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
759 fPhotonToPhotoElectron = 0.128;
770 LongitudinalXmaxScanner::CalculateTimeLength(
const utl::Point& pos1,
772 const unsigned int eyeId)
779 const Vector pos1Eye = pos1 - eyePos;
780 const Vector pos2Eye = pos2 - eyePos;
781 const Vector pos1pos2 = pos1 - pos2;
786 return fabs(tof1 - tof2);
790 vector<unsigned short>
791 LongitudinalXmaxScanner::CalculatePixelTrigger(
const vector<double>& npeVec)
794 vector<unsigned short> triggerVec;
800 for (
unsigned int i = 0; i < npeVec.size(); ++i) {
802 if (fDeltaAngle[i] < 0) {
803 triggerVec.push_back(0);
807 timeSum += fDeltaTime[i];
808 angSum += fDeltaAngle[i];
811 if (angSum > fPixelSize) {
813 const bool triggered = IsTriggered(timeSum, angSum, npeSum);
814 for (
unsigned int j = triggerVec.size(); j <= i; ++j)
815 triggerVec.push_back(triggered);
825 const bool triggered = IsTriggered(timeSum, angSum, npeSum);
826 for (
unsigned int j = triggerVec.size(); j < npeVec.size(); ++j)
827 triggerVec.push_back(triggered);
835 LongitudinalXmaxScanner::IsTriggered(
const double dT,
const double dAng,
const double npe)
838 const double thresholdSlope = 15.;
839 const double threshold = thresholdSlope*fPhotoElectronBGRMS;
840 const int nBoxCar = 10;
841 const double timeBinLength = 100*
ns;
843 const double timeInPixel = fPixelSize / dAng * dT;
844 const double signalInPixel = fPixelSize / dAng * npe;
845 const double signalBoxTime = fmin(timeInPixel, nBoxCar*timeBinLength);
847 return signalInPixel/timeInPixel*signalBoxTime > threshold;
852 LongitudinalXmaxScanner::CalculateTotalError(
const double geomVar,
853 const double profVar,
854 const FDEvent& fdEvent)
858 fAngularLength < 1*
degree)
861 const double xmaxAngleErr =
SpaceAngle(fXmaxAngularLength, fdEvent);
862 const double currAngleErr =
SpaceAngle(fAngularLength, fdEvent);
865 const double adstFactor = 1;
866 const double currentFactor = currAngleErr / xmaxAngleErr;
868 fGeomVarScaleFac =
pow(adstFactor*currentFactor, 2);
870 const double totErr =
sqrt(fGeomVarScaleFac*geomVar + profVar);
877 LongitudinalXmaxScanner::IsNearBorder(
const utl::Vector& direction,
878 const unsigned int eyeId,
879 const unsigned int telId,
889 const double angle =
Angle(direction, *iter);
898 std::array<unsigned int, 2>
899 LongitudinalXmaxScanner::GetTelescopeAndPixelId(
const utl::Vector& direction,
900 const unsigned int eyeId)
906 unsigned int iPix = 0;
907 unsigned int iTel = 0;
908 double min = std::numeric_limits<double>::infinity();
912 for (
unsigned int i = tIt->GetFirstPixelId(), n = tIt->GetLastPixelId();
914 const double diff =
Angle(direction, tIt->GetPixel(i).GetDirection());
923 return { iTel, iPix };
928 LongitudinalXmaxScanner::EstimateXmaxVariance(
const vector<double>& x,
929 const vector<double>& ghFunc,
930 const vector<double>& eY,
942 for (
unsigned int i = 0; i < x.size(); ++i) {
949 const double tmp = eY[i] / ghFunc[i];
950 const double invSqRelErr = 1 /
pow(tmp, 2);
952 const double logTerm = log((x0 - x[i]) / (x0 - xMax));
954 const double ghRelDeriv1 = 1 / nMax;
956 const double ghRelDeriv2 = logTerm / lambda;
957 const double nominatorX0 = (x0 - x[i]) * logTerm + (x[i] - xMax);
958 const double nominatorLambda = (x0 - xMax) * logTerm + (x[i] - xMax);
960 const double ghRelDeriv3 = nominatorX0 / lambda / (x[i] - x0);
962 const double ghRelDeriv4 = nominatorLambda / (lambda * lambda);
964 const double deriv[4] = { ghRelDeriv1, ghRelDeriv2, ghRelDeriv3, ghRelDeriv4 };
966 for (
int i = 0; i < 4; ++i)
967 for (
int j = 0; j <= i; ++j)
968 a[i][j] += invSqRelErr * deriv[i] * deriv[j];
983 a.InvertFast(&determinant);
985 if (determinant <= 0) {
987 info <<
"error matrix is singular, det="
989 <<
", XmaxError = " <<
sqrt(a[1][1])/
gcm2 << endl;
AxialVector Cross(const Vector &l, const Vector &r)
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
const utl::TabulatedFunction & EvaluateFluorescenceYield(const double heightAboveSeaLevel) const
Evaluated Fluorescence Yield for a specific model.
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
Description of the electronic channel for the 480 channels of the crate.
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
const std::vector< double > & GetWavelengths(const EmissionMode mode=eFluorescence) const
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
Class to hold collection (x,y) points and provide interpolation between them.
double SpaceAngle(const double angularLength, const FDEvent &fdEvent)
std::pair< gh::EShapeParameter, double > ShapeParameter
double GetMeasuredRelativeEfficiency(const double wl) const
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
double GetGainVariance() const
const Channel & GetChannel(const unsigned int channelId) const
Get Channel by id, throw utl::NonExistentComponentException if n.a.
double GetEndToEndCalibrationAtReferenceWavelength() const
#define INFO(message)
Macro for logging informational messages.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Detector description interface for Eye-related data.
double pow(const double x, const unsigned int i)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
OutOfBorderPixelsIterator OutOfBorderPixelsEnd() const
End of pixels out of the border.
const Pixel & GetPixel(const unsigned int pixelId) const
Get Pixel by id, throw utl::NonExistentComponentException if n.a.
const atm::Atmosphere & GetAtmosphere() const
double AverageErr(const double x0, const double x1, const double x2)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Reference ellipsoids for UTM transformations.
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
Class describing the Atmospheric profile.
TelescopeIterator TelescopesBegin() const
Beginning of the collection of telescopes.
constexpr double nanosecond
const Telescope & GetTelescope(const unsigned int telescopeId) const
Find Telescope by numerical Id.
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
Top of the hierarchy of the detector description interface.
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
const fdet::FDetector & GetFDetector() const
std::vector< utl::Vector >::const_iterator OutOfBorderPixelsIterator
AxialVector Normalized(const AxialVector &v)
const double & GetY(const unsigned int idx) const
double Eval(const double depth) const
evaluate function a X = depth
double GetReferenceLambda() const
boost::filter_iterator< TelIsCommissioned, InternalConstTelescopeIterator > TelescopeIterator
An iterator over telescopes.
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
const double kAverageLambda
double GetFADCBinSize() const
utl::CoordinateSystemPtr GetReferenceCoordinateSystem() const
Get the reference coordinate system used for analysis (usually PampaAmarilla for Auger) ...
execption handling for calculation/access for inclined atmosphere model
const double & GetX(const unsigned int idx) const
double GetdEdX0() const
get reference energy deposit for fluorescence yield model
OutOfBorderPixelsIterator OutOfBorderPixelsBegin() const
Begin of pixels out of the border.
void SetCherenkovEnergyCutoff(const double eCut) const
TelescopeIterator TelescopesEnd() const
End of the collection of telescopes.
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
double GetADCVariance() const
double GetIntegral() const
calculate integral
Gaisser Hillas with 4 parameters.
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
const std::string & GetMessage() const
Retrieve the message from the exception.
utl::Point GetPosition() const
Eye position.
Class describing the Atmospheric attenuation.
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
void AddScanResult(double depth, double error, double minViewAngle)
const double kMaxVariance