File indexing completed on 2025-01-18 09:17:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include "XrayFluoPlaneDetectorConstruction.hh"
0036 #include "XrayFluoPlaneDetectorMessenger.hh"
0037 #include "XrayFluoSD.hh"
0038 #include "XrayFluoNistMaterials.hh"
0039 #include "G4PhysicalConstants.hh"
0040 #include "G4SystemOfUnits.hh"
0041 #include "G4Material.hh"
0042 #include "G4ThreeVector.hh"
0043 #include "G4Box.hh"
0044 #include "G4Sphere.hh"
0045 #include "G4LogicalVolume.hh"
0046 #include "G4PVPlacement.hh"
0047 #include "G4TransportationManager.hh"
0048 #include "G4SDManager.hh"
0049 #include "G4RunManager.hh"
0050 #include "G4VisAttributes.hh"
0051 #include "G4Colour.hh"
0052 #include "G4PVReplica.hh"
0053 #include "G4UserLimits.hh"
0054 #include "G4GeometryManager.hh"
0055 #include "G4PhysicalVolumeStore.hh"
0056 #include "G4LogicalVolumeStore.hh"
0057 #include "G4SolidStore.hh"
0058 #include "G4SDManager.hh"
0059
0060
0061
0062
0063 XrayFluoPlaneDetectorConstruction::XrayFluoPlaneDetectorConstruction()
0064 : detectorType(0),planeGranularity(false), DeviceSizeX(0),
0065 DeviceSizeY(0),DeviceThickness(0),
0066 solidWorld(0),logicWorld(0),physiWorld(0),
0067 solidHPGe(0),logicHPGe(0),physiHPGe(0),
0068 solidScreen(0),logicScreen(0),physiScreen(0),
0069 solidPlane (0),logicPlane(0),physiPlane (0),
0070 solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0),
0071 solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0),
0072 solidPixel(0),logicPixel(0), physiPixel(0),
0073 screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0),
0074 pixelMaterial(0),planeMaterial(0),
0075 defaultMaterial(0),HPGeSD(0)
0076
0077 {
0078 materials = XrayFluoNistMaterials::GetInstance();
0079
0080 DefineDefaultMaterials();
0081
0082 NbOfPixelRows = 1;
0083 NbOfPixelColumns = 1;
0084 NbOfPixels = NbOfPixelRows*NbOfPixelColumns;
0085 PixelSizeXY = 5 * cm;
0086 PixelThickness = 3.5 * mm;
0087
0088 G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl;
0089 G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl;
0090
0091 ContactSizeXY = 5 * cm;
0092 planeThickness = 5 * cm;
0093 planeSizeXY = 5. * m;
0094
0095 OhmicNegThickness = 0.005*mm;
0096 OhmicPosThickness = 0.005*mm;
0097
0098 screenThickness = 5 * mm;
0099
0100 ThetaHPGe = 0. * deg;
0101 PhiHPGe = 0. * deg;
0102
0103
0104 DistDe = 0.5 * m;
0105
0106 distScreen = DistDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ;
0107
0108 grainDia = 1 * mm;
0109
0110
0111 PixelCopyNb=0;
0112 grainCopyNb=0;
0113 G4String defaultDetectorType = "sili";
0114 ComputeApparateParameters();
0115 SetDetectorType(defaultDetectorType);
0116
0117
0118
0119 detectorMessenger = new XrayFluoPlaneDetectorMessenger(this);
0120 G4cout << "XrayFluoPlaneDetectorConstruction created" << G4endl;
0121 }
0122
0123
0124
0125 XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::instance = 0;
0126
0127 XrayFluoPlaneDetectorConstruction* XrayFluoPlaneDetectorConstruction::GetInstance()
0128 {
0129 if (instance == 0)
0130 {
0131 instance = new XrayFluoPlaneDetectorConstruction;
0132
0133 }
0134 return instance;
0135 }
0136
0137 void XrayFluoPlaneDetectorConstruction::SetDetectorType(G4String type)
0138 {
0139
0140 if (type=="sili")
0141 {
0142 detectorType = XrayFluoSiLiDetectorType::GetInstance();
0143 }
0144 else if (type=="hpge")
0145 {
0146 detectorType = XrayFluoHPGeDetectorType::GetInstance();
0147 }
0148 else
0149 {
0150 G4ExceptionDescription execp;
0151 execp << type + "detector type unknown";
0152 G4Exception("XrayFluoPlaneDetectorConstruction::SetDetectorType()","example-xray_fluorescence03",
0153 FatalException, execp);
0154 }
0155 }
0156
0157
0158
0159 XrayFluoVDetectorType* XrayFluoPlaneDetectorConstruction::GetDetectorType() const
0160 {
0161 return detectorType;
0162 }
0163
0164
0165
0166 XrayFluoPlaneDetectorConstruction::~XrayFluoPlaneDetectorConstruction()
0167
0168 {
0169 delete detectorMessenger;
0170 delete detectorType;
0171 G4cout << "XrayFluoPlaneDetectorConstruction deleted" << G4endl;
0172 }
0173
0174
0175
0176 G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::Construct()
0177 {
0178 return ConstructApparate();
0179 }
0180
0181
0182 void XrayFluoPlaneDetectorConstruction::DefineDefaultMaterials()
0183 {
0184
0185
0186
0187
0188 planeMaterial = materials->GetMaterial("Anorthosite");
0189 screenMaterial = materials->GetMaterial("G4_Pb");
0190 pixelMaterial = materials->GetMaterial("G4_Si");
0191 OhmicPosMaterial = materials->GetMaterial("G4_Cu");
0192 OhmicNegMaterial = materials->GetMaterial("G4_Pb");
0193 defaultMaterial = materials->GetMaterial("G4_Galactic");
0194 }
0195
0196
0197
0198 G4VPhysicalVolume* XrayFluoPlaneDetectorConstruction::ConstructApparate()
0199 {
0200
0201
0202
0203
0204
0205
0206 solidWorld = new G4Box("World",
0207 WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2);
0208
0209 logicWorld = new G4LogicalVolume(solidWorld,
0210 defaultMaterial,
0211 "World");
0212 physiWorld = new G4PVPlacement(0,
0213 G4ThreeVector(),
0214 "World",
0215 logicWorld,
0216 0,
0217 false,
0218 0);
0219
0220
0221
0222 solidHPGe = 0; physiHPGe = 0; logicHPGe=0;
0223 solidPixel=0; logicPixel=0; physiPixel=0;
0224
0225 if (DeviceThickness > 0.)
0226 {
0227 solidHPGe = new G4Box("HPGeDetector",
0228 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);
0229
0230
0231 logicHPGe = new G4LogicalVolume(solidHPGe,
0232 defaultMaterial,
0233 "HPGeDetector");
0234
0235 zRotPhiHPGe.rotateX(PhiHPGe);
0236 G4double x,y,z;
0237
0238 z = -1. * DistDe;
0239 y = 0.*cm;
0240 x = 0.*cm;
0241
0242 physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
0243 "HPGeDetector",
0244 logicHPGe,
0245 physiWorld,
0246 false,
0247 0);
0248 }
0249
0250
0251
0252
0253
0254 for ( G4int j=0; j < NbOfPixelColumns ; j++ )
0255 { for ( G4int i=0; i < NbOfPixelRows ; i++ )
0256 {
0257 solidPixel=0; logicPixel=0; physiPixel=0;
0258 if (PixelThickness > 0.)
0259 solidPixel = new G4Box("Pixel",
0260 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2);
0261
0262 logicPixel = new G4LogicalVolume(solidPixel,
0263 pixelMaterial,
0264 "Pixel");
0265
0266
0267
0268
0269
0270
0271
0272 physiPixel = new G4PVPlacement(0,
0273 G4ThreeVector(0,
0274 i*PixelSizeXY,
0275 j*PixelSizeXY ),
0276 "Pixel",
0277 logicPixel,
0278 physiHPGe,
0279 false,
0280 PixelCopyNb);
0281
0282
0283
0284
0285
0286
0287
0288
0289 solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0;
0290
0291 if (OhmicNegThickness > 0.)
0292 { solidOhmicNeg = new G4Box("OhmicNeg",
0293 PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2);
0294
0295 logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg,
0296 OhmicNegMaterial,
0297 "OhmicNeg");
0298
0299 physiOhmicNeg = new G4PVPlacement(0,
0300 G4ThreeVector
0301 (0.,
0302 0.,
0303 (PixelThickness+OhmicNegThickness)/2),
0304 "OhmicNeg",
0305 logicOhmicNeg,
0306 physiHPGe,
0307 false,
0308 PixelCopyNb);
0309
0310 }
0311
0312 solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0;
0313
0314 if (OhmicPosThickness > 0.)
0315 { solidOhmicPos = new G4Box("OhmicPos",
0316 PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2);
0317
0318 logicOhmicPos = new G4LogicalVolume(solidOhmicPos,
0319 OhmicPosMaterial,
0320 "OhmicPos");
0321
0322 physiOhmicPos = new G4PVPlacement(0,
0323 G4ThreeVector(0.,
0324 0.,
0325 (-PixelThickness-OhmicPosThickness)/2),
0326 "OhmicPos",
0327 logicOhmicPos,
0328 physiHPGe,
0329 false,
0330 PixelCopyNb);
0331
0332 }
0333
0334 PixelCopyNb += PixelCopyNb;
0335 G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl;
0336 }
0337
0338 }
0339
0340
0341
0342 if (DeviceThickness > 0.)
0343 {
0344 solidScreen = new G4Box("DetectorScreen",
0345 screenSizeXY/2,screenSizeXY/2,screenThickness/2);
0346
0347
0348 logicScreen = new G4LogicalVolume(solidScreen,
0349 defaultMaterial,
0350 "DetectorScreen");
0351
0352
0353 G4double x,y,z;
0354 G4cout << "distScreen: "<< distScreen/m <<G4endl;
0355 z = -1 * distScreen;
0356 y = 0.*cm;
0357 x = 0.*cm;
0358 physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
0359 "DetectorScreen",
0360 logicScreen,
0361 physiWorld,
0362 false,
0363 0);
0364 }
0365
0366
0367
0368 if (planeGranularity) {
0369
0370 solidPlane=0; logicPlane=0; physiPlane=0;
0371 if (planeThickness > 0.)
0372 {
0373 solidPlane = new G4Box("Plane",
0374 planeSizeXY/2,planeSizeXY/2,planeThickness/2);
0375
0376 logicPlane= new G4LogicalVolume(solidPlane,
0377 defaultMaterial,
0378 "Plane");
0379
0380 physiPlane = new G4PVPlacement(0,
0381 G4ThreeVector(),
0382 "Plane",
0383 logicPlane,
0384 physiWorld,
0385 false,
0386 0);
0387
0388 }
0389
0390
0391
0392
0393 G4int nbOfGrainsX = ((G4int)(planeSizeXY/grainDia)) -1 ;
0394
0395
0396
0397
0398
0399
0400 G4double a = (1.-(std::sqrt(3.)/2.));
0401 G4int nbOfGrainsY = (G4int) ( ((planeSizeXY/(grainDia/2.)) -a)/(2.-a) ) -1;
0402
0403
0404
0405 G4double b = 2. * (std::sqrt(3.) - std::sqrt(2.))/std::sqrt(3.);
0406 G4int nbOfGrainsZ = (G4int) ( ((planeThickness/(grainDia/2.)) -b)/(2.-b) )-1;
0407
0408 if (planeThickness > 0.){
0409
0410 solidGrain=0; logicGrain=0; physiGrain=0;
0411 solidGrain = new G4Sphere("Grain",0.,
0412 grainDia/2,0., twopi, 0., pi);
0413
0414 logicGrain = new G4LogicalVolume(solidGrain,
0415 planeMaterial,
0416 "Grain");
0417 G4ThreeVector grainPosition;
0418 G4double grainInitPositionX = 0;
0419 G4double grainInitPositionY = 0;
0420 G4double grainInitPositionZ = (-1.*planeThickness/2.+grainDia/2.);
0421 G4double grainStepX = grainDia = 0;
0422 G4double grainStepY = grainDia*(1.-(0.5-(std::sqrt(3.)/4.)));
0423 G4double grainStepZ = grainDia*std::sqrt(2./3.);
0424
0425 for ( G4int k=0; k < nbOfGrainsZ ; k++ ) {
0426 for ( G4int j=0; j < nbOfGrainsY ; j++ ) {
0427 for ( G4int i=0; i < nbOfGrainsX ; i++ ) {
0428
0429
0430
0431
0432
0433 if (k%3 == 0) {
0434 grainInitPositionY = (-1.*planeSizeXY/2.+grainDia/2.);
0435 if (j%2 ==0) {
0436 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.);
0437 }
0438
0439 else if ( ((j+1) % 2) == 0 ) {
0440 grainInitPositionX = (-1.*planeSizeXY/2.+ grainDia);
0441 }
0442
0443 }
0444 else if ( ((k+2) % 3) == 0 ) {
0445
0446 grainInitPositionY = ( (-1.*planeSizeXY/2.) + (grainDia/2.)*(1. + (1./std::sqrt(3.)) ) );
0447
0448 if (j%2 ==0) {
0449 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia);
0450 }
0451
0452 else if ( (j+1)%2 == 0 ) {
0453 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2);
0454 }
0455
0456 }
0457
0458 else if ( (k+1)%3 == 0 ) {
0459
0460 grainInitPositionY = (-1.*planeSizeXY/2.+(grainDia/2.)*(1.+2./std::sqrt(3.)) );
0461
0462 if (j%2 ==0) {
0463 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia/2.);
0464 }
0465
0466 else if ( (j+1)%2 == 0 ) {
0467 grainInitPositionX = (-1.*planeSizeXY/2.+grainDia);
0468 }
0469
0470 }
0471
0472 physiGrain = new G4PVPlacement(0,
0473 G4ThreeVector( grainInitPositionX + i*grainStepX,
0474 grainInitPositionY + j*grainStepY,
0475 grainInitPositionZ + k*grainStepZ),
0476 "Grain",
0477 logicGrain,
0478 physiPlane,
0479 false,
0480 grainCopyNb);
0481
0482 grainCopyNb = grainCopyNb +1;
0483 }
0484 }
0485 }
0486 }
0487 }
0488 else {
0489
0490 solidPlane=0; logicPlane=0; physiPlane=0;
0491 if (planeThickness > 0.)
0492 {
0493 solidPlane = new G4Box("Plane",
0494 planeSizeXY/2,planeSizeXY/2,planeThickness/2);
0495
0496 logicPlane= new G4LogicalVolume(solidPlane,
0497 planeMaterial,
0498 "Plane");
0499
0500 physiPlane = new G4PVPlacement(0,
0501 G4ThreeVector(),
0502 "Plane",
0503 logicPlane,
0504 physiWorld,
0505 false,
0506 0);
0507
0508 }
0509 }
0510
0511
0512
0513 logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
0514 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
0515 G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. ));
0516 G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. ));
0517 G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. , 255/255. ));
0518 G4VisAttributes * grayc= new G4VisAttributes( G4Colour(128/255. , 128/255. , 128/255. ));
0519 G4VisAttributes * lightGray= new G4VisAttributes( G4Colour(178/255. , 178/255. , 178/255. ));
0520 yellow->SetVisibility(true);
0521 yellow->SetForceSolid(true);
0522 red->SetVisibility(true);
0523 red->SetForceSolid(true);
0524 blue->SetVisibility(true);
0525 grayc->SetVisibility(true);
0526 grayc->SetForceSolid(true);
0527 lightGray->SetVisibility(true);
0528 lightGray->SetForceSolid(true);
0529 simpleBoxVisAtt->SetVisibility(true);
0530
0531 logicPixel->SetVisAttributes(red);
0532 logicHPGe->SetVisAttributes(blue);
0533
0534 logicPlane->SetVisAttributes(lightGray);
0535
0536
0537 logicScreen->SetVisAttributes(grayc);
0538 logicOhmicNeg->SetVisAttributes(yellow);
0539 logicOhmicPos->SetVisAttributes(yellow);
0540
0541
0542
0543 if (planeGranularity) logicGrain->SetVisAttributes(grayc);
0544
0545
0546
0547 PrintApparateParameters();
0548
0549 return physiWorld;
0550 }
0551
0552
0553
0554 void XrayFluoPlaneDetectorConstruction::ConstructSDandField()
0555 {
0556
0557
0558
0559 if (HPGeSD.Get() == 0)
0560 {
0561 XrayFluoSD* SD = new XrayFluoSD ("HPGeSD",this);
0562 HPGeSD.Put( SD );
0563 }
0564 G4SDManager::GetSDMpointer()->AddNewDetector(HPGeSD.Get());
0565 if (logicPixel)
0566 SetSensitiveDetector(logicPixel,HPGeSD.Get());
0567 }
0568
0569
0570
0571 void XrayFluoPlaneDetectorConstruction::PrintApparateParameters()
0572 {
0573 G4cout << "-----------------------------------------------------------------------"
0574 << G4endl
0575 << "The plane is a box whose size is: "
0576 << G4endl
0577 << planeThickness/cm
0578 << " cm * "
0579 << planeSizeXY/cm
0580 << " cm * "
0581 << planeSizeXY/cm
0582 << " cm"
0583 << G4endl
0584 <<" Material: " << logicPlane->GetMaterial()->GetName()
0585 <<G4endl
0586 <<"The Detector is a slice " << DeviceThickness/(1.e-6*m) << " micron thick of " << pixelMaterial->GetName()
0587 <<G4endl
0588
0589
0590 <<"-------------------------------------------------------------------------"
0591 << G4endl;
0592 }
0593
0594
0595 void XrayFluoPlaneDetectorConstruction::UpdateGeometry()
0596 {
0597 G4GeometryManager::GetInstance()->OpenGeometry();
0598 G4PhysicalVolumeStore::Clean();
0599 G4LogicalVolumeStore::Clean();
0600 G4SolidStore::Clean();
0601
0602 zRotPhiHPGe.rotateX(-1.*PhiHPGe);
0603
0604 G4RunManager::GetRunManager()->ReinitializeGeometry();
0605 }
0606
0607
0608
0609 void XrayFluoPlaneDetectorConstruction::DeleteGrainObjects()
0610 {
0611 if (planeGranularity) {
0612 delete solidGrain;
0613 delete logicGrain;
0614 delete physiGrain;
0615 }
0616
0617 }
0618
0619
0620
0621 void XrayFluoPlaneDetectorConstruction::SetPlaneMaterial(G4String newMaterial)
0622 {
0623
0624 logicPlane->SetMaterial(materials->GetMaterial(newMaterial));
0625 PrintApparateParameters();
0626
0627
0628 }
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642