File indexing completed on 2025-01-31 09:21:58
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
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include "doiPETDetectorConstruction.hh"
0051 #include "doiPETAnalysis.hh"
0052 #include "doiPETDetectorConstructionMessenger.hh"
0053 #include "doiPETGlobalParameters.hh"
0054
0055 #include "G4NistManager.hh"
0056 #include "G4Box.hh"
0057 #include "G4Tubs.hh"
0058 #include "G4LogicalVolume.hh"
0059 #include "G4PVPlacement.hh"
0060 #include "G4RotationMatrix.hh"
0061 #include "G4Transform3D.hh"
0062 #include "G4SDManager.hh"
0063 #include "G4MultiFunctionalDetector.hh"
0064 #include "G4VPrimitiveScorer.hh"
0065 #include "G4PSEnergyDeposit.hh"
0066 #include "G4PSDoseDeposit.hh"
0067 #include "G4VisAttributes.hh"
0068 #include "G4PhysicalConstants.hh"
0069 #include "G4SystemOfUnits.hh"
0070
0071
0072 #include "G4SubtractionSolid.hh"
0073 #include "G4UnionSolid.hh"
0074 #include "G4IntersectionSolid.hh"
0075
0076 #include "G4Element.hh"
0077 #include "G4Material.hh"
0078 #include "G4Sphere.hh"
0079 #include "G4Colour.hh"
0080 #include "G4RunManager.hh"
0081 #include "G4StateManager.hh"
0082 #include "G4GeometryManager.hh"
0083 #include "G4PhysicalVolumeStore.hh"
0084 #include "G4LogicalVolumeStore.hh"
0085 #include "G4SolidStore.hh"
0086
0087
0088
0089
0090 doiPETDetectorConstruction::doiPETDetectorConstruction()
0091 : G4VUserDetectorConstruction(),
0092 fCheckOverlaps(true)
0093 {
0094 DefineMaterials();
0095 fDetectorMessenger = new doiPETDetectorConstructionMessenger(this);
0096
0097
0098 PhantomType = "NEMA_imageQualityPhantom_wholeBody";
0099 phantomRadius = 100 * mm;
0100 phantomLength = 700 * mm;
0101 phantomPosition = G4ThreeVector(0,0,0);
0102 numOfSleeves = 5;
0103 }
0104
0105
0106
0107 doiPETDetectorConstruction::~doiPETDetectorConstruction()
0108 {
0109 delete fDetectorMessenger;
0110 }
0111
0112
0113
0114 void doiPETDetectorConstruction::DefineMaterials()
0115 {
0116 G4NistManager* nist = G4NistManager::Instance();
0117
0118
0119 air = nist->FindOrBuildMaterial("G4_AIR");
0120
0121
0122 pmma = nist->FindOrBuildMaterial("G4_PLEXIGLASS");
0123
0124
0125 water = nist->FindOrBuildMaterial("G4_WATER");
0126
0127
0128 polyethylene = nist->BuildMaterialWithNewDensity("polyethylene","G4_POLYETHYLENE",0.959*g/cm3);
0129 polyethylene->GetIonisation()->SetMeanExcitationEnergy(56*eV);
0130
0131
0132 polyethylene_NEMA = nist->FindOrBuildMaterial("G4_POLYETHYLENE");
0133
0134
0135
0136 polystyrene = nist->BuildMaterialWithNewDensity( "polystyrene","G4_POLYSTYRENE",0.3*g/cm3);
0137
0138 isotopes = false;
0139
0140
0141 Aluminum = nist->FindOrBuildMaterial("G4_Al", isotopes);
0142
0143
0144 O = nist->FindOrBuildElement("O" , isotopes);
0145 Si = nist->FindOrBuildElement("Si", isotopes);
0146 Gd = nist->FindOrBuildElement("Gd", isotopes);
0147
0148
0149
0150 GSO = new G4Material("GSO", 6.7*g/cm3, 3);
0151 GSO->AddElement(Gd, 2);
0152 GSO->AddElement(Si, 1);
0153 GSO->AddElement(O, 5);
0154 crystalMaterial = nist->FindOrBuildMaterial("GSO");
0155 }
0156
0157
0158
0159 G4VPhysicalVolume* doiPETDetectorConstruction::Construct()
0160 {
0161
0162 worldSizeX = 2 * m;
0163 worldSizeY = 2 * m;
0164 worldSizeZ = 4. * m;
0165
0166
0167
0168 G4Box* solid_world = new G4Box("world", worldSizeX/2., worldSizeY/2., worldSizeZ/2.);
0169
0170
0171 world_logicalV = new G4LogicalVolume(solid_world, air, "world_logicalV", 0,0,0);
0172
0173
0174
0175 world_physicalV = new G4PVPlacement(0,G4ThreeVector(),world_logicalV, "world_physicalV", 0, false, 0, fCheckOverlaps);
0176 world_logicalV->SetVisAttributes (G4VisAttributes::GetInvisible());
0177
0178
0179
0180
0181
0182 blockIndex = 0;
0183
0184
0185 crystalIndex = 0;
0186
0187
0188
0189 ConstructPhantom(world_logicalV);
0190
0191
0192 sizeOfAirBox_DOI = (numberOfCrystal_DOI * sizeOfCrystal_DOI) + (numberOfCrystal_DOI - 1)*crystalGap_DOI;
0193 sizeOfAirBox_axial = (numberOfCrystal_axial * sizeOfCrystal_axial) + (numberOfCrystal_axial - 1)*crystalGap_axial;
0194 sizeOfAirBox_tangential = (numberOfCrystal_tangential * sizeOfCrystal_tangential) + (numberOfCrystal_tangential - 1)*crystalGap_tangential;
0195
0196
0197
0198 pAnalysis = doiPETAnalysis::GetInstance();
0199 pAnalysis->GetSizeOfDetector(sizeOfAirBox_DOI,sizeOfAirBox_tangential, sizeOfAirBox_axial);
0200
0201 G4cout<<"size of crytal element: "<<sizeOfCrystal_tangential<<" "<<sizeOfCrystal_axial<<" "<<sizeOfCrystal_DOI<<G4endl;
0202 G4cout<<"Size of detector block (without Al cover): "<<sizeOfAirBox_tangential<<" "<<sizeOfAirBox_axial<<" "<<sizeOfAirBox_DOI<<G4endl;
0203
0204
0205
0206
0207 sizeOfBlockDetector_DOI = sizeOfAirBox_DOI + AluminumCoverThickness;
0208 sizeOfBlockDetector_axial = sizeOfAirBox_axial + AluminumCoverThickness;
0209 sizeOfBlockDetector_tangential = sizeOfAirBox_tangential + AluminumCoverThickness;
0210
0211
0212
0213
0214 G4Box* blockDetector = new G4Box("blockDetector",sizeOfBlockDetector_DOI/2,sizeOfBlockDetector_tangential/2,sizeOfBlockDetector_axial/2);
0215
0216
0217 blockDetector_logicalV = new G4LogicalVolume(blockDetector,Aluminum,"blockDetector_logicalV", 0,0,0);
0218
0219
0220
0221
0222 G4Box* airBox = new G4Box("airBox", sizeOfAirBox_DOI/2, sizeOfAirBox_tangential/2,sizeOfAirBox_axial/2);
0223
0224
0225 airBox_logicalV = new G4LogicalVolume(airBox,air,"airBox_logicalV", 0,0,0);
0226
0227
0228 airBox_physicalV = new G4PVPlacement (0,G4ThreeVector(0,0,0),airBox_logicalV,"airBox_physicalV", blockDetector_logicalV,false,0,fCheckOverlaps);
0229
0230
0231
0232
0233 for(G4int Ring = 0; Ring< numberOfRings; Ring++)
0234 {
0235
0236
0237 detectorPositionZ = (Ring-((G4double)numberOfRings)/2 + 0.5)*(sizeOfBlockDetector_axial + ringGap - AluminumCoverThickness);
0238
0239 for(G4int i = 0; i<numberOfDetector_perRing; i++)
0240 {
0241
0242 thetaDetector = (double)(i*twopi/numberOfDetector_perRing);
0243
0244
0245 detectorPositionX = (scannerRadius + sizeOfBlockDetector_DOI/2 - AluminumCoverThickness/2)*std::cos(thetaDetector);
0246 detectorPositionY = (scannerRadius + sizeOfBlockDetector_DOI/2 - AluminumCoverThickness/2)*std::sin(thetaDetector);
0247
0248
0249 G4RotationMatrix rotm_PET = G4RotationMatrix();
0250 rotm_PET.rotateZ(thetaDetector);
0251 G4ThreeVector uz_PET = G4ThreeVector(detectorPositionX,detectorPositionY,detectorPositionZ);
0252 G4Transform3D transform = G4Transform3D(rotm_PET,uz_PET);
0253
0254
0255 blockDetector_physicalV = new G4PVPlacement (transform,blockDetector_logicalV,"blockDetector_physicalV", world_logicalV,false,blockIndex,fCheckOverlaps);
0256 blockIndex++;
0257
0258
0259 }
0260 }
0261
0262
0263 G4VSolid* CrystalSolid = new G4Box("Crystal", sizeOfCrystal_DOI/2., sizeOfCrystal_tangential/2., sizeOfCrystal_axial/2.);
0264
0265
0266 crystal_logicalV = new G4LogicalVolume(CrystalSolid,crystalMaterial,"Crystal_logicalV", 0,0,0);
0267
0268
0269 for(G4int i_DOI = 0; i_DOI<numberOfCrystal_DOI; i_DOI++){
0270 crystalPositionX=(i_DOI-((G4double)numberOfCrystal_DOI)/2 + 0.5)*(sizeOfCrystal_DOI + crystalGap_DOI);
0271 for(G4int i_axial=0; i_axial< numberOfCrystal_axial;i_axial++){
0272 crystalPositionZ = (i_axial-((G4double)numberOfCrystal_axial)/2 + 0.5)*(sizeOfCrystal_axial + crystalGap_axial);
0273 for(G4int i_tan=0; i_tan<numberOfCrystal_tangential;i_tan++){
0274 crystalPositionY=(i_tan-((G4double)numberOfCrystal_tangential)/2 + 0.5)*(sizeOfCrystal_tangential + crystalGap_tangential);
0275
0276
0277
0278 crystal_physicalV = new G4PVPlacement (0, G4ThreeVector (crystalPositionX,crystalPositionY,crystalPositionZ), crystal_logicalV, "Crystal_physicalV", airBox_logicalV,false,crystalIndex);
0279 crystalIndex++;
0280 }
0281 }
0282 }
0283
0284
0285
0286
0287 G4VisAttributes* blockDetectorVisAtt;
0288 blockDetectorVisAtt = new G4VisAttributes(G4Colour(1,1.0,1.0));
0289 blockDetectorVisAtt->SetVisibility (true);
0290
0291 blockDetector_logicalV->SetVisAttributes (blockDetectorVisAtt);
0292
0293
0294
0295 G4VisAttributes* airBoxVisAtt;
0296 airBoxVisAtt = new G4VisAttributes(G4Colour(1,1.0,1.0));
0297 airBoxVisAtt->SetVisibility (true);
0298 airBoxVisAtt->SetForceWireframe (true);
0299 airBox_logicalV->SetVisAttributes (airBoxVisAtt);
0300 airBox_logicalV->SetVisAttributes (G4VisAttributes::GetInvisible());
0301
0302
0303 G4VisAttributes* crystalVisAtt;
0304 crystalVisAtt = new G4VisAttributes(G4Colour(0.88,0.55,1.0));
0305
0306 crystalVisAtt->SetForceWireframe (true);
0307 crystal_logicalV->SetVisAttributes (crystalVisAtt);
0308 crystal_logicalV->SetVisAttributes (G4VisAttributes::GetInvisible());
0309
0310
0311
0312 return world_physicalV;
0313 }
0314
0315
0316
0317
0318 void doiPETDetectorConstruction::ConstructPhantom(G4LogicalVolume* worldLogical)
0319 {
0320 G4cout<<"------------------================- " <<PhantomType<<" Phantom has been used -==================-----------\n"<<G4endl;
0321
0322
0323 if(PhantomType == "NEMA_imageQualityPhantom_wholeBody"){
0324
0325
0326
0327
0328
0329
0330 yOffsetBodyPhantom = 35*mm;
0331
0332
0333 zOffsetBodyPhantom =70*mm;
0334
0335
0336 lengthOfBodyPhantom = 180*mm;
0337
0338
0339 radiusOfBodyPhantom = 147 * mm;
0340
0341
0342 wallThicknessOfBodyPhantom = 3 * mm;
0343
0344
0345 radiusOfSmallcyl = 77 * mm;
0346 boxWidth = 140*mm;
0347 boxHeight = 77 * mm;
0348
0349
0350
0351
0352
0353 G4Tubs* halfcyl_pmma = new G4Tubs("halfcyl_pmma", 0*mm,(radiusOfBodyPhantom + wallThicknessOfBodyPhantom),(lengthOfBodyPhantom + wallThicknessOfBodyPhantom)/2,0*deg,180*deg);
0354
0355
0356 G4Tubs* cyl1_pmma = new G4Tubs("cyl_pmma", 0*mm,radiusOfSmallcyl + wallThicknessOfBodyPhantom, (lengthOfBodyPhantom + wallThicknessOfBodyPhantom)/2,0*deg,360*deg);
0357 G4Tubs* cyl2_pmma = new G4Tubs("cyl_pmma", 0*mm,radiusOfSmallcyl + wallThicknessOfBodyPhantom, (lengthOfBodyPhantom + wallThicknessOfBodyPhantom)/2,0*deg,360*deg);
0358
0359
0360 G4Box* box_pmma = new G4Box("box_pmma", boxWidth/2, (boxHeight + wallThicknessOfBodyPhantom)/2, (lengthOfBodyPhantom + wallThicknessOfBodyPhantom)/2);
0361
0362
0363 G4ThreeVector translation_cyl1 = G4ThreeVector(boxWidth/2, 0, 0);
0364
0365
0366 G4ThreeVector translation_cyl2 = G4ThreeVector(-boxWidth/2, 0, 0);
0367
0368
0369 G4ThreeVector translation_box = G4ThreeVector(0,-(boxHeight + wallThicknessOfBodyPhantom)/2, 0);
0370
0371
0372 G4UnionSolid* union1_pmma = new G4UnionSolid("union1",halfcyl_pmma,cyl1_pmma,0,translation_cyl1);
0373
0374
0375 G4UnionSolid* union2_pmma = new G4UnionSolid("union2",union1_pmma,cyl2_pmma,0,translation_cyl2);
0376
0377
0378
0379 G4UnionSolid* phantom = new G4UnionSolid("phantom",union2_pmma,box_pmma,0,translation_box);
0380
0381
0382 phantom_logicalV = new G4LogicalVolume(phantom, pmma, "phantom_logicalV",0,0,0);
0383
0384
0385 phantom_physicalV = new G4PVPlacement(0, G4ThreeVector(0,-yOffsetBodyPhantom,-(lengthOfBodyPhantom + 2*wallThicknessOfBodyPhantom)/2 + zOffsetBodyPhantom), phantom_logicalV, "pmma_phantom_physicalV", worldLogical, false, 0, fCheckOverlaps);
0386
0387
0388
0389
0390
0391
0392 G4Tubs* halfcyl_water = new G4Tubs("halfcyl_water", 0*mm,radiusOfBodyPhantom,lengthOfBodyPhantom/2,0*deg,180*deg);
0393
0394
0395 G4Tubs* cyl1_water = new G4Tubs("cyl_water", 0*mm,radiusOfSmallcyl, lengthOfBodyPhantom/2,0*deg,360*deg);
0396 G4Tubs* cyl2_water = new G4Tubs("cyl_water", 0*mm,radiusOfSmallcyl, lengthOfBodyPhantom/2,0*deg,360*deg);
0397
0398
0399 G4Box* box_water = new G4Box("box_water", boxWidth/2, boxHeight/2, lengthOfBodyPhantom/2);
0400
0401
0402 G4ThreeVector translation_cyl1_water = G4ThreeVector(boxWidth/2, 0, 0);
0403
0404
0405 G4ThreeVector translation_cyl2_water = G4ThreeVector(-boxWidth/2, 0, 0);
0406
0407
0408 G4ThreeVector translation_box_water = G4ThreeVector(0,-boxHeight/2, 0);
0409
0410
0411 G4UnionSolid* union1_water = new G4UnionSolid("union1",halfcyl_water,cyl1_water,0,translation_cyl1_water);
0412
0413
0414 G4UnionSolid* union2_water = new G4UnionSolid("union2",union1_water,cyl2_water,0,translation_cyl2_water);
0415
0416
0417
0418 G4UnionSolid* phantom_water = new G4UnionSolid("phantom_water",union2_water,box_water,0,translation_box_water);
0419
0420
0421 water_logicalV = new G4LogicalVolume(phantom_water, water, "phantom_logicalV",0,0,0);
0422
0423
0424 water_physicalV = new G4PVPlacement(0, G4ThreeVector(0,0,0), water_logicalV, "phantom_physicalV", phantom_logicalV, false, 0, fCheckOverlaps);
0425
0426
0427
0428
0429
0430 G4double wallThiknessOfLungPhantom = 4 *mm;
0431 radiusOfLungPhantom = 21 *mm;
0432
0433
0434
0435 G4Tubs* phantom_lungPMMA = new G4Tubs("Phantom_lung", 0*mm, radiusOfLungPhantom + wallThiknessOfLungPhantom,lengthOfBodyPhantom/2,0*deg,360*deg);
0436
0437
0438 lung_logicalV_PMMA = new G4LogicalVolume(phantom_lungPMMA, pmma, "coldRegion_logicalV",0,0,0);
0439
0440
0441 lung_physicalVPMMA = new G4PVPlacement(0, G4ThreeVector(0,yOffsetBodyPhantom,0), lung_logicalV_PMMA, "coldRegion_physicalV", water_logicalV, false, 0, fCheckOverlaps);
0442
0443
0444
0445 G4Tubs* phantom_lung = new G4Tubs("Phantom_lung", 0*mm,radiusOfLungPhantom,lengthOfBodyPhantom/2,0*deg,360*deg);
0446
0447
0448 lung_logicalV = new G4LogicalVolume(phantom_lung, polystyrene, "coldRegion_logicalV",0,0,0);
0449
0450
0451 lung_physicalV = new G4PVPlacement(0, G4ThreeVector(0,0,0), lung_logicalV, "coldRegion_physicalV", lung_logicalV_PMMA, false, 0, fCheckOverlaps);
0452
0453
0454
0455
0456
0457
0458 hieghtOfTestPhantom = 705* mm;
0459 diameterOfTestPhantom = 203 * mm;
0460 G4double zOffset_testPhantom = 0*mm;
0461
0462
0463 G4Tubs* phantom_test = new G4Tubs("Phantom", 0*mm,diameterOfTestPhantom/2,hieghtOfTestPhantom/2,0*deg,360*deg);
0464
0465
0466 test_logicalV = new G4LogicalVolume(phantom_test, polyethylene_NEMA, "phantom_logicalV",0,0,0);
0467
0468
0469 test_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,hieghtOfTestPhantom/2+zOffsetBodyPhantom + zOffset_testPhantom), test_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0470
0471
0472
0473
0474
0475 distanceFromCenter = 114.4*mm;
0476
0477
0478 numberOfSpheres = 6;
0479
0480
0481 sphereWallThickness = 1*mm;
0482
0483
0484 zOffsetSpherePhantom = lengthOfBodyPhantom/2 + wallThicknessOfBodyPhantom- zOffsetBodyPhantom;
0485
0486
0487 for(G4int i = 0; i < numberOfSpheres; i++){
0488 if(i == 0) sphereDiameter = 37*mm;
0489 if(i == 1) sphereDiameter = 10*mm;
0490 if(i == 2) sphereDiameter = 13*mm;
0491 if(i == 3) sphereDiameter = 17*mm;
0492 if(i == 4) sphereDiameter = 22*mm;
0493 if(i == 5) sphereDiameter = 28*mm;
0494
0495 spherePositionX = distanceFromCenter/2*std::cos(((G4double)i*twopi/numberOfSpheres));
0496 spherePositionY = distanceFromCenter/2*std::sin(((G4double)i*twopi/numberOfSpheres));
0497
0498
0499
0500 if(i>0 && i <5){
0501
0502
0503
0504 G4Sphere* hotSpherePMMA = new G4Sphere("hotSphere", 0., sphereDiameter/2 + sphereWallThickness, 0*deg, 360*deg, 0*deg, 180*deg);
0505
0506
0507 hotSpherePMMA_logicalV = new G4LogicalVolume(hotSpherePMMA, pmma , "hotSphere_logicalV",0,0,0);
0508
0509
0510 hotSpherePMMA_physicalV = new G4PVPlacement(0, G4ThreeVector(spherePositionX,spherePositionY+yOffsetBodyPhantom,zOffsetSpherePhantom), hotSpherePMMA_logicalV, "hotSphere_physicalV", water_logicalV, false, i,fCheckOverlaps);
0511
0512
0513
0514
0515 G4Sphere* hotSphereWater = new G4Sphere("hotSphere", 0., sphereDiameter/2, 0*deg, 360*deg, 0*deg, 180*deg);
0516
0517
0518 hotSphereWater_logicalV = new G4LogicalVolume(hotSphereWater, water , "hotSphere_logicalV",0,0,0);
0519
0520
0521 hotSphereWater_physicalV = new G4PVPlacement(0, G4ThreeVector(0,0,0), hotSphereWater_logicalV, "phantom_physicalV", hotSpherePMMA_logicalV, false, i,fCheckOverlaps);
0522
0523
0524
0525 }
0526
0527
0528 if(i==0 || i==5){
0529
0530
0531 G4Sphere* coldSpherePMMA = new G4Sphere("coldSphere", 0., sphereDiameter/2 + sphereWallThickness, 0*deg, 360*deg, 0*deg, 180*deg);
0532
0533
0534 coldSpherePMMA_logicalV = new G4LogicalVolume(coldSpherePMMA, pmma , "coldRegion_logicalV",0,0,0);
0535
0536
0537 coldSpherePMMA_physicalV = new G4PVPlacement(0, G4ThreeVector(spherePositionX,spherePositionY+yOffsetBodyPhantom,zOffsetSpherePhantom), coldSpherePMMA_logicalV, "coldRegion_physicalV", water_logicalV, false, i,fCheckOverlaps);
0538
0539
0540
0541
0542 G4Sphere* coldSphereWater = new G4Sphere("coldSphere", 0., sphereDiameter/2, 0*deg, 360*deg, 0*deg, 180*deg);
0543
0544
0545 coldSphereWater_logicalV = new G4LogicalVolume(coldSphereWater, water , "coldRegion_logicalV",0,0,0);
0546
0547
0548 coldSphereWater_physicalV = new G4PVPlacement(0, G4ThreeVector(0,0,0), coldSphereWater_logicalV, "coldRegion_physicalV", coldSpherePMMA_logicalV, false, i,fCheckOverlaps);
0549
0550
0551
0552 }
0553 }
0554 }
0555
0556 else if(PhantomType == "NEMA_imageQualityPhantom_smallAnimal"){
0557
0558
0559
0560
0561 phantomRadius = 16.75*mm;
0562
0563
0564 phantomLength = 63*mm;
0565
0566
0567 waterPhantomRadius = 15*mm;
0568 waterPhantomLength = 30*mm;
0569
0570
0571
0572 rodPhantomLength = 20*mm;
0573
0574
0575 numberOfRods = 5;
0576
0577
0578 distanceFromCenter = 7*mm;
0579
0580
0581
0582 G4Tubs* phantom = new G4Tubs("Phantom", 0*mm,phantomRadius,phantomLength/2,0*deg,360*deg);
0583
0584
0585 phantom_logicalV = new G4LogicalVolume(phantom, pmma, "phantom_logicalV",0,0,0);
0586
0587
0588 phantom_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,0), phantom_logicalV, "pmma_phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0589
0590
0591 rodPositionZ = -waterPhantomLength/2;
0592
0593 for(G4int i = 0; i < numberOfRods; i++){
0594
0595 if(i == 0) rodDiameter = 1 * mm;
0596 if(i == 1) rodDiameter = 2 * mm;
0597 if(i == 2) rodDiameter = 3 * mm;
0598 if(i == 3) rodDiameter = 4 * mm;
0599 if(i == 4) rodDiameter = 5 * mm;
0600
0601 rodPositionX = distanceFromCenter*std::cos(((G4double)i*twopi/numberOfRods));
0602 rodPositionY = distanceFromCenter*std::sin(((G4double)i*twopi/numberOfRods));
0603
0604
0605 G4Tubs* rod_phantom = new G4Tubs("Phantom", 0*mm,rodDiameter/2,rodPhantomLength/2,0*deg,360*deg);
0606
0607
0608 rod_phantom_logicalV = new G4LogicalVolume(rod_phantom, water, "rod_phantom_logicalV",0,0,0);
0609
0610
0611 rod_phantom_physicalV = new G4PVPlacement(0,G4ThreeVector(rodPositionX,rodPositionY,rodPositionZ), rod_phantom_logicalV, "phantom_physicalV", phantom_logicalV, false, 0, fCheckOverlaps);
0612 }
0613
0614
0615 chamberPhantomLength = 15*mm;
0616 chamberDiameter = 10*mm;
0617
0618
0619 wallThicknessOfChamber = 1*mm;
0620
0621
0622 chamberPositionX = distanceFromCenter;
0623 chamberPositionY = 0*mm;
0624 chamberPositionZ = waterPhantomLength/2 - chamberPhantomLength/2;
0625
0626
0627 G4Tubs* water_phantom = new G4Tubs("Phantom", 0*mm,waterPhantomRadius,waterPhantomLength/2,0*deg,360*deg);
0628
0629 waterPhantom_logicalV = new G4LogicalVolume(water_phantom, water, "waterPhantom_logicalV",0,0,0);
0630
0631
0632 WaterPhantom_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,rodPhantomLength/2), waterPhantom_logicalV, "phantom_physicalV", phantom_logicalV, false, 0,fCheckOverlaps);
0633
0634
0635
0636 G4Tubs* chamberPMMA = new G4Tubs("chamber_phantom1", 0*mm,chamberDiameter/2,chamberPhantomLength/2,0*deg,360*deg);
0637
0638
0639 chamberPMMA_logicalV = new G4LogicalVolume(chamberPMMA, pmma, "chamberPMMA_logicalV",0,0,0);
0640
0641
0642 chamberPMMA_physicalV = new G4PVPlacement(0,G4ThreeVector(chamberPositionX, chamberPositionY, chamberPositionZ), chamberPMMA_logicalV, "pmma_phantom_physicalV", waterPhantom_logicalV, false, 0,fCheckOverlaps);
0643
0644
0645
0646
0647
0648 G4Tubs* chamberWater = new G4Tubs("chamber_phantom1", 0*mm,chamberDiameter/2 - wallThicknessOfChamber,chamberPhantomLength/2 - wallThicknessOfChamber,0*deg,360*deg);
0649
0650
0651 chamberWater_logicalV = new G4LogicalVolume(chamberWater, water, "chamber_phantom_logicalV",0,0,0);
0652
0653
0654 chamberWater_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,0), chamberWater_logicalV, "coldRegion_physicalV", chamberPMMA_logicalV, false, 0,fCheckOverlaps);
0655
0656
0657
0658 chamberPMMA_physicalV = new G4PVPlacement(0,G4ThreeVector(-chamberPositionX, chamberPositionY, chamberPositionZ), chamberPMMA_logicalV, "pmma_phantom_physicalV", waterPhantom_logicalV, false, 0,fCheckOverlaps);
0659
0660
0661 G4Tubs* chamberAir = new G4Tubs("chamber_phantom1", 0*mm,chamberDiameter/2 - wallThicknessOfChamber,chamberPhantomLength/2 - wallThicknessOfChamber,0*deg,360*deg);
0662
0663
0664 chamberAir_logicalV = new G4LogicalVolume(chamberAir, air, "chamber_phantom_logicalV",0,0,0);
0665
0666
0667 chamberAir_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,0), chamberAir_logicalV, "coldRegion_physicalV", chamberPMMA_logicalV, false, 0,fCheckOverlaps);
0668
0669 }
0670
0671 else if(PhantomType == "NEMA_phantom_NECR"){
0672
0673
0674
0675
0676 G4Tubs* phantom = new G4Tubs("Phantom", 0*mm,phantomRadius,phantomLength/2,0*deg,360*deg);
0677
0678
0679 phantom_logicalV = new G4LogicalVolume(phantom, polyethylene_NEMA, "phantom_logicalV",0,0,0);
0680
0681
0682 phantom_physicalV = new G4PVPlacement(0,G4ThreeVector(0,0,0), phantom_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0683 }
0684 else if(PhantomType == "Phantom_sensitivity"){
0685
0686
0687
0688
0689
0690
0691
0692 G4double Rmin, Rmax;
0693 G4cout<<"Total number of sleeves : "<<numOfSleeves<<G4endl;
0694
0695 for(G4int i=0; i<numOfSleeves; i++){
0696 if(i==0){
0697 Rmin = 3.9/2 * mm;
0698 Rmax = 3.2 * mm;
0699 }
0700 if(i==1){
0701 Rmin = 7.0/2 * mm;
0702 Rmax = 4.75 * mm;
0703 }
0704 if(i==2){
0705 Rmin = 10.2/2 * mm;
0706 Rmax = 6.35*mm;
0707 }
0708 if(i==3){
0709 Rmin = 13.4/2 * mm;
0710 Rmax = 7.95 *mm;
0711 }
0712 if(i==4){
0713 Rmin = 16.6/2 * mm;
0714 Rmax = 9.55 * mm;
0715
0716 }
0717 G4cout<<"Sleeve "<<i+1 <<" is placed, Rmin = "<<Rmin<< " mm, Rmax = "<<Rmax<< " mm, "<< "length = " <<phantomLength <<" mm."<<G4endl;
0718
0719
0720 G4Tubs* phantom = new G4Tubs("Phantom_sensitivity", Rmin,Rmax,phantomLength/2,0*deg,360*deg);
0721
0722
0723 phantom_logicalV = new G4LogicalVolume(phantom, Aluminum, "phantom_logicalV",0,0,0);
0724
0725
0726 phantom_physicalV = new G4PVPlacement(0, phantomPosition, phantom_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0727 }
0728
0729
0730 G4Tubs* phantomPE = new G4Tubs("Phantom_sensitivity", 0 *mm,1.5*mm,phantomLength/2,0*deg,360*deg);
0731
0732
0733 phantomPE_logicalV = new G4LogicalVolume(phantomPE, polyethylene_NEMA, "phantom_logicalV",0,0,0);
0734
0735
0736 phantomPE_physicalV = new G4PVPlacement(0, phantomPosition, phantomPE_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0737
0738
0739 G4cout<<"---------------Phantom dimension: "<<"radius (mm) = "<<phantomRadius<<" "<<"Length (mm) = "<<phantomLength<<G4endl;
0740 G4cout<<"---------------Phantom position (mm) : "<<phantomPosition<<G4endl;
0741 }
0742 else if(PhantomType == "Phantom_spatialResolution"){
0743
0744
0745
0746
0747
0748 G4Tubs* phantom = new G4Tubs("Phantom_point", 0., phantomRadius,phantomLength/2,0*deg,360*deg);
0749
0750
0751 phantom_logicalV = new G4LogicalVolume(phantom, polyethylene_NEMA , "phantom_logicalV",0,0,0);
0752
0753
0754 phantomPosition = G4ThreeVector(phantomPosition.x(),phantomPosition.y(),phantomPosition.z());
0755
0756
0757 phantom_physicalV = new G4PVPlacement(0, phantomPosition, phantom_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0758 G4cout<<"---------------Phantom dimension: "<<"radius (mm) = "<<phantomRadius<<" "<<", Length (mm) = "<<phantomLength<<G4endl;
0759 G4cout<<"---------------Phantom position: "<<phantomPosition<< "mm"<<G4endl;
0760 }
0761
0762 else if (PhantomType == "Normalization")
0763 {
0764
0765
0766
0767
0768 G4Tubs* phantom = new G4Tubs("Phantom", phantomRadius - 3*mm, phantomRadius,phantomLength/2,0*deg,360*deg);
0769
0770
0771 phantom_logicalV = new G4LogicalVolume(phantom, polyethylene_NEMA, "phantom_logicalV",0,0,0);
0772
0773
0774 phantom_physicalV = new G4PVPlacement(0, phantomPosition, phantom_logicalV, "phantom_physicalV", worldLogical, false, 0,fCheckOverlaps);
0775
0776
0777 G4cout<<"---------------Phantom dimension: "<<"radius (mm) = "<<phantomRadius<<" "<<"Length = "<<phantomLength<<G4endl;
0778 G4cout<<"---------------Phantom position : "<<phantomPosition<< "mm"<<G4endl;
0779
0780 }
0781
0782 else
0783 {
0784 G4cerr << "****************************************\nERROR: Phantom Remains: " << PhantomType <<"\n****************************************" << G4endl;
0785 exit(0);
0786
0787 }
0788
0789
0790 G4VisAttributes* phantomVisAtt;
0791 phantomVisAtt = new G4VisAttributes(G4Colour(0.88,0.55,1.0));
0792 phantomVisAtt->SetVisibility (true);
0793 phantomVisAtt->SetForceWireframe (true);
0794 phantom_logicalV->SetVisAttributes (phantomVisAtt);
0795
0796 }
0797
0798
0799 void doiPETDetectorConstruction::ChangePhantom(G4String NewPhantomtype)
0800 {
0801 PhantomType = NewPhantomtype;
0802 }
0803
0804
0805 void doiPETDetectorConstruction::SetPhantomPosition(G4ThreeVector NewphantomPosition)
0806 {
0807 phantomPosition = NewphantomPosition;
0808 }
0809
0810
0811 void doiPETDetectorConstruction::SetPhantomRadius(G4double newPhantomRadius){
0812 phantomRadius = newPhantomRadius;
0813 }
0814
0815
0816 void doiPETDetectorConstruction::SetPhantomLength(G4double newPhantomLength){
0817 phantomLength = newPhantomLength;
0818 }
0819
0820 void doiPETDetectorConstruction::SetNumberOfSleeves(G4int NewNumOfSleeves){
0821 numOfSleeves = NewNumOfSleeves;
0822
0823 }