SdAccidentalInjector.cc
Go to the documentation of this file.
1 #include "SdAccidentalInjector.h"
2 
3 #include <det/Detector.h>
4 
5 #include <sdet/SDetector.h>
6 #include <sdet/Station.h>
7 
8 #include <evt/Event.h>
9 #include <evt/ShowerSimData.h>
10 
11 #include <fwk/CentralConfig.h>
12 #include <fwk/RunController.h>
13 
14 #include <sevt/SEvent.h>
15 #include <sevt/Station.h>
16 #include <sevt/StationSimData.h>
17 #include <sevt/Header.h>
18 
19 #include <utl/Math.h>
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/TimeInterval.h>
28 #include <utl/ErrorLogger.h>
29 #include <utl/Vector.h>
30 #include <utl/Cache.h>
31 #include <utl/CoordinateSystemPtr.h>
32 
33 #include <TH2D.h>
34 #include <TFile.h>
35 
36 #include <cstddef>
37 #include <sstream>
38 #include <vector>
39 
40 using namespace SdAccidentalInjectorKG;
41 using namespace fwk;
42 using namespace utl;
43 using namespace std;
44 
45 
48 {
49  const Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("SdAccidentalInjector");
50 
51  // Beware: We assume that all stations are identical
52  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
53  const double radius = sDetector.StationsBegin()->GetRadius();
54  const double height = sDetector.StationsBegin()->GetHeight();
55  const double hull = sDetector.StationsBegin()->GetThickness();
56  fCyl = CylinderSurfaceSampler(radius, height, hull);
57 
58  topBranch.GetChild("muonRatePerStation").GetData(fMuonRatePerStation);
59  // these times are relative to core time
60  topBranch.GetChild("timeBefore").GetData(fTimeBefore);
61  topBranch.GetChild("timeAfter").GetData(fTimeAfter);
62  topBranch.GetChild("maxDistance").GetData(fMaxDistance2);
63  fMaxDistance2 *= fMaxDistance2;
64 
65  Branch bFlux = topBranch.GetChild("fluxHistogram");
66  const auto nCosThetaColumns = bFlux.GetChild("nCosThetaColumns").Get<unsigned int>();
67  const auto nLog10EGeVRows = bFlux.GetChild("nLog10EGeVRows").Get<unsigned int>();
68  const auto rangeCosTheta = bFlux.GetChild("rangeCosTheta").Get<vector<double>>();
69  const auto rangeLog10EGeV = bFlux.GetChild("rangeLog10EGeV").Get<vector<double>>();
70  const auto table = bFlux.GetChild("table").Get<vector<double>>();
71 
72  const double minimumEnergy = topBranch.GetChild("minimumEnergy").Get<double>();
73  const double lgEmin = log10(minimumEnergy / GeV);
74  const int iemin = max(0., floor((lgEmin - rangeLog10EGeV.at(0)) / (rangeLog10EGeV.at(1) - rangeLog10EGeV.at(0)) * nLog10EGeVRows));
75  if (iemin >= int(nLog10EGeVRows)) {
76  ERROR("minimumEnergy cuts the whole histogram away!");
77  return eFailure;
78  }
79  const double lgEminEdge = rangeLog10EGeV[0] + iemin * (rangeLog10EGeV[1] - rangeLog10EGeV[0]) / nLog10EGeVRows;
80 
81  // we only need histogram above minimum energy
82  TH2D h("SdAccidentalInjector::fHist", "",
83  nLog10EGeVRows - iemin, lgEminEdge, rangeLog10EGeV[1], // x
84  nCosThetaColumns, rangeCosTheta.at(0), rangeCosTheta.at(1)); // y
85 
86  // muon rate per station =
87  // integral (muon_flux * effective_station_area dlogE dCosTheta dPhi)
88  // only relative intensities are important for sampling,
89  // so constant factors are skipped
90  int i = 0;
91  for (unsigned int ie = 1; ie <= nLog10EGeVRows; ++ie) {
92  //const double lgE = h.GetXaxis().GetBinCenter(ie);
93  for (unsigned int ic = 1; ic <= nCosThetaColumns; ++ic) {
94  const double cosTh = h.GetYaxis()->GetBinCenter(ic);
95  const double area = StationArea(radius, height, cosTh);
96  const double flux = table.at(i++);
97  if (int(ie) >= iemin)
98  h.SetBinContent(ie - iemin, ic, flux * area);
99  }
100  }
101 
102  fHist = HistogramSampler(h);
103 
104  ostringstream msg;
105  msg << "Configuration:\n"
106  "Muon rate per station [Hz] : " << fMuonRatePerStation/(1./s) << "\n"
107  "Minimum energy [GeV] : " << minimumEnergy/GeV << "\n"
108  "Start injection [ns, rel. to core time]: " << -fTimeBefore/ns << "\n"
109  "Stop injection [ns, rel. to core time]: " << fTimeAfter/ns;
110  INFO(msg);
111 
112  return eSuccess;
113 }
114 
115 
118 {
119  if (!event.HasSimShower()) {
120  ERROR("Current event does not have a simulated shower.");
121  return eFailure;
122  }
123 
124  const Point& core = event.GetSimShower().GetPosition();
125 
126  sevt::SEvent& sEvent = event.GetSEvent();
127  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
128 
129  ostringstream msg;
130  msg << "Injecting accidental muons:";
131  int nTotal = 0;
132  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
133  sdIt != sDetector.StationsEnd(); ++sdIt) {
134 
135  const sdet::Station& dStation = *sdIt;
136 
137  if ((dStation.GetPosition() - core).GetMag2() > fMaxDistance2)
138  continue;
139 
140  const int nMuons = fPoisson(fMuonRatePerStation * (fTimeAfter + fTimeBefore));
141 
142  if (!nMuons)
143  continue;
144 
145  if (!sEvent.HasStation(dStation.GetId()))
146  sEvent.MakeStation(dStation.GetId());
147  sevt::Station& station = sEvent.GetStation(dStation.GetId());
148 
149  if (!station.HasSimData())
150  station.MakeSimData();
151 
152  const CoordinateSystemPtr dStationCS = dStation.GetLocalCoordinateSystem();
153 
154  msg << "\n"
155  "station " << dStation.GetId() << " gets " << nMuons << " muon" << (nMuons == 1 ? "" : "s") << ':';
156 
157  for (int iMu = 0; iMu < nMuons; ++iMu) {
158 
159  const auto ec = fHist(); // returns: lg(E/GeV), cos(th)
160  const double energy = pow(10, ec.first) * GeV;
161  const double theta = acos(ec.second);
162  const double phi = fFlat(2 * kPi);
163 
164  const double totalMomentum = sqrt(energy*energy - kMuonMass*kMuonMass);
165  const Vector pMomentum(-totalMomentum, theta, phi, dStationCS, Vector::kSpherical);
166  const TimeInterval pTime = fFlat(-fTimeBefore, fTimeAfter);
167 
168  const tuple<double, double, double> xyz = fCyl(theta, phi);
169  const Point pPosition(get<0>(xyz), get<1>(xyz), get<2>(xyz), dStationCS);
170 
171  const Particle particle(Particle::eMuon, Particle::eBackground, pPosition, pMomentum, pTime, 1);
172 
173  station.AddParticle(particle);
174 
175  msg << "\n"
176  " energy = " << (energy/GeV) << " GeV, "
177  "theta = " << theta/degree << " deg, "
178  "time = " << pTime.GetInterval() / nanosecond << " ns";
179 
180  }
181 
182  nTotal += nMuons;
183 
184  }
185 
186  msg << "\n"
187  "Total number of accidental muons: " << nTotal;
188  INFO(msg);
189 
190  return eSuccess;
191 }
Branch GetTopBranch() const
Definition: Branch.cc:63
double StationArea(const double radius, const double height, const double cosTheta)
const double degree
Point object.
Definition: Point.h:32
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
Detector description interface for Station-related data.
void MakeSimData()
Make station simulated data object.
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
Describes a particle for Simulation.
Definition: Particle.h:26
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
bool HasSimShower() const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
utl::Point GetPosition() const
Tank position.
T Get() const
Definition: Branch.h:271
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
constexpr double s
Definition: AugerUnits.h:163
bool HasSimData() const
Check whether station simulated data exists.
const double ns
constexpr double kPi
Definition: MathConstants.h:24
constexpr double nanosecond
Definition: AugerUnits.h:143
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)
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
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 GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
constexpr double kMuonMass
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
double GetThickness() const
Thickness of the tank walls.
struct particle_info particle[80]
Vector object.
Definition: Vector.h:30
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
int GetId() const
Station ID.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.