File indexing completed on 2025-01-31 09:22:02
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
0028
0029
0030 #include "PhysGeoImport.hh"
0031 #include "Randomize.hh"
0032 #include "G4Sphere.hh"
0033 #include "G4PhysicalConstants.hh"
0034
0035
0036
0037 PhysGeoImport::PhysGeoImport() :
0038 fFactor(1.),
0039 fGeoName("")
0040 {
0041 DefineMaterial();
0042 }
0043
0044
0045
0046 PhysGeoImport::PhysGeoImport(G4bool isVisu) :
0047 fIsVisu(isVisu),
0048 fFactor(1.),
0049 fGeoName("")
0050 {
0051 if (fIsVisu) G4cout<<" For Checking Visualization!"<<G4endl;
0052 DefineMaterial();
0053 }
0054
0055
0056
0057 G4LogicalVolume* PhysGeoImport::CreateLogicVolume(const G4String& fileName,G4String& voxelName)
0058 {
0059
0060
0061
0062 std::map<G4String, G4Material*> materials;
0063
0064
0065 for(G4int i=0, ie=fMaterialVect.size(); i<ie; ++i)
0066 {
0067 G4String matName("");
0068
0069 if(fMaterialVect[i]->GetName()=="adenine_PU") matName = "adenine";
0070 else if(fMaterialVect[i]->GetName()=="thymine_PY") matName = "thymine";
0071 else if(fMaterialVect[i]->GetName()=="guanine_PU") matName = "guanine";
0072 else if(fMaterialVect[i]->GetName()=="cytosine_PY") matName = "cytosine";
0073 else if(fMaterialVect[i]->GetName()=="backbone_THF") matName = "deoxyribose";
0074 else if(fMaterialVect[i]->GetName()=="backbone_TMP") matName = "phosphate";
0075 else if(fMaterialVect[i]->GetName()=="G4_WATER") matName = "water";
0076 else if(fMaterialVect[i]->GetName()=="homogeneous_dna") matName = "homogeneous_dna";
0077 else if(fMaterialVect[i]->GetName()=="G4_Galactic") matName = "vacuum";
0078 else
0079 {
0080 matName = fMaterialVect[i]->GetName();
0081 }
0082
0083 materials[matName] = fMaterialVect[i];
0084 }
0085
0086
0087
0088
0089 voxelName = ParseFile(fileName);
0090
0091
0092
0093 G4String boxNameSolid = fGeoName+"_solid";
0094 G4Box* box_solid = new G4Box(boxNameSolid, fSize/2, fSize/2, fSize/2);
0095
0096 G4String boxNameLogic = fGeoName+"_logic";
0097 G4LogicalVolume* box_logic = new G4LogicalVolume(box_solid, fpWater, boxNameLogic);
0098
0099
0100 std::sort(fMolecules.begin(), fMolecules.end() );
0101
0102
0103 for(G4int i=0, ie=fMolecules.size(); i<ie; ++i)
0104 {
0105
0106
0107 G4String name = fMolecules[i].fName;
0108 G4String materialName = "water";
0109 G4double radius = fMolecules[i].fRadius;
0110 G4double waterRadius = fMolecules[i].fRadiusWater;
0111 G4ThreeVector moleculePosition = fMolecules[i].fPosition;
0112 G4int copyNum = fMolecules[i].fCopyNumber;
0113
0114
0115
0116 G4Orb* moleculeWater_solid = 0;
0117 G4VSolid* moleculeWaterCut_solid = 0;
0118 G4LogicalVolume* moleculeWater_logic = 0;
0119
0120
0121 G4double tol = 0.0001;
0122 if(waterRadius > (0 + tol)*nm)
0123 {
0124 G4Material* mat = 0;
0125
0126 mat=materials[materialName];
0127
0128 G4String nameWaterSolid = name+"_water_solid";
0129 moleculeWater_solid = new G4Orb(nameWaterSolid, waterRadius);
0130 moleculeWaterCut_solid = CreateCutSolid(moleculeWater_solid, fMolecules[i], fMolecules, false);
0131
0132 G4String nameWaterLogic = name+"_water_logic";
0133 moleculeWater_logic = new G4LogicalVolume(moleculeWaterCut_solid, mat, nameWaterLogic);
0134
0135 G4String nameWaterPhys = name+"_water_phys";
0136 new G4PVPlacement(0, moleculePosition, moleculeWater_logic, nameWaterPhys, box_logic, false, copyNum);
0137 }
0138
0139
0140
0141 G4Orb* molecule_solid = 0;
0142 G4VSolid* moleculeCut_solid = 0;
0143 G4LogicalVolume* molecule_logic = 0;
0144
0145 G4String nameSolid = fMolecules[i].fName+"_solid";
0146 molecule_solid = new G4Orb(nameSolid, radius);
0147 moleculeCut_solid = CreateCutSolid(molecule_solid, fMolecules[i], fMolecules, true);
0148
0149 G4String nameLogic = name+"_logic";
0150 molecule_logic = new G4LogicalVolume(moleculeCut_solid, materials[materialName], nameLogic);
0151
0152
0153
0154 if(waterRadius > (0 + tol)*nm)
0155 {
0156 G4ThreeVector position(0.,0.,0.);
0157 G4String namePhys = name+"_phys";
0158 new G4PVPlacement(0, position, molecule_logic, namePhys, moleculeWater_logic, false, copyNum);
0159 }
0160
0161 else
0162 {
0163 G4ThreeVector position = moleculePosition;
0164 G4String namePhys = name+"_phys";
0165 new G4PVPlacement(0, position, molecule_logic, namePhys, box_logic, false, copyNum);
0166 }
0167 }
0168
0169
0170 fMolecules.clear();
0171 fRadiusMap.clear();
0172 fWaterRadiusMap.clear();
0173
0174 return box_logic;
0175 }
0176
0177
0178
0179 G4String PhysGeoImport::ParseFile(const G4String& fileName)
0180 {
0181 G4cout<<"Start parsing of "<<fileName<<G4endl;
0182
0183
0184 fMolecules.clear();
0185 fRadiusMap.clear();
0186 fWaterRadiusMap.clear();
0187
0188
0189 std::ifstream file(fileName.c_str());
0190
0191
0192 if(!file.is_open())
0193 {
0194
0195 G4String msg = fileName+" could not be opened";
0196 G4Exception("PhysGeoImport::ParseFile()", "Geo_InputFileNotOpened", FatalException, msg);
0197 }
0198
0199
0200 G4String line;
0201 G4int preBpCpNo = -1;
0202 G4int preHistoneCpNo =-1;
0203 G4int NoBp = 0;
0204 G4int NoHistone = 0;
0205
0206 while(std::getline(file, line) )
0207 {
0208
0209 if(line.empty()) continue;
0210
0211
0212 std::istringstream issLine(line);
0213
0214
0215 G4String firstItem;
0216
0217
0218 issLine >> firstItem;
0219
0220
0221 if(firstItem=="#") continue;
0222
0223
0224 else if(firstItem=="_Name")
0225 {
0226 G4String name;
0227 issLine >> name;
0228
0229 fGeoName = name;
0230 }
0231 else if(firstItem=="_Size")
0232 {
0233 G4double size;
0234 issLine >> size;
0235 size *= fFactor*nm;
0236
0237 fSize = size;
0238 }
0239 else if(firstItem == "_Version")
0240 {
0241
0242 }
0243 else if(firstItem=="_Number")
0244 {
0245
0246 }
0247 else if(firstItem=="_Radius")
0248 {
0249 G4String name;
0250 issLine >> name;
0251
0252 G4double radius;
0253 issLine >> radius;
0254 radius *= fFactor*nm;
0255
0256 G4double waterRadius;
0257 issLine >> waterRadius;
0258 waterRadius *= fFactor*nm;
0259
0260 fRadiusMap[name] = radius;
0261 fWaterRadiusMap[name] = waterRadius;
0262 }
0263 else if(firstItem=="_pl")
0264 {
0265 G4String name;
0266 issLine >> name;
0267
0268 G4String material;
0269 issLine >> material;
0270
0271 G4int strand;
0272 issLine >> strand;
0273
0274 G4int copyNumber;
0275 issLine >> copyNumber;
0276
0277 if (name == "histone") {
0278 if (copyNumber != preHistoneCpNo ) {
0279 NoHistone ++;
0280 preHistoneCpNo = copyNumber;
0281 }
0282 } else {
0283 if (copyNumber != preBpCpNo) {
0284 NoBp++;
0285 preBpCpNo = copyNumber;
0286 }
0287 }
0288
0289 G4double x;
0290 issLine >> x;
0291 x *= fFactor*nm;
0292
0293 G4double y;
0294 issLine >> y;
0295 y *= fFactor*nm;
0296
0297 G4double z;
0298 issLine >> z;
0299 z *= fFactor*nm;
0300
0301 Molecule molecule(name, copyNumber, G4ThreeVector(x, y, z), fRadiusMap[name], fWaterRadiusMap[name], material, strand);
0302
0303 fMolecules.push_back(molecule);
0304 }
0305 else
0306 {
0307
0308 G4String msg = firstItem+" is not defined in the parser. Check the input file: "+fileName+".";
0309 G4Exception("PhysGeoImport::ParseFile()", "Geo_WrongParse", FatalException, msg);
0310 }
0311 }
0312
0313
0314 file.close();
0315
0316 G4cout<<"End parsing of "<<fileName<<G4endl;
0317 fVoxelNbHistoneMap.insert({fGeoName,NoHistone});
0318 fVoxelNbBpMap.insert({fGeoName,NoBp});
0319 return fGeoName;
0320 }
0321
0322
0323
0324 G4VSolid* PhysGeoImport::CreateCutSolid(G4Orb *solidOrbRef,
0325 Molecule &molRef,
0326 std::vector<Molecule> &molList,
0327 G4bool in)
0328 {
0329
0330
0331
0332
0333
0334 G4double tinySpace = 0.001*fFactor*nm;
0335
0336
0337 G4SubtractionSolid* solidCut(NULL);
0338
0339
0340 G4bool isCutted = false;
0341 G4bool isOurVol = false;
0342
0343
0344 G4double radiusRef;
0345 if(molRef.fRadiusWater==0) radiusRef = molRef.fRadius;
0346 else radiusRef = molRef.fRadiusWater;
0347
0348
0349 G4ThreeVector posRef = molRef.fPosition;
0350
0351
0352 if(std::abs(posRef.x() ) + radiusRef > fSize/2
0353 || std::abs(posRef.y() ) + radiusRef > fSize/2
0354 || std::abs(posRef.z() ) + radiusRef > fSize/2)
0355 {
0356
0357
0358 G4Box* solidBox = new G4Box("solid_box_for_cut", fSize/2, fSize/2, fSize/2);
0359 G4ThreeVector posBox;
0360
0361
0362 G4RotationMatrix *rotMat = new G4RotationMatrix;
0363 rotMat->rotate(0, G4ThreeVector(0,0,1) );
0364
0365
0366
0367
0368 if(std::abs( posRef.y() + radiusRef ) > fSize/2 )
0369 {
0370 posBox = -posRef + G4ThreeVector(0,fSize,0);
0371
0372
0373 if(!isCutted)
0374 {
0375 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef, solidBox, rotMat, posBox);
0376 isCutted = true;
0377 }
0378
0379 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0380 }
0381
0382
0383 if(std::abs( posRef.y() - radiusRef ) > fSize/2 )
0384 {
0385 posBox = -posRef + G4ThreeVector(0,-fSize,0);
0386
0387
0388 if(!isCutted)
0389 {
0390 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef,solidBox,rotMat, posBox);
0391 isCutted = true;
0392 }
0393
0394 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0395 }
0396
0397
0398 if(std::abs( posRef.x() + radiusRef ) > fSize/2 )
0399 {
0400 posBox = -posRef + G4ThreeVector(fSize,0,0);
0401
0402
0403 if(!isCutted)
0404 {
0405 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef, solidBox, rotMat, posBox);
0406 isCutted = true;
0407 }
0408
0409 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0410 }
0411
0412
0413 if(std::abs( posRef.x() - radiusRef ) > fSize/2 )
0414 {
0415 posBox = -posRef + G4ThreeVector(-fSize,0,0);
0416
0417
0418 if(!isCutted)
0419 {
0420 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef, solidBox, rotMat, posBox);
0421 isCutted = true;
0422 }
0423
0424 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0425 }
0426
0427
0428 if(std::abs( posRef.z() + radiusRef ) > fSize/2 )
0429 {
0430 posBox = -posRef + G4ThreeVector(0,0,fSize);
0431
0432
0433 if(!isCutted)
0434 {
0435 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef, solidBox, rotMat, posBox);
0436 isCutted = true;
0437 }
0438
0439 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0440 }
0441
0442
0443 if(std::abs( posRef.z() - radiusRef ) > fSize/2 )
0444 {
0445 posBox = -posRef + G4ThreeVector(0,0,-fSize);
0446
0447
0448 if(!isCutted)
0449 {
0450 solidCut = new G4SubtractionSolid("solidCut", solidOrbRef, solidBox, rotMat, posBox);
0451 isCutted = true;
0452 }
0453
0454 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, posBox);
0455 }
0456 }
0457
0458
0459
0460 for(G4int i=0, ie=molList.size(); i<ie; ++i)
0461 {
0462 G4ThreeVector posTar = molList[i].fPosition;
0463
0464 G4double rTar = posRef.z();
0465 G4double zTar = posTar.z();
0466
0467 if(zTar>rTar+20*fFactor*nm)
0468 {
0469 break;
0470 }
0471 else if(zTar<rTar-20*fFactor*nm)
0472 {
0473 continue;
0474 }
0475
0476
0477 G4double radiusTar;
0478 if(molList[i].fRadiusWater==0) radiusTar = molList[i].fRadius;
0479 else radiusTar = molList[i].fRadiusWater;
0480
0481
0482 G4double distance = std::abs( (posRef - posTar).getR() );
0483
0484
0485
0486 if(distance==0 && !isOurVol)
0487 {
0488
0489
0490
0491 isOurVol = true;
0492
0493
0494 continue;
0495 }
0496
0497 else if(distance == 0 && isOurVol)
0498 {
0499 G4ExceptionDescription desmsg;
0500 desmsg << "DetectorConstruction::CreateCutSolid: Two volumes are placed at the same position.";
0501 G4Exception("ChemGeoImport::BuildGeometry", "", FatalException, desmsg);
0502 }
0503
0504
0505
0506 else if(distance <= radiusRef+radiusTar)
0507 {
0508
0509
0510
0511 G4Box* solidBox = new G4Box("solid_box_for_cut", 2*radiusTar, 2*radiusTar, 2*radiusTar);
0512
0513
0514
0515
0516
0517 G4ThreeVector diff = posTar - posRef;
0518
0519
0520 G4double d = (std::pow(radiusRef,2)-std::pow(radiusTar,2)+std::pow(distance,2) ) /
0521 (2*distance) + solidBox->GetZHalfLength() - tinySpace;
0522
0523
0524
0525
0526 if(in) d -= 2*tinySpace;
0527
0528
0529
0530 G4ThreeVector pos = d *( diff/diff.getR() );
0531
0532
0533
0534 G4double phi = std::acos(pos.getZ()/pos.getR());
0535 G4double theta = std::acos( pos.getX() / ( pos.getR()*std::cos(pi/2.-phi) ) );
0536
0537 if(pos.getY()<0) theta = -theta;
0538
0539 G4ThreeVector rotAxisForPhi(1*fFactor*nm,0.,0.);
0540 rotAxisForPhi.rotateZ(theta+pi/2);
0541
0542
0543 G4RotationMatrix *rotMat = new G4RotationMatrix;
0544 rotMat->rotate(-phi, rotAxisForPhi);
0545
0546
0547 G4ThreeVector rotZAxis(0.,0.,1*fFactor*nm);
0548 rotMat->rotate(theta, rotZAxis);
0549
0550
0551 if(!isCutted) solidCut = new G4SubtractionSolid("solidCut", solidOrbRef,
0552 solidBox, rotMat, pos);
0553
0554
0555 else solidCut = new G4SubtractionSolid("solidCut", solidCut, solidBox, rotMat, pos);
0556
0557
0558 isCutted = true;
0559 }
0560 }
0561
0562
0563 if(isCutted) return solidCut;
0564
0565
0566 else return solidOrbRef;
0567
0568 }
0569
0570
0571
0572 void PhysGeoImport::DefineMaterial()
0573 {
0574 G4NistManager * man = G4NistManager::Instance();
0575 fpWater = man->FindOrBuildMaterial("G4_WATER");
0576 fMaterialVect.push_back(fpWater);
0577 fVacuum = man->FindOrBuildMaterial("G4_Galactic");
0578 fMaterialVect.push_back(fVacuum);
0579
0580 G4double z, a, density;
0581 G4String name, symbol;
0582 G4int nComponents, nAtoms;
0583
0584 a = 12.0107*g/mole;
0585 G4Element* elC = new G4Element(name="Carbon", symbol="C", z=6., a);
0586 a = 1.00794*g/mole;
0587 G4Element* elH = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
0588 a = 15.9994*g/mole;
0589 G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
0590 a = 14.00674*g/mole;
0591 G4Element* elN = new G4Element(name="Nitrogen" ,symbol="N" , z= 7., a);
0592 a = 30.973762*g/mole;
0593 G4Element* elP = new G4Element(name="Phosphorus" ,symbol="P" , z= 15., a);
0594
0595 density = 1.*g/cm3;
0596
0597 fTHF = new G4Material("THF", density, nComponents=3);
0598 fTHF->AddElement(elC, nAtoms=4);
0599 fTHF->AddElement(elH, nAtoms=8);
0600 fTHF->AddElement(elO, nAtoms=1);
0601
0602 fPY = new G4Material("PY", density, nComponents=3);
0603 fPY->AddElement(elC, nAtoms=4);
0604 fPY->AddElement(elH, nAtoms=4);
0605 fPY->AddElement(elN, nAtoms=2);
0606
0607 fPU = new G4Material("PU", density, nComponents=3);
0608 fPU->AddElement(elC, nAtoms=5);
0609 fPU->AddElement(elH, nAtoms=4);
0610 fPU->AddElement(elN, nAtoms=4);
0611
0612 fTMP = new G4Material("TMP", density,4);
0613 fTMP->AddElement(elC, nAtoms=3);
0614 fTMP->AddElement(elH, nAtoms=6);
0615 fTMP->AddElement(elP, nAtoms=1);
0616 fTMP->AddElement(elO, nAtoms=4);
0617
0618 fMaterialVect.push_back(fTHF);
0619 fMaterialVect.push_back(fPY);
0620 fMaterialVect.push_back(fPU);
0621 fMaterialVect.push_back(fTMP);
0622
0623
0624 fSugarMixt = new G4Material("sugarMixt", density, nComponents=2);
0625 fSugarMixt->AddMaterial(fTHF,0.5);
0626 fSugarMixt->AddMaterial(fTMP,0.5);
0627 fMaterialVect.push_back(fSugarMixt);
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637 G4double MBackbone = (5.*12.0104 + 10.*1.00794 + 4.*15.9994)*g/mole;
0638 G4double VBackbone = 1.823912/20. * std::pow(1.e-9, 3.) *m3;
0639 G4double densityBaTHF = (MBackbone/(g/mole) * 1. )/(6.022e23*VBackbone/cm3) *g/cm3;
0640
0641 fDeoxyribose = new G4Material("backbone_THF", densityBaTHF, nComponents=3);
0642 fDeoxyribose->AddElement(elC, nAtoms=5);
0643 fDeoxyribose->AddElement(elH, nAtoms=10);
0644 fDeoxyribose->AddElement(elO, nAtoms=4);
0645 fMaterialVect.push_back(fDeoxyribose);
0646
0647 MBackbone = (3.*1.00794 + 1.*30.973762 + 4.*15.9994)*g/mole;
0648 VBackbone = 1.19114/20. * std::pow(1.e-9, 3.) *m3;
0649 G4double densityBaTMP = (MBackbone/(g/mole) * 1. )/(6.022e23*VBackbone/cm3) *g/cm3;
0650
0651 fPhosphate = new G4Material("backbone_TMP", densityBaTMP,3);
0652 fPhosphate->AddElement(elH, nAtoms=3);
0653 fPhosphate->AddElement(elP, nAtoms=1);
0654 fPhosphate->AddElement(elO, nAtoms=4);
0655 fMaterialVect.push_back(fPhosphate);
0656
0657 G4double MCytosine = (4.*12.0104 + 5.*1.00794 + 3.*14.0067 + 1.*15.9994)*g/mole;
0658 G4double VBase = 1.8527205/20. * std::pow(1.e-9, 3.) *m3;
0659 G4double densityCy = (MCytosine/(g/mole) * 1. )/(6.022e23*VBase/cm3) *g/cm3;
0660
0661 fCytosine_PY = new G4Material("cytosine_PY", densityCy, nComponents=4);
0662 fCytosine_PY->AddElement(elC, nAtoms=4);
0663 fCytosine_PY->AddElement(elH, nAtoms=5);
0664 fCytosine_PY->AddElement(elN, nAtoms=3);
0665 fCytosine_PY->AddElement(elO, nAtoms=1);
0666 fMaterialVect.push_back(fCytosine_PY);
0667
0668 G4double MThy = (5.*12.0104 + 6.*1.00794 + 2.*14.0067 + 2.*15.9994)*g/mole;
0669 VBase = 1.8527205/20. * std::pow(1.e-9, 3.) *m3;
0670 densityCy = (MThy/(g/mole) * 1. )/(6.022e23*VBase/cm3) *g/cm3;
0671
0672 fThymine_PY = new G4Material("thymine_PY", densityCy, nComponents=4);
0673 fThymine_PY->AddElement(elC, nAtoms=5);
0674 fThymine_PY->AddElement(elH, nAtoms=6);
0675 fThymine_PY->AddElement(elN, nAtoms=2);
0676 fThymine_PY->AddElement(elO, nAtoms=2);
0677 fMaterialVect.push_back(fThymine_PY);
0678
0679 G4double MAdenine = (5.*12.0104 + 5.*1.00794 + 5.*14.0067)*g/mole;
0680 VBase = 1.8527205/20. * std::pow(1.e-9, 3.) *m3;
0681 G4double densityAd = (MAdenine/(g/mole) * 1. )/(6.022e23*VBase/cm3) *g/cm3;
0682
0683 fAdenine_PU = new G4Material("adenine_PU", densityAd, nComponents=3);
0684 fAdenine_PU->AddElement(elC, nAtoms=5);
0685 fAdenine_PU->AddElement(elH, nAtoms=5);
0686 fAdenine_PU->AddElement(elN, nAtoms=5);
0687 fMaterialVect.push_back(fAdenine_PU);
0688
0689 MAdenine = (5.*12.0104 + 5.*1.00794 + 5.*14.0067 + 1.*15.999)*g/mole;
0690 VBase = 1.8527205/20. * std::pow(1.e-9, 3.) *m3;
0691 densityAd = (MAdenine/(g/mole) * 1. )/(6.022e23*VBase/cm3) *g/cm3;
0692
0693 fGuanine_PU = new G4Material("guanine_PU", densityAd, nComponents=4);
0694 fGuanine_PU->AddElement(elC, nAtoms=5);
0695 fGuanine_PU->AddElement(elH, nAtoms=5);
0696 fGuanine_PU->AddElement(elN, nAtoms=5);
0697 fGuanine_PU->AddElement(elO, nAtoms=1);
0698 fMaterialVect.push_back(fGuanine_PU);
0699
0700 fHomogeneous_dna = new G4Material("homogeneous_dna", 19.23e-21/(12.30781*1.e-21) *g/cm3, nComponents=7);
0701 fHomogeneous_dna->AddMaterial(fpWater, 0.37);
0702 fHomogeneous_dna->AddMaterial(fDeoxyribose, 0.23);
0703 fHomogeneous_dna->AddMaterial(fPhosphate, 0.17);
0704 fHomogeneous_dna->AddMaterial(fAdenine_PU, 0.06);
0705 fHomogeneous_dna->AddMaterial(fGuanine_PU, 0.07);
0706 fHomogeneous_dna->AddMaterial(fCytosine_PY, 0.05);
0707 fHomogeneous_dna->AddMaterial(fThymine_PY, 0.05);
0708
0709 fMaterialVect.push_back(fHomogeneous_dna);
0710 }
0711
0712
0713
0714 G4LogicalVolume* PhysGeoImport::CreateNucleusLogicVolume(const G4String& fileName)
0715 {
0716
0717
0718 G4cout<<"Start the nucleus creation..."<<G4endl;
0719
0720 G4VSolid* nucleusSolid = 0;
0721 G4LogicalVolume* nucleusLogic = 0;
0722
0723 G4bool isNucleusBuild (false);
0724
0725
0726 std::ifstream nucleusFile;
0727 nucleusFile.open(fileName.c_str());
0728
0729
0730 if(!nucleusFile.is_open())
0731 {
0732
0733 G4String msg = fileName+" could not be opened";
0734 G4Exception("PhysGeoImport::ParseFile()", "Geo_InputFileNotOpened", FatalException, msg);
0735 }
0736
0737
0738 G4String line;
0739
0740
0741 while(std::getline(nucleusFile, line) && !isNucleusBuild)
0742 {
0743
0744 if(line.empty()) continue;
0745
0746
0747 std::istringstream issLine(line);
0748
0749
0750 G4String firstItem;
0751
0752
0753 issLine >> firstItem;
0754
0755
0756 if(firstItem=="#") continue;
0757
0758
0759
0760 else if(firstItem == "_Name")
0761 {
0762 issLine >> fNucleusName;
0763 }
0764
0765 else if(firstItem=="_Type")
0766 {
0767 issLine >> fNucleusType;
0768
0769 if (fNucleusType == "Ellipsoid")
0770 {
0771 G4float semiX, semiY, semiZ;
0772
0773 issLine >> semiX >> semiY >> semiZ;
0774
0775 semiX *= fFactor*nm;
0776 semiY *= fFactor*nm;
0777 semiZ *= fFactor*nm;
0778
0779 fNucleusData["SemiX"] = semiX;
0780 fNucleusData["SemiY"] = semiY;
0781 fNucleusData["SemiZ"] = semiZ;
0782
0783 nucleusSolid = new G4Ellipsoid(fNucleusName, semiX, semiY, semiZ);
0784 nucleusLogic = new G4LogicalVolume(nucleusSolid, fpWater, "nucleus_logic");
0785 G4double r3 = semiX*semiY*semiZ/m3;
0786 fNucleusVolume = 4.0*pi*r3/3.0;
0787 } else if (fNucleusType == "EllipticCylinder") {
0788 G4float semiX, semiY, semiZ;
0789
0790 issLine >> semiX >> semiY >> semiZ;
0791
0792 semiX *= fFactor*nm;
0793 semiY *= fFactor*nm;
0794 semiZ *= fFactor*nm;
0795
0796 fNucleusData["SemiX"] = semiX;
0797 fNucleusData["SemiY"] = semiY;
0798 fNucleusData["SemiZ"] = semiZ;
0799
0800 nucleusSolid = new G4EllipticalTube(fNucleusName, semiX, semiY, semiZ);
0801 nucleusLogic = new G4LogicalVolume(nucleusSolid, fpWater, "nucleus_logic");
0802 G4double r3 = 2*semiX*semiY*semiZ/m3;
0803 fNucleusVolume = pi*r3;
0804 } else if (fNucleusType == "Spherical") {
0805 G4float radius;
0806 issLine >> radius;
0807 radius *= fFactor*nm;
0808 fNucleusData["SemiX"] = radius;
0809 fNucleusData["SemiY"] = radius;
0810 fNucleusData["SemiZ"] = radius;
0811 nucleusSolid = new G4Orb(fNucleusName,radius);
0812 nucleusLogic = new G4LogicalVolume(nucleusSolid, fpWater, "nucleus_logic");
0813 G4double r3 = radius*radius*radius/m3;
0814 fNucleusVolume = 4.0*pi*r3/3.0;
0815 } else {
0816 G4String msg =fNucleusType+" is not registered.";
0817 G4Exception("PhysGeoImport::CreateNucleusLogicVolume()",
0818 "Geo_InputFile_Unknown_Nucleus", FatalException, msg);
0819 }
0820
0821 isNucleusBuild = true;
0822 }
0823 }
0824
0825 nucleusFile.close();
0826
0827 if(!isNucleusBuild)
0828 {
0829 G4String msg = "Nucleus data were not found for "+fNucleusType;
0830 G4Exception("PhysGeoImport::CreateNucleusLogicVolume()",
0831 "Geo_InputFile_Unknown_Nucleus", FatalException, msg);
0832 }
0833
0834 return nucleusLogic;
0835 }
0836
0837
0838
0839 std::vector<Voxel>* PhysGeoImport::CreateVoxelsData(const G4String& fileName)
0840 {
0841 fTotalNbBpPlacedInGeo = 0;
0842 fTotalNbHistonePlacedInGeo = 0;
0843 G4cout<<"Start the voxel data generation..."<<G4endl;
0844
0845 std::vector<Voxel>* voxels = new std::vector<Voxel>;
0846
0847
0848 voxels->clear();
0849
0850 voxels->reserve(1000000);
0851
0852
0853 std::ifstream nucleusFile;
0854 nucleusFile.open(fileName.c_str());
0855
0856
0857 if(!nucleusFile.is_open())
0858 {
0859
0860 G4String msg = fileName+" could not be opened";
0861 G4Exception("PhysGeoImport::ParseFile()", "Geo_InputFileNotOpened", FatalException, msg);
0862 }
0863
0864
0865 G4int voxelCopyNumber = 0;
0866
0867
0868 G4String line;
0869
0870 auto whatchromatintype = [] (Voxel::VoxelType voxt) -> ChromatinType {
0871 if (voxt == Voxel::Straight || voxt == Voxel::Left || voxt == Voxel::Right ||
0872 voxt == Voxel::Up || voxt == Voxel::Down) return ChromatinType::fHeterochromatin;
0873 else if (voxt == Voxel::Straight2 || voxt == Voxel::Left2 || voxt == Voxel::Right2 ||
0874 voxt == Voxel::Up2 || voxt == Voxel::Down2) return ChromatinType::fEuchromatin;
0875 else return ChromatinType::fUnspecified;
0876 };
0877
0878 while(std::getline(nucleusFile, line) )
0879 {
0880
0881 if(line.empty()) continue;
0882
0883
0884 std::istringstream issLine(line);
0885
0886
0887 G4String firstItem;
0888
0889
0890 issLine >> firstItem;
0891
0892
0893 if(firstItem=="#") continue;
0894
0895
0896
0897 else if(firstItem == "_pl")
0898 {
0899
0900
0901 G4String name;
0902 issLine >> name;
0903
0904 G4int chromoCpN;
0905 issLine >> chromoCpN;
0906
0907 G4int domainCpN;
0908 issLine >> domainCpN;
0909
0910 G4double x;
0911 issLine >> x;
0912 x *= fFactor*nm;
0913
0914 G4double y;
0915 issLine >> y;
0916 y *= fFactor*nm;
0917
0918 G4double z;
0919 issLine >> z;
0920 z *= fFactor*nm;
0921
0922 G4double xx;
0923 issLine >> xx;
0924
0925 G4double yx;
0926 issLine >> yx;
0927
0928 G4double zx;
0929 issLine >> zx;
0930
0931 G4double xy;
0932 issLine >> xy;
0933
0934 G4double yy;
0935 issLine >> yy;
0936
0937 G4double zy;
0938 issLine >> zy;
0939
0940 G4double xz;
0941 issLine >> xz;
0942
0943 G4double yz;
0944 issLine >> yz;
0945
0946 G4double zz;
0947 issLine >> zz;
0948
0949
0950 G4RotationMatrix* rot = new G4RotationMatrix(G4ThreeVector(xx,xy,xz),
0951 G4ThreeVector(yx,yy,yz),G4ThreeVector(zx,zy,zz));
0952
0953 Voxel::VoxelType type = Voxel::Other;
0954
0955 if(name=="voxelStraight" || name=="VoxelStraight")
0956 {
0957 type = Voxel::Straight;
0958 }
0959 else if(name=="voxelUp" || name=="VoxelUp")
0960 {
0961 type = Voxel::Up;
0962 }
0963 else if(name=="voxelDown" || name=="VoxelDown")
0964 {
0965 type = Voxel::Down;
0966 }
0967 else if(name=="voxelRight" || name=="VoxelRight")
0968 {
0969 type = Voxel::Right;
0970 }
0971 else if(name=="voxelLeft" || name=="VoxelLeft")
0972 {
0973 type = Voxel::Left;
0974 }
0975 else if(name=="voxelStraight2" || name=="VoxelStraight2")
0976 {
0977 type = Voxel::Straight2;
0978 }
0979 else if(name=="voxelUp2" || name=="VoxelUp2")
0980 {
0981 type = Voxel::Up2;
0982 }
0983 else if(name=="voxelDown2" || name=="VoxelDown2")
0984 {
0985 type = Voxel::Down2;
0986 }
0987 else if(name=="voxelRight2" || name=="VoxelRight2")
0988 {
0989 type = Voxel::Right2;
0990 }
0991 else if(name=="voxelLeft2" || name=="VoxelLeft2")
0992 {
0993 type = Voxel::Left2;
0994 }
0995 else
0996 {
0997 G4ExceptionDescription msg ;
0998 msg << "The voxel named "<<name<<" is not registered in the parser";
0999 G4Exception("PhysGeoImport::CreateVoxelsData", "", FatalException, msg, "");
1000 }
1001
1002 voxels->push_back(Voxel(voxelCopyNumber, chromoCpN, domainCpN, type,
1003 G4ThreeVector(x,y,z), rot) );
1004 fTotalNbBpPlacedInGeo += fVoxelNbBpMap[name];
1005 fTotalNbHistonePlacedInGeo += fVoxelNbHistoneMap[name];
1006 voxelCopyNumber++;
1007 auto chromatintype = whatchromatintype(type);
1008 if (fChromatinTypeCount.find(chromatintype) == fChromatinTypeCount.end())
1009 fChromatinTypeCount.insert({chromatintype,1});
1010 else fChromatinTypeCount[chromatintype]++;
1011 }
1012 }
1013
1014 nucleusFile.close();
1015
1016 G4cout<<"End the voxel data generation"<<G4endl;
1017
1018 return voxels;
1019 }
1020
1021