555 const G4Track* aTrack = aStep.GetTrack();
557 G4StepPoint
const* pPreStepPoint = aStep.GetPreStepPoint();
560 const G4DynamicParticle* aParticle = aTrack->GetDynamicParticle();
561 const G4Material* aMaterial = aTrack->GetMaterial();
563 G4int materialIndex = aMaterial->GetIndex();
564 G4int tracknumber = aStep.GetTrack()->GetTrackID();
566 G4ThreeVector x0 = pPreStepPoint->GetPosition();
567 G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
569 G4double
t0 = pPreStepPoint->GetGlobalTime();
571 G4MaterialPropertiesTable* aMaterialPropertiesTable = aMaterial->GetMaterialPropertiesTable();
573 G4MaterialPropertyVector* Fast_Intensity =
574 aMaterialPropertiesTable->GetProperty(
"FASTCOMPONENT");
575 G4MaterialPropertyVector* Slow_Intensity =
576 aMaterialPropertiesTable->GetProperty(
"SLOWCOMPONENT");
578 if (!Fast_Intensity && !Slow_Intensity)
return 1;
586 if (Fast_Intensity && Slow_Intensity) nscnt = 2;
589 double YieldRatio = 0;
596 G4ParticleDefinition* pDef = aParticle->GetDefinition();
603 if (pDef == G4Proton::ProtonDefinition()) {
604 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"PROTONYIELDRATIO");
607 else if (pDef == G4MuonPlus::MuonPlusDefinition() ||
608 pDef == G4MuonMinus::MuonMinusDefinition()) {
609 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"MUONYIELDRATIO");
612 else if (pDef == G4PionPlus::PionPlusDefinition() ||
613 pDef == G4PionMinus::PionMinusDefinition()) {
614 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"PIONYIELDRATIO");
617 else if (pDef == G4KaonPlus::KaonPlusDefinition() ||
618 pDef == G4KaonMinus::KaonMinusDefinition()) {
619 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"KAONYIELDRATIO");
622 else if (pDef == G4Alpha::AlphaDefinition()) {
623 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"ALPHAYIELDRATIO");
627 else if (pDef == G4Electron::ElectronDefinition() || pDef == G4Gamma::GammaDefinition()) {
628 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"ELECTRONYIELDRATIO");
632 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"ELECTRONYIELDRATIO");
637 if (YieldRatio == 0) {
638 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"ELECTRONYIELDRATIO");
681 for (G4int scnt = 1; scnt <= nscnt; scnt++) {
682 G4double ScintillationTime = 0. *
CLHEP::ns;
683 G4double ScintillationRiseTime = 0. *
CLHEP::ns;
684 G4PhysicsOrderedFreeVector* ScintillationIntegral = NULL;
687 if (Fast_Intensity) {
688 ScintillationTime = aMaterialPropertiesTable->GetConstProperty(
"FASTTIMECONSTANT");
690 ScintillationRiseTime =
691 aMaterialPropertiesTable->GetConstProperty(
"FASTSCINTILLATIONRISETIME");
693 ScintillationIntegral =
696 if (Slow_Intensity) {
697 ScintillationTime = aMaterialPropertiesTable->GetConstProperty(
"SLOWTIMECONSTANT");
699 ScintillationRiseTime =
700 aMaterialPropertiesTable->GetConstProperty(
"SLOWSCINTILLATIONRISETIME");
702 ScintillationIntegral =
708 YieldRatio = aMaterialPropertiesTable->GetConstProperty(
"YIELDRATIO");
714 ScintillationTime = aMaterialPropertiesTable->GetConstProperty(
"FASTTIMECONSTANT");
716 ScintillationRiseTime =
717 aMaterialPropertiesTable->GetConstProperty(
"FASTSCINTILLATIONRISETIME");
719 ScintillationIntegral =
725 Num = MeanNumberOfPhotons - Num;
726 ScintillationTime = aMaterialPropertiesTable->GetConstProperty(
"SLOWTIMECONSTANT");
728 ScintillationRiseTime =
729 aMaterialPropertiesTable->GetConstProperty(
"SLOWSCINTILLATIONRISETIME");
731 ScintillationIntegral =
735 if (!ScintillationIntegral)
continue;
750 std::map<size_t, int> DetectedNum;
754 int const DetThis = std::round(G4Poisson(Visibilities[OpDet] * Num));
755 if (DetThis > 0) DetectedNum[OpDet] = DetThis;
763 std::map<size_t, int> ReflDetectedNum;
768 int const ReflDetThis = std::round(G4Poisson(ReflVisibilities[OpDet] * Num));
769 if (ReflDetThis > 0) ReflDetectedNum[OpDet] = ReflDetThis;
777 std::vector<double> arrival_time_dist;
779 for (
size_t Reflected = 0; Reflected <= 1; ++Reflected) {
786 itstart = ReflDetectedNum.begin();
787 itend = ReflDetectedNum.end();
790 itstart = DetectedNum.begin();
791 itend = DetectedNum.end();
793 for (
auto itdetphot = itstart; itdetphot != itend; ++itdetphot) {
794 const size_t OpChannel = itdetphot->first;
795 const int NPhotons = itdetphot->second;
802 double Edeposited = 0;
805 Edeposited = aStep.GetTotalEnergyDeposit();
814 Edeposited = aStep.GetTotalEnergyDeposit();
818 arrival_time_dist.resize(NPhotons);
822 Edeposited = Edeposited / double(NPhotons);
825 for (G4int i = 0; i < NPhotons; ++i) {
827 G4double Time = t0 +
scint_time(aStep, ScintillationTime, ScintillationRiseTime) +
831 tmpOpDetBTRecord.AddScintillationPhotons(thisG4TrackID, Time, 1, xyzPos, Edeposited);
835 fst->AddLitePhoton(OpChannel, static_cast<int>(Time), 1, Reflected);
839 TVector3 PhotonPosition(x0[0], x0[1], x0[2]);
841 float PhotonEnergy = 0;
850 PhotToAdd.
Energy = PhotonEnergy;
851 PhotToAdd.
Time = Time;
855 fst->AddPhoton(OpChannel,
std::move(PhotToAdd), Reflected);
858 fst->AddOpDetBacktrackerRecord(tmpOpDetBTRecord, Reflected);
static constexpr double cm
code to link reconstructed objects back to the MC truth information
Index OpChannel(Index detNum, Index channel)
G4bool scintillationByParticleType
void detectedDirectHits(std::map< size_t, int > &DetectedNum, const double Num, geo::Point_t const &ScintPoint) const
void detectedReflecHits(std::map< size_t, int > &ReflDetectedNum, const double Num, geo::Point_t const &ScintPoint) const
void average_position(G4Step const &aStep, double *xzyPos) const
bool isScintInActiveVolume(geo::Point_t const &ScintPoint)
std::vector< geo::Point_t > fOpDetCenter
double VisibleEnergyDeposit() const
void propagationTime(std::vector< double > &arrival_time_dist, G4ThreeVector x0, const size_t OpChannel, bool Reflected=false)
bool const fOnlyActiveVolume
Whether photon propagation is performed only from active volumes.
All information of a photon entering the sensitive optical detector volume.
bool isOpDetInSameTPC(geo::Point_t const &ScintPoint, geo::Point_t const &OpDetPoint) const
MappedFunctions_t GetTimingTF1(Point const &p) const
void ProcessStep(const G4Step &step)
std::unique_ptr< G4PhysicsTable > theSlowIntegralTable
static constexpr double MeV
G4double scint_time(const G4Step &aStep, G4double ScintillationTime, G4double ScintillationRiseTime) const
Energy deposited on a readout Optical Detector by simulated tracks.
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
bool StoreReflected() const
bool const bPropagate
Whether propagation of photons is enabled.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
bool usesSemiAnalyticModel() const
Returns whether the semi-analytic visibility parametrization is being used.
MappedT0s_t GetReflT0s(Point const &p) const
static constexpr double eV
static IonizationAndScintillation * Instance()
bool FillSimEnergyDeposits() const
MappedCounts_t GetAllVisibilities(Point const &p, bool wantReflected=false) const
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
static OpDetPhotonTable * Instance(bool LitePhotons=false)
A container for photon visibility mapping data.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
bool SetInSD
Whether the photon reaches the sensitive detector.
double reemission_energy() const
phot::MappedT0s_t ReflT0s
static int GetCurrentTrackID()
phot::PhotonVisibilityService const *const fPVS
Photon visibility service instance.
bool const fOpaqueCathode
Whether the cathodes are fully opaque; currently hard coded "no".
G4EmSaturation * emSaturation
bool IncludeParPropTime() const
float Energy
Scintillation photon energy [GeV].
size_t NOpChannels() const
phot::MappedFunctions_t ParPropTimeTF1
bool UseLitePhotons() const
std::unique_ptr< G4PhysicsTable > theFastIntegralTable
int MotherTrackID
ID of the GEANT4 track causing the scintillation.