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 // 29 aug 2003 Alfonso Mantero Created 33 // ------------------------------------------------------------------- 34 35 #include "XrayFluoPlaneDetectorConstruction.hh" 36 #include "XrayFluoPlaneDetectorMessenger.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 "G4LogicalVolume.hh" 46 #include "G4PVPlacement.hh" 47 #include "G4TransportationManager.hh" 48 #include "G4SDManager.hh" 49 #include "G4RunManager.hh" 50 #include "G4VisAttributes.hh" 51 #include "G4Colour.hh" 52 #include "G4PVReplica.hh" 53 #include "G4UserLimits.hh" 54 #include "G4GeometryManager.hh" 55 #include "G4PhysicalVolumeStore.hh" 56 #include "G4LogicalVolumeStore.hh" 57 #include "G4SolidStore.hh" 58 #include "G4SDManager.hh" 59 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 61 62 63 XrayFluoPlaneDetectorConstruction::XrayFluoPlaneDetectorConstruction() 64 : detectorType(0),planeGranularity(false), DeviceSizeX(0), 65 DeviceSizeY(0),DeviceThickness(0), 66 solidWorld(0),logicWorld(0),physiWorld(0), 67 solidHPGe(0),logicHPGe(0),physiHPGe(0), 68 solidScreen(0),logicScreen(0),physiScreen(0), 69 solidPlane (0),logicPlane(0),physiPlane (0), 70 solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0), 71 solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0), 72 solidPixel(0),logicPixel(0), physiPixel(0), 73 screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0), 74 pixelMaterial(0),planeMaterial(0), 75 defaultMaterial(0),HPGeSD(0) 76 77 { 78 materials = XrayFluoNistMaterials::GetInstance(); 79 80 DefineDefaultMaterials(); 81 82 NbOfPixelRows = 1; // should be 1 83 NbOfPixelColumns = 1; // should be 1 84 NbOfPixels = NbOfPixelRows*NbOfPixelColumns; 85 PixelSizeXY = 5 * cm; // should be 5 86 PixelThickness = 3.5 * mm; //changed should be 3.5 mm 87 88 G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl; 89 G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl; 90 91 ContactSizeXY = 5 * cm; //should be the same as pixelSizeXY 92 planeThickness = 5 * cm; 93 planeSizeXY = 5. * m; 94 95 OhmicNegThickness = 0.005*mm; 96 OhmicPosThickness = 0.005*mm; 97 98 screenThickness = 5 * mm; 99 100 ThetaHPGe = 0. * deg; 101 PhiHPGe = 0. * deg; 102 103 104 DistDe = 0.5 * m; 105 106 distScreen = DistDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ; 107 108 grainDia = 1 * mm; 109 110 111 PixelCopyNb=0; 112 grainCopyNb=0; 113 G4String defaultDetectorType = "sili"; 114 ComputeApparateParameters(); 115 SetDetectorType(defaultDetectorType); 116 117 // create commands for interactive definition of the apparate 118 119 detectorMessenger = new XrayFluoPlaneDetectorMessenger(this); 120 G4cout << "XrayFluoPlaneDetectorConstruction created" << G4endl; 121 } 122 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 123 124 125 XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::instance = 0; 126 127 XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::GetInstance() 128 { 129 if (instance == 0) 130 { 131 instance = new XrayFluoPlaneDetectorConstruction; 132 133 } 134 return instance; 135 } 136 137 void XrayFluoPlaneDetectorConstruction::SetDetectorType(G4String type) 138 { 139 140 if (type=="sili") 141 { 142 detectorType = XrayFluoSiLiDetectorType::GetInstance(); 143 } 144 else if (type=="hpge") 145 { 146 detectorType = XrayFluoHPGeDetectorType::GetInstance(); 147 } 148 else 149 { 150 G4ExceptionDescription execp; 151 execp << type + "detector type unknown"; 152 G4Exception("XrayFluoPlaneDetectorConstruction::SetDetectorType()","example-xray_fluorescence03", 153 FatalException, execp); 154 } 155 } 156 157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 158 159 XrayFluoVDetectorType* XrayFluoPlaneDetectorConstruction::GetDetectorType() const 160 { 161 return detectorType; 162 } 163 164 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 165 166 XrayFluoPlaneDetectorConstruction::~XrayFluoPlaneDetectorConstruction() 167 168 { 169 delete detectorMessenger; 170 delete detectorType; 171 G4cout << "XrayFluoPlaneDetectorConstruction deleted" << G4endl; 172 } 173 174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 175 176 G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::Construct() 177 { 178 return ConstructApparate(); 179 } 180 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 181 182 void XrayFluoPlaneDetectorConstruction::DefineDefaultMaterials() 183 { 184 185 186 //define materials of the apparate 187 188 planeMaterial = materials->GetMaterial("Anorthosite"); 189 screenMaterial = materials->GetMaterial("G4_Pb"); 190 pixelMaterial = materials->GetMaterial("G4_Si"); 191 OhmicPosMaterial = materials->GetMaterial("G4_Cu"); 192 OhmicNegMaterial = materials->GetMaterial("G4_Pb"); 193 defaultMaterial = materials->GetMaterial("G4_Galactic"); 194 } 195 196 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 197 198 G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::ConstructApparate() 199 { 200 // complete the apparate parameters definition 201 202 //ComputeApparateParameters(); 203 204 //world 205 206 solidWorld = new G4Box("World", //its name 207 WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2); //its size 208 209 logicWorld = new G4LogicalVolume(solidWorld, //its solid 210 defaultMaterial, //its material 211 "World"); //its name 212 physiWorld = new G4PVPlacement(0, //no rotation 213 G4ThreeVector(), //at (0,0,0) 214 "World", //its name 215 logicWorld, //its logical volume 216 0, //its mother volume 217 false, //no boolean operation 218 0); //copy number 219 220 //detector 221 222 solidHPGe = 0; physiHPGe = 0; logicHPGe=0; 223 solidPixel=0; logicPixel=0; physiPixel=0; 224 225 if (DeviceThickness > 0.) 226 { 227 solidHPGe = new G4Box("HPGeDetector", //its name 228 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);//size 229 230 231 logicHPGe = new G4LogicalVolume(solidHPGe, //its solid 232 defaultMaterial, //its material 233 "HPGeDetector"); //its name 234 235 zRotPhiHPGe.rotateX(PhiHPGe); 236 G4double x,y,z; 237 238 z = -1. * DistDe; //* std::cos(ThetaHPGe); 239 y = 0.*cm; //distScreen * std::sin(ThetaHPGe); 240 x = 0.*cm; 241 242 physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 243 "HPGeDetector", //its name 244 logicHPGe, //its logical volume 245 physiWorld, //its mother volume 246 false, //no boolean operation 247 0); //copy number 248 } 249 // Pixel 250 251 252 253 254 for ( G4int j=0; j < NbOfPixelColumns ; j++ ) 255 { for ( G4int i=0; i < NbOfPixelRows ; i++ ) 256 { 257 solidPixel=0; logicPixel=0; physiPixel=0; 258 if (PixelThickness > 0.) 259 solidPixel = new G4Box("Pixel", 260 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2); 261 262 logicPixel = new G4LogicalVolume(solidPixel, 263 pixelMaterial, //its material 264 "Pixel"); //its name 265 266 /* 267 zRotPhiHPGe.rotateX(PhiHPGe); 268 G4double x,y,z; 269 z = DistDe * std::cos(ThetaHPGe); 270 y =DistDe * std::sin(ThetaHPGe); 271 x = 0.*cm;*/ 272 physiPixel = new G4PVPlacement(0, 273 G4ThreeVector(0, 274 i*PixelSizeXY, 275 j*PixelSizeXY ), 276 "Pixel", 277 logicPixel, //its logical volume 278 physiHPGe, //its mother volume 279 false, //no boolean operation 280 PixelCopyNb);//copy number 281 282 283 284 285 286 287 // OhmicNeg 288 289 solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0; 290 291 if (OhmicNegThickness > 0.) 292 { solidOhmicNeg = new G4Box("OhmicNeg", //its name 293 PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2); 294 295 logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg, //its solid 296 OhmicNegMaterial, //its material 297 "OhmicNeg"); //its name 298 299 physiOhmicNeg = new G4PVPlacement(0, 300 G4ThreeVector 301 (0., 302 0., 303 (PixelThickness+OhmicNegThickness)/2), 304 "OhmicNeg", //its name 305 logicOhmicNeg, //its logical volume 306 physiHPGe, //its mother 307 false, //no boulean operat 308 PixelCopyNb); //copy number 309 310 } 311 // OhmicPos 312 solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0; 313 314 if (OhmicPosThickness > 0.) 315 { solidOhmicPos = new G4Box("OhmicPos", //its name 316 PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2); 317 318 logicOhmicPos = new G4LogicalVolume(solidOhmicPos, //its solid 319 OhmicPosMaterial, //its material 320 "OhmicPos"); //its name 321 322 physiOhmicPos = new G4PVPlacement(0, 323 G4ThreeVector(0., 324 0., 325 (-PixelThickness-OhmicPosThickness)/2), 326 "OhmicPos", 327 logicOhmicPos, 328 physiHPGe, 329 false, 330 PixelCopyNb); 331 332 } 333 334 PixelCopyNb += PixelCopyNb; 335 G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl; 336 } 337 338 } 339 340 // Screen 341 342 if (DeviceThickness > 0.) 343 { 344 solidScreen = new G4Box("DetectorScreen", //its name 345 screenSizeXY/2,screenSizeXY/2,screenThickness/2);//size 346 347 348 logicScreen = new G4LogicalVolume(solidScreen, //its solid 349 defaultMaterial, //its material 350 "DetectorScreen"); //its name 351 352 //zRotPhiHPGe.rotateX(PhiHPGe); 353 G4double x,y,z; 354 G4cout << "distScreen: "<< distScreen/m <<G4endl; 355 z = -1 * distScreen; //* std::cos(ThetaHPGe); 356 y = 0.*cm; //distScreen * std::sin(ThetaHPGe); 357 x = 0.*cm; 358 physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 359 "DetectorScreen", //its name 360 logicScreen, //its logical volume 361 physiWorld, //its mother volume 362 false, //no boolean operation 363 0); //copy number 364 } 365 366 //Plane 367 368 if (planeGranularity) { 369 370 solidPlane=0; logicPlane=0; physiPlane=0; 371 if (planeThickness > 0.) 372 { 373 solidPlane = new G4Box("Plane", //its name 374 planeSizeXY/2,planeSizeXY/2,planeThickness/2);//size 375 376 logicPlane= new G4LogicalVolume(solidPlane, //its solid 377 defaultMaterial, //its material 378 "Plane"); //its name 379 380 physiPlane = new G4PVPlacement(0, //no rotation 381 G4ThreeVector(), //at (0,0,0) 382 "Plane", //its name 383 logicPlane, //its logical volume 384 physiWorld, //its mother volume 385 false, //no boolean operation 386 0); //copy number 387 388 } 389 390 391 392 393 G4int nbOfGrainsX = ((G4int)(planeSizeXY/grainDia)) -1 ; 394 395 // y dim of a max density plane is 2rn-(n-1)ar, wehere a = (1-(std::sqrt(3)/2)), n is 396 // number of rows and r the radius of the grain. so the Y-dim of the plane must 397 // be greater or equal to this. It results that nmust be <= (PlaneY-a)/(1-a). 398 // Max Y shift of the planes superimposing along Z axis is minor (2/std::sqrt(3)r) 399 400 G4double a = (1.-(std::sqrt(3.)/2.)); 401 G4int nbOfGrainsY = (G4int) ( ((planeSizeXY/(grainDia/2.)) -a)/(2.-a) ) -1; 402 403 // same for the z axis, but a = 2 * (std::sqrt(3) - std::sqrt(2))/std::sqrt(3) 404 405 G4double b = 2. * (std::sqrt(3.) - std::sqrt(2.))/std::sqrt(3.); 406 G4int nbOfGrainsZ = (G4int) ( ((planeThickness/(grainDia/2.)) -b)/(2.-b) )-1; 407 408 if (planeThickness > 0.){ 409 410 solidGrain=0; logicGrain=0; physiGrain=0; 411 solidGrain = new G4Sphere("Grain",0., 412 grainDia/2,0., twopi, 0., pi); 413 414 logicGrain = new G4LogicalVolume(solidGrain, 415 planeMaterial, //its material 416 "Grain"); //its name 417 G4ThreeVector grainPosition; 418 G4double grainInitPositionX = 0; 419 G4double grainInitPositionY = 0; 420 G4double grainInitPositionZ = (-1.*planeThickness/2.+grainDia/2.); 421 G4double grainStepX = grainDia = 0; 422 G4double grainStepY = grainDia*(1.-(0.5-(std::sqrt(3.)/4.))); 423 G4double grainStepZ = grainDia*std::sqrt(2./3.); 424 425 for ( G4int k=0; k < nbOfGrainsZ ; k++ ) { 426 for ( G4int j=0; j < nbOfGrainsY ; j++ ) { 427 for ( G4int i=0; i < nbOfGrainsX ; i++ ) { 428 429 // Now we identify the layer and the row where the grain is , to place it in the right position 430 431 432 433 if (k%3 == 0) { // first or (4-multiple)th layer: structure is ABCABC 434 grainInitPositionY = (-1.*planeSizeXY/2.+grainDia/2.); 435 if (j%2 ==0) { //first or (3-multiple)th row 436 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.); 437 } 438 439 else if ( ((j+1) % 2) == 0 ) { 440 grainInitPositionX = (-1.*planeSizeXY/2.+ grainDia); 441 } 442 443 } 444 else if ( ((k+2) % 3) == 0 ) { // B-layer 445 446 grainInitPositionY = ( (-1.*planeSizeXY/2.) + (grainDia/2.)*(1. + (1./std::sqrt(3.)) ) ); 447 448 if (j%2 ==0) { //first or (3-multiple)th row 449 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia); 450 } 451 452 else if ( (j+1)%2 == 0 ) { 453 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2); 454 } 455 456 } 457 458 else if ( (k+1)%3 == 0 ) { // B-layer 459 460 grainInitPositionY = (-1.*planeSizeXY/2.+(grainDia/2.)*(1.+2./std::sqrt(3.)) ); 461 462 if (j%2 ==0) { //first or (3-multiple)th row 463 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.); 464 } 465 466 else if ( (j+1)%2 == 0 ) { 467 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia); 468 } 469 470 } 471 472 physiGrain = new G4PVPlacement(0, 473 G4ThreeVector( grainInitPositionX + i*grainStepX, 474 grainInitPositionY + j*grainStepY, 475 grainInitPositionZ + k*grainStepZ), 476 "Grain", 477 logicGrain, //its logical volume 478 physiPlane, //its mother volume 479 false, //no boolean operation 480 grainCopyNb);//copy number 481 482 grainCopyNb = grainCopyNb +1; 483 } 484 } 485 } 486 } 487 } 488 else { 489 490 solidPlane=0; logicPlane=0; physiPlane=0; 491 if (planeThickness > 0.) 492 { 493 solidPlane = new G4Box("Plane", //its name 494 planeSizeXY/2,planeSizeXY/2,planeThickness/2);//size 495 496 logicPlane= new G4LogicalVolume(solidPlane, //its solid 497 planeMaterial, //its material 498 "Plane"); //its name 499 500 physiPlane = new G4PVPlacement(0, //no rotation 501 G4ThreeVector(), //at (0,0,0) 502 "Plane", //its name 503 logicPlane, //its logical volume 504 physiWorld, //its mother volume 505 false, //no boolean operation 506 0); //copy number 507 508 } 509 } 510 511 // Visualization attributes 512 513 logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible()); 514 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); 515 G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. )); 516 G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. )); 517 G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. , 255/255. )); 518 G4VisAttributes * grayc= new G4VisAttributes( G4Colour(128/255. , 128/255. , 128/255. )); 519 G4VisAttributes * lightGray= new G4VisAttributes( G4Colour(178/255. , 178/255. , 178/255. )); 520 yellow->SetVisibility(true); 521 yellow->SetForceSolid(true); 522 red->SetVisibility(true); 523 red->SetForceSolid(true); 524 blue->SetVisibility(true); 525 grayc->SetVisibility(true); 526 grayc->SetForceSolid(true); 527 lightGray->SetVisibility(true); 528 lightGray->SetForceSolid(true); 529 simpleBoxVisAtt->SetVisibility(true); 530 531 logicPixel->SetVisAttributes(red); //modified!!! 532 logicHPGe->SetVisAttributes(blue); 533 534 logicPlane->SetVisAttributes(lightGray); 535 536 537 logicScreen->SetVisAttributes(grayc); 538 logicOhmicNeg->SetVisAttributes(yellow); 539 logicOhmicPos->SetVisAttributes(yellow); 540 541 542 543 if (planeGranularity) logicGrain->SetVisAttributes(grayc); 544 545 //always return the physical World 546 547 PrintApparateParameters(); 548 549 return physiWorld; 550 } 551 552 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo... 553 554 void XrayFluoPlaneDetectorConstruction::ConstructSDandField() 555 { 556 // 557 // Sensitive Detectors 558 // 559 if (HPGeSD.Get() == 0) 560 { 561 XrayFluoSD* SD = new XrayFluoSD ("HPGeSD",this); 562 HPGeSD.Put( SD ); 563 } 564 G4SDManager::GetSDMpointer()->AddNewDetector(HPGeSD.Get()); 565 if (logicPixel) 566 SetSensitiveDetector(logicPixel,HPGeSD.Get()); 567 } 568 569 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 570 571 void XrayFluoPlaneDetectorConstruction::PrintApparateParameters() 572 { 573 G4cout << "-----------------------------------------------------------------------" 574 << G4endl 575 << "The plane is a box whose size is: " 576 << G4endl 577 << planeThickness/cm 578 << " cm * " 579 << planeSizeXY/cm 580 << " cm * " 581 << planeSizeXY/cm 582 << " cm" 583 << G4endl 584 <<" Material: " << logicPlane->GetMaterial()->GetName() 585 <<G4endl 586 <<"The Detector is a slice " << DeviceThickness/(1.e-6*m) << " micron thick of " << pixelMaterial->GetName() 587 <<G4endl 588 589 590 <<"-------------------------------------------------------------------------" 591 << G4endl; 592 } 593 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 594 595 void XrayFluoPlaneDetectorConstruction::UpdateGeometry() 596 { 597 G4GeometryManager::GetInstance()->OpenGeometry(); 598 G4PhysicalVolumeStore::Clean(); 599 G4LogicalVolumeStore::Clean(); 600 G4SolidStore::Clean(); 601 602 zRotPhiHPGe.rotateX(-1.*PhiHPGe); 603 //Triggers a new call of Construct() and of all the geometry resets. 604 G4RunManager::GetRunManager()->ReinitializeGeometry(); 605 } 606 607 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 608 609 void XrayFluoPlaneDetectorConstruction::DeleteGrainObjects() 610 { 611 if (planeGranularity) { 612 delete solidGrain; 613 delete logicGrain; 614 delete physiGrain; 615 } 616 617 } 618 619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 620 621 void XrayFluoPlaneDetectorConstruction::SetPlaneMaterial(G4String newMaterial) 622 { 623 //G4cout << "Material!!!!" << newMaterial << G4endl; 624 logicPlane->SetMaterial(materials->GetMaterial(newMaterial)); 625 PrintApparateParameters(); 626 //GeometryHasBeenModified is called by the messenger 627 628 } 629 630 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 631 632 633 634 635 636 637 638 639 640 641 642 643