Belle II Software  release-05-01-25
SensitiveDetector.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2015 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Martin Ritter, Igal Jaegle *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <beast/claws/simulation/SensitiveDetector.h>
12 #include <framework/gearbox/Unit.h>
13 #include <G4Track.hh>
14 #include <G4Step.hh>
15 #include <G4Version.hh>
16 
17 #include <array>
18 
19 namespace Belle2 {
25  namespace claws {
26  namespace {
27  std::array<float, 3> vecToFloat(const G4ThreeVector& vec)
28  {
29  return std::array<float, 3> {{(float)vec.x(), (float)vec.y(), (float)vec.z()}};
30  }
31  }
32 
34  Simulation::SensitiveDetectorBase("CLAWSSensitiveDetector", Const::invalidDetector)
35  {
36  //Register all collections we want to modify and require those we want to use
37  m_mcParticles.registerInDataStore();
38  m_simHits.registerInDataStore();
39  m_relMCSimHit.registerInDataStore();
40 
41  //Register the Relation so that the TrackIDs get replaced by the actual
42  //MCParticle indices after simulating the events. This is needed as
43  //secondary particles might not be stored so everything relating to those
44  //particles will be attributed to the last saved mother particle
46 
47 #if G4VERSION_NUMBER < 1010
48  m_saturationEngine = new G4EmSaturation();
49 #else
50  m_saturationEngine = new G4EmSaturation(1); // verbose level
51 #endif
52  }
53 
54  bool SensitiveDetector::step(G4Step* step, G4TouchableHistory*)
55  {
56  //Get scintilator ladder and sensor number
57  const G4TouchableHistory* touchable = dynamic_cast<const G4TouchableHistory*>(step->GetPreStepPoint()->GetTouchable());
58  int ladderID = touchable->GetVolume(2)->GetCopyNo();
59  int sensorID = touchable->GetVolume(1)->GetCopyNo();
60 
61  //Get Track information
62  const G4Track& track = *step->GetTrack();
63  const int trackID = track.GetTrackID();
64  const int pdgCode = step->GetTrack()->GetDefinition()->GetPDGEncoding();
65  // deposited Energy in Geant4 Units
66  double depEnergy = step->GetTotalEnergyDeposit();
67  // get visible energy deposition
68  double visibleEnergy = m_saturationEngine->VisibleEnergyDeposition(
69  track.GetDefinition(),
70  track.GetMaterialCutsCouple(),
71  step->GetStepLength(),
72  depEnergy, 0.
73  );
74  // convert into Belle2 Units
75  depEnergy *= Unit::GeV / CLHEP::GeV;
76  visibleEnergy *= Unit::GeV / CLHEP::GeV;
77 
78  // get pre and post step point
79  const G4StepPoint& preStep = *step->GetPreStepPoint();
80  const G4StepPoint& postStep = *step->GetPostStepPoint();
81 
82  // check if this is the same sensor traversal, otherwise add one to the stack
83  if (m_tracks.empty() || (!m_tracks.top().check(trackID, ladderID, sensorID))) {
84  m_tracks.push(SensorTraversal());
85  }
86  // get the top of the stack
87  SensorTraversal& traversal = m_tracks.top();
88 
89  //If new track, remember values
90  if (traversal.getTrackID() == 0) {
91  bool isPrimary = Simulation::TrackInfo::getInfo(track).hasStatus(MCParticle::c_PrimaryParticle);
92  //Add start position
93  const G4ThreeVector preStepPos = preStep.GetPosition() / CLHEP::mm * Unit::mm;
94  const G4ThreeVector preStepMom = preStep.GetMomentum() / CLHEP::MeV * Unit::MeV;
95  const double time = preStep.GetGlobalTime() / CLHEP::ns * Unit::ns;
96  traversal.setInitial(trackID, ladderID, sensorID, pdgCode, isPrimary, preStepPos, preStepMom, time);
97  //Remember if the track came from the outside
98  if (preStep.GetStepStatus() == fGeomBoundary) traversal.hasEntered();
99  }
100 
101  //Add current step
102  const G4ThreeVector postStepPos = postStep.GetPosition() / CLHEP::mm * Unit::mm;
103  const double length = step->GetStepLength() / CLHEP::cm * Unit::cm;
104  traversal.add(postStepPos, depEnergy, visibleEnergy, length);
105 
106  //check if we are leaving the volume
107  bool isLeaving = (postStep.GetStepStatus() == fGeomBoundary);
108  if (isLeaving) traversal.hasLeft();
109 
110  //if we are leaving or the track is stopped, finish it
111  if (isLeaving || track.GetTrackStatus() >= fStopAndKill) {
112  bool contained = traversal.isContained();
113  bool saved = finishTrack();
114  //we mark all particles as important which created a hit and entered or left the volume
115  if (saved && !contained) {
116  Simulation::TrackInfo::getInfo(track).setIgnore(false);
117  }
118  return saved;
119  }
120  // Track not finished, return false right now
121  return false;
122  }
123 
124  bool SensitiveDetector::finishTrack()
125  {
126  SensorTraversal& traversal = m_tracks.top();
127  // ignore everything below 1eV
128  bool save = traversal.getDepEnergy() > Unit::eV;
129  if (save) {
130  auto momEntry = vecToFloat(traversal.getEntryMomentum());
131  auto posEntry = vecToFloat(traversal.getEntryPosition());
132  auto posExit = vecToFloat(traversal.getExitPosition());
133  int hitIndex = m_simHits.getEntries();
134  m_simHits.appendNew(
135  traversal.getLadderID(), traversal.getSensorID(),
136  traversal.getPDGCode(), traversal.getEntryTime(),
137  traversal.getDepEnergy(), traversal.getVisibleEnergy(),
138  traversal.getLength(), posEntry.data(), posExit.data(),
139  momEntry.data()
140  );
141  m_relMCSimHit.add(traversal.getTrackID(), hitIndex, traversal.getDepEnergy());
142  }
143  //No we just need to take care of the stack of traversals
144  if (m_tracks.size() == 1) {
145  //reuse traversal to keep memory if this is the first one
146  traversal.reset();
147  } else {
148  //this should only happen if the parent track got suspended. As this
149  //rarely happens in PXD we do not care for re-usability here
150  m_tracks.pop();
151  }
152  return save;
153  }
154  } //claw namespace
156 } //Belle2 namespace
Belle2::Unit::cm
static const double cm
Standard units with the value = 1.
Definition: Unit.h:57
Belle2::claws::SensorTraversal
Class to keep track of the traversal of the sensitive volume for one track.
Definition: SensorTraversal.h:35
Belle2::Unit::ns
static const double ns
Standard of [time].
Definition: Unit.h:58
Belle2::claws::SensorTraversal::getDepEnergy
double getDepEnergy() const
get total energy deposition
Definition: SensorTraversal.h:59
Belle2::RelationArray::c_negativeWeight
@ c_negativeWeight
Flip the sign of the weight to become negative if the original element got re-attributed.
Definition: RelationArray.h:89
Belle2::Simulation::UserInfo::getInfo
static Payload getInfo(Carrier &obj)
Static function to just return UserInformation attached to the obj of type Carrier.
Definition: UserInfo.h:110
Belle2::claw::SensitiveDetector::step
bool step(G4Step *step, G4TouchableHistory *) override
Step processing method.
Definition: SensitiveDetector.cc:87
Belle2::claws::SensorTraversal::isContained
bool isContained() const
return whether the track was contained in the volume so far
Definition: SensorTraversal.h:74
Belle2::claws::SensitiveDetector::SensitiveDetector
SensitiveDetector()
Constructor.
Definition: SensitiveDetector.cc:41
Belle2::claws::SensorTraversal::hasEntered
void hasEntered()
indicate that the track originated outisde the current volume
Definition: SensorTraversal.h:79
Belle2::Simulation::SensitiveDetectorBase::registerMCParticleRelation
static void registerMCParticleRelation(const std::string &name, RelationArray::EConsolidationAction ignoreAction=RelationArray::c_negativeWeight)
Register an relation involving MCParticles.
Definition: SensitiveDetectorBase.cc:24
Belle2::claws::SensorTraversal::getTrackID
int getTrackID() const
get Geant4 trackID
Definition: SensorTraversal.h:51
Belle2::Unit::MeV
static const double MeV
[megaelectronvolt]
Definition: Unit.h:124
Belle2::Unit::eV
static const double eV
[electronvolt]
Definition: Unit.h:122
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::Unit::mm
static const double mm
[millimeters]
Definition: Unit.h:80
Belle2::claws::SensorTraversal::add
void add(const G4ThreeVector &position, double depEnergy, double visibleEnergy, double length)
add a new step
Definition: SensorTraversal.h:42
Belle2::claws::SensorTraversal::hasLeft
void hasLeft()
indicate that the track left the current volume
Definition: SensorTraversal.h:81
Belle2::Unit::GeV
static const double GeV
Standard of [energy, momentum, mass].
Definition: Unit.h:61
Belle2::claws::SensorTraversal::setInitial
void setInitial(int trackID, int ladderID, int sensorID, int pdgCode, bool primary, const G4ThreeVector &position, const G4ThreeVector &momentum, double time)
set initial values for a new track
Definition: SensorTraversal.h:84
Belle2::MCParticle::c_PrimaryParticle
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:58