CFMatrixCalculator.cc
Go to the documentation of this file.
1 #include "CFMatrixCalculator.h"
3 #include "TelescopeData.h"
4 #include "ZetaPixel.h"
5 
6 #include <fevt/Eye.h>
7 #include <fevt/EyeRecData.h>
8 #include <fevt/EyeHeader.h>
9 #include <fevt/Telescope.h>
10 #include <fevt/TelescopeRecData.h>
11 #include <fevt/Pixel.h>
12 
13 #include <evt/ShowerFRecData.h>
14 
15 #include <det/Detector.h>
16 #include <fdet/FDetector.h>
17 #include <fdet/Eye.h>
18 #include <fdet/Pixel.h>
19 #include <fdet/Telescope.h>
20 
21 #include <atm/Atmosphere.h>
22 #include <atm/ProfileResult.h>
23 #include <atm/AttenuationResult.h>
24 #include <atm/ScatteringResult.h>
25 #include <atm/InclinedAtmosphericProfile.h>
26 
27 #include <fwk/CentralConfig.h>
28 #include <utl/Reader.h>
29 #include <utl/ErrorLogger.h>
30 #include <utl/UTMPoint.h>
31 #include <utl/AugerException.h>
32 #include <utl/TabulatedFunctionErrors.h>
33 #include <utl/PhysicalConstants.h>
34 #include <utl/PhysicalFunctions.h>
35 
36 #include <fwk/LocalCoordinateSystem.h>
37 
38 #include <sstream>
39 #include <string>
40 #include <algorithm>
41 
42 using namespace fevt;
43 using namespace evt;
44 using namespace utl;
45 using namespace atm;
46 using namespace det;
47 using namespace std;
48 using namespace FdEnergyDepositFinderKG;
49 
50 
51 #undef _CFMDEBUG_
52 
53 
54 const std::string gPrintPrefix = " ==> CFMatrixBuilder:";
55 
56 
57 void
59 {
60  delete fLateralLightCalculator;
61  fLateralLightCalculator = new LateralLightCalculator();
62 
63  auto topBranch = fwk::CentralConfig::GetInstance()->GetTopBranch("FdEnergyDepositFinder");
64  auto lldBranch = topBranch.GetChild("lateralLight");
65 
66  lldBranch.GetChild("multipleScattering").GetData(fDoMultipleScattering);
67  ostringstream info;
68  info << "\n\t multiple scattering is "
69  << (fDoMultipleScattering ? "on" : "off");
70  INFO(info);
71 }
72 
73 
74 CFMatrixCalculator::~CFMatrixCalculator()
75 {
76  delete fLateralLightCalculator;
77 }
78 
79 
80 void
81 CFMatrixCalculator::BuildMatrix(const fevt::Eye& eye, const bool leavingAtmoIsError, const unsigned int addDense)
82 {
83  Clear();
84 
85  if (InitCalculation(eye) && CalculateTelescopeData(eye, leavingAtmoIsError, addDense)) {
86 
87  if (fVerbosity > -1)
88  cout << gPrintPrefix << " building CF-matrix, dim="
89  << fNumberOfDepthBins << "..." << endl;
90 
91  CalculateDiagonalParameters();
92  CalculateFluorescenceMatrix();
93  CalculateDirectCherenkovMatrix();
94 
95  if (fOnlyDirect) {
96  fDirectCFMatrix = fDirectCherenkovMatrix + fDirectFluorescenceMatrix;
97  return;
98  }
99 
100  CalculateMieAndRayScattCherenkovMatrix();
101 
102  fCFMatrix = fMieScatteredCherenkovMatrix +
103  fRayScatteredCherenkovMatrix +
104  fDirectCherenkovMatrix +
105  fDirectFluorescenceMatrix;
106 
107  if (fVerbosity > -1)
108  cout << gPrintPrefix << " done " << endl;
109 
110  }
111 }
112 
113 
114 bool
115 CFMatrixCalculator::InitCalculation(const fevt::Eye& eye)
116 {
117  fEyeId = eye.GetId();
118 
119  // --- Assert that there's a successful aperture light reconstruction
120  if (!eye.HasRecData())
121  return false;
122  const auto& eyeRecData = eye.GetRecData();
123  if (!eyeRecData.HasLightFlux(fevt::FdConstants::eTotal))
124  return false;
125 
126  // --- Xmax
127  const auto& shower = eye.GetRecData().GetFRecShower();
128  if (shower.HasGHParameters() && shower.GetGHParameters().GetXMax() > 0)
129  fXmax = shower.GetGHParameters().GetXMax();
130  else
131  fXmax = 750*g/cm2;
132 
133  // --- set the Cherenkov model energy threshold for this calculation
134  fElectronEnergyThreshold = shower.GetEnergyCutoff();
135  const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
136  atmo.SetCherenkovEnergyCutoff(fElectronEnergyThreshold);
137 
138  // --- wave lengths
139  fCherWaveLength = atmo.GetWavelengths(Atmosphere::eCerenkov);
140  fFluoWaveLength = atmo.GetWavelengths(Atmosphere::eFluorescence);
141 
142  // remove wave lengths with no or zero efficiency
143  const auto& fdDetector = Detector::GetInstance().GetFDetector();
144  // note: we assume all telescope-effs are equal --> get first one...
145  const auto& relEff = fdDetector.GetEye(fEyeId).TelescopesBegin()->GetMeasuredRelativeEfficiency();
146  const double effMinLam = relEff.GetX(0);
147  const double effMaxLam = relEff.GetX(relEff.GetNPoints() - 1);
148 
149  for (auto lIt = fFluoWaveLength.begin(); lIt != fFluoWaveLength.end(); ) {
150  if (effMinLam <= *lIt && *lIt <= effMaxLam && relEff.Y(*lIt) > 0)
151  ++lIt;
152  else
153  lIt = fFluoWaveLength.erase(lIt);
154  }
155 
156  for (auto lIt = fCherWaveLength.begin(); lIt != fCherWaveLength.end(); ) {
157  // in contrast to fluorescence, C-bins are integration bounds
158  if (effMinLam <= *lIt && *lIt <= effMaxLam)
159  ++lIt;
160  else
161  lIt = fCherWaveLength.erase(lIt);
162  }
163 
164  return true;
165 }
166 
167 
168 bool
169 CFMatrixCalculator::CalculateTelescopeData(const fevt::Eye& eye, const bool leavingAtmoIsError, const unsigned int addDense)
170 {
171  const auto& shower = eye.GetRecData().GetFRecShower();
172  const auto& axis = shower.GetAxis();
173  fShowerAxis = -shower.GetAxis(); // downward!
174  const auto& core = shower.GetCorePosition();
175  const auto& coreCS = fwk::LocalCoordinateSystem::Create(core);
176  // should be local (in air) cos theta like in ShowerPhotonGenerator
177  // fCosTheta = axis.GetCosTheta(coreCS);
178 
179  const auto& coreTime = shower.GetCoreTime();
180  const auto& eyeGPSTime = eye.GetHeader().GetTimeStamp();
181 //#warning hardcoded trace time length!
182  const auto eyeTriggerTime = eyeGPSTime - TimeInterval(1000*100*utl::ns);
183 
184  const auto& atmo = Detector::GetInstance().GetAtmosphere();
185  try {
186  atmo.InitSlantProfileModel(core, axis, fMethod == ePrecise ? 10*g/cm2 : 100*g/cm2);
188  ERROR(e.GetMessage());
189  return false;
190  }
191 
192  const auto& slantDepthProfile = atmo.EvaluateSlantDepthVsDistance();
193  const auto& slantDistProfile = atmo.EvaluateDistanceVsSlantDepth();
194  const double atmMinDistance = slantDepthProfile.MinX() + 1*mm;
195  const double atmMaxDistance = slantDepthProfile.MaxX() - 1*mm;
196  const auto& verticalDepthProfile = atmo.EvaluateDepthVsHeight();
197  const double atmMinHeight = verticalDepthProfile.MinX();
198  const double atmMaxHeight = verticalDepthProfile.MaxX();
199 
200  for (auto telIter = eye.TelescopesBegin(fevt::ComponentSelector::eInDAQ);
201  telIter != eye.TelescopesEnd(fevt::ComponentSelector::eInDAQ); ++telIter) {
202 
203  if (!telIter->HasRecData())
204  continue;
205 
206  // Fetch light fluxes from the TelescopeRecData
207  const auto& telRecData = telIter->GetRecData();
208  if (!telRecData.HasLightFlux(fevt::FdConstants::eTotal) ||
209  !telRecData.HasLightFlux(fevt::FdConstants::eBackground))
210  continue;
211 
212  const auto& photonTrace = telRecData.GetLightFlux(fevt::FdConstants::eTotal);
213  const auto& bgTrace = telRecData.GetLightFlux(fevt::FdConstants::eBackground);
214 
215  if (photonTrace.GetNPoints() != bgTrace.GetNPoints()) {
216  ERROR("incompatible light fluxes --> skip tel!!");
217  continue;
218  }
219 
220  // Fetch the light collection efficiencies from the TelescopeRecData
221  // or fake them if they're not available
222  typedef unique_ptr<TabulatedFunctionErrors> TabFuncErrAutoPtr;
223  TabFuncErrAutoPtr fluorLCEff(CalculateLCEff(FdConstants::eFluorDirect, telRecData));
224  TabFuncErrAutoPtr directCherLCEff(CalculateLCEff(FdConstants::eCherDirect, telRecData));
225  TabFuncErrAutoPtr rayCherLCEff(CalculateLCEff(FdConstants::eCherRayleighScattered, telRecData));
226  TabFuncErrAutoPtr mieCherLCEff(CalculateLCEff(FdConstants::eCherMieScattered, telRecData));
227 
228  const auto& zetaPixelIds = telRecData.GetPixelsInZetaOverTime();
229  if (fMethod == ePrecise && zetaPixelIds.size() != photonTrace.GetNPoints()) {
230  ostringstream errMsg;
231  errMsg << "inconsistent trace/zetaPixels: N(trace) = "
232  << photonTrace.GetNPoints() << " N(zetaPixels)="
233  << zetaPixelIds.size();
234  ERROR(errMsg);
235  throw NonExistentComponentException(errMsg.str());
236  }
237 
238  // Currently only the largest portion of the lightflux is
239  // taken into account.
240  // (Which is the whole time range anyway if it was calculated
241  // by FdLightCollectionEfficiencyKG, but not necessarily if it's
242  // from FdApertureLightFinderKG.)
243  bool firstTime = true;
244  double maxRange = 0;
245  double minTime = 0;
246  double maxTime = 0;
247  double maxSignal = 0;
248  const auto& timeRangeList = telRecData.GetSpotFarFromBorderTimeRanges();
249  for (auto timeRangeIter = timeRangeList.begin(), end = timeRangeList.end(); timeRangeIter != end; ++timeRangeIter) {
250 
251  const double thisRange = fabs(timeRangeIter->first - timeRangeIter->second);
252  const double thisRangeMin = fmin(timeRangeIter->first, timeRangeIter->second);
253  const double thisRangeMax = fmax(timeRangeIter->first, timeRangeIter->second);
254 
255  const auto& flux = telRecData.GetLightFlux();
256  double thisSignal = 0;
257  for (auto it = flux.Begin(), end = flux.End(); it != end; ++it) {
258  if (thisRangeMin <= it->X() && it->X() <= thisRangeMax)
259  thisSignal += it->Y() / it->YErr();
260  }
261 
262  // Use the integrated signal of the time range to decide
263  if (firstTime || thisSignal > maxSignal) {
264  firstTime = false;
265  maxSignal = thisSignal;
266  maxRange = thisRange;
267  minTime = thisRangeMin;
268  maxTime = thisRangeMax;
269  }
270  } // end foreach time ranges
271 
272  if (maxRange <= 0) {
273  ostringstream errMsg;
274  errMsg << " zero time range for telId=" << telIter->GetId() << "??";
275  ERROR(errMsg);
276  continue;
277  }
278 
279  const auto& fdDetector = Detector::GetInstance().GetFDetector();
280  const auto& detTel = fdDetector.GetEye(eye.GetId()).GetTelescope(telIter->GetId());
281  const unsigned int physicalEyeId = detTel.GetParentPhysicalEyeId();
282  const auto& telEyeCS = fdDetector.GetEye(physicalEyeId).GetEyeCoordinateSystem();
283 
284  // for distance from shower core to emission point (aDist)
285  // law of cosines: bDist^2 = aDist^2 + cDist^2 - 2*aDist*cDist*cos(beta)
286  // cDist = distance(telescope, core)
287  // bDist-aDist = (telTime-coreTime)/c = delta (see below)
288  const auto coreTelescopeVec = detTel.GetPosition() - core;
289  const double cDist = coreTelescopeVec.GetMag();
290  const double cosBeta = CosAngle(axis, coreTelescopeVec);
291 
292  TelescopeData telData(telIter->GetId());
293  //noiseTelData contains everything as telData plus bins coming from
294  //light corresponding to the part of shower outside of the atmosphere - NOT FOR CFM calculation!
295  TelescopeData noiseTelData(telIter->GetId());
296  for (unsigned int i = 0; i < photonTrace.GetNPoints(); ++i) {
297 
298  // divide real photonTrace bins into several dense (virtual) bins for finer CFM in ProfileFitter
299  for (unsigned int j = 0; j < addDense; ++j) {
300 
301  /*
302  const double tMean = photonTrace.GetX(i);
303  const double halfBinWidth = photonTrace.GetXErr(i);
304  const double tFirst = tMean-halfBinWidth;
305  const double tLast = tMean+halfBinWidth;
306  */
307  // definition according to dense binning
308  const double halfBinWidth = photonTrace.GetXErr(i);
309  const double tMean = photonTrace.GetX(i) - halfBinWidth + (2*j + 1) * halfBinWidth / addDense;
310  const double tFirst = tMean-halfBinWidth / addDense;
311  const double tLast = tMean+halfBinWidth / addDense;
312 
313  /*
314  if (tFirst < minTime)
315  continue;
316  if (tLast > maxTime)
317  break;
318  */
319  if (photonTrace.GetX(i) - halfBinWidth < minTime)
320  break;
321  if (photonTrace.GetX(i) + halfBinWidth > maxTime)
322  break;
323 
324  try {
325 
326  const auto& wgs84 = ReferenceEllipsoid::GetWGS84();
327 
328  const auto firstTimeAtTelescope = eyeTriggerTime + tFirst;
329  const double deltaFirst = (firstTimeAtTelescope - coreTime).GetInterval()*kSpeedOfLight;
330  const double firstDistance =
331  -(cDist*cDist - deltaFirst*deltaFirst) / (2*(deltaFirst + cDist*cosBeta));
332  const auto firstPointOnShower = core - firstDistance*axis;
333  const double firstHeight = wgs84.PointToLatitudeLongitudeHeight(firstPointOnShower).get<2>();
334 
335  if (firstDistance < atmMinDistance || firstDistance > atmMaxDistance ||
336  firstHeight < atmMinHeight || firstHeight > atmMaxHeight) {
337  if (leavingAtmoIsError)
338  return false;
339  else {
340  map<FdConstants::LightSource, double> lightEfficiencies;
341  TelescopeDataBin telDataBin(0.,0.,0., Point(), Point(), Point(),
342  tMean,
343  halfBinWidth / addDense,
344  photonTrace.GetY(i),
345  photonTrace.GetYErr(i),
346  pow(bgTrace.GetYErr(i), 2),
347  lightEfficiencies, i);
348  noiseTelData.AddTelescopeDataBin(telDataBin);
349  continue;
350  }
351  }
352 
353  const double firstDepth = slantDepthProfile.Y(firstDistance);
354 
355  TimeStamp lastTimeAtTelescope = eyeTriggerTime + tLast;
356  const double deltaLast =
357  (lastTimeAtTelescope-coreTime).GetInterval()*kSpeedOfLight;
358  const double lastDistance =
359  -(cDist*cDist-deltaLast*deltaLast)/(2*(deltaLast+cDist*cosBeta));
360  const Point lastPointOnShower = core-lastDistance*axis;
361  const double lastHeight =
362  wgs84.PointToLatitudeLongitudeHeight(lastPointOnShower).get<2>();
363 
364  if (lastDistance < atmMinDistance || lastDistance > atmMaxDistance ||
365  lastHeight < atmMinHeight || lastHeight > atmMaxHeight) {
366  if (leavingAtmoIsError)
367  return false;
368  else {
369  map<FdConstants::LightSource, double> lightEfficiencies;
370  TelescopeDataBin telDataBin(0.,0.,0.,Point(),Point(),Point(),
371  tMean,
372  halfBinWidth/addDense,
373  photonTrace.GetY(i),
374  photonTrace.GetYErr(i),
375  pow(bgTrace.GetYErr(i),2),
376  lightEfficiencies, i);
377  noiseTelData.AddTelescopeDataBin(telDataBin);
378  continue;
379  }
380  }
381 
382  const double lastDepth = slantDepthProfile.Y(lastDistance);
383  const double meanDepth = (firstDepth + lastDepth) / 2.;
384  const double meanDistance = slantDistProfile.Y(meanDepth);
385  const Point meanPointOnShower = core - meanDistance * axis;
386  const double meanHeight =
387  wgs84.PointToLatitudeLongitudeHeight(meanPointOnShower).get<2>();
388  if (meanHeight < atmMinHeight || meanHeight > atmMaxHeight) {
389  if (leavingAtmoIsError)
390  return false;
391  else {
392  map<FdConstants::LightSource, double> lightEfficiencies;
393  TelescopeDataBin telDataBin(0.,0.,0.,Point(),Point(),Point(),
394  tMean,
395  halfBinWidth/addDense,
396  photonTrace.GetY(i),
397  photonTrace.GetYErr(i),
398  pow(bgTrace.GetYErr(i),2),
399  lightEfficiencies, i);
400  noiseTelData.AddTelescopeDataBin(telDataBin);
401  continue;
402  }
403  }
404 
405  if (!isfinite(firstDepth) || !isfinite(lastDepth))
406  continue;
407 
408  map<FdConstants::LightSource, double> lightEfficiencies;
409  if (fluorLCEff.get())
410  lightEfficiencies[FdConstants::eFluorDirect] =
411  fluorLCEff->GetY(i);
412  if (directCherLCEff.get())
413  lightEfficiencies[FdConstants::eCherDirect] =
414  directCherLCEff->GetY(i);
415  if (rayCherLCEff.get())
416  lightEfficiencies[FdConstants::eCherRayleighScattered] =
417  rayCherLCEff->GetY(i);
418  if (mieCherLCEff.get())
419  lightEfficiencies[FdConstants::eCherMieScattered] =
420  mieCherLCEff->GetY(i);
421 
422  TelescopeDataBin telDataBin(fmin(firstDepth,lastDepth),
423  fmax(firstDepth,lastDepth),
424  meanHeight,
425  firstPointOnShower,
426  lastPointOnShower,
427  meanPointOnShower,
428  tMean,
429  halfBinWidth/addDense,
430  photonTrace.GetY(i),
431  photonTrace.GetYErr(i),
432  pow(bgTrace.GetYErr(i),2),
433  lightEfficiencies, i);
434 
435  // ---- add zeta pixels
436  // pixel coordinates in CS with x-axis pointing to shower
437 
438  if (fMethod == ePrecise) {
439  Vector vecToShower = meanPointOnShower-detTel.GetPosition();
440  const double vecToShowerPhi = vecToShower.GetPhi(telEyeCS);
441  const double vecToShowerElevation =
442  kPiOnTwo-vecToShower.GetTheta(telEyeCS);
443  const CoordinateSystemPtr auxCS =
444  CoordinateSystem::RotationZ(vecToShowerPhi, telEyeCS);
445  const CoordinateSystemPtr toShowerCS =
446  CoordinateSystem::RotationY(-vecToShowerElevation, auxCS);
447 
448  const vector<unsigned int> pixelIdVec = zetaPixelIds[i];
449  for (unsigned int iPix=0; iPix < pixelIdVec.size(); ++iPix) {
450 
451  const unsigned int pixId = pixelIdVec[iPix];
452  const fdet::Pixel& thisPixel = detTel.GetPixel(pixId);
453  const Vector& pixelDir = thisPixel.GetDirection();
454  const double x = pixelDir.GetPhi(toShowerCS);
455  const double y = kPiOnTwo-pixelDir.GetTheta(toShowerCS);
456  // side length from solid angle
457  const double omega = thisPixel.GetSolidAngle();
458  const double sideLength = sqrt(2./3.*omega/kSqrt3);
459 
460  double tiltAngle = 0;
461 
462  // local tilt from slope to pixel from next column
463  // (if not a single pixel telescope)
464  if (detTel.GetFirstColumn() != detTel.GetLastColumn()) {
465  const unsigned int thisRow = thisPixel.GetRow();
466  const unsigned int thisColumn = thisPixel.GetColumn();
467  const unsigned int nextColumn =
468  (thisColumn == 1 ? thisColumn + 1: thisColumn - 1);
469  const fdet::Pixel& nextPixel = detTel.GetPixel(thisRow, nextColumn);
470  const double nextX = nextPixel.GetDirection().GetPhi(toShowerCS);
471  const double nextY =
472  kPiOnTwo-nextPixel.GetDirection().GetTheta(toShowerCS);
473  tiltAngle = atan2(nextY - y, nextX -x );
474  if (thisColumn == 1)
475  tiltAngle += kPi;
476  }
477 
478  telDataBin.AddZetaPixel( ZetaPixel(pixId, x, y, sideLength, tiltAngle));
479 
480  }
481  }
482 
483  telData.AddTelescopeDataBin(telDataBin);
484  noiseTelData.AddTelescopeDataBin(telDataBin);
485 
486  } catch (UTMPoint::UTMZoneException& d) {
487  ERROR(d.GetMessage());
488  continue;
489  }
490 
491  }
492 
493  } // end for each photon trace bin
494 
495  if (!telData.GetTelescopeDataBins().empty()) {
496  telData.SortBins();
497  noiseTelData.SortBins();
498  SetTelescopeParameters(eye, telData);
499  SetTelescopeParameters(eye, noiseTelData);
500  telData.SetZeta(telRecData.GetZeta());
501  noiseTelData.SetZeta(telRecData.GetZeta());
502  fTelescopeData.push_back(telData);
503  fNoiseTelescopeData.push_back(noiseTelData);
504  }
505 
506  } // end for each telescope
507 
508  if (!fTelescopeData.empty()) {
509 
510  fFOVsize = 0;
511  for (std::vector<TelescopeData>::const_iterator
512  telIter = fTelescopeData.begin();
513  telIter != fTelescopeData.end(); ++telIter)
514  fFOVsize += telIter->GetTelescopeDataBins().size();
515 
516  AddBinsOutsideFOV(eye);
517 
518  fNumberOfDepthBins = 0;
519  sort(fTelescopeData.begin(), fTelescopeData.end());
520  for (std::vector<TelescopeData>::const_iterator
521  telIter = fTelescopeData.begin();
522  telIter != fTelescopeData.end(); ++telIter)
523  fNumberOfDepthBins += telIter->GetTelescopeDataBins().size();
524 
525  sort(fNoiseTelescopeData.begin(), fNoiseTelescopeData.end());
526 
527  return true;
528  }
529 
530  return false;
531 }
532 
533 
534 void
535 CFMatrixCalculator::AddBinsOutsideFOV(const fevt::Eye& eye)
536 {
537  double minDepth = 0;
538  bool first = true;
539 
540  for (std::vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
541  telIter != fTelescopeData.end(); ++telIter) {
542 
543  const double minTelDepth = telIter->GetMinDepth();
544  if (first || minTelDepth < minDepth) {
545  minDepth = minTelDepth;
546  first = false;
547  }
548  }
549 
550  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
551  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
552  const ProfileResult& distProfile = atmo.EvaluateDistanceVsSlantDepth();
553  const double atmoMinDepth = distProfile.MinX();
554  const ProfileResult& verticalDepthProfile = atmo.EvaluateDepthVsHeight();
555  const double atmMinHeight = verticalDepthProfile.MinX();
556  const double atmMaxHeight = verticalDepthProfile.MaxX();
557  const double dX = 25.*(g/cm2); // depth step size
558 
559  const ShowerFRecData& shower = eye.GetRecData().GetFRecShower();
560  const Vector& axis = shower.GetAxis();
561  const Point& core = shower.GetCorePosition();
562 
563  // no C-light from below detector
564  const Point& detEyePos =
565  Detector::GetInstance().GetFDetector().GetEye(fEyeId).GetPosition();
566  const double minHeight =
567  wgs84.PointToLatitudeLongitudeHeight(detEyePos).get<2>();
568 
569  // push bins into fake telescope
570 
571  TelescopeData telData(0, TelescopeData::eOutsideFOV);
572  telData.SetZeta(1.3*degree);
573 
574  double thisDepth = minDepth;
575  while (thisDepth > atmoMinDepth+dX) {
576  const double nextDepth = thisDepth - dX;
577  const Point firstPointOnShower = core-distProfile.Y(nextDepth)*axis;
578  const Point lastPointOnShower = core-distProfile.Y(thisDepth)*axis;
579  const double meanDepth = (thisDepth+nextDepth)/2.;
580  const double meanDistance = distProfile.Y(meanDepth);
581  const Point meanPointOnShower = core-meanDistance*axis;
582  const map<FdConstants::LightSource, double> dummyEff;
583  const double meanHeight =
584  wgs84.PointToLatitudeLongitudeHeight(meanPointOnShower).get<2>();
585  if (meanHeight > minHeight && meanHeight > atmMinHeight &&
586  meanHeight < atmMaxHeight && fmin(thisDepth, nextDepth) > atmoMinDepth) {
587  telData.AddTelescopeDataBin(TelescopeDataBin(fmin(thisDepth,nextDepth),
588  fmax(thisDepth,nextDepth),
589  meanHeight,
590  firstPointOnShower,
591  lastPointOnShower,
592  meanPointOnShower,
593  0, 0, 0, 0, 0,
594  dummyEff, -1));
595  }
596 
597  thisDepth = nextDepth;
598  }
599 
600  if (fVerbosity > -1)
601  cout << gPrintPrefix
602  << " added " << telData.GetTelescopeDataBins().size()
603  << " bins outside FOV (X<" << minDepth/g*cm2 << ")"
604  << endl;
605 
606  if (!telData.GetTelescopeDataBins().empty()) {
607  telData.SortBins();
608  fTelescopeData.push_back(telData);
609  fNoiseTelescopeData.push_back(telData);
610  }
611 }
612 
613 
614 void
615 CFMatrixCalculator::CalculateDiagonalParameters()
616 {
617  fCherTransmissionToTel.clear();
618  fFluoTransmissionToTel.clear();
619 
620  const Atmosphere& atmo = Detector::GetInstance().GetAtmosphere();
621  const fdet::Eye& detEye =
622  Detector::GetInstance().GetFDetector().GetEye(fEyeId);
623 
624  // vector of C/F wave lengths
625  const std::vector<double>& lambdaCVec = fCherWaveLength;
626  const unsigned int nCLambda = lambdaCVec.size();
627  vector<double> cherenkovTelTransmission(nCLambda);
628  vector<double> cherenkovTrackTransmission(nCLambda);
629  vector<double> cherenkovRayleighScattering(nCLambda);
630  vector<double> cherenkovMieScattering(nCLambda);
631  vector<double> cherenkovProduction(nCLambda);
632 
633  const std::vector<double>& lambdaFVec = fFluoWaveLength;
634  const unsigned int nFLambda = lambdaFVec.size();
635  std::vector<double> fluorescenceTransmission(nFLambda);
636 
637  const double fourPi = 4.0*kPi;
638  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
639 
640  for (vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
641  telIter != fTelescopeData.end(); ++telIter) {
642 
643  const Point& telPos = telIter->GetType() == TelescopeData::eInsideFOV?
644  detEye.GetTelescope(telIter->GetId()).GetPosition():
645  detEye.GetPosition();
646 
647  for (vector<TelescopeDataBin>::const_iterator binIter =
648  telIter->TelDataBinsBegin();
649  binIter != telIter->TelDataBinsEnd(); ++binIter) {
650 
651  const Point& meanPos = binIter->fMeanDepthPoint;
652 
653  // ---- geometrical factor
654 
655  const Vector showerTelVec = telPos-meanPos;
656  const double distToTelSquared = showerTelVec.GetMag2();
657  const double distToTel = sqrt(distToTelSquared);
658  fGeometricalFactor.push_back(1./fourPi/distToTelSquared);
659  fZetaDistance.push_back(tan(telIter->GetZeta())*distToTel);
660 
661  // ---- average energy deposit per electron
662  const double alpha = utl::EnergyDeposit(binIter->GetMeanDepth(),
663  fXmax,
664  fElectronEnergyThreshold);
665  fMeandEdXPerElectron.push_back(alpha);
666 
667  // ---- local cosTheta
668  const double cosLocalZenith =
669  (-fShowerAxis).GetCosTheta(fwk::LocalCoordinateSystem::Create(UTMPoint(meanPos, wgs84)));
670  fCosTheta.push_back(cosLocalZenith);
671 
672  // ---- attenuation to telescope for cherenkov
673 
674  // Mie attenuation
675  const AttenuationResult mCAtt =
676  atmo.EvaluateMieAttenuation(telPos, meanPos, lambdaCVec);
677  const utl::TabulatedFunctionErrors& mieCAtt =
678  mCAtt.GetTransmissionFactor();
679  // Rayleigh attenuation
680  const AttenuationResult rCAtt =
681  atmo.EvaluateRayleighAttenuation(telPos, meanPos, lambdaCVec);
682  const utl::TabulatedFunctionErrors& rayCAtt =
683  rCAtt.GetTransmissionFactor();
684 
685  // ---- attenuation to telescope for fluorescence
686 
687  // Mie attenuation
688  const AttenuationResult mFAtt =
689  atmo.EvaluateMieAttenuation(telPos, meanPos, lambdaFVec);
690  const utl::TabulatedFunctionErrors& mieFAtt =
691  mFAtt.GetTransmissionFactor();
692  // Rayleigh attenuation
693  const AttenuationResult rFAtt =
694  atmo.EvaluateRayleighAttenuation(telPos, meanPos, lambdaFVec);
695  const utl::TabulatedFunctionErrors& rayFAtt =
696  rFAtt.GetTransmissionFactor();
697 
698  // --- scattering to telescope
699 
700  const double emissionAngle = Angle(fShowerAxis, showerTelVec);
701  ScatteringResult rScattering =
702  atmo.EvaluateRayleighScattering(binIter->fFirstPoint,
703  binIter->fLastPoint,
704  emissionAngle, distToTel, lambdaCVec);
705  ScatteringResult mScattering =
706  atmo.EvaluateMieScattering(binIter->fFirstPoint,
707  binIter->fLastPoint,
708  emissionAngle, distToTel, lambdaCVec);
709  const utl::TabulatedFunctionErrors& rayleighScattTrackTel =
710  rScattering.GetScatteringFactor();
711  const utl::TabulatedFunctionErrors& mieScattTrackTel =
712  mScattering.GetScatteringFactor();
713 
714  // --- transmission along track
715  const AttenuationResult mAtt =
716  atmo.EvaluateMieAttenuation(binIter->fFirstPoint,
717  binIter->fLastPoint, lambdaCVec);
718  const utl::TabulatedFunctionErrors& mieTrackAtt =
719  mAtt.GetTransmissionFactor();
720  const AttenuationResult rAtt =
721  atmo.EvaluateRayleighAttenuation(binIter->fFirstPoint,
722  binIter->fLastPoint, lambdaCVec);
723  const utl::TabulatedFunctionErrors& rayTrackAtt =
724  rAtt.GetTransmissionFactor();
725 
726  // --- cherenkov at track
727  const double showerAge = utl::ShowerAge(binIter->GetMeanDepth(), fXmax);
728  const utl::TabulatedFunction& cherenkovProd =
729  atmo.EvaluateCherenkovPhotons(binIter->fFirstPoint,
730  binIter->fLastPoint, showerAge);
731 
732  // --- finally copy to data members
733  for (unsigned int j=0; j<nCLambda; ++j) {
734  cherenkovRayleighScattering[j] = rayleighScattTrackTel.GetY(j);
735  cherenkovMieScattering[j] = mieScattTrackTel.GetY(j);
736  cherenkovTelTransmission[j] = mieCAtt.GetY(j)*rayCAtt.GetY(j);
737  cherenkovTrackTransmission[j] = rayTrackAtt.GetY(j)*mieTrackAtt.GetY(j);
738  cherenkovProduction[j] = cherenkovProd.GetY(j);
739  }
740 
741  for (unsigned int j=0; j<nFLambda; ++j)
742  fluorescenceTransmission[j] = mieFAtt.GetY(j) * rayFAtt.GetY(j);
743 
744  fFluoTransmissionToTel.push_back(fluorescenceTransmission);
745  fRayScatToTel.push_back(cherenkovRayleighScattering);
746  fMieScatToTel.push_back(cherenkovMieScattering);
747  fCherTransmissionToTel.push_back(cherenkovTelTransmission);
748  fCherenkovAtTrack.push_back(cherenkovProduction);
749  fCherTransmissionShower.push_back(cherenkovTrackTransmission);
750 
751  }
752  }
753 }
754 
755 
756 void
757 CFMatrixCalculator::CalculateFluorescenceMatrix()
758 {
759  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
760  const double dEdX0 = atmo.GetdEdX0();
761 
762  const std::vector<double>& lambdaVec = fFluoWaveLength;
763  const fdet::FDetector& fdDetector = Detector::GetInstance().GetFDetector();
764  const fdet::Eye& detEye = fdDetector.GetEye(fEyeId);
765  fDirectFluorescenceMatrix.SetSize(fNumberOfDepthBins);
766 
767  int i = 0;
768  for (vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
769  telIter != fTelescopeData.end(); ++telIter) {
770 
771  const bool realTelescope =
772  (telIter->GetType() == TelescopeData::eInsideFOV);
773  const unsigned int telId = realTelescope? telIter->GetId() :
774  detEye.GetFirstTelescopeId();
775 
776  const TabulatedFunction& relEff =
777  fdDetector.GetEye(fEyeId).GetTelescope(telId).GetMeasuredRelativeEfficiency();
778 
779  const Point& telPos = detEye.GetTelescope(telId).GetPosition();
780 
781  for (vector<TelescopeDataBin>::const_iterator binIter =
782  telIter->TelDataBinsBegin();
783  binIter != telIter->TelDataBinsEnd(); ++binIter) {
784 
785  const double height = binIter->fHeight;
786 
787  const utl::TabulatedFunction& fluoyield_tab =
788  atmo.EvaluateFluorescenceYield(height);
789 
790  double epsYTsum = 0.;
791  for (unsigned int j = 0; j < lambdaVec.size(); j++) {
792  const double Y_j = fluoyield_tab.Y(lambdaVec[j]);
793  epsYTsum += Y_j * relEff.Y(lambdaVec[j]) * fFluoTransmissionToTel[i][j];
794  }
795 
796  const double deltaL =
797  (binIter->fFirstPoint - binIter->fLastPoint).GetMag();
798  const double lldFraction =
799  fLateralLightCalculator->GetLightFraction(FdConstants::eFluorDirect,
800  *binIter, *binIter,
801  detEye.GetTelescope(telId),
802  fXmax,
803  fCosTheta[i],
804  telIter->GetZeta());
805 
806  const double msFactor =
807  1. / (1 - MultipleScatteringFraction(*binIter,
808  lambdaVec,
809  fluoyield_tab,
810  telIter->GetZeta(),
811  telPos,
812  relEff));
813  fFluorescenceMultipleScattering.push_back(msFactor);
814 
815  fDirectFluorescenceMatrix(i,i) = lldFraction * msFactor *
816  epsYTsum * fGeometricalFactor[i] / dEdX0 * deltaL;
817 
818  ++i;
819  }
820  }
821 }
822 
823 
824 void
825 CFMatrixCalculator::CalculateDirectCherenkovMatrix()
826 {
827  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
828  const std::vector<double>& lambdaVec = fCherWaveLength;
829  const fdet::FDetector& fdDetector = Detector::GetInstance().GetFDetector();
830  const fdet::Eye& detEye = fdDetector.GetEye(fEyeId);
831 
832  fDirectCherenkovMatrix.SetSize(fNumberOfDepthBins);
833 
834  int i = 0;
835  for (vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
836  telIter != fTelescopeData.end(); ++telIter) {
837 
838  const bool realTelescope =
839  (telIter->GetType() == TelescopeData::eInsideFOV);
840  const unsigned int telId = realTelescope? telIter->GetId() :
841  detEye.GetFirstTelescopeId();
842 
843  const TabulatedFunction& relEff =
845 
846  const Point& telPos = detEye.GetTelescope(telId).GetPosition();
847 
848  for (vector<TelescopeDataBin>::const_iterator binIter =
849  telIter->TelDataBinsBegin();
850  binIter != telIter->TelDataBinsEnd(); ++binIter) {
851 
852  const double showerAge = utl::ShowerAge(binIter->GetMeanDepth(),fXmax);
853  const utl::TabulatedFunction& directCherenkov =
854  atmo.EvaluateCherenkovDirect(binIter->fFirstPoint,
855  binIter->fLastPoint, telPos, showerAge);
856  double epsYTsum=0.;
857  for (unsigned int j = 0; j < lambdaVec.size(); j++) {
858  const double Y_j = directCherenkov.GetY(j);
859  epsYTsum += Y_j * relEff.Y(lambdaVec[j]) * fCherTransmissionToTel[i][j];
860  }
861 
862  const double lldFraction =
863  fLateralLightCalculator->GetLightFraction(FdConstants::eCherDirect,
864  *binIter, *binIter,
865  detEye.GetTelescope(telId),
866  fXmax,
867  fCosTheta[i],
868  telIter->GetZeta());
869 
870  const double msFactor =
871  1. / (1 - MultipleScatteringFraction(*binIter,
872  lambdaVec,
873  directCherenkov,
874  telIter->GetZeta(),
875  telPos,
876  relEff));
877  fCherenkovMultipleScattering.push_back(msFactor);
878 
879  fDirectCherenkovMatrix(i) =
880  epsYTsum / fMeandEdXPerElectron[i] * msFactor * lldFraction;
881 
882  ++i;
883  }
884  }
885 }
886 
887 
888 void
889 CFMatrixCalculator::CalculateMieAndRayScattCherenkovMatrix()
890 {
891  fMieScatteredCherenkovMatrix.SetSize(fNumberOfDepthBins);
892  fRayScatteredCherenkovMatrix.SetSize(fNumberOfDepthBins);
893 
894  const fdet::FDetector& fdDetector = Detector::GetInstance().GetFDetector();
895  const fdet::Eye& detEye = fdDetector.GetEye(fEyeId);
896 
897  const unsigned int nLambda = fCherWaveLength.size();
898  vector<double> transmission(nLambda);
899 
900  int i = 0;
901  for (vector<TelescopeData>::const_iterator telIter_i = fTelescopeData.begin();
902  telIter_i != fTelescopeData.end(); ++telIter_i) {
903  const bool realTelescope = telIter_i->GetType() == TelescopeData::eInsideFOV;
904  const unsigned int telId =
905  realTelescope? telIter_i->GetId() : detEye.GetFirstTelescopeId();
906 
907  const TabulatedFunction& relEff =
908  fdDetector.GetEye(fEyeId).GetTelescope(telId).GetMeasuredRelativeEfficiency();
909 
910  for (vector<TelescopeDataBin>::const_iterator binIter_i = telIter_i->TelDataBinsBegin();
911  binIter_i != telIter_i->TelDataBinsEnd(); ++binIter_i) {
912 
913  const double msFactor = fCherenkovMultipleScattering[i];
914 
915  for (unsigned int k = 0; k < nLambda; ++k)
916  transmission[k] = 1;
917 
918  const bool realTelescope =
919  (telIter_i->GetType() == TelescopeData::eInsideFOV);
920  const unsigned int telId = realTelescope? telIter_i->GetId():
921  detEye.GetFirstTelescopeId();
922 
923  for (int j = i; j >= 0; --j) {
924 
925  // check for telescope overlaps that might (should!) occur
926  // in lightCollectionEfficiency-mode
927  if (IsOverlapBin(i,j)) {
928  fMieScatteredCherenkovMatrix(i, j) = 0;
929  fRayScatteredCherenkovMatrix(i, j) = 0;
930  continue;
931  }
932 
933  double epsYTsumMie = 0;
934  double epsYTsumRay = 0;
935  for (unsigned int k = 0; k < nLambda; ++k) {
936 
937  if (j != i)
938  transmission[k]*=fCherTransmissionShower[j][k];
939 
940  const double detEff = relEff.Y(fCherWaveLength[k]);
941  const double factor =
942  transmission[k]*detEff*fCherenkovAtTrack[j][k]*
943  fCherTransmissionToTel[i][k];
944 
945  epsYTsumMie += factor*fMieScatToTel[i][k];
946  epsYTsumRay += factor*fRayScatToTel[i][k];
947 
948  }
949 
950  const double oneOverAlpha = 1 / fMeandEdXPerElectron[j];
951 
952  fMieScatteredCherenkovMatrix(i, j) = epsYTsumMie * oneOverAlpha;
953  fRayScatteredCherenkovMatrix(i, j) = epsYTsumRay * oneOverAlpha;
954 
955  const TelescopeDataBin& emissionBin = *(GetTelescopeDataBin(j).second);
956  const TelescopeDataBin& detectionBin = *binIter_i;
957 
958  // no difference between eCherMieScattered and eCherRayScattered
960 
961  const double lldFraction =
962  fLateralLightCalculator->GetLightFraction(lightType,
963  emissionBin, detectionBin,
964  detEye.GetTelescope(telId),
965  fXmax,
966  fCosTheta[i],
967  telIter_i->GetZeta());
968  fRayScatteredCherenkovMatrix(i,j) *= (lldFraction*msFactor);
969  fMieScatteredCherenkovMatrix(i,j) *= (lldFraction*msFactor);
970 
971  }
972 
973  ++i;
974  }
975  }
976 }
977 
978 
980 CFMatrixCalculator::CalculateLCEff(const FdConstants::LightSource lightSource,
981  const TelescopeRecData& telRecData)
982  const
983 {
984  utl::TabulatedFunctionErrors* lcEff = nullptr;
985 
986  // fetch lceff from TelescopeRecData if available...
987  if (telRecData.HasLightCollectionEfficiency()) {
988  const MultiTabulatedFunctionErrors& lcEffs =
989  telRecData.GetLightCollectionEfficiency();
990  if (lcEffs.HasLabel(lightSource)) {
991  const utl::TabulatedFunctionErrors& tmp =
992  lcEffs.GetTabulatedFunctionErrors(lightSource);
993  lcEff = new utl::TabulatedFunctionErrors(tmp);
994  }
995  }
996 
997  return lcEff;
998 }
999 
1000 
1001 void
1002 CFMatrixCalculator::Clear()
1003 {
1004  fCFMatrix.Clear();
1005  fMieScatteredCherenkovMatrix.Clear();
1006  fRayScatteredCherenkovMatrix.Clear();
1007  fDirectCherenkovMatrix.Clear();
1008  fDirectFluorescenceMatrix.Clear();
1009  fTelescopeData.clear();
1010  fNoiseTelescopeData.clear();
1011  fCherWaveLength.clear();
1012  fFluoWaveLength.clear();
1013  fCherTransmissionToTel.clear();
1014  fFluoTransmissionToTel.clear();
1015  fCherTransmissionShower.clear();
1016  fRayScatToTel.clear();
1017  fMieScatToTel.clear();
1018  fFluorescenceMultipleScattering.clear();
1019  fCherenkovMultipleScattering.clear();
1020  fCherenkovAtTrack.clear();
1021  fGeometricalFactor.clear();
1022  fZetaDistance.clear();
1023  fMeandEdXPerElectron.clear();
1024 }
1025 
1026 
1027 pair<const TelescopeData*, const TelescopeDataBin*>
1028 CFMatrixCalculator::GetTelescopeDataBin(const unsigned int i)
1029  const
1030 {
1031  int j = 0;
1032  for (std::vector<TelescopeData>::const_iterator
1033  telIter = fTelescopeData.begin();
1034  telIter != fTelescopeData.end(); ++telIter) {
1035  const unsigned int thisSize =
1036  telIter->TelDataBinsEnd()-telIter->TelDataBinsBegin();
1037  if (j + thisSize > i) {
1038  const TelescopeData* tel = &(*telIter);
1039  const TelescopeDataBin* data = &(*(telIter->TelDataBinsBegin()+(i-j)));
1040  return pair<const TelescopeData*, const TelescopeDataBin*>(tel, data);
1041  } else
1042  j += thisSize;
1043  }
1044 
1045  // if reach this point --> error
1046  ostringstream errMsg;
1047  errMsg << " request bin " << i << " in ";
1048  for (std::vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
1049  telIter != fTelescopeData.end(); ++telIter)
1050  errMsg << "(tel " << telIter->GetId() << " n="
1051  << telIter->TelDataBinsEnd()-telIter->TelDataBinsBegin()
1052  << ") ";
1053 
1054  ERROR(errMsg.str());
1055  throw OutOfBoundException(errMsg.str());
1056 
1057  // to make compiler happy
1058  return pair<const TelescopeData*, const TelescopeDataBin*>
1059  (&fTelescopeData[0], &(*fTelescopeData[0].TelDataBinsBegin()));
1060 }
1061 
1062 
1063 bool
1064 CFMatrixCalculator::IsOverlapBin(const int i, const int j)
1065  const
1066 {
1067  // check causality
1068  if (j > i)
1069  return true;
1070 
1071  typedef std::pair<const TelescopeData*, const TelescopeDataBin*> TelDataPair;
1072  TelDataPair data_j = GetTelescopeDataBin(j);
1073  TelDataPair data_i = GetTelescopeDataBin(i);
1074 
1075  // same telescope is always OK
1076  if (data_i.first->GetId() == data_j.first->GetId())
1077  return false;
1078 
1079  // different telescope j, but depth_j in telescope i is not OK
1080  if (data_i.first->DepthInRange(data_j.second->fMinDepth) ||
1081  data_i.first->DepthInRange(data_j.second->fMaxDepth)) {
1082 #ifdef _CFMDEBUG_
1083  cout << " overlap type1, i=" << i << " j=" << j << " depth(j)="
1084  << data_j.second->GetMeanDepth()/g*cm2 << " tel_j="
1085  << data_j.first->GetId()
1086  << " tel_i " << data_i.first->GetId() << " X=["
1087  << data_i.first->GetMinDepth()/g*cm2 << ","
1088  << data_i.first->GetMaxDepth()/g*cm2 << "]" << endl;
1089 #endif
1090  return true;
1091  }
1092 
1093  // depth_j occurs the first time in tel_j is OK
1094  for (vector<TelescopeData>::const_iterator telIter = fTelescopeData.begin();
1095  telIter != fTelescopeData.end(); ++telIter) {
1096  if (telIter->DepthInRange(data_j.second->fMinDepth) ||
1097  telIter->DepthInRange(data_j.second->fMaxDepth)) {
1098  if (telIter->GetId() != data_j.first->GetId()) {
1099 #ifdef _CFMDEBUG_
1100  cout << " overlap type2, i=" << i << " j=" << j << " depth(j)="
1101  << data_j.second->GetMeanDepth()/g*cm2 << " tel_j="
1102  << data_j.first->GetId()
1103  << " tel_k " << telIter->GetId() << " X=["
1104  << telIter->GetMinDepth()/g*cm2 << ","
1105  << telIter->GetMaxDepth()/g*cm2 << "]" << endl;
1106 #endif
1107  return true;
1108  }
1109  else
1110  return false;
1111  }
1112  }
1113 
1114  // this part should never be reached
1115  ostringstream errMsg;
1116  errMsg << " logical error for i=" << i << " j=" << j;
1117  ERROR(errMsg.str());
1118  throw OutOfBoundException(errMsg.str());
1119 
1120  return true;
1121 }
1122 
1123 
1124 void
1125 CFMatrixCalculator::SetTelescopeParameters(const fevt::Eye& eye,
1126  TelescopeData& telData)
1127  const
1128 {
1129  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
1130  const double referenceLambda = detFD.GetReferenceLambda();
1131  const fevt::Telescope& evtTel = eye.GetTelescope(telData.GetId());
1132 
1133  double avgPEfactor = 0;
1134  int countPix = 0;
1137  pixiter != evtTel.PixelsEnd(ComponentSelector::eHasData);
1138  ++pixiter) {
1139  const fdet::Pixel& detPixel = detFD.GetPixel(*pixiter);
1140  avgPEfactor += detPixel.GetDiaPhoton2PEFactor(referenceLambda);
1141  ++countPix;
1142  }
1143 
1144  if (countPix)
1145  avgPEfactor /= countPix;
1146 
1147  const fdet::Telescope& detTel = detFD.GetTelescope(evtTel);
1148 
1149  telData.SetTelescopeParameters(avgPEfactor,
1150  detTel.GetCamera().GetGainVariance(),
1151  detTel.GetDiaphragmArea());
1152 }
1153 
1154 
1155 /******************************************************************\
1156  *
1157  * MultipleScatteringFraction()
1158  *
1159  * fraction of multiple scattered light wrt. total signal from
1160  *
1161  * M. Roberts, J.Phys.G31:1291,2005
1162  *
1163  *
1164 \******************************************************************/
1165 double
1166 CFMatrixCalculator::MultipleScatteringFraction(const TelescopeDataBin& telDataBin,
1167  const std::vector<double>& waveLengths,
1168  const utl::TabulatedFunction& yield,
1169  const double zeta,
1170  const Point& telescopePosition,
1171  const TabulatedFunction& efficiency)
1172  const
1173 {
1174  if (!fDoMultipleScattering)
1175  return 0;
1176 
1177  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
1178 
1179  // optical depth and scattering coefficient
1180 
1181  // attenuation shower-->eye
1182  const utl::Point& meanPos = telDataBin.fMeanDepthPoint;
1183  const AttenuationResult mieResultAttShowerToEye =
1184  atmo.EvaluateMieAttenuation(telescopePosition,
1185  meanPos,
1186  waveLengths);
1187  const utl::TabulatedFunctionErrors& mieAttShowerToEye =
1188  mieResultAttShowerToEye.GetTransmissionFactor();
1189 
1190  const AttenuationResult rayAttResultShowerToEye =
1191  atmo.EvaluateRayleighAttenuation(telescopePosition,
1192  meanPos,
1193  waveLengths);
1194  const utl::TabulatedFunctionErrors& rayAttShowerToEye =
1195  rayAttResultShowerToEye.GetTransmissionFactor();
1196 
1197  // attenuation within bin
1198  const AttenuationResult mieAttResultInBin =
1199  atmo.EvaluateMieAttenuation(telDataBin.fFirstPoint,
1200  telDataBin.fLastPoint,
1201  waveLengths);
1202  const utl::TabulatedFunctionErrors& mieAttInBin =
1203  mieAttResultInBin.GetTransmissionFactor();
1204 
1205  const AttenuationResult rayAttResultInBin =
1206  atmo.EvaluateRayleighAttenuation(telDataBin.fFirstPoint,
1207  telDataBin.fLastPoint,
1208  waveLengths);
1209  const utl::TabulatedFunctionErrors& rayAttInBin =
1210  rayAttResultInBin.GetTransmissionFactor();
1211 
1212  double yieldEffSum = 0;
1213  double yieldEffAttEyeSum = 0;
1214  double yieldEffAttBinSum = 0;
1215 
1216  for (unsigned int j = 0; j < waveLengths.size(); ++j) {
1217  const double Y_j = yield.Y(waveLengths[j]);
1218  const double eff = efficiency.Y(waveLengths[j]);
1219  const double attEye = rayAttShowerToEye.GetY(j)*mieAttShowerToEye.GetY(j);
1220  const double attBin = rayAttInBin.GetY(j)*mieAttInBin.GetY(j);
1221 
1222  const double yEff = Y_j*eff;
1223  yieldEffSum += yEff;
1224  yieldEffAttEyeSum += yEff*attEye;
1225  yieldEffAttBinSum += yEff*attBin;
1226  }
1227 
1228  const double distanceToEye = (meanPos-telescopePosition).GetMag();
1229  const double binLength = (telDataBin.fFirstPoint-
1230  telDataBin.fLastPoint).GetMag();
1231 
1232  const double attenuationToEye = yieldEffAttEyeSum/yieldEffSum;
1233  const double attenuationInBin = yieldEffAttBinSum/yieldEffSum;
1234 
1235  const double opticalDepth = attenuationToEye > 0 ?
1236  -log(attenuationToEye):
1238  const double alphaTot = attenuationInBin > 0 ?
1239  -log(attenuationInBin)/binLength:
1241 
1242  // see Eq. (3) in Mike's paper
1243  const double argument = opticalDepth * alphaTot/utl::m *
1244  sqrt(distanceToEye/utl::m) *
1245  pow(zeta/utl::degree, 1.1);
1246  const double fraction = 0.774 * pow(argument , 0.68);
1247 
1248  return fraction;
1249 }
Telescope & GetTelescope(const unsigned int telescopeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Retrieve Telescope by Id, throw exception if not existent.
Definition: FEvent/Eye.cc:57
unsigned int GetId() const
Definition: FEvent/Eye.h:54
const utl::Vector & GetDirection() const
pointing direction of this pixel
Top of the interface to Atmosphere information.
const utl::TabulatedFunction & EvaluateFluorescenceYield(const double heightAboveSeaLevel) const
Evaluated Fluorescence Yield for a specific model.
constexpr double mm
Definition: AugerUnits.h:113
const double degree
Point object.
Definition: Point.h:32
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
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
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
unsigned int GetColumn(const unsigned int pixelid) const
const Pixel & GetPixel(const fevt::Pixel &eventPixel) const
Get fdet::Pixel from fevt::Channel.
Definition: FDetector.cc:198
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
Class to hold collection (x,y) points and provide interpolation between them.
const std::string gPrintPrefix
double GetMeasuredRelativeEfficiency(const double wl) const
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
double GetGainVariance() const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Base class for exceptions trying to access non-existing components.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
unsigned int GetFirstTelescopeId() const
First telescope id in the eye.
double pow(const double x, const unsigned int i)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Report attempts to use invalid UTM zone.
Definition: UTMPoint.h:300
PixelIterator PixelsEnd()
iterator pointing to end of available pixels of status eHasData (DEPRECATED)
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
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
Exception for reporting variable out of valid range.
Class holding the output of the ScatteringResult function.
double GetSolidAngle() const
The solid angle viewed by this pixel.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Reference ellipsoids for UTM transformations.
LightSource
Possible light sources.
Definition: FdConstants.h:9
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
const utl::TabulatedFunction & EvaluateCherenkovDirect(const utl::Point &xA, const utl::Point &xB, const utl::Point &xEye, const double showerAge) const
constexpr double kPi
Definition: MathConstants.h:24
const Telescope & GetTelescope(const unsigned int telescopeId) const
Find Telescope by numerical Id.
constexpr double fraction
Definition: AugerUnits.h:281
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
constexpr double kSqrt3
Definition: MathConstants.h:31
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
unsigned int GetId() const
Eye numerical Id.
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
boost::filter_iterator< ComponentSelector, ConstAllPixelIterator > ConstPixelIterator
constexpr double kPiOnTwo
Definition: MathConstants.h:25
constexpr double degree
atm::ScatteringResult EvaluateRayleighScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const
Telescope-specific shower reconstruction data.
constexpr double g
Definition: AugerUnits.h:200
utl::MultiTabulatedFunctionErrors & GetLightCollectionEfficiency()
Get the light-collection-efficiency multi tabulated function (for various LightSources) ...
A collection of TabulatedFunctionErrors, which provides methods to access different sources...
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
TabulatedFunctionErrors & GetTabulatedFunctionErrors(const int label=0)
Returns the TabulatedFunctionErrors for /par source.
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
const double & GetY(const unsigned int idx) const
bool HasLightCollectionEfficiency() const
Check that a light-collection-efficiency multi tabulated function exists (for various LightSources) ...
double GetReferenceLambda() const
Definition: FDetector.cc:332
const utl::TabulatedFunctionErrors & GetScatteringFactor() const
Scattering factor.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
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.
const Telescope & GetTelescope(const fevt::Telescope &eventTel) const
Get fdet::Telescope from fevt::Telescope.
Definition: FDetector.cc:150
double GetDiaphragmArea() const
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
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
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
void SetTelescopeParameters(double peFactor, double gainVariance, double diaArea)
uint16_t * data
Definition: dump1090.h:228
Description of a pixel.
utl::Point GetPosition() const
const utl::TabulatedFunction & EvaluateCherenkovPhotons(const utl::Point &xA, const utl::Point &xB, const double showerAge) const
double EnergyDeposit(const double age, const double enCut)
Parametrization for the average energy deposit per particle.
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.
double GetdEdX0() const
get reference energy deposit for fluorescence yield model
const std::vector< TelescopeDataBin > & GetTelescopeDataBins() const
double CosAngle(const Vector &l, const Vector &r)
Definition: OperationsVV.h:71
constexpr double ns
Definition: AugerUnits.h:162
Fluorescence Detector Telescope Event.
PixelIterator PixelsBegin()
iterator pointing to first available pixel of status eHasData (DEPRECATED)
void AddZetaPixel(const ZetaPixel &pixel)
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
unsigned int GetRow(const unsigned int pixelid) const
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
double GetDiaPhoton2PEFactor(const double wavelength, const std::string &configSignature="") const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
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.
utl::Point GetPosition() const
Eye position.
bool HasLabel(const int label) const
Definition: MultiObject.h:91
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
Class describing the Atmospheric attenuation.
void AddTelescopeDataBin(const TelescopeDataBin &telDataBin)
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
constexpr double cm2
Definition: AugerUnits.h:118
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
double GetMag2() const
Definition: Vector.h:61
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.