RPCSimulator.cc
Go to the documentation of this file.
1 #include "RPCSimulator.h"
2 #include "RPCChargeGenerator.h"
3 
4 #include <iostream>
5 #include <fstream>
6 #include <iterator>
7 
8 #include <det/Detector.h>
9 #include <sdet/SDetector.h>
10 #include <sdet/Station.h>
11 #include <cdet/CDetector.h>
12 
13 #include <evt/Event.h>
14 #include <evt/ShowerSimData.h>
15 
16 #include <fwk/CentralConfig.h>
17 #include <fwk/RunController.h>
18 #include <fwk/LocalCoordinateSystem.h>
19 #include <fwk/CoordinateSystemRegistry.h>
20 #include <fwk/RandomEngineRegistry.h>
21 
22 #include <cevt/CEvent.h>
23 
24 #include <utl/config.h>
25 #include <utl/Trace.h>
26 #include <utl/AugerUnits.h>
27 #include <utl/Math.h>
28 #include <utl/MathConstants.h>
29 #include <utl/PhysicalConstants.h>
30 #include <utl/TimeStamp.h>
31 #include <utl/TabulatedFunction.h>
32 #include <utl/ErrorLogger.h>
33 #include <utl/Particle.h>
34 #include <utl/AugerCoordinateSystem.h>
35 #include <utl/UTMPoint.h>
36 #include <utl/MultiTimeDistribution.h>
37 #include <utl/GeometryUtilities.h>
38 
39 #include <CLHEP/Random/RandGauss.h>
40 
41 #include <TH1.h>
42 #include <TProfile.h>
43 #include <TFile.h>
44 
45 #include <sstream>
46 #include <string>
47 #include <vector>
48 
49 using namespace RPCSimulatorLX;
50 using namespace det;
51 using namespace evt;
52 using namespace fwk;
53 using namespace cevt;
54 using namespace utl;
55 using namespace std;
56 using CLHEP::RandGauss;
57 
58 
60 {
61  delete fChargeHisto;
62  delete fChargeProfileHisto;
63  delete fChargeGenerator;
64 }
65 
66 
68 {
69  INFO("RPCSimulator::Init()");
70 
71  Branch topB = CentralConfig::GetInstance()->GetTopBranch("RPCSimulator");
72 
73  const AttributeMap useAtt({{ "use", "yes" }});
74  Branch rootB = topB.GetChild("RootHistogramsFilename", useAtt);
75  if (rootB) {
76  fUseRootHistos = true;
77  rootB.GetData(fRootHistoFilename);
78  fChargeHisto = new TH1D("chargeDist", "charge distribution", 200, 0, 100);
79  fChargeProfileHisto = new TProfile("AverageChargeVsAngle", "Average charge vs angle of incidence at RPC", 90, 0, 90);
80  }
81 
82  Branch chargeB = topB.GetChild("ChargeGenerator", useAtt);
83  if (chargeB) {
84  fUseChargeDistribution = true;
85  const double k0 = chargeB.GetChild("k_param").Get<double>();
86  const double th0 = chargeB.GetChild("th_param").Get<double>();
87  const double referenceAngle = chargeB.GetChild("ref_angle").Get<double>();
88  fChargeGenerator = new RPCChargeGenerator(k0, th0, referenceAngle);
89  } else {
90  WARNING("PDF for charge generation in the RPC switched off! "
91  "A fixed charge of 3.1415 pC will be set for each particle crossing the gas!");
92  }
93 
94  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
95 
96  return eSuccess;
97 }
98 
99 
102 {
103  INFO("RPCSimulator::Finish()");
104 
105  if (fUseRootHistos) {
106  TFile outFile(fRootHistoFilename.c_str(), "RECREATE");
107 
108  fChargeHisto->Write();
109  fChargeProfileHisto->Write();
110  outFile.Write();
111  outFile.Close();
112 
113  delete fChargeHisto;
114  delete fChargeProfileHisto;
115 
116  fChargeHisto = nullptr;
117  fChargeProfileHisto = nullptr;
118  }
119 
120  delete fChargeGenerator;
121  fChargeGenerator = nullptr;
122 
123  return eSuccess;
124 }
125 
126 
129 {
130  INFO("RPCSimulator::Run()");
131 
132  if (!event.HasCEvent()) {
133  ERROR("RPCSimulator::No CEvent!");
134  return eFailure;
135  }
136 
137  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
138  const cdet::CDetector& cDetector = det::Detector::GetInstance().GetCDetector();
139 
140  CEvent &cEvent = event.GetCEvent();
141 
142  for (CEvent::StationIterator cIt = cEvent.StationsBegin(); cIt != cEvent.StationsEnd(); ++cIt) {
143 
144  Station& station = *cIt;
145 
146  if (!station.HasSimData()) {
147  cout << "No sim data for station " << station.GetId() << " !!!!";
148  continue;
149  }
150 
151  StationSimData &simData = station.GetSimData();
152 
153  if (simData.ParticlesBegin() == simData.ParticlesEnd())
154  continue;
155 
156  const CoordinateSystemPtr cs = sDetector.GetStation(station.GetId()).GetLocalCoordinateSystem();
157 
158  const cdet::Station& dStation = cDetector.GetStation(station);
159 
160  for (StationSimData::ParticleIterator partIt = simData.ParticlesBegin();
161  partIt != simData.ParticlesEnd(); ++partIt) {
162 
163  const Particle& part = *partIt;
164 
165  // Consider only partices with energy deposited in the gas of the RPC
166  // Energy deposited is stored in the weight data member of class utl::Particle
167 
168  if (part.GetWeight() <= 0) // Consider only particles depositing energy in the gas
169  continue;
170 
171  const Point& partPosition = part.GetPosition();
172  const Vector& partMomentum = part.GetDirection();
173 
174  const double particleTime = part.GetTime().GetInterval();
175 
176  // CBT start by creating the trace of particles in each pad
177 
178  const unsigned padId = dStation.GetPadId(partPosition);
179 
180  if (!padId) {
181  WARNING("Pad Id is zero !!!");
182  continue;
183  }
184 
185  if (!station.HasPad(padId))
186  station.MakePad(padId);
187 
188  Pad& pad = station.GetPad(padId);
189  if (!pad.HasSimData())
190  pad.MakeSimData();
191 
192  PadSimData& padSimData = pad.GetSimData();
193 
194  // Fill time distributions of particles arriving at the gas of the RPC, with dE>0.0
195 
196  if (!padSimData.HasParticleTimeDistribution())
197  padSimData.MakeParticleTimeDistribution();
198 
199  TimeDistributionI& particleDist1 = padSimData.GetParticleTimeDistribution();
200  particleDist1.AddTime(particleTime);
201 
202  // Make time distribution for any electron at RPC
203  if (part.GetType() == utl::Particle::eElectron ||
204  part.GetType() == utl::Particle::ePositron) {
205 
208 
209  padSimData.GetParticleTimeDistribution(Station::eElectron).AddTime(particleTime);
210  }
211 
212  // Make time distribution for any photon at RPC
213  if (part.GetType() == utl::Particle::ePhoton) {
214 
217 
218  padSimData.GetParticleTimeDistribution(Station::ePhoton).AddTime(particleTime);
219  }
220 
221  // Now for more detailed components
222  Station::SignalComponent component = Station::GetSignalComponent(part);
223 
224  if (!padSimData.HasParticleTimeDistribution(component))
225  padSimData.MakeParticleTimeDistribution(component);
226 
227  TimeDistributionI& particleDist2 = padSimData.GetParticleTimeDistribution(component);
228  particleDist2.AddTime(particleTime);
229 
230  // its ptheta direction (momentum direction)
231  const double theta = partMomentum.GetTheta(cs);
232 
233  const double pC = utl::pico*coulomb;
234 
235  // Generate charge according to particle length inside RPC (i.e. prop to sec(theta))
236  const double charge = fUseChargeDistribution ? fChargeGenerator->GetCharge(theta) : kPi*pC;
237 
238  if (fUseRootHistos) {
239  fChargeHisto->Fill(charge / pC);
240  fChargeProfileHisto->Fill(theta / deg, charge / pC);
241  }
242 
243  const double time = particleTime;
244 
245  // Fill charge distributions of particles arriving at the gas of the RPC, with dE>0.0
246 
247  if (!padSimData.HasChargeTimeDistribution())
248  padSimData.MakeChargeTimeDistribution();
249 
250  TimeDistributionD& chargeDist1 = padSimData.GetChargeTimeDistribution();
251  chargeDist1.AddTime(time, charge);
252 
253  // Make charge time distribution for any electron at RPC
254  if (part.GetType() == utl::Particle::eElectron ||
255  part.GetType() == utl::Particle::ePositron) {
256 
259 
260  padSimData.GetChargeTimeDistribution(Station::eElectron).AddTime(time, charge);
261  }
262 
263  // Make charge time distribution for any photon at RPC
264  if (part.GetType() == utl::Particle::ePhoton) {
265 
268 
269  padSimData.GetChargeTimeDistribution(Station::ePhoton).AddTime(time, charge);
270  }
271 
272  // Now for more detailed components
273  if (!padSimData.HasChargeTimeDistribution(component))
274  padSimData.MakeChargeTimeDistribution(component);
275 
276  TimeDistributionD& chargeDist2 = padSimData.GetChargeTimeDistribution(component);
277  chargeDist2.AddTime(time, charge);
278 
279  }
280  }
281 
282  return eSuccess;
283 }
Branch GetTopBranch() const
Definition: Branch.cc:63
bool HasChargeTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if Pad signal already exists (optionally for a given source)
Definition: PadSimData.h:105
Point object.
Definition: Point.h:32
boost::indirect_iterator< InternalParticleIterator, utl::Particle & > ParticleIterator
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
const TimeInterval & GetTime() const
Arrival time delay at the ground.
Definition: Particle.h:122
Station Level Simulated Data
Detector description interface for CDetector-related data.
Definition: CDetector.h:40
bool HasSimData() const
Check whether station simulated data exists.
Pad & GetPad(const unsigned int padId)
Retrive a Pad by Id.
unsigned int GetPadId(const utl::Point &position) const
StationIterator StationsEnd()
End of all stations.
Definition: CEvent.h:67
Describes a particle for Simulation.
Definition: Particle.h:26
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
utl::TimeDistributionD & GetChargeTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Get simulated signal at the Pad base, optionally for a given source.
Definition: PadSimData.h:93
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
Histogram class for time distributions with suppressed empty bins.
#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
Class to hold simulated data at Pad level.
Definition: PadSimData.h:39
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
Definition: RPCSimulator.cc:67
Detector description interface for MARTA Station-related data.
constexpr double deg
Definition: AugerUnits.h:140
T Get() const
Definition: Branch.h:271
class to hold data at Pad level
Definition: Pad.h:27
utl::TimeDistributionI & GetParticleTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Simulated particle time distribution.
Definition: PadSimData.h:48
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
constexpr double pico
Definition: AugerUnits.h:63
bool HasPad(const unsigned int padId) const
Check if a particular Pad object exists.
int GetId() const
Get the station Id.
constexpr double kPi
Definition: MathConstants.h:24
bool HasParticleTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if a Particle release time distribution exists (optionally for a given source) ...
Definition: PadSimData.h:60
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: CDetector.cc:192
double GetInterval() const
Get the time interval as a double (in Auger base units)
Definition: TimeInterval.h:69
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
void MakeSimData()
Make Pad simulated data object.
Definition: Pad.cc:39
class to hold data at Station level
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
double GetWeight() const
Particle weight (assigned by shower generator thinning algorithms)
Definition: Particle.h:126
ParticleIterator ParticlesBegin()
Beginning of simulated particles entering the station.
StationIterator StationsBegin()
Beginning of all stations.
Definition: CEvent.h:64
Vector object.
Definition: Vector.h:30
int GetType() const
Definition: Particle.h:101
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
const Point & GetPosition() const
Position of the particle.
Definition: Particle.h:110
PadSimData & GetSimData()
Get object containing Pad simulated data.
Definition: Pad.h:41
void MakeParticleTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Create a Particle release time distribution (optionally for given source)
Definition: PadSimData.cc:14
bool HasCEvent() const
boost::indirect_iterator< InternalStationIterator, Station & > StationIterator
Iterator over all stations.
Definition: CEvent.h:59
void MakePad(const unsigned int padId)
Make a Pad by Id.
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
constexpr double coulomb
Definition: AugerUnits.h:169
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const Vector & GetDirection() const
Unit vector giving particle direction.
Definition: Particle.h:114
void AddTime(const double time, const T weight=T(1))
Add an entry (optionally weighted) for the given time. Slot will be computed.
ParticleIterator ParticlesEnd()
End of simulated particles entering the station.
StationSimData & GetSimData()
Get simulated data at station level.
void MakeChargeTimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Create a TimeDistributionD representing signal at Pad (optionally for a give source) ...
Definition: PadSimData.cc:21
Interface class to access to the SD part of an event.
Definition: CEvent.h:46
bool HasSimData() const
Check for existence of Pad simulated data object.
Definition: Pad.h:48

, generated on Tue Sep 26 2023.