Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/dna/dsbandrepair/src/DetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 /// \file DetectorConstruction.cc
 28 /// \brief Implementation of the DetectorConstruction class
 29 
 30 #include "DetectorConstruction.hh"
 31 #include "Analysis.hh"
 32 #include "DetectorConstructionMessenger.hh"
 33 
 34 #include "G4SystemOfUnits.hh"
 35 #include "G4Region.hh"
 36 #include "G4ProductionCuts.hh"
 37 #include "G4UserLimits.hh"
 38 #include "G4NistManager.hh"
 39 #include "G4RunManager.hh"
 40 #include "G4UnionSolid.hh"
 41 #include "G4SubtractionSolid.hh"
 42 #include "G4Filesystem.hh"
 43 
 44 RunningMode gRunMode = RunningMode::Phys;
 45 
 46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 47 
 48 DetectorConstruction::DetectorConstruction(G4double factor, G4int verbose, G4bool isVisu) :
 49     G4VUserDetectorConstruction(), fFactor(factor), fVerbose(verbose), fBVisu(isVisu)
 50 {
 51     fDetectorMessenger = new DetectorConstructionMessenger(this);
 52     fWorldBoxSizeX = fWorldBoxSizeY = fWorldBoxSizeZ = 1*nm;
 53     if (gRunMode == RunningMode::Chem) fChemGeoImport = std::make_unique<ChemGeoImport>();
 54 }
 55 
 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 57 
 58 G4VPhysicalVolume* DetectorConstruction::Construct()
 59 
 60 {
 61     G4NistManager * man = G4NistManager::Instance();
 62     fWater = man->FindOrBuildMaterial("G4_WATER");
 63     if (gRunMode == RunningMode::Phys) ConstructFullCellNucleusGeo();
 64     else if (gRunMode == RunningMode::Chem) ConstructVoxelGeo();
 65     else {
 66         // only a world volume
 67         G4ExceptionDescription msg;
 68         msg <<"Only world volume is constructed."
 69             <<" Make sure you choose the correct running mode."
 70             <<" Ignore this message if you intentionally test the code.";
 71         G4Exception("DetectorConstruction::Construct()", 
 72                     "", JustWarning, msg);
 73         fSolidWorld = new G4Box("solidWorld",fWorldBoxSizeX, fWorldBoxSizeY, fWorldBoxSizeZ);
 74         fLogicWorld = new G4LogicalVolume(fSolidWorld, fWater, "logicWorld");
 75         fPhysWorld = new G4PVPlacement(0,G4ThreeVector(),"physWorld", 
 76         fLogicWorld, 0, false, false);
 77     }
 78     return fPhysWorld;
 79 }
 80 
 81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 82 
 83 G4VPhysicalVolume * DetectorConstruction::ConstructFullCellNucleusGeo()
 84 {
 85     PhysGeoImport geo(fBVisu);
 86     geo.SetFactor(fFactor);
 87 
 88     std::map<G4String, G4LogicalVolume*> voxelMap;
 89     // Create an empty logical nucleus
 90 
 91     G4LogicalVolume* logicNucleus = geo.CreateNucleusLogicVolume(fCellDefFilePath);
 92     if (!fUsingUserDefinedSizesForWorld) {
 93         G4double scale = 2.0;
 94         fWorldBoxSizeX = scale*geo.GetNucleusSizeData()["SemiX"];
 95         fWorldBoxSizeY = scale*geo.GetNucleusSizeData()["SemiY"];
 96         fWorldBoxSizeZ = geo.GetNucleusSizeData()["SemiZ"];
 97     }
 98    
 99     G4cout<<"===>>World box sizes: SemiX = "<<G4BestUnit(fWorldBoxSizeX,"Length")<<" , SemiY = "
100           <<G4BestUnit(fWorldBoxSizeY,"Length")<<", SemiZ = "
101           <<G4BestUnit(fWorldBoxSizeZ,"Length")<<"<<===="<<G4endl;
102     fSolidWorld = new G4Box("solidWorld",fWorldBoxSizeX, fWorldBoxSizeY, fWorldBoxSizeZ);
103     fLogicWorld = new G4LogicalVolume(fSolidWorld, fWater, "logicWorld");
104     fPhysWorld = new G4PVPlacement(0,G4ThreeVector(),"physWorld", fLogicWorld, 0, false, false);
105     // then place cell nucleus in world
106     new G4PVPlacement(0, G4ThreeVector(), logicNucleus, "nucleus_pl", fLogicWorld, false, false);
107   
108     G4LogicalVolume* logicStraightVoxel{nullptr}, *logicUpVoxel{nullptr}, *logicDownVoxel{nullptr}, 
109                         *logicLeftVoxel{nullptr},*logicRightVoxel{nullptr};
110     G4LogicalVolume* logicStraightVoxel2{nullptr},*logicUpVoxel2{nullptr},*logicDownVoxel2{nullptr}
111                         , *logicLeftVoxel2{nullptr},*logicRightVoxel2{nullptr};
112     
113     for (const auto & entry : fVoxelDefFilesList) {
114         G4String name="";
115         auto ptemp = geo.CreateLogicVolume(entry,name);
116         if (name=="voxelStraight" || name=="VoxelStraight") {
117             logicStraightVoxel = ptemp;
118             voxelMap["VoxelStraight"] = logicStraightVoxel;
119         }
120         if (name=="voxelUp" || name=="VoxelUp") {
121             logicUpVoxel = ptemp;
122             voxelMap["VoxelUp"] = logicUpVoxel;
123         }
124         if (name=="voxelDown" || name=="VoxelDown") {
125             logicDownVoxel = ptemp;
126             voxelMap["VoxelDown"] = logicDownVoxel;
127         }
128         if (name=="voxelRight" || name=="VoxelRight") {
129             logicRightVoxel = ptemp;
130             voxelMap["VoxelRight"] = logicRightVoxel;
131         }
132         if (name=="voxelLeft" || name=="VoxelLeft") {
133             logicLeftVoxel = ptemp;
134             voxelMap["VoxelLeft"] = logicLeftVoxel;
135         }
136         if (name=="voxelStraight2" || name=="VoxelStraight2") {
137             logicStraightVoxel2 = ptemp;
138             voxelMap["VoxelStraight2"] = logicStraightVoxel2;
139         }
140         if (name=="voxelUp2" || name=="VoxelUp2") {
141             logicUpVoxel2 = ptemp;
142             voxelMap["VoxelUp2"] = logicUpVoxel2;
143         }
144         if (name=="voxelDown2" || name=="VoxelDown2") {
145             logicDownVoxel2 = ptemp;
146             voxelMap["VoxelDown2"] = logicDownVoxel2;
147         }
148         if (name=="voxelRight2" || name=="VoxelRight2") {
149             logicRightVoxel2 = ptemp;
150             voxelMap["VoxelRight2"] = logicRightVoxel2;
151         }
152         if (name=="voxelLeft2" || name=="VoxelLeft2") {
153             logicLeftVoxel2 = ptemp;
154             voxelMap["VoxelLeft2"] = logicLeftVoxel2;
155         }
156     }
157 
158     // Create the voxel data table
159     std::vector<Voxel>* voxelTable = geo.CreateVoxelsData(fCellDefFilePath);
160     const G4int nucleusSize = voxelTable->size();
161     G4cout<<"============================================================================"<<G4endl;
162     G4cout<<"=====> Number of Histones in each voxel: "<<G4endl;
163     for (auto [key, value] : geo.GetVoxelNbHistoneMap()) {
164         G4cout<<key<<": \t\t\t"<<value<<G4endl;
165     }
166     G4cout<<"=====> Number of Basepairs in each voxel: "<<G4endl;
167     for (auto [key, value] : geo.GetVoxelNbBpMap()) {
168         G4cout<<key<<": \t\t\t"<<value<<G4endl;
169     }
170     G4cout  <<"=====> Total Number of Histones placed in geometry: \t"
171             <<geo.GetTotalNbHistonePlacedInGeo()<<G4endl;
172     G4cout  <<"=====> Total Number of Basepairs placed in geometry: \t"
173             <<geo.GetTotalNbBpPlacedInGeo()<<G4endl;
174     G4cout  <<"=====> Number of each chromatin type placed in geometry: "<<G4endl;
175     for (auto [key, value] : geo.GetChromatinTypeCountMap()) {
176         G4String chromatinname = "Heterochromatin";
177         if (key == ChromatinType::fEuchromatin) chromatinname = "Euchromatin";
178         G4cout<<chromatinname<<": \t\t\t"<<value<<G4endl;
179     }
180     G4cout<<"============================================================================"<<G4endl;
181     
182     // Create the voxel parameterisation
183     if (voxelMap.size() > 0) {
184         // The following dummy declarations are nescessary for SetLogicalVolum() 
185         // in VoxelParameterisation to prevent from coredump
186         G4double prevZpos = -fWorldBoxSizeZ;
187         for (auto it = voxelMap.begin(); it != voxelMap.end(); it++) {
188             G4double posX = fWorldBoxSizeX - geo.GetVoxelFullSize();
189             G4double posY = fWorldBoxSizeY - geo.GetVoxelFullSize();
190             G4double posZ = prevZpos + geo.GetVoxelFullSize();
191             new G4PVPlacement(0, G4ThreeVector(posX,posY,posZ), 
192                             it->second, "xx", fLogicWorld, false, 0);
193         }
194         // End dummy declaration
195         G4int nthreads=0;
196 #ifdef G4MULTITHREADED
197         nthreads = G4RunManager::GetRunManager()->GetNumberOfThreads();
198 #endif
199         if ( (nthreads >1) && (voxelMap.size() >1)) {
200             G4ExceptionDescription msg;
201             msg <<"Number of thread is "<<nthreads<<" > 1; Thus, dsbandrepair will run in testing mode. "
202                 <<"\nThere will be no DNA constituents placed inside Cell Nucleus!!!";
203             G4Exception("DetectorConstruction::ConstructFullCellNucleusGeo", 
204                         "RunningMode", JustWarning, msg);
205         } else {
206             G4VPVParameterisation* voxelParam = new VoxelParameterisation(voxelMap, voxelTable);
207             new G4PVParameterised("VoxelParam", voxelMap.begin()->second, 
208                             logicNucleus, kUndefined, nucleusSize, voxelParam);
209         }
210     } else {
211         G4ExceptionDescription msg;
212         msg <<"It seems that voxel-definition files are not provided."
213             <<" There will be no DNA constituents placed inside Cell Nucleus!!!";
214         G4Exception("DetectorConstruction::ConstructFullCellNucleusGeo", 
215                     "Geo_InputFile_NoFile", JustWarning, msg);
216     }
217     Analysis::GetAnalysis()->RecordVoxelDefFilesList(fVoxelDefFilesList); 
218     Analysis::GetAnalysis()->SetTotalNbBpPlacedInGeo(geo.GetTotalNbBpPlacedInGeo());
219     Analysis::GetAnalysis()->SetTotalNbHistonePlacedInGeo(geo.GetTotalNbHistonePlacedInGeo());
220     Analysis::GetAnalysis()->SetNucleusVolume(geo.GetNucleusVolume());
221     Analysis::GetAnalysis()->SetNucleusMassDensity(
222         logicNucleus->GetMaterial()->GetDensity()/(kg/m3)); // density in kg/m3;
223     return fPhysWorld;
224 }
225 
226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
227 
228 G4VPhysicalVolume *DetectorConstruction::ConstructVoxelGeo()
229 {
230     if (fWorldBoxSizeX < fVoxelHalfSizeXYZ) {
231         fWorldBoxSizeX = fWorldBoxSizeY = fWorldBoxSizeZ = fVoxelHalfSizeXYZ*1.1;
232     }
233     fSolidWorld = new G4Box("solidWorld", fWorldBoxSizeX, fWorldBoxSizeY, fWorldBoxSizeZ);
234     fLogicWorld = new G4LogicalVolume(fSolidWorld, fWater, "logicWorld");
235     fPhysWorld = new G4PVPlacement(0,G4ThreeVector(),"physWorld", fLogicWorld, 0, false, 0);
236 
237     if (fVoxelHalfSizeXYZ>0) {
238         G4cout<<"=====> Construct voxel ........"<<G4endl;
239         G4Box* solidVoxel = new G4Box("solidVoxel", fVoxelHalfSizeXYZ, fVoxelHalfSizeXYZ, fVoxelHalfSizeXYZ );
240         G4LogicalVolume* logicVoxel = new G4LogicalVolume(solidVoxel, fWater, "logicVoxel");
241         new G4PVPlacement(0, G4ThreeVector(), logicVoxel, "physVoxel", fLogicWorld, false, 0);
242     }
243     return fPhysWorld;
244 }
245 
246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
247 
248 void DetectorConstruction::SetCellDefFilePath(const G4String finput)
249 {
250     const G4fs::path thisP{std::string(finput)};
251     G4fs::file_status fst = G4fs::file_status{};
252     auto isExist = G4fs::status_known(fst) ? G4fs::exists(fst) : G4fs::exists(thisP);
253     if (! isExist) {
254         G4String msg = "File " + finput + "does not exist !!! ";
255         G4Exception("DetectorConstruction::SetNucleusDefFilePath()", 
256         "Geo_InputFileNotOpened", FatalException, msg);
257     } else {
258         fCellDefFilePath = finput;
259         Analysis::GetAnalysis()->RecordCellDefFiliePath(fCellDefFilePath);
260     }
261 }
262 
263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
264 
265 void DetectorConstruction::AddVoxelDefFile(const G4String finput)
266 {
267     const G4fs::path thisP{std::string(finput)};
268     G4fs::file_status fst = G4fs::file_status{};
269     auto isExist = G4fs::status_known(fst) ? G4fs::exists(fst) : G4fs::exists(thisP);
270     if (! isExist) {
271         G4String msg = "File " + finput + "does not exist !!! ";
272         G4Exception("DetectorConstruction::AddVoxelDefFile()", 
273         "Geo_InputFileNotOpened", FatalException, msg);
274     } else {
275         fVoxelDefFilesList.insert(finput);
276     }
277 }
278 
279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
280 
281 void DetectorConstruction::SetWorldBoxSizes(G4ThreeVector v)
282 {
283     G4double sizex = v.getX();
284     G4double sizey = v.getY();
285     G4double sizez = v.getZ();
286     if (sizex > 0. && sizey > 0. && sizez > 0.) {
287         fWorldBoxSizeX = sizex;
288         fWorldBoxSizeY = sizey;
289         fWorldBoxSizeZ = sizez;
290         fUsingUserDefinedSizesForWorld = true;
291     } else {
292         G4ExceptionDescription msg ;
293         msg << " Check your setting? One world dimensions is <= 0 !!! ";
294         G4Exception("DetectorConstruction::SetWorldBoxSizes", 
295         "Geo_WorldSizes", FatalException, msg);
296     }
297 }
298 
299 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
300 
301 void DetectorConstruction::ParseGeoFileForChemMode(const G4String fn)
302 {
303     fChemGeoImport->ParseFiles(fn);
304     fVoxelHalfSizeXYZ = fChemGeoImport->GetSize()/2.;
305 }