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