10#include <ecl/simulation/SensitiveDetector.h>
13#include <ecl/geometry/ECLGeometryPar.h>
16#include <framework/gearbox/Const.h>
17#include <framework/gearbox/Unit.h>
18#include <simulation/background/BkgNeutronWeight.h>
21using namespace Belle2::ECL;
26 G4double UNUSED(thresholdKineticEnergy)):
27 Simulation::SensitiveDetectorBase(name,
Const::ECL),
28 m_eclSimHitRel(m_mcParticles, m_eclSimHits),
29 m_eclHitRel(m_mcParticles, m_eclHits),
30 m_ECLHadronComponentEmissionFunction()
37 m_hadronenergyDeposit = 0;
39 registerMCParticleRelation(m_eclSimHitRel);
40 registerMCParticleRelation(m_eclHitRel);
42 m_eclSimHits.registerInDataStore();
43 m_eclHits.registerInDataStore();
45 m_mcParticles.registerRelationTo(m_eclSimHits);
46 m_mcParticles.registerRelationTo(m_eclHits);
48 m_HadronEmissionFunction = m_ECLHadronComponentEmissionFunction->getHadronComponentEmissionFunction();
70double GetCsITlScintillationEfficiency(
double x)
72 const double p0 = 1.52;
73 const double p1 = 0.00344839;
74 const double p2 = 2.0;
77 val = (x * p0) / (x + (p1 * x * x) + p2);
87 double preKineticEnergy = aStep->GetPreStepPoint()->GetKineticEnergy();
88 double postKineticEnergy = aStep->GetPostStepPoint()->GetKineticEnergy();
89 double avgKineticEnergy = 0.5 * (preKineticEnergy + postKineticEnergy);
90 const G4ParticleDefinition* StepParticleDefinition = aStep->GetTrack()->GetParticleDefinition();
91 G4Material* StepMaterial = aStep->GetTrack()->GetMaterial();
92 const double CsIDensity = 4.51;
93 double ELE_DEDX =
m_emCal.ComputeDEDX(avgKineticEnergy, StepParticleDefinition,
"eIoni",
94 StepMaterial) / CLHEP::MeV * CLHEP::cm / (CsIDensity);
95 double MU_DEDX =
m_emCal.ComputeDEDX(avgKineticEnergy, StepParticleDefinition,
"muIoni",
96 StepMaterial) / CLHEP::MeV * CLHEP::cm / (CsIDensity);
97 double HAD_DEDX =
m_emCal.ComputeDEDX(avgKineticEnergy, StepParticleDefinition,
"hIoni",
98 StepMaterial) / CLHEP::MeV * CLHEP::cm / (CsIDensity);
99 double ION_DEDX =
m_emCal.ComputeDEDX(avgKineticEnergy, StepParticleDefinition,
"ionIoni",
100 StepMaterial) / CLHEP::MeV * CLHEP::cm / (CsIDensity);
101 G4double DEDX_val = ELE_DEDX + MU_DEDX + HAD_DEDX + ION_DEDX;
103 G4double edep = aStep->GetTotalEnergyDeposit();
104 double LightOutputCorrection = GetCsITlScintillationEfficiency(DEDX_val);
105 edep *= LightOutputCorrection;
106 const G4StepPoint& s0 = *aStep->GetPreStepPoint();
107 const G4StepPoint& s1 = *aStep->GetPostStepPoint();
108 const G4Track& track = *aStep->GetTrack();
120 G4double hedep = 0.5 * edep;
122 m_WeightedTime += (s0.GetGlobalTime() + s1.GetGlobalTime()) * hedep;
123 m_WeightedPos += (s0.GetPosition() + s1.GetPosition()) * hedep;
129 if (track.GetNextVolume() != track.GetVolume() || track.GetTrackStatus() >= fStopAndKill) {
136 int pdgCode = track.GetDefinition()->GetPDGEncoding();
147 struct hit_t {
double e, t; };
150 struct thit_t {
int tid, hid; };
156 double tof = t.getFlightTime();
157 if (tof >= 8000.0 || tof < -8000.0)
continue;
158 int TimeIndex = (tof + 8000.0) * (1. / 100);
159 int cellId = t.getCellId() - 1;
160 int key = cellId * 160 + TimeIndex;
161 double edep = t.getEnergyDep();
162 double tsen = tof + eclp->
time2sensor(cellId, t.getPosition());
166 int trkid = t.getTrackId();
167 tr.push_back({trkid, key});
169 double old_edep = h.e, old_tsen = h.t;
170 double new_edep = old_edep + edep;
173 h.t = (old_edep * old_tsen + edep * tsen) / new_edep;
178 for (pair<int, hit_t> t : a) {
179 int key = t.first, cellId = key / 160;
180 for (
const thit_t& s : tr)
182 const hit_t& h = t.second;
183 m_eclHits.appendNew(cellId + 1, h.e, h.t); hitNum++;
188 const G4ThreeVector& mom,
const G4ThreeVector& pos,
double Hadronedep)
192 tof *= 1 / CLHEP::ns;
193 edep *= 1 / CLHEP::GeV;
194 m_eclSimHits.appendNew(cellId + 1, trackID, pid, tof, edep, mom * (1 / CLHEP::GeV), pos * (1 / CLHEP::cm), Hadronedep);
199 Simulation::SensitiveDetectorBase(name,
Const::ECL)
201 m_eclHits.registerInDataStore(
"ECLDiodeHits");
223 const G4StepPoint& s0 = *aStep->GetPreStepPoint();
224 const G4StepPoint& s1 = *aStep->GetPostStepPoint();
225 const G4Track& track = *aStep->GetTrack();
234 G4double edep = aStep->GetTotalEnergyDeposit();
236 m_tsum += (s0.GetGlobalTime() + s1.GetGlobalTime()) * edep;
238 if (track.GetNextVolume() != track.GetVolume() ||
239 track.GetTrackStatus() >= fStopAndKill) {
247 const G4ThreeVector& p = s0.GetPosition();
250 double dz = (p - cp) * cv;
251 double rho = ((p - cp) - dz * cv).perp();
252 cout <<
"diff " << cellID <<
" " << dz <<
" " << rho << endl;
253 if (abs(dz - 150) > 1) {
254 const G4VTouchable* touch = s0.GetTouchable();
255 const G4NavigationHistory* h = touch->GetHistory();
256 int hd = h->GetDepth();
257 int i1 = h->GetReplicaNo(hd - 1);
258 int i2 = h->GetReplicaNo(hd - 2);
259 const G4String& vname = touch->GetVolume()->GetName();
260 cout << vname <<
" " << hd <<
" " << i1 <<
" " << i2 << endl;
261 for (
int i = 0; i <= hd; i++) {
262 G4VPhysicalVolume* v = h->GetVolume(i);
263 cout << v->GetName() << endl;
276 struct dep_t {
double e, t;};
281 if (cellId == h.cellId) v.push_back({h.e, h.t});
284 double esum = 0, tsum = 0;
285 for (
const dep_t& t : v) {
291 tsum *= 1 / CLHEP::ns;
292 esum *= 1 / CLHEP::GeV;
293 m_eclHits.appendNew(cellId + 1, esum, tsum);
307 Simulation::SensitiveDetectorBase(name,
Const::invalidDetector),
308 m_eclBeamBkgHitRel(m_mcParticles, m_eclBeamBkgHits)
327 const G4StepPoint& s0 = *aStep->GetPreStepPoint();
328 const G4Track& track = *aStep->GetTrack();
333 const G4ThreeVector& worldPosition = s0.GetPosition();
335 m_startPos.SetXYZ(worldPosition.x() * mm2cm, worldPosition.y() * mm2cm, worldPosition.z() * mm2cm);
337 const G4ThreeVector& momentum = s0.GetMomentum() ;
352 if (track.GetNextVolume() != track.GetVolume() ||
353 track.GetTrackStatus() >= fStopAndKill) {
354 int pdgCode = track.GetDefinition()->GetPDGEncoding();
355 double endEnergy = track.GetKineticEnergy() *
Unit::MeV;
356 double neutWeight = 0;
The class to get the weighting factor for a 1-MeV-equivalent neutron flux on silicon.
This class provides a set of constants for the framework.
static const ParticleType neutron
neutron particle
ClassECLSimHit - Geant4 simulated hit for the ECL.
bool step(G4Step *aStep, G4TouchableHistory *history) override
Process each step and calculate variables defined in ECLHit.
double m_energyDeposit
energy deposited in volume
ROOT::Math::XYZVector m_startPos
particle position at the entrance in volume
BkgSensitiveDiode(const G4String &)
Constructor.
double m_startEnergy
particle energy at the entrance in volume
double m_startTime
global time
double m_trackLength
length of the track in the volume
ECLGeometryPar * m_eclp
pointer to ECLGeometryPar
StoreArray< MCParticle > m_mcParticles
MCParticle array.
RelationArray m_eclBeamBkgHitRel
MCParticle to BeamBackHit relation array.
ROOT::Math::XYZVector m_startMom
particle momentum at the entrance in volume
StoreArray< BeamBackHit > m_eclBeamBkgHits
BeamBackHit array.
The Class for ECL Geometry Parameters.
G4ThreeVector getCrystalVec(int cid)
The direction of crystal.
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
int TouchableToCellID(const G4VTouchable *)
The same as above but without sanity checks.
G4ThreeVector getCrystalPos(int cid)
The Position of crystal.
double time2sensor(int cid, const G4ThreeVector &hit_pos)
function to calculate flight time to diode sensor
int TouchableDiodeToCellID(const G4VTouchable *)
Mapping from G4VTouchable copyNumbers to Crystal CellID.
bool step(G4Step *aStep, G4TouchableHistory *history) override
Process each step and calculate variables defined in ECLHit.
double m_energyDeposit
total energy deposited in a volume by a track
double GetHadronIntensityFromDEDX(double)
Evaluates hadron scintillation component emission function.
double m_hadronenergyDeposit
energy deposited resulting in hadronic scint component
TGraph * m_HadronEmissionFunction
Graph for hadron scintillation component emission function.
int m_trackID
current track id
StoreArray< ECLSimHit > m_eclSimHits
ECLSimHit array.
G4ThreeVector m_momentum
initial momentum of track before energy deposition inside sensitive volume
G4EmCalculator m_emCal
Used to get dE/dx for pulse shape simulations.
void EndOfEvent(G4HCofThisEvent *eventHC) override
Do what you want to do at the end of each event.
void Initialize(G4HCofThisEvent *HCTE) override
Register ECL hits collection into G4HCofThisEvent.
double m_WeightedTime
average track time weighted by energy deposition
RelationArray m_eclHitRel
MCParticle to ECLHit relation array.
StoreArray< ECLHit > m_eclHits
ECLHit array.
SensitiveDetector(G4String, G4double, G4double)
Constructor.
int saveSimHit(G4int, G4int, G4int, G4double, G4double, const G4ThreeVector &, const G4ThreeVector &, double)
Create ECLSimHit and ECLHit and relations from MCParticle and put them in datastore.
~SensitiveDetector()
Destructor.
G4ThreeVector m_WeightedPos
average track position weighted by energy deposition
RelationArray m_eclSimHitRel
MCParticle to ECLSimHit relation array.
bool step(G4Step *aStep, G4TouchableHistory *history) override
Process each step and calculate variables defined in ECLHit.
std::vector< hit_t > m_hits
array of hits
int m_trackID
current track id
double m_tsum
average track time weighted by energy deposition
std::vector< int > m_cells
array of hit crystals
SensitiveDiode(const G4String &)
Constructor.
double m_esum
total energy deposited in a volume by a track
void EndOfEvent(G4HCofThisEvent *eventHC) override
Do what you want to do at the end of each event.
~SensitiveDiode()
Destructor.
void Initialize(G4HCofThisEvent *HCTE) override
Register ECL hits collection into G4HCofThisEvent.
ECLGeometryPar * m_eclp
pointer to ECLGeometryPar
StoreArray< ECLHit > m_eclHits
ECLHit array.
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
static void registerMCParticleRelation(const std::string &name, RelationArray::EConsolidationAction ignoreAction=RelationArray::c_negativeWeight)
Register an relation involving MCParticles.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
static const double mm
[millimeters]
static const double MeV
[megaelectronvolt]
static const double cm
Standard units with the value = 1.
double getWeight(double ke)
Get weighting factor to convert a neutron to its 1-MeV equivalent.
static BkgNeutronWeight & getInstance()
Return a reference to the singleton BkgNeutronWeight instance.