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/ParticleCases.h>
39 #include <utl/PhysicalConstants.h>
40 #include <utl/Point.h>
41 #include <utl/RandomEngine.h>
42 #include <utl/TimeStamp.h>
44 #include <utl/Reader.h>
45 #include <utl/TabularStream.h>
46 #include <utl/TabulatedFunction.h>
48 #include <CLHEP/Random/RandFlat.h>
49 #include <CLHEP/Random/RandPoisson.h>
50 #include <CLHEP/Random/RandGauss.h>
55 using namespace CachedXShowerRegeneratorAG;
62 using CLHEP::RandFlat;
63 using CLHEP::RandPoisson;
65 namespace CachedXShowerRegeneratorAG {
67 template<
typename Map,
typename T>
72 const typename Map::iterator sIt = map.find(sId);
76 map.insert(make_pair(sId,
typename Map::mapped_type(value)));
81 Round(
const double div,
const double val)
83 return round(div*val)/div;
95 const Point& position)
104 fMaxParticles(numeric_limits<unsigned int>::
max()),
106 fOuterRadiusCut(1.e6*
km),
107 fElectronEnergyCut(0),
114 fHorizontalParticleCut(0),
115 fUseStationPositionMatrix(true),
120 fUseWeightLimiting(false),
122 fAccumulatedWeightLimit(0),
125 fTimeSlotSize(1.*
ns),
126 fNOutOfRangeWeight(0),
128 fSimulateAmiga(false)
141 CentralConfig::GetInstance()->
GetTopBranch(
"CachedXShowerRegenerator");
144 useAtt[
"use"] = string(
"yes");
176 Branch limitSwitchB = topB.
GetChild(
"ResamplingWeightLimiting", useAtt);
183 if (topB.
GetChild(
"MuonWeightScale"))
188 INFO(
"AMIGA tank+ground G4 simulation has been activated" );
193 fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector).GetEngine();
196 WARNING(
"Not using StationPositionMatrix. "
197 "All stations will be searched for injection.");
205 const double pEnergy)
250 const double showerZenith = (-simShower.
GetDirection()).GetTheta(localCS);
255 SEvent& sEvent =
event.GetSEvent();
260 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
271 const int sId = sdIt->GetId();
286 const Point& sPosition = sdIt->GetPosition();
293 const double sR = sPosition.
GetRho(showerCS);
315 const double samplingArea = samplingAreaFactor *
Sqr(sR);
322 fShowerData->fStationMatrix.PushBack(*sdIt, station,
333 info <<
"Out of " << nStations <<
" stations: inner cut " << nInner <<
", outer " << nOuter;
341 INFO(
"Starting G4XTank simulation...");
344 ERROR(
"Current event does not have a simulated shower.");
362 info <<
"Regenerating batch of "
367 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
368 SEvent& sEvent =
event.GetSEvent();
373 sEvent.
GetStation(sdIt->GetId()).GetSimData().ClearParticleList();
386 unsigned int nParticlesInjected = 0;
390 for (; particleIt !=
fShowerData->fParticlesEnd; ++particleIt) {
395 info << nParticlesInjected <<
" particles processed.";
401 const double pR2ShowerFrame = pPosition.
GetRho2(showerCS);
412 double pPlaneFrontDelay = pTime -
PlaneFrontTime(showerCS, corePosition, pPosition);
413 if (pPlaneFrontDelay < -0.1*
ns )
416 if (pR2ShowerFrame <= fShowerData->fMinR2)
419 const double pLogR2ShowerFrame = log(pR2ShowerFrame);
421 const double pPhiShowerFrame = pPosition.
GetPhi(showerCS);
424 fShowerData->fStationMatrix.GetStationList(pPhiShowerFrame, pLogR2ShowerFrame);
432 for (StationPositionMatrix::StationInfoPtrList::const_iterator sIt = sList.begin();
433 sIt != sList.end(); ++sIt) {
437 if (!sInfo.
IsIn(pPhiShowerFrame, pLogR2ShowerFrame))
440 const double pWeight =
463 const double sRadius = dStation.
GetRadius() + sThickness;
464 const double sHeight = dStation.
GetHeight() + sThickness;
469 const unsigned int sId = dStation.
GetId();
472 const double pStationCosine = pDirection.
GetZ(dStationCS);
473 const double pPlaneCosine = pDirection.
GetZ(grParticleCS);
474 const double pPlaneAbsCosine =
abs(pPlaneCosine);
486 const double avgN = pWeightDensity * effArea;
496 if (
int(weight) == 1)
508 for (
unsigned int i = 0; i < n; ++i) {
524 double pShiftedTime =
528 const double planeFrontTime =
531 fShowerData->fLogXGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
534 newParticle.
SetTime(pShiftedTime);
543 nParticlesInjected += n;
552 const double pStationSine = pDirection.
GetRho(dStationCS);
558 }
else if (pStationSine) {
561 const double effArea = 2*sRadius*sHeight * pStationSine/pPlaneAbsCosine;
562 const double avgN = pWeightDensity * effArea;
578 for (
unsigned int i = 0; i < n; ++i) {
584 const double phi = pPhi + acos(RandFlat::shoot(
fRandomEngine, -1, 1));
585 const double z = RandFlat::shoot(
fRandomEngine, -sThickness, sHeight);
590 double pShiftedTime =
593 const double planeFrontTime =
596 fShowerData->fLogXGauss->GetSmearedTime(planeFrontTime, pShiftedTime);
598 newParticle.
SetTime(pShiftedTime);
605 nParticlesInjected += n;
606 if (pStationCosine >= 0)
614 info << nParticlesInjected <<
" particles processed.";
633 INFO(
"\nStation particle statistics:");
642 for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
643 sIt != sList.end(); ++sIt) {
645 const unsigned sId = sIt->GetDetStation().GetId();
651 ShowerData::WeightStatMap::const_iterator wIt =
fShowerData->fWeightStat.find(sId);
653 tab << sId <<
' ' <<
endc
654 << setprecision(4) << sIt->GetR()/
km <<
endc
658 <<
' ' << setprecision(4) << wIt->second.GetMin() <<
endc
659 <<
' ' << setprecision(4) << wIt->second.GetAverage() <<
endc
660 <<
' ' << setprecision(4) << wIt->second.GetMax() <<
endr;
671 cerr <<
"No stations were hit." << endl;
675 INFO(
"\nStation timing statistics:\n"
676 "abs = absolute time difference to core time\n"
677 "rel = relative time to station plane-front arrival");
680 <<
"min rel" <<
endc <<
"max rel" <<
endr
682 <<
"station" <<
endc <<
"[km]" <<
endc <<
"time [ns]" <<
endc <<
"time [ns]" <<
endc
688 for (StationPositionMatrix::StationInfoList::const_iterator sIt = sList.begin();
689 sIt != sList.end(); ++sIt) {
691 const unsigned sId = sIt->GetDetStation().GetId();
698 sIt->GetEvtStation().GetSimData().GetPlaneFrontTime() - coreTime;
701 ShowerData::TimeStatMap::const_iterator mmIt =
fShowerData->fTimeStat.find(sId);
702 tab << sId <<
' ' <<
endc
703 << setprecision(4) << sIt->GetR()/
km <<
endc
704 <<
' ' <<
Round(10, mmIt->second.GetMin().GetInterval()/
ns) <<
endc
705 <<
' ' <<
Round(10, mmIt->second.GetMax().GetInterval()/
ns) <<
endc
706 <<
' ' <<
Round(10, (mmIt->second.GetMin() - sTime).GetInterval()/
ns) <<
endc
707 <<
' ' <<
Round(10, (mmIt->second.GetMax() - sTime).GetInterval()/
ns) <<
endr;
721 info << endl <<
fShowerData->fNHorizontalParticles <<
" horizontal particles rejected.";
733 "weighted particle(s) resulted in generation of unity-weight particles exceeding "
749 boost::tuple<unsigned int, double>
781 return boost::make_tuple(n, weight);
void SetTime(const TimeInterval &time)
Branch GetTopBranch() const
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
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.
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.
bool IsIn(const double phi, const double r) const
void SetPosition(const utl::Point &position)
sevt::Station & GetEvtStation() const
double fAccumulatedWeightLimit
Interface class to access to the SD part of an event.
Describes a particle for Simulation.
bool HasSimShower() const
boost::tuple< unsigned int, double > ParticleNumberAndWeight(const double &, const int &)
(Optional) special handling for particles with very large weights.
std::map< std::string, std::string > AttributeMap
#define INFO(message)
Macro for logging informational messages.
void InsertValue(Map &map, const int sId, const T &value)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
unsigned int fMaxParticles
VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
double GetResamplingArea() const
double fHorizontalParticleCut
bool IsParticleEnergyLow(const int, const double) const
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.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
static const CCylindrical kCylindrical
double abs(const SVector< n, T > &v)
const utl::Point & GetPosition() const
Get the position of the shower core.
VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
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
double GetHeight() const
Height of the tank (water only)
void SetWeight(const double weight)
StationIterator StationsBegin() const
Beginning of the collection of pointers to commissioned stations.
double Round(const double div, const double val)
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
void AddParticle(const utl::Particle &particle)
const sdet::Station & GetDetStation() const
#define WARNING(message)
Macro for logging warning messages.
double fElectronEnergyCut
void GetData(bool &b) const
Overloads of the GetData member template function.
double PlaneFrontTime(const CoordinateSystemPtr showerCS, const Point &corePosition, const Point &position)
Calculate time of arrival of the plan front at point x.
vector< StationInfo > StationInfoList
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.
unsigned int fNOutOfRangeWeight
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
double GetThickness() const
Thickness of the tank walls.
Source GetSource() const
Source of the particle (eg. shower or background)
VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
void SetMinRadiusCut(const double minR)
Set the minimum radius cut.
utl::ShadowPtr< ShowerData > fShowerData
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 InitNewShower(evt::Event &event)
#define OFFLINE_ELECTRONS
void SetMuonWeightScale(const double scale)
Set the muon weight scale.
sevt::StationSimData & GetSimData()
Get simulated data at station level.
void SetParent(Particle &parent)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void SetIsInsideMinRadius(const bool isIn=true)
Set flag indicating whether station is in the shower hole.
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::RandomEngine::RandomEngineType * fRandomEngine
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
bool fUseStationPositionMatrix
CachedXShowerRegenerator()
double fLogXGaussSmearingWidth