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 // 26 // 27 // 28 // Author: Alfonso Mantero (Alfonso.Mantero@ge.infn.it) 29 // 30 // History: 31 // ----------- 32 // 08 Sep 2003 Alfonso Mantero Created 33 // ------------------------------------------------------------------- 34 35 #include "XrayFluoMercuryDetectorConstruction.hh" 36 #include "XrayFluoMercuryDetectorMessenger.hh" 37 #include "XrayFluoSD.hh" 38 #include "XrayFluoNistMaterials.hh" 39 #include "G4PhysicalConstants.hh" 40 #include "G4SystemOfUnits.hh" 41 #include "G4Material.hh" 42 #include "G4ThreeVector.hh" 43 #include "G4Box.hh" 44 #include "G4Sphere.hh" 45 #include "G4Tubs.hh" 46 #include "G4LogicalVolume.hh" 47 #include "G4PVPlacement.hh" 48 #include "G4TransportationManager.hh" 49 #include "G4SDManager.hh" 50 #include "G4RunManager.hh" 51 #include "G4VisAttributes.hh" 52 #include "G4Colour.hh" 53 #include "G4ios.hh" 54 #include "G4PVReplica.hh" 55 #include "G4UserLimits.hh" 56 #include "G4GeometryManager.hh" 57 #include "G4PhysicalVolumeStore.hh" 58 #include "G4LogicalVolumeStore.hh" 59 #include "G4SolidStore.hh" 60 #include "G4SDManager.hh" 61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 62 63 64 XrayFluoMercuryDetectorConstruction::XrayFluoMercuryDetectorConstruction() 65 : detectorType(0),mercuryGranularity(false), DeviceSizeX(0), 66 DeviceSizeY(0),DeviceThickness(0), 67 solidWorld(0),logicWorld(0),physiWorld(0), 68 solidHPGe(0),logicHPGe(0),physiHPGe(0), 69 solidScreen(0),logicScreen(0),physiScreen(0), 70 solidMercury (0),logicMercury(0),physiMercury (0), 71 solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0), 72 solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0), 73 solidPixel(0),logicPixel(0), physiPixel(0), 74 screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0), 75 pixelMaterial(0),mercuryMaterial(0), 76 defaultMaterial(0),HPGeSD(0) 77 78 { 79 materials = XrayFluoNistMaterials::GetInstance(); 80 81 DefineDefaultMaterials(); 82 83 NbOfPixelRows = 1; // should be 1 84 NbOfPixelColumns = 1; // should be 1 85 NbOfPixels = NbOfPixelRows*NbOfPixelColumns; 86 PixelSizeXY = std::sqrt(40.) * mm *0.5e6; // should be std::sqrt(40) * mm 87 PixelThickness = 3.5 * mm * 1e6; //should be 3.5 mm 88 89 G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl; 90 G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl; 91 92 ContactSizeXY = std::sqrt(40.) * mm * 0.5e6; //should be the same as PixelSize or lower 93 94 mercuryDia = 2 * 4880 * km ; 95 sunDia = 1390000 * km ; 96 mercurySunDistance = 57910000 * km ; 97 98 99 OhmicNegThickness = 0.005*mm *0.5e6 ; 100 OhmicPosThickness = 0.005*mm *0.5e6 ; 101 102 screenThickness = 5 * mm *0.5e6; 103 104 ThetaHPGe = 135. * deg ; 105 PhiHPGe = 225. * deg ; 106 107 108 distDe = (mercuryDia/2 + 400 * km); 109 110 distScreen = distDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ; 111 112 distOptic = distDe - 1.*m * 1e5;//!!! 113 114 opticThickness = 1.* cm *0.5e6; 115 opticDia = 21. * cm *0.5e6; 116 opticAperture = 1. * deg; 117 118 PixelCopyNb=0; 119 grainCopyNb=0; 120 G4String defaultDetectorType = "sili"; 121 ComputeApparateParameters(); 122 SetDetectorType(defaultDetectorType); 123 124 // create commands for interactive definition of the apparate 125 126 detectorMessenger = new XrayFluoMercuryDetectorMessenger(this); 127 G4cout << "XrayFluoMercuryDetectorConstruction created" << G4endl; 128 } 129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 130 131 132 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::instance = 0; 133 134 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::GetInstance() 135 { 136 if (instance == 0) 137 { 138 instance = new XrayFluoMercuryDetectorConstruction; 139 140 } 141 return instance; 142 } 143 144 void XrayFluoMercuryDetectorConstruction::SetDetectorType(G4String type) 145 { 146 147 if (type=="sili") 148 { 149 detectorType = XrayFluoSiLiDetectorType::GetInstance(); 150 } 151 else if (type=="hpge") 152 { 153 detectorType = XrayFluoHPGeDetectorType::GetInstance(); 154 } 155 else 156 { 157 G4ExceptionDescription execp; 158 execp << type + "detector type unknown"; 159 G4Exception("XrayFluoMercuryDetectorConstruction::SetDetectorType()","example-xray_fluorescence05", 160 FatalException, execp); 161 } 162 } 163 164 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 165 166 XrayFluoVDetectorType* XrayFluoMercuryDetectorConstruction::GetDetectorType() const 167 { 168 return detectorType; 169 } 170 171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 172 173 XrayFluoMercuryDetectorConstruction::~XrayFluoMercuryDetectorConstruction() 174 175 { 176 delete detectorMessenger; 177 delete detectorType; 178 G4cout << "XrayFluoMercuryDetectorConstruction deleted" << G4endl; 179 } 180 181 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 182 183 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::Construct() 184 { 185 return ConstructApparate(); 186 } 187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 188 189 void XrayFluoMercuryDetectorConstruction::DefineDefaultMaterials() 190 { 191 192 193 //define materials of the apparate 194 195 mercuryMaterial = materials->GetMaterial("Anorthosite"); 196 screenMaterial = materials->GetMaterial("G4_Pb"); 197 pixelMaterial = materials->GetMaterial("G4_Si"); 198 OhmicPosMaterial = materials->GetMaterial("G4_Cu"); 199 OhmicNegMaterial = materials->GetMaterial("G4_Pb"); 200 defaultMaterial = materials->GetMaterial("G4_Galactic"); 201 202 203 } 204 205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 206 207 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::ConstructApparate() 208 { 209 // complete the apparate parameters definition 210 211 ComputeApparateParameters(); 212 213 //world 214 215 solidWorld = new G4Box("World", //its name 216 WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2); //its size 217 218 logicWorld = new G4LogicalVolume(solidWorld, //its solid 219 defaultMaterial, //its material 220 "World"); //its name 221 physiWorld = new G4PVPlacement(0, //no rotation 222 G4ThreeVector(), //at (0,0,0) 223 "World", //its name 224 logicWorld, //its logical volume 225 0, //its mother volume 226 false, //no boolean operation 227 0); //copy number 228 229 //detector 230 231 solidHPGe = 0; physiHPGe = 0; logicHPGe=0; 232 solidPixel=0; logicPixel=0; physiPixel=0; 233 234 if (DeviceThickness > 0.) 235 { 236 solidHPGe = new G4Box("HPGeDetector", //its name 237 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);//size 238 239 240 logicHPGe = new G4LogicalVolume(solidHPGe, //its solid 241 defaultMaterial, //its material 242 "HPGeDetector"); //its name 243 244 zRotPhiHPGe.rotateX(PhiHPGe); 245 G4double x,y,z; 246 247 z = distDe * std::cos(ThetaHPGe); 248 y = distScreen * std::sin(ThetaHPGe); 249 x = 0.*cm; 250 251 physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 252 "HPGeDetector", //its name 253 logicHPGe, //its logical volume 254 physiWorld, //its mother volume 255 false, //no boolean operation 256 0); //copy number 257 } 258 // Pixel 259 260 261 262 263 for ( G4int j=0; j < NbOfPixelColumns ; j++ ) 264 { for ( G4int i=0; i < NbOfPixelRows ; i++ ) 265 { 266 solidPixel=0; logicPixel=0; physiPixel=0; 267 if (PixelThickness > 0.) 268 solidPixel = new G4Box("Pixel", 269 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2); 270 271 logicPixel = new G4LogicalVolume(solidPixel, 272 pixelMaterial, //its material 273 "Pixel"); //its name 274 275 /* 276 zRotPhiHPGe.rotateX(PhiHPGe); 277 G4double x,y,z; 278 z = distDe * std::cos(ThetaHPGe); 279 y =distDe * std::sin(ThetaHPGe); 280 x = 0.*cm;*/ 281 physiPixel = new G4PVPlacement(0, 282 G4ThreeVector(0, 283 i*PixelSizeXY, 284 j*PixelSizeXY ), 285 "Pixel", 286 logicPixel, //its logical volume 287 physiHPGe, //its mother volume 288 false, //no boolean operation 289 PixelCopyNb);//copy number 290 291 292 293 294 295 296 // OhmicNeg 297 298 solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0; 299 300 if (OhmicNegThickness > 0.) 301 { solidOhmicNeg = new G4Box("OhmicNeg", //its name 302 PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2); 303 304 logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg, //its solid 305 OhmicNegMaterial, //its material 306 "OhmicNeg"); //its name 307 308 physiOhmicNeg = new G4PVPlacement(0, 309 G4ThreeVector 310 (0., 311 0., 312 (PixelThickness+OhmicNegThickness)/2), 313 "OhmicNeg", //its name 314 logicOhmicNeg, //its logical volume 315 physiHPGe, //its mother 316 false, //no boulean operat 317 PixelCopyNb); //copy number 318 319 } 320 // OhmicPos 321 solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0; 322 323 if (OhmicPosThickness > 0.) 324 { solidOhmicPos = new G4Box("OhmicPos", //its name 325 PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2); 326 327 logicOhmicPos = new G4LogicalVolume(solidOhmicPos, //its solid 328 OhmicPosMaterial, //its material 329 "OhmicPos"); //its name 330 331 physiOhmicPos = new G4PVPlacement(0, 332 G4ThreeVector(0., 333 0., 334 (-PixelThickness-OhmicPosThickness)/2), 335 "OhmicPos", 336 logicOhmicPos, 337 physiHPGe, 338 false, 339 PixelCopyNb); 340 341 } 342 343 PixelCopyNb += PixelCopyNb; 344 G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl; 345 } 346 347 } 348 349 // Optics 350 351 if (DeviceThickness > 0.) 352 { 353 solidOptic = new G4Tubs("DetectorOptic", //its name 354 0.,opticDia/2, opticThickness, 0.,2.*pi);//size 355 356 357 logicOptic = new G4LogicalVolume(solidOptic, //its solid 358 defaultMaterial, //its material 359 "DetectorOptic"); //its name 360 361 //zRotPhiHPGe.rotateX(PhiHPGe); 362 G4double x,y,z; 363 z = distOptic * std::cos(ThetaHPGe); 364 y = distOptic * std::sin(ThetaHPGe); 365 x = 0.*cm; 366 physiOptic = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 367 "DetectorOptic", //its name 368 logicOptic, //its logical volume 369 physiWorld, //its mother volume 370 false, //no boolean operation 371 0); //copy number 372 } 373 374 375 // Screen 376 377 if (DeviceThickness > 0.) 378 { 379 solidScreen = new G4Box("DetectorScreen", //its name 380 screenSizeXY/2,screenSizeXY/2,screenThickness/2);//size 381 382 383 logicScreen = new G4LogicalVolume(solidScreen, //its solid 384 defaultMaterial, //its material 385 "DetectorScreen"); //its name 386 387 //zRotPhiHPGe.rotateX(PhiHPGe); 388 G4double x,y,z; 389 G4cout << "distScreen: "<< distScreen/m <<G4endl; 390 z = distScreen * std::cos(ThetaHPGe); 391 y = distScreen * std::sin(ThetaHPGe); 392 x = 0.*cm; 393 physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 394 "DetectorScreen", //its name 395 logicScreen, //its logical volume 396 physiWorld, //its mother volume 397 false, //no boolean operation 398 0); //copy number 399 } 400 401 //Mercury 402 403 404 solidMercury=0; logicMercury=0; physiMercury=0; 405 if (mercuryDia > 0.) 406 { 407 408 409 410 411 412 413 solidMercury = new G4Sphere("Mercury",0.,mercuryDia/2., 0., twopi, 0., pi); 414 415 logicMercury= new G4LogicalVolume(solidMercury, //its solid 416 mercuryMaterial, //its material 417 "Mercury"); //its name 418 419 physiMercury = new G4PVPlacement(0, //no rotation 420 G4ThreeVector(), //at (0,0,0) 421 "Mercury", //its name 422 logicMercury, //its logical volume 423 physiWorld, //its mother volume 424 false, //no boolean operation 425 0); //copy number 426 427 } 428 429 430 // Visualization attributes 431 432 433 logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible()); 434 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); 435 G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. )); 436 G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. )); 437 G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. , 255/255. )); 438 G4VisAttributes * grayc= new G4VisAttributes( G4Colour(128/255. , 128/255. , 128/255. )); 439 G4VisAttributes * darkGray= new G4VisAttributes( G4Colour(95/255. , 95/255. , 95/255. )); 440 //G4VisAttributes * green= new G4VisAttributes( G4Colour(25/255. , 255/255. , 25/255. )); 441 yellow->SetVisibility(true); 442 yellow->SetForceSolid(true); 443 red->SetVisibility(true); 444 red->SetForceSolid(true); 445 blue->SetVisibility(true); 446 grayc->SetVisibility(true); 447 grayc->SetForceSolid(true); 448 simpleBoxVisAtt->SetVisibility(true); 449 450 //logicWorld->SetVisAttributes (simpleBoxVisAtt); 451 452 logicPixel->SetVisAttributes(red); 453 logicHPGe->SetVisAttributes(G4VisAttributes::GetInvisible()); 454 455 logicMercury->SetVisAttributes(darkGray); 456 457 458 logicScreen->SetVisAttributes(red); 459 logicOhmicNeg->SetVisAttributes(yellow); 460 logicOhmicPos->SetVisAttributes(yellow); 461 logicOptic->SetVisAttributes(grayc); 462 463 464 if (mercuryGranularity) logicGrain->SetVisAttributes(grayc); 465 466 //always return the physical World 467 468 PrintApparateParameters(); 469 470 return physiWorld; 471 } 472 473 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 474 475 void XrayFluoMercuryDetectorConstruction::ConstructSDandField() 476 { 477 // 478 // Sensitive Detectors 479 // 480 if (HPGeSD.Get() == 0) 481 { 482 XrayFluoSD* SD = new XrayFluoSD ("HPGeSD",this); 483 HPGeSD.Put( SD ); 484 } 485 G4SDManager::GetSDMpointer()->AddNewDetector(HPGeSD.Get()); 486 if (logicPixel) 487 SetSensitiveDetector(logicPixel,HPGeSD.Get()); 488 } 489 490 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 491 492 void XrayFluoMercuryDetectorConstruction::PrintApparateParameters() 493 { 494 G4cout << "-----------------------------------------------------------------------" 495 << G4endl 496 << "The mercury is a sphere whose diamter is: " 497 << G4endl 498 << mercuryDia/km 499 << " Km " 500 << G4endl 501 <<" Material: " << logicMercury->GetMaterial()->GetName() 502 <<G4endl 503 <<"The Detector is a slice " << DeviceThickness/(1.e-6*m) 504 << " micron thick of " << pixelMaterial->GetName()<<G4endl 505 <<"-------------------------------------------------------------------------" 506 << G4endl; 507 } 508 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 509 510 void XrayFluoMercuryDetectorConstruction::UpdateGeometry() 511 { 512 513 G4GeometryManager::GetInstance()->OpenGeometry(); 514 G4PhysicalVolumeStore::Clean(); 515 G4LogicalVolumeStore::Clean(); 516 G4SolidStore::Clean(); 517 518 zRotPhiHPGe.rotateX(-1.*PhiHPGe); 519 ComputeApparateParameters(); 520 521 //Triggers a new call of Construct() and of all the geometry resets. 522 G4RunManager::GetRunManager()->ReinitializeGeometry(); 523 524 } 525 526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 527 528 void XrayFluoMercuryDetectorConstruction::SetMercuryMaterial(G4String newMaterial) 529 { 530 G4cout << "New Mercury Material: " << newMaterial << G4endl; 531 logicMercury->SetMaterial(materials->GetMaterial(newMaterial)); 532 PrintApparateParameters(); 533 //GeometryHasBeenModified is called by the messenger 534 } 535 536 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 537 538 539 540 541 542 543 544 545 546 547 548