File indexing completed on 2025-04-11 08:04:39
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
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include "PDBlib.hh"
0040
0041
0042 #define GEANT4
0043
0044 #ifdef GEANT4
0045
0046 # include "globals.hh"
0047 #else
0048 # define G4cout std::cout
0049 # define G4cerr std::cerr
0050 # define G4endl std::endl
0051 # define G4String std::string
0052 # include <cfloat>
0053 #endif
0054 #include <cmath>
0055 #include <fstream>
0056 #include <iostream>
0057 #include <limits>
0058 #include <sstream>
0059 #include <stdlib.h>
0060
0061 using namespace std;
0062
0063
0064
0065 PDBlib::PDBlib() : fNbNucleotidsPerStrand(0) {}
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 Molecule* PDBlib::Load(const std::string& filename, unsigned short int& isDNA,
0080 unsigned short int verbose = 0)
0081 {
0082 G4String sLine = "";
0083 ifstream infile;
0084 infile.open(filename.c_str());
0085 if (!infile) {
0086 G4cout << "PDBlib::load >> file " << filename << " not found !!!!" << G4endl;
0087 }
0088 else {
0089 int nbAtom = 0;
0090 int numAtomInRes = 0;
0091 int nbResidue = 0;
0092 int nbMolecule = 0;
0093
0094 Atom* AtomicOld = nullptr;
0095 Atom* AtomicNext = nullptr;
0096
0097 int serial;
0098 G4String atomName;
0099 G4String element;
0100 G4String resName;
0101 double x, y, z;
0102 double occupancy;
0103
0104 Residue* residueOld = nullptr;
0105 Residue* residueFirst = nullptr;
0106 Residue* residueNext = nullptr;
0107
0108 Molecule* moleculeFirst = nullptr;
0109 Molecule* moleculeOld = nullptr;
0110 Molecule* moleculeNext = nullptr;
0111
0112
0113
0114
0115 double minGlobZ, maxGlobZ;
0116 double minGlobX, maxGlobX;
0117 double minGlobY, maxGlobY;
0118 double minX, maxX, minY, maxY, minZ, maxZ;
0119
0120 minGlobZ = -DBL_MAX;
0121 minGlobX = -DBL_MAX;
0122 minGlobY = -DBL_MAX;
0123 maxGlobZ = DBL_MAX;
0124 maxGlobX = DBL_MAX;
0125 maxGlobY = DBL_MAX;
0126 minX = -DBL_MAX;
0127 minY = -DBL_MAX;
0128 minZ = -DBL_MAX;
0129 maxX = DBL_MAX;
0130 maxY = DBL_MAX;
0131 maxZ = DBL_MAX;
0132
0133 int lastResSeq = -1;
0134 int resSeq = 0;
0135
0136 G4String nameMol;
0137
0138 unsigned short int numModel = 0;
0139 unsigned short int model = 0;
0140
0141
0142 int ter = 0;
0143
0144
0145 int terMax = INT_MAX;
0146
0147 if (!infile.eof()) {
0148 getline(infile, sLine);
0149 std::size_t found = sLine.find("DNA");
0150 if (found != G4String::npos) {
0151 terMax = 2;
0152 isDNA = 1;
0153 }
0154 else
0155 isDNA = 0;
0156
0157 found = sLine.find("HEADER");
0158 if (found == G4String::npos) {
0159 infile.close();
0160 infile.open(filename.c_str());
0161
0162 G4cout << "PDBlib::load >> No header found !!!!" << G4endl;
0163 }
0164 }
0165
0166 while (!infile.eof()) {
0167 getline(infile, sLine);
0168
0169 if ((sLine.substr(0, 6)).compare("NUMMDL") == 0) {
0170 istringstream((sLine.substr(10, 4))) >> numModel;
0171 }
0172 if ((numModel > 0) && ((sLine.substr(0, 6)).compare("MODEL ") == 0)) {
0173 istringstream((sLine.substr(10, 4))) >> model;
0174
0175 if (model > 1) break;
0176
0177 }
0178
0179 if ((sLine.substr(0, 6)).compare("SEQRES") == 0) {
0180
0181 if (verbose > 1) G4cout << sLine << G4endl;
0182 }
0183
0184
0185 if ((numModel > 0) && ((sLine.substr(0, 6)).compare("ENDMDL") == 0)) {
0186 ;
0187 }
0188 else if ((sLine.substr(0, 6)).compare("TER ") == 0)
0189 {
0190
0191
0192 ter++;
0193 if (ter > terMax) break;
0194
0195
0196
0197
0198 lastResSeq = -1;
0199 resSeq = 0;
0200
0201 AtomicOld->SetNext(NULL);
0202 residueOld->SetNext(NULL);
0203 residueOld->fNbAtom = nbAtom;
0204
0205
0206 if (moleculeOld == NULL) {
0207 nameMol = filename;
0208 moleculeOld = new Molecule(nameMol, nbMolecule);
0209 moleculeOld->SetFirst(residueFirst);
0210 moleculeOld->fNbResidue = nbResidue;
0211 moleculeFirst = moleculeOld;
0212 }
0213 else {
0214 moleculeNext = new Molecule(nameMol, nbMolecule);
0215 moleculeOld->SetNext(moleculeNext);
0216 moleculeNext->SetFirst(residueFirst);
0217 moleculeNext->fNbResidue = nbResidue;
0218 moleculeOld = moleculeNext;
0219 }
0220
0221 nbMolecule++;
0222 moleculeOld->SetNext(NULL);
0223 moleculeOld->fCenterX = (int)((minX + maxX) / 2.);
0224 moleculeOld->fCenterY = (int)((minY + maxY) / 2.);
0225 moleculeOld->fCenterZ = (int)((minZ + maxZ) / 2.);
0226 moleculeOld->fMaxGlobZ = maxGlobZ;
0227 moleculeOld->fMinGlobZ = minGlobZ;
0228 moleculeOld->fMaxGlobX = maxGlobX;
0229 moleculeOld->fMinGlobX = minGlobX;
0230 moleculeOld->fMaxGlobY = maxGlobY;
0231 moleculeOld->fMinGlobY = minGlobY;
0232
0233 minGlobZ = -DBL_MAX;
0234 minGlobX = -DBL_MAX;
0235 minGlobY = -DBL_MAX;
0236 maxGlobZ = DBL_MAX;
0237 maxGlobX = DBL_MAX;
0238 maxGlobY = DBL_MAX;
0239 minX = -DBL_MAX;
0240 minY = -DBL_MAX;
0241 minZ = -DBL_MAX;
0242 maxX = DBL_MAX;
0243 maxY = DBL_MAX;
0244 maxZ = DBL_MAX;
0245
0246 nbAtom = 0;
0247 numAtomInRes = 0;
0248 nbResidue = 0;
0249 AtomicOld = NULL;
0250 AtomicNext = NULL;
0251 residueOld = NULL;
0252 residueFirst = NULL;
0253 residueNext = NULL;
0254
0255
0256 }
0257 else if ((sLine.substr(0, 6)).compare("ATOM ") == 0) {
0258
0259
0260 istringstream((sLine.substr(6, 5))) >> serial;
0261
0262
0263
0264 atomName = sLine.substr(12, 4);
0265 if (atomName.substr(0, 1).compare(" ") == 0)
0266 element = sLine.substr(13, 1);
0267 else
0268 element = sLine.substr(12, 1);
0269
0270
0271 double vdwRadius = -1.;
0272 if (element == "H") {
0273 vdwRadius = 1.2;
0274 }
0275 else if (element == "C") {
0276 vdwRadius = 1.7;
0277 }
0278 else if (element == "N") {
0279 vdwRadius = 1.55;
0280 }
0281 else if (element == "O") {
0282 vdwRadius = 1.52;
0283 }
0284 else if (element == "P") {
0285 vdwRadius = 1.8;
0286 }
0287 else if (element == "S") {
0288 vdwRadius = 1.8;
0289 }
0290 else {
0291 #ifndef GEANT4
0292 G4cerr << "Element not recognized : " << element << G4endl;
0293 G4cerr << "Stop now" << G4endl;
0294 exit(1);
0295 #else
0296 G4ExceptionDescription errMsg;
0297 errMsg << "Element not recognized : " << element << G4endl;
0298
0299 G4Exception("PDBlib::Load", "ELEM_NOT_RECOGNIZED", FatalException, errMsg);
0300 #endif
0301 }
0302
0303 {
0304
0305 resName = sLine.substr(17, 3);
0306
0307 istringstream((sLine.substr(22, 4))) >> resSeq;
0308
0309 stringstream((sLine.substr(30, 8))) >> x;
0310 stringstream((sLine.substr(38, 8))) >> y;
0311 stringstream((sLine.substr(46, 8))) >> z;
0312
0313 occupancy = 1.;
0314
0315 if (minGlobZ < z) minGlobZ = z;
0316 if (maxGlobZ > z) maxGlobZ = z;
0317 if (minGlobX < x) minGlobX = x;
0318 if (maxGlobX > x) maxGlobX = x;
0319 if (minGlobY < y) minGlobY = y;
0320 if (maxGlobY > y) maxGlobY = y;
0321 if (minX > x) minX = x;
0322 if (maxX < x) maxX = x;
0323 if (minY > y) minY = y;
0324 if (maxY < y) maxY = y;
0325 if (minZ > z) minZ = z;
0326 if (maxZ < z) maxZ = z;
0327
0328
0329 if (AtomicOld == NULL) {
0330 AtomicOld =
0331 new Atom(serial, atomName, "", 0, 0, x, y, z, vdwRadius, occupancy, 0, element);
0332 AtomicOld->SetNext(NULL);
0333 }
0334 else {
0335 AtomicNext =
0336 new Atom(serial, atomName, "", 0, 0, x, y, z, vdwRadius, occupancy, 0, element);
0337 AtomicOld->SetNext(AtomicNext);
0338 AtomicOld = AtomicNext;
0339 }
0340 nbAtom++;
0341 }
0342
0343
0344 if (residueOld == NULL) {
0345 if (verbose > 2) G4cout << "residueOld == NULL" << G4endl;
0346
0347 AtomicOld->fNumInRes = 0;
0348 residueOld = new Residue(resName, resSeq);
0349 residueOld->SetFirst(AtomicOld);
0350 residueOld->SetNext(NULL);
0351 residueFirst = residueOld;
0352 lastResSeq = resSeq;
0353 nbResidue++;
0354 }
0355 else {
0356 if (lastResSeq == resSeq) {
0357 numAtomInRes++;
0358 AtomicOld->fNumInRes = numAtomInRes;
0359 }
0360 else {
0361 numAtomInRes = 0;
0362 AtomicOld->fNumInRes = numAtomInRes;
0363
0364 residueNext = new Residue(resName, resSeq);
0365 residueNext->SetFirst(AtomicOld);
0366 residueOld->SetNext(residueNext);
0367 residueOld->fNbAtom = nbAtom - 1;
0368
0369 nbAtom = 1;
0370 residueOld = residueNext;
0371 lastResSeq = resSeq;
0372 nbResidue++;
0373 }
0374 }
0375
0376
0377 }
0378 }
0379
0380 infile.close();
0381 return moleculeFirst;
0382 }
0383 return NULL;
0384 }
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395 Barycenter* PDBlib::ComputeNucleotideBarycenters(Molecule* moleculeListTemp)
0396 {
0397
0398
0399 Barycenter* BarycenterFirst = NULL;
0400 Barycenter* BarycenterOld = NULL;
0401 Barycenter* BarycenterNext = NULL;
0402
0403
0404 Residue* residueListTemp;
0405
0406 Atom* AtomTemp;
0407
0408 int k = 0;
0409 int j_old = 0;
0410
0411 while (moleculeListTemp) {
0412 residueListTemp = moleculeListTemp->GetFirst();
0413
0414 k++;
0415 int j = 0;
0416
0417
0418 int correctNumerotationNumber = 0;
0419 if (k == 2 && residueListTemp->fResSeq > 1) {
0420 correctNumerotationNumber = residueListTemp->fResSeq;
0421 }
0422
0423 while (residueListTemp) {
0424 AtomTemp = residueListTemp->GetFirst();
0425 j++;
0426
0427
0428 if (correctNumerotationNumber != 0) {
0429 residueListTemp->fResSeq = residueListTemp->fResSeq - correctNumerotationNumber + 1;
0430 }
0431
0432
0433 double baryX = 0., baryY = 0., baryZ = 0.;
0434 double baryBaseX = 0., baryBaseY = 0., baryBaseZ = 0.;
0435 double barySugX = 0., barySugY = 0., barySugZ = 0.;
0436 double baryPhosX = 0., baryPhosY = 0., baryPhosZ = 0.;
0437 unsigned short int nbAtomInBase = 0;
0438
0439 for (int i = 0; i < residueListTemp->fNbAtom; i++) {
0440
0441 baryX += AtomTemp->fX;
0442 baryY += AtomTemp->fY;
0443 baryZ += AtomTemp->fZ;
0444
0445 if (residueListTemp->fResSeq == 1) {
0446 if (i == 0) {
0447 baryPhosX += AtomTemp->fX;
0448 baryPhosY += AtomTemp->fY;
0449 baryPhosZ += AtomTemp->fZ;
0450 }
0451 else if (i < 8) {
0452 barySugX += AtomTemp->fX;
0453 barySugY += AtomTemp->fY;
0454 barySugZ += AtomTemp->fZ;
0455 }
0456 else {
0457
0458
0459 if (AtomTemp->fElement != "H") {
0460 baryBaseX += AtomTemp->fX;
0461 baryBaseY += AtomTemp->fY;
0462 baryBaseZ += AtomTemp->fZ;
0463 nbAtomInBase++;
0464 }
0465 }
0466 }
0467 else {
0468 if (i < 4) {
0469 baryPhosX += AtomTemp->fX;
0470 baryPhosY += AtomTemp->fY;
0471 baryPhosZ += AtomTemp->fZ;
0472 }
0473 else if (i < 11) {
0474 barySugX += AtomTemp->fX;
0475 barySugY += AtomTemp->fY;
0476 barySugZ += AtomTemp->fZ;
0477 }
0478 else {
0479
0480
0481 if (AtomTemp->fElement != "H") {
0482 baryBaseX += AtomTemp->fX;
0483 baryBaseY += AtomTemp->fY;
0484 baryBaseZ += AtomTemp->fZ;
0485 nbAtomInBase++;
0486 }
0487 }
0488 }
0489 AtomTemp = AtomTemp->GetNext();
0490 }
0491
0492 baryX = baryX / (double)residueListTemp->fNbAtom;
0493 baryY = baryY / (double)residueListTemp->fNbAtom;
0494 baryZ = baryZ / (double)residueListTemp->fNbAtom;
0495
0496 if (residueListTemp->fResSeq != 1)
0497 {
0498 baryPhosX = baryPhosX / 4.;
0499 baryPhosY = baryPhosY / 4.;
0500 baryPhosZ = baryPhosZ / 4.;
0501 }
0502 barySugX = barySugX / 7.;
0503 barySugY = barySugY / 7.;
0504 barySugZ = barySugZ / 7.;
0505 baryBaseX = baryBaseX / (double)nbAtomInBase;
0506 baryBaseY = baryBaseY / (double)nbAtomInBase;
0507 baryBaseZ = baryBaseZ / (double)nbAtomInBase;
0508
0509
0510 if (BarycenterOld == NULL) {
0511 BarycenterOld = new Barycenter(j + j_old, baryX, baryY, baryZ,
0512 baryBaseX, baryBaseY, baryBaseZ, barySugX, barySugY,
0513 barySugZ, baryPhosX, baryPhosY, baryPhosZ);
0514 BarycenterFirst = BarycenterOld;
0515 }
0516 else {
0517 BarycenterNext =
0518 new Barycenter(j + j_old, baryX, baryY, baryZ, baryBaseX, baryBaseY, baryBaseZ, barySugX,
0519 barySugY, barySugZ, baryPhosX, baryPhosY, baryPhosZ);
0520 BarycenterOld->SetNext(BarycenterNext);
0521 BarycenterOld = BarycenterNext;
0522 }
0523
0524
0525
0526
0527 AtomTemp = residueListTemp->GetFirst();
0528 double dT3Dp;
0529 double max = 0.;
0530 for (int ii = 0; ii < residueListTemp->fNbAtom; ii++) {
0531 dT3Dp = DistanceTwo3Dpoints(AtomTemp->fX, BarycenterOld->fCenterX, AtomTemp->fY,
0532 BarycenterOld->fCenterY, AtomTemp->fZ, BarycenterOld->fCenterZ);
0533 BarycenterOld->SetDistance(ii, dT3Dp);
0534 if (dT3Dp > max) max = dT3Dp;
0535 AtomTemp = AtomTemp->GetNext();
0536 }
0537
0538 BarycenterOld->SetRadius(max + 1.8);
0539 residueListTemp = residueListTemp->GetNext();
0540
0541 }
0542
0543 j_old += j;
0544
0545
0546 moleculeListTemp = moleculeListTemp->GetNext();
0547 }
0548
0549 if (BarycenterNext != NULL) {
0550 BarycenterNext->SetNext(NULL);
0551 }
0552
0553 return BarycenterFirst;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563 void PDBlib::ComputeBoundingVolumeParams(Molecule* moleculeListTemp, double& dX, double& dY,
0564 double& dZ,
0565 double& tX, double& tY,
0566 double& tZ)
0567 {
0568 double minminX, minminY, minminZ;
0569 double maxmaxX, maxmaxY, maxmaxZ;
0570
0571 minminX = DBL_MAX;
0572 minminY = DBL_MAX;
0573 minminZ = DBL_MAX;
0574 maxmaxX = -DBL_MAX;
0575 maxmaxY = -DBL_MAX;
0576 maxmaxZ = -DBL_MAX;
0577
0578 while (moleculeListTemp) {
0579 if (minminX > moleculeListTemp->fMaxGlobX) {
0580 minminX = moleculeListTemp->fMaxGlobX;
0581 }
0582 if (minminY > moleculeListTemp->fMaxGlobY) {
0583 minminY = moleculeListTemp->fMaxGlobY;
0584 }
0585 if (minminZ > moleculeListTemp->fMaxGlobZ) {
0586 minminZ = moleculeListTemp->fMaxGlobZ;
0587 }
0588 if (maxmaxX < moleculeListTemp->fMinGlobX) {
0589 maxmaxX = moleculeListTemp->fMinGlobX;
0590 }
0591 if (maxmaxY < moleculeListTemp->fMinGlobY) {
0592 maxmaxY = moleculeListTemp->fMinGlobY;
0593 }
0594 if (maxmaxZ < moleculeListTemp->fMinGlobZ) {
0595 maxmaxZ = moleculeListTemp->fMinGlobZ;
0596 }
0597
0598 moleculeListTemp = moleculeListTemp->GetNext();
0599 }
0600
0601 dX = (maxmaxX - minminX) / 2. + 1.8;
0602 dY = (maxmaxY - minminY) / 2. + 1.8;
0603 dZ = (maxmaxZ - minminZ) / 2. + 1.8;
0604
0605 tX = minminX + (maxmaxX - minminX) / 2.;
0606 tY = minminY + (maxmaxY - minminY) / 2.;
0607 tZ = minminZ + (maxmaxZ - minminZ) / 2.;
0608 }
0609
0610
0611
0612
0613
0614
0615
0616
0617 void PDBlib::ComputeNbNucleotidsPerStrand(Molecule* moleculeListTemp)
0618 {
0619 Residue* residueListTemp;
0620
0621 int j_old = 0;
0622
0623 while (moleculeListTemp) {
0624 residueListTemp = moleculeListTemp->GetFirst();
0625
0626 int j = 0;
0627
0628 while (residueListTemp) {
0629 j++;
0630 residueListTemp = residueListTemp->GetNext();
0631 }
0632
0633 j_old += j;
0634 moleculeListTemp = moleculeListTemp->GetNext();
0635 }
0636
0637 fNbNucleotidsPerStrand = j_old / 2;
0638 }
0639
0640
0641
0642
0643
0644
0645
0646
0647 unsigned short int PDBlib::ComputeMatchEdepDNA(Barycenter* BarycenterList,
0648 Molecule* moleculeListTemp, double x, double y,
0649 double z, int& numStrand, int& numNucleotid,
0650 int& codeResidue)
0651 {
0652 unsigned short int matchFound = 0;
0653
0654 Molecule* mLTsavedPointer = moleculeListTemp;
0655 Barycenter* BLsavedPointer = BarycenterList;
0656
0657 short int strandNum = 0;
0658 int residueNum = 1;
0659 G4String baseName;
0660 unsigned short int BSP = 2;
0661
0662 double smallestDist;
0663 double distEdepDNA;
0664 double distEdepAtom;
0665
0666
0667 Residue* residueListTemp;
0668
0669 Atom* AtomTemp;
0670
0671 int k = 0;
0672 moleculeListTemp = mLTsavedPointer;
0673 BarycenterList = BLsavedPointer;
0674
0675 smallestDist = 33.0;
0676 while (moleculeListTemp) {
0677 k++;
0678 residueListTemp = moleculeListTemp->GetFirst();
0679
0680 int j = 0;
0681
0682 int j_save = INT_MAX;
0683
0684 while (residueListTemp) {
0685 j++;
0686
0687 if (j - j_save > 2) break;
0688
0689 distEdepDNA = DistanceTwo3Dpoints(x, BarycenterList->fCenterX, y, BarycenterList->fCenterY, z,
0690 BarycenterList->fCenterZ);
0691 if (distEdepDNA < BarycenterList->GetRadius()) {
0692
0693
0694
0695 AtomTemp = residueListTemp->GetFirst();
0696 for (int iii = 0; iii < residueListTemp->fNbAtom; iii++) {
0697 distEdepAtom =
0698 DistanceTwo3Dpoints(x, AtomTemp->GetX(), y, AtomTemp->GetY(), z, AtomTemp->GetZ());
0699
0700 if ((distEdepAtom < AtomTemp->GetVanDerWaalsRadius()) && (smallestDist > distEdepAtom)) {
0701 strandNum = k;
0702
0703 if (k == 2) {
0704 residueNum = fNbNucleotidsPerStrand + 1 - residueListTemp->fResSeq;
0705 }
0706 else {
0707 residueNum = residueListTemp->fResSeq;
0708 }
0709
0710 baseName = (residueListTemp->fResName)[2];
0711 if (residueListTemp->fResSeq == 1) {
0712 if (iii == 0)
0713 BSP = 0;
0714 else if (iii < 8)
0715 BSP = 1;
0716 else
0717 BSP = 2;
0718 }
0719 else {
0720 if (iii < 4)
0721 BSP = 0;
0722 else if (iii < 11)
0723 BSP = 1;
0724 else
0725 BSP = 2;
0726 }
0727
0728 smallestDist = distEdepAtom;
0729
0730 int j_max_value = INT_MAX;
0731
0732 if (j_save == j_max_value) j_save = j;
0733 matchFound = 1;
0734 }
0735 AtomTemp = AtomTemp->GetNext();
0736 }
0737 }
0738 BarycenterList = BarycenterList->GetNext();
0739 residueListTemp = residueListTemp->GetNext();
0740 }
0741 moleculeListTemp = moleculeListTemp->GetNext();
0742 }
0743
0744 numStrand = strandNum;
0745 numNucleotid = residueNum;
0746 codeResidue = BSP;
0747
0748 return matchFound;
0749 }
0750
0751
0752
0753 double PDBlib::DistanceTwo3Dpoints(double xA, double xB, double yA, double yB, double zA, double zB)
0754 {
0755 return sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB) + (zA - zB) * (zA - zB));
0756 }