ShowerInventor.cc
Go to the documentation of this file.
1 #include "ShowerInventor.h"
3 
4 #include <utl/ErrorLogger.h>
5 #include <utl/AugerUnits.h>
6 #include <utl/MathConstants.h>
7 #include <utl/PhysicalConstants.h>
8 #include <utl/TimeStamp.h>
9 #include <utl/UTCDateTime.h>
10 #include <utl/Point.h>
11 #include <utl/Plane.h>
12 #include <utl/Line.h>
13 #include <utl/GeometryUtilities.h>
14 #include <utl/UTMPoint.h>
15 #include <utl/Vector.h>
16 #include <utl/RandomSamplerFromPDF.h>
17 #include <utl/RandomEngine.h>
18 #include <utl/TabulatedFunction.h>
19 #include <utl/Branch.h>
20 #include <utl/AugerException.h>
21 
22 #include <fwk/CoordinateSystemRegistry.h>
23 #include <fwk/RandomEngineRegistry.h>
24 #include <fwk/CentralConfig.h>
25 
26 #include <evt/Event.h>
27 #include <evt/ShowerSimData.h>
28 #include <evt/DefaultShowerGeometryProducer.h>
29 
30 #include <det/Detector.h>
31 
32 #include <sdet/SDetector.h>
33 
34 #include <CLHEP/Evaluator/Evaluator.h>
35 
36 #include <TH1F.h>
37 #include <TH2F.h>
38 #include <TFile.h>
39 
40 #include <boost/lexical_cast.hpp>
41 
42 #include <limits>
43 #include <sstream>
44 
45 using namespace std;
46 using namespace utl;
47 using namespace fwk;
48 using namespace evt;
49 using namespace det;
50 using namespace sdet;
51 using namespace ShowerInventorNS;
52 
53 
54 ShowerInventor::ShowerInventor() :
55  fRandomEngine(0),
56  fCurrentParticle(0),
57  fGroundPlane(0),
58  fCoreLocation(0),
59  fCurrentZenith(0),
60  fCurrentDistIndex(0),
61  fRandomCacheMaxSize(5e6),
62  fDiagnosticsOn(false),
63  fDiagnosticsFileName("")
64 { }
65 
66 
69 {
70  INFO("ShowerInventor::Init()");
71 
73 
74  Branch topB = CentralConfig::GetInstance()->GetTopBranch("ShowerInventor");
75 
76  topB.GetChild("RandomCacheSize").GetData(fRandomCacheMaxSize);
77 
78  AttributeMap genAtts;
79  genAtts["generate"] = "yes";
80  Branch dB = topB.GetChild("DiagnosticPlots", genAtts);
81  if (dB) {
82  fDiagnosticsOn = true;
84  }
85 
86  // Zeniths
87 
88  Branch showerAxesB = topB.GetChild("ShowerAxes");
89  showerAxesB.GetChild("Zeniths").GetData(fZeniths);
90  showerAxesB.GetChild("Azimuth").GetData(fAzimuth);
91 
92  // Axis
93 
94  Branch coreB = showerAxesB.GetChild("core");
95  coreB.GetChild("northing").GetData(fCoreNorthing);
96  coreB.GetChild("easting").GetData(fCoreEasting);
97  coreB.GetChild("altitude").GetData(fCoreAltitude);
98 
99  // Distributions
100 
101  Branch distB = topB.GetChild("Distributions");
102  for (Branch pB = distB.GetFirstChild();
103  pB; pB = pB.GetNextSibling()) {
104 
105  ParticleDistInfo pdi;
106 
107  const AttributeMap aM = pB.GetAttributes();
108  pdi.particleType =
109  boost::lexical_cast<int>(aM.find("type")->second);
110 
112  boost::lexical_cast<unsigned int>(aM.find("number")->second);
113 
115 
116  pdi.radialDistro = GetSampler(pB.GetChild("Density"));
117  pdi.azimuthDistro = GetSampler(pB.GetChild("Azimuth"));
118  pdi.timeDistro = GetSampler(pB.GetChild("Time"));
119  pdi.weightDistro = GetSampler(pB.GetChild("Weight"));
120 
121  pdi.radiusRandomCache = 0;
122  pdi.azimuthRandomCache = 0;
123  pdi.timeRandomCache = 0;
124  pdi.weightRandomCache = 0;
125 
126  pdi.cachePosition = 0;
127  pdi.numGeneratedParticles = 0;
128 
129  fParticleDistros.push_back(pdi);
130  }
131 
133 
134  // Book diagnostic histograms
135 
136  if (fDiagnosticsOn) {
137 
138  const unsigned int posBins = 150;
139  const double posMin = -15;
140  const double posMax = 15;
141 
142  for (vector<ParticleDistInfo>::iterator dIt = fParticleDistros.begin();
143  dIt != fParticleDistros.end() ; ++dIt) {
144 
145  string pType = boost::lexical_cast<string>(dIt->particleType);
146 
147  // NB histos should have some intelligent way to bin
148  // and bound themselves.
149 
150  DiagnosticHistos histos;
151 
152  string radialTitle = "radial distribution (km), particle type " + pType;
153  histos.radialDistro = new TH1F(radialTitle.c_str(),
154  radialTitle.c_str(),
155  400, 0, 10);
156 
157  string azimuthTitle = "azimuthal distribution, particle type " + pType;
158  histos.azimuthDistro = new TH1F(azimuthTitle.c_str(),
159  azimuthTitle.c_str(),
160  400, 0, 2*kPi);
161 
162  string timeTitle = "time distribution (ns), particle type " + pType;
163  histos.timeDistro = new TH1F(timeTitle.c_str(),
164  timeTitle.c_str(),
165  100, 0., 500);
166 
167  string weightTitle = "weight distribution, particle type " + pType;
168  histos.weightDistro = new TH1F(weightTitle.c_str(),
169  weightTitle.c_str(),
170  100, 0, 10000);
171 
172  string positionsShowerCSTitle = "particle positions, shower CS";
173  histos.positionsShowerCS = new TH2F(positionsShowerCSTitle.c_str(),
174  positionsShowerCSTitle.c_str(),
175  posBins, posMin, posMax,
176  posBins, posMin, posMax);
177 
178  string positionsGroundCSTitle = "particle positions, ground CS";
179  histos.positionsGroundCS = new TH2F(positionsGroundCSTitle.c_str(),
180  positionsGroundCSTitle.c_str(),
181  posBins, posMin, posMax,
182  posBins, posMin, posMax);
183 
184  fDiagnosticHistos[dIt->particleType] = histos;
185 
186  }
187 
188  string stationPosGroundCSTitle = "station positions, ground CS";
189  fStationPosGroundCS = new TH2F(stationPosGroundCSTitle.c_str(),
190  stationPosGroundCSTitle.c_str(),
191  posBins, posMin, posMax,
192  posBins, posMin, posMax);
193 
194  }
195 
196  return eSuccess;
197 }
198 
199 
202 {
203  fCurrentEvent = &event;
204 
205  // Stop the run when we've stepped through all the zeniths
206 
207  if (fCurrentZenithIndex == fZeniths.size())
208  return eBreakLoop;
209 
210  // set a ficticious time for the event
211 
212  const TimeStamp tEvt = UTCDateTime(2008, 1, 1, 0, 0).GetTimeStamp();
213  det::Detector::GetInstance().Update(tEvt);
214 
215  if (!event.HasSimShower())
217 
218  ShowerSimData& shower = event.GetSimShower();
219 
220  if (!shower.HasGroundParticles())
221  shower.MakeGroundParticles();
222 
223  // Set the ground particle list proxy (and clear any old one).
224  // Note that this MUST be done before ShowerSimData::MakePosition
225  // is called, since the core local CS cannot be set until the
226  // particle list is connected to a 'file'. For additional info
227  // see notes in docs of ShowerSimData::MakePosition
228 
229  if (fFileIterator)
230  delete fFileIterator;
231 
234 
236  // fCurrentPDI = fParticleDistros.at(fCurrentDistIndex);
237 
238  // NB shower zenith and azimuth used later to set shower direction
241 
242  // Set some ficticious primary poperties, to keep offline IO happy (otherwise
243  // it tires to dereference a null shadow pointer when writing)
244  shower.SetPrimaryParticle(22);
245 
246  // Set up the shower position and direction
247  const ReferenceEllipsoid& e = ReferenceEllipsoid::GetWGS84();
249  19, 'H', e);
250  CoordinateSystemPtr sCs =
251  AugerCoordinateSystem::Create(utmPos.GetPoint(), e, e.GetECEF());
252 
255 
256  if (!shower.HasGeometry())
257  shower.MakeGeometry(Point(0, 0, 0, sCs));
258 
259  if (!shower.HasTimeStamp())
260  shower.MakeTimeStamp(tEvt);
261 
263 
266 
267  // Set the CS's to be used in GetOneParticle
268  // (they are set here in hopes of eeking out a little bit of speed)
269 
271 
272  // Generate the particle PDFs for this zenith.
273  // fill in fRadialDistro and fAzimuthDistro ..
274  // It might (or might not) make sense to move this
275  // to a separate function. (can be moved to init)
276  // -----------------------------------------------
277 
278  fRandomEngine =
279  &RandomEngineRegistry::GetInstance().
280  Get(RandomEngineRegistry::eDetector).GetEngine();
281 
282  fCurrentDistIndex = 0;
284 
285  // force generation of first batch of particles on
286  // startup of GetOneParticle
287  fCurrentPDI.cachePosition = UINT_MAX;
288 
290 
291  // Dump station positions as a diagnostic
292 
293  if (fDiagnosticsOn) {
294  const SDetector& sDet = Detector::GetInstance().GetSDetector();
297  sIt != sDet.AllStationsEnd() ; ++sIt) {
298  fStationPosGroundCS->Fill(sIt->GetPosition().GetX(lCs)/kilometer,
299  sIt->GetPosition().GetY(lCs)/kilometer);
300  }
301  }
302 
303 
304  return eSuccess;
305 }
306 
307 
310 {
311  INFO("ShowerInventor::Finish()");
312 
313  delete fGroundPlane;
314  delete fCoreLocation;
315  delete fCurrentParticle;
316 
317  for (vector<ParticleDistInfo>::iterator it = fParticleDistros.begin();
318  it != fParticleDistros.end(); ++it) {
319  delete it->radialDistro;
320  delete it->azimuthDistro;
321  delete it->timeDistro;
322  delete it->weightDistro;
323  }
324  fParticleDistros.clear();
325 
326  if (fDiagnosticsOn) {
327 
328  TFile diagnosticsFile(fDiagnosticsFileName.c_str(), "recreate");
329 
330  for (map<int, DiagnosticHistos>::iterator dIt = fDiagnosticHistos.begin() ;
331  dIt != fDiagnosticHistos.end() ; ++dIt) {
332 
333  dIt->second.radialDistro->Write();
334  dIt->second.azimuthDistro->Write();
335  dIt->second.timeDistro->Write();
336  dIt->second.weightDistro->Write();
337  dIt->second.positionsShowerCS->Write();
338  dIt->second.positionsGroundCS->Write();
339  }
340  fStationPosGroundCS->Write();
341 
342  diagnosticsFile.cd();
343  diagnosticsFile.Close();
344  }
345 
346  return eSuccess;
347 }
348 
349 
350 Particle*
352 {
355  fCurrentPDI.cachePosition = UINT_MAX;
356  }
357 
358  // Cache random numbers from various distributions (for speed).
359 
361  FillCaches();
362 
363  const unsigned int cI = fCurrentPDI.cachePosition;
364 
365  const double phi = (*fCurrentPDI.azimuthRandomCache)[cI];
366  const double r = (*fCurrentPDI.radiusRandomCache)[cI];
367 
368  const double x1 = r * cos(phi) / cos(fCurrentZenith);
369  const double y1 = r * sin(phi);
370 
371  const double showerAzimuth = fAzimuth;
372  const double sinShowerAzimuth = sin(-showerAzimuth);
373  const double cosShowerAzimuth = cos(-showerAzimuth);
374 
375  // how to introduce small perturbations to individual particle directions?
376  const Vector
377  particleDirection(-1, 0, 0, fShowerCS, Vector::kSpherical);
378 
379  const Point
380  particlePosition( cosShowerAzimuth * x1 + sinShowerAzimuth * y1,
381  -sinShowerAzimuth * x1 + cosShowerAzimuth * y1,
382  0, fShowerLocalCS);
383 
384  if (fCurrentParticle)
385  delete fCurrentParticle;
386 
389  Particle::eShower,
390  particlePosition,
391  particleDirection,
394  15*GeV); // energy goes here
395 
398 
399  if (fDiagnosticsOn) {
400 
401  const int idx = fCurrentPDI.particleType;
402 
403  // fDiagnosticHistos[idx].positionsShowerCS->
404  // Fill(particlePosition.GetX(fExternalCS)/kilometer,
405  // particlePosition.GetY(fExternalCS)/kilometer);
406  fDiagnosticHistos[idx].positionsShowerCS->
409  fDiagnosticHistos[idx].positionsGroundCS->
412  fDiagnosticHistos[idx].radialDistro->
414  fDiagnosticHistos[idx].azimuthDistro->
415  Fill((*fCurrentPDI.azimuthRandomCache)[cI]);
416  fDiagnosticHistos[idx].timeDistro->
418  fDiagnosticHistos[idx].weightDistro->
419  Fill((*fCurrentPDI.weightRandomCache)[cI]);
420  }
421 
422  return fCurrentParticle;
423 }
424 
425 
428 {
429  Branch pdfB = b.GetChild("PDF");
430  if (pdfB) {
431  string pdf;
432  pdfB.GetData(pdf);
433  double min;
434  b.GetChild("Min").GetData(min);
435  double max;
436  b.GetChild("Max").GetData(max);
437  unsigned int nBins;
438  b.GetChild("NumberBins").GetData(nBins);
439  return new RandomSamplerFromPDF(pdf, min, max, nBins);
440  }
441 
442  Branch xB = b.GetChild("X");
443  if (xB) {
444  vector<double> xValues;
445  xB.GetData(xValues);
446  vector<double> yValues;
447  b.GetChild("Y").GetData(yValues);
448  return new RandomSamplerFromPDF(TabulatedFunction(xValues, yValues));
449  }
450 
451  Branch dB = b.GetChild("Discrete");
452  if (dB) {
453  vector<double> x;
454  vector<double> y;
455  dB.GetChild("x").GetData(x);
456  dB.GetChild("y").GetData(y);
457  return new RandomSamplerFromPDF(x, y, RandomSamplerFromPDF::eDiscrete);
458  }
459 
460  throw XMLParseException("No RandomSampler corresponds to the specifications in the configuration file.");
461 }
462 
463 
464 void
466 {
467  // density vs. radius
468 
472 
476 
477  // azimuth
478 
481 
486  // time smearing vs radius
487 
490 
492  fCurrentPDI.timeDistro->shootArray(*fRandomEngine,
495  // weight vs radius
496 
499 
504 
506 }
std::vector< double > RandomCacheContainer
Branch GetTopBranch() const
Definition: Branch.cc:63
utl::VRandomSampler * GetSampler(const utl::Branch &b)
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
double Plane(const utl::Point &point, const utl::Vector &normal, const utl::Photon &photonIn, utl::Photon &photonOut)
Definition: RTFunctions.cc:41
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
Point object.
Definition: Point.h:32
Report success to RunController.
Definition: VModule.h:62
StationIterator AllStationsEnd() const
End of the collection of pointers to all stations in the history of the array.
Definition: SDetector.h:126
Describes a particle for Simulation.
Definition: Particle.h:26
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
Class to hold collection (x,y) points and provide interpolation between them.
bool HasGroundParticles() const
bool HasSimShower() const
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
void SetGroundParticleCoordinateSystemAzimuth(const double azimuth)
Set the azimuth angle of the shower. Angle in x-y plane wrt. to the x axis (0 is from east)...
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
utl::CoordinateSystemPtr fShowerLocalCS
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Exception for errors encountered when parsing XML.
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
void SetFileInterface(VShowerFileParticleIterator *const interface)
StationIterator AllStationsBegin() const
Beginning of the collection of pointers to all stations in the history of the array.
Definition: SDetector.h:121
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
Branch GetNextSibling() const
Get next sibling of this branch.
Definition: Branch.cc:284
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Break current loop. It works for nested loops too!
Definition: VModule.h:66
Reference ellipsoids for UTM transformations.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
constexpr double kPi
Definition: MathConstants.h:24
constexpr double nanosecond
Definition: AugerUnits.h:143
ShowerSimData & GetSimShower()
utl::RandomEngine::RandomEngineType * fRandomEngine
utl::ShowerParticleList & GetGroundParticles()
Get particle list Proxy.
const CoordinateSystemPtr GetECEF() const
Get the ECEF.
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Iterator that generates particles &quot;on-the-fly&quot; . This uses the machinery in ShowerInventor to fetch p...
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
std::vector< ParticleDistInfo > fParticleDistros
void SetPrimaryParticle(const int type)
Set the type of the shower primary particle.
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
constexpr double GeV
Definition: AugerUnits.h:187
utl::CoordinateSystemPtr fShowerCS
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
void SetGroundParticleCoordinateSystemZenith(const double zenith)
Set the zenith angle of the shower. Room angle between z-axis and direction from where the shower is ...
bool HasGeometry() const
check initialization of shower geometry
void MakeGeometry(const utl::Point &pointOnShowerAxis)
initialize the shower geometry. Pos is a point on the shower axis, but not necessarily the core ...
constexpr double kilometer
Definition: AugerUnits.h:93
Vector object.
Definition: Vector.h:30
void MakeSimShower(const evt::VShowerGeometryProducer &p)
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
bool HasTimeStamp() const
Check initialization of the TimeStamp.
void MakeTimeStamp(const utl::TimeStamp &ts)
Make the TimeStamp of the shower.
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
std::map< int, DiagnosticHistos > fDiagnosticHistos
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
Point GetPoint(const CoordinateSystemPtr &theCS=CoordinateSystemPtr()) const
Get a cartesian point from an UTMPoint.
Definition: UTMPoint.cc:45
std::vector< double > fZeniths
TimeStamp GetTimeStamp() const
Definition: UTCDateTime.cc:115
Class to shoot random numbers given by a user-defined distribution function.
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
ShowerInventorParticleIterator * fFileIterator

, generated on Tue Sep 26 2023.