LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
AuxDetReadoutGeometry.cxx
Go to the documentation of this file.
1 
8 
9 // Framework includes
11 
12 // LArSoft includes
15 
16 // G4 includes
17 #include "Geant4/G4LogicalVolume.hh"
18 #include "Geant4/G4Point3D.hh"
19 #include "Geant4/G4SDManager.hh"
20 
21 namespace larg4 {
22 
23  // Constructor and destructor.
25  : G4VUserParallelWorld(name), fNumSensitiveVol(0)
26  {}
28 
31  {
32 
33  // We want to find all of the AuxDets that the Geometry service would
34  // find and make each one a G4 sensitive detector.
35 
36  // Call initial case of a function that will rucursively run through
37  // the volume tree down to max depth. Start at 0 depth with World,
38  // where the initial translation and rotation should be 0 as well
39  unsigned int MaxDepth = 8; // should be plenty
40  std::vector<const G4VPhysicalVolume*> path(MaxDepth);
42  G4Transform3D InitTransform(path[0]->GetObjectRotationValue(), path[0]->GetObjectTranslation());
43 
44  // first try to make sensitive volumes, if those are not in
45  // the gdml file (ie file was made before the introduction of
46  // sensitive volumes) fall back to looking for the aux dets
47  this->FindAndMakeAuxDetSensitive(path, 0, InitTransform);
48  if (fNumSensitiveVol < 1) this->FindAndMakeAuxDet(path, 0, InitTransform);
49 
50  return;
51  } // end Construct
52 
53  //---------------------------------------------------------------
55  std::vector<const G4VPhysicalVolume*>& path,
56  unsigned int depth,
57  G4Transform3D DepthToWorld)
58  {
59 
60  G4LogicalVolume* LogicalVolumeAtDepth = path[depth]->GetLogicalVolume();
61 
62  std::string volName(path[depth]->GetName());
63  if (volName.find("volAuxDet") != std::string::npos &&
64  volName.find("Sensitive") != std::string::npos) {
65 
66  // find world coordinate of the AuxDet origin in cm
67  G4Point3D local(0., 0., 0.);
68  G4Point3D world = DepthToWorld * local; // G4 works in mm
69  geo::Point_t const worldPos{
70  world.x() / CLHEP::cm, world.y() / CLHEP::cm, world.z() / CLHEP::cm};
71 
72  size_t adNum = 0;
73  size_t svNum = 0;
74  fGeo->FindAuxDetSensitiveAtPosition(worldPos, adNum, svNum);
75  // N.B. This name is expected by code in LArG4:
76  std::string SDName = "AuxDetSD_AuxDet" + std::to_string(adNum) + "_" + std::to_string(svNum);
77  AuxDetReadout* adReadout = new larg4::AuxDetReadout(SDName, adNum, svNum);
78 
79  MF_LOG_DEBUG("AuxDetReadoutGeometry")
80  << "found" << path[depth]->GetName() << ", number " << adNum << ":" << svNum;
81 
82  // Tell Geant4's sensitive-detector manager about the AuxDetReadout class
83  (G4SDManager::GetSDMpointer())->AddNewDetector(adReadout);
84  LogicalVolumeAtDepth->SetSensitiveDetector(adReadout);
86  return;
87  }
88 
89  // Explore the next layer down -- unless it is a very deep geometry,
90  // recursion should end before exception is thrown.
91  unsigned int deeper = depth + 1;
92  if (deeper >= path.size()) {
93  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
94  }
95 
96  // Note that there will be nd different branches off of path[depth]
97  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
98  for (int d = 0; d < nd; ++d) {
99 
100  // get the physvol daughter in the logicalvol
101  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
102 
103  // keep track of the transform to world coordinates for PositionToAuxDet
104  G4Transform3D DeeperToMother(path[deeper]->GetObjectRotationValue(),
105  path[deeper]->GetObjectTranslation());
106  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
107  this->FindAndMakeAuxDetSensitive(path, deeper, DeeperToWorld);
108  }
109  }
110 
111  //---------------------------------------------------------------
112  void AuxDetReadoutGeometry::FindAndMakeAuxDet(std::vector<const G4VPhysicalVolume*>& path,
113  unsigned int depth,
114  G4Transform3D DepthToWorld)
115  {
116 
117  G4LogicalVolume* LogicalVolumeAtDepth = path[depth]->GetLogicalVolume();
118 
119  std::string volName(path[depth]->GetName());
120  if (volName.find("volAuxDet") != std::string::npos) {
121 
122  // find world coordinate of the AuxDet origin in cm
123  G4Point3D local(0., 0., 0.);
124  G4Point3D world = DepthToWorld * local; // G4 works in mm
125  geo::Point_t const worldPos{
126  world.x() / CLHEP::cm, world.y() / CLHEP::cm, world.z() / CLHEP::cm};
127 
128  unsigned int adNum;
129  fGeo->PositionToAuxDet(worldPos, adNum);
130  // N.B. This name is expected by code in LArG4:
131  std::string SDName = "AuxDetSD_AuxDet" + std::to_string(adNum) + "_0";
132  AuxDetReadout* adReadout = new larg4::AuxDetReadout(SDName, adNum, 0);
133 
134  MF_LOG_DEBUG("AuxDetReadoutGeometry")
135  << "found" << path[depth]->GetName() << ", number " << adNum << ":0";
136 
137  // Tell Geant4's sensitive-detector manager about the AuxDetReadout class
138  (G4SDManager::GetSDMpointer())->AddNewDetector(adReadout);
139  LogicalVolumeAtDepth->SetSensitiveDetector(adReadout);
141  return;
142  }
143 
144  // Explore the next layer down -- unless it is a very deep geometry,
145  // recursion should end before exception is thrown.
146  unsigned int deeper = depth + 1;
147  if (deeper >= path.size()) {
148  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
149  }
150 
151  // Note that there will be nd different branches off of path[depth]
152  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
153  for (int d = 0; d < nd; ++d) {
154 
155  // get the physvol daughter in the logicalvol
156  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
157 
158  // keep track of the transform to world coordinates for PositionToAuxDet
159  G4Transform3D DeeperToMother(path[deeper]->GetObjectRotationValue(),
160  path[deeper]->GetObjectTranslation());
161  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
162  this->FindAndMakeAuxDet(path, deeper, DeeperToWorld);
163  }
164  }
165 
166 } // namespace larg4
Build Geant4 geometry from GDML.
static G4VPhysicalVolume * GetWorld()
Geant4 interface.
void FindAndMakeAuxDet(std::vector< const G4VPhysicalVolume * > &path, unsigned int depth, G4Transform3D DepthToWorld)
uint32_t fNumSensitiveVol
number of sensitive volumes
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
void FindAuxDetSensitiveAtPosition(Point_t const &point, std::size_t &adg, std::size_t &sv, double tolerance=0) const
Fills the indices of the sensitive auxiliary detector at location.
Float_t d
Definition: plot.C:235
AuxDetReadoutGeometry(const G4String name="AuxDetReadoutGeometry")
Constructor and destructor.
AuxDetGeo const & PositionToAuxDet(Point_t const &point, unsigned int &ad, double tolerance=0) const
Returns the auxiliary detector at specified location.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
art::ServiceHandle< geo::Geometry const > fGeo
Handle to the geometry.
Define the "parallel" geometry that&#39;s seen by the AuxDet.
#define MF_LOG_DEBUG(id)
A Geant4 sensitive detector that accumulates information.
void FindAndMakeAuxDetSensitive(std::vector< const G4VPhysicalVolume * > &path, unsigned int depth, G4Transform3D DepthToWorld)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33