Geant4 Cross Reference |
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 // g 26 /// \file persistency/gdml/G02/src/G02DetectorConstruction.cc 27 /// \brief Implementation of the G02DetectorConstruction class 28 // 29 // 30 // 31 // Class G02DetectorConstruction implementation 32 // 33 // ---------------------------------------------------------------------------- 34 35 #include "G02DetectorConstruction.hh" 36 37 // Geant4 includes 38 // 39 #include "G4GeometryManager.hh" 40 #include "G4VisAttributes.hh" 41 #include "globals.hh" 42 43 // Materials 44 // 45 #include "G4Material.hh" 46 47 // Geometry includes 48 // 49 #include "G4Box.hh" 50 #include "G4LogicalVolume.hh" 51 #include "G4PVParameterised.hh" 52 #include "G4PVPlacement.hh" 53 #include "G4Tubs.hh" 54 #include "G4VPhysicalVolume.hh" 55 56 // Reflected solids 57 // 58 #include "G4AffineTransform.hh" 59 #include "G4DisplacedSolid.hh" 60 #include "G4ReflectedSolid.hh" 61 #include "G4ReflectionFactory.hh" 62 #include "G4RotationMatrix.hh" 63 #include "G4Transform3D.hh" 64 65 // Assembly volumes 66 // 67 #include "G4AssemblyVolume.hh" 68 69 // Volume parameterisations 70 // 71 #include "G02ChamberParameterisation.hh" 72 73 // Messenger 74 // 75 #include "G02DetectorMessenger.hh" 76 77 // GDML parser include 78 // 79 #include "G4GDMLParser.hh" 80 #include "G4PhysicalConstants.hh" 81 #include "G4SystemOfUnits.hh" 82 83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 84 // 85 // Constructor 86 // 87 G02DetectorConstruction::G02DetectorConstruction() 88 : G4VUserDetectorConstruction(), fAir(0), fAluminum(0), fPb(0), fXenon(0), fDetectorMessenger(0) 89 { 90 fExpHall_x = 5. * m; 91 92 fReadFile = "test.gdml"; 93 fWriteFile = "wtest.gdml"; 94 fStepFile = "mbb"; 95 fWritingChoice = 1; 96 97 fDetectorMessenger = new G02DetectorMessenger(this); 98 } 99 100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 101 // 102 // Destructor 103 // 104 G02DetectorConstruction::~G02DetectorConstruction() 105 { 106 if (fDetectorMessenger) delete fDetectorMessenger; 107 } 108 109 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 110 // 111 // Constructs geometries and materials 112 // 113 G4VPhysicalVolume* G02DetectorConstruction::Construct() 114 { 115 // Writing or Reading of Geometry using G4GDML 116 117 G4VPhysicalVolume* fWorldPhysVol; 118 119 if (fWritingChoice == 0) { 120 // **** LOOK HERE*** FOR READING GDML FILES 121 // 122 123 // ACTIVATING OVERLAP CHECK when read volumes are placed. 124 // Can take long time in case of complex geometries 125 // 126 // fParser.SetOverlapCheck(true); 127 128 fParser.Read(fReadFile); 129 130 // READING GDML FILES OPTION: 2nd Boolean argument "Validate". 131 // Flag to "false" disables check with the Schema when reading GDML file. 132 // See the GDML Documentation for more information. 133 // 134 // fParser.Read(fReadFile,false); 135 136 // Prints the material information 137 // 138 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 139 140 // Giving World Physical Volume from GDML Parser 141 // 142 fWorldPhysVol = fParser.GetWorldVolume(); 143 } 144 else if (fWritingChoice == 1) { 145 // **** LOOK HERE*** FOR WRITING GDML FILES 146 // Detector Construction and WRITING to GDML 147 // 148 ListOfMaterials(); 149 fWorldPhysVol = ConstructDetector(); 150 151 // OPTION: TO ADD MODULE AT DEPTH LEVEL ... 152 // 153 // Can be a integer or a pointer to the top Physical Volume: 154 // 155 // G4int depth=1; 156 // fParser.AddModule(depth); 157 158 // OPTION: SETTING ADDITION OF POINTER TO NAME TO FALSE 159 // 160 // By default, written names in GDML consist of the given name with 161 // appended the pointer reference to it, in order to make it unique. 162 // Naming policy can be changed by using the following method, or 163 // calling Write with additional Boolean argument to "false". 164 // NOTE: you have to be sure not to have duplication of names in your 165 // Geometry Setup. 166 // 167 // fParser.SetAddPointerToName(false); 168 // 169 // or 170 // 171 // fParser.Write(fWriteFile, fWorldPhysVol, false); 172 173 // OPTION: SET MAXIMUM LEVEL TO EXPORT (REDUCED TREE)... 174 // 175 // Can be a integer greater than zero: 176 // 177 // G4int maxlevel=3; 178 // fParser.SetMaxExportLevel(maxlevel); 179 180 // Writing Geometry to GDML File 181 // 182 fParser.Write(fWriteFile, fWorldPhysVol); 183 184 // OPTION: SPECIFYING THE SCHEMA LOCATION 185 // 186 // When writing GDML file the default the Schema Location from the 187 // GDML web site will be used: 188 // "http://cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd" 189 // 190 // NOTE: GDML Schema is distributed in Geant4 in the directory: 191 // $G4INSTALL/source/persistency/gdml/schema 192 // 193 // You can change the Schema path by adding a parameter to the Write 194 // command, as follows: 195 // 196 // fParser.Write(fWriteFile, fWorldPhysVol, "your-path-to-schema/gdml.xsd"); 197 } 198 else // Demonstration how to Read STEP files using GDML 199 { 200 // Some printout... 201 // 202 ListOfMaterials(); 203 204 // Arbitrary values that should enclose any reasonable geometry 205 // 206 const G4double expHall_y = fExpHall_x / 50.; 207 const G4double expHall_z = fExpHall_x / 50.; 208 209 // Create the hall 210 // 211 G4Box* experimentalHallBox = new G4Box("ExpHallBox", fExpHall_x / 50., expHall_y, expHall_z); 212 G4LogicalVolume* experimentalHallLV = 213 new G4LogicalVolume(experimentalHallBox, fAir, "ExpHallLV"); 214 fWorldPhysVol = new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), experimentalHallLV, 215 "ExpHallPhys", 0, false, 0); 216 217 // G02DetectorConstruction via reading STEP File 218 // 219 G4LogicalVolume* LogicalVolST = fParser.ParseST(fStepFile, fAir, fAluminum); 220 221 // Placement inside of the hall 222 // 223 new G4PVPlacement(0, G4ThreeVector(10.0, 0.0, 0.0), LogicalVolST, "StepPhys", 224 experimentalHallLV, false, 0); 225 } 226 227 // Set Visualization attributes to world 228 // 229 G4VisAttributes* BoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0)); 230 fWorldPhysVol->GetLogicalVolume()->SetVisAttributes(BoxVisAtt); 231 232 return fWorldPhysVol; 233 } 234 235 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 236 // 237 // Utility to build and list necessary materials 238 // 239 void G02DetectorConstruction::ListOfMaterials() 240 { 241 G4double a; // atomic mass 242 G4double z; // atomic number 243 G4double density, temperature, pressure; 244 G4double fractionmass; 245 G4String name, symbol; 246 G4int ncomponents; 247 248 // Elements needed for the materials 249 250 a = 14.01 * g / mole; 251 G4Element* elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a); 252 253 a = 16.00 * g / mole; 254 G4Element* elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a); 255 256 a = 26.98 * g / mole; 257 G4Element* elAl = new G4Element(name = "Aluminum", symbol = "Al", z = 13., a); 258 259 // Print the Element information 260 // 261 G4cout << *(G4Element::GetElementTable()) << G4endl; 262 263 // Air 264 // 265 density = 1.29 * mg / cm3; 266 fAir = new G4Material(name = "Air", density, ncomponents = 2); 267 fAir->AddElement(elN, fractionmass = 0.7); 268 fAir->AddElement(elO, fractionmass = 0.3); 269 270 // Aluminum 271 // 272 density = 2.70 * g / cm3; 273 fAluminum = new G4Material(name = "Aluminum", density, ncomponents = 1); 274 fAluminum->AddElement(elAl, fractionmass = 1.0); 275 276 // Lead 277 // 278 fPb = new G4Material("Lead", z = 82., a = 207.19 * g / mole, density = 11.35 * g / cm3); 279 280 // Xenon gas 281 // 282 fXenon = new G4Material("XenonGas", z = 54., a = 131.29 * g / mole, density = 5.458 * mg / cm3, 283 kStateGas, temperature = 293.15 * kelvin, pressure = 1 * atmosphere); 284 285 // Prints the material information 286 // 287 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 288 } 289 290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 291 // 292 // Detector Construction 293 // 294 // Detector consist from DetectorBox, Conrol Room and 4 SubDetectors 295 // SubDetectors1 and 2 show how to use Reflection Factory and Assembly 296 // SubDetectors 3 and 4 show how to use Parameterisation 297 // 298 G4VPhysicalVolume* G02DetectorConstruction::ConstructDetector() 299 { 300 // Arbitary values that should enclose any reasonable geometry 301 // 302 const G4double expHall_y = fExpHall_x; 303 const G4double expHall_z = fExpHall_x; 304 305 // Create the hall 306 // 307 G4Box* experimentalHallBox = new G4Box("ExpHallBox", fExpHall_x, expHall_y, expHall_z); 308 G4LogicalVolume* experimentalHallLV = new G4LogicalVolume(experimentalHallBox, fAir, "ExpHallLV"); 309 G4PVPlacement* experimentalHallPhys = new G4PVPlacement( 310 0, G4ThreeVector(0.0, 0.0, 0.0), experimentalHallLV, "ExpHallPhys", 0, false, 0); 311 312 // G02DetectorConstruction 313 314 const G4double det_x = fExpHall_x * 0.8; 315 const G4double det_y = fExpHall_x * 0.7; 316 const G4double det_z = det_y; 317 318 // Create the detector box 319 // 320 G4Box* detectorBox = new G4Box("detectorBox", det_x, det_y, det_z); 321 G4LogicalVolume* detectorLV = new G4LogicalVolume(detectorBox, fAir, "detLV"); 322 // G4PVPlacement * detectorPhys = 323 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), detectorLV, "detPhys", experimentalHallLV, 324 false, 0); 325 326 // Create the Control room box 327 // 328 const G4double room_x = fExpHall_x / 20.; 329 const G4double room_y = room_x; 330 const G4double room_z = room_x; 331 332 G4Box* roomBox = new G4Box("roomBox", room_x, room_y, room_z); 333 G4LogicalVolume* roomLV = new G4LogicalVolume(roomBox, fAir, "roomLV"); 334 // G4PVPlacement * roomPhys = 335 new G4PVPlacement(0, G4ThreeVector(fExpHall_x - room_x - 10., 0.0, 0.0), roomLV, "roomPhys", 336 experimentalHallLV, false, 0); 337 338 // SubDetector1 339 // 340 const G4double bigL = fExpHall_x / 5. + 50.; 341 G4LogicalVolume* subDetectorLV1 = ConstructSubDetector1(); 342 // G4PVPlacement * detPhys1 = 343 new G4PVPlacement(0, G4ThreeVector(bigL, 0.0, 0.0), subDetectorLV1, "PhysSubDetector1", 344 detectorLV, false, 0); 345 346 // 347 // LOOK HERE FOR REFLECTIONS 348 // 349 350 // SubDetector2 351 // 352 G4Translate3D translation(-bigL, 0., 0.); 353 G4RotationMatrix* rotD3 = new G4RotationMatrix(); 354 G4Transform3D rotation = G4Rotate3D(*rotD3); 355 G4ReflectX3D reflection; 356 G4Transform3D transform = translation * rotation * reflection; 357 358 // Place the reflected part using G4ReflectionFactory 359 // 360 G4ReflectionFactory::Instance()->Place(transform, "reflSubDetector", subDetectorLV1, detectorLV, 361 false, 0); 362 363 // SubDetector3 364 // 365 G4LogicalVolume* subDetectorLV3 = ConstructSubDetector2(); 366 // G4PVPlacement * detPhys3 = 367 new G4PVPlacement(0, G4ThreeVector(0.0, bigL, 0.0), subDetectorLV3, "PhysSubDetectorFirst3", 368 detectorLV, false, 0); 369 370 // SubDetector4, placement of parameterised chambers 371 // 372 G4LogicalVolume* subDetectorLV4 = ConstructSubDetector2(); 373 G4LogicalVolume* subChamberLV = ConstructParametrisationChamber(); 374 // G4PVPlacement * detChamb = 375 new G4PVPlacement(0, G4ThreeVector(0, 0.0, 0.0), subChamberLV, "AssemblyPhys", subDetectorLV4, 376 false, 0); 377 // G4PVPlacement * detPhys4 = 378 new G4PVPlacement(0, G4ThreeVector(0.0, -bigL, 0.0), subDetectorLV4, "PhysSubDetectorSecond3", 379 detectorLV, false, 0); 380 381 return experimentalHallPhys; 382 } 383 384 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 385 // 386 // SubDetector1 387 // 388 G4LogicalVolume* G02DetectorConstruction::ConstructSubDetector1() 389 { 390 const G4double sub_x = fExpHall_x / 5.; 391 const G4double sub_y = sub_x; 392 393 // Create the hall 394 // 395 G4Tubs* subTub = new G4Tubs("subTub", 0., sub_x, sub_y, -90. * deg, 180 * deg); 396 G4LogicalVolume* subTubLV = new G4LogicalVolume(subTub, fPb, "tubLV"); 397 G4LogicalVolume* AssemblyLV = ConstructAssembly(); 398 // G4PVPlacement * detAss = 399 new G4PVPlacement(0, G4ThreeVector(sub_x / 3, 0.0, 0.0), AssemblyLV, "AssemblyPhys", subTubLV, 400 false, 0); 401 return subTubLV; 402 } 403 404 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 405 // 406 // SubDetector2 407 // 408 G4LogicalVolume* G02DetectorConstruction::ConstructSubDetector2() 409 { 410 const G4double sub_x = fExpHall_x / 10.; 411 const G4double sub_y = sub_x * 2.; 412 const G4double sub_z = sub_x; 413 414 // Create the hall 415 // 416 G4Box* detHallBox = new G4Box("detHallBox", sub_x, sub_y, sub_z); 417 G4LogicalVolume* detHallLV = new G4LogicalVolume(detHallBox, fAluminum, "detHallLV"); 418 419 return detHallLV; 420 } 421 422 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 423 // 424 // Assembly 425 // 426 G4LogicalVolume* G02DetectorConstruction::ConstructAssembly() 427 { 428 const G4double big_x = fExpHall_x / 17; 429 const G4double big_y = big_x; 430 const G4double big_z = big_x; 431 432 // Create the Box 433 // 434 G4Box* OuterBox = new G4Box("OuterBox", big_x, big_y, big_z); 435 G4LogicalVolume* OuterBoxLV = new G4LogicalVolume(OuterBox, fAir, "OuterBoxLV"); 436 // G4PVPlacement * OuterBoxPhys = 437 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), OuterBoxLV, "OuterBoxPhys", 0, false, 0); 438 439 // The aluminum object's logical volume 440 // 441 const G4double bigL = big_x / 2.5; 442 const G4double medL = big_x / 8; 443 const G4double smalL = big_x / 12; 444 445 G4Box* BigBox = new G4Box("BBox", bigL, bigL, bigL); 446 G4LogicalVolume* BigBoxLV = new G4LogicalVolume(BigBox, fAluminum, "AlBigBoxLV"); 447 G4Box* MedBox = new G4Box("MBox", medL, medL, medL); 448 G4LogicalVolume* MedBoxLV1 = new G4LogicalVolume(MedBox, fAluminum, "AlMedBoxLV1"); 449 G4Box* SmallBox = new G4Box("SBox", smalL, smalL, smalL); 450 G4LogicalVolume* SmallBoxLV = new G4LogicalVolume(SmallBox, fAluminum, "AlSmaBoxLV"); 451 452 const G4double bigPlace = bigL + 10.; 453 const G4double medPlace = medL + 10.; 454 // G4PVPlacement * BigBoxPhys = 455 new G4PVPlacement(0, G4ThreeVector(bigPlace, 0.0, 0.0), BigBoxLV, "AlPhysBig", OuterBoxLV, false, 456 0); 457 458 // Construction of Tub 459 // 460 G4Tubs* BigTube = new G4Tubs("BTube", 0, smalL, smalL, -pi / 2., pi); 461 462 // Construction of Reflection of Tub 463 // 464 G4ReflectX3D Xreflection; 465 G4Translate3D translation(-bigPlace, 0., 0.); 466 G4Transform3D transform = Xreflection; 467 468 G4ReflectedSolid* ReflBig = new G4ReflectedSolid("Refll_Big", BigTube, transform); 469 G4LogicalVolume* ReflBigLV = new G4LogicalVolume(ReflBig, fXenon, "ReflBigAl"); 470 new G4PVPlacement(0, G4ThreeVector(0., 0.0, 0.0), ReflBigLV, "AlPhysBigTube", SmallBoxLV, false, 471 0); 472 // 473 // LOOK HERE FOR ASSEMBLY 474 // 475 476 // create Assembly of Boxes and Tubs 477 // 478 G4AssemblyVolume* assembly = new G4AssemblyVolume(); 479 G4RotationMatrix* rot = new G4RotationMatrix(); 480 G4ThreeVector posBig(-bigPlace, 0, 0); 481 G4ThreeVector posBig0(bigPlace / 4, 0, 0); 482 G4ThreeVector posMed(-medPlace, 0, 0); 483 G4ThreeVector posMed0(medPlace, 0, 0); 484 G4ThreeVector position(0., 0., 0.); 485 486 // Add to Assembly the MediumBox1 487 // 488 assembly->AddPlacedVolume(MedBoxLV1, posMed0, rot); 489 490 // Add to Assembly the Small Box 491 // 492 assembly->AddPlacedVolume(SmallBoxLV, posMed, rot); 493 494 // Place the Assembly 495 // 496 assembly->MakeImprint(BigBoxLV, posBig0, rot, 0); 497 498 // 499 // LOOK HERE FOR ASSEMBLY with REFLECTION 500 // 501 502 G4Translate3D translation1(-bigPlace, 0., 0.); 503 G4RotationMatrix* rotD3 = new G4RotationMatrix(); 504 G4Transform3D rotation = G4Rotate3D(*rotD3); 505 G4ReflectX3D reflection; 506 G4Transform3D transform1 = translation1 * rotation * reflection; 507 508 assembly->MakeImprint(OuterBoxLV, transform1, 0, 0); 509 510 return OuterBoxLV; 511 } 512 513 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 514 // 515 // Parameterised Chamber 516 // 517 G4LogicalVolume* G02DetectorConstruction::ConstructParametrisationChamber() 518 { 519 const G4double chamber_x = fExpHall_x / 12.; 520 const G4double chamber_y = chamber_x; 521 const G4double chamber_z = chamber_x; 522 523 // Create the hall 524 // 525 G4Box* paramChamberBox = new G4Box("ChamberBox", chamber_x, chamber_y, chamber_z); 526 G4LogicalVolume* paramChamberLV = new G4LogicalVolume(paramChamberBox, fAir, "ChamberLV"); 527 528 // Parametrisation Chamber (taken from N02 novice example) 529 // 530 G4int NbOfChambers = 5; 531 G4double ChamberWidth = 2 * cm; 532 G4double ChamberSpacing = 8 * cm; 533 G4double fTrackerLength = (NbOfChambers + 1) * ChamberSpacing; // Full length 534 G4double trackerSize = 0.5 * fTrackerLength; 535 536 // An example of parameterised volume 537 // dummy values for G4Box -- modified by parameterised volume 538 // 539 G4Box* solidChamber = new G4Box("chamber", 10 * cm, 10 * cm, 1 * cm); 540 G4LogicalVolume* logicChamber = new G4LogicalVolume(solidChamber, fAluminum, "Chamber", 0, 0, 0); 541 542 G4double firstPosition = -trackerSize + 0.5 * ChamberWidth; 543 G4double firstLength = fTrackerLength / 10; 544 G4double lastLength = fTrackerLength; 545 546 G4VPVParameterisation* chamberParam = 547 new G02ChamberParameterisation(NbOfChambers, // NoChambers 548 firstPosition, // Z of center of first 549 ChamberSpacing, // Z spacing of centers 550 ChamberWidth, // Width Chamber 551 firstLength, // lengthInitial 552 lastLength); // lengthFinal 553 // G4VPhysicalVolume* physiChamber = 554 new G4PVParameterised("Chamber", // their name 555 logicChamber, // their logical volume 556 paramChamberLV, // mother logical volume 557 kZAxis, // Are placed along this axis 558 NbOfChambers, // Number of chambers 559 chamberParam); // The parametrisation 560 return paramChamberLV; 561 } 562 563 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 564 // 565 // SetReadFile 566 // 567 void G02DetectorConstruction::SetReadFile(const G4String& File) 568 { 569 fReadFile = File; 570 fWritingChoice = 0; 571 } 572 573 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 574 // 575 // SetWriteFile 576 // 577 void G02DetectorConstruction::SetWriteFile(const G4String& File) 578 { 579 fWriteFile = File; 580 fWritingChoice = 1; 581 } 582 583 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 584 // 585 // SetStepFile 586 // 587 void G02DetectorConstruction::SetStepFile(const G4String& File) 588 { 589 fStepFile = File; 590 fWritingChoice = 3; 591 } 592