CachedDirectInjector.cc
Go to the documentation of this file.
1 #include <utl/config.h>
2 
3 #include <cmath>
4 #include <sstream>
5 #include <vector>
6 #include <fstream>
7 
8 #include <fwk/CentralConfig.h>
9 #include <fwk/RunController.h>
10 #include <fwk/CoordinateSystemRegistry.h>
11 #include <io/CorsikaUtilities.h>
12 
13 #include <evt/Event.h>
14 #include <evt/ShowerSimData.h>
15 
16 #include <sevt/SEvent.h>
17 #include <sevt/Station.h>
18 #include <sevt/StationSimData.h>
19 
20 #include <det/Detector.h>
21 
22 #include <sdet/SDetector.h>
23 #include <sdet/Station.h>
24 
25 #include <utl/AugerUnits.h>
26 #include <utl/ErrorLogger.h>
27 #include <utl/GeometryUtilities.h>
28 #include <utl/MathConstants.h>
29 #include <utl/Particle.h>
30 #include <utl/PhysicalConstants.h>
31 #include <utl/Point.h>
32 #include <utl/TimeStamp.h>
33 #include <utl/Math.h>
34 #include <utl/Reader.h>
35 #include <utl/TabularStream.h>
36 #include <utl/NucleusProperties.h>
37 
38 #include "CachedDirectInjector.h"
39 
40 using namespace CachedDirectInjectorOG;
41 using namespace fwk;
42 using namespace evt;
43 using namespace sevt;
44 using namespace utl;
45 using namespace std;
46 
47 
48 namespace CachedDirectInjectorOG {
49 
50  istream&
52  {
53  string ppp;
54  return
55  is >> ws >> ppp
56  >> ws >> p.fId
57  >> ws >> p.fR
58  >> ws >> p.fPhi
59  >> ws >> p.fHeight
60  >> ws >> p.fSTime
61  >> ws >> p.fType
62  >> ws >> p.fSource
63  >> ws >> p.fPosX >> ws >> p.fPosY >> ws >> p.fPosZ
64  >> ws >> p.fDirX >> ws >> p.fDirY >> ws >> p.fDirZ
65  >> ws >> p.fTime
66  >> ws >> p.fWeight
67  >> ws >> p.fEk
68  >> ws;
69  }
70 
71  inline
72  double
73  PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point& corePosition,
74  const Point& position)
75  {
76  return (corePosition.GetZ(showerCS) - position.GetZ(showerCS)) / kSpeedOfLight;
77  }
78 
79  inline
80  double
81  Round(const double div, const double val)
82  {
83  return round(div*val)/div;
84  }
85 
86 
89  {
90  Branch topB = CentralConfig::GetInstance()->GetTopBranch("CachedDirectInjector");
91 
92  AttributeMap useAtt;
93  useAtt["use"] = string("yes");
94 
95  if (topB) {
96 
97  //Check for file with additional particles to be injected
98  Branch partTrackB = topB.GetChild("ParticleInjectionFile", useAtt);
99  if (partTrackB) {
100  const string filename = partTrackB.Get<string>();
101  ifstream file(filename);
102  if (!file.is_open()) {
103  ERROR("Could not open particle-injection file.");
104  return eFailure;
105  } else {
106  ostringstream info;
107  info << "Successfully opened particle injection file " << filename;
108  INFO(info);
109 
110  string line;
111  while (getline(file, line)) {
112  const InjectedParticle particle = boost::lexical_cast<InjectedParticle>(line);
113  fTankToInjectedParticles[particle.fId].push_back(particle);
114  }
115  }
116  }
117 
118  //Check for particle-tank distance and other option
119  Branch particleTankDistB = topB.GetChild("ParticleTankDistanceCut");
120  if (particleTankDistB)
121  particleTankDistB.GetData(fParticleTankDistanceCut);
122  Branch maxPart = topB.GetChild("MaxNumberOfParticles");
123  if (maxPart)
124  maxPart.GetData(fMaxParticles);
125 
126  //Check for dense stations option
127  Branch denseStations = topB.GetChild("UseDenseStations");
128  if (denseStations)
129  denseStations.GetData(fUseDense);
130  if(fUseDense){
131  Branch denseStationsOnly = topB.GetChild("UseDenseStationsOnly");
132  if (denseStationsOnly)
133  denseStationsOnly.GetData(fUseDenseOnly);
134  }
135 
136  }
137  else{
138  ERROR("Cannot find XML scheme for direct injection.");
139  return eFailure;
140  }
141 
142  return eSuccess;
143  }
144 
145 
148  {
149 
150  ostringstream info;
151 
152  if (!event.HasSimShower()) {
153  ERROR("Current event does not have a simulated shower.");
154  return eFailure;
155  }
156 
157  const ShowerSimData& simShower = event.GetSimShower();
158  const CoordinateSystemPtr showerCS = simShower.GetShowerCoordinateSystem();
159  const Point& corePosition = simShower.GetPosition();
160  const TimeStamp& coreTime = simShower.GetTimeStamp();
161 
162  if (!event.HasSEvent())
163  event.MakeSEvent();
164  SEvent& sEvent = event.GetSEvent();
165 
166  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
167 
168  vector<const sdet::Station*> dStationVec;
169  vector<sevt::Station*> stationVec;
170 
171  vector<double> sRShowerFrameVec;
172  vector<double> sPhiShowerFrameVec;
173 
174  for (sdet::SDetector::StationIterator sdIt = sDetector.StationsBegin();
175  sdIt != sDetector.StationsEnd(); ++sdIt) {
176 
177  const sdet::Station& dStation = *sdIt;
178  const int sId = dStation.GetId();
179  const CoordinateSystemPtr dStationCS = dStation.GetLocalCoordinateSystem();
180 
181  if (!fUseDense && dStation.IsDense())
182  continue; // only NOT dense stations
183 
184  if (fUseDenseOnly && !dStation.IsDense())
185  continue; // only dense stations
186 
187  if (!sEvent.HasStation(sId))
188  sEvent.MakeStation(sId);
189 
190  Station& station = sEvent.GetStation(sId);
191 
192  if (!station.HasSimData())
193  station.MakeSimData();
194  StationSimData& sSim = station.GetSimData();
195 
196  if (station.HasScintillator() && !station.GetScintillator().HasSimData())
197  station.GetScintillator().MakeSimData();
198 
199  sSim.ClearParticleList();
200 
201  const Point sPos = sdIt->GetPosition();
202  const double sR = sPos.GetRho(showerCS);
203 
204  const TimeStamp planeTime =
205  coreTime + TimeInterval(PlaneFrontTime(showerCS, corePosition, sPos));
206  sSim.SetPlaneFrontTime(planeTime);
207 
208  dStationVec.push_back(&dStation);
209  stationVec.push_back(&station);
210  sRShowerFrameVec.push_back(sR);
211  sPhiShowerFrameVec.push_back(sPos.GetPhi(showerCS));
212 
213  // let's inject some dummies, so we can, for example, force a trigger
214  // in the not dense stantions ...
215  if (!dStation.IsDense() && fTankToInjectedParticles.size()) {
216  if (fTankToInjectedParticles.count(sId)) {
217  for (const InjectedParticle& p : fTankToInjectedParticles[sId]) {
218  const Vector myDir(p.fDirX, p.fDirY, p.fDirZ, dStationCS);
219  const Point pShiftedPosition(p.fR, p.fPhi, p.fHeight, dStationCS, Point::kCylindrical);
220  const Particle myParticle(p.fType, (utl::Particle::Source)p.fSource,
221  pShiftedPosition, myDir, p.fSTime, p.fWeight, p.fEk);
222  station.AddParticle(myParticle);
223  }
224  }
225  }
226  }
227 
228  const unsigned int nStations = dStationVec.size();
229  fEarliestTime.clear();
230 
231  unsigned int nParticles = 0;
232  unsigned int nParticlesInjected = 0;
233 
234  for (fParticleIt = simShower.GroundParticlesBegin();
235  fParticleIt != simShower.GroundParticlesEnd(); ++fParticleIt) {
236 
237  //if (nParticles % 1000 == 0)
238  //std::cout << "Particles : " << nParticles << '\r';
239 
240  const Point pPosition = fParticleIt->GetPosition();
241  const double pRShowerFrame = pPosition.GetRho(showerCS);
242  const double pPhiShowerFrame = pPosition.GetPhi(showerCS);
243  const double pTime = fParticleIt->GetTime().GetInterval();
244 
245  // do not inject unknown particles
246  const int particleType = io::Corsika::CorsikaToPDG(fParticleIt->GetType());
247  if (particleType == utl::Particle::eUndefined)
248  continue;
249 
250  // Check particle time relative to the shower front
251  // (see CachedShowerGenerator.cc for explanation)
252  const double pPlaneFrontDelay =
253  pTime - PlaneFrontTime(showerCS, corePosition, pPosition);
254  if (pPlaneFrontDelay < -0.1*ns)
255  continue;
256 
257  for (unsigned int si = 0; si < nStations; ++si) {
258 
259  const sdet::Station& dStation = *dStationVec[si];
260  Station& station = *stationVec[si];
261  const unsigned int sId = dStation.GetId();
262  const CoordinateSystemPtr dStationCS = dStation.GetLocalCoordinateSystem();
263 
264  // Check if particle is nearer than chosen distance
265  const double dPhi = NormalizeAngleMinusPiPi(pPhiShowerFrame - sPhiShowerFrameVec[si]);
266  if (std::abs(sRShowerFrameVec[si] - pRShowerFrame) > fParticleTankDistanceCut ||
267  std::abs(dPhi)*sRShowerFrameVec[si] > fParticleTankDistanceCut)
268  continue;
269 
270  TimeInterval& earliestTime = fEarliestTime[sId];
271  if (earliestTime.GetInterval() < numeric_limits<double>::min())
272  earliestTime = TimeInterval::Max();
273 
274  // Is particle already inside station ?
275  if (dStation.IsInsideStation(fParticleIt->GetPosition()))
276  continue;
277 
278  bool particleHit = false;
279 
280  if (dStation.HasScintillator())
281  particleHit = dStation.GetScintillator().IsHit(fParticleIt->GetPosition(),
282  fParticleIt->GetDirection());
283  if (!particleHit)
284  particleHit = dStation.IsHit(fParticleIt->GetPosition(),
285  fParticleIt->GetDirection());
286 
287  if (particleHit) {
288 
289  Particle newParticle(*fParticleIt);
290 
291  const double sThickness = dStation.GetThickness();
292  const double sHeight = dStation.GetHeight() + 2*sThickness;
293  double injectionHeight = sHeight;
294  if (dStation.HasScintillator()) {
295  const double scintHeight = dStation.GetScintillator().GetMaxHeight();
296  injectionHeight = max(injectionHeight, scintHeight);
297  }
298  const Line particleLine(fParticleIt->GetPosition(), fParticleIt->GetDirection());
299  const Plane topPlane(Point(0, 0, injectionHeight*utl::meter, dStationCS),
300  Vector(0, 0, 1, dStationCS));
301  Point hitPoint = Intersection(topPlane, particleLine);
302  const double timeShift =
303  pTime + (fParticleIt->GetPosition() - hitPoint).GetMag() / kSpeedOfLight;
304 
305  newParticle.SetPosition(hitPoint);
306  newParticle.SetTime(timeShift);
307 
308  if (timeShift < earliestTime)
309  earliestTime = timeShift;
310 
311  station.AddParticle(newParticle);
312  ++nParticlesInjected;
313 
314  info.str("");
315  info << "\nInjecting particle with ";
316  info << "energy = " << newParticle.GetKineticEnergy()/utl::GeV << " GeV ";
317  info << "at time = " << newParticle.GetTime()/utl::ns << " ns \n";
318  info << "in (x,y,z) = (" << newParticle.GetPosition().GetX(dStationCS)/utl::meter << ", "
319  << newParticle.GetPosition().GetY(dStationCS)/utl::meter << ", "
320  << newParticle.GetPosition().GetZ(dStationCS)/utl::meter << ") m\n";
321  //INFO(info);
322 
323  } // if particle hits a detector
324 
325  } // end cycle over stations
326 
327  if (nParticlesInjected >= fMaxParticles) {
328  info.str("");
329  info << "Reached max number of " << nParticlesInjected << " injected particles.";
330  INFO(info);
331  return eSuccess;
332  }
333 
334  ++nParticles;
335  }
336 
337  info.str("");
338  info << nParticlesInjected << " particles injected over "
339  << nParticles << " particles processed.";
340  INFO(info);
341 
342  for (unsigned si = 0; si < nStations; ++si) {
343 
344  const unsigned sId = dStationVec[si]->GetId();
345  const TimeStamp newTime = coreTime + fEarliestTime[sId];
346  StationSimData& sSim = stationVec[si]->GetSimData();
347  const TimeStamp sTime = sSim.GetPlaneFrontTime();
348 
349  if (!sTime || newTime < sTime)
350  sSim.SetPlaneFrontTime(newTime);
351 
352  }
353 
354  return eSuccess;
355  }
356 
357 
360  {
361  return eSuccess;
362  }
363 
364 }
void SetTime(const TimeInterval &time)
Definition: Particle.h:123
Branch GetTopBranch() const
Definition: Branch.cc:63
VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
Station Level Simulated Data
double NormalizeAngleMinusPiPi(const double x)
Normalize angle to lie between -pi and pi (-180 and 180 deg)
Point object.
Definition: Point.h:32
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
utl::ShowerParticleIterator GroundParticlesEnd() const
const TimeInterval & GetTime() const
Arrival time delay at the ground.
Definition: Particle.h:122
Detector description interface for Station-related data.
void MakeSimData()
Make station simulated data object.
void SetPosition(const utl::Point &position)
Definition: Particle.h:111
bool IsInsideStation(const utl::Point &pos) const
bool HasSimData() const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
Describes a particle for Simulation.
Definition: Particle.h:26
bool IsHit(const utl::Point &from, const utl::Vector &direction, const double halo=0) const
const utl::TimeStamp & GetPlaneFrontTime() const
Get Shower front plane arrival time.
VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
bool is(const double a, const double b)
Definition: testlib.cc:113
bool HasSimShower() const
std::map< std::string, std::string > AttributeMap
Definition: Branch.h:24
void ClearParticleList()
Clear the station particle list.
#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
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
Line Intersection(const Plane &p1, const Plane &p2)
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
T Get() const
Definition: Branch.h:271
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
bool IsHit(const utl::Point &from, const utl::Vector &direction, utl::Point &where) const
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
double PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point &corePosition, const Point &position)
bool HasSimData() const
Check whether station simulated data exists.
Class describing a Plane object.
Definition: Plane.h:17
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
const double ns
double abs(const SVector< n, T > &v)
const utl::Point & GetPosition() const
Get the position of the shower core.
constexpr double meter
Definition: AugerUnits.h:81
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.
const Scintillator & GetScintillator() const
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 SetPlaneFrontTime(const utl::TimeStamp &time)
Set shower front plane arrival time.
Scintillator & GetScintillator()
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
const string file
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
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Definition: BasicVector.h:263
double GetKineticEnergy() const
Get kinetic energy of the particle.
Definition: Particle.h:130
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
constexpr double kSpeedOfLight
istream & operator>>(istream &is, InjectedParticle &p)
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
int CorsikaToPDG(const int corsikaCode)
converters from CORSIKA to PDG particle codes
double Round(const double div, const double val)
double GetThickness() const
Thickness of the tank walls.
struct particle_info particle[80]
bool IsDense() const
Tells whether the station belongs to set of hypothetical &quot;dense&quot; stations.
bool HasScintillator() const
bool HasScintillator() const
Vector object.
Definition: Vector.h:30
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
const Point & GetPosition() const
Position of the particle.
Definition: Particle.h:110
sevt::StationSimData & GetSimData()
Get simulated data at station level.
constexpr double ns
Definition: AugerUnits.h:162
char * filename
Definition: dump1090.h:266
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
int GetId() const
Station ID.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
utl::ShowerParticleIterator GroundParticlesBegin() const
bool HasSEvent() const
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
Definition: Line.h:17

, generated on Tue Sep 26 2023.