File indexing completed on 2026-09-19 08:38:07
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 #include "DetectorConstruction.hh"
0047
0048 #include "ScoreLET.hh"
0049 #include "ScoreSpecies.hh"
0050 #include "ScoreStrandBreaks.hh"
0051
0052 #include "G4Box.hh"
0053 #include "G4GeometryManager.hh"
0054 #include "G4LogicalVolume.hh"
0055 #include "G4LogicalVolumeStore.hh"
0056 #include "G4MultiFunctionalDetector.hh"
0057 #include "G4NistManager.hh"
0058 #include "G4PVPlacement.hh"
0059 #include "G4PhysicalConstants.hh"
0060 #include "G4RunManager.hh"
0061 #include "G4SDManager.hh"
0062 #include "G4SystemOfUnits.hh"
0063 #include "G4VPrimitiveScorer.hh"
0064 #include "G4VisAttributes.hh"
0065
0066
0067
0068 DetectorConstruction::DetectorConstruction() : G4VUserDetectorConstruction()
0069 {
0070 fDetDir = new G4UIdirectory("/det/");
0071 fDetDir->SetGuidance("Detector control.");
0072
0073 fSizeCmd = new G4UIcmdWithADoubleAndUnit("/det/setSize", this);
0074 fSizeCmd->SetDefaultUnit("um");
0075
0076 fpOffSetFileUI = new G4UIcmdWithAString("/det/OffSetFile", this);
0077 fpPlasmidNbUI = new G4UIcmdWithAnInteger("/det/NbOfPlasmids", this);
0078
0079 fpPlasmidFile = new G4UIcmdWithAString("/det/PlasmidFile", this);
0080 fpUseDNA = new G4UIcmdWithABool("/det/UseDNAVolumes", this);
0081 }
0082
0083
0084
0085 DetectorConstruction::~DetectorConstruction()
0086 {
0087 delete fSizeCmd;
0088 delete fpOffSetFileUI;
0089 delete fpPlasmidFile;
0090 delete fpUseDNA;
0091 }
0092
0093
0094
0095 void DetectorConstruction::SetNewValue(G4UIcommand* command, G4String newValue)
0096 {
0097 if (command == fSizeCmd) {
0098 G4double size = fSizeCmd->GetNewDoubleValue(newValue);
0099 SetSize(size);
0100 }
0101
0102 if (command == fpPlasmidNbUI) {
0103 fNbOfPlasmids = fpPlasmidNbUI->GetNewIntValue(newValue);
0104 }
0105
0106 if (command == fpOffSetFileUI) {
0107 G4String File = newValue;
0108 ReadOffsetFile(File);
0109 }
0110
0111 if (command == fpPlasmidFile) {
0112 fPlasmidFile = newValue;
0113 }
0114
0115 if (command == fpUseDNA) {
0116 fUseDNAVolumes = fpUseDNA->GetNewBoolValue(newValue);
0117 }
0118 }
0119
0120
0121
0122 void DetectorConstruction::SetSize(G4double size)
0123 {
0124 G4GeometryManager::GetInstance()->OpenGeometry();
0125 fPlasmidEnvelope->SetRadius(size / 2);
0126 G4RunManager::GetRunManager()->GeometryHasBeenModified();
0127 G4cout << "#### the geometry has been modified " << G4endl;
0128 }
0129
0130
0131
0132 G4VPhysicalVolume* DetectorConstruction::Construct()
0133 {
0134
0135 fSampleDNANames.clear();
0136 fSampleDNAPositions.clear();
0137 fSampleDNADetails.clear();
0138 fDNANames.clear();
0139 fDNAPositions.clear();
0140 fDNADetails.clear();
0141
0142
0143 G4NistManager* man = G4NistManager::Instance();
0144 G4Material* normalWater = man->FindOrBuildMaterial("G4_WATER");
0145 G4Material* waterWorld =
0146 man->BuildMaterialWithNewDensity("G4_WATER_WORLD", "G4_WATER", 1.0 * g / cm / cm / cm);
0147
0148
0149
0150 G4Box* solidWenvelope = new G4Box("SWorld", 1 * um, 1 * um, 1 * um);
0151 G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWenvelope, waterWorld, "LWorld");
0152 G4VPhysicalVolume* physWorld =
0153 new G4PVPlacement(0, G4ThreeVector(), "PWorld", logicWorld, 0, false, 0);
0154
0155
0156 fPlasmidEnvelope = new G4Orb("plasmidEnvelope", 0.5 * fWorldSize);
0157
0158 G4LogicalVolume* tlogicPlasmid =
0159 new G4LogicalVolume(fPlasmidEnvelope, normalWater, "PlasmidVolume");
0160 new G4PVPlacement(0, G4ThreeVector(), tlogicPlasmid, "plasmid", logicWorld, false, 0);
0161
0162
0163 G4VisAttributes worldVis(G4Colour(0.0, 0.0, 1.0));
0164 logicWorld->SetVisAttributes(worldVis);
0165
0166 PhysGeoImport GeoImport = PhysGeoImport();
0167
0168 G4LogicalVolume* logicStraightVoxel;
0169
0170 logicStraightVoxel = GeoImport.CreateLogicVolumeXYZ(fPlasmidFile);
0171
0172 fSampleDNANames = GeoImport.GetMoleculesNames();
0173 fSampleDNAPositions = GeoImport.GetMoleculesPositions();
0174 fSampleDNADetails = GeoImport.GetMoleculesDetails();
0175
0176 for (int i = 0; i < fNbOfPlasmids; i++) {
0177 if (fUseDNAVolumes)
0178 new G4PVPlacement(0, fVOffset[i], logicStraightVoxel, "VoxelStraight", logicWorld, true, i);
0179 AddDNAInformation(i, fVOffset[i]);
0180 }
0181
0182
0183 return physWorld;
0184 }
0185
0186
0187
0188 void DetectorConstruction::ConstructSDandField()
0189 {
0190 G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
0191
0192
0193
0194 G4MultiFunctionalDetector* mfDetector = new G4MultiFunctionalDetector("mfDetector");
0195
0196
0197
0198
0199 ScoreLET* LET = new ScoreLET("LET");
0200 mfDetector->RegisterPrimitive(LET);
0201
0202
0203
0204
0205
0206 G4VPrimitiveScorer* primitivSpecies = new ScoreSpecies("Species");
0207 mfDetector->RegisterPrimitive(primitivSpecies);
0208
0209
0210
0211
0212
0213 G4VPrimitiveScorer* primitiveSB = new ScoreStrandBreaks("StrandBreaks", this, &fWorldSize);
0214 mfDetector->RegisterPrimitive(primitiveSB);
0215
0216
0217 G4LogicalVolumeStore* theLogicalVolumes = G4LogicalVolumeStore::GetInstance();
0218 for (size_t t = 0; t < theLogicalVolumes->size(); t++) {
0219 G4String lVolumeName = (*theLogicalVolumes)[t]->GetName();
0220 if (lVolumeName != "LWorld") {
0221 (*theLogicalVolumes)[t]->SetSensitiveDetector(mfDetector);
0222 }
0223 }
0224 G4SDManager::GetSDMpointer()->AddNewDetector(mfDetector);
0225 }
0226
0227
0228
0229 void DetectorConstruction::ReadOffsetFile(G4String file)
0230 {
0231 if (fVOffset.size() > 0) fVOffset.clear();
0232
0233 std::ifstream OffSetFile;
0234 OffSetFile.open(file);
0235 G4double x, y, z;
0236
0237 if (!OffSetFile) {
0238 G4cout << "Plasmid Offset positions file not found!!!" << G4endl;
0239 exit(1);
0240 }
0241
0242 else {
0243 while (OffSetFile >> x >> y >> z) {
0244 fVOffset.push_back(G4ThreeVector(x * nm, y * nm, z * nm));
0245 }
0246 }
0247 }
0248
0249
0250
0251 void DetectorConstruction::AddDNAInformation(G4int copy, G4ThreeVector offset)
0252 {
0253 for (size_t i = 0; i < fSampleDNANames.size(); i++) {
0254 fDNANames.push_back(fSampleDNANames[i]);
0255 fDNAPositions.push_back(fSampleDNAPositions[i] + offset);
0256
0257 std::vector<G4int> Details = fSampleDNADetails[i];
0258 Details[0] = copy;
0259 fDNADetails.push_back(Details);
0260 }
0261 }
0262
0263