ParticleInjectorOG/ParticleInjector.cc
Go to the documentation of this file.
1 #include <utl/config.h>
2 
3 #include "ParticleInjector.h"
4 
5 #include <det/Detector.h>
6 
7 #include <sdet/SDetector.h>
8 #include <sdet/Station.h>
9 
10 #include <evt/Event.h>
11 
12 #include <fwk/CentralConfig.h>
13 #include <fwk/RandomEngineRegistry.h>
14 
15 #include <sevt/SEvent.h>
16 #include <sevt/Station.h>
17 #include <sevt/StationSimData.h>
18 #include <sevt/Header.h>
19 
20 #include <utl/AugerCoordinateSystem.h>
21 #include <utl/AugerUnits.h>
22 #include <utl/MathConstants.h>
23 #include <utl/Particle.h>
24 #include <utl/PhysicalConstants.h>
25 #include <utl/Point.h>
26 #include <utl/TimeStamp.h>
27 #include <utl/ErrorLogger.h>
28 #include <utl/RandomEngine.h>
29 #include <utl/Reader.h>
30 #include <utl/Vector.h>
31 
32 #include <CLHEP/Random/Randomize.h>
33 
34 #include <TF1.h>
35 #include <TFile.h>
36 #include <TNtuple.h>
37 
38 #include <cstddef>
39 #include <sstream>
40 #include <vector>
41 #include <iostream>
42 
43 using namespace ParticleInjectorOG;
44 using namespace det;
45 using namespace sdet;
46 using namespace evt;
47 using namespace fwk;
48 using namespace sevt;
49 using namespace utl;
50 using namespace std;
51 
52 using CLHEP::RandFlat;
53 
54 
60 
61 
63  fUseSingleTank(false),
64  fUseDiscreteDirection(true),
65  fUseDiscreteSpectrum(true),
66  fUseInjectAllParticles(false),
67  fUseSinglePosition(false),
68  fUseDiscreteTime(true),
69  fNumberOfParticles(0),
70  fSingleTankID(0),
71  fX(0.0), fY(0.0), fZ(0.0),
72  //fContinuousZenithString(""),
73  //fContinuousAzimuthString(""),
74  //fContinuousTimeString(""),
75  //fMuonSpectrumString(""),
76  //fElectronSpectrumString(""),
77  //fPhotonSpectrumString(""),
78  fContinuousZenithDistribution(NULL),
79  fContinuousAzimuthDistribution(NULL),
80  fTimeSpectrum(NULL),
81  fMuonSpectrum(NULL),
82  fElectronSpectrum(NULL),
83  fPhotonSpectrum(NULL),
84  fMuonEnergyMin(0.0), fMuonEnergyMax(0.0),
85  fElectronEnergyMin(0.0), fElectronEnergyMax(0.0),
86  fPhotonEnergyMin(0.0), fPhotonEnergyMax(0.0),
87  fMuonSpectrumMax(0.0), fElectronSpectrumMax(0.0), fPhotonSpectrumMax(0.0),
88  fParticleType(utl::Particle::eUndefined),
89  fRandomEngine(0),
90  fCurrentDetectorStation(NULL), fSEvent(NULL)
91 {
92 }
93 
94 
96 {
97  delete fTimeSpectrum;
99  delete fMuonSpectrum;
100  delete fElectronSpectrum;
101  delete fPhotonSpectrum;
103 }
104 
105 
108 {
109 //#warning dv: ParticleInjector needs xsd!
110  Branch topB =
111  CentralConfig::GetInstance()->GetTopBranch("ParticleInjector");
112 
113  Branch configB = topB.GetChild("config");
114 
115  // Reading config branch
116  configB.GetChild("UseSingleTank").GetData(fUseSingleTank);
117  configB.GetChild("UseInjectAllParticles").GetData(fUseInjectAllParticles);
118  configB.GetChild("UseSinglePosition").GetData(fUseSinglePosition);
119  configB.GetChild("UseDiscreteDirection").GetData(fUseDiscreteDirection);
120  configB.GetChild("UseDiscreteEnergy").GetData(fUseDiscreteSpectrum);
121  configB.GetChild("UseDiscreteTime").GetData(fUseDiscreteTime);
122  cerr << "UseInjectAllParticles = " << fUseInjectAllParticles << '\n'
123  << "UseSinglePosition = " << fUseSinglePosition << '\n'
124  << "UseDiscreteDirection = " << fUseDiscreteDirection << '\n'
125  << "UseDiscreteSpectrum = " << fUseDiscreteSpectrum << '\n'
126  << "UseDiscreteTime = " << fUseDiscreteTime << endl;
127 
128  topB.GetChild("NumberOfParticles").GetData(fNumberOfParticles);
129 
130  // Single Position
131  if (fUseSinglePosition) {
132  Branch singlePositionB = topB.GetChild("SinglePosition");
133  singlePositionB.GetChild("ParticleX").GetData(fX);
134  singlePositionB.GetChild("ParticleY").GetData(fY);
135  singlePositionB.GetChild("ParticleZ").GetData(fZ);
136  }
137 
138  // Direction Branch
139  if (!fUseDiscreteDirection) {
140  //Continuous distribution
141  Branch cdsB = topB.GetChild("UseContinuousDirectionSpectrum");
142  //zenith angle
143  cdsB.GetChild("Zenith").GetData(fContinuousZenithString);
145  new TF1("Zenith", fContinuousZenithString.c_str(), 0.0, utl::kPi/2.0);
146  //azimuth angle
147  cdsB.GetChild("Azimuth").GetData(fContinuousAzimuthString);
149  new TF1("Azimuth", fContinuousAzimuthString.c_str(), 0.0, 2.0*utl::kPi);
150  } else {
151  //Discrete distribution
152  Branch ddsB = topB.GetChild("UseDiscreteDirectionSpectrum");
153  //zenith angle
154  ddsB.GetChild("Zenith").GetData(fDiscreteZenith);
155  //azimuth angle
156  ddsB.GetChild("Azimuth").GetData(fDiscreteAzimuth);
157  }
158 
159  // Energy Branch
160  if (!fUseDiscreteSpectrum) {
161 
162  //Continuous distribution
163  Branch cesB = topB.GetChild("UseContinuousEnergySpectrum");
164 
165  cesB.GetChild("MuonSpectrum").GetData(fMuonSpectrumString);
166  cesB.GetChild("MuonEnergyMin").GetData(fMuonEnergyMin);
167  cesB.GetChild("MuonEnergyMax").GetData(fMuonEnergyMax);
168  fMuonSpectrum =
169  new TF1("MuonSpectrum", fMuonSpectrumString.c_str(),
171 
172  cesB.GetChild("ElectronSpectrum").GetData(fElectronSpectrumString);
173  cesB.GetChild("ElectronEnergyMin").GetData(fElectronEnergyMin);
174  cesB.GetChild("ElectronEnergyMax").GetData(fElectronEnergyMax);
176  new TF1("ElectronSpectrum", fElectronSpectrumString.c_str(),
178 
179  cesB.GetChild("PhotonSpectrum").GetData(fPhotonSpectrumString);
180  cesB.GetChild("PhotonEnergyMin").GetData(fPhotonEnergyMin);
181  cesB.GetChild("PhotonEnergyMax").GetData(fPhotonEnergyMax);
183  new TF1("PhotonSpectrum", fPhotonSpectrumString.c_str(),
185 
186  } else {
187 
188  //Discrete distribution
189  Branch desB = topB.GetChild("UseDiscreteEnergySpectrum");
190 
191  desB.GetChild("MuonSpectrum").GetData(fDiscreteMuonFlux);
192  fMuonSpectrumMax = -10;
193  for (unsigned int i = 0; i < fDiscreteMuonFlux.size(); ++i)
196  desB.GetChild("MuonEnergy").GetData(fDiscreteMuonEnergy);
197 
198  desB.GetChild("ElectronSpectrum").GetData(fDiscreteElectronFlux);
199  fElectronSpectrumMax = -10;
200  for (unsigned int i = 0; i < fDiscreteElectronFlux.size(); ++i)
203  desB.GetChild("ElectronEnergy").GetData(fDiscreteElectronEnergy);
204 
205  desB.GetChild("PhotonSpectrum").GetData(fDiscretePhotonFlux);
206  fPhotonSpectrumMax = -10;
207  for (unsigned int i = 0; i < fDiscretePhotonFlux.size(); i++)
210  desB.GetChild("PhotonEnergy").GetData(fDiscretePhotonEnergy);
211 
212  }
213 
214  topB.GetChild("SingleTankID").GetData(fSingleTankID);
215 
216  int particleType;
217  topB.GetChild("ParticleType").GetData(particleType);
218  fParticleType = static_cast<utl::Particle::Type>(particleType);
219 
220  if (fUseDiscreteTime)
221  topB.GetChild("UseDiscreteTimeSpectrum").GetChild("ParticleTime").GetData(fDiscreteParticleTime);
222 
223  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
224 
225  return eSuccess;
226 }
227 
228 
231 {
232  if (!theEvent.HasSEvent()) {
233  ERROR("No SEvent present. Use EventGenerator module to create "
234  "an event before running ParticleInjector.");
235  return eFailure;
236  }
237 
238  fSEvent = &theEvent.GetSEvent();
239 
240  const sdet::SDetector& theSDetector =
241  det::Detector::GetInstance().GetSDetector();
242 
243  if (fUseSingleTank) {
244 
246  InjectParticles();
247 
248  } else
249 
250  for (SDetector::StationIterator sdIt = theSDetector.StationsBegin();
251  sdIt != theSDetector.StationsEnd(); ++sdIt) {
252 
253  fCurrentDetectorStation = &theSDetector.GetStation(sdIt->GetId());
254  InjectParticles();
255 
256  }
257 
258  return eSuccess;
259 }
260 
261 
264 {
269  delete fMuonSpectrum;
270  fMuonSpectrum = 0;
271  delete fElectronSpectrum;
272  fElectronSpectrum = 0;
273  delete fPhotonSpectrum;
274  fPhotonSpectrum = 0;
275  return eSuccess;
276 }
277 
278 
279 void
281 {
284 
285  sevt::Station& currentEventStation =
287 
288  if (!currentEventStation.HasSimData())
289  currentEventStation.MakeSimData();
290 
292 
293  for (unsigned int num = 0; num < fNumberOfParticles; ++num) {
294 
295  const double azimuth = GetAzimuth();
296  const double zenith = GetZenith();
297 
298  double x;
299  double y;
300  double z;
301  SetPosition(x, y, z);
302 
303  const Point position(x, y, z, cs);
304 
305  const double sinZenith = sin(zenith);
306  const double pX = -sinZenith*cos(azimuth);
307  const double pY = -sinZenith*sin(azimuth);
308  const double pZ = -cos(zenith);
309 
310  const Vector direction(pX, pY, pZ, cs);
311 
312  const TimeInterval time(GetTime());
313 
315 
316  const int index = int(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 5));
318 
319  }
320 
321  const double energy = GetEnergy();
323  position, direction, time, 1, energy);
324 
325  currentEventStation.AddParticle(newParticle);
326 
327  }
328 }
329 
330 
331 double
333 {
334  if (fUseDiscreteDirection) {
335 
336  const unsigned int num = fDiscreteAzimuth.size();
337  unsigned int index;
338 
339  do
340  index =
341  (unsigned int)(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, num));
342  while (index >= num);
343 
344  return fDiscreteAzimuth[index];
345 
346  } else
347 
348  return fContinuousAzimuthDistribution->GetRandom();
349 }
350 
351 
352 double
354 {
355  if (fUseDiscreteDirection) {
356 
357  const unsigned int num = fDiscreteZenith.size();
358  unsigned int index;
359 
360  do
361  index =
362  (unsigned int)(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, num));
363  while (index >= num);
364 
365  return fDiscreteZenith[index];
366 
367  } else
368 
369  return fContinuousZenithDistribution->GetRandom();
370 }
371 
372 
373 double
375 {
376  switch (fParticleType) {
377 
380 
381  return fUseDiscreteSpectrum ?
383  fMuonSpectrum->GetRandom()*GeV;
384  break;
385 
388 
389  return fUseDiscreteSpectrum ?
391  fElectronSpectrum->GetRandom()*GeV;
392  break;
393 
395 
396  return fUseDiscreteSpectrum ?
398  fPhotonSpectrum->GetRandom()*GeV;
399  break;
400 
401  default:
402 
403  INFO("Unknown particle type used for spectrum injection in ParticleInjector.");
404  return 0;
405  break;
406 
407  }
408 }
409 
410 
411 double
413 {
414  const unsigned int num = fDiscreteParticleTime.size();
415  unsigned int index;
416 
417  do
418  index =
419  (unsigned int)(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, num));
420  while (index >= num);
421 
422  return fDiscreteParticleTime[index];
423 }
424 
425 
426 void
427 ParticleInjector::SetPosition(double& x, double& y, double& z)
428 {
429  const double height = fCurrentDetectorStation->GetHeight();
430  const double radius = fCurrentDetectorStation->GetRadius();
431 
432  if (fUseSinglePosition) {
433 
434  x = fX;
435  y = fY;
436  z = fZ;
437 
438  } else {
439 
440  // Something simple and easy for now
441 
442  const double theta =
443  acos(RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0)),
444  phi = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 2.0*kPi);
445 
446  if (fabs(theta) >= atan2(radius, height)) {
447 
448  x = radius*cos(phi);
449  y = radius*sin(phi);
450  z = radius*cos(theta);
451 
452  } else {
453 
454  // We should be guarded against tan(kPi/2.0) since atan2(radius/height)
455  // is less than this
456 
457  x = height*tan(theta)*cos(phi);
458  y = height*tan(theta)*sin(phi);
459  z = height;
460 
461  }
462 
463  }
464 
465 }
466 
467 
468 double
469 ParticleInjector::GetDiscreteEnergy(std::vector<double>& flux,
470  std::vector<double>& energy,
471  const double max)
472 {
473  if (flux.size() != energy.size()) {
474  INFO("Flux and energy array sizes not equal!");
475  }
476  else if (max <= 0) {
477  INFO("Non-positive maximum value for flux given.");
478  }
479  else {
480 
481  const unsigned int num = flux.size();
482  unsigned int index;
483 
484  do
485  index =
486  (unsigned int)(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, num));
487  while (index >= num ||
488  RandFlat::shoot(&fRandomEngine->GetEngine(), 0, max) >= flux[index]);
489 
490  return energy[index];
491 
492  }
493 
494  return 0;
495 }
496 
497 
498 // Configure (x)emacs for this file ...
499 // Local Variables:
500 // modex: c++
501 // compile-command: "make -C .. -k"
502 // End:
Branch GetTopBranch() const
Definition: Branch.cc:63
Point object.
Definition: Point.h:32
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
Report success to RunController.
Definition: VModule.h:62
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
void MakeSimData()
Make station simulated data object.
static utl::Particle::Type spectrumParticles[5]
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
Describes a particle for Simulation.
Definition: Particle.h:26
fwk::VModule::ResultFlag Run(evt::Event &theEvent)
Run: invoked once per event.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Type
Particle types.
Definition: Particle.h:48
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
bool HasSimData() const
Check whether station simulated data exists.
constexpr double kPi
Definition: MathConstants.h:24
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
Definition: SDetector.h:102
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger reference system centered on the tank.
double GetRadius() const
Radius of the tank (water only)
double GetHeight() const
Height of the tank (water only)
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
Definition: SDetector.h:97
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
Definition: SEvent.cc:65
void AddParticle(const utl::Particle &particle)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
Definition: SEvent.h:116
double GetDiscreteEnergy(std::vector< double > &flux, std::vector< double > &energy, double max)
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
constexpr double GeV
Definition: AugerUnits.h:187
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
Vector object.
Definition: Vector.h:30
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
void SetPosition(double &x, double &y, double &z)
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
int GetId() const
Station ID.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
sevt::SEvent & GetSEvent()
bool HasSEvent() const

, generated on Tue Sep 26 2023.