AuxDetReadoutGeometry.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file AuxDetReadoutGeometry.cxx
3 /// \brief Define the "parallel" geometry that's seen by the LAr Voxels.
4 /// \author miceli@fnal.gov, talion@fnal.gov
5 ////////////////////////////////////////////////////////////////////////
6 
7 #include "nug4/G4Base/DetectorConstruction.h"
8 
9 // Framework includes
11 
12 // LArSoft includes
15 
16 // G4 includes
17 #include "Geant4/G4LogicalVolume.hh"
18 #include "Geant4/G4SDManager.hh"
19 #include "Geant4/G4Point3D.hh"
20 
21 namespace larg4 {
22 
23  // Constructor and destructor.
25  : G4VUserParallelWorld(name)
26  , fNumSensitiveVol(0)
27  {}
29  {}
30 
31  ////////////////////////////////////////////////////////////////////
33  {
34 
35  // We want to find all of the AuxDets that the Geometry service would
36  // find and make each one a G4 sensitive detector.
37 
38  // Call initial case of a function that will rucursively run through
39  // the volume tree down to max depth. Start at 0 depth with World,
40  // where the initial translation and rotation should be 0 as well
41  unsigned int MaxDepth = 8; // should be plenty
42  std::vector<const G4VPhysicalVolume*> path(MaxDepth);
43  path[0] = g4b::DetectorConstruction::GetWorld();
44  G4Transform3D InitTransform( path[0]->GetObjectRotationValue(),
45  path[0]->GetObjectTranslation() );
46 
47  // first try to make sensitive volumes, if those are not in
48  // the gdml file (ie file was made before the introduction of
49  // sensitive volumes) fall back to looking for the aux dets
50  this->FindAndMakeAuxDetSensitive(path, 0, InitTransform);
51  if(fNumSensitiveVol < 1)
52  this->FindAndMakeAuxDet(path, 0, InitTransform);
53 
54 
55  return;
56  }// end Construct
57 
58  //---------------------------------------------------------------
59  void AuxDetReadoutGeometry::FindAndMakeAuxDetSensitive(std::vector<const G4VPhysicalVolume*>& path,
60  unsigned int depth,
61  G4Transform3D DepthToWorld)
62  {
63 
64  G4LogicalVolume* LogicalVolumeAtDepth = path[depth]->GetLogicalVolume();
65 
66  std::string volName(path[depth]->GetName());
67  if( volName.find("volAuxDet") != std::string::npos &&
68  volName.find("Sensitive") != std::string::npos){
69 
70  // find world coordinate of the AuxDet origin in cm
71  G4Point3D local(0., 0., 0.);
72  G4Point3D world = DepthToWorld * local; // G4 works in mm
73  double worldPos[3] = { world.x() / CLHEP::cm, world.y() / CLHEP::cm, world.z() / CLHEP::cm };
74 
75  size_t adNum = 0;
76  size_t svNum = 0;
77  fGeo->FindAuxDetSensitiveAtPosition(worldPos, adNum, svNum);
78  // N.B. This name is expected by code in LArG4:
79  std::string SDName = "AuxDetSD_AuxDet" + std::to_string(adNum) + "_" + std::to_string(svNum);
80  AuxDetReadout* adReadout = new larg4::AuxDetReadout(SDName, adNum, svNum);
81 
82  MF_LOG_DEBUG("AuxDetReadoutGeometry") << "found" << path[depth]->GetName()
83  << ", number " << adNum << ":" << svNum;
84 
85  // Tell Geant4's sensitive-detector manager about the AuxDetReadout class
86  (G4SDManager::GetSDMpointer())->AddNewDetector(adReadout);
87  LogicalVolumeAtDepth->SetSensitiveDetector(adReadout);
89  return;
90  }
91 
92  // Explore the next layer down -- unless it is a very deep geometry,
93  // recursion should end before exception is thrown.
94  unsigned int deeper = depth+1;
95  if(deeper >= path.size()){
96  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
97  }
98 
99  // Note that there will be nd different branches off of path[depth]
100  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
101  for(int d = 0; d < nd; ++d){
102 
103  // get the physvol daughter in the logicalvol
104  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
105 
106  // keep track of the transform to world coordinates for PositionToAuxDet
107  G4Transform3D DeeperToMother( path[deeper]->GetObjectRotationValue(),
108  path[deeper]->GetObjectTranslation() );
109  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
110  this->FindAndMakeAuxDetSensitive(path, deeper, DeeperToWorld);
111  }
112 
113  }
114 
115  //---------------------------------------------------------------
116  void AuxDetReadoutGeometry::FindAndMakeAuxDet(std::vector<const G4VPhysicalVolume*>& path,
117  unsigned int depth,
118  G4Transform3D DepthToWorld)
119  {
120 
121  G4LogicalVolume* LogicalVolumeAtDepth = path[depth]->GetLogicalVolume();
122 
123  std::string volName(path[depth]->GetName());
124  if( volName.find("volAuxDet") != std::string::npos ){
125 
126  // find world coordinate of the AuxDet origin in cm
127  G4Point3D local(0., 0., 0.);
128  G4Point3D world = DepthToWorld * local; // G4 works in mm
129  double worldPos[3] = { world.x() / CLHEP::cm, world.y() / CLHEP::cm, world.z() / CLHEP::cm };
130 
131  unsigned int adNum;
132  fGeo->PositionToAuxDet(worldPos, adNum);
133  // N.B. This name is expected by code in LArG4:
134  std::string SDName = "AuxDetSD_AuxDet" + std::to_string(adNum) + "_0";
135  AuxDetReadout* adReadout = new larg4::AuxDetReadout(SDName, adNum, 0);
136 
137  MF_LOG_DEBUG("AuxDetReadoutGeometry") << "found" << path[depth]->GetName()
138  << ", number " << adNum << ":0";
139 
140  // Tell Geant4's sensitive-detector manager about the AuxDetReadout class
141  (G4SDManager::GetSDMpointer())->AddNewDetector(adReadout);
142  LogicalVolumeAtDepth->SetSensitiveDetector(adReadout);
144  return;
145  }
146 
147  // Explore the next layer down -- unless it is a very deep geometry,
148  // recursion should end before exception is thrown.
149  unsigned int deeper = depth+1;
150  if(deeper >= path.size()){
151  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
152  }
153 
154  // Note that there will be nd different branches off of path[depth]
155  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
156  for(int d = 0; d < nd; ++d){
157 
158  // get the physvol daughter in the logicalvol
159  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
160 
161  // keep track of the transform to world coordinates for PositionToAuxDet
162  G4Transform3D DeeperToMother( path[deeper]->GetObjectRotationValue(),
163  path[deeper]->GetObjectTranslation() );
164  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
165  this->FindAndMakeAuxDet(path, deeper, DeeperToWorld);
166  }
167 
168  }
169 
170 
171 } // namespace larg4
static constexpr double cm
Definition: Units.h:68
static QCString name
Definition: declinfo.cpp:673
void FindAuxDetSensitiveAtPosition(geo::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.
std::string string
Definition: nybbler.cc:12
Geant4 interface.
void FindAndMakeAuxDet(std::vector< const G4VPhysicalVolume * > &path, unsigned int depth, G4Transform3D DepthToWorld)
uint32_t fNumSensitiveVol
number of sensitive volumes
AuxDetReadoutGeometry(const G4String name="AuxDetReadoutGeometry")
Constructor and destructor.
AuxDetGeo const & PositionToAuxDet(geo::Point_t const &point, unsigned int &ad, double tolerance=0) const
Returns the auxiliary detector at specified location.
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)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
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