File indexing completed on 2026-09-16 08:30:46
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 #include "RE02DetectorConstruction.hh"
0030
0031 #include "RE02NestedPhantomParameterisation.hh"
0032
0033 #include "G4Box.hh"
0034 #include "G4Colour.hh"
0035 #include "G4LogicalVolume.hh"
0036 #include "G4Material.hh"
0037 #include "G4NistManager.hh"
0038 #include "G4PSCellFlux3D.hh"
0039 #include "G4PSEnergyDeposit3D.hh"
0040 #include "G4PSFlatSurfaceCurrent3D.hh"
0041 #include "G4PSFlatSurfaceFlux3D.hh"
0042 #include "G4PSNofStep3D.hh"
0043 #include "G4PSPassageCellFlux3D.hh"
0044 #include "G4PVParameterised.hh"
0045 #include "G4PVPlacement.hh"
0046 #include "G4SDChargedFilter.hh"
0047 #include "G4SDManager.hh"
0048 #include "G4SDParticleFilter.hh"
0049 #include "G4SDParticleWithEnergyFilter.hh"
0050 #include "G4SystemOfUnits.hh"
0051 #include "G4VisAttributes.hh"
0052 #include "G4ios.hh"
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 RE02DetectorConstruction::RE02DetectorConstruction() : G4VUserDetectorConstruction()
0099 {
0100
0101 fPhantomSize.setX(200. * mm);
0102 fPhantomSize.setY(200. * mm);
0103 fPhantomSize.setZ(400. * mm);
0104 fNx = fNy = fNz = 100;
0105 fInsertLead = TRUE;
0106 }
0107
0108
0109 RE02DetectorConstruction::~RE02DetectorConstruction()
0110 {
0111 ;
0112 }
0113
0114
0115 G4VPhysicalVolume* RE02DetectorConstruction::Construct()
0116 {
0117
0118
0119
0120
0121
0122
0123
0124 G4NistManager* NISTman = G4NistManager::Instance();
0125 G4Material* air = NISTman->FindOrBuildMaterial("G4_AIR");
0126 G4Material* water = NISTman->FindOrBuildMaterial("G4_WATER");
0127 G4Material* lead = NISTman->FindOrBuildMaterial("G4_Pb");
0128
0129
0130
0131 G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
0132 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 G4ThreeVector worldSize = G4ThreeVector(200 * cm, 200 * cm, 200 * cm);
0143
0144 G4Box* solidWorld =
0145 new G4Box("world", worldSize.x() / 2., worldSize.y() / 2., worldSize.z() / 2.);
0146 G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, air, "World", 0, 0, 0);
0147
0148
0149
0150 G4VPhysicalVolume* physiWorld = new G4PVPlacement(0,
0151 G4ThreeVector(),
0152 logicWorld,
0153 "World",
0154 0,
0155 false,
0156 0);
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 G4ThreeVector phantomSize = fPhantomSize;
0168
0169 G4Box* solidPhantom =
0170 new G4Box("phantom", phantomSize.x() / 2., phantomSize.y() / 2., phantomSize.z() / 2.);
0171 G4LogicalVolume* logicPhantom = new G4LogicalVolume(solidPhantom, water, "Phantom", 0, 0, 0);
0172
0173 G4RotationMatrix* rot = new G4RotationMatrix();
0174
0175 G4ThreeVector positionPhantom;
0176
0177 new G4PVPlacement(rot,
0178 positionPhantom,
0179 logicPhantom,
0180 "Phantom",
0181 logicWorld,
0182 false,
0183 0);
0184
0185
0186
0187
0188
0189 G4cout << "<-- RE02DetectorConstruction::Construct-------" << G4endl;
0190 G4cout << " Water Phantom Size " << fPhantomSize / mm << G4endl;
0191 G4cout << " Segmentation (" << fNx << "," << fNy << "," << fNz << ")" << G4endl;
0192 G4cout << " Lead plate at even copy # (0-False,1-True): " << IsLeadSegment() << G4endl;
0193 G4cout << "<---------------------------------------------" << G4endl;
0194
0195
0196 G4int nxCells = fNx;
0197 G4int nyCells = fNy;
0198 G4int nzCells = fNz;
0199
0200 G4ThreeVector sensSize;
0201 sensSize.setX(phantomSize.x() / (G4double)nxCells);
0202 sensSize.setY(phantomSize.y() / (G4double)nyCells);
0203 sensSize.setZ(phantomSize.z() / (G4double)nzCells);
0204
0205
0206
0207
0208
0209 G4String yRepName("RepY");
0210 G4VSolid* solYRep =
0211 new G4Box(yRepName, phantomSize.x() / 2., sensSize.y() / 2., phantomSize.z() / 2.);
0212 G4LogicalVolume* logYRep = new G4LogicalVolume(solYRep, water, yRepName);
0213
0214 new G4PVReplica(yRepName, logYRep, logicPhantom, kYAxis, fNy, sensSize.y());
0215
0216 G4String xRepName("RepX");
0217 G4VSolid* solXRep =
0218 new G4Box(xRepName, sensSize.x() / 2., sensSize.y() / 2., phantomSize.z() / 2.);
0219 G4LogicalVolume* logXRep = new G4LogicalVolume(solXRep, water, xRepName);
0220
0221 new G4PVReplica(xRepName, logXRep, logYRep, kXAxis, fNx, sensSize.x());
0222
0223
0224
0225
0226
0227
0228 G4String zVoxName("phantomSens");
0229 G4VSolid* solVoxel = new G4Box(zVoxName, sensSize.x() / 2., sensSize.y() / 2., sensSize.z() / 2.);
0230 fLVPhantomSens = new G4LogicalVolume(solVoxel, water, zVoxName);
0231
0232
0233 std::vector<G4Material*> phantomMat(2, water);
0234 if (IsLeadSegment()) phantomMat[1] = lead;
0235
0236
0237
0238
0239 RE02NestedPhantomParameterisation* paramPhantom =
0240 new RE02NestedPhantomParameterisation(sensSize / 2., nzCells, phantomMat);
0241
0242 new G4PVParameterised("PhantomSens",
0243 fLVPhantomSens,
0244 logXRep,
0245 kUndefined,
0246 nzCells,
0247 paramPhantom);
0248
0249
0250
0251
0252
0253
0254
0255
0256 G4VisAttributes* boxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0257 logicWorld->SetVisAttributes(boxVisAtt);
0258
0259
0260
0261 G4VisAttributes* phantomVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0));
0262 logicPhantom->SetVisAttributes(phantomVisAtt);
0263
0264
0265 G4VisAttributes* yRepVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
0266 logYRep->SetVisAttributes(yRepVisAtt);
0267 G4VisAttributes* xRepVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
0268 logXRep->SetVisAttributes(xRepVisAtt);
0269
0270
0271 fLVPhantomSens->SetVisAttributes(G4VisAttributes::GetInvisible());
0272
0273 return physiWorld;
0274 }
0275
0276 void RE02DetectorConstruction::ConstructSDandField()
0277 {
0278
0279
0280
0281
0282
0283 G4SDManager* pSDman = G4SDManager::GetSDMpointer();
0284
0285
0286 G4String phantomSDname = "PhantomSD";
0287
0288
0289
0290
0291
0292
0293 G4MultiFunctionalDetector* mFDet = new G4MultiFunctionalDetector(phantomSDname);
0294 pSDman->AddNewDetector(mFDet);
0295 fLVPhantomSens->SetSensitiveDetector(mFDet);
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 G4String fltName, particleName;
0306
0307
0308 G4SDParticleFilter* protonFilter =
0309 new G4SDParticleFilter(fltName = "protonFilter", particleName = "proton");
0310
0311
0312 G4SDParticleFilter* electronFilter = new G4SDParticleFilter(fltName = "electronFilter");
0313 electronFilter->add(particleName = "e+");
0314 electronFilter->add(particleName = "e-");
0315
0316
0317 G4SDChargedFilter* chargedFilter = new G4SDChargedFilter(fltName = "chargedFilter");
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 G4String psName;
0328 G4PSEnergyDeposit3D* scorer0 = new G4PSEnergyDeposit3D(psName = "totalEDep", fNx, fNy, fNz);
0329 G4PSEnergyDeposit3D* scorer1 = new G4PSEnergyDeposit3D(psName = "protonEDep", fNx, fNy, fNz);
0330 scorer1->SetFilter(protonFilter);
0331
0332
0333
0334 G4PSNofStep3D* scorer2 = new G4PSNofStep3D(psName = "protonNStep", fNx, fNy, fNz);
0335 scorer2->SetFilter(protonFilter);
0336
0337
0338
0339 G4PSPassageCellFlux3D* scorer3 =
0340 new G4PSPassageCellFlux3D(psName = "chargedPassCellFlux", fNx, fNy, fNz);
0341 G4PSCellFlux3D* scorer4 = new G4PSCellFlux3D(psName = "chargedCellFlux", fNx, fNy, fNz);
0342 G4PSFlatSurfaceFlux3D* scorer5 =
0343 new G4PSFlatSurfaceFlux3D(psName = "chargedSurfFlux", fFlux_InOut, fNx, fNy, fNz);
0344 scorer3->SetFilter(chargedFilter);
0345 scorer4->SetFilter(chargedFilter);
0346 scorer5->SetFilter(chargedFilter);
0347
0348
0349
0350
0351
0352 mFDet->RegisterPrimitive(scorer0);
0353 mFDet->RegisterPrimitive(scorer1);
0354 mFDet->RegisterPrimitive(scorer2);
0355 mFDet->RegisterPrimitive(scorer3);
0356 mFDet->RegisterPrimitive(scorer4);
0357 mFDet->RegisterPrimitive(scorer5);
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 for (G4int i = 0; i < 4; i++) {
0372 std::ostringstream name;
0373 name << "gammaSurfCurr" << std::setfill('0') << std::setw(3) << i;
0374 G4String psgName = name.str();
0375 G4double kmin = std::pow(10., (G4double)i) * keV;
0376 G4double kmax = std::pow(10., (G4double)(i + 1)) * keV;
0377
0378 G4SDParticleWithEnergyFilter* pkinEFilter =
0379 new G4SDParticleWithEnergyFilter(fltName = "gammaE filter", kmin, kmax);
0380 pkinEFilter->add("gamma");
0381 pkinEFilter->show();
0382
0383 G4PSFlatSurfaceCurrent3D* scorer =
0384 new G4PSFlatSurfaceCurrent3D(psgName, fCurrent_InOut, fNx, fNy, fNz);
0385 scorer->SetFilter(pkinEFilter);
0386 mFDet->RegisterPrimitive(scorer);
0387 }
0388 }