Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/dna/neuron/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 // This example is provided by the Geant4-DNA collaboration
 27 // Any report or published results obtained using the Geant4-DNA software
 28 // shall cite the following Geant4-DNA collaboration publication:
 29 // Med. Phys. 37 (2010) 4692-4708
 30 // and papers
 31 // M. Batmunkh et al. J Radiat Res Appl Sci 8 (2015) 498-507
 32 // O. Belov et al. Physica Medica 32 (2016) 1510-1520
 33 // The Geant4-DNA web site is available at http://geant4-dna.org
 34 //
 35 // -------------------------------------------------------------------
 36 // November 2016
 37 // -------------------------------------------------------------------
 38 //
 39 /// \file DetectorConstruction.cc
 40 /// \brief Implementation of the DetectorConstruction class
 41 
 42 #include "DetectorConstruction.hh"
 43 
 44 #include "G4Colour.hh"
 45 #include "G4PhysicalConstants.hh"
 46 #include "G4ProductionCuts.hh"
 47 #include "G4Region.hh"
 48 #include "G4RotationMatrix.hh"
 49 #include "G4SystemOfUnits.hh"
 50 #include "G4VisAttributes.hh"
 51 
 52 #include <algorithm>
 53 #include <iostream>
 54 
 55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 56 
 57 DetectorConstruction::DetectorConstruction()
 58 {
 59   fNeuronLoadParamz = new NeuronLoadDataFile();
 60   DefineMaterials();
 61 }
 62 
 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 64 
 65 DetectorConstruction::~DetectorConstruction()
 66 {
 67   delete fNeuronLoadParamz;
 68 }
 69 
 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 71 
 72 void DetectorConstruction::DefineMaterials()
 73 {
 74   // Water is defined from NIST material database
 75   G4NistManager* man = G4NistManager::Instance();
 76   fpWaterMaterial = man->FindOrBuildMaterial("G4_WATER");
 77   fpWorldMaterial = man->FindOrBuildMaterial("G4_Galactic");
 78 }
 79 
 80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 81 
 82 G4VPhysicalVolume* DetectorConstruction::Construct()
 83 {
 84   G4cout << " ---- Begin of Neuron Construction! ---- "
 85          << "\n"
 86          << " ==========================================================" << G4endl;
 87 
 88   // ===============================================
 89   // WORLD VOLUME - filled by default material
 90   // ===============================================
 91 
 92   // Dimensions of world volume are calculated as overall dimensions of neuron!
 93 
 94   G4double worldSizeX;
 95   worldSizeX = fNeuronLoadParamz->GetdiagnlLength() * um;
 96 
 97   if (worldSizeX <= 0.0) {
 98     worldSizeX = 10. * cm;
 99   }
100 
101   G4double worldSizeY = worldSizeX;
102   G4double worldSizeZ = worldSizeX;
103   G4cout << " Side length of word volume is calculated : " << worldSizeX / um << " um" << G4endl;
104   G4VSolid* worldS = new G4Box("World", worldSizeX / 2, worldSizeY / 2, worldSizeZ / 2);
105 
106   G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, fpWorldMaterial, "World");
107 
108   // Visualization attributes
109   G4VisAttributes* worldVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.5, 0.1));  // Gray
110   worldVisAtt->SetVisibility(true);
111   worldLV->SetVisAttributes(worldVisAtt);
112 
113   G4VPhysicalVolume* worldPV = new G4PVPlacement(0,  // no rotation
114                                                  G4ThreeVector(),  // at (0,0,0)
115                                                  "World",  // its name
116                                                  worldLV,  // its logical volume
117                                                  0,  // its mother  volume
118                                                  false,  // no boolean operation
119                                                  0,  // copy number
120                                                  true);  // checking overlaps forced to YES
121 
122   // ===============================================
123   // HOMOGENEOUS MEDIUM - LARGE SPHERE VOLUME
124   // ===============================================
125 
126   // Radius of water sphere calculated as overall dimensions of neuron.
127   fTotMassMedium = fNeuronLoadParamz->GetTotMassMedium();
128   fTotSurfMedium = fNeuronLoadParamz->GetTotSurfMedium();
129   G4double RadiusMedium = fNeuronLoadParamz->GetdiagnlLength() * um / 2.;
130   G4cout << " Radius of homogeneous medium is calculated : " << RadiusMedium / um << " um"
131          << G4endl;
132   G4VSolid* mediumS = new G4Orb("Medium", RadiusMedium);
133 
134   G4LogicalVolume* mediumLV = new G4LogicalVolume(mediumS, fpWaterMaterial, "Medium");
135 
136   // Visualization attributes
137   G4VisAttributes* mediumVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0, 0.02));  // Green
138   // mediumVisAtt->SetForceSolid(true);
139   // mediumVisAtt->SetForceWireframe (true);
140   mediumVisAtt->SetForceLineSegmentsPerCircle(180);
141   mediumVisAtt->SetVisibility(true);
142   mediumLV->SetVisAttributes(mediumVisAtt);
143 
144   G4VPhysicalVolume* mediumPV =
145     new G4PVPlacement(0, G4ThreeVector(), "Medium", mediumLV, worldPV, false, 0, fCheckOverlaps);
146 
147   // ===============================================
148   // TARGET - BOUNDING SLICE including NEURON
149   // ===============================================
150 
151   // Dimensions of bounding slice volume defined as overall measure of neuron
152 
153   G4double TargetSizeX = fNeuronLoadParamz->GetwidthB() * um;
154   G4double TargetSizeY = fNeuronLoadParamz->GetheightB() * um;
155   G4double TargetSizeZ = fNeuronLoadParamz->GetdepthB() * um;
156   fTotMassSlice = fNeuronLoadParamz->GetTotMassSlice();
157   G4cout << " Overall dimensions (um) of neuron morphology : "
158          << "\n"
159          << '\t' << " width = " << TargetSizeX / um << " height = " << TargetSizeY / um
160          << " depth = " << TargetSizeZ / um << G4endl;
161 
162   G4cout << " Volume (um3), surface (um2) and mass (ug) of Bounding Slice are"
163          << " calculated : "
164          << "\n"
165          << '\t' << fNeuronLoadParamz->GetTotVolSlice() / std::pow(um, 3) << "; " << '\t'
166          << fNeuronLoadParamz->GetTotSurfSlice() / (um * um) << "; " << '\t'
167          << fNeuronLoadParamz->GetTotMassSlice() * 1e6 / g << "\n " << G4endl;
168 
169   G4Box* boundingS =
170     new G4Box("BoundingSlice", TargetSizeX / 2., TargetSizeY / 2., TargetSizeZ / 2.);
171 
172   G4LogicalVolume* boundingLV = new G4LogicalVolume(boundingS, fpWaterMaterial, "BoundingSlice");
173 
174   // Visualization attributes with opacity!
175   G4VisAttributes* TargetVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0, 0.1));
176   TargetVisAtt->SetForceSolid(true);
177   TargetVisAtt->SetVisibility(true);
178   boundingLV->SetVisAttributes(TargetVisAtt);
179   new G4PVPlacement(0, G4ThreeVector(), "BoundingSlice", boundingLV, mediumPV, false, 0,
180                     fCheckOverlaps);
181 
182   // ===============================================
183   // NEURON MORPHOLOGY
184   // ===============================================
185 
186   G4cout << " Volume (um3), surface (um2) and mass(ug) of Neuron "
187          << "are calculated : "
188          << "\n"
189          << '\t' << fNeuronLoadParamz->GetTotVolNeuron() / std::pow(um, 3) << "; " << '\t'
190          << fNeuronLoadParamz->GetTotSurfNeuron() / (um * um) << "; " << '\t'
191          << fNeuronLoadParamz->GetTotMassNeuron() * 1e6 / g << G4endl;
192   fTotMassNeuron = fNeuronLoadParamz->GetTotMassNeuron();
193   G4cout << " Total number of compartments into Neuron : " << fNeuronLoadParamz->GetnbNeuroncomp()
194          << G4endl;
195   G4cout << " Shift values (um) for Neuron translation are calculated : "
196          << "\n"
197          << '\t' << " shiftX = " << fNeuronLoadParamz->GetshiftX()
198          << " shiftY = " << fNeuronLoadParamz->GetshiftY()
199          << " shiftZ = " << fNeuronLoadParamz->GetshiftZ() << G4endl;
200 
201   // Soma in Violet with opacity   // 0.85,0.44,0.84
202   fSomaColour = new G4VisAttributes;
203   fSomaColour->SetColour(G4Colour(G4Colour(22 / 255., 200 / 255., 30 / 255.)));
204   fSomaColour->SetForceSolid(true);  // true
205   fSomaColour->SetVisibility(true);
206 
207   // Dendrites in Dark-Blue
208   fDendColour = new G4VisAttributes;
209   fDendColour->SetColour(G4Colour(G4Colour(0.0, 0.0, 0.5)));
210   fDendColour->SetForceSolid(true);
211   // fDendColour->SetVisibility(true);
212 
213   // Axon in Maroon
214   fAxonColour = new G4VisAttributes;
215   fAxonColour->SetColour(G4Colour(G4Colour(0.5, 0.0, 0.0)));
216   fAxonColour->SetForceSolid(true);
217   fAxonColour->SetVisibility(true);
218 
219   // Spines in Dark-Green
220   fSpineColour = new G4VisAttributes;
221   fSpineColour->SetColour(G4Colour(G4Colour(0.0, 100 / 255., 0.0)));
222   fSpineColour->SetForceSolid(true);
223   fSpineColour->SetVisibility(true);
224 
225   // Whole neuron in semitransparent navy blue
226   fNeuronColour = new G4VisAttributes;
227   fNeuronColour->SetColour(G4Colour(G4Colour(0.0, 0.4, 0.8, 0.9)));
228   fNeuronColour->SetForceSolid(true);
229   fNeuronColour->SetVisibility(true);
230 
231   // Placement volumes: G4examples/extended/parameterisations/gflash
232 
233   // =======================================================================
234   // Structure-1: Soma
235 
236   // Create Target G4Region and add logical volume
237   // Active Geant4-DNA processes in this region
238   fpRegion = new G4Region("Soma");
239   G4ProductionCuts* cuts = new G4ProductionCuts();
240   G4double defCut = 1 * nanometer;
241   cuts->SetProductionCut(defCut, "gamma");
242   cuts->SetProductionCut(defCut, "e-");
243   cuts->SetProductionCut(defCut, "e+");
244   cuts->SetProductionCut(defCut, "proton");
245   fpRegion->SetProductionCuts(cuts);
246   G4ThreeVector shift(fNeuronLoadParamz->GetshiftX(), fNeuronLoadParamz->GetshiftY(),
247                       fNeuronLoadParamz->GetshiftZ());
248 
249   G4int n = fNeuronLoadParamz->GetnbSomacomp();
250   if (n <= 0) {
251     G4cout << " ---- Soma not found! ---- " << G4endl;
252   }
253   else {
254     G4cout << " ---- Soma for construction: ---- " << G4endl;
255     G4cout << " Total number of compartments into Soma : " << n << G4endl;
256     fnbSomacomp = n;
257     fMassSomaTot = fNeuronLoadParamz->GetMassSomaTot();
258     fMassSomacomp.resize(n, 0.0);
259     fPosSomacomp.resize(n);
260     fsomaS.resize(n, nullptr);
261     fsomaLV.resize(n, nullptr);
262     fsomaPV.resize(n, nullptr);
263 
264     for (G4int i = 0; i < n; ++i) {
265       fsomaS[i] = new G4Orb("Soma", fNeuronLoadParamz->GetRadSomacomp(i) * um);
266       // you can change parameters of Soma with a single compartment
267       G4ThreeVector pos = (fNeuronLoadParamz->GetPosSomacomp(i) - shift) * um;
268       fsomaLV[i] = new G4LogicalVolume(fsomaS[i], fpWaterMaterial, "Soma");
269       fsomaLV[i]->SetVisAttributes(fSomaColour);
270       fsomaPV[i] = new G4PVPlacement(0,  // no rotation
271                                      pos, fsomaLV[i], "Soma", boundingLV, false, i);
272       fMassSomacomp[i] = fNeuronLoadParamz->GetMassSomacomp(i);
273       fPosSomacomp[i] = fNeuronLoadParamz->GetPosSomacomp(i);
274       fpRegion->AddRootLogicalVolume(fsomaLV[i]);
275     }
276   }
277 
278   // =======================================================================
279   // Structure-2: Dendrites
280 
281   n = fNeuronLoadParamz->GetnbDendritecomp();
282   if (n <= 0) {
283     G4cout << " ---- Dendrites not found! ---- " << G4endl;
284   }
285   else {
286     fnbDendritecomp = n;
287     G4cout << " ---- Dendrites for construction: ---- " << G4endl;
288     G4cout << " Total number of compartments into Dendrites: " << n << G4endl;
289 
290     // Active Geant4-DNA processes in this region
291     auto region = new G4Region("Dendrites");
292     region->SetProductionCuts(cuts);
293 
294     fMassDendTot = fNeuronLoadParamz->GetMassDendTot();
295     fMassDendcomp.resize(n, 0.0);
296     fDistADendSoma.resize(n, 0.0);
297     fDistBDendSoma.resize(n, 0.0);
298     fPosDendcomp.resize(n);
299     fdendriteS.resize(n, nullptr);
300     fdendriteLV.resize(n, nullptr);
301     fdendritePV.resize(n, nullptr);
302     for (G4int i = 1; i < n; ++i) {
303       fdendriteS[i] = new G4Tubs("Dendrites", 0., fNeuronLoadParamz->GetRadDendcomp(i) * um,
304                                  fNeuronLoadParamz->GetHeightDendcomp(i) * um / 2., 0., 2. * pi);
305       fdendriteLV[i] = new G4LogicalVolume(fdendriteS[i], fpWaterMaterial, "Dendrites");
306       fdendriteLV[i]->SetVisAttributes(fDendColour);
307 
308       G4ThreeVector pos = (fNeuronLoadParamz->GetPosDendcomp(i) - shift) * um;
309       // rotation checking with function ComputeTransformation!
310       // RotationMatrix with Inverse
311       fdendritePV[i] = new G4PVPlacement(G4Transform3D(fNeuronLoadParamz->GetRotDendcomp(i), pos),
312                                          fdendriteLV[i], "Dendrites", boundingLV, false, i);
313       fMassDendcomp[i] = fNeuronLoadParamz->GetMassDendcomp(i);
314       fPosDendcomp[i] = fNeuronLoadParamz->GetPosDendcomp(i);
315       fDistADendSoma[i] = fNeuronLoadParamz->GetDistADendSoma(i);
316       fDistBDendSoma[i] = fNeuronLoadParamz->GetDistBDendSoma(i);
317       region->AddRootLogicalVolume(fdendriteLV[i]);
318     }
319   }
320 
321   // =======================================================================
322   // Structure-3: Axon
323 
324   n = fNeuronLoadParamz->GetnbAxoncomp();
325   if (n <= 0) {
326     G4cout << " ---- Axon not found! ---- " << G4endl;
327   }
328   else {
329     G4cout << " ---- Axon for construction: ---- " << G4endl;
330     G4cout << " Total number of compartments into Axon : " << n << G4endl;
331     // Active Geant4-DNA processes in this region
332     auto region = new G4Region("Axon");
333     region->SetProductionCuts(cuts);
334 
335     fnbAxoncomp = n;
336     fMassAxonTot = fNeuronLoadParamz->GetMassAxonTot();
337     fMassAxoncomp.resize(n, 0.0);
338     fDistAxonsoma.resize(n, 0.0);
339     fPosAxoncomp.resize(n);
340     faxonS.resize(n, nullptr);
341     faxonLV.resize(n, nullptr);
342     faxonPV.resize(n, nullptr);
343 
344     for (G4int i = 1; i < n; ++i) {
345       faxonS[i] = new G4Tubs("Axon", 0., fNeuronLoadParamz->GetRadAxoncomp(i) * um,
346                              fNeuronLoadParamz->GetHeightAxoncomp(i) * um / 2., 0., 2. * pi);
347       faxonLV[i] = new G4LogicalVolume(faxonS[i], fpWaterMaterial, "Axon");
348       faxonLV[i]->SetVisAttributes(fAxonColour);
349       // RotationMatrix with Inverse
350       G4ThreeVector pos = (fNeuronLoadParamz->GetPosAxoncomp(i) - shift) * um;
351       faxonPV[i] = new G4PVPlacement(G4Transform3D(fNeuronLoadParamz->GetRotAxoncomp(i), pos),
352                                      faxonLV[i], "Axon", boundingLV, false, i);
353       fMassAxoncomp[i] = fNeuronLoadParamz->GetMassAxoncomp(i);
354       fPosAxoncomp[i] = fNeuronLoadParamz->GetPosAxoncomp(i);
355       fDistAxonsoma[i] = fNeuronLoadParamz->GetDistAxonsoma(i);
356       region->AddRootLogicalVolume(faxonLV[i]);
357     }
358   }
359   // =======================================================================
360   // Structure-4: Spines
361   if (fNeuronLoadParamz->GetnbSpinecomp() == 0) {
362     G4cout << " ---- Spines not found! ---- " << G4endl;
363   }
364   else {
365     G4cout << " ---- Spines for construction: ---- " << G4endl;
366     G4cout << " Total number of compartments into Spines : " << fNeuronLoadParamz->GetnbSpinecomp()
367            << G4endl;
368   }
369 
370   G4cout << "\n ---- End of Neuron Construction! ---- "
371          << "\n ========================================================== \n"
372          << G4endl;
373 
374   // =======================================================================
375   // Active Geant4-DNA processes in BoundingSlice with whole neuron structure
376   // fpRegion = new G4Region("BoundingSlice");
377   // fpRegion->SetProductionCuts(cuts);
378   // fpRegion->AddRootLogicalVolume(boundingLV);
379 
380   return worldPV;
381 }
382