FdLaserEnergyReconstructor.cc
Go to the documentation of this file.
1 /*
2  implementation FdLaserEnergyReconstructorKG
3 
4  \author Joachim Debatin
5 
6  */
7 
9 
10 #include <utl/ErrorLogger.h>
11 #include <utl/Reader.h>
12 #include <utl/Vector.h>
13 #include <utl/Point.h>
14 #include <utl/PhysicalConstants.h>
15 #include <utl/TabulatedFunctionErrors.h>
16 #include <utl/MathConstants.h>
17 #include <utl/PairErr.h>
18 
19 #include <evt/Event.h>
20 #include <evt/ShowerFRecData.h>
21 #include <evt/GaisserHillas4Parameter.h>
22 
23 
24 #include <fevt/FEvent.h>
25 #include <fevt/Eye.h>
26 #include <fevt/Telescope.h>
27 #include <fevt/EyeHeader.h>
28 #include <fevt/EyeRecData.h>
29 #include <fevt/TelescopeRecData.h>
30 #include <fevt/FdConstants.h>
31 #include <fevt/Pixel.h>
32 
33 #include <fwk/CentralConfig.h>
34 #include <fwk/RunController.h>
35 #include <fwk/CoordinateSystemRegistry.h>
36 #include <fwk/LocalCoordinateSystem.h>
37 
38 #include <det/Detector.h>
39 
40 #include <fdet/FDetector.h>
41 #include <fdet/Eye.h>
42 #include <fdet/Telescope.h>
43 #include <fdet/Camera.h>
44 
45 #include <atm/Atmosphere.h>
46 #include <atm/InclinedAtmosphericProfile.h>
47 #include <atm/ProfileResult.h>
48 
49 #include <vector>
50 #include <cmath>
51 
52 using namespace FdLaserEnergyReconstructorKG;
53 using namespace std;
54 using namespace utl;
55 using namespace fwk;
56 using namespace fevt;
57 using namespace evt;
58 using namespace det;
59 
60 
63 {
64  CentralConfig* const cc = CentralConfig::GetInstance();
65 
66  Branch topB = cc->GetTopBranch("FdLaserEnergyReconstructorKG");
67 
68  if (!topB) {
69  ERROR("Could not find branch FdLaserEnergyReconstructorKG");
70  return eFailure;
71  }
72 
73  topB.GetChild("laserwavelength").GetData(fLaserWaveLength);
74  return eSuccess;
75 
76  topB.GetChild("pixelswithpeak").GetData(fPixelsWithPeak);
77  return eSuccess;
78 }
79 
80 
83 {
84  /*if (event.GetHeader().GetTime().GetGPSNanoSecond() < 249000000. || event.GetHeader().GetTime().GetGPSNanoSecond() > 252000000.) {
85  const string msg = "Probably no CLF event";
86  INFO(msg);
87  return eContinueLoop;
88  }*/
89 
90  if (!event.HasFEvent())
91  return eSuccess;
92 
93  const det::Detector& detector = det::Detector::GetInstance();
94  const atm::Atmosphere& atmos = detector.GetAtmosphere();
95 
96  //loop eyes
97  for (FEvent::EyeIterator eyeiter = event.GetFEvent().EyesBegin(ComponentSelector::eHasData);
98  eyeiter != event.GetFEvent().EyesEnd(ComponentSelector::eHasData); ++eyeiter) {
99 
100  Eye& eye = *eyeiter;
101 
102  if (!eye.HasRecData() || !eye.GetRecData().HasFRecShower()) {
103  cout << " no recData for eye " << eye.GetId() << " --> skip! " << endl;
104  continue;
105  }
106 
107  GetGeometryData(eye);
108 
109  evt::ShowerFRecData& shower = eye.GetRecData().GetFRecShower();
110 
111  //init slant depth profile
112  try {
113  atmos.InitSlantProfileModel(fCore, fAxis, 10*g/cm2);
115  ERROR(e.GetMessage());
116  return eFailure;
117  }
118 
119  const atm::ProfileResult& slantDepthProfile = atmos.EvaluateSlantDepthVsDistance();
120  const double atmMinDistance = slantDepthProfile.MinX() + 1*utl::millimeter;
121  const double atmMaxDistance = slantDepthProfile.MaxX() - 1*utl::millimeter;
122 
123  //reuse stuff to show Laser in the EventBrowser
124  if (!shower.HasEnergyDeposit())
125  shower.MakeEnergyDeposit();
126  TabulatedFunctionErrors& dedxProfile = shower.GetEnergyDeposit();
127 
128  if (!shower.HasLongitudinalProfile())
129  shower.MakeLongitudinalProfile();
130  TabulatedFunctionErrors& longProfile = shower.GetLongitudinalProfile();
131 
132  //for average energy
133  double sum = 0;
134  double wsum = 0;
135 
136  //loop telescopes
137  for (fevt::Eye::TelescopeIterator teliter = eye.TelescopesBegin(ComponentSelector::eHasData);
138  teliter != eye.TelescopesEnd(ComponentSelector::eHasData); ++teliter) {
139 
140  const Telescope& tel = *teliter;
141 
142  const fdet::Telescope& detTel = detector.GetFDetector().GetEye(eye).GetTelescope(tel.GetId());
143 
144  GetTelescopeData(tel, detTel);
145 
146  //This can be used to cut on clouds
147  int pixels = 0;
148  for (fevt::Telescope::ConstPixelIterator pixiter = tel.PixelsBegin(ComponentSelector::eHasData);
149  pixiter != tel.PixelsEnd(ComponentSelector::eHasData); ++pixiter) {
150 
151  const Pixel& pix = *pixiter;
152  if (pix.HasRecData() && pix.GetRecData().PulseIsFound()) {
153  ++pixels;
154  }
155  }
156  if (pixels < fPixelsWithPeak) {
157  string msg = "Telescope with to few pixels";
158  INFO(msg);
159  continue;
160  }
161 
162  const double eff = detTel.GetMeasuredRelativeEfficiency(fLaserWaveLength);
163 
164  if (!eye.GetRecData().HasLightFlux()) {
165  cout << "No LightFlux for this Eye ---> skip" << endl;
166  continue;
167  }
168 
170  utl::ConstTabulatedFunctionErrIterator it = FluxAtTelescope.Begin();
171 
172  //loop timebins
173  for (int i = 1; i <= int(fTraceLength); ++i) {
174 
175  const int midTimeBin = int(i * fBinSize - 0.5 * fBinSize);
176 
177  // check for FieldOfView by ApertureLightFinder
178  const utl::PairErr& bin = *it;
179  if (int(bin.X()) == midTimeBin) {
180 
181  if (!tel.GetRecData().IsSpotFarFromBorder(bin.X())) {
182  ++it;
183  continue;
184  }
185 
186  const utl::Point pointAtLaserBeam = CalculateLaserBeamPosition(double(i));
187 
188  const double Coefficient = CalculateAtmosphereCoefficient(atmos, pointAtLaserBeam, eff, i);
189 
190  const double recEnergy = bin.Y() * utl::kPlanck * utl::kSpeedOfLight / fLaserWaveLength / Coefficient;
191  const double recEnergyErr = bin.YErr() * utl::kPlanck * utl::kSpeedOfLight / fLaserWaveLength / Coefficient;
192 
193  //Get slant depth
194  const double distanceToCore = (pointAtLaserBeam - fCore).GetMag();
195  if (distanceToCore < atmMinDistance || distanceToCore > atmMaxDistance) {
196  cerr << "Error - point outside atmosphere, d=" << distanceToCore << endl;
197  continue;
198  }
199 
200  const double X = slantDepthProfile.Y(distanceToCore);
201 
202  const double w = 1 / pow(recEnergyErr, 2);
203  sum += w * recEnergy;
204  wsum += w;
205 
206  //Fill profiles EventBrowser
207  dedxProfile.PushBack(X, 0, recEnergy/g*cm2, recEnergyErr/g*cm2);
208  longProfile.PushBack(X, 0, recEnergy, recEnergyErr);
209  ++it;
210  }
211 
212  }
213 
214  }
215  //Calculate average Energy
216  const double avEnergy = sum / wsum;
217  const double avEnergyErr = sqrt(1 / wsum);
218 
219  if (std::isnan(avEnergy) || std::isnan(avEnergyErr) || avEnergy < 1 || avEnergyErr < 1) {
220  cout << "Energy Reconstruction failed! --> skip" << endl;
221  continue;
222  }
223 
224  shower.SetTotalEnergy(avEnergy, avEnergyErr);
225  //cout << " average energy " << avEnergy << endl;
226 
227  //calculate chi squared
228  unsigned int ndf = 0;
229  double chisquared = 0;
230  bool setchisquared = false;
231  if (longProfile.GetNPoints() > 0) {
232  utl::TabulatedFunctionErrIterator it = longProfile.Begin();
233  while (ndf < longProfile.GetNPoints()) {
234  const utl::PairErr& bin = *it;
235  chisquared += pow(((bin.Y() - avEnergy) / bin.YErr()), 2);
236  ++ndf;
237  ++it;
238  }
239  setchisquared = true;
240  }
241 
242  //needed for EventBrowser to show energy versus slant depth
243  if (!shower.HasGHParameters()) {
245  shower.MakeGHParameters(ghTmp);
246  }
248  dynamic_cast<GaisserHillas4Parameter&>(shower.GetGHParameters());
249 
250  gh4.SetShapeParameter(gh::eX0, -50000*g/cm2, 0);
251  gh4.SetShapeParameter(gh::eLambda, 6000*g/cm2, 0);
252 
253  if (setchisquared) {
254  gh4.SetChiSquare(chisquared, ndf-1);
255  } else {
256  gh4.SetChiSquare(1, 1);
257  }
258 
259  }
260 
261  return eSuccess;
262 }
263 
264 
267 {
268  //Get absolute time for bin + half of a binSize for middle of timeBin
269  const utl::TimeStamp binTime =
270  fGPSTime - TimeInterval(((fTraceLength - bin) * fBinSize - (fBinSize / 2) + static_cast<double>(fTelTimeOffset)));
271 
272  //time between core and bin in nanoseconds
273  const double deltaT = (binTime - fCoreTime).GetInterval();
274 
275  //GetVector pointing from Eye to Core
276  const utl::Vector eyeToCore = fCore - fTelPos;
277 
278  const double factor = (eyeToCore * eyeToCore - utl::kSpeedOfLight2 * deltaT * deltaT)/(2 * (eyeToCore * fAxis - utl::kSpeedOfLight * deltaT));
279 
280  return fCore - factor * fAxis;
281 }
282 
283 
284 //Calculate Coefficient for Energy = c * Signal
285 double
287  const utl::Point pointAtLaserBeam,
288  const double efficiency,
289  const double i)
290 {
291  //Point A and B are the points at the laser beam for beginning and end of one time bin at the telescope
292  const utl::Point pointAtLaserBeamA = CalculateLaserBeamPosition(i - 0.5);
293  const utl::Point pointAtLaserBeamB = CalculateLaserBeamPosition(i + 0.5);
294  const utl::Vector eyeToPointLaser = pointAtLaserBeam - fTelPos;
295  const double angle = Angle(-eyeToPointLaser, fAxis);
296 
297  //Transmission Factors
298  const double TRay1 = atmos.EvaluateRayleighAttenuation(fCore, pointAtLaserBeam, fLaserWaveLength);
299  const double TRay2 = atmos.EvaluateRayleighAttenuation(pointAtLaserBeam, fTelPos, fLaserWaveLength);
300  const double TMie1 = atmos.EvaluateMieAttenuation(fCore, pointAtLaserBeam, fLaserWaveLength);
301  const double TMie2 = atmos.EvaluateMieAttenuation(pointAtLaserBeam, fTelPos, fLaserWaveLength);
302 
303  //Scattering Factors
304  const double SRay = atmos.EvaluateRayleighScattering(pointAtLaserBeamA, pointAtLaserBeamB, angle, eyeToPointLaser.GetMag(), fLaserWaveLength);
305  const double SMie = atmos.EvaluateMieScattering(pointAtLaserBeamA, pointAtLaserBeamB, angle, eyeToPointLaser.GetMag(), fLaserWaveLength);
306  const double STot = SMie + SRay;
307 
308  const double Coefficient = TRay1 * TRay2 * TMie1 * TMie2 * STot * efficiency;
309 
310  return Coefficient;
311 }
312 
313 
314 void
316 {
317  const evt::ShowerFRecData& shower = eye.GetRecData().GetFRecShower();
318 
319  fCore = shower.GetCorePosition();
320  fAxis = shower.GetAxis();
321  fCoreTime = shower.GetCoreTime();
322  fGPSTime = eye.GetHeader().GetTimeStamp();
323 }
324 
325 
326 void
328  const fdet::Telescope& detTel)
329 {
330  fTelPos = detTel.GetPosition();
331  fBinSize = detTel.GetCamera().GetFADCBinSize();
332  fTraceLength = detTel.GetCamera().GetFADCTraceLength();
333  fTelTimeOffset = tel.GetTimeOffset();
334 }
335 
336 
339 {
340  return eSuccess;
341 }
unsigned int GetId() const
Definition: FEvent/Eye.h:54
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
double YErr() const
Definition: PairErr.h:29
double GetFADCBinSize() const
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
Definition: EyeRecData.h:297
Point object.
Definition: Point.h:32
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
constexpr double kPlanck
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
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
unsigned int GetTimeOffset() const
Time offset of this Telescope compared to fevt::Header::GetTime [ns].
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool HasFEvent() const
A pair of graph points (x,y) with errors.
Definition: PairErr.h:17
bool HasRecData() const
Definition: FEvent/Pixel.h:43
double GetMeasuredRelativeEfficiency(const double wl) const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void SetShapeParameter(const gh::EShapeParameter par, const double value, const double error)
Setters.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
fevt::TelescopeRecData & GetRecData()
Reconstructed data for this telescope.
double pow(const double x, const unsigned int i)
double GetMag() const
Definition: Vector.h:58
bool PulseIsFound() const
Definition: PixelRecData.h:84
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
PixelIterator PixelsEnd()
iterator pointing to end of available pixels of status eHasData (DEPRECATED)
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
double X() const
Definition: PairErr.h:25
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Class representing a document branch.
Definition: Branch.h:107
bool IsSpotFarFromBorder(const double timeRelToEyeTriggerTime) const
bool HasLongitudinalProfile() const
Fluorescence Detector Pixel event.
Definition: FEvent/Pixel.h:28
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
void GetTelescopeData(const fevt::Telescope &tel, const fdet::Telescope &detTel)
constexpr double millimeter
Definition: AugerUnits.h:85
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.
Definition: Detector.h:81
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
const fdet::FDetector & GetFDetector() const
Definition: Detector.cc:131
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
atm::ScatteringResult EvaluateRayleighScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const
constexpr double g
Definition: AugerUnits.h:200
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
void PushBack(const double x, const double xErr, const double y, const double yErr)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
void SetChiSquare(const double chi, const unsigned int ndof)
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
fevt::FEvent & GetFEvent()
bool HasGHParameters() const
constexpr double kSpeedOfLight
Detector description interface for Telescope-related data.
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
utl::TabulatedFunctionErrors & GetLongitudinalProfile()
retrieve longitudinal profile information (size vs depth)
double Y() const
Definition: PairErr.h:26
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
unsigned int GetId() const
utl::TimeStamp GetTimeStamp() const
Time of the Eye Event as tagged by FD-DAS (== eye trigger time plus pixel trace length) ...
Definition: EyeHeader.h:118
utl::Point GetPosition() const
execption handling for calculation/access for inclined atmosphere model
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
Main configuration utility.
Definition: CentralConfig.h:51
constexpr double kSpeedOfLight2
Fluorescence Detector Telescope Event.
PixelIterator PixelsBegin()
iterator pointing to first available pixel of status eHasData (DEPRECATED)
Gaisser Hillas with 4 parameters.
void SetTotalEnergy(const double energy, const double energyError, const EUncertaintyType type=eTotal)
void MakeGHParameters(const VGaisserHillasParameter &gh)
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
const std::string & GetMessage() const
Retrieve the message from the exception.
bool HasEnergyDeposit() const
double CalculateAtmosphereCoefficient(const atm::Atmosphere &atmos, const utl::Point pointAtLaserBeam, const double eps, const double i)
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
PixelRecData & GetRecData()
Definition: FEvent/Pixel.h:40
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
utl::TabulatedFunctionErrors & GetEnergyDeposit()
retrieve dE/dX
constexpr double cm2
Definition: AugerUnits.h:118
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.
atm::ScatteringResult EvaluateMieScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const

, generated on Tue Sep 26 2023.