Warning, file /geant4/examples/advanced/dna/moleculardna/src/ChromosomeFactory.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 #include "ChromosomeFactory.hh"
0028
0029 #include "CylindricalChromosome.hh"
0030 #include "EllipticalChromosome.hh"
0031 #include "RodChromosome.hh"
0032 #include "SphericalChromosome.hh"
0033 #include "BoxChromosome.hh"
0034 #include "VirtualChromosome.hh"
0035
0036 #include "G4PhysicalConstants.hh"
0037 #include "G4ThreeVector.hh"
0038 #include "G4UnitsTable.hh"
0039 #include "Randomize.hh"
0040
0041
0042
0043 VirtualChromosome* ChromosomeFactory::MakeChromosome(const G4String& name,
0044 const std::vector<G4String>& commands)
0045 {
0046 VirtualChromosome* chromosome = nullptr;
0047 G4String chromosome_type = commands[0];
0048 if (chromosome_type == CylindricalChromosome::fShape) {
0049
0050
0051
0052 if (commands.size() == 7) {
0053 G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
0054 G4double radius = std::stod(commands[1]) * unit;
0055 G4double hgt = std::stod(commands[2]) * unit;
0056 G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
0057 std::stod(commands[5]) * unit);
0058 chromosome = new CylindricalChromosome(name, center, radius, hgt);
0059 }
0060 else if (commands.size() == 10)
0061 {
0062 G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
0063 G4double radius = std::stod(commands[1]) * unit;
0064 G4double hgt = std::stod(commands[2]) * unit;
0065 G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
0066 std::stod(commands[5]) * unit);
0067
0068
0069 G4RotationMatrix rot;
0070 rot.rotateX(std::stod(commands[7]) * pi / 180);
0071 rot.rotateY(std::stod(commands[8]) * pi / 180);
0072 rot.rotateZ(std::stod(commands[9]) * pi / 180);
0073
0074 chromosome = new CylindricalChromosome(name, center, radius, hgt, rot);
0075 }
0076 else {
0077 G4cout << "The arguments for a cylinder are:" << G4endl;
0078 G4cout << "1) name cyl rad height x y z unit" << G4endl;
0079 G4cout << "2) name cyl rad height x y z unit rx ry rz" << G4endl;
0080 G4cout << "Note that rotations are in degrees" << G4endl;
0081 InvalidReading(chromosome_type);
0082 }
0083 }
0084 else if (chromosome_type == RodChromosome::fShape) {
0085
0086
0087
0088 if (commands.size() == 7) {
0089 G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
0090 G4double radius = std::stod(commands[1]) * unit;
0091 G4double hgt = std::stod(commands[2]) * unit;
0092 G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
0093 std::stod(commands[5]) * unit);
0094 chromosome = new RodChromosome(name, center, radius, hgt);
0095 }
0096 else if (commands.size() == 10)
0097 {
0098 G4double unit = G4UnitDefinition::GetValueOf(commands[6]);
0099 G4double radius = std::stod(commands[1]) * unit;
0100 G4double hgt = std::stod(commands[2]) * unit;
0101 G4ThreeVector center(std::stod(commands[3]) * unit, std::stod(commands[4]) * unit,
0102 std::stod(commands[5]) * unit);
0103
0104
0105 G4RotationMatrix rot;
0106 rot.rotateX(std::stod(commands[7]) * pi / 180);
0107 rot.rotateY(std::stod(commands[8]) * pi / 180);
0108 rot.rotateZ(std::stod(commands[9]) * pi / 180);
0109
0110 chromosome = new RodChromosome(name, center, radius, hgt, rot);
0111 }
0112 else {
0113 G4cout << "The arguments for a cylinder are:" << G4endl;
0114 G4cout << "1) name rod rad height x y z unit" << G4endl;
0115 G4cout << "2) name rod rad height x y z unit rx ry rz" << G4endl;
0116 G4cout << "Note that rotations are in degrees" << G4endl;
0117 InvalidReading(chromosome_type);
0118 }
0119 }
0120 else if (chromosome_type == SphericalChromosome::fShape) {
0121
0122
0123
0124 if (commands.size() == 6) {
0125 G4double unit = G4UnitDefinition::GetValueOf(commands[5]);
0126 G4double radius = std::stod(commands[1]) * unit;
0127 G4ThreeVector center(std::stod(commands[2]) * unit, std::stod(commands[3]) * unit,
0128 std::stod(commands[4]) * unit);
0129 chromosome = new SphericalChromosome(name, center, radius);
0130 }
0131 else if (commands.size() == 9)
0132 {
0133 G4double unit = G4UnitDefinition::GetValueOf(commands[5]);
0134 G4double radius = std::stod(commands[1]) * unit;
0135 G4ThreeVector center(std::stod(commands[2]) * unit, std::stod(commands[3]) * unit,
0136 std::stod(commands[4]) * unit);
0137
0138
0139 G4RotationMatrix rot;
0140 rot.rotateX(std::stod(commands[6]) * pi / 180);
0141 rot.rotateY(std::stod(commands[7]) * pi / 180);
0142 rot.rotateZ(std::stod(commands[8]) * pi / 180);
0143
0144 chromosome = new SphericalChromosome(name, center, radius, rot);
0145 }
0146 else {
0147 G4cout << "The arguments for a sphere are:" << G4endl;
0148 G4cout << "1) name sphere rad x y z unit" << G4endl;
0149 G4cout << "2) name sphere rad x y z unit rx ry rz" << G4endl;
0150 G4cout << "Note that rotations are in degrees" << G4endl;
0151 InvalidReading(chromosome_type);
0152 }
0153 }
0154 else if (chromosome_type == EllipticalChromosome::fShape) {
0155
0156
0157
0158
0159 if (commands.size() == 8) {
0160 G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
0161 G4double sx = std::stod(commands[1]) * unit;
0162 G4double sy = std::stod(commands[2]) * unit;
0163 G4double sz = std::stod(commands[3]) * unit;
0164 G4ThreeVector center(std::stod(commands[4]) * unit, std::stod(commands[5]) * unit,
0165 std::stod(commands[6]) * unit);
0166 chromosome = new EllipticalChromosome(name, center, sx, sy, sz);
0167 }
0168 else if (commands.size() == 11)
0169 {
0170 G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
0171 G4double sx = std::stod(commands[1]) * unit;
0172 G4double sy = std::stod(commands[2]) * unit;
0173 G4double sz = std::stod(commands[3]) * unit;
0174 G4ThreeVector center(std::stod(commands[4]) * unit, std::stod(commands[5]) * unit,
0175 std::stod(commands[6]) * unit);
0176
0177
0178 G4RotationMatrix rot;
0179 rot.rotateX(std::stod(commands[8]) * pi / 180);
0180 rot.rotateY(std::stod(commands[9]) * pi / 180);
0181 rot.rotateZ(std::stod(commands[10]) * pi / 180);
0182
0183 chromosome = new EllipticalChromosome(name, center, sx, sy, sz, rot);
0184 }
0185 else {
0186 G4cout << "The arguments for a ellipse are:" << G4endl;
0187 G4cout << "1) name ellipse sx sy sz x y z unit" << G4endl;
0188 G4cout << "2) name ellipse sx sy sz x y z unit rx ry rz" << G4endl;
0189 G4cout << "Note that rotations are in degrees" << G4endl;
0190 G4cout << "Note that dimensions (sx, sy, sz) are semi-major axes" << G4endl;
0191 InvalidReading(chromosome_type);
0192 }
0193 }
0194
0195
0196 else if(chromosome_type == BoxChromosome::fShape)
0197 {
0198
0199
0200
0201
0202 if(commands.size() == 8)
0203 {
0204 G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
0205 G4double xdim = std::stod(commands[1]) * unit;
0206 G4double ydim = std::stod(commands[2]) * unit;
0207 G4double zdim = std::stod(commands[3]) * unit;
0208 G4ThreeVector center(std::stod(commands[4]) * unit,
0209 std::stod(commands[5]) * unit,
0210 std::stod(commands[6]) * unit);
0211 chromosome = new BoxChromosome(name, center, xdim, ydim, zdim);
0212 }
0213 else if(commands.size() == 11)
0214 {
0215 G4double unit = G4UnitDefinition::GetValueOf(commands[7]);
0216 G4double xdim = std::stod(commands[1]) * unit;
0217 G4double ydim = std::stod(commands[2]) * unit;
0218 G4double zdim = std::stod(commands[3]) * unit;
0219 G4ThreeVector center(std::stod(commands[4]) * unit,
0220 std::stod(commands[5]) * unit,
0221 std::stod(commands[6]) * unit);
0222
0223
0224 G4RotationMatrix rot;
0225 rot.rotateX(std::stod(commands[8]) * pi / 180);
0226 rot.rotateY(std::stod(commands[9]) * pi / 180);
0227 rot.rotateZ(std::stod(commands[10]) * pi / 180);
0228
0229 chromosome = new BoxChromosome(name, center, xdim, ydim, zdim, rot);
0230 }
0231 else
0232 {
0233 G4cout << "The arguments for a box are:" << G4endl;
0234 G4cout << "1) name box xdim ydim zdim x y z unit" << G4endl;
0235 G4cout << "2) name box xdim ydim zdim x y z unit rx ry rz" << G4endl;
0236 G4cout << "Note that rotations are in degrees" << G4endl;
0237 G4cout << "Note that dimensions (xdim, ydim, zdim) are box edges"
0238 << G4endl;
0239 InvalidReading(chromosome_type);
0240 }
0241 }
0242 else
0243 {
0244 chromosome = nullptr;
0245 InvalidReading(chromosome_type);
0246 }
0247 return chromosome;
0248 }
0249
0250
0251 void ChromosomeFactory::InvalidReading(const G4String& chromosome_type)
0252 {
0253 G4ExceptionDescription errmsg;
0254 errmsg << "Chromosome type: " << chromosome_type << " is not valid" << G4endl;
0255 G4Exception("ChromosomeFactory::MakeChromosome", "", FatalException, errmsg);
0256 }
0257
0258
0259 void ChromosomeFactory::Test()
0260 {
0261 G4cout << "------------------------------------------------------------"
0262 << "--------------------" << G4endl;
0263 G4cout << "Chromosome Test" << G4endl;
0264
0265 std::vector<std::vector<G4String>*> tests;
0266 G4double r;
0267 for (G4int ii = 0; ii != 50; ii++) {
0268
0269 auto vec = new std::vector<G4String>();
0270 r = G4UniformRand();
0271 if (r < 0.25) {
0272 vec->push_back("rod");
0273 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0274 vec->push_back(std::to_string(5 * G4UniformRand() + 10));
0275 }
0276 else if (r < 0.5) {
0277 vec->push_back("sphere");
0278 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0279 }
0280 else if (r < 0.75) {
0281 vec->push_back("cyl");
0282 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0283 vec->push_back(std::to_string(5 * G4UniformRand() + 5));
0284 }
0285 else {
0286 vec->push_back("ellipse");
0287 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0288 vec->push_back(std::to_string(5 * G4UniformRand() + 5));
0289 vec->push_back(std::to_string(20 * G4UniformRand() - 6));
0290 }
0291
0292 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0293 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0294 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0295 vec->push_back("um");
0296 tests.push_back(vec);
0297 }
0298 for (G4int ii = 0; ii != 50; ++ii) {
0299
0300 auto vec = new std::vector<G4String>();
0301 r = G4UniformRand();
0302 if (r < 0.25) {
0303 vec->push_back("rod");
0304 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0305 vec->push_back(std::to_string(5 * G4UniformRand() + 10));
0306 }
0307 else if (r < 0.5) {
0308 vec->push_back("sphere");
0309 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0310 }
0311 else if (r < 0.75) {
0312 vec->push_back("cyl");
0313 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0314 vec->push_back(std::to_string(5 * G4UniformRand() + 5));
0315 }
0316 else {
0317 vec->push_back("ellipse");
0318 vec->push_back(std::to_string(10 * G4UniformRand() + 2));
0319 vec->push_back(std::to_string(5 * G4UniformRand() + 5));
0320 vec->push_back(std::to_string(20 * G4UniformRand() - 6));
0321 }
0322
0323 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0324 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0325 vec->push_back(std::to_string(10 * (G4UniformRand() - 0.5)));
0326
0327 vec->push_back("um");
0328
0329 vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
0330 vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
0331 vec->push_back(std::to_string(720 * (G4UniformRand() - 0.5)));
0332
0333 tests.push_back(vec);
0334 }
0335
0336 VirtualChromosome* chromo;
0337 for (auto& test : tests) {
0338 chromo = this->MakeChromosome("test", (*test));
0339 G4int passes = 0;
0340 G4int n = 1000;
0341 for (G4int jj = 0; jj != n; jj++) {
0342 G4ThreeVector point = chromo->RandomPointInChromosome();
0343 if (chromo->PointInChromosome(point)) {
0344 passes++;
0345 }
0346 else {
0347 G4cout << point << G4endl;
0348 }
0349 }
0350 if (passes == n) {
0351 G4cout << "Chromosome Test Passed for " << chromo->GetShape() << " based on " << n
0352 << " test points" << G4endl;
0353 }
0354 else {
0355 G4cout << "Chromosome Test Failed for " << chromo->GetShape() << " based on " << n
0356 << " test points (only " << passes << " pass)" << G4endl;
0357 chromo->Print();
0358 }
0359 delete chromo;
0360 }
0361
0362 for (auto& test : tests) {
0363 delete test;
0364 }
0365 G4cout << "------------------------------------------------------------"
0366 << "--------------------" << G4endl;
0367 }
0368
0369