ShowerPhotonGenerator.cc
Go to the documentation of this file.
1 
12 #include <utl/config.h>
13 
14 #include "ShowerPhotonGenerator.h"
15 #include "MultipleScatterer.h"
16 
17 #include <utl/Reader.h>
18 #include <utl/ErrorLogger.h>
19 #include <utl/AugerUnits.h>
20 #include <utl/MathConstants.h>
21 #include <utl/Math.h>
22 #include <utl/PhysicalConstants.h>
23 #include <utl/PhysicalFunctions.h>
24 #include <utl/Point.h>
25 #include <utl/Vector.h>
26 #include <utl/TabulatedFunction.h>
27 #include <utl/TabulatedFunctionErrors.h>
28 #include <utl/Trace.h>
29 #include <utl/MultiTabulatedFunction.h>
30 #include <utl/Photon.h>
31 #include <utl/RandomEngine.h>
32 #include <utl/RandomSamplerFromPDF.h>
33 #include <utl/UTMPoint.h>
34 
35 #include <fwk/CentralConfig.h>
36 #include <fwk/CoordinateSystemRegistry.h>
37 #include <fwk/LocalCoordinateSystem.h>
38 #include <fwk/RandomEngineRegistry.h>
39 
40 #include <det/Detector.h>
41 
42 #include <fdet/FDetector.h>
43 #include <fdet/Eye.h>
44 #include <fdet/Telescope.h>
45 #include <fdet/Mirror.h>
46 #include <fdet/Filter.h>
47 #include <fdet/Corrector.h>
48 #include <fdet/Camera.h>
49 
50 #include <evt/Event.h>
51 #include <evt/ShowerSimData.h>
52 #include <evt/LaserData.h> // Modified by D'Urso & Valore 02/03/06
53 
54 #include <fevt/FEvent.h>
55 #include <fevt/Eye.h>
56 #include <fevt/TelescopeSimData.h>
57 #include <fevt/Telescope.h>
58 
59 #include <atm/ProfileResult.h>
60 #include <atm/InclinedAtmosphericProfile.h>
61 
62 #include <CLHEP/Random/Randomize.h>
63 
64 #include <boost/tuple/tuple.hpp>
65 
66 #include <iomanip>
67 #include <fstream>
68 #include <sstream>
69 #include <map>
70 
71 #include <TROOT.h>
72 #include <TStyle.h>
73 #include <TH1D.h>
74 #include <TCanvas.h>
75 #include <TLegend.h>
76 
77 // #define DEBUG 1
78 // #define DEBUG_3D 1
79 
80 using namespace ShowerPhotonGeneratorOG;
81 using namespace std;
82 using namespace utl;
83 using namespace evt;
84 using namespace fwk;
85 using namespace det;
86 using namespace fdet;
87 using namespace atm;
88 
89 using CLHEP::RandFlat;
90 
91 
92 
94  fUseOnlyReferenceWavelength(false),
95  fFluorescenceLDF(eOff),
96  fScatteredCherenkovLDF(eOff),
97  fDirectCherenkovLDF(eOff),
98  fLightSourceSelector(-2),
99  fMultipleScatterer(NULL)
100 {
101 }
102 
103 
106 {
107  CentralConfig* const cc = CentralConfig::GetInstance();
108  Branch topB = cc->GetTopBranch("ShowerPhotonGenerator");
109 
110  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
111 
112  topB.GetChild("maxNRayTracePerBin").GetData(fMaxNRayTrace);
113  topB.GetChild("minNRayTracePerBin").GetData(fMinNRayTrace);
114  topB.GetChild("extraRayTraceFactor").GetData(fExtraRayTraceFactor);
115 
116  string fluorescence3D;
117  topB.GetChild("FluorescenceLDF").GetData(fluorescence3D);
118  if (fluorescence3D == "off")
120  else if (fluorescence3D == "NKG")
122  else if (fluorescence3D == "Gora")
124  else {
125  ostringstream err;
126  err << " Unknown fluorescence LDF mode: \"" << fluorescence3D;
127  ERROR(err);
128  return eFailure;
129  }
130 
131  string cherenkov3D;
132  topB.GetChild("DirectCherenkovLDF").GetData(cherenkov3D);
133  if (cherenkov3D == "off")
135  else if (cherenkov3D == "NKG")
137  else if (cherenkov3D == "Gora")
139  else if (cherenkov3D == "Cherenkov")
141  else if (cherenkov3D == "CherenkovAtAxis")
143  else if (cherenkov3D == "CORSIKA")
145  else {
146  ostringstream err;
147  err << " Unknown direct cherenkov LDF option: " << cherenkov3D;
148  ERROR(err);
149  return eFailure;
150  }
151  topB.GetChild("ScatteredCherenkovLDF").GetData(cherenkov3D);
152  if (cherenkov3D == "off")
154  else if (cherenkov3D == "NKG")
156  else if (cherenkov3D == "Gora")
158  else if (cherenkov3D == "Cherenkov")
160  else if (cherenkov3D == "CherenkovAtAxis")
162  else {
163  ostringstream err;
164  err << " Unknown scattered cherenkov LDF option: " << cherenkov3D;
165  ERROR(err);
166  return eFailure;
167  }
168  topB.GetChild("MultipleScattering").GetData(fMultipleScattering);
169 
170  // ---- info output -----
171  ostringstream info;
172  info << " Version: "
173  << GetVersionInfo(VModule::eRevisionNumber) << "\n"
174  " Parameters:\n"
175  " max raytraced photons per time bin: " << fMaxNRayTrace<< "\n"
176  " min raytraced photons per time bin: " << fMinNRayTrace<< "\n"
177  " artificial factor for extra photons: " << fExtraRayTraceFactor<< "\n"
178  " fluorescence LDF: ";
179  switch (fFluorescenceLDF) {
180  case eOff: info << "off\n"; break;
181  case eNKG: info << "NKG\n"; break;
182  case eGora: info << "Gora et al.\n"; break;
183  default: info << "UNKNOWN\n"; break;
184  }
185  info << " direct Cherenkov LDF: ";
186  switch (fDirectCherenkovLDF) {
187  case eOff: info << "off\n"; break;
188  case eNKG: info << "NKG\n"; break;
189  case eGora: info << "Gora\n"; break;
190  case eCherenkov: info << "full sim. Cherenkov emission\n"; break;
191  case eCherenkovAtAxis: info << "Cherenkov sim. for electrons at axis\n"; break;
192  case eCherenkovCORSIKA: info << "Cherenkov input from CORSIKA\n"; break;
193  }
194  info << " scattered Cherenkov LDF: ";
195  switch (fScatteredCherenkovLDF) {
196  case eOff: info << "off\n"; break;
197  case eNKG: info << "NKG\n"; break;
198  case eGora: info << "Gora\n"; break;
199  case eCherenkov: info << "full sim. Cherenkov emission\n"; break;
200  case eCherenkovAtAxis: info << "Cherenkov sim. for electrons at axis\n"; break;
201  case eCherenkovCORSIKA: info << "eCherenkovCORSIKA?\n"; break;
202  }
203  info << " multiple scattering: " << (fMultipleScattering ? "ON" : "OFF") << "\n";
204  INFO(info);
205 
208 
210 //#warning Sim. Cherenkov LDF for direct Cherenkov emission not implemeted yet.
211  ERROR("Sim. Cherenkov LDF for direct Cherenkov emission not implemeted yet.");
212  return eFailure;
213  }
214 
215  return eSuccess;
216 } // end of Init
217 
218 
219 // ************************************************************************
222 {
223  if (!event.HasFEvent()) {
224  ERROR ("Event has no FEvent.");
225  return eContinueLoop;
226  }
227  fevt::FEvent& fEvent = event.GetFEvent();
228 
229  if (!event.HasSimShower() ||
230  !event.GetSimShower().HasDirection() ||
231  (!event.GetSimShower().HasGHParameters() && !event.GetSimShower().HasLaserData())) {
232  ERROR ("Event has no sim-data.");
233  return eContinueLoop;
234  }
235 
236  evt::ShowerSimData& simShower = event.GetSimShower();
237  const CoordinateSystemPtr& showerCS = simShower.GetShowerCoordinateSystem();
238 
239  const bool isLaser = simShower.HasLaserData();
240 
241  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
242  const Point showerCore(0, 0, 0, showerCS);
243  const Vector showerAxis(0, 0, -1, showerCS);
244 
245  const CoordinateSystemPtr localCS = simShower.GetLocalCoordinateSystem();
246  const double cosZenith = (-simShower.GetDirection()).GetCosTheta(localCS); // just for flat earth
247  const double absCosZenith = std::fabs(cosZenith); // just for flat earth
248  const double coreZ = wgs84.PointToLatitudeLongitudeHeight(showerCore).get<2>();
249 
250  Detector& detector = Detector::GetInstance();
251  const FDetector& detFD = detector.GetFDetector();
252  const Atmosphere& atmo = detector.GetAtmosphere();
253 
254  const double refWl = detFD.GetReferenceLambda();
255  const vector<double>& WLengthFluo = atmo.GetWavelengths(Atmosphere::eFluorescence);
256  const vector<double>& WLengthCkov = atmo.GetWavelengths(Atmosphere::eCerenkov);
257  const int nWLengthCkov = WLengthCkov.size();
258 
259  const ProfileResult& depthProfile = atmo.EvaluateDepthVsHeight();
260  const ProfileResult& temperatureProfile = atmo.EvaluateTemperatureVsHeight();
261  const ProfileResult& pressureProfile = atmo.EvaluatePressureVsHeight();
262 
263  const double tempHeightMin = temperatureProfile.MinX();
264  const double tempHeightMax = temperatureProfile.MaxX();
265  const double pressHeightMin = pressureProfile.MinX();
266  const double pressHeightMax = pressureProfile.MaxX();
267 
268  bool flatEarth = false;
269  ProfileResult const * slantDepthVsDistance = 0;
270  double atmDistanceMin = 0;
271  double atmDistanceMax = 0;
272  if (!isLaser && (fFluorescenceLDF != eOff ||
273  (fDirectCherenkovLDF != eOff) ||
275  try {
276  slantDepthVsDistance = &atmo.EvaluateSlantDepthVsDistance();
278  flatEarth = true;
279  }
280  atmDistanceMin = flatEarth ? (coreZ - depthProfile.MinX()) / absCosZenith : slantDepthVsDistance->MinX();
281  atmDistanceMax = flatEarth ? (coreZ - depthProfile.MaxX()) / absCosZenith : slantDepthVsDistance->MaxX();
282  }
283 
284  double X1 = 0;
285  double showerXmax = 0;
286  double laserWavelength = 0;
287  if (!isLaser) {
288  X1 = simShower.GetXFirst();
289  showerXmax = simShower.GetGHParameters().GetXMax();
290  } else {
291  laserWavelength = simShower.GetLaserData().GetLaserWavelength();
292  }
293 
294  // For making nice LDF-pictures -----------
295  // Add shower ages to following vector to
296  // produce LDF pictures
297  vector<double> ages;
298  //ages.push_back(0.7);
299  //ages.push_back(0.9);
300  //ages.push_back(1.0);
301  //ages.push_back(1.2);
302  //ages.push_back(1.3);
303  for (unsigned int i = 0; i < ages.size(); ++i) {
304  const double agePlot = ages[i];
305  PlotLDF(simShower, simShower.GetCherenkovBeamProductionPhotons(nWLengthCkov/2), agePlot);
306  } // -------------------------------------------
307 
308 
311  iEye != end; ++iEye) {
312 
313  if (iEye->GetStatus() == fevt::ComponentSelector::eDeSelected)
314  continue;
315 
316  unsigned int eyeId = iEye->GetId();
317  fevt::Eye& eyeEvent = *iEye;
318 
321  iTel != end; ++iTel) {
322 
323  const unsigned int telId = iTel->GetId();
324 
325  fevt::Telescope& telEvent = *iTel;
326  const fdet::Telescope& detTel = detFD.GetTelescope(telEvent);
327 
328  const double rDia = detTel.GetDiaphragmRadius();
329  const double diaphragmArea = detTel.GetDiaphragmArea();
330 
331  if (!telEvent.HasSimData())
332  continue;
333  fevt::TelescopeSimData& telSim = telEvent.GetSimData();
334 
335  if (!telSim.HasDistanceTrace())
336  continue;
337  const TraceD& distanceTrace = telSim.GetDistanceTrace();
338 
339  ostringstream info;
340  info << "Photons for eye=" << eyeId
341  << ", telescope=" << telId
342  << ", rDia:" << setw(4) << detTel.GetDiaphragmRadius();
343  unsigned int countRTPhotons = 0;
344  double totalWeightPhotons = 0;
345 
346 
347  const CoordinateSystemPtr& telCS = detTel.GetTelescopeCoordinateSystem();
348  const Point telescopePos(0.0, 0.0, 0.0, telCS);
349  // RU ---- nkg option ---------
350  const Point p1(telescopePos);
351  const Vector telescopeToShowerCore(showerCore-p1);
352  // const double distTelToCore = telescopeToShowerCore.GetMag();
353  // ----------------------------
354 
355  // definition of the light trace at the diaphragm
356  const unsigned int nBins = distanceTrace.GetSize();
357  const double tracebin = distanceTrace.GetBinning(); // [ns]
358 
359  if (!telSim.HasRayTracedPhotonTrace())
360  telSim.MakeRayTracedPhotonTrace(nBins, tracebin);
361  TraceI& rayTracedPhotonTrace = telSim.GetRayTracedPhotonTrace();
362 
363  const fdet::Camera& detCamera = detTel.GetCamera();
364  const double telTraceBinWidth = detCamera.GetFADCBinSize();
365  const double totalTraceDuration = tracebin * nBins;
366  const unsigned int telTraceNBins = int(0.5 + totalTraceDuration / telTraceBinWidth);
367  telSim.SetNumberOfPhotonBins(telTraceNBins);
368 
369 #ifdef DEBUG
370  info << " photonTraceSize=" << nBins
371  << " tracebin=" << tracebin
372  << " telTraceBinWidth=" << telTraceBinWidth
373  << " telTraceNBins=" << telTraceNBins << endl;
374 #endif
375 
376 
377  // --- main loop along the shower axis -------------------------
378 
379  if (nBins<2)
380  continue;
381 
382  double previousDistance = 0;
383  for (unsigned int iTrace = 0; iTrace < nBins; ++iTrace) {
384 
385  unsigned int totalNRayTracedPhotonsPerBin = 0;
386 
387  // smear photons along distance equally
388  const bool firstBin = iTrace <= 0;
389  const bool lastBin = iTrace >= nBins-1;
390 
391  const double currentDistance = distanceTrace[iTrace];
392  const double deltaNext = (lastBin ? 0. : distanceTrace[iTrace+1]-currentDistance);
393  const double deltaPrev = (firstBin ? 0. : currentDistance-previousDistance);
394  const double binFraction = RandFlat::shoot(&fRandomEngine->GetEngine(), -0.5, +0.5); // where exactly in distance bin
395  const double delta = (binFraction<0 ? deltaPrev : deltaNext); // distance to next/previous bin
396  double distancePhoton = currentDistance + delta * binFraction;
397  previousDistance = currentDistance;
398 
399  const double traceTime = tracebin * (0.5 + binFraction + iTrace);
400 
401  // some quantities in the middle of the current trace bin
402  // that need not be re-calculated for each photon
403  // const double averageDistancePhoton = 0.5*(distanceBin + distanceTrace[min(iTrace+1,nBins-1)]);
404  const Point pointOnShower = showerCore + showerAxis * distancePhoton;
405  const double height = wgs84.PointToLatitudeLongitudeHeight(pointOnShower).get<2>();
406  const double temperature = temperatureProfile.Y(std::max(std::min(height, tempHeightMax),
407  tempHeightMin));
408  const double pressure = pressureProfile.Y(std::max(std::min(height, pressHeightMax),
409  pressHeightMin));
410  const double cosLocalZenith =
411  (-showerAxis).GetCosTheta(LocalCoordinateSystem::Create(UTMPoint(pointOnShower, wgs84)));
412  const double moliereR = MoliereRadius(temperature, pressure,
413  flatEarth ? cosZenith : cosLocalZenith);
414 
415  // build probability distribution for wavelengths AND light sources
416  map<double, double> sourcePDF;
417  map<int, RandomSamplerFromPDF*> randomWavelengthSource;
418  ScopeGuard wlGuard(randomWavelengthSource); // will free the RandomSamplerFromPDF objects on scope exit
419 
420  double totalSumPhotons = 0;
422  end = telSim.PhotonTracesSourceEnd();
423  iSource != end; ++iSource) {
424 
425  // this can be used to select a single light source for tests:
426  if (GetLightSourceSelection() >= 0 && (int)(iSource->first) != GetLightSourceSelection())
427  continue;
428 
429  // if direct-Cherenkov photons are to be taken from CORSIKA directly, IGNORE them here:
431  continue;
432 
433  map<double, double> sourceWavelengthPDF;
434 
435  double totalSumPhotonsSource = 0;
436  for (fevt::TelescopeSimData::PhotonTraceIterator iBin = telSim.PhotonTracesBegin(iSource->first),
437  end = telSim.PhotonTracesEnd(iSource->first);
438  iBin != end; ++iBin) {
439  const TraceD& photonTrace = iBin->GetTrace();
440  const double nPhotonsWL = photonTrace[iTrace];
441  if (nPhotonsWL > 0) {
442  sourceWavelengthPDF[iBin->GetLabel()] = nPhotonsWL;
443  totalSumPhotonsSource += nPhotonsWL;
444  }
445  }
446 
447  if (totalSumPhotonsSource <= 0)
448  continue;
449 
450  if (!laserWavelength) {
451  randomWavelengthSource[int(iSource->first)] = new RandomSamplerFromPDF(sourceWavelengthPDF);
452  }
453  sourcePDF[int(iSource->first)] = totalSumPhotonsSource;
454  totalSumPhotons += totalSumPhotonsSource;
455  }
456 
457  if (totalSumPhotons <= 0) // nothing to do
458  continue;
459 
460  RandomSamplerFromPDF randomSource(sourcePDF);
461 
462  // no. photons to trace, taking into account the
463  // min/max per bin and the extra ray-tracing factor
464  const unsigned int tmpRayTrace = (unsigned int)(fExtraRayTraceFactor*((unsigned int)totalSumPhotons + 1));
465  const unsigned int nRayTrace = std::min(fMaxNRayTrace, std::max(fMinNRayTrace, tmpRayTrace));
466 
467  totalNRayTracedPhotonsPerBin += nRayTrace;
468  countRTPhotons += nRayTrace;
469  const double nBunchPhotons = totalSumPhotons / nRayTrace;
470 
471  map<int, RandomSamplerFromPDF*> cherenkovProductionDistance;
472  ScopeGuard cherProdDistGuard(cherenkovProductionDistance);
473 
474  for (unsigned int iSample = 0; iSample < nRayTrace; ++iSample) {
475 
476  // sample light source and wavelength
477  const fevt::FdConstants::LightSource lightSource =
479  const int iwl = isLaser ? 0 : int(randomWavelengthSource[lightSource]->shoot(fRandomEngine->GetEngine()));
480 
481  EPhotonSource photonSource = eUnkown;
482  double wavelength = 0;
483  switch (lightSource) {
485  ERROR("DONT KNOW WHAT TO DO");
486  return eFailure;
487  break;
493  photonSource = eFluorescence;
494  wavelength = fUseOnlyReferenceWavelength ? refWl : WLengthFluo[iwl];
495  break;
497  photonSource = eDirectCherenkov;
498  wavelength = fUseOnlyReferenceWavelength ? refWl : WLengthCkov[iwl];
499  break;
505  {
506  photonSource = eScatteredCherenkov;
507  wavelength = fUseOnlyReferenceWavelength ? refWl : WLengthCkov[iwl];
508  if (!cherenkovProductionDistance.count(iwl)) {
509  TabulatedFunction& cherenkovBeamProduction = simShower.GetCherenkovBeamProductionPhotons(iwl);
510  TabulatedFunction cherenkovProductionBeamLDF;
511  double totalBeamLDF = 0;
512  for (unsigned int iTraceBeam = 0; iTraceBeam < cherenkovBeamProduction.GetNPoints(); ++iTraceBeam) {
513  const double distanceBeam = cherenkovBeamProduction[iTraceBeam].X();
514  if (distanceBeam > distancePhoton)
515  break;
516  const double nProd = cherenkovBeamProduction[iTraceBeam].Y();
517  cherenkovProductionBeamLDF.PushBack(distanceBeam, nProd);
518  totalBeamLDF += nProd;
519  }
520  cherenkovProductionDistance[iwl] = 0;
521  if (totalBeamLDF>0) {
522  cherenkovProductionDistance[iwl] =
523  new RandomSamplerFromPDF(cherenkovProductionBeamLDF, RandomSamplerFromPDF::eLinear);
524  }
525  }
526  break;
527  }
530  photonSource = eLaser;
531  wavelength = laserWavelength;
532  break;
534  ERROR("Background light photons are not implemented");
535  return eFailure;
536  break;
537  default:
538  break;
539  }
540 
541  if (wavelength == 0) {
542  ERROR("No wavelength selected");
543  return eFailure;
544  }
545 
546  // Generating random point on the diaphragm
547  // Uniform phi
548  const double diaPh = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, kTwoPi);
549  const double diaR = rDia * sqrt(RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0));
550  const double xDia = diaR * cos(diaPh);
551  const double yDia = diaR * sin(diaPh);
552  const Point pIn(xDia, yDia, 0.0, telCS);
553 
554  Point pointOnShower = showerCore + showerAxis * distancePhoton;
555  Vector photonDir = pointOnShower - telescopePos;
556  double timeShift = 0; // time shift with respect to 1D flight path
557 
558  if (!isLaser && (fFluorescenceLDF != eOff ||
559  (fDirectCherenkovLDF != eOff) ||
561 
562  const double distToShower = (pointOnShower-telescopePos).GetMag();
563  const double height = wgs84.PointToLatitudeLongitudeHeight(pointOnShower).get<2>();
564  const double Xvert = depthProfile.Y(std::max(depthProfile.MinX(), std::min(height, depthProfile.MaxX())));
565  const double Xslant = flatEarth ? Xvert/absCosZenith : slantDepthVsDistance->Y(std::max(atmDistanceMin, std::min(distancePhoton, atmDistanceMax)));
566 
567  if (Xslant > X1) { // no LDF before the first interaction
568 
569  const double age = ShowerAge(Xslant, showerXmax);
570  // const double rm = moliereR;
571 
572  switch(photonSource) {
573 
574  case eFluorescence:
575  {
576  switch(fFluorescenceLDF) {
577  case eNKG: pointOnShower += LateralDistributionNKG(showerCS, age, moliereR); break;
578  case eGora: pointOnShower += LateralDistributionGora(showerCS, age, moliereR); break;
579  default: break;
580  }
581  }
582  break;
583 
584  case eDirectCherenkov:
585  {
586  switch(fDirectCherenkovLDF) {
587  case eNKG: pointOnShower += LateralDistributionNKG(showerCS, age, moliereR); break;
588  case eGora: pointOnShower += LateralDistributionGora(showerCS, age, moliereR); break;
589  default: break;
590  }
591  }
592  break;
593 
594  case eScatteredCherenkov:
595  {
596  switch(fScatteredCherenkovLDF) {
597  case eNKG: pointOnShower += LateralDistributionNKG(showerCS, age, moliereR); break;
598  case eGora: pointOnShower += LateralDistributionGora(showerCS, age, moliereR); break;
599  case eCherenkov:
600  case eCherenkovAtAxis:
601  {
602  if (cherenkovProductionDistance[iwl]) {
603  double emissionDistance = 0;
604  Point pointOfCkovEmission;
605  Vector directionOfCkovEmission;
606  pointOnShower +=
607  LateralDistributionScatteredCherenkov(showerCS, showerCore, showerAxis,
608  distancePhoton,
609  showerXmax,
610  moliereR,
611  emissionDistance,
612  pointOfCkovEmission, directionOfCkovEmission,
613  *cherenkovProductionDistance[iwl],
614  depthProfile,
615  slantDepthVsDistance,
616  absCosZenith,
617  coreZ,
618  flatEarth,
619  atmDistanceMin,
620  atmDistanceMax);
621  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
622  * RU, Mon Feb 1 13:57:32 EST 2010
623  *
624  * the time shift by the longer flight path of the direct cherenkov
625  * photons in the Cherenkov cone vs. the 1 dimensional propagation is not taken
626  * into account. It is of the order of ~<100ns, and thus similar to the
627  * effect caused by the shower front curvature, which is also neglected
628  * here.
629  *
630  */
631  }
632  }
633  break;
634  default: break;
635  }
636  }
637  break;
638  default: break;
639  }
640 
641  photonDir = pointOnShower - telescopePos; // altered photon incident direction
642 
643  const double dist3D = photonDir.GetMag(); // real length of photon flight path
644  timeShift += (dist3D - distToShower) / kSpeedOfLight; // distance difference -> time difference
645 
646 #ifdef DEBUG_3D
647  info << " p " << Pressure/bar
648  << " rm: " << moliereR/m
649  << " age: " << age
650  << " T: " << Temperature
651  << " Height: " << height/m
652  << " X: " << Xvert/g*cm*cm
653  // << " tel: " << telescopePos.GetZ (localCS)
654  << " dist: " << distToShower/m
655  << " anlge: " << angleToCore/deg
656  << " shift: " << timeShift/ns
657  << endl;
658 #endif
659  } // if Xslant>X1
660  else {
661  // before first interaction -> no LDF (!)
662  }
663 
664  } // 3d shower
665 
666  photonDir.Normalize();
667  const double projectedDiaphragmArea = diaphragmArea * photonDir.GetCosTheta(telCS);
668  const double weight = nBunchPhotons * projectedDiaphragmArea; // NOW IN LIGHTATDIAPHRAGMSIMULATOR
669 
670  /*
671  // don't track photons with weight<1
672  if (weight<1) {
673  if (RandFlat::shoot(&fRandomEngine->GetEngine(), 0., 1.))
674 
675  }
676  */
677 
678  /*
679  This can happen if photonDir.GetCosTheta(telCS) gets negative due to
680  large sample LDF distance in shower disc. Sometimes photons are then
681  emitted "behind" the telescope aperture ...
682  */
683  if (weight <= 0)
684  continue;
685 
686  totalWeightPhotons += weight;
687  utl::Photon photonIn(pIn, -photonDir, wavelength, weight, lightSource);
688  photonIn.SetTime(TimeInterval(traceTime + timeShift)); // time at diaphragm
689  telSim.AddPhoton(photonIn);
690 
691  if (fMultipleScattering) {
692  vector<Photon> photonVector;
693  fMultipleScatterer->AddPhotons(pointOnShower, photonIn,
694  telescopePos, photonVector);
695  for (unsigned int iPh = 0; iPh < photonVector.size(); ++iPh)
696  telSim.AddPhoton(photonVector[iPh]);
697  }
698 
699  } // loop over raytrace samples
700 
701  rayTracedPhotonTrace[iTrace] += totalNRayTracedPhotonsPerBin;
702  } // loop over time bin
703 
704  info << ", generated " << setw(6) << countRTPhotons << " photons"
705  << ", total weight=" << totalWeightPhotons;
706  INFO(info);
707 
708  } // End loop over Telescopes
709 
710  } // End loop over Eyes
711 
712  return eSuccess;
713 
714 } // end of Run
715 
716 
719 {
720  return eSuccess;
721 }
722 
723 
724 #include <TCanvas.h>
725 #include <TPolyMarker3D.h>
726 #include <TPolyLine3D.h>
727 #include <TH2D.h>
728 
729 TH1D*
730 ShowerPhotonGenerator::ToCumu(TH1D* h, double total)
731 {
732  ostringstream newname;
733  newname << h->GetName() << "_cumulative";
734  TH1D* const o = new TH1D(newname.str().c_str(), newname.str().c_str(),
735  h->GetNbinsX(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
736  o->SetLineColor(h->GetLineColor());
737  o->SetLineStyle(h->GetLineStyle());
738  o->SetLineWidth(h->GetLineWidth());
739  if (total <= 0)
740  total = 1.0;
741  double sum = 0;
742  for (int i = 1; i <= h->GetNbinsX(); ++i) {
743  sum += h->GetBinContent(i);
744  o->SetBinContent(i, sum/total);
745  }
746  return o;
747 }
748 
749 
750 // ---------------------------------------------------------------------------------------
751 void
753  const TabulatedFunction& cherenkovProductionBeam,
754  const double age)
755 {
756  const bool flatEarth = false;
757 
758  Detector& detector = Detector::GetInstance();
759  const Atmosphere& atmo = detector.GetAtmosphere();
760 
761  const ReferenceEllipsoid& wgs84 = ReferenceEllipsoid::GetWGS84();
762 
763  const ProfileResult& depthProfile = atmo.EvaluateDepthVsHeight();
764  const ProfileResult& temperatureProfile = atmo.EvaluateTemperatureVsHeight();
765  const double tempHeightMin = temperatureProfile.MinX();
766  const double tempHeightMax = temperatureProfile.MaxX();
767  const ProfileResult& distanceVsSlantDepth = atmo.EvaluateDistanceVsSlantDepth();
768  const ProfileResult* const slantDepthVsDistance = &atmo.EvaluateSlantDepthVsDistance();
769  const double atmDistanceMin = slantDepthVsDistance->MinX();
770  const double atmDistanceMax = slantDepthVsDistance->MaxX();
771  const ProfileResult& heightVsDistance = atmo.EvaluateHeightVsDistance();
772 
773  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
774  const Point showerCore(0,0,0,showerCS);
775  const Vector showerAxis(0,0,-1,showerCS);
776 
777  const CoordinateSystemPtr localCS = simShower.GetLocalCoordinateSystem();
778  const double cosZenith = (-simShower.GetDirection()).GetCosTheta(localCS); // just for flat earth
779  const double absCosZenith = std::fabs(cosZenith); // just for flat earth
780  const double coreZ = wgs84.PointToLatitudeLongitudeHeight(showerCore).get<2>();
781  const double showerXmax = simShower.GetGHParameters().GetXMax();
782  const double X1 = simShower.GetXFirst();
783  const double distanceX1 = atmo.EvaluateDistanceVsSlantDepth().Y(X1);
784  const Point& pointX1 = showerCore + showerAxis*distanceX1;
785 
786  const double Xslant = 2. * age * showerXmax / (3 - age);
787  const double distance = distanceVsSlantDepth.Y(Xslant);
788  const double height = heightVsDistance.Y(distance);
789  const double Xvert = depthProfile.Y(height);
790  const Point& pointOnShower = showerCore + showerAxis*distance;
791 
792  const double Temperature = temperatureProfile.Y(std::max(std::min(height, tempHeightMax), tempHeightMin));
793  const double Pressure = Xvert * kgEarth;
794  const double rm = MoliereRadius(Temperature, Pressure,
795  (-showerAxis).GetCosTheta(LocalCoordinateSystem::Create(UTMPoint(pointOnShower, wgs84))) );
796 
797  TabulatedFunction cherenkovProductionBeamLDF;
798  for (unsigned int iTrace = 0; iTrace < cherenkovProductionBeam.GetNPoints(); ++iTrace) {
799  const double distanceBin = cherenkovProductionBeam[iTrace].X();
800  if (distanceBin > distance)
801  break;
802  cherenkovProductionBeamLDF.PushBack(cherenkovProductionBeam[iTrace].X(), cherenkovProductionBeam[iTrace].Y());
803  }
804  RandomSamplerFromPDF* const cherenkovProductionDistance =
805  new RandomSamplerFromPDF(cherenkovProductionBeamLDF, RandomSamplerFromPDF::eLinear);
806 
807  // RU: for making LDF-pictures
808  cout << " PlotLDF: age=" << age
809  << " Xslant=" << Xslant/g*cm2
810  << " Xvert=" << Xvert/g*cm2
811  << " distance=" << distance
812  << " height=" << height
813  << " rm=" << rm
814  << " bins=" << cherenkovProductionBeamLDF.GetNPoints()
815  << endl;
816 
817  ostringstream hFluoLDFName, hCkovLDFName;
818  hFluoLDFName << "hFluoLDF_" << fixed << setprecision(2) << age;
819  hCkovLDFName << "hCkovLDF_" << fixed << setprecision(2) << age;
820  const int nBins = 100;
821  const double minR = 0;
822  const double maxR = 1600;
823  TH1D* const hFluoLDF = new TH1D(hFluoLDFName.str().c_str(), hFluoLDFName.str().c_str(), nBins, minR, maxR);
824  TH1D* const hCkovLDF = new TH1D(hCkovLDFName.str().c_str(), hCkovLDFName.str().c_str(), nBins, minR, maxR);
825  TCanvas* const c3D = new TCanvas("c3D", "c3D", 500, 1500);
826  c3D->SetFillColor(kWhite);
827  /*
828  TH2D* frame = new TH2D("frame", "rame",
829  10, -maxR, maxR, 10, distanceX1, distance, 0);
830  frame->Draw();
831  TH2D* projXZ = new TH2D("projXZ", "projection",
832  100, -maxR, maxR, 500, distanceX1, distance, 0);
833  */
834  TPolyMarker3D* const p1 = new TPolyMarker3D(2);
835  p1->SetPoint(0, pointOnShower.GetX(showerCS), pointOnShower.GetY(showerCS), pointOnShower.GetZ(showerCS));
836  p1->SetPoint(1, pointX1.GetX(showerCS), pointX1.GetY(showerCS), pointX1.GetZ(showerCS));
837  p1->SetMarkerStyle(20);
838  p1->SetMarkerColor(kRed);
839  p1->Draw();
840  const int n_samples = 100000;
841  for (int i = 0; i < n_samples; ++i) {
842  const double fluoLDF = (fFluorescenceLDF == eGora ?
843  LateralDistributionGora(showerCS, age, rm).GetMag() :
844  LateralDistributionNKG(showerCS, age, rm).GetMag()) ;
845  double emissionDistance = 0;
846  Point pointOfCkovEmission;
847  Vector directionOfCkovEmission;
848  Vector ckovR = LateralDistributionScatteredCherenkov(showerCS, showerCore, showerAxis,
849  distance,
850  showerXmax,
851  rm,
852  emissionDistance,
853  pointOfCkovEmission,
854  directionOfCkovEmission,
855  *cherenkovProductionDistance,
856  depthProfile,
857  slantDepthVsDistance,
858  absCosZenith,
859  coreZ,
860  flatEarth,
861  atmDistanceMin,
862  atmDistanceMax);
863  TPolyLine3D* const l3D = new TPolyLine3D(2);
864  l3D->SetPoint(0, pointOfCkovEmission.GetX(showerCS), pointOfCkovEmission.GetY(showerCS), pointOfCkovEmission.GetZ(showerCS));
865  l3D->SetPoint(1, (pointOnShower+ckovR).GetX(showerCS), (pointOnShower+ckovR).GetY(showerCS), (pointOnShower+ckovR).GetZ(showerCS));
866  l3D->SetLineStyle(1);
867  l3D->SetLineWidth(1);
868  l3D->SetLineColor(kBlue);
869  l3D->Draw();
870  const double ckovLDF = ckovR.GetMag();
871  hFluoLDF->Fill(fluoLDF/m);
872  hCkovLDF->Fill(ckovLDF/m);
873  } // end n-photons
874 
875  TH1D* const hFluoLDFc = ToCumu(hFluoLDF, n_samples);
876  TH1D* const hCkovLDFc = ToCumu(hCkovLDF, n_samples);
877 
878  ostringstream hLDFPrint, hLDFcumu;
879  hLDFPrint << "LDF_" << fixed << setfill('0') << setw(3) << setprecision(3) << age << ".eps";
880  hLDFcumu << "LDF_" << fixed << setfill('0') << setw(3) << setprecision(3) << age << ".cumulative.eps";
881  gROOT->SetStyle("Plain");
882  gStyle->SetOptTitle(0);
883  gStyle->SetOptStat(0);
884  TCanvas* const c = new TCanvas("ldf", "ldf");
885  TLegend* const l = new TLegend(0.5, 0.6, 0.85, 0.85);
886  l->SetFillColor(0);
887  l->SetBorderSize(0);
888  l->SetTextFont(42);
889  l->SetTextSize(0.045);
890  l->AddEntry(hFluoLDF, "Fluorescence", "l");
891  l->AddEntry(hCkovLDF, "Cherenkov", "l");
892 
893  double integral = hFluoLDF->Integral();
894  if (integral)
895  hFluoLDF->Scale(1. / integral);
896  integral = hCkovLDF->Integral();
897  if (integral)
898  hCkovLDF->Scale(1. / integral);
899 
900  hFluoLDF->SetLineColor(2);
901  hCkovLDF->SetLineColor(4);
902  hFluoLDF->SetXTitle("Distance [m]");
903  hFluoLDF->SetYTitle("R dP/dR");
904  hFluoLDF->GetYaxis()->SetTitleOffset(1.15);
905  hFluoLDF->Draw("l");
906  hCkovLDF->Draw("lsame");
907  l->Draw();
908  c->Print(hLDFPrint.str().c_str());
909 
910  TCanvas* const c2 = new TCanvas("ldfcumu", "ldfcumu");
911  TLegend* const l2 = new TLegend(0.5, 0.2, 0.85, 0.6);
912  l2->SetFillColor(0);
913  l2->SetBorderSize(0);
914  l2->SetTextFont(42);
915  l2->SetTextSize(0.045);
916  l2->AddEntry(hFluoLDF, "Fluorescence", "l");
917  l2->AddEntry(hCkovLDF, "Cherenkov", "l");
918 
919  hFluoLDFc->SetLineColor(2);
920  hCkovLDFc->SetLineColor(4);
921  hFluoLDFc->SetXTitle("Distance [m]");
922  hFluoLDFc->SetYTitle("R dP/dR");
923  hFluoLDFc->GetYaxis()->SetTitleOffset(1.15);
924  hFluoLDFc->Draw("l");
925  hCkovLDFc->Draw("lsame");
926  l2->Draw();
927  c2->Print(hLDFcumu.str().c_str());
928 
929  ostringstream h3DPrint;
930  h3DPrint << "LDF_" << fixed << setfill('0') << setw(3) << setprecision(3) << age << ".3d.root";
931  //c3D.ShoweAxis3D();
932  c3D->Print(h3DPrint.str().c_str());
933 
934  delete cherenkovProductionDistance;
935 }
936 
937 
938 //==========================================================================
942 //==========================================================================
943 Vector
945  const double s_age,
946  const double r_moliere)
947 {
948  const double fMax = 0.95;
949  const double r = r_moliere * NKGFunction(s_age, fMax);
950  const double phi = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., kTwoPi);
951 
952  return Vector(r, phi, 0., shwCS, Vector::kCylindrical);
953 }
954 
955 
956 //==========================================================================
960 //==========================================================================
961 Vector
963  const double s_age,
964  const double r_moliere)
965 {
966  const double r = r_moliere * GoraFunction(s_age);
967  const double phi = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., kTwoPi);
968 
969  return Vector(r, phi, 0., shwCS, Vector::kCylindrical);
970 }
971 
972 
973 //==========================================================================
977 //==========================================================================
978 Vector
980  const utl::Point& core,
981  const utl::Vector& axis,
982  double distanceCoreToPointOnShower,
983  double Xmax,
984  double rMoliere,
985  double& emissionDistance,
986  utl::Point& pointOfEmission,
987  utl::Vector& directionOfEmission,
988  const utl::VRandomSampler& cherenkovProduction,
989  const ProfileResult& depthProfile,
990  const ProfileResult* slantDepthVsDistance,
991  const double absCosZenith,
992  const double coreZ,
993  const bool flatEarth,
994  const double atmDistanceMin,
995  const double atmDistanceMax)
996 {
997  // --------- point of cherenkov emission at shower axis ---------
998  emissionDistance = cherenkovProduction.shoot(fRandomEngine->GetEngine());
999 
1000  const bool emissionIn = emissionDistance > atmDistanceMin && emissionDistance < atmDistanceMax;
1001  const double emissionDepthVert =
1002  emissionIn ? depthProfile.Y(std::max(depthProfile.MinX(), std::min(depthProfile.MaxX(), coreZ-emissionDistance*absCosZenith))) : 0;
1003  const double emissionDepth =
1004  flatEarth ? emissionDepthVert / absCosZenith :
1005  (emissionIn ? slantDepthVsDistance->Y(emissionDistance) : 0);
1006  const double emissionAge = ShowerAge(emissionDepth, Xmax);
1007 
1008  pointOfEmission = core + emissionDistance*axis + LateralDistributionGora(showerCS, emissionAge, rMoliere);
1009 
1010  // --------- Cherenkov emission angle at shower axis ---------
1011  const double maxIntegrationAngle = 90.*utl::degree;
1012  const double deltaAngle = 0.25*utl::degree;
1013 
1014  const Atmosphere& atmo = Detector::GetInstance().GetAtmosphere();
1015 
1016  const double rndmCDFVal = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
1017  const double cdfMax =
1018  atmo.AngularCherenkovCDF(maxIntegrationAngle, emissionDepthVert, emissionAge);
1019 
1020  // find inverse of CDF at rndmCDFVal using bisection method
1021  double leftAngle = 0.;
1022  double rightAngle = maxIntegrationAngle;
1023  double cdfLeft =
1024  atmo.AngularCherenkovCDF(leftAngle, emissionDepthVert, emissionAge)/cdfMax - rndmCDFVal;
1025 
1026  while (fabs(leftAngle - rightAngle) > 2*deltaAngle) {
1027 
1028  const double midAngle = 0.5 * (leftAngle + rightAngle);
1029  const double cdfMiddle =
1030  atmo.AngularCherenkovCDF(midAngle, emissionDepthVert, emissionAge)/cdfMax - rndmCDFVal;
1031 
1032  if (cdfLeft*cdfMiddle < 0)
1033  rightAngle = midAngle;
1034  else {
1035  cdfLeft =
1036  atmo.AngularCherenkovCDF(midAngle, emissionDepthVert, emissionAge)/cdfMax - rndmCDFVal;
1037  leftAngle = midAngle;
1038  }
1039  }
1040 
1041  const double cdfRight =
1042  atmo.AngularCherenkovCDF(rightAngle, emissionDepthVert, emissionAge)/cdfMax - rndmCDFVal;
1043  const double electronAngleTheta = leftAngle - (rightAngle-leftAngle)/(cdfRight-cdfLeft) * (cdfLeft);
1044 
1045  const double electronAnglePhi = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., kTwoPi);
1046 
1047  const CoordinateSystemPtr electronCS =
1048  CoordinateSystem::RotationX(electronAngleTheta, CoordinateSystem::RotationZ(electronAnglePhi, showerCS));
1049 
1050  // sample from Cherenkov cone
1051  const double cherenkovAnglePhi = RandFlat::shoot(&fRandomEngine->GetEngine(), 0., kTwoPi);
1052  // Cherenkov angle for beta=1
1053  const double nRefrac = utl::RefractionIndex::LorentzLorentz(emissionDepthVert);
1054  const double cosCherenkovTheta = 1. / nRefrac;
1055  const double sinCherenkovTheta = sqrt(1.-cosCherenkovTheta*cosCherenkovTheta);
1056  /*
1057  //#warning turned off cherenkov cone
1058  const double cherenkovAnglePhi = 0;
1059  const double cosCherenkovTheta = 1.;
1060  const double sinCherenkovTheta = 0;
1061  */
1062 
1063  directionOfEmission = Vector(-sinCherenkovTheta*sin(cherenkovAnglePhi),
1064  -sinCherenkovTheta*cos(cherenkovAnglePhi),
1065  -cosCherenkovTheta,
1066  electronCS);
1067 
1068  // const double cosPhotonAngle = CosAngle(directionOfEmission, axis); // not needed any more
1069 
1070  const double photonTravelDistance = (distanceCoreToPointOnShower-emissionDistance) / (directionOfEmission*axis); //cosPhotonAngle;
1071 
1072  return Vector(pointOfEmission.GetX(showerCS) + directionOfEmission.GetX(showerCS) * photonTravelDistance,
1073  pointOfEmission.GetY(showerCS) + directionOfEmission.GetY(showerCS) * photonTravelDistance,
1074  0,
1075  showerCS);
1076 }
1077 
1078 
1096 double
1097 ShowerPhotonGenerator::NKGFunction(double s, const double fMax)
1098 {
1099  const double closeToZero = 1.e-20;
1100  const double sMax = 1.999;
1101 
1102  static double lastFmax = -1;
1103  static double xMaxArr[200];
1104 
1105  // initialize xMax array on startup or if fMax changed
1106  if (fMax != lastFmax) {
1107  lastFmax = fMax;
1108  double dX = 0.001;
1109  for (int j = 0; j < 200; ++j) {
1110  const double a = (0.5+j)/100;
1111  const double b = 4.5 - 2*a;
1112  double frac = 0;
1113  double xxMax = closeToZero;
1114  while (frac < fMax) {
1115  xxMax += dX;
1116  const double arg = 1/(1+1/xxMax);
1117  frac = IncompleteBeta(a, b, arg);
1118  }
1119  xMaxArr[j] = xxMax;
1120  // incrase dX
1121  dX = xxMax/100;
1122  }
1123  }
1124 
1125  // random generation
1126 
1127  if (s >= sMax)
1128  s = sMax;
1129 
1130  const double xMin = closeToZero;
1131  const int ageBin = int(s*100);
1132  const double xMax = xMaxArr[ageBin];
1133 
1134  double rdm = 1;
1135  double Y = 0;
1136  double x;
1137  while (rdm > Y) {
1138 
1139  if (s > 1) {
1140 
1141  // get random number ~ (1.+x)^(s-4.5) between Xmin and Xmax
1142 
1143  const double g = s - 4.5;
1144  const double g1 = g + 1;
1145 
1146  rdm = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
1147 
1148  const double Fa = pow(xMin+1, g1);
1149  const double Fb = pow(xMax+1, g1);
1150  const double y = Fa + (Fb-Fa)*rdm;
1151  x = pow(y, 1/g1);
1152 
1153  // hit or miss for additional x*(x)^(s-2)
1154 
1155  x -= 1;
1156  Y = pow(x, s-1);
1157  const double Ymax = pow(xMax, s-1);
1158  rdm = Ymax * RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
1159 
1160  } else {
1161 
1162  // get random number ~ x*(x)^(s-2.) between Xmin and Xmax
1163 
1164  const double g = s - 1;
1165  const double g1 = g + 1;
1166 
1167  rdm = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
1168 
1169  if (fabs(g1) > closeToZero) {
1170  const double Fa = pow(xMin, g1);
1171  const double Fb = pow(xMax, g1);
1172  const double y = Fa + (Fb - Fa)*rdm;
1173  x = pow(y, 1/g1);
1174  } else {
1175  const double lMin = log10(xMin);
1176  const double lMax = log10(xMax);
1177  x = pow(10, lMin + rdm*(lMax - lMin));
1178  }
1179 
1180  // hit or miss for additional (1+x)^(s-4.5)
1181 
1182  Y = pow(1+x, s - 4.5);
1183  rdm = RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 1);
1184  }
1185 
1186  }
1187 
1188  return x;
1189 }
1190 
1191 
1192 //==========================================================================
1201 //==========================================================================
1202 inline double
1204 {
1205 
1206  double rdm = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
1207 
1208  // avoid div by zero
1209  if (rdm < std::numeric_limits<double>::min())
1210  rdm = std::numeric_limits<double>::min();
1211 
1212  // r = F(rdm)^(-1)
1213  return utl::InverseGoraCDF(rdm, s);
1214 }
1215 
1216 
1217 //==========================================================================
1218 //==========================================================================
1219 ScopeGuard::ScopeGuard(std::map<int, utl::RandomSamplerFromPDF*>& theMap)
1220  : fMap(theMap)
1221 {
1222 }
1223 
1224 //==========================================================================
1226 {
1227  for (map<int, RandomSamplerFromPDF*>::iterator iMap = fMap.begin(),
1228  end = fMap.end();
1229  iMap != end; ++iMap) {
1230  delete iMap->second;
1231  }
1232 }
1233 
1234 // Configure (x)emacs for this file ...
1235 // Local Variables:
1236 // mode: c++
1237 // End:
unsigned int GetId() const
Definition: FEvent/Eye.h:54
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
PhotonTraceSourceIterator PhotonTracesSourceEnd()
LaserData & GetLaserData()
Get the laser data.
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
double GetFADCBinSize() const
unsigned int fMinNRayTrace
max no. of photons per bin
void Normalize()
Definition: Vector.h:64
double InverseGoraCDF(const double fraction, const double age)
Point object.
Definition: Point.h:32
bool HasLaserData() const
Check initialization of the LaserData.
double GetLaserWavelength() const
Definition: LaserData.h:32
utl::Vector LateralDistributionNKG(const utl::CoordinateSystemPtr &shwCS, const double s_age, const double r_moliere)
Distribute points according to a NKG function.
void AddPhotons(const utl::Point &PointOfOrigin, const utl::Photon &PhotonDirect, const utl::Point &PointOfDetection, std::vector< utl::Photon > &photonVector)
Report success to RunController.
Definition: VModule.h:62
const std::vector< double > & GetWavelengths(const EmissionMode mode=eFluorescence) const
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
const utl::TabulatedFunction & GetCherenkovBeamProductionPhotons(const int wavelength) const
Get the cherenkov beam production along the shower axis.
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
bool HasFEvent() const
utl::Vector LateralDistributionGora(const utl::CoordinateSystemPtr &shwCS, const double s_age, const double r_moliere)
Distribute points according to a Gora function.
PhotonTraceSourceIterator PhotonTracesSourceBegin()
unsigned int fMaxNRayTrace
Returns int as implementation of an eNone equivalent.
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
Skip remaining modules in the current loop and continue with next iteration of the loop...
Definition: VModule.h:68
Class to hold collection (x,y) points and provide interpolation between them.
const atm::ProfileResult & EvaluatePressureVsHeight() const
Tabulated function giving Y=air pressure as a function of X=height.
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
bool HasSimShower() const
EyeIterator EyesEnd(const ComponentSelector::Status status)
Definition: FEvent.h:66
double GetBinning() const
size of one slot
Definition: Trace.h:138
double GetDiaphragmRadius() const
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
void PlotLDF(const evt::ShowerSimData &simShower, const utl::TabulatedFunction &cherenkovProductionBeam, const double age)
utl::TraceI & GetRayTracedPhotonTrace()
Number of photons that were actually ray-traced (per time bin)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void AddPhoton(const utl::Photon &p)
boost::filter_iterator< ComponentSelector, AllEyeIterator > EyeIterator
selective Eye iterators
Definition: FEvent.h:55
void PushBack(const double x, const double y)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
utl::Vector LateralDistributionScatteredCherenkov(const utl::CoordinateSystemPtr &showerCX, const utl::Point &core, const utl::Vector &axis, double distanceCoreToPointOnShower, double Xmax, double rMoliere, double &emissionDistance, utl::Point &pointOfEnission, utl::Vector &directionOfEmission, const utl::VRandomSampler &cherenkovProduction, const atm::ProfileResult &depthProfile, const atm::ProfileResult *slantDepthVsDistance, const double absCosZenith, const double coreZ, const bool flatEarth, const double atmDistanceMin, const double atmDistanceMax)
Distribute points according to scattered Cherenkov emission.
double pow(const double x, const unsigned int i)
EPhotonSource
The source that generated this photon.
double shoot(HepEngine &engine) const
Method to shoot random values using a given engine by-passing the static generator.
std::string GetVersionInfo(const VersionInfoType v) const
Retrieve different sorts of module version info.
Definition: VModule.cc:26
constexpr double kgEarth
double GetMag() const
Definition: Vector.h:58
utl::MultiTraceD::Iterator PhotonTraceIterator
An iterator over the components of the photon trace.
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
utl::RandomEngine * fRandomEngine
This can be set in order to simulate photons for a single source ONLY (for FdLightCollectionEfficienc...
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)
double fExtraRayTraceFactor
min no. of photons per bin
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
const atm::Atmosphere & GetAtmosphere() const
Definition: Detector.h:113
double IncompleteBeta(const double a, const double b, const double x)
Incomplete Beta function.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
double AngularCherenkovCDF(const double theta, const double verticalDepth, const double showerAge) const
cumulative of angular Cherenkov distribution from 0 to theta
double GetXFirst() const
Get depth of first interaction.
fevt::TelescopeSimData & GetSimData()
Description of simulated data for one Telescope.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
utl::CoordinateSystemPtr GetTelescopeCoordinateSystem() const
PhotonTraceSourceContainer::iterator PhotonTraceSourceIterator
constexpr double s
Definition: AugerUnits.h:163
Reference ellipsoids for UTM transformations.
double GoraFunction(const double s)
returns random numbers drawn from Gora et al. LDF
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
LightSource
Possible light sources.
Definition: FdConstants.h:9
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
double MoliereRadius(double temperature, double pressure, const double cosTheta)
The Moliere Radius (2 radiation length above obs-level, GAP-1998-002)
const double ns
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
constexpr double kTwoPi
Definition: MathConstants.h:27
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
const fdet::FDetector & GetFDetector() const
Definition: Detector.cc:131
constexpr double degree
constexpr double g
Definition: AugerUnits.h:200
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
SizeType GetSize() const
Definition: Trace.h:156
PhotonTraceIterator PhotonTracesEnd(const fevt::FdConstants::LightSource source)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
ScopeGuard(std::map< int, utl::RandomSamplerFromPDF * > &theMap)
bool HasDistanceTrace() const
Check that trace for the distance along the shower axis is present.
bool HasRayTracedPhotonTrace() const
Check that &quot;ray-traced photon trace&quot; is present.
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
ELDFMode fFluorescenceLDF
Photons are generated at the reference wavelength only if this is set.
double GetReferenceLambda() const
Definition: FDetector.cc:332
double LorentzLorentz(const double verticalDepth)
Calculate the refraction index for a given depth.
bool fUseOnlyReferenceWavelength
for doing more tracing to reduce fluctuations
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.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
PhotonTraceIterator PhotonTracesBegin(const fevt::FdConstants::LightSource source)
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.
constexpr double cm
Definition: AugerUnits.h:117
execption handling for calculation/access for inclined atmosphere model
Vector object.
Definition: Vector.h:30
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
Main configuration utility.
Definition: CentralConfig.h:51
Fluorescence Detector Telescope Event.
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
std::map< int, utl::RandomSamplerFromPDF * > & fMap
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
void MakeRayTracedPhotonTrace(const unsigned int size=0, const double binSize=0)
Add a trace for the number of photons that were ray-traced.
void SetTime(const utl::TimeInterval &t)
Definition: Photon.h:36
void SetNumberOfPhotonBins(const int n)
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
Automatically frees memory on scope exit.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
double NKGFunction(const double s, const double fMax)
returns random numbers drawn from
constexpr double bar
Definition: AugerUnits.h:213
bool HasSimData() const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
Class to shoot random numbers given by a user-defined distribution function.
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
utl::TraceD & GetDistanceTrace()
Trace for the distance along the shower axis of the light at the diaphragm.
Description of a camera.
const atm::ProfileResult & EvaluateHeightVsDistance() const
Table of height as a function of distance.
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.