Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 /// \file DetectorConstruction.cc 28 /// \brief Implementation of the DetectorConst 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........oo 51 52 DetectorConstruction::DetectorConstruction() 53 { 54 fMessenger = new DetectorMessenger(this); 55 } 56 57 //....oooOO0OOooo........oooOO0OOooo........oo 58 59 DetectorConstruction::~DetectorConstruction() 60 { 61 delete fMessenger; 62 } 63 64 //....oooOO0OOooo........oooOO0OOooo........oo 65 66 G4VPhysicalVolume* DetectorConstruction::Const 67 { 68 // Materials 69 G4NistManager* nist = G4NistManager::Instanc 70 G4Material* material = nist->FindOrBuildMate 71 72 // Clean old geometry, if any 73 // 74 G4GeometryManager::GetInstance()->OpenGeomet 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", // na 89 rmin, rmax, hz, 90 91 fWorldVolume = new G4LogicalVolume(solidWorl 92 material, 93 "World"); 94 95 G4VPhysicalVolume* physiWorld = new G4PVPlac 96 97 98 99 100 101 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, 113 114 fTrdVolume = new G4LogicalVolume(solidTrd, 115 material, 116 "trd"); // 117 118 // Place Volume1 and Volume2 according to se 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........oo 146 147 void DetectorConstruction::PlaceWithDirectMatr 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 155 G4ThreeVector u = G4ThreeVector(0, 0, -1); 156 G4ThreeVector v = G4ThreeVector(-std::sin(ph 157 G4ThreeVector w = G4ThreeVector(std::cos(phi 158 G4RotationMatrix rotm1 = G4RotationMatrix(u, 159 G4cout << "\n --> phi = " << phi / deg << " 160 rotm1.print(G4cout); 161 G4ThreeVector position1 = og * w; 162 G4Transform3D transform1 = G4Transform3D(rot 163 164 new G4PVPlacement(transform1, // position, 165 fTrdVolume, // logical vo 166 "Trd", // name 167 fWorldVolume, // mother v 168 false, // no boolean oper 169 1); // copy number 170 171 // 2nd position 172 // 173 phi = phi + 90 * deg; 174 v = G4ThreeVector(-std::sin(phi), std::cos(p 175 w = G4ThreeVector(std::cos(phi), std::sin(ph 176 G4RotationMatrix rotm2 = G4RotationMatrix(u, 177 G4ThreeVector position2 = og * w; 178 G4Transform3D transform2 = G4Transform3D(rot 179 new G4PVPlacement(transform2, // position, 180 fTrdVolume, // logical vo 181 "Trd", // name 182 fWorldVolume, // mother v 183 false, // no boolean oper 184 2); // copy number 185 } 186 187 //....oooOO0OOooo........oooOO0OOooo........oo 188 189 void DetectorConstruction::PlaceWithInverseMat 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 197 G4ThreeVector u = G4ThreeVector(0, 0, -1); 198 G4ThreeVector v = G4ThreeVector(-std::sin(ph 199 G4ThreeVector w = G4ThreeVector(std::cos(phi 200 G4RotationMatrix rotm1 = G4RotationMatrix(u, 201 auto rotm1Inv = new G4RotationMatrix(rotm1.i 202 G4cout << "\n --> phi = " << phi / deg << " 203 rotm1Inv->print(G4cout); 204 G4ThreeVector position1 = og * w; 205 206 new G4PVPlacement(rotm1Inv, position1, 207 fTrdVolume, // logical vo 208 "Trd", // name 209 fWorldVolume, // mother v 210 false, // no boolean oper 211 1); // copy number 212 213 // 2nd position 214 // 215 phi = phi + 90 * deg; 216 v = G4ThreeVector(-std::sin(phi), std::cos(p 217 w = G4ThreeVector(std::cos(phi), std::sin(ph 218 G4RotationMatrix rotm2 = G4RotationMatrix(u, 219 auto rotm2Inv = new G4RotationMatrix(rotm2.i 220 G4ThreeVector position2 = og * w; 221 222 new G4PVPlacement(rotm2Inv, // rotation 223 position2, // position 224 fTrdVolume, // logical vo 225 "Trd", // name 226 fWorldVolume, // mother v 227 false, // no boolean oper 228 2); // copy number 229 } 230 231 //....oooOO0OOooo........oooOO0OOooo........oo 232 233 void DetectorConstruction::PlaceWithAxialRotat 234 { 235 G4double og = 3 * cm; 236 237 // 1st position (with first G4PVPlacement co 238 // 239 G4double phi = 30 * deg, theta = 90 * deg; 240 G4ThreeVector rotAxis = G4ThreeVector(std::s 241 G4RotationMatrix rotm1 = G4RotationMatrix(); 242 rotm1.rotateY(theta); 243 rotm1.rotate(phi, rotAxis); 244 G4cout << "\n --> direct rotation matrix : " 245 << " theta = " << theta / deg << " de 246 << " phi = " << phi / deg << " deg;" 247 rotm1.print(G4cout); 248 G4ThreeVector w = 249 G4ThreeVector(std::sin(theta) * std::cos(p 250 G4ThreeVector position1 = og * w; 251 G4Transform3D transform1(rotm1, position1); 252 253 new G4PVPlacement(transform1, // rotation,p 254 fTrdVolume, // logical vo 255 "Trd", // name 256 fWorldVolume, // mother v 257 false, // no boolean oper 258 1); // copy number 259 260 // 2nd position (with second G4PVPlacement c 261 // 262 phi = phi + 90 * deg; 263 // rotm2Inv could be calculated with rotm2.i 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(p 270 G4ThreeVector position2 = og * w; 271 272 new G4PVPlacement(rotm2Inv, // rotation 273 position2, // position 274 fTrdVolume, // logical vo 275 "Trd", // name 276 fWorldVolume, // mother v 277 false, // no boolean oper 278 2); // copy number 279 } 280 281 //....oooOO0OOooo........oooOO0OOooo........oo 282 283 void DetectorConstruction::PlaceWithEulerAngle 284 { 285 // definitions : mother frame = {x,y,z} ; da 286 // n = node line = intercept of xy and uv p 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 co 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 300 G4RotationMatrix rotm1Inv = G4RotationMatrix 301 G4RotationMatrix rotm1 = rotm1Inv.inverse(); 302 // remark : could be built as rotm1 = G4Rota 303 G4cout << "\n --> phi = " << phi / deg << " 304 rotm1.print(G4cout); 305 G4ThreeVector w = G4ThreeVector(std::cos(phi 306 G4ThreeVector position1 = og * w; 307 G4Transform3D transform1 = G4Transform3D(rot 308 309 new G4PVPlacement(transform1, // position, 310 fTrdVolume, // logical vo 311 "Trd", // name 312 fWorldVolume, // mother v 313 false, // no boolean oper 314 1); // copy number 315 316 // 2nd position (with second G4PVPlacement c 317 // 318 phi = phi + 90 * deg; 319 320 phi_euler = phi + pi / 2; 321 auto rotm2Inv = new G4RotationMatrix(phi_eul 322 w = G4ThreeVector(std::cos(phi), std::sin(ph 323 G4ThreeVector position2 = og * w; 324 325 new G4PVPlacement(rotm2Inv, // rotation 326 position2, // position 327 fTrdVolume, // logical vo 328 "Trd", // name 329 fWorldVolume, // mother v 330 false, // no boolean oper 331 2); // copy number 332 } 333 334 //....oooOO0OOooo........oooOO0OOooo........oo 335 336 void DetectorConstruction::PlaceWithReflection 337 { 338 /// Placement with reflections. 339 /// In order to better show the reflection s 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(ph 353 G4ThreeVector position = og * uz; 354 G4Transform3D transform1(rotm1, position); 355 G4Transform3D translateZ = HepGeom::Translat 356 357 new G4PVPlacement(translateZ * transform1, 358 fTrdVolume, // logical vo 359 "Trd", // name 360 fWorldVolume, // mother v 361 false, // no boolean oper 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(p 370 position = og * uz; 371 G4Transform3D transform2 = G4Transform3D(rot 372 373 new G4PVPlacement(translateZ * transform2, 374 fTrdVolume, // logical vo 375 "Trd", // name 376 fWorldVolume, // mother v 377 false, // no boolean oper 378 2); // copy number 379 380 // Place next two positionz in z = - 3cm wit 381 // 382 383 // 3rd position 384 translateZ = HepGeom::Translate3D(0, 0, -3. 385 G4Transform3D reflect3D = HepGeom::ReflectZ3 386 387 G4ReflectionFactory::Instance()->Place(trans 388 "Trd" 389 fTrdV 390 fWorl 391 false 392 3); 393 394 // 4rd position 395 G4ReflectionFactory::Instance()->Place(trans 396 "Trd" 397 fTrdV 398 fWorl 399 false 400 4); 401 } 402 403 //....oooOO0OOooo........oooOO0OOooo........oo 404 405 #include "G4RunManager.hh" 406 407 void DetectorConstruction::SetMethod(EMethod m 408 { 409 fMethod = method; 410 G4RunManager::GetRunManager()->DefineWorldVo 411 } 412 413 //....oooOO0OOooo........oooOO0OOooo........oo 414