BondVectors.cpp
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:18k
源码类别:

并行计算

开发平台:

Visual C++

  1. /*
  2.     FastGrid (formerly AutoGrid)
  3.     Copyright (C) 2009 The Scripps Research Institute. All rights reserved.
  4.     Copyright (C) 2009 Masaryk University. All rights reserved.
  5.     AutoGrid is a Trade Mark of The Scripps Research Institute.
  6.     This program is free software; you can redistribute it and/or
  7.     modify it under the terms of the GNU General Public License
  8.     as published by the Free Software Foundation; either version 2
  9.     of the License, or (at your option) any later version.
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17. */
  18. #include <cstring>
  19. #include "BondVectors.h"
  20. BondVectors::BondVectors(int numReceptorAtoms, LogFile *logFile): logFile(logFile)
  21. {
  22.     disorder = new bool[numReceptorAtoms];
  23.     rexp = new int[numReceptorAtoms];
  24.     rvector = new Vec3d[numReceptorAtoms];
  25.     rvector2 = new Vec3d[numReceptorAtoms];
  26.     
  27.     memset(rexp, 0, sizeof(sizeof(int) * numReceptorAtoms));
  28. }
  29. BondVectors::~BondVectors()
  30. {
  31.     delete [] disorder;
  32.     delete [] rexp;
  33.     delete [] rvector;
  34.     delete [] rvector2;
  35. }
  36. void BondVectors::calculate(const InputData *input, const ParameterLibrary &parameterLibrary)
  37. {
  38.     Vec3d d;
  39.     Vec3d dc;
  40.     double rdot;
  41.     int from, to;
  42.     int nbond;
  43.     int i1 = 0, i2 = 0, i3 = 0;
  44.     double inv_rd, rd2;
  45.     // Loop over all RECEPTOR atoms to
  46.     // calculate bond vectors for directional H-bonds
  47.     // setup the canned atom types here....
  48.     // at this point set up hydrogen, carbon, oxygen and nitrogen
  49.     int hydrogen = parameterLibrary.getAtomParameterRecIndex("HD");
  50.     int nonHB_hydrogen = parameterLibrary.getAtomParameterRecIndex("H");
  51.     int carbon = parameterLibrary.getAtomParameterRecIndex("C");
  52.     int arom_carbon = parameterLibrary.getAtomParameterRecIndex("A");
  53.     int oxygen = parameterLibrary.getAtomParameterRecIndex("OA");
  54.     int sulphur = parameterLibrary.getAtomParameterRecIndex("SA");
  55.     // These are not used
  56.     /*int nitrogen = parameterLibrary.getAtomParameterRecIndex("NA");
  57.     int nonHB_nitrogen = parameterLibrary.getAtomParameterRecIndex("N");
  58.     int nonHB_sulphur = parameterLibrary.getAtomParameterRecIndex("S");*/
  59.     // 7:CHANGE HERE: scan the 'mapIndex' from the input
  60.     for (int ia = 0; ia < input->numReceptorAtoms; ia++)
  61.     {
  62.         //** ia = i_receptor_atom_a **
  63.         disorder[ia] = false;   // initialize disorder flag.
  64.         bool warned = false;
  65.         // Set scan limits looking for bonded atoms
  66.         from = Mathi::Max(ia - 20, 0);
  67.         to = Mathi::Min(ia + 20, input->numReceptorAtoms - 1);
  68.         // If 'ia' is a hydrogen atom, it could be a
  69.         // RECEPTOR hydrogen-BOND DONOR,
  70.         // TODO: 8:CHANGE HERE: fix the input->atomType vs atom_types problem in following
  71.         if (input->hbond[ia] == D1) // D1 hydrogen bond donor
  72.         {
  73.             for (int ib = from; ib <= to; ib++)
  74.                 if (ib != ia) // ib = i_receptor_atom_b
  75.                 {
  76.                     // =>  NH-> or OH->
  77.                     // if ((input->atomType[ib] == nitrogen) || (input->atomType[ib]==nonHB_nitrogen) ||(input->atomType[ib] == oxygen)||(input->atomType[ib] == sulphur)||(input->atomType[ib]==nonHB_sulphur)) {
  78.                     // Calculate the square of the N-H or O-H bond distance, rd2,
  79.                     //                            ib-ia  ib-ia
  80.                     d = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[ib]);
  81.                     rd2 = d.MagnitudeSqr();
  82.                     // If ia & ib are less than 1.3 A apart -- they are covalently bonded,
  83.                     if (rd2 < 1.90)
  84.                     {
  85.                         // INCREASED for H-S bonds
  86.                         if (rd2 < APPROX_ZERO)
  87.                         {
  88.                             if (rd2 == 0)
  89.                                 logFile->printErrorFormatted(WARNING,
  90.                                     "While calculating an H-O or H-N bond vector...nAttempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn",
  91.                                     ia + 1, ib + 1);
  92.                             rd2 = APPROX_ZERO;
  93.                         }
  94.                         inv_rd = Mathd::Rsqrt(rd2);
  95.                         // N-H: Set exponent rexp to 2 for m/m H-atom,
  96.                         // if (input->atomType[ib] == nitrogen) rexp[ia] = 2;
  97.                         if ((input->atomType[ib] != oxygen) && (input->atomType[ib] != sulphur))
  98.                             rexp[ia] = 2;
  99.                         // O-H: Set exponent rexp to 4 for m/m H-atom,
  100.                         // and flag disordered hydroxyls
  101.                         if ((input->atomType[ib] == oxygen) || (input->atomType[ib] == sulphur))
  102.                         {
  103.                             rexp[ia] = 4;
  104.                             if (input->disorderH)
  105.                                 disorder[ia] = true;
  106.                         }
  107.                         // Normalize the vector from ib to ia, N->H or O->H...
  108.                         rvector[ia] = d * inv_rd;
  109.                         // First O-H/N-H H-bond-donor found; Go on to next atom,
  110.                         break;
  111.                     }           // Found covalent bond.
  112.                     // } Found NH or OH in receptor.
  113.                 }
  114.             // Finished scanning for the NH or OH in receptor.
  115.             // If 'ia' is an Oxygen atom, it could be a
  116.             // RECEPTOR H_BOND ACCEPTOR,
  117.         }
  118.         else if (input->hbond[ia] == A2)
  119.         {
  120.             // A2
  121.             // Scan from at most, (ia-20)th m/m atom, or ia-th (if ia<20)
  122.             //        to (ia + 5)th m/m-atom
  123.             // determine number of atoms bonded to the oxygen
  124.             nbond = 0;
  125.             int ib = from;
  126.             for (; ib <= to; ib++)
  127.                 if (ib != ia)
  128.                 {
  129.                     dc = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[ib]);
  130.                     rd2 = dc.MagnitudeSqr();
  131.                     if (((rd2 < 3.61) && ((input->atomType[ib] != hydrogen) && (input->atomType[ib] != nonHB_hydrogen))) ||
  132.                         ((rd2 < 1.69) && ((input->atomType[ib] == hydrogen) || (input->atomType[ib] == nonHB_hydrogen))))
  133.                     {
  134.                         if (nbond == 2)
  135.                             logFile->printErrorFormatted(WARNING, "Found an H-bonding atom with three bonded atoms, atom serial number %dn", ia + 1);
  136.                         if (nbond == 1)
  137.                         {
  138.                             nbond = 2;
  139.                             i2 = ib;
  140.                         }
  141.                         if (nbond == 0)
  142.                         {
  143.                             nbond = 1;
  144.                             i1 = ib;
  145.                         }
  146.                     }
  147.                 }               // (ib != ia)
  148.             // if no bonds, something is wrong
  149.             if (nbond == 0)
  150.                 logFile->printErrorFormatted(WARNING, "Oxygen atom found with no bonded atoms, atom serial number %d, input->atomType %dn", ia + 1, input->atomType[ia]);
  151.             // one bond: Carbonyl Oxygen O=C-X
  152.             if (nbond == 1)
  153.             {
  154.                 // calculate normalized carbonyl bond vector rvector[ia][]
  155.                 rvector[ia] = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[i1]);
  156.                 rd2 = rvector[ia].MagnitudeSqr();
  157.                 if (rd2 < APPROX_ZERO)
  158.                 {
  159.                     if ((rd2 == 0) && !warned)
  160.                     {
  161.                         logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", ia + 1, i1 + 1);
  162.                         warned = true;
  163.                     }
  164.                     rd2 = APPROX_ZERO;
  165.                 }
  166.                 inv_rd = Mathd::Rsqrt(rd2);
  167.                 rvector[ia] *= inv_rd;
  168.                 // find a second atom (i2) bonded to carbonyl carbon (i1)
  169.                 for (int i2 = from; i2 <= to; i2++)
  170.                     if ((i2 != i1) && (i2 != ia))
  171.                     {
  172.                         dc = Vec3d(input->receptorAtom[i1]) - Vec3d(input->receptorAtom[i2]);
  173.                         rd2 = dc.MagnitudeSqr();
  174.                         if (((rd2 < 2.89) && (input->atomType[i2] != hydrogen)) || ((rd2 < 1.69) && (input->atomType[i2] == hydrogen)))
  175.                         {
  176.                             // found one
  177.                             // d[i] vector from carbon to second atom
  178.                             d = Vec3d(input->receptorAtom[i2]) - Vec3d(input->receptorAtom[i1]);
  179.                             rd2 = d.MagnitudeSqr();
  180.                             if (rd2 < APPROX_ZERO)
  181.                             {
  182.                                 if ((rd2 == 0) && !warned)
  183.                                 {
  184.                                     logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", i1 + 1, i2 + 1);
  185.                                     warned = true;
  186.                                 }
  187.                                 rd2 = APPROX_ZERO;
  188.                             }
  189.                             inv_rd = Mathd::Rsqrt(rd2);
  190.                             d *= inv_rd;
  191.                             // C=O cross C-X gives the lone pair plane normal
  192.                             rvector2[ia] = Vec3d::Cross(rvector[ia], d);
  193.                             rd2 = rvector2[ia].MagnitudeSqr();
  194.                             if (rd2 < APPROX_ZERO)
  195.                             {
  196.                                 if ((rd2 == 0) && !warned)
  197.                                 {
  198.                                     logFile->printError(WARNING, "Attempt to divide by zero was just prevented.nn");
  199.                                     warned = true;
  200.                                 }
  201.                                 rd2 = APPROX_ZERO;
  202.                             }
  203.                             inv_rd = Mathd::Rsqrt(rd2);
  204.                             rvector2[ia] *= inv_rd;
  205.                         }
  206.                     }
  207.             }                   // endif nbond==1
  208.             // two bonds: Hydroxyl or Ether Oxygen X1-O-X2
  209.             if (nbond == 2)
  210.                 // disordered hydroxyl
  211.                 if ((input->atomType[i1] == hydrogen || input->atomType[i2] == hydrogen) && input->atomType[i1] != input->atomType[i2] && input->disorderH)
  212.                 {
  213.                     if ((input->atomType[i1] == carbon) || (input->atomType[i1] == arom_carbon))
  214.                         ib = i1;
  215.                     if ((input->atomType[i2] == carbon) || (input->atomType[i1] == arom_carbon))
  216.                         ib = i2;
  217.                     disorder[ia] = true;
  218.                     rvector[ia] = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[ib]);
  219.                     rd2 = rvector[ia].MagnitudeSqr();
  220.                     if (rd2 < APPROX_ZERO)
  221.                     {
  222.                         if ((rd2 == 0) && !warned)
  223.                         {
  224.                             logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", ia + 1, ib + 1);
  225.                             warned = true;
  226.                         }
  227.                         rd2 = APPROX_ZERO;
  228.                     }
  229.                     inv_rd = Mathd::Rsqrt(rd2);
  230.                     rvector[ia] *= inv_rd;
  231.                 }
  232.                 else
  233.                 {
  234.                     // not a disordered hydroxyl
  235.                     // normalized X1 to X2 vector, defines lone pair plane
  236.                     rvector2[ia] = Vec3d(input->receptorAtom[i2]) - Vec3d(input->receptorAtom[i1]);
  237.                     rd2 = rvector2[ia].MagnitudeSqr();
  238.                     if (rd2 < APPROX_ZERO)
  239.                     {
  240.                         if ((rd2 == 0) && !warned)
  241.                         {
  242.                             logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", i1 + 1, i2 + 1);
  243.                             warned = true;
  244.                         }
  245.                         rd2 = APPROX_ZERO;
  246.                     }
  247.                     inv_rd = Mathd::Rsqrt(rd2);
  248.                     rvector2[ia] *= inv_rd;
  249.                     // vector pointing between the lone pairs:
  250.                     // front of the vector is the oxygen atom,
  251.                     // X1->O vector dotted with normalized X1->X2 vector plus
  252.                     // coords of X1 gives the point on the X1-X2 line for the
  253.                     // back of the vector.
  254.                     rdot = Vec3d::Dot(Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[i1]), rvector2[ia]);
  255.                     rvector[ia] = Vec3d(input->receptorAtom[ia]) - (rvector2[ia]*rdot + Vec3d(input->receptorAtom[i1]));
  256.                     rd2 = rvector[ia].MagnitudeSqr();
  257.                     if (rd2 < APPROX_ZERO)
  258.                     {
  259.                         if ((rd2 == 0) && !warned)
  260.                         {
  261.                             logFile->printError(WARNING, "Attempt to divide by zero was just prevented.nn");
  262.                             warned = true;
  263.                         }
  264.                         rd2 = APPROX_ZERO;
  265.                     }
  266.                     inv_rd = Mathd::Rsqrt(rd2);
  267.                     rvector[ia] *= inv_rd;
  268.                 }               // end disordered hydroxyl
  269.         }
  270.         else if (input->hbond[ia] == A1)
  271.         {                       // A1
  272.             // Scan from at most, (ia-20)th m/m atom, or ia-th (if ia<20)
  273.             //        to (ia+5)th m/m-atom
  274.             // determine number of atoms bonded to the oxygen
  275.             nbond = 0;
  276.             int ib = from;
  277.             for (; ib <= to; ib++)
  278.                 if (ib != ia)
  279.                 {
  280.                     dc = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[ib]);
  281.                     rd2 = dc.MagnitudeSqr();
  282.                     if (((rd2 < 2.89) && ((input->atomType[ib] != hydrogen) && (input->atomType[ib] != nonHB_hydrogen))) ||
  283.                         ((rd2 < 1.69) && ((input->atomType[ib] == hydrogen) || (input->atomType[ib] == nonHB_hydrogen))))
  284.                     {
  285.                         if (nbond == 2)
  286.                         {
  287.                             nbond = 3;
  288.                             i3 = ib;
  289.                         }
  290.                         if (nbond == 1)
  291.                         {
  292.                             nbond = 2;
  293.                             i2 = ib;
  294.                         }
  295.                         if (nbond == 0)
  296.                         {
  297.                             nbond = 1;
  298.                             i1 = ib;
  299.                         }
  300.                     }
  301.                 }               // (ib != ia)
  302.             // if no bonds, something is wrong
  303.             if (nbond == 0)
  304.                 logFile->printErrorFormatted(WARNING, "Nitrogen atom found with no bonded atoms, atom serial number %dn", ia);
  305.             // one bond: Azide Nitrogen :N=C-X
  306.             if (nbond == 1)
  307.             {
  308.                 // calculate normalized N=C bond vector rvector[ia][]
  309.                 rvector[ia] = Vec3d(input->receptorAtom[ia]) - Vec3d(input->receptorAtom[i1]);
  310.                 rd2 = rvector[ia].MagnitudeSqr();
  311.                 if (rd2 < APPROX_ZERO)
  312.                 {
  313.                     if ((rd2 == 0) && !warned)
  314.                     {
  315.                         logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", ia, ib);
  316.                         warned = true;
  317.                     }
  318.                     rd2 = APPROX_ZERO;
  319.                 }
  320.                 inv_rd = Mathd::Rsqrt(rd2);
  321.                 rvector[ia] *= inv_rd;
  322.             }                   // endif nbond==1
  323.             // two bonds: X1-N=X2
  324.             if (nbond == 2)
  325.             {
  326.                 // normalized vector from Nitrogen to midpoint between X1 and X2
  327.                 rvector[ia] = Vec3d(input->receptorAtom[ia]) - (Vec3d(input->receptorAtom[i2]) + Vec3d(input->receptorAtom[i1])) / 2;
  328.                 rd2 = rvector[ia].MagnitudeSqr();
  329.                 if (rd2 < APPROX_ZERO)
  330.                 {
  331.                     if ((rd2 == 0) && !warned)
  332.                     {
  333.                         logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", ia, ib);
  334.                         warned = true;
  335.                     }
  336.                     rd2 = APPROX_ZERO;
  337.                 }
  338.                 inv_rd = Mathd::Rsqrt(rd2);
  339.                 rvector[ia] *= inv_rd;
  340.             }                   // end two bonds for nitrogen
  341.             // three bonds: X1,X2,X3
  342.             if (nbond == 3)
  343.             {
  344.                 // normalized vector from Nitrogen to midpoint between X1, X2, and X3
  345.                 rvector[ia] = Vec3d(input->receptorAtom[ia]) - (Vec3d(input->receptorAtom[i1]) + Vec3d(input->receptorAtom[i2]) + Vec3d(input->receptorAtom[i3])) / 3;
  346.                 rd2 = rvector[ia].MagnitudeSqr();
  347.                 if (rd2 < APPROX_ZERO)
  348.                 {
  349.                     if ((rd2 == 0) && !warned)
  350.                     {
  351.                         logFile->printErrorFormatted(WARNING, "Attempt to divide by zero was just prevented.nAre the coordinates of atoms %d and %d the same?nn", ia, ib);
  352.                         warned = true;
  353.                     }
  354.                     rd2 = APPROX_ZERO;
  355.                 }
  356.                 inv_rd = Mathd::Rsqrt(rd2);
  357.                 rvector[ia] *= inv_rd;
  358.             }                   // end three bonds for Nitrogen
  359.             // endNEW directional N Acceptor
  360.         }                       // end test for atom type
  361.     }                           // Do Next receptor atom...
  362. }