All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OpDetReadoutGeometry.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file OpDetReadoutGeometry.cxx
3 //
4 /// \author bjpjones@mit.edu
5 ////////////////////////////////////////////////////////////////////////
6 #include "nug4/G4Base/DetectorConstruction.h"
7 
8 #include "CLHEP/Geometry/Transform3D.h"
9 #include "CLHEP/Vector/Rotation.h"
10 #include "CLHEP/Vector/ThreeVector.h"
11 #include "Geant4/G4LogicalVolume.hh"
12 #include "Geant4/G4PVPlacement.hh"
13 #include "Geant4/G4RotationMatrix.hh"
14 #include "Geant4/G4ThreeVector.hh"
15 #include "Geant4/G4Types.hh"
16 #include "Geant4/G4VPhysicalVolume.hh"
17 
23 
24 #include <sstream>
25 
26 #include "art/Framework/Services/Registry/ServiceHandle.h"
27 #include "cetlib_except/exception.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 
30 namespace larg4 {
31 
32  OpDetReadoutGeometry::OpDetReadoutGeometry(G4String OpDetSensitiveName,
33  const G4String name,
34  bool useLitePhotons /* = false */)
35  : G4VUserParallelWorld(name), fUseLitePhotons(useLitePhotons)
36  {
37  fOpDetSensitiveName = OpDetSensitiveName;
38  }
39 
41 
42  void
44  {
45  mf::LogInfo("OpDetReadoutGeometry")
46  << "constructing parallel world, looking for " << fOpDetSensitiveName;
47 
48  // Get an empty parallel world volume
49  G4VPhysicalVolume* ParallelWorld = GetWorld();
50 
51  // Start with empty vectors
52  std::vector<G4LogicalVolume*> OpDetVolumes;
53  std::vector<G4Transform3D> OpDetTransformations;
54 
55  // Get the primary world volume
56  G4VPhysicalVolume* WorldPhysical = g4b::DetectorConstruction::GetWorld();
57 
58  // Find the OpDet volumes
59  std::vector<G4Transform3D> EmptyVector;
60  EmptyVector.clear();
62  WorldPhysical, fOpDetSensitiveName, EmptyVector, OpDetVolumes, OpDetTransformations);
63 
64  fOpDetVolumes = OpDetVolumes;
65  fOpDetTransformations = OpDetTransformations;
66 
67  // Get the OpDet Lookup Table
69 
70  // Create sensitive detector
71  OpDetSensitiveDetector* TheSD =
72  new OpDetSensitiveDetector("OpDetSensitiveDetector", fUseLitePhotons);
73 
74  if (OpDetVolumes.size() > 0) {
75 
76  // Make placements
77  for (unsigned int i = 0; i != OpDetVolumes.size(); i++) {
78  std::stringstream VolumeName;
79  VolumeName.flush();
80  VolumeName.str("OpDetVolume_");
81  VolumeName << i;
82 
83  G4Transform3D TheTransform = OpDetTransformations.at(i);
84 
85  G4VSolid* TheSolid = OpDetVolumes.at(i)->GetSolid();
86  G4Material* TheMaterial = OpDetVolumes.at(i)->GetMaterial();
87  G4LogicalVolume* TheLogVolume =
88  new G4LogicalVolume(TheSolid, TheMaterial, VolumeName.str().c_str());
89 
90  TheLogVolume->SetSensitiveDetector(TheSD);
91 
92  G4PVPlacement* ThePlacement = new G4PVPlacement(
93  TheTransform, VolumeName.str().c_str(), TheLogVolume, ParallelWorld, false, 0);
94 
95  // CLHEP::Hep3Vector trans = ThePlacement->GetTranslation();
96 
97  TheOpDetLookup->AddPhysicalVolume(ThePlacement);
98  }
99  }
100 
101  // Now add any optically parameterized volumes
102 
103  std::vector<G4LogicalVolume*> OpParamVolumesFound;
104  std::vector<G4Transform3D> OpParamTransformationsFound;
105 
106  art::ServiceHandle<sim::LArG4Parameters const> lgp;
107 
108  std::vector<std::string> OpParamModels = lgp->OpticalParamModels();
109  std::vector<std::string> OpParamVolumes = lgp->OpticalParamVolumes();
110  std::vector<int> OpParamOrientations = lgp->OpticalParamOrientations();
111  ;
112  std::vector<std::vector<std::vector<double>>> OpParamParameters = lgp->OpticalParamParameters();
113 
114  if ((OpParamModels.size() != OpParamVolumes.size()) ||
115  (OpParamModels.size() != OpParamOrientations.size()) ||
116  (OpParamModels.size() != OpParamParameters.size())) {
117  throw cet::exception("OpDetReadoutGeometry")
118  << "sizes of OpParam specification vectors do not match\n";
119  }
120 
121  for (size_t imodel = 0; imodel != OpParamVolumes.size(); ++imodel) {
122  EmptyVector.clear();
123  FindVolumes(WorldPhysical,
124  OpParamVolumes.at(imodel),
125  EmptyVector,
126  OpParamVolumesFound,
127  OpParamTransformationsFound);
128  mf::LogInfo("OpDetReadoutGeometry")
129  << "Found " << OpParamVolumesFound.size() << " volumes of name "
130  << OpParamVolumes.at(imodel) << " to attach optical parameterization "
131  << OpParamModels.at(imodel) << std::endl;
132 
133  // Since the same named model may be instantiated more than once with
134  // different parameters, create a unique sensitive detector name for this
135  // instance
136 
137  std::stringstream SDName("");
138  SDName << OpParamModels.at(imodel) << "_" << imodel;
139 
140  OpParamSD* ParamSD = new OpParamSD(SDName.str().c_str(),
141  OpParamModels.at(imodel),
142  OpParamOrientations.at(imodel),
143  OpParamParameters.at(imodel));
144 
145  if (OpParamVolumesFound.size() > 0) {
146  for (unsigned int ivol = 0; ivol != OpParamVolumes.size(); ivol++) {
147  std::stringstream VolumeName;
148  VolumeName.flush();
149  VolumeName.str("OpParamVolume_");
150  VolumeName << ivol;
151 
152  G4Transform3D TheTransform = OpParamTransformationsFound.at(ivol);
153 
154  G4VSolid* TheSolid = OpParamVolumesFound.at(ivol)->GetSolid();
155  G4Material* TheMaterial = OpParamVolumesFound.at(ivol)->GetMaterial();
156  G4LogicalVolume* TheLogVolume =
157  new G4LogicalVolume(TheSolid, TheMaterial, VolumeName.str().c_str());
158 
159  G4PVPlacement* ThePlacement = new G4PVPlacement(
160  TheTransform, VolumeName.str().c_str(), TheLogVolume, ParallelWorld, false, 0);
161 
162  TheLogVolume->SetSensitiveDetector(ParamSD);
163 
164  // This line just suppressed a compiler warning
165  ThePlacement->GetTranslation();
166  }
167  }
168  }
169  }
170 
171  void
172  OpDetReadoutGeometry::FindVolumes(G4VPhysicalVolume* PhysicalVolume,
173  G4String OpDetName,
174  std::vector<G4Transform3D> TransformSoFar,
175  std::vector<G4LogicalVolume*>& OpDetVolumes,
176  std::vector<G4Transform3D>& OpDetTransformations)
177  {
178 
179  // Add the next layer of transformation to the vector
180  G4ThreeVector Translation = PhysicalVolume->GetObjectTranslation();
181  G4RotationMatrix Rotation = PhysicalVolume->GetObjectRotationValue();
182  G4Transform3D NextTransform(Rotation, Translation);
183 
184  TransformSoFar.push_back(NextTransform);
185 
186  // Check if this volume is a OpDet
187  G4String OpDetNameUnderscore = OpDetName + "_";
188  G4String VolumeName = PhysicalVolume->GetName();
189  if ((VolumeName == OpDetName) ||
190  (VolumeName.find(OpDetNameUnderscore, 0, OpDetNameUnderscore.length()) == 0)) {
191 
192  // We found a OpDet! Store its volume and global transformation
193  G4ThreeVector Trans(0, 0, 0);
194  G4RotationMatrix Rot(0, 0, 0);
195  G4Transform3D TotalTransform(Rot, Trans);
196  //for ( std::vector<G4Transform3D>::reverse_iterator it = TransformSoFar.rbegin();
197  // it != TransformSoFar.rend(); ++it )
198 
199  for (std::vector<G4Transform3D>::iterator it = TransformSoFar.begin();
200  it != TransformSoFar.end();
201  ++it) {
202  CLHEP::Hep3Vector trans = (*it).getTranslation();
203  CLHEP::HepRotation rot = (*it).getRotation();
204  TotalTransform = TotalTransform * (*it);
205  }
206 
207  OpDetVolumes.push_back(PhysicalVolume->GetLogicalVolume());
208  OpDetTransformations.push_back(TotalTransform);
209  }
210  else {
211  // We did not find a OpDet. Keep looking through daughters.
212  G4LogicalVolume* LogicalVolume = PhysicalVolume->GetLogicalVolume();
213 
214  // Loop through the daughters of the volume
215  G4int NumberDaughters = LogicalVolume->GetNoDaughters();
216  for (G4int i = 0; i != NumberDaughters; ++i) {
217  // Get the ith daughter volume
218  G4VPhysicalVolume* Daughter = LogicalVolume->GetDaughter(i);
219 
220  // Recursively step into this volume
221  FindVolumes(Daughter, OpDetName, TransformSoFar, OpDetVolumes, OpDetTransformations);
222  }
223  }
224  }
225 
226 }
void FindVolumes(G4VPhysicalVolume *, G4String, std::vector< G4Transform3D >, std::vector< G4LogicalVolume * > &, std::vector< G4Transform3D > &)
Store parameters for running LArG4.
std::vector< G4Transform3D > fOpDetTransformations
OpDetReadoutGeometry(G4String OpDetSensitiveName, const G4String name="OpDetReadoutGeometry", bool useLitePhotons=false)
bool const fUseLitePhotons
Pass-through option for sensitive detector.
std::vector< G4LogicalVolume * > fOpDetVolumes
void AddPhysicalVolume(G4VPhysicalVolume *)
Definition: OpDetLookup.cxx:96
static OpDetLookup * Instance()
Definition: OpDetLookup.cxx:33
OpDetLookup * TheOpDetLookup
Definition: OpDetLookup.cxx:24
then echo fcl name