File indexing completed on 2025-01-18 09:17:09
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 "XrayFluoMercuryDetectorConstruction.hh"
0036 #include "XrayFluoMercuryDetectorMessenger.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 "G4Tubs.hh"
0046 #include "G4LogicalVolume.hh"
0047 #include "G4PVPlacement.hh"
0048 #include "G4TransportationManager.hh"
0049 #include "G4SDManager.hh"
0050 #include "G4RunManager.hh"
0051 #include "G4VisAttributes.hh"
0052 #include "G4Colour.hh"
0053 #include "G4ios.hh"
0054 #include "G4PVReplica.hh"
0055 #include "G4UserLimits.hh"
0056 #include "G4GeometryManager.hh"
0057 #include "G4PhysicalVolumeStore.hh"
0058 #include "G4LogicalVolumeStore.hh"
0059 #include "G4SolidStore.hh"
0060 #include "G4SDManager.hh"
0061
0062
0063
0064 XrayFluoMercuryDetectorConstruction::XrayFluoMercuryDetectorConstruction()
0065 : detectorType(0),mercuryGranularity(false), DeviceSizeX(0),
0066 DeviceSizeY(0),DeviceThickness(0),
0067 solidWorld(0),logicWorld(0),physiWorld(0),
0068 solidHPGe(0),logicHPGe(0),physiHPGe(0),
0069 solidScreen(0),logicScreen(0),physiScreen(0),
0070 solidMercury (0),logicMercury(0),physiMercury (0),
0071 solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0),
0072 solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0),
0073 solidPixel(0),logicPixel(0), physiPixel(0),
0074 screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0),
0075 pixelMaterial(0),mercuryMaterial(0),
0076 defaultMaterial(0),HPGeSD(0)
0077
0078 {
0079 materials = XrayFluoNistMaterials::GetInstance();
0080
0081 DefineDefaultMaterials();
0082
0083 NbOfPixelRows = 1;
0084 NbOfPixelColumns = 1;
0085 NbOfPixels = NbOfPixelRows*NbOfPixelColumns;
0086 PixelSizeXY = std::sqrt(40.) * mm *0.5e6;
0087 PixelThickness = 3.5 * mm * 1e6;
0088
0089 G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl;
0090 G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl;
0091
0092 ContactSizeXY = std::sqrt(40.) * mm * 0.5e6;
0093
0094 mercuryDia = 2 * 4880 * km ;
0095 sunDia = 1390000 * km ;
0096 mercurySunDistance = 57910000 * km ;
0097
0098
0099 OhmicNegThickness = 0.005*mm *0.5e6 ;
0100 OhmicPosThickness = 0.005*mm *0.5e6 ;
0101
0102 screenThickness = 5 * mm *0.5e6;
0103
0104 ThetaHPGe = 135. * deg ;
0105 PhiHPGe = 225. * deg ;
0106
0107
0108 distDe = (mercuryDia/2 + 400 * km);
0109
0110 distScreen = distDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ;
0111
0112 distOptic = distDe - 1.*m * 1e5;
0113
0114 opticThickness = 1.* cm *0.5e6;
0115 opticDia = 21. * cm *0.5e6;
0116 opticAperture = 1. * deg;
0117
0118 PixelCopyNb=0;
0119 grainCopyNb=0;
0120 G4String defaultDetectorType = "sili";
0121 ComputeApparateParameters();
0122 SetDetectorType(defaultDetectorType);
0123
0124
0125
0126 detectorMessenger = new XrayFluoMercuryDetectorMessenger(this);
0127 G4cout << "XrayFluoMercuryDetectorConstruction created" << G4endl;
0128 }
0129
0130
0131
0132 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::instance = 0;
0133
0134 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::GetInstance()
0135 {
0136 if (instance == 0)
0137 {
0138 instance = new XrayFluoMercuryDetectorConstruction;
0139
0140 }
0141 return instance;
0142 }
0143
0144 void XrayFluoMercuryDetectorConstruction::SetDetectorType(G4String type)
0145 {
0146
0147 if (type=="sili")
0148 {
0149 detectorType = XrayFluoSiLiDetectorType::GetInstance();
0150 }
0151 else if (type=="hpge")
0152 {
0153 detectorType = XrayFluoHPGeDetectorType::GetInstance();
0154 }
0155 else
0156 {
0157 G4ExceptionDescription execp;
0158 execp << type + "detector type unknown";
0159 G4Exception("XrayFluoMercuryDetectorConstruction::SetDetectorType()","example-xray_fluorescence05",
0160 FatalException, execp);
0161 }
0162 }
0163
0164
0165
0166 XrayFluoVDetectorType* XrayFluoMercuryDetectorConstruction::GetDetectorType() const
0167 {
0168 return detectorType;
0169 }
0170
0171
0172
0173 XrayFluoMercuryDetectorConstruction::~XrayFluoMercuryDetectorConstruction()
0174
0175 {
0176 delete detectorMessenger;
0177 delete detectorType;
0178 G4cout << "XrayFluoMercuryDetectorConstruction deleted" << G4endl;
0179 }
0180
0181
0182
0183 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::Construct()
0184 {
0185 return ConstructApparate();
0186 }
0187
0188
0189 void XrayFluoMercuryDetectorConstruction::DefineDefaultMaterials()
0190 {
0191
0192
0193
0194
0195 mercuryMaterial = materials->GetMaterial("Anorthosite");
0196 screenMaterial = materials->GetMaterial("G4_Pb");
0197 pixelMaterial = materials->GetMaterial("G4_Si");
0198 OhmicPosMaterial = materials->GetMaterial("G4_Cu");
0199 OhmicNegMaterial = materials->GetMaterial("G4_Pb");
0200 defaultMaterial = materials->GetMaterial("G4_Galactic");
0201
0202
0203 }
0204
0205
0206
0207 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::ConstructApparate()
0208 {
0209
0210
0211 ComputeApparateParameters();
0212
0213
0214
0215 solidWorld = new G4Box("World",
0216 WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2);
0217
0218 logicWorld = new G4LogicalVolume(solidWorld,
0219 defaultMaterial,
0220 "World");
0221 physiWorld = new G4PVPlacement(0,
0222 G4ThreeVector(),
0223 "World",
0224 logicWorld,
0225 0,
0226 false,
0227 0);
0228
0229
0230
0231 solidHPGe = 0; physiHPGe = 0; logicHPGe=0;
0232 solidPixel=0; logicPixel=0; physiPixel=0;
0233
0234 if (DeviceThickness > 0.)
0235 {
0236 solidHPGe = new G4Box("HPGeDetector",
0237 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);
0238
0239
0240 logicHPGe = new G4LogicalVolume(solidHPGe,
0241 defaultMaterial,
0242 "HPGeDetector");
0243
0244 zRotPhiHPGe.rotateX(PhiHPGe);
0245 G4double x,y,z;
0246
0247 z = distDe * std::cos(ThetaHPGe);
0248 y = distScreen * std::sin(ThetaHPGe);
0249 x = 0.*cm;
0250
0251 physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
0252 "HPGeDetector",
0253 logicHPGe,
0254 physiWorld,
0255 false,
0256 0);
0257 }
0258
0259
0260
0261
0262
0263 for ( G4int j=0; j < NbOfPixelColumns ; j++ )
0264 { for ( G4int i=0; i < NbOfPixelRows ; i++ )
0265 {
0266 solidPixel=0; logicPixel=0; physiPixel=0;
0267 if (PixelThickness > 0.)
0268 solidPixel = new G4Box("Pixel",
0269 PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2);
0270
0271 logicPixel = new G4LogicalVolume(solidPixel,
0272 pixelMaterial,
0273 "Pixel");
0274
0275
0276
0277
0278
0279
0280
0281 physiPixel = new G4PVPlacement(0,
0282 G4ThreeVector(0,
0283 i*PixelSizeXY,
0284 j*PixelSizeXY ),
0285 "Pixel",
0286 logicPixel,
0287 physiHPGe,
0288 false,
0289 PixelCopyNb);
0290
0291
0292
0293
0294
0295
0296
0297
0298 solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0;
0299
0300 if (OhmicNegThickness > 0.)
0301 { solidOhmicNeg = new G4Box("OhmicNeg",
0302 PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2);
0303
0304 logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg,
0305 OhmicNegMaterial,
0306 "OhmicNeg");
0307
0308 physiOhmicNeg = new G4PVPlacement(0,
0309 G4ThreeVector
0310 (0.,
0311 0.,
0312 (PixelThickness+OhmicNegThickness)/2),
0313 "OhmicNeg",
0314 logicOhmicNeg,
0315 physiHPGe,
0316 false,
0317 PixelCopyNb);
0318
0319 }
0320
0321 solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0;
0322
0323 if (OhmicPosThickness > 0.)
0324 { solidOhmicPos = new G4Box("OhmicPos",
0325 PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2);
0326
0327 logicOhmicPos = new G4LogicalVolume(solidOhmicPos,
0328 OhmicPosMaterial,
0329 "OhmicPos");
0330
0331 physiOhmicPos = new G4PVPlacement(0,
0332 G4ThreeVector(0.,
0333 0.,
0334 (-PixelThickness-OhmicPosThickness)/2),
0335 "OhmicPos",
0336 logicOhmicPos,
0337 physiHPGe,
0338 false,
0339 PixelCopyNb);
0340
0341 }
0342
0343 PixelCopyNb += PixelCopyNb;
0344 G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl;
0345 }
0346
0347 }
0348
0349
0350
0351 if (DeviceThickness > 0.)
0352 {
0353 solidOptic = new G4Tubs("DetectorOptic",
0354 0.,opticDia/2, opticThickness, 0.,2.*pi);
0355
0356
0357 logicOptic = new G4LogicalVolume(solidOptic,
0358 defaultMaterial,
0359 "DetectorOptic");
0360
0361
0362 G4double x,y,z;
0363 z = distOptic * std::cos(ThetaHPGe);
0364 y = distOptic * std::sin(ThetaHPGe);
0365 x = 0.*cm;
0366 physiOptic = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
0367 "DetectorOptic",
0368 logicOptic,
0369 physiWorld,
0370 false,
0371 0);
0372 }
0373
0374
0375
0376
0377 if (DeviceThickness > 0.)
0378 {
0379 solidScreen = new G4Box("DetectorScreen",
0380 screenSizeXY/2,screenSizeXY/2,screenThickness/2);
0381
0382
0383 logicScreen = new G4LogicalVolume(solidScreen,
0384 defaultMaterial,
0385 "DetectorScreen");
0386
0387
0388 G4double x,y,z;
0389 G4cout << "distScreen: "<< distScreen/m <<G4endl;
0390 z = distScreen * std::cos(ThetaHPGe);
0391 y = distScreen * std::sin(ThetaHPGe);
0392 x = 0.*cm;
0393 physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)),
0394 "DetectorScreen",
0395 logicScreen,
0396 physiWorld,
0397 false,
0398 0);
0399 }
0400
0401
0402
0403
0404 solidMercury=0; logicMercury=0; physiMercury=0;
0405 if (mercuryDia > 0.)
0406 {
0407
0408
0409
0410
0411
0412
0413 solidMercury = new G4Sphere("Mercury",0.,mercuryDia/2., 0., twopi, 0., pi);
0414
0415 logicMercury= new G4LogicalVolume(solidMercury,
0416 mercuryMaterial,
0417 "Mercury");
0418
0419 physiMercury = new G4PVPlacement(0,
0420 G4ThreeVector(),
0421 "Mercury",
0422 logicMercury,
0423 physiWorld,
0424 false,
0425 0);
0426
0427 }
0428
0429
0430
0431
0432
0433 logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
0434 G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
0435 G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. ));
0436 G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. ));
0437 G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. , 255/255. ));
0438 G4VisAttributes * grayc= new G4VisAttributes( G4Colour(128/255. , 128/255. , 128/255. ));
0439 G4VisAttributes * darkGray= new G4VisAttributes( G4Colour(95/255. , 95/255. , 95/255. ));
0440
0441 yellow->SetVisibility(true);
0442 yellow->SetForceSolid(true);
0443 red->SetVisibility(true);
0444 red->SetForceSolid(true);
0445 blue->SetVisibility(true);
0446 grayc->SetVisibility(true);
0447 grayc->SetForceSolid(true);
0448 simpleBoxVisAtt->SetVisibility(true);
0449
0450
0451
0452 logicPixel->SetVisAttributes(red);
0453 logicHPGe->SetVisAttributes(G4VisAttributes::GetInvisible());
0454
0455 logicMercury->SetVisAttributes(darkGray);
0456
0457
0458 logicScreen->SetVisAttributes(red);
0459 logicOhmicNeg->SetVisAttributes(yellow);
0460 logicOhmicPos->SetVisAttributes(yellow);
0461 logicOptic->SetVisAttributes(grayc);
0462
0463
0464 if (mercuryGranularity) logicGrain->SetVisAttributes(grayc);
0465
0466
0467
0468 PrintApparateParameters();
0469
0470 return physiWorld;
0471 }
0472
0473
0474
0475 void XrayFluoMercuryDetectorConstruction::ConstructSDandField()
0476 {
0477
0478
0479
0480 if (HPGeSD.Get() == 0)
0481 {
0482 XrayFluoSD* SD = new XrayFluoSD ("HPGeSD",this);
0483 HPGeSD.Put( SD );
0484 }
0485 G4SDManager::GetSDMpointer()->AddNewDetector(HPGeSD.Get());
0486 if (logicPixel)
0487 SetSensitiveDetector(logicPixel,HPGeSD.Get());
0488 }
0489
0490
0491
0492 void XrayFluoMercuryDetectorConstruction::PrintApparateParameters()
0493 {
0494 G4cout << "-----------------------------------------------------------------------"
0495 << G4endl
0496 << "The mercury is a sphere whose diamter is: "
0497 << G4endl
0498 << mercuryDia/km
0499 << " Km "
0500 << G4endl
0501 <<" Material: " << logicMercury->GetMaterial()->GetName()
0502 <<G4endl
0503 <<"The Detector is a slice " << DeviceThickness/(1.e-6*m)
0504 << " micron thick of " << pixelMaterial->GetName()<<G4endl
0505 <<"-------------------------------------------------------------------------"
0506 << G4endl;
0507 }
0508
0509
0510 void XrayFluoMercuryDetectorConstruction::UpdateGeometry()
0511 {
0512
0513 G4GeometryManager::GetInstance()->OpenGeometry();
0514 G4PhysicalVolumeStore::Clean();
0515 G4LogicalVolumeStore::Clean();
0516 G4SolidStore::Clean();
0517
0518 zRotPhiHPGe.rotateX(-1.*PhiHPGe);
0519 ComputeApparateParameters();
0520
0521
0522 G4RunManager::GetRunManager()->ReinitializeGeometry();
0523
0524 }
0525
0526
0527
0528 void XrayFluoMercuryDetectorConstruction::SetMercuryMaterial(G4String newMaterial)
0529 {
0530 G4cout << "New Mercury Material: " << newMaterial << G4endl;
0531 logicMercury->SetMaterial(materials->GetMaterial(newMaterial));
0532 PrintApparateParameters();
0533
0534 }
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547