Belle II Software  release-08-01-10
SensitiveBar.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <top/simulation/SensitiveBar.h>
10 
11 #include <simulation/kernel/UserInfo.h>
12 #include <G4Step.hh>
13 #include <G4Track.hh>
14 #include <G4UnitsTable.hh>
15 #include <G4ParticleDefinition.hh>
16 #include <G4ParticleTypes.hh>
17 
18 #include <framework/logging/Logger.h>
19 #include <framework/gearbox/Unit.h>
20 
21 #include <Math/Vector3D.h>
22 #include <Math/Point3D.h>
23 #include <TRandom.h>
24 #include <cmath>
25 
26 using namespace std;
27 
28 namespace Belle2 {
33  namespace TOP {
34 
35  SensitiveBar::SensitiveBar():
36  Simulation::SensitiveDetectorBase("TOP", Const::TOP)
37  {
38 
39  // registration of store arrays and relations
40 
41  m_barHits.registerInDataStore();
43 
44  // additional registration of MCParticle relation (required for correct relations)
45 
47 
48  const auto* geo = m_topgp->getGeometry();
49  m_trackIDs.resize(geo->getNumModules(), 0);
50 
51  }
52 
53 
54  bool SensitiveBar::step(G4Step* aStep, G4TouchableHistory*)
55  {
56 
57  // get track and particle definition
58 
59  G4Track* aTrack = aStep->GetTrack();
60  G4ParticleDefinition* particle = aTrack->GetDefinition();
61 
62  // if optical photon, apply QE and return false
63 
64  if (particle == G4OpticalPhoton::OpticalPhotonDefinition()) {
65  auto* info = dynamic_cast<Simulation::TrackInfo*>(aTrack->GetUserInformation());
66  if (!info) return false;
67  if (info->getStatus() < 2) {
68  double energy = aTrack->GetKineticEnergy() * Unit::MeV / Unit::eV;
69  double qeffi = m_topgp->getPMTEfficiencyEnvelope(energy);
70  double fraction = info->getFraction();
71  if (qeffi == 0 or gRandom->Uniform() * fraction > qeffi) {
72  aTrack->SetTrackStatus(fStopAndKill);
73  return false;
74  }
75  info->setStatus(2);
76  info->setFraction(qeffi);
77  }
78  return false;
79  }
80 
81  // continue for other particles, if they enter the volume for the first time
82 
83  G4StepPoint* PrePosition = aStep->GetPreStepPoint();
84  if (PrePosition->GetStepStatus() != fGeomBoundary) return false; // not on boundary
85 
86  if (m_barHits.getEntries() == 0) {
87  for (auto& trackID : m_trackIDs) trackID = -1; // reset on new event
88  }
89 
90  int moduleID = PrePosition->GetTouchableHandle()->GetReplicaNumber(m_replicaDepth);
91  const auto* geo = m_topgp->getGeometry();
92  if (!geo->isModuleIDValid(moduleID)) {
93  B2ERROR("TOP::SensitiveBar: undefined module ID."
94  << LogVar("moduleID", moduleID));
95  return false;
96  }
97 
98  int trackID = aTrack->GetTrackID();
99  if (trackID == m_trackIDs[moduleID - 1]) return false; // not first time on boundary
100  m_trackIDs[moduleID - 1] = trackID;
101 
102  // particle other than optical photon entered the volume for the first time
103  // convert to basf2 units and write-out the hit
104 
105  G4ThreeVector worldPosition = PrePosition->GetPosition();
106  double tracklength = aTrack->GetTrackLength() - aStep->GetStepLength();
107  double globalTime = PrePosition->GetGlobalTime();
108  G4ThreeVector momentum = PrePosition->GetMomentum();
109 
110  ROOT::Math::XYZPoint TPosition(worldPosition.x(), worldPosition.y(), worldPosition.z());
111  ROOT::Math::XYZVector TMomentum(momentum.x(), momentum.y(), momentum.z());
112  ROOT::Math::XYZPoint TOrigin(aTrack->GetVertexPosition().x(),
113  aTrack->GetVertexPosition().y(),
114  aTrack->GetVertexPosition().z());
115 
116  // convert to basf2 units
117  TPosition = TPosition * Unit::mm;
118  TMomentum = TMomentum * Unit::MeV;
119  TOrigin = TOrigin * Unit::mm;
120  tracklength = tracklength * Unit::mm;
121 
122  const auto& module = geo->getModule(moduleID);
123  auto locPosition = module.pointToLocal(TPosition);
124  auto locMomentum = module.momentumToLocal(TMomentum);
125  double theta = locMomentum.Theta();
126  double phi = locMomentum.Phi();
127 
128  int PDG = (int)(particle->GetPDGEncoding());
129 
130  // write hit to datastore
131  auto* hit = m_barHits.appendNew(moduleID, PDG, TOrigin, TPosition, TMomentum,
132  globalTime, tracklength, locPosition,
133  theta, phi);
134 
135  // set the relation
136  m_relParticleHit.add(trackID, hit->getArrayIndex());
137 
138  return true;
139  }
140 
141 
142  } // end of namespace top
144 } // end of namespace Belle2
This class provides a set of constants for the framework.
Definition: Const.h:34
@ c_deleteElement
Delete the whole relation element if the original element got re-attributed.
Definition: RelationArray.h:81
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.
UserInfo class which is used to attach additional information to Geant4 particles and tracks.
Definition: UserInfo.h:36
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.
Definition: StoreArray.h:140
bool step(G4Step *aStep, G4TouchableHistory *) override
Process each step and fill TOPBarHits.
Definition: SensitiveBar.cc:54
int m_replicaDepth
replica depth of module volume
Definition: SensitiveBar.h:55
std::vector< int > m_trackIDs
track ID's
Definition: SensitiveBar.h:57
RelationArray m_relParticleHit
relations
Definition: SensitiveBar.h:61
TOPGeometryPar * m_topgp
geometry parameters
Definition: SensitiveBar.h:56
StoreArray< MCParticle > m_mcParticles
collection of MC particles
Definition: SensitiveBar.h:59
StoreArray< TOPBarHit > m_barHits
collection of entrance-to-bar hits
Definition: SensitiveBar.h:60
double getPMTEfficiencyEnvelope(double energy) const
Returns PMT efficiency envelope, e.g.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static const double mm
[millimeters]
Definition: Unit.h:70
static const double eV
[electronvolt]
Definition: Unit.h:112
static const double MeV
[megaelectronvolt]
Definition: Unit.h:114
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.