12 #include <utl/config.h>
19 #include <fwk/CentralConfig.h>
20 #include <fwk/CoordinateSystemRegistry.h>
21 #include <fwk/RandomEngineRegistry.h>
23 #include <evt/Event.h>
24 #include <evt/ShowerSimData.h>
26 #include <sevt/SEvent.h>
27 #include <sevt/Station.h>
28 #include <sevt/StationSimData.h>
30 #include <det/Detector.h>
31 #include <sdet/SDetector.h>
32 #include <sdet/Station.h>
34 #include <utl/ErrorLogger.h>
35 #include <utl/GeometryUtilities.h>
36 #include <utl/MathConstants.h>
37 #include <utl/Particle.h>
38 #include <utl/PhysicalConstants.h>
39 #include <utl/Point.h>
40 #include <utl/RandomEngine.h>
41 #include <utl/TimeStamp.h>
43 #include <utl/Reader.h>
44 #include <utl/TabularStream.h>
45 #include <utl/TabulatedFunction.h>
47 #include <CLHEP/Random/RandFlat.h>
48 #include <CLHEP/Random/RandPoisson.h>
49 #include <CLHEP/Random/RandGauss.h>
54 using namespace CachedShowerRegeneratorASCII;
61 using CLHEP::RandFlat;
62 using CLHEP::RandPoisson;
65 #define PHOTONS utl::Particle::ePhoton
66 #define ELECTRONS utl::Particle::eElectron: \
67 case utl::Particle::ePositron
68 #define MUONS utl::Particle::eMuon: \
69 case utl::Particle::eAntiMuon
70 #define BARYONS utl::Particle::eProton: \
71 case utl::Particle::eAntiProton: \
72 case utl::Particle::eNeutron: \
73 case utl::Particle::eAntiNeutron: \
74 case utl::Particle::eLambda: \
75 case utl::Particle::eAntiLambda
76 #define MESONS utl::Particle::ePiZero: \
77 case utl::Particle::ePiPlus: \
78 case utl::Particle::ePiMinus: \
79 case utl::Particle::eEta: \
80 case utl::Particle::eKaon0L: \
81 case utl::Particle::eKaon0S: \
82 case utl::Particle::eKaonPlus: \
83 case utl::Particle::eKaonMinus
86 namespace CachedShowerRegeneratorASCII {
88 template<
typename Map,
typename T>
93 const typename Map::iterator sIt = map.find(sId);
97 map.insert(make_pair(sId,
typename Map::mapped_type(value)));
102 Round(
const double div,
const double val)
104 return round(div*val)/div;
116 const Point& position)
125 fMaxParticles(numeric_limits<unsigned int>::
max()),
127 fOuterRadiusCut(1.e6*
km),
128 fElectronEnergyCut(0),
135 fHorizontalParticleCut(0),
136 fUseStationPositionMatrix(true),
141 fUseWeightLimiting(false),
143 fAccumulatedWeightLimit(0),
146 fTimeSlotSize(1.*
ns),
147 fNOutOfRangeWeight(0),
161 CentralConfig::GetInstance()->
GetTopBranch(
"CachedShowerRegeneratorASCII");
167 useAtt[
"use"] = string(
"yes");
199 Branch limitSwitchB = topB.
GetChild(
"ResamplingWeightLimiting", useAtt);
206 if (topB.
GetChild(
"MuonWeightScale"))
209 fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
212 WARNING(
"Not using StationPositionMatrix. "
213 "All stations will be searched for injection.");
221 const double pEnergy)
265 const double showerZenith = simShower.GetZenith();
266 const double samplingAreaFactor =
271 SEvent& sEvent =
event.GetSEvent();
276 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
287 const int sId = sdIt->GetId();
301 const Point& sPosition = sdIt->GetPosition();
307 const double sR = sPosition.
GetRho(showerCS);
329 const double samplingArea = samplingAreaFactor *
Sqr(sR);
335 fShowerData->fStationMatrix.PushBack(*sdIt, station,
346 info <<
"Out of " << nStations <<
" stations: inner cut " << nInner <<
", outer " << nOuter;
355 ERROR(
"Current event does not have a simulated shower.");
373 info <<
"Cached Shower Regenerator ASCII : Regenerating batch of "
378 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
379 SEvent& sEvent =
event.GetSEvent();
384 sEvent.
GetStation(sdIt->GetId()).GetSimData().ClearParticleList();
397 unsigned int nParticlesInjected = 0;
401 for (; particleIt !=
fShowerData->fParticlesEnd; ++particleIt) {
406 info << nParticlesInjected <<
" particles processed.";
412 const double pR2ShowerFrame = pPosition.
GetRho2(showerCS);
423 double pPlaneFrontDelay = pTime -
PlaneFrontTime(showerCS, corePosition, pPosition);
424 if (pPlaneFrontDelay < -0.1*
ns )
427 if (pR2ShowerFrame <= fShowerData->fMinR2)
430 const double pLogR2ShowerFrame = log(pR2ShowerFrame);
432 const double pPhiShowerFrame = pPosition.
GetPhi(showerCS);
435 fShowerData->fStationMatrix.GetStationList(pPhiShowerFrame, pLogR2ShowerFrame);
443 for (StationPositionMatrix::StationInfoPtrList::const_iterator sIt = sList.begin();
444 sIt != sList.end(); ++sIt) {
448 if (!sInfo.
IsIn(pPhiShowerFrame, pLogR2ShowerFrame))
451 const double pWeight =
472 const double sRadius = dStation.
GetRadius() + sThickness;
480 const unsigned int sId = dStation.
GetId();
483 const double pStationCosine = pDirection.
GetZ(dStationCS);
484 const double pPlaneCosine = pDirection.
GetZ(grParticleCS);
485 const double pPlaneAbsCosine =
abs(pPlaneCosine);
498 const double effArea =
kPi*
Sqr(sRadius) * pStationCosine/pPlaneCosine;
500 const double avgN = pWeightDensity * effArea;
515 if (
int(weight) == 1)
532 for (
unsigned int i = 0; i < n; ++i) {
548 double pShiftedTime =
551 const double planeFrontTime =
554 fShowerData->fLogGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
556 newParticle.
SetTime(pShiftedTime);
565 nParticlesInjected += n;
571 const double pStationSine = pDirection.
GetRho(dStationCS);
579 else if (pStationSine) {
582 const double effArea = 2*sRadius*sHeight * pStationSine/pPlaneAbsCosine;
583 const double avgN = pWeightDensity * effArea;
613 for (
unsigned int i = 0; i < n; ++i) {
619 const double phi = pPhi + acos(RandFlat::shoot(
fRandomEngine, -1, 1));
620 const double z = RandFlat::shoot(
fRandomEngine, -sThickness, sHeight);
625 double pShiftedTime =
628 const double planeFrontTime =
631 fShowerData->fLogGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
633 newParticle.
SetTime(pShiftedTime);
640 nParticlesInjected += n;
641 if (pStationCosine >= 0)
648 info << nParticlesInjected <<
" particles processed.";
667 INFO(
"\nStation particle statistics:");
676 for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
677 sIt != sList.end(); ++sIt) {
679 const unsigned sId = sIt->GetDetStation().GetId();
685 ShowerData::WeightStatMap::const_iterator wIt =
fShowerData->fWeightStat.find(sId);
687 tab << sId <<
' ' <<
endc
688 << setprecision(4) << sIt->GetR()/
km <<
endc
692 <<
' ' << setprecision(4) << wIt->second.GetMin() <<
endc
693 <<
' ' << setprecision(4) << wIt->second.GetAverage() <<
endc
694 <<
' ' << setprecision(4) << wIt->second.GetMax() <<
endr;
705 cerr <<
"No stations were hit." << endl;
709 INFO(
"\nStation timing statistics:\n"
710 "abs = absolute time difference to core time\n"
711 "rel = relative time to station plane-front arrival");
714 <<
"min rel" <<
endc <<
"max rel" <<
endr
716 <<
"station" <<
endc <<
"[km]" <<
endc <<
"time [ns]" <<
endc <<
"time [ns]" <<
endc
722 for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
723 sIt != sList.end(); ++sIt) {
725 const unsigned sId = sIt->GetDetStation().GetId();
732 sIt->GetEvtStation().GetSimData().GetPlaneFrontTime() - coreTime;
735 ShowerData::TimeStatMap::const_iterator mmIt =
fShowerData->fTimeStat.find(sId);
736 tab << sId <<
' ' <<
endc
737 << setprecision(4) << sIt->GetR()/
km <<
endc
738 <<
' ' <<
Round(10, mmIt->second.GetMin().GetInterval()/
ns) <<
endc
739 <<
' ' <<
Round(10, mmIt->second.GetMax().GetInterval()/
ns) <<
endc
740 <<
' ' <<
Round(10, (mmIt->second.GetMin() - sTime).GetInterval()/
ns) <<
endc
741 <<
' ' <<
Round(10, (mmIt->second.GetMax() - sTime).GetInterval()/
ns) <<
endr;
755 info <<
fShowerData->fNHorizontalParticles <<
" horizontal particles rejected.";
767 "weighted particle(s) resulted in generation of unity-weight particles exceeding "
783 boost::tuple<unsigned int, double>
815 return boost::make_tuple(n, weight);
void SetTime(const TimeInterval &time)
Branch GetTopBranch() const
CachedShowerRegenerator()
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
Iterator to retrieve particles from utl::VShowerParticlList.
Station Level Simulated Data
unsigned int fNOutOfRangeWeight
constexpr T Sqr(const T &x)
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
bool HasStation(const int stationId) const
Check whether station exists.
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
utl::ShowerParticleIterator GroundParticlesEnd() const
const TimeInterval & GetTime() const
Arrival time delay at the ground.
Detector description interface for Station-related data.
double GetResamplingArea() const
Report success to RunController.
void OutputStats(evt::Event &event)
double GetMinRadiusCut() const
Get the minimum radius from shower axis for which there are valid particles in the shower...
void MakeSimData()
Make station simulated data object.
boost::tuple< unsigned int, double > ParticleNumberAndWeight(const double &, const int &)
(Optional) special handling for particles with very large weights.
void SetPosition(const utl::Point &position)
Interface class to access to the SD part of an event.
Describes a particle for Simulation.
bool HasSimShower() const
std::map< std::string, std::string > AttributeMap
bool IsParticleEnergyLow(const int, const double) const
double fElectronEnergyCut
VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
#define INFO(message)
Macro for logging informational messages.
bool IsIn(const double phi, const double r) const
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
utl::RandomEngine::RandomEngineType * fRandomEngine
unsigned int fMaxParticles
double fLogGaussSmearingWidth
double fAccumulatedWeightLimit
A TimeStamp holds GPS second and nanosecond for some event.
Interface class to access Shower Simulated parameters.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Break current loop. It works for nested loops too!
class to hold data at Station level
bool HasSimData() const
Check whether station simulated data exists.
static const CCylindrical kCylindrical
bool fUseStationPositionMatrix
double abs(const SVector< n, T > &v)
const utl::Point & GetPosition() const
Get the position of the shower core.
StationIterator StationsEnd() const
End of the collection of pointers to commissioned stations.
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger reference system centered on the tank.
double GetRadius() const
Radius of the tank (water only)
constexpr double kPiOnTwo
void SetWeight(const double weight)
double Round(const double div, const double val)
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
void SetPlaneFrontTime(const utl::TimeStamp &time)
Set shower front plane arrival time.
class to format data in tabular form
void MakeStation(const int stationId)
make a station with specifying Id, throw if invalid stationId
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
sevt::Station & GetEvtStation() const
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
double GetInterval() const
Get the time interval as a double (in Auger base units)
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
double GetKineticEnergy() const
Get kinetic energy of the particle.
vector< StationInfo > StationInfoList
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
double GetWeight() const
Particle weight (assigned by shower generator thinning algorithms)
vector< const StationInfo * > StationInfoPtrList
const sdet::Station & GetDetStation() const
void InitNewShower(evt::Event &event)
double GetThickness() const
Thickness of the tank walls.
Source GetSource() const
Source of the particle (eg. shower or background)
double PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point &corePosition, const Point &position)
Calculate time of arrival of the plan front at point x.
void SetMinRadiusCut(const double minR)
Set the minimum radius cut.
double GetRho2(const CoordinateSystemPtr &coordinateSystem) const
radius r^2 in cylindrical coordinates (distance to z axis)^2
Detector description interface for SDetector-related data.
const Point & GetPosition() const
Position of the particle.
Report failure to RunController, causing RunController to terminate execution.
void SetMuonWeightScale(const double scale)
Set the muon weight scale.
sevt::StationSimData & GetSimData()
Get simulated data at station level.
VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void AddParticle(const utl::Particle &particle)
double fHorizontalParticleCut
void SetIsInsideMinRadius(const bool isIn=true)
Set flag indicating whether station is in the shower hole.
void InsertValue(Map &map, const int sId, const T &value)
int GetId() const
Station ID.
#define ERROR(message)
Macro for logging error messages.
const Vector & GetDirection() const
Unit vector giving particle direction.
utl::ShowerParticleIterator GroundParticlesBegin() const
utl::ShadowPtr< ShowerData > fShowerData
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const