Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/dna/moleculardna/src/ChromosomeFactory.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 #include "ChromosomeFactory.hh"
 28 
 29 #include "CylindricalChromosome.hh"
 30 #include "EllipticalChromosome.hh"
 31 #include "RodChromosome.hh"
 32 #include "SphericalChromosome.hh"
 33 #include "BoxChromosome.hh"
 34 #include "VirtualChromosome.hh"
 35 
 36 #include "G4PhysicalConstants.hh"
 37 #include "G4ThreeVector.hh"
 38 #include "G4UnitsTable.hh"
 39 #include "Randomize.hh"
 40 
 41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 42 
 43 VirtualChromosome* ChromosomeFactory::MakeChromosome(const G4String& name,
 44                                                      const std::vector<G4String>& commands)
 45 {
 46   VirtualChromosome* chromosome = nullptr;
 47   G4String chromosome_type = commands[0];
 48   if (chromosome_type == CylindricalChromosome::fShape) {
 49     // interpret the command for cylinder
 50     // expect cyl rad height x y z unit rx ry rz
 51     // rotations are in degrees
 52     if (commands.size() == 7) {
 53       G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
 54       G4double radius = std::stod(commands[1]) * unit;
 55       G4double hgt = std::stod(commands[2]) * unit;
 56       G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
 57                            std::stod(commands[5]) * unit);
 58       chromosome = new CylindricalChromosome(name, center, radius, hgt);
 59     }
 60     else if (commands.size() == 10)  // euler angles given
 61     {
 62       G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
 63       G4double radius = std::stod(commands[1]) * unit;
 64       G4double hgt = std::stod(commands[2]) * unit;
 65       G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
 66                            std::stod(commands[5]) * unit);
 67 
 68       // Rotations are first X, then Y, Then Z
 69       G4RotationMatrix rot;
 70       rot.rotateX(std::stod(commands[7]) * pi / 180);
 71       rot.rotateY(std::stod(commands[8]) * pi / 180);
 72       rot.rotateZ(std::stod(commands[9]) * pi / 180);
 73 
 74       chromosome = new CylindricalChromosome(name, center, radius, hgt, rot);
 75     }
 76     else {
 77       G4cout << "The arguments for a cylinder are:" << G4endl;
 78       G4cout << "1)    name cyl rad height x y z unit" << G4endl;
 79       G4cout << "2)    name cyl rad height x y z unit rx ry rz" << G4endl;
 80       G4cout << "Note that rotations are in degrees" << G4endl;
 81       InvalidReading(chromosome_type);
 82     }
 83   }
 84   else if (chromosome_type == RodChromosome::fShape) {
 85     // interpret the command for rod
 86     // expect cyl rad height x y z unit rx ry rz
 87     // rotations are in degrees
 88     if (commands.size() == 7) {
 89       G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
 90       G4double radius = std::stod(commands[1]) * unit;
 91       G4double hgt = std::stod(commands[2]) * unit;
 92       G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
 93                            std::stod(commands[5]) * unit);
 94       chromosome = new RodChromosome(name, center, radius, hgt);
 95     }
 96     else if (commands.size() == 10)  // euler angles given
 97     {
 98       G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
 99       G4double radius = std::stod(commands[1]) * unit;
100       G4double hgt = std::stod(commands[2]) * unit;
101       G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
102                            std::stod(commands[5]) * unit);
103 
104       // Rotations are first X, then Y, Then Z
105       G4RotationMatrix rot;
106       rot.rotateX(std::stod(commands[7]) * pi / 180);
107       rot.rotateY(std::stod(commands[8]) * pi / 180);
108       rot.rotateZ(std::stod(commands[9]) * pi / 180);
109 
110       chromosome = new RodChromosome(name, center, radius, hgt, rot);
111     }
112     else {
113       G4cout << "The arguments for a cylinder are:" << G4endl;
114       G4cout << "1)    name rod rad height x y z unit" << G4endl;
115       G4cout << "2)    name rod rad height x y z unit rx ry rz" << G4endl;
116       G4cout << "Note that rotations are in degrees" << G4endl;
117       InvalidReading(chromosome_type);
118     }
119   }
120   else if (chromosome_type == SphericalChromosome::fShape) {
121     // interpret the command for sphere
122     // expect sphere rad x y z unit rx ry rz
123     // rotations are in degrees
124     if (commands.size() == 6) {
125       G4double unit = G4UnitDefinition::GetValueOf(commands[5]);
126       G4double radius = std::stod(commands[1]) * unit;
127       G4ThreeVector center(std::stod(commands[2]) * unit, std::stod(commands[3]) * unit,
128                            std::stod(commands[4]) * unit);
129       chromosome = new SphericalChromosome(name, center, radius);
130     }
131     else if (commands.size() == 9)  // euler angles given
132     {
133       G4double unit = G4UnitDefinition::GetValueOf(commands[5]);
134       G4double radius = std::stod(commands[1]) * unit;
135       G4ThreeVector center(std::stod(commands[2]) * unit, std::stod(commands[3]) * unit,
136                            std::stod(commands[4]) * unit);
137 
138       // Rotations are first X, then Y, Then Z
139       G4RotationMatrix rot;
140       rot.rotateX(std::stod(commands[6]) * pi / 180);
141       rot.rotateY(std::stod(commands[7]) * pi / 180);
142       rot.rotateZ(std::stod(commands[8]) * pi / 180);
143 
144       chromosome = new SphericalChromosome(name, center, radius, rot);
145     }
146     else {
147       G4cout << "The arguments for a sphere are:" << G4endl;
148       G4cout << "1)    name sphere rad x y z unit" << G4endl;
149       G4cout << "2)    name sphere rad x y z unit rx ry rz" << G4endl;
150       G4cout << "Note that rotations are in degrees" << G4endl;
151       InvalidReading(chromosome_type);
152     }
153   }
154   else if (chromosome_type == EllipticalChromosome::fShape) {
155     // interpret the command for Ellipse
156     // expect ellipse sx sy sz x y z unit rx ry rz
157     // rotations are in degrees
158     // sx sy sz are semi-major axes
159     if (commands.size() == 8) {
160       G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
161       G4double sx = std::stod(commands[1]) * unit;
162       G4double sy = std::stod(commands[2]) * unit;
163       G4double sz = std::stod(commands[3]) * unit;
164       G4ThreeVector center(std::stod(commands[4]) * unit, std::stod(commands[5]) * unit,
165                            std::stod(commands[6]) * unit);
166       chromosome = new EllipticalChromosome(name, center, sx, sy, sz);
167     }
168     else if (commands.size() == 11)  // euler angles given
169     {
170       G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
171       G4double sx = std::stod(commands[1]) * unit;
172       G4double sy = std::stod(commands[2]) * unit;
173       G4double sz = std::stod(commands[3]) * unit;
174       G4ThreeVector center(std::stod(commands[4]) * unit, std::stod(commands[5]) * unit,
175                            std::stod(commands[6]) * unit);
176 
177       // Rotations are first X, then Y, Then Z
178       G4RotationMatrix rot;
179       rot.rotateX(std::stod(commands[8]) * pi / 180);
180       rot.rotateY(std::stod(commands[9]) * pi / 180);
181       rot.rotateZ(std::stod(commands[10]) * pi / 180);
182 
183       chromosome = new EllipticalChromosome(name, center, sx, sy, sz, rot);
184     }
185     else {
186       G4cout << "The arguments for a ellipse are:" << G4endl;
187       G4cout << "1)    name ellipse sx sy sz x y z unit" << G4endl;
188       G4cout << "2)    name ellipse sx sy sz x y z unit rx ry rz" << G4endl;
189       G4cout << "Note that rotations are in degrees" << G4endl;
190       G4cout << "Note that dimensions (sx, sy, sz) are semi-major axes" << G4endl;
191       InvalidReading(chromosome_type);
192     }
193   }
194     // added by sara
195 
196   else if(chromosome_type == BoxChromosome::fShape)
197   {
198     // interpret the command for Box
199     // expect ellipse xdim ydim zdim x y z unit rx ry rz
200     // rotations are in degrees
201     // xdim ydim zdim are edges of box
202     if(commands.size() == 8)
203     {
204       G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
205       G4double xdim   = std::stod(commands[1]) * unit;
206       G4double ydim   = std::stod(commands[2]) * unit;
207       G4double zdim   = std::stod(commands[3]) * unit;
208       G4ThreeVector center(std::stod(commands[4]) * unit,
209                            std::stod(commands[5]) * unit,
210                            std::stod(commands[6]) * unit);
211       chromosome = new BoxChromosome(name, center, xdim, ydim, zdim);
212     }
213     else if(commands.size() == 11)  // euler angles given
214     {
215       G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
216       G4double xdim   = std::stod(commands[1]) * unit;
217       G4double ydim   = std::stod(commands[2]) * unit;
218       G4double zdim   = std::stod(commands[3]) * unit;
219       G4ThreeVector center(std::stod(commands[4]) * unit,
220                            std::stod(commands[5]) * unit,
221                            std::stod(commands[6]) * unit);
222 
223       // Rotations are first X, then Y, Then Z
224       G4RotationMatrix rot;
225       rot.rotateX(std::stod(commands[8]) * pi / 180);
226       rot.rotateY(std::stod(commands[9]) * pi / 180);
227       rot.rotateZ(std::stod(commands[10]) * pi / 180);
228 
229       chromosome = new BoxChromosome(name, center, xdim, ydim, zdim, rot);
230     }
231     else
232     {
233       G4cout << "The arguments for a box are:" << G4endl;
234       G4cout << "1)    name box xdim ydim zdim x y z unit" << G4endl;
235       G4cout << "2)    name box xdim ydim zdim x y z unit rx ry rz" << G4endl;
236       G4cout << "Note that rotations are in degrees" << G4endl;
237       G4cout << "Note that dimensions (xdim, ydim, zdim) are box edges"
238              << G4endl;
239       InvalidReading(chromosome_type);
240     }
241   }
242   else
243   {
244     chromosome = nullptr;
245     InvalidReading(chromosome_type);
246   }
247   return chromosome;
248 }
249 
250 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
251 void ChromosomeFactory::InvalidReading(const G4String& chromosome_type)
252 {
253   G4ExceptionDescription errmsg;
254   errmsg << "Chromosome type: " << chromosome_type << " is not valid" << G4endl;
255   G4Exception("ChromosomeFactory::MakeChromosome", "", FatalException, errmsg);
256 }
257 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
258 
259 void ChromosomeFactory::Test()
260 {
261   G4cout << "------------------------------------------------------------"
262          << "--------------------" << G4endl;
263   G4cout << "Chromosome Test" << G4endl;
264   // populate vector for tests
265   std::vector<std::vector<G4String>*> tests;
266   G4double r;
267   for (G4int ii = 0; ii != 50; ii++) {
268     // No rotation constructor test
269     auto vec = new std::vector<G4String>();
270     r = G4UniformRand();
271     if (r < 0.25) {
272       vec->push_back("rod");
273       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
274       vec->push_back(std::to_string(5 * G4UniformRand() + 10));
275     }
276     else if (r < 0.5) {
277       vec->push_back("sphere");
278       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
279     }
280     else if (r < 0.75) {
281       vec->push_back("cyl");
282       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
283       vec->push_back(std::to_string(5 * G4UniformRand() + 5));
284     }
285     else {
286       vec->push_back("ellipse");
287       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
288       vec->push_back(std::to_string(5 * G4UniformRand() + 5));
289       vec->push_back(std::to_string(20 * G4UniformRand() - 6));
290     }
291 
292     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
293     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
294     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
295     vec->push_back("um");
296     tests.push_back(vec);
297   }
298   for (G4int ii = 0; ii != 50; ++ii) {
299     // Test with rotation
300     auto vec = new std::vector<G4String>();
301     r = G4UniformRand();
302     if (r < 0.25) {
303       vec->push_back("rod");
304       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
305       vec->push_back(std::to_string(5 * G4UniformRand() + 10));
306     }
307     else if (r < 0.5) {
308       vec->push_back("sphere");
309       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
310     }
311     else if (r < 0.75) {
312       vec->push_back("cyl");
313       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
314       vec->push_back(std::to_string(5 * G4UniformRand() + 5));
315     }
316     else {
317       vec->push_back("ellipse");
318       vec->push_back(std::to_string(10 * G4UniformRand() + 2));
319       vec->push_back(std::to_string(5 * G4UniformRand() + 5));
320       vec->push_back(std::to_string(20 * G4UniformRand() - 6));
321     }
322 
323     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
324     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
325     vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
326 
327     vec->push_back("um");
328 
329     vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
330     vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
331     vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
332 
333     tests.push_back(vec);
334   }
335 
336   VirtualChromosome* chromo;
337   for (auto& test : tests) {
338     chromo = this->MakeChromosome("test", (*test));
339     G4int passes = 0;
340     G4int n = 1000;
341     for (G4int jj = 0; jj != n; jj++) {
342       G4ThreeVector point = chromo->RandomPointInChromosome();
343       if (chromo->PointInChromosome(point)) {
344         passes++;
345       }
346       else {
347         G4cout << point << G4endl;
348       }
349     }
350     if (passes == n) {
351       G4cout << "Chromosome Test Passed for " << chromo->GetShape() << " based on " << n
352              << " test points" << G4endl;
353     }
354     else {
355       G4cout << "Chromosome Test Failed for " << chromo->GetShape() << " based on " << n
356              << " test points (only " << passes << " pass)" << G4endl;
357       chromo->Print();
358     }
359     delete chromo;
360   }
361 
362   for (auto& test : tests) {
363     delete test;
364   }
365   G4cout << "------------------------------------------------------------"
366          << "--------------------" << G4endl;
367 }
368 
369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......