Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/geometry/transforms/src/DetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 /// \file DetectorConstruction.cc
 28 /// \brief Implementation of the DetectorConstruction class
 29 
 30 #include "DetectorConstruction.hh"
 31 
 32 #include "DetectorMessenger.hh"
 33 
 34 #include "G4GeometryManager.hh"
 35 #include "G4LogicalVolume.hh"
 36 #include "G4LogicalVolumeStore.hh"
 37 #include "G4Material.hh"
 38 #include "G4NistManager.hh"
 39 #include "G4PVPlacement.hh"
 40 #include "G4PhysicalConstants.hh"
 41 #include "G4PhysicalVolumeStore.hh"
 42 #include "G4ReflectionFactory.hh"
 43 #include "G4RotationMatrix.hh"
 44 #include "G4SolidStore.hh"
 45 #include "G4SystemOfUnits.hh"
 46 #include "G4Transform3D.hh"
 47 #include "G4Trd.hh"
 48 #include "G4Tubs.hh"
 49 
 50 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 51 
 52 DetectorConstruction::DetectorConstruction()
 53 {
 54   fMessenger = new DetectorMessenger(this);
 55 }
 56 
 57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 58 
 59 DetectorConstruction::~DetectorConstruction()
 60 {
 61   delete fMessenger;
 62 }
 63 
 64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 65 
 66 G4VPhysicalVolume* DetectorConstruction::Construct()
 67 {
 68   // Materials
 69   G4NistManager* nist = G4NistManager::Instance();
 70   G4Material* material = nist->FindOrBuildMaterial("G4_AIR");
 71 
 72   // Clean old geometry, if any
 73   //
 74   G4GeometryManager::GetInstance()->OpenGeometry();
 75   G4PhysicalVolumeStore::GetInstance()->Clean();
 76   G4LogicalVolumeStore::GetInstance()->Clean();
 77   G4SolidStore::GetInstance()->Clean();
 78   G4ReflectionFactory::Instance()->Clean();
 79 
 80   // World
 81   //
 82   G4double rmin = 0.;
 83   G4double rmax = 5 * cm;
 84   G4double hz = 5 * cm;
 85   G4double phiMin = 0.;
 86   G4double deltaPhi = 360 * degree;
 87 
 88   auto solidWorld = new G4Tubs("World",  // name
 89                                rmin, rmax, hz, phiMin, deltaPhi);  // size
 90 
 91   fWorldVolume = new G4LogicalVolume(solidWorld,  // solid
 92                                      material,  // material
 93                                      "World");  // name
 94 
 95   G4VPhysicalVolume* physiWorld = new G4PVPlacement(nullptr,  // no rotation
 96                                                     G4ThreeVector(),  // at (0,0,0)
 97                                                     fWorldVolume,  // logical volume
 98                                                     "World",  // name
 99                                                     nullptr,  // mother volume
100                                                     false,  // no boolean operation
101                                                     0);  // copy number
102 
103   // Trd volume
104   //
105   G4double dX1 = 1 * cm;
106   G4double dX2 = 1 * cm;
107   G4double dY1 = 1 * cm;
108   G4double dY2 = 2 * cm;
109   G4double dZ = 3 * cm;
110 
111   auto solidTrd = new G4Trd("trd",  // name
112                             dX1 / 2, dX2 / 2, dY1 / 2, dY2 / 2, dZ / 2);  // size
113 
114   fTrdVolume = new G4LogicalVolume(solidTrd,  // solid
115                                    material,  // material
116                                    "trd");  // name
117 
118   // Place Volume1 and Volume2 according to selected methods
119   //
120   switch (fMethod) {
121     case kWithDirectMatrix:
122       PlaceWithDirectMatrix();
123       break;
124     case kWithInverseMatrix:
125       PlaceWithInverseMatrix();
126       break;
127     case kWithAxialRotations:
128       PlaceWithAxialRotations();
129       break;
130     case kWithEulerAngles:
131       PlaceWithEulerAngles();
132       break;
133     case kWithReflections:
134       PlaceWithReflections();
135       break;
136     default:;
137       ;
138   }
139 
140   // Return the root volume
141   //
142   return physiWorld;
143 }
144 
145 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
146 
147 void DetectorConstruction::PlaceWithDirectMatrix()
148 {
149   G4double og = 3 * cm;
150 
151   // 1st position
152   //
153   G4double phi = 30 * deg;
154   // u, v, w are the daughter axes, projected on the mother frame
155   G4ThreeVector u = G4ThreeVector(0, 0, -1);
156   G4ThreeVector v = G4ThreeVector(-std::sin(phi), std::cos(phi), 0.);
157   G4ThreeVector w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
158   G4RotationMatrix rotm1 = G4RotationMatrix(u, v, w);
159   G4cout << "\n --> phi = " << phi / deg << " deg;  direct rotation matrix : ";
160   rotm1.print(G4cout);
161   G4ThreeVector position1 = og * w;
162   G4Transform3D transform1 = G4Transform3D(rotm1, position1);
163 
164   new G4PVPlacement(transform1,  // position, rotation
165                     fTrdVolume,  // logical volume
166                     "Trd",  // name
167                     fWorldVolume,  // mother volume
168                     false,  // no boolean operation
169                     1);  // copy number
170 
171   // 2nd position
172   //
173   phi = phi + 90 * deg;
174   v = G4ThreeVector(-std::sin(phi), std::cos(phi), 0.);
175   w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
176   G4RotationMatrix rotm2 = G4RotationMatrix(u, v, w);
177   G4ThreeVector position2 = og * w;
178   G4Transform3D transform2 = G4Transform3D(rotm2, position2);
179   new G4PVPlacement(transform2,  // position, rotation
180                     fTrdVolume,  // logical volume
181                     "Trd",  // name
182                     fWorldVolume,  // mother volume
183                     false,  // no boolean operation
184                     2);  // copy number
185 }
186 
187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
188 
189 void DetectorConstruction::PlaceWithInverseMatrix()
190 {
191   G4double og = 3 * cm;
192 
193   // 1st position
194   //
195   G4double phi = 30 * deg;
196   // u, v, w are the daughter axes, projected on the mother frame
197   G4ThreeVector u = G4ThreeVector(0, 0, -1);
198   G4ThreeVector v = G4ThreeVector(-std::sin(phi), std::cos(phi), 0.);
199   G4ThreeVector w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
200   G4RotationMatrix rotm1 = G4RotationMatrix(u, v, w);
201   auto rotm1Inv = new G4RotationMatrix(rotm1.inverse());
202   G4cout << "\n --> phi = " << phi / deg << " deg;  inverse rotation matrix : ";
203   rotm1Inv->print(G4cout);
204   G4ThreeVector position1 = og * w;
205 
206   new G4PVPlacement(rotm1Inv, position1,
207                     fTrdVolume,  // logical volume
208                     "Trd",  // name
209                     fWorldVolume,  // mother volume
210                     false,  // no boolean operation
211                     1);  // copy number
212 
213   // 2nd position
214   //
215   phi = phi + 90 * deg;
216   v = G4ThreeVector(-std::sin(phi), std::cos(phi), 0.);
217   w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
218   G4RotationMatrix rotm2 = G4RotationMatrix(u, v, w);
219   auto rotm2Inv = new G4RotationMatrix(rotm2.inverse());
220   G4ThreeVector position2 = og * w;
221 
222   new G4PVPlacement(rotm2Inv,  // rotation
223                     position2,  // position
224                     fTrdVolume,  // logical volume
225                     "Trd",  // name
226                     fWorldVolume,  // mother volume
227                     false,  // no boolean operation
228                     2);  // copy number
229 }
230 
231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
232 
233 void DetectorConstruction::PlaceWithAxialRotations()
234 {
235   G4double og = 3 * cm;
236 
237   // 1st position (with first G4PVPlacement constructor)
238   //
239   G4double phi = 30 * deg, theta = 90 * deg;
240   G4ThreeVector rotAxis = G4ThreeVector(std::sin(theta - pi / 2), 0., std::cos(theta - pi / 2));
241   G4RotationMatrix rotm1 = G4RotationMatrix();
242   rotm1.rotateY(theta);
243   rotm1.rotate(phi, rotAxis);
244   G4cout << "\n --> direct rotation matrix : "
245          << " theta = " << theta / deg << " deg;"
246          << " phi  = " << phi / deg << " deg;";
247   rotm1.print(G4cout);
248   G4ThreeVector w =
249     G4ThreeVector(std::sin(theta) * std::cos(phi), std::sin(phi), std::cos(theta) * std::cos(phi));
250   G4ThreeVector position1 = og * w;
251   G4Transform3D transform1(rotm1, position1);
252 
253   new G4PVPlacement(transform1,  // rotation,position
254                     fTrdVolume,  // logical volume
255                     "Trd",  // name
256                     fWorldVolume,  // mother volume
257                     false,  // no boolean operation
258                     1);  // copy number
259 
260   // 2nd position (with second G4PVPlacement constructor)
261   //
262   phi = phi + 90 * deg;
263   // rotm2Inv could be calculated with rotm2.inverse()
264   // but also by the following :
265   auto rotm2Inv = new G4RotationMatrix();
266   rotm2Inv->rotate(-phi, rotAxis);
267   rotm2Inv->rotateY(-theta);
268   w =
269     G4ThreeVector(std::sin(theta) * std::cos(phi), std::sin(phi), std::cos(theta) * std::cos(phi));
270   G4ThreeVector position2 = og * w;
271 
272   new G4PVPlacement(rotm2Inv,  // rotation
273                     position2,  // position
274                     fTrdVolume,  // logical volume
275                     "Trd",  // name
276                     fWorldVolume,  // mother volume
277                     false,  // no boolean operation
278                     2);  // copy number
279 }
280 
281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
282 
283 void DetectorConstruction::PlaceWithEulerAngles()
284 {
285   // definitions : mother frame = {x,y,z} ; daughter frame = {u,v,w}
286   //  n = node line = intercept of xy and uv planes
287   //  phi_euler   = (x,n) : precession
288   //  theta_euler = (z,w) : nutation
289   //  psi_euler   = (n,u) : proper rotation
290 
291   G4double og = 3 * cm;
292 
293   // 1st position (with first G4PVPlacement constructor)
294   //
295   G4double phi = 30 * deg;
296   G4double phi_euler = phi + pi / 2;
297   G4double theta_euler = 90 * deg;
298   G4double psi_euler = -90 * deg;
299   // attention : clhep Euler constructor build inverse matrix !
300   G4RotationMatrix rotm1Inv = G4RotationMatrix(phi_euler, theta_euler, psi_euler);
301   G4RotationMatrix rotm1 = rotm1Inv.inverse();
302   // remark : could be built as rotm1 = G4RotationMatrix(-psi, -theta, -phi)
303   G4cout << "\n --> phi = " << phi / deg << " deg;  direct rotation matrix : ";
304   rotm1.print(G4cout);
305   G4ThreeVector w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
306   G4ThreeVector position1 = og * w;
307   G4Transform3D transform1 = G4Transform3D(rotm1, position1);
308 
309   new G4PVPlacement(transform1,  // position, rotation
310                     fTrdVolume,  // logical volume
311                     "Trd",  // name
312                     fWorldVolume,  // mother volume
313                     false,  // no boolean operation
314                     1);  // copy number
315 
316   // 2nd position (with second G4PVPlacement constructor)
317   //
318   phi = phi + 90 * deg;
319 
320   phi_euler = phi + pi / 2;
321   auto rotm2Inv = new G4RotationMatrix(phi_euler, theta_euler, psi_euler);
322   w = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
323   G4ThreeVector position2 = og * w;
324 
325   new G4PVPlacement(rotm2Inv,  // rotation
326                     position2,  // position
327                     fTrdVolume,  // logical volume
328                     "Trd",  // name
329                     fWorldVolume,  // mother volume
330                     false,  // no boolean operation
331                     2);  // copy number
332 }
333 
334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
335 
336 void DetectorConstruction::PlaceWithReflections()
337 {
338   /// Placement with reflections.
339   /// In order to better show the reflection symmetry we do not apply
340   /// the rotation along Y axis.
341 
342   G4double og = 3 * cm;
343 
344   // Place first two positionz in z = + 3cm
345   //
346 
347   // 1st position
348   G4double phi = 30 * deg;
349   G4RotationMatrix rotm1;
350   // rotm1.rotateY(90*deg);
351   rotm1.rotateZ(phi);
352   G4ThreeVector uz = G4ThreeVector(std::cos(phi), std::sin(phi), 0);
353   G4ThreeVector position = og * uz;
354   G4Transform3D transform1(rotm1, position);
355   G4Transform3D translateZ = HepGeom::Translate3D(0, 0, 3. * cm);
356 
357   new G4PVPlacement(translateZ * transform1,  // rotation,position
358                     fTrdVolume,  // logical volume
359                     "Trd",  // name
360                     fWorldVolume,  // mother volume
361                     false,  // no boolean operation
362                     1);  // copy number
363 
364   // 2nd position
365   phi = phi + pi / 2;
366   G4RotationMatrix rotm2;
367   // rotm2.rotateY(90*deg);
368   rotm2.rotateZ(phi);
369   uz = G4ThreeVector(std::cos(phi), std::sin(phi), 0.);
370   position = og * uz;
371   G4Transform3D transform2 = G4Transform3D(rotm2, position);
372 
373   new G4PVPlacement(translateZ * transform2,  // rotation, position
374                     fTrdVolume,  // logical volume
375                     "Trd",  // name
376                     fWorldVolume,  // mother volume
377                     false,  // no boolean operation
378                     2);  // copy number
379 
380   // Place next two positionz in z = - 3cm with reflection
381   //
382 
383   // 3rd position
384   translateZ = HepGeom::Translate3D(0, 0, -3. * cm);
385   G4Transform3D reflect3D = HepGeom::ReflectZ3D();
386 
387   G4ReflectionFactory::Instance()->Place(translateZ * transform1 * reflect3D,  // rotation,position
388                                          "Trd",  // name
389                                          fTrdVolume,  // logical volume
390                                          fWorldVolume,  // mother volume
391                                          false,  // no boolean operation
392                                          3);  // copy number
393 
394   // 4rd position
395   G4ReflectionFactory::Instance()->Place(translateZ * transform2 * reflect3D,  // rotation,position
396                                          "Trd",  // name
397                                          fTrdVolume,  // logical volume
398                                          fWorldVolume,  // mother volume
399                                          false,  // no boolean operation
400                                          4);  // copy number
401 }
402 
403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
404 
405 #include "G4RunManager.hh"
406 
407 void DetectorConstruction::SetMethod(EMethod method)
408 {
409   fMethod = method;
410   G4RunManager::GetRunManager()->DefineWorldVolume(Construct());
411 }
412 
413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
414