LArSoft  v06_85_00
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);
103  return;
104  }
105 
106  // Explore the next layer down -- unless it is a very deep geometry,
107  // recursion should end before exception is thrown.
108  unsigned int deeper = depth+1;
109  if(deeper >= path.size()){
110  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
111  }
112 
113  // Note that there will be nd different branches off of path[depth]
114  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
115  for(int d = 0; d < nd; ++d){
116 
117  // get the physvol daughter in the logicalvol
118  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
119 
120  // keep track of the transform to world coordinates for PositionToAuxDet
121  G4Transform3D DeeperToMother( path[deeper]->GetObjectRotationValue(),
122  path[deeper]->GetObjectTranslation() );
123  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
124  this->FindAndMakeAuxDetSensitive(path, deeper, DeeperToWorld);
125  }
126 
127  }
128 
129  //---------------------------------------------------------------
130  void AuxDetReadoutGeometry::FindAndMakeAuxDet(std::vector<const G4VPhysicalVolume*>& path,
131  unsigned int depth,
132  G4Transform3D DepthToWorld)
133  {
134 
135  G4LogicalVolume* LogicalVolumeAtDepth = path[depth]->GetLogicalVolume();
136 
137  std::string volName(path[depth]->GetName());
138  if( volName.find("volAuxDet") != std::string::npos ){
139 
140  // find world coordinate of the AuxDet origin in cm
141  G4Point3D local(0., 0., 0.);
142  G4Point3D world = DepthToWorld * local; // G4 works in mm
143  double worldPos[3] = { world.x() / CLHEP::cm, world.y() / CLHEP::cm, world.z() / CLHEP::cm };
144 
145  unsigned int adNum;
146  fGeo->PositionToAuxDet(worldPos, adNum);
147  // N.B. This name is expected by code in LArG4:
148  std::string SDName = "AuxDetSD_AuxDet" + std::to_string(adNum) + "_0";
149  AuxDetReadout* adReadout = new larg4::AuxDetReadout(SDName, adNum, 0);
150 
151  LOG_DEBUG("AuxDetReadoutGeometry") << "found" << path[depth]->GetName()
152  << ", number " << adNum << ":0";
153 
154  // Tell Geant4's sensitive-detector manager about the AuxDetReadout class
155  (G4SDManager::GetSDMpointer())->AddNewDetector(adReadout);
156  LogicalVolumeAtDepth->SetSensitiveDetector(adReadout);
157  return;
158  }
159 
160  // Explore the next layer down -- unless it is a very deep geometry,
161  // recursion should end before exception is thrown.
162  unsigned int deeper = depth+1;
163  if(deeper >= path.size()){
164  throw cet::exception("AuxDetReadoutGeometry") << "exceeded maximum TGeoNode depth\n";
165  }
166 
167  // Note that there will be nd different branches off of path[depth]
168  G4int nd = LogicalVolumeAtDepth->GetNoDaughters();
169  for(int d = 0; d < nd; ++d){
170 
171  // get the physvol daughter in the logicalvol
172  path[deeper] = LogicalVolumeAtDepth->GetDaughter(d);
173 
174  // keep track of the transform to world coordinates for PositionToAuxDet
175  G4Transform3D DeeperToMother( path[deeper]->GetObjectRotationValue(),
176  path[deeper]->GetObjectTranslation() );
177  G4Transform3D DeeperToWorld = DepthToWorld * DeeperToMother;
178  this->FindAndMakeAuxDet(path, deeper, DeeperToWorld);
179  }
180 
181  }
182 
183 
184 } // 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