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