Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/dna/pdb4dna/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 // Delage et al. PDB4DNA: implementation of DNA geometry from the Protein Data
 31 //                  Bank (PDB) description for Geant4-DNA Monte-Carlo
 32 //                  simulations (submitted to Comput. Phys. Commun.)
 33 // The Geant4-DNA web site is available at http://geant4-dna.org
 34 //
 35 //
 36 /// \file DetectorConstruction.cc
 37 /// \brief Implementation of the DetectorConstruction class
 38 
 39 #include "DetectorConstruction.hh"
 40 
 41 #include "DetectorMessenger.hh"
 42 
 43 #include "G4Box.hh"
 44 #include "G4Colour.hh"
 45 #include "G4GeometryManager.hh"
 46 #include "G4LogicalVolume.hh"
 47 #include "G4LogicalVolumeStore.hh"
 48 #include "G4Material.hh"
 49 #include "G4NistManager.hh"
 50 #include "G4Orb.hh"
 51 #include "G4PVPlacement.hh"
 52 #include "G4PhysicalConstants.hh"
 53 #include "G4PhysicalVolumeStore.hh"
 54 #include "G4SolidStore.hh"
 55 #include "G4SystemOfUnits.hh"
 56 #include "G4Tubs.hh"
 57 #include "G4VisAttributes.hh"
 58 
 59 #ifdef G4MULTITHREADED
 60 #  include "G4MTRunManager.hh"
 61 #else
 62 #  include "G4RunManager.hh"
 63 #endif
 64 
 65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 66 
 67 DetectorConstruction::DetectorConstruction()
 68   : G4VUserDetectorConstruction(), fpMessenger(0), fCheckOverlaps(false)
 69 {
 70   // Select a PDB file name by default
 71   // otherwise modified by the LoadPDBfile messenger
 72   //
 73   fPdbFileName = G4String("1ZBB.pdb");
 74   fPdbFileStatus = 0;
 75   fChosenOption = 11;
 76 
 77   fpDefaultMaterial = 0;
 78   fpWaterMaterial = 0;
 79   fpMessenger = new DetectorMessenger(this);
 80 }
 81 
 82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 83 
 84 DetectorConstruction::~DetectorConstruction() {}
 85 
 86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 87 
 88 G4VPhysicalVolume* DetectorConstruction::Construct()
 89 {
 90   fChosenOption = 11;  // Draw atomic with bounding box (visualisation by default)
 91   fPdbFileStatus = 0;  // There is no PDB file loaded at this stage
 92 
 93   // Define materials and geometry
 94   G4VPhysicalVolume* worldPV;
 95   worldPV = DefineVolumes(fPdbFileName, fChosenOption);
 96   return worldPV;
 97 }
 98 
 99 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
100 
101 void DetectorConstruction::ConstructMaterials()
102 {
103   //[G4_WATER]
104   //
105   G4NistManager* nistManager = G4NistManager::Instance();
106   G4bool fromIsotopes = false;
107   nistManager->FindOrBuildMaterial("G4_WATER", fromIsotopes);
108   fpWaterMaterial = G4Material::GetMaterial("G4_WATER");
109 
110   //[Vacuum]
111   G4double a;  // mass of a mole;
112   G4double z;  // z=mean number of protons;
113   G4double density;
114   new G4Material("Galactic", z = 1., a = 1.01 * g / mole, density = universe_mean_density,
115                  kStateGas, 2.73 * kelvin, 3.e-18 * pascal);
116   fpDefaultMaterial = G4Material::GetMaterial("Galactic");
117 }
118 
119 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
120 
121 void DetectorConstruction::CheckMaterials()
122 {
123   if (!fpDefaultMaterial)
124     G4Exception("DetectorConstruction::CheckMaterials", "DEFAULT_MATERIAL_NOT_INIT_1",
125                 FatalException, "Default material not initialized.");
126 
127   if (!fpWaterMaterial)
128     G4Exception("DetectorConstruction::CheckMaterials", "WATER_MATERIAL_NOT_INIT", FatalException,
129                 "Water material not initialized.");
130 }
131 
132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
133 
134 G4VPhysicalVolume* DetectorConstruction::ConstructWorld()
135 {
136   // Geometry parameters
137   G4double worldSize = 1000 * 1 * angstrom;
138 
139   if (!fpDefaultMaterial) {
140     G4Exception("DetectorConstruction::ConstructWorld", "DEFAULT_MATERIAL_NOT_INIT_2",
141                 FatalException, "Default material not initialized.");
142   }
143 
144   //
145   // World
146   //
147   G4VSolid* worldS = new G4Box("World",  // its name
148                                worldSize / 2, worldSize / 2, worldSize / 2);  // its size
149 
150   G4LogicalVolume* worldLV = new G4LogicalVolume(worldS,  // its solid
151                                                  fpDefaultMaterial,  // its material
152                                                  "World");  // its name
153 
154   G4VisAttributes* MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Gray()));
155   MyVisAtt_ZZ->SetVisibility(false);
156   worldLV->SetVisAttributes(MyVisAtt_ZZ);
157 
158   G4VPhysicalVolume* worldPV = new G4PVPlacement(0,  // no rotation
159                                                  G4ThreeVector(),  // at (0,0,0)
160                                                  worldLV,  // its logical volume
161                                                  "World",  // its name
162                                                  0,  // its mother  volume
163                                                  false,  // no boolean operation
164                                                  0,  // copy number
165                                                  true);  // checking overlaps forced to YES
166 
167   return worldPV;
168 }
169 
170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
171 
172 G4VPhysicalVolume* DetectorConstruction::DefineVolumes(G4String filename, unsigned short int option)
173 {
174   // Clean old geometry
175   //
176   G4GeometryManager::GetInstance()->OpenGeometry();
177   G4PhysicalVolumeStore::GetInstance()->Clean();
178   G4LogicalVolumeStore::GetInstance()->Clean();
179   G4SolidStore::GetInstance()->Clean();
180 
181   // Define Materials
182   //
183   ConstructMaterials();
184 
185   // Reconstruct world not to superimpose on geometries
186   G4VPhysicalVolume* worldPV;
187   G4LogicalVolume* worldLV;
188   worldPV = ConstructWorld();
189   worldLV = worldPV->GetLogicalVolume();
190 
191   // List of molecules inside pdb file separated by TER keyword
192   fpMoleculeList = NULL;
193   fpBarycenterList = NULL;
194 
195   //'fPDBlib.load' is currently done for each 'DefineVolumes' call.
196   int verbosity = 0;  // To be implemented
197   unsigned short int isDNA;
198   fpMoleculeList = fPDBlib.Load(filename, isDNA, verbosity);
199   if (fpMoleculeList != NULL && isDNA == 1) {
200     fPDBlib.ComputeNbNucleotidsPerStrand(fpMoleculeList);
201     fpBarycenterList = fPDBlib.ComputeNucleotideBarycenters(fpMoleculeList);
202     G4cout << "This PDB file is DNA." << G4endl;
203   }
204 
205   if (fpMoleculeList != NULL) {
206     fPdbFileStatus = 1;
207   }
208 
209   if (option == 1) {
210     AtomisticView(worldLV, fpMoleculeList, 1.0);
211   }
212   else if (option == 2) {
213     BarycenterView(worldLV, fpBarycenterList);
214   }
215   else if (option == 3) {
216     ResiduesView(worldLV, fpBarycenterList);
217   }
218   else if (option == 10) {
219     DrawBoundingVolume(worldLV, fpMoleculeList);
220   }
221   else if (option == 11) {
222     AtomisticView(worldLV, fpMoleculeList, 1.0);
223     DrawBoundingVolume(worldLV, fpMoleculeList);
224   }
225   else if (option == 12) {
226     BarycenterView(worldLV, fpBarycenterList);
227     DrawBoundingVolume(worldLV, fpMoleculeList);
228   }
229   else if (option == 13) {
230     ResiduesView(worldLV, fpBarycenterList);
231     DrawBoundingVolume(worldLV, fpMoleculeList);
232   }
233   // Always return the physical World
234   //
235   return worldPV;
236 }
237 
238 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
239 
240 PDBlib DetectorConstruction::GetPDBlib()
241 {
242   return fPDBlib;
243 }
244 
245 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
246 
247 Barycenter* DetectorConstruction::GetBarycenterList()
248 {
249   return fpBarycenterList;
250 }
251 
252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
253 
254 Molecule* DetectorConstruction::GetMoleculeList()
255 {
256   return fpMoleculeList;
257 }
258 
259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
260 
261 //////////////////////////////////////////////////
262 ///////////////// BEGIN atomistic representation
263 //
264 void DetectorConstruction::AtomisticView(G4LogicalVolume* worldLV, Molecule* moleculeListTemp,
265                                          double atomSizeFactor)
266 {
267   CheckMaterials();
268 
269   // All solids are defined for different color attributes :
270   G4double sphereSize = atomSizeFactor * 1 * angstrom;
271   G4VSolid* atomS_H = new G4Orb("Sphere", sphereSize * 1.2);
272   G4VSolid* atomS_C = new G4Orb("Sphere", sphereSize * 1.7);
273   G4VSolid* atomS_O = new G4Orb("Sphere", sphereSize * 1.52);
274   G4VSolid* atomS_N = new G4Orb("Sphere", sphereSize * 1.55);
275   G4VSolid* atomS_S = new G4Orb("Sphere", sphereSize * 1.8);
276   G4VSolid* atomS_P = new G4Orb("Sphere", sphereSize * 1.8);
277   G4VSolid* atomS_X = new G4Orb("Sphere", sphereSize);  // Undefined
278 
279   // Logical volumes and color table for atoms :
280   G4LogicalVolume* atomLV_H =
281     new G4LogicalVolume(atomS_H, fpWaterMaterial, "atomLV_H");  // its solid, material, name
282   G4VisAttributes* MyVisAtt_H = new G4VisAttributes(G4Colour(G4Colour::White()));
283   MyVisAtt_H->SetForceSolid(true);
284   atomLV_H->SetVisAttributes(MyVisAtt_H);
285 
286   G4LogicalVolume* atomLV_C =
287     new G4LogicalVolume(atomS_C, fpWaterMaterial, "atomLV_C");  // its solid, material, name
288   G4VisAttributes* MyVisAtt_C =
289     new G4VisAttributes(G4Colour(G4Colour::Gray()));  // Black in CPK, but bad rendering
290   MyVisAtt_C->SetForceSolid(true);
291   atomLV_C->SetVisAttributes(MyVisAtt_C);
292 
293   G4LogicalVolume* atomLV_O =
294     new G4LogicalVolume(atomS_O, fpWaterMaterial, "atomLV_O");  // its solid, material, name
295   G4VisAttributes* MyVisAtt_O = new G4VisAttributes(G4Colour(G4Colour::Red()));
296   MyVisAtt_O->SetForceSolid(true);
297   atomLV_O->SetVisAttributes(MyVisAtt_O);
298 
299   G4LogicalVolume* atomLV_N =
300     new G4LogicalVolume(atomS_N, fpWaterMaterial, "atomLV_N");  // its solid, material, name
301   G4VisAttributes* MyVisAtt_N = new G4VisAttributes(G4Colour(G4Colour(0., 0., 0.5)));  // Dark blue
302   MyVisAtt_N->SetForceSolid(true);
303   atomLV_N->SetVisAttributes(MyVisAtt_N);
304 
305   G4LogicalVolume* atomLV_S =
306     new G4LogicalVolume(atomS_S, fpWaterMaterial, "atomLV_S");  // its solid, material, name
307   G4VisAttributes* MyVisAtt_S = new G4VisAttributes(G4Colour(G4Colour::Yellow()));
308   MyVisAtt_S->SetForceSolid(true);
309   atomLV_S->SetVisAttributes(MyVisAtt_S);
310 
311   G4LogicalVolume* atomLV_P =
312     new G4LogicalVolume(atomS_P, fpWaterMaterial, "atomLV_P");  // its solid, material, name
313   G4VisAttributes* MyVisAtt_P = new G4VisAttributes(G4Colour(G4Colour(1.0, 0.5, 0.)));  // Orange
314   MyVisAtt_P->SetForceSolid(true);
315   atomLV_P->SetVisAttributes(MyVisAtt_P);
316 
317   G4LogicalVolume* atomLV_X =
318     new G4LogicalVolume(atomS_X, fpWaterMaterial, "atomLV_X");  // its solid, material, name
319   G4VisAttributes* MyVisAtt_X =
320     new G4VisAttributes(G4Colour(G4Colour(1.0, 0.75, 0.8)));  // Pink, other elements in CKP
321   MyVisAtt_X->SetForceSolid(true);
322   atomLV_X->SetVisAttributes(MyVisAtt_X);
323 
324   // Placement and physical volume construction from memory
325   Residue* residueListTemp;
326   Atom* AtomTemp;
327 
328   int nbAtomTot = 0;  // Number total of atoms
329   int nbAtomH = 0, nbAtomC = 0, nbAtomO = 0, nbAtomN = 0, nbAtomS = 0, nbAtomP = 0;
330   int nbAtomX = 0;
331   int k = 0;
332 
333   while (moleculeListTemp) {
334     residueListTemp = moleculeListTemp->GetFirst();
335 
336     k++;
337     while (residueListTemp) {
338       AtomTemp = residueListTemp->GetFirst();
339 
340       int startFrom = 0;
341       int upTo = residueListTemp->fNbAtom;  // case Base+sugar+phosphat (all atoms)
342       for (int i = 0; i < (upTo + startFrom); i++)  // Phosphat or Sugar or Base
343       {
344         if (AtomTemp->fElement.compare("H") == 0) {
345           nbAtomH++;
346           new G4PVPlacement(0,
347                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
348                                           AtomTemp->fZ * 1 * angstrom),
349                             atomLV_H, "atomP", worldLV, false, 0, fCheckOverlaps);
350         }
351         else if (AtomTemp->fElement.compare("C") == 0) {
352           nbAtomC++;
353           new G4PVPlacement(0,
354                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
355                                           AtomTemp->fZ * 1 * angstrom),
356                             atomLV_C, "atomP", worldLV, false, 0, fCheckOverlaps);
357         }
358         else if (AtomTemp->fElement.compare("O") == 0) {
359           nbAtomO++;
360           new G4PVPlacement(0,
361                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
362                                           AtomTemp->fZ * 1 * angstrom),
363                             atomLV_O, "atomP", worldLV, false, 0, fCheckOverlaps);
364         }
365         else if (AtomTemp->fElement.compare("N") == 0) {
366           nbAtomN++;
367           new G4PVPlacement(0,
368                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
369                                           AtomTemp->fZ * 1 * angstrom),
370                             atomLV_N, "atomP", worldLV, false, 0, fCheckOverlaps);
371         }
372         else if (AtomTemp->fElement.compare("S") == 0) {
373           nbAtomS++;
374           new G4PVPlacement(0,
375                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
376                                           AtomTemp->fZ * 1 * angstrom),
377                             atomLV_S, "atomP", worldLV, false, 0, fCheckOverlaps);
378         }
379         else if (AtomTemp->fElement.compare("P") == 0) {
380           nbAtomP++;
381           new G4PVPlacement(0,
382                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
383                                           AtomTemp->fZ * 1 * angstrom),
384                             atomLV_P, "atomP", worldLV, false, 0, fCheckOverlaps);
385         }
386         else {
387           nbAtomX++;
388           new G4PVPlacement(0,
389                             G4ThreeVector(AtomTemp->fX * 1 * angstrom, AtomTemp->fY * 1 * angstrom,
390                                           AtomTemp->fZ * 1 * angstrom),
391                             atomLV_X, "atomP", worldLV, false, 0, fCheckOverlaps);
392         }
393 
394         nbAtomTot++;
395         //}//End if (i>=startFrom)
396         AtomTemp = AtomTemp->GetNext();
397       }  // end of for (  i=0 ; i < residueListTemp->nbAtom ; i++)
398 
399       residueListTemp = residueListTemp->GetNext();
400     }  // end of while (residueListTemp)
401 
402     moleculeListTemp = moleculeListTemp->GetNext();
403   }  // end of while (moleculeListTemp)
404 
405   G4cout << "**************** atomisticView(...) ****************" << G4endl;
406   G4cout << "Number of loaded chains = " << k << G4endl;
407   G4cout << "Number of Atoms      = " << nbAtomTot << G4endl;
408   G4cout << "Number of Hydrogens  = " << nbAtomH << G4endl;
409   G4cout << "Number of Carbons    = " << nbAtomC << G4endl;
410   G4cout << "Number of Oxygens    = " << nbAtomO << G4endl;
411   G4cout << "Number of Nitrogens  = " << nbAtomN << G4endl;
412   G4cout << "Number of Sulfurs    = " << nbAtomS << G4endl;
413   G4cout << "Number of Phosphorus = " << nbAtomP << G4endl;
414   G4cout << "Number of undifined atoms =" << nbAtomX << G4endl << G4endl;
415 }
416 
417 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
418 
419 //////////////////////////////////////////////////
420 ///////////////// BEGIN representation for nucleotide barycenters
421 //
422 void DetectorConstruction::BarycenterView(G4LogicalVolume* worldLV, Barycenter* barycenterListTemp)
423 {
424   CheckMaterials();
425 
426   G4VSolid* atomS_ZZ;
427   G4LogicalVolume* atomLV_ZZ;
428   G4VisAttributes* MyVisAtt_ZZ;
429 
430   while (barycenterListTemp) {
431     atomS_ZZ = new G4Orb("Sphere", (barycenterListTemp->GetRadius()) * angstrom);
432     atomLV_ZZ = new G4LogicalVolume(atomS_ZZ, fpWaterMaterial, "atomLV_ZZ");
433     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Magenta()));
434     MyVisAtt_ZZ->SetForceSolid(true);
435     atomLV_ZZ->SetVisAttributes(MyVisAtt_ZZ);
436 
437     new G4PVPlacement(0,
438                       G4ThreeVector(barycenterListTemp->fCenterX * 1 * angstrom,
439                                     barycenterListTemp->fCenterY * 1 * angstrom,
440                                     barycenterListTemp->fCenterZ * 1 * angstrom),
441                       atomLV_ZZ, "atomZZ", worldLV, false, 0, fCheckOverlaps);
442 
443     barycenterListTemp = barycenterListTemp->GetNext();
444   }  // end of while (moleculeListTemp)
445 }
446 
447 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
448 
449 //////////////////////////////////////////////////
450 ///////////////// BEGIN representation for Base Sugar Phosphate barycenters
451 //
452 void DetectorConstruction::ResiduesView(G4LogicalVolume* worldLV, Barycenter* barycenterListTemp)
453 {
454   CheckMaterials();
455   G4VisAttributes* MyVisAtt_ZZ;
456 
457   G4VSolid* tubS1_ZZ;
458   G4LogicalVolume* tubLV1_ZZ;
459   G4VSolid* tubS2_ZZ;
460   G4LogicalVolume* tubLV2_ZZ;
461 
462   G4VSolid* AS_ZZ;
463   G4LogicalVolume* ALV_ZZ;
464   G4VSolid* BS_ZZ;
465   G4LogicalVolume* BLV_ZZ;
466   G4VSolid* CS_ZZ;
467   G4LogicalVolume* CLV_ZZ;
468 
469   while (barycenterListTemp) {
470     // 3 spheres to Base, Sugar, Phosphate)
471     AS_ZZ = new G4Orb("Sphere", 1. * angstrom);
472     ALV_ZZ = new G4LogicalVolume(AS_ZZ, fpWaterMaterial, "ALV_ZZ");
473     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Blue()));
474     MyVisAtt_ZZ->SetForceSolid(true);
475     ALV_ZZ->SetVisAttributes(MyVisAtt_ZZ);
476     new G4PVPlacement(0,
477                       G4ThreeVector(barycenterListTemp->fCenterBaseX * angstrom,
478                                     barycenterListTemp->fCenterBaseY * angstrom,
479                                     barycenterListTemp->fCenterBaseZ * angstrom),
480                       ALV_ZZ, "AZZ", worldLV, false, 0, fCheckOverlaps);
481 
482     BS_ZZ = new G4Orb("Sphere", 1. * angstrom);
483     BLV_ZZ = new G4LogicalVolume(BS_ZZ, fpWaterMaterial, "BLV_ZZ");
484     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Red()));
485     MyVisAtt_ZZ->SetForceSolid(true);
486     BLV_ZZ->SetVisAttributes(MyVisAtt_ZZ);
487     new G4PVPlacement(0,
488                       G4ThreeVector((barycenterListTemp->fCenterPhosphateX) * angstrom,
489                                     (barycenterListTemp->fCenterPhosphateY) * angstrom,
490                                     (barycenterListTemp->fCenterPhosphateZ) * angstrom),
491                       BLV_ZZ, "BZZ", worldLV, false, 0, fCheckOverlaps);
492 
493     CS_ZZ = new G4Orb("Sphere", 1. * angstrom);
494     CLV_ZZ = new G4LogicalVolume(CS_ZZ, fpWaterMaterial, "CLV_ZZ");
495     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Yellow()));
496     MyVisAtt_ZZ->SetForceSolid(true);
497     CLV_ZZ->SetVisAttributes(MyVisAtt_ZZ);
498     new G4PVPlacement(0,
499                       G4ThreeVector(barycenterListTemp->fCenterSugarX * angstrom,
500                                     barycenterListTemp->fCenterSugarY * angstrom,
501                                     barycenterListTemp->fCenterSugarZ * angstrom),
502                       CLV_ZZ, "CZZ", worldLV, false, 0, fCheckOverlaps);
503 
504     // 2 cylinders (Base<=>Sugar and Sugar<=>Phosphat)
505     //  Cylinder Base<=>Sugar
506     tubS1_ZZ = new G4Tubs(
507       "Cylinder", 0., 0.5 * angstrom,
508       std::sqrt((barycenterListTemp->fCenterBaseX - barycenterListTemp->fCenterSugarX)
509                   * (barycenterListTemp->fCenterBaseX - barycenterListTemp->fCenterSugarX)
510                 + (barycenterListTemp->fCenterBaseY - barycenterListTemp->fCenterSugarY)
511                     * (barycenterListTemp->fCenterBaseY - barycenterListTemp->fCenterSugarY)
512                 + (barycenterListTemp->fCenterBaseZ - barycenterListTemp->fCenterSugarZ)
513                     * (barycenterListTemp->fCenterBaseZ - barycenterListTemp->fCenterSugarZ))
514         / 2 * angstrom,
515       0., 2. * pi);
516 
517     tubLV1_ZZ = new G4LogicalVolume(tubS1_ZZ, fpWaterMaterial, "tubLV_ZZ");
518     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Green()));
519     MyVisAtt_ZZ->SetForceSolid(true);
520     tubLV1_ZZ->SetVisAttributes(MyVisAtt_ZZ);
521 
522     G4double Ux = barycenterListTemp->fCenterBaseX - barycenterListTemp->fCenterSugarX;
523     G4double Uy = barycenterListTemp->fCenterBaseY - barycenterListTemp->fCenterSugarY;
524     G4double Uz = barycenterListTemp->fCenterBaseZ - barycenterListTemp->fCenterSugarZ;
525     G4double llUll = std::sqrt(Ux * Ux + Uy * Uy + Uz * Uz);
526 
527     Ux = Ux / llUll;
528     Uy = Uy / llUll;
529     Uz = Uz / llUll;
530 
531     G4ThreeVector direction = G4ThreeVector(Ux, Uy, Uz);
532     G4double theta_euler = direction.theta();
533     G4double phi_euler = direction.phi();
534     G4double psi_euler = 0;
535 
536     // Warning : clhep Euler constructor build inverse matrix !
537     G4RotationMatrix rotm1Inv = G4RotationMatrix(phi_euler + pi / 2, theta_euler, psi_euler);
538     G4RotationMatrix rotm1 = rotm1Inv.inverse();
539     G4ThreeVector translm1 = G4ThreeVector(
540       (barycenterListTemp->fCenterBaseX + barycenterListTemp->fCenterSugarX) / 2. * angstrom,
541       (barycenterListTemp->fCenterBaseY + barycenterListTemp->fCenterSugarY) / 2. * angstrom,
542       (barycenterListTemp->fCenterBaseZ + barycenterListTemp->fCenterSugarZ) / 2. * angstrom);
543     G4Transform3D transform1 = G4Transform3D(rotm1, translm1);
544     new G4PVPlacement(transform1,  // rotation translation
545                       tubLV1_ZZ, "atomZZ", worldLV, false, 0, fCheckOverlaps);
546 
547     // Cylinder Sugar<=>Phosphat
548     tubS2_ZZ = new G4Tubs(
549       "Cylinder2", 0., 0.5 * angstrom,
550       std::sqrt((barycenterListTemp->fCenterSugarX - barycenterListTemp->fCenterPhosphateX)
551                   * (barycenterListTemp->fCenterSugarX - barycenterListTemp->fCenterPhosphateX)
552                 + (barycenterListTemp->fCenterSugarY - barycenterListTemp->fCenterPhosphateY)
553                     * (barycenterListTemp->fCenterSugarY - barycenterListTemp->fCenterPhosphateY)
554                 + (barycenterListTemp->fCenterSugarZ - barycenterListTemp->fCenterPhosphateZ)
555                     * (barycenterListTemp->fCenterSugarZ - barycenterListTemp->fCenterPhosphateZ))
556         / 2 * angstrom,
557       0., 2. * pi);
558 
559     tubLV2_ZZ = new G4LogicalVolume(tubS2_ZZ, fpWaterMaterial, "tubLV2_ZZ");
560     MyVisAtt_ZZ = new G4VisAttributes(G4Colour(1, 0.5, 0));
561     MyVisAtt_ZZ->SetForceSolid(true);
562     tubLV2_ZZ->SetVisAttributes(MyVisAtt_ZZ);
563 
564     Ux = barycenterListTemp->fCenterSugarX - barycenterListTemp->fCenterPhosphateX;
565     Uy = barycenterListTemp->fCenterSugarY - barycenterListTemp->fCenterPhosphateY;
566     Uz = barycenterListTemp->fCenterSugarZ - barycenterListTemp->fCenterPhosphateZ;
567     llUll = std::sqrt(Ux * Ux + Uy * Uy + Uz * Uz);
568 
569     Ux = Ux / llUll;
570     Uy = Uy / llUll;
571     Uz = Uz / llUll;
572 
573     direction = G4ThreeVector(Ux, Uy, Uz);
574     theta_euler = direction.theta();
575     phi_euler = direction.phi();
576     psi_euler = 0;
577 
578     // Warning : clhep Euler constructor build inverse matrix !
579     rotm1Inv = G4RotationMatrix(phi_euler + pi / 2, theta_euler, psi_euler);
580     rotm1 = rotm1Inv.inverse();
581     translm1 = G4ThreeVector(
582       (barycenterListTemp->fCenterSugarX + barycenterListTemp->fCenterPhosphateX) / 2. * angstrom,
583       (barycenterListTemp->fCenterSugarY + barycenterListTemp->fCenterPhosphateY) / 2. * angstrom,
584       (barycenterListTemp->fCenterSugarZ + barycenterListTemp->fCenterPhosphateZ) / 2. * angstrom);
585     transform1 = G4Transform3D(rotm1, translm1);
586     new G4PVPlacement(transform1,  // rotation translation
587                       tubLV2_ZZ, "atomZZ", worldLV, false, 0, fCheckOverlaps);
588 
589     barycenterListTemp = barycenterListTemp->GetNext();
590   }  // end of while sur moleculeListTemp
591 }
592 
593 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
594 
595 //////////////////////////////////////////////////
596 ///////////////// BEGIN draw a bounding volume
597 //
598 void DetectorConstruction::DrawBoundingVolume(G4LogicalVolume* worldLV, Molecule* moleculeListTemp)
599 {
600   CheckMaterials();
601 
602   double dX, dY, dZ;  // Dimensions for bounding volume
603   double tX, tY, tZ;  // Translation for bounding volume
604   fPDBlib.ComputeBoundingVolumeParams(moleculeListTemp, dX, dY, dZ, tX, tY, tZ);
605 
606   //[Geometry] Build a box :
607   G4VSolid* boundingS =
608     new G4Box("Bounding", dX * 1 * angstrom, dY * 1 * angstrom, dZ * 1 * angstrom);
609 
610   G4LogicalVolume* boundingLV = new G4LogicalVolume(boundingS, fpWaterMaterial, "BoundingLV");
611 
612   G4RotationMatrix* pRot = new G4RotationMatrix();
613 
614   G4VisAttributes* MyVisAtt_ZZ = new G4VisAttributes(G4Colour(G4Colour::Gray()));
615   boundingLV->SetVisAttributes(MyVisAtt_ZZ);
616 
617   new G4PVPlacement(pRot,
618                     G4ThreeVector(tX * 1 * angstrom, tY * 1 * angstrom,
619                                   tZ * 1 * angstrom),  // at (x,y,z)
620                     boundingLV, "boundingPV", worldLV, false, 0, fCheckOverlaps);
621 }
622 
623 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
624 
625 void DetectorConstruction::LoadPDBfile(G4String fileName)
626 {
627   G4cout << "Load PDB file : " << fileName << "." << G4endl << G4endl;
628   fPdbFileName = fileName;
629 #ifdef G4MULTITHREADED
630   G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, fChosenOption));
631   G4MTRunManager::GetRunManager()->ReinitializeGeometry();
632 #else
633   G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, fChosenOption));
634 #endif
635 }
636 
637 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
638 
639 void DetectorConstruction::BuildBoundingVolume()
640 {
641   if (fPdbFileStatus > 0)  // a PDB file has been loaded
642   {
643     G4cout << "Build only world volume and bounding volume"
644               " for computation."
645            << G4endl << G4endl;
646 #ifdef G4MULTITHREADED
647     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 10));
648     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
649 #else
650     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 10));
651 #endif
652   }
653   else
654     G4cout << "PDB file not found!" << G4endl << G4endl;
655 }
656 
657 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
658 
659 void DetectorConstruction::DrawAtoms_()
660 {
661   if (fPdbFileStatus > 0)  // a PDB file has been loaded
662   {
663 #ifdef G4MULTITHREADED
664     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 1));
665     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
666 #else
667     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 1));
668 #endif
669   }
670   else
671     G4cout << "PDB file not found!" << G4endl << G4endl;
672 }
673 
674 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
675 
676 void DetectorConstruction::DrawNucleotides_()
677 {
678   if (fPdbFileStatus > 0)  // a PDB file has been loaded
679   {
680 #ifdef G4MULTITHREADED
681     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 2));
682     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
683 #else
684     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 2));
685 #endif
686   }
687   else
688     G4cout << "PDB file not found!" << G4endl << G4endl;
689 }
690 
691 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
692 
693 void DetectorConstruction::DrawResidues_()
694 {
695   if (fPdbFileStatus > 0)  // a PDB file has been loaded
696   {
697 #ifdef G4MULTITHREADED
698     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 3));
699     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
700 #else
701     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 3));
702 #endif
703   }
704   else
705     G4cout << "PDB file not found!" << G4endl << G4endl;
706 }
707 
708 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
709 
710 void DetectorConstruction::DrawAtomsWithBounding_()
711 {
712   if (fPdbFileStatus > 0)  // a PDB file has been loaded
713   {
714 #ifdef G4MULTITHREADED
715     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 11));
716     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
717 #else
718     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 11));
719 #endif
720   }
721   else
722     G4cout << "PDB file not found!" << G4endl << G4endl;
723 }
724 
725 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
726 
727 void DetectorConstruction::DrawNucleotidesWithBounding_()
728 {
729   if (fPdbFileStatus > 0)  // a PDB file has been loaded
730   {
731 #ifdef G4MULTITHREADED
732     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 12));
733     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
734 #else
735     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 12));
736 #endif
737   }
738   else
739     G4cout << "PDB file not found!" << G4endl << G4endl;
740 }
741 
742 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
743 
744 void DetectorConstruction::DrawResiduesWithBounding_()
745 {
746   if (fPdbFileStatus > 0)  // a PDB file has been loaded
747   {
748 #ifdef G4MULTITHREADED
749     G4MTRunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 13));
750     G4MTRunManager::GetRunManager()->ReinitializeGeometry();
751 #else
752     G4RunManager::GetRunManager()->DefineWorldVolume(DefineVolumes(fPdbFileName, 13));
753 #endif
754   }
755   else
756     G4cout << "PDB file not found!" << G4endl << G4endl;
757 }
758