public static void Compute(Vector[] coords, out double energy, out double forceij, out double springij, double epsij, double rmin) { /// !V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6] /// !epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j) /// !Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j /// /// V(r) = epsij * r0^12 * rij^-12 - 2 * epsij * r0^6 * rij^-6 /// = epsij * (r0 / rij)^12 - 2 * epsij * (r0 / rij)^6 /// F(r) = -12 * epsij * r0^12 * rij^-13 - -6*2 * epsij * r0^6 * rij^-7 /// = -12 * epsij * (r0 / rij)^12 / rij - -6*2 * epsij * (r0 / rij)^6 / rij /// K(r) = -13*-12 * epsij * r0^12 * rij^-14 - -7*-6*2 * epsij * r0^6 * rij^-8 /// = -13*-12 * epsij * (r0 / rij)^12 / rij^2 - -7*-6*2 * epsij * (r0 / rij)^6 / rij^2 double rij = (coords[1] - coords[0]).Dist; double rij2 = rij * rij; double rmin_rij = rmin / rij; double rmin_rij_2 = rmin_rij * rmin_rij; double rmin_rij_6 = rmin_rij_2 * rmin_rij_2 * rmin_rij_2; double rmin_rij_12 = rmin_rij_6 * rmin_rij_6; energy = epsij * rmin_rij_12 - 2 * epsij * rmin_rij_6; forceij = (-12) * epsij * rmin_rij_12 / rij - (-6 * 2) * epsij * rmin_rij_6 / rij; springij = (-13 * -12) * epsij * rmin_rij_12 / rij2 - (-7 * -6 * 2) * epsij * rmin_rij_6 / rij2; HDebug.AssertIf(forceij > 0, rmin < rij); // positive force => attractive HDebug.AssertIf(forceij < 0, rij < rmin); // negative force => repulsive }
public Nonbonded FindNonbonded(string type0, ITextLogger logger) { if (_FindNonbonded.ContainsKey(type0) == false) { Nonbonded found = null; foreach (Nonbonded nonbonded in nonbondeds) { if (nonbonded.types[0] == type0) { if (found != null) { bool writelog = ((found.epsilon != nonbonded.epsilon) || (found.Rmin2 != nonbonded.Rmin2) || (found.eps_14 != nonbonded.eps_14) || (found.Rmin2_14 != nonbonded.Rmin2_14)); if (writelog) { logger.Log(string.Format("Nonbonded params of {0}-(eps {1}, rmin2 {2}, esp_14 {3}, rmin2_14 {4}) is replaced to ({5}, {6}, {7}, {8})", type0, found.epsilon, found.Rmin2, found.eps_14, found.Rmin2_14, nonbonded.epsilon, nonbonded.Rmin2, nonbonded.eps_14, nonbonded.Rmin2_14)); } } found = nonbonded; } } HDebug.Assert(found != null); HDebug.AssertIf(double.IsNaN(found.Rmin2) == false, found.Rmin2 > 0); HDebug.AssertIf(double.IsNaN(found.Rmin2_14) == false, found.Rmin2_14 > 0); _FindNonbonded.Add(type0, found); } return(_FindNonbonded[type0]); }
public static void Compute(Vector[] coords, out double energy, out double force01, out double spring01, double Kb, double b0) { /// BONDS /// !V(bond) = Kb(b - b0)**2 /// /// p0 ---------- p1 /// (+) --→ ←-- (+) /// ←-- (-) (-) --→ /// /// V = Kb ( b - b0 ) ^ 2 /// d_V / d_b = 2 Kb ( b - b0 ) /// d2_V / d_b2 = 2 Kb /// /// b = b1 + t /// d_b / d_t = 1 /// d2_b / d_t2 = 0 /// /// energy = V /// = Kb ( b - b0 ) ^ 2 /// /// force = d_V / d_t /// = {d_V / d_b } * {d_b / d_t} /// = {2 Kb ( b - b0 )} * { 1 } /// = 2 Kb ( b - b0 ) /// /// spring = d_V2 / d2_t /// = d_(d_V / d_t) / d_t /// = d_({d_V / d_b } * {d_b / d_t}) / d_t /// = {d_{d_V / d_b } / d_t} * {d_b / d_t} /// + {d_V / d_b } * {d_{d_b / d_t} / d_t} /// = {d2_V / d_b2}*{d_b / d_t} * {d_b / d_t} /// + {d_V / d_b } * {d2_b / d_t2} /// = {d2_V / d_b2}*{d_b / d_t}*{d_b / d_t} + {d_V / d_b }*{d2_b / d_t2} /// = {2 Kb }*{ 1 }*{ 1 } + {2 Kb (b - b0)}*{ 0 } /// = 2 Kb /////////////////////////////////////////////////////////////////////////////// Vector pos1 = coords[0]; Vector pos2 = coords[1]; double b = (pos1 - pos2).Dist; HDebug.Assert(b != 0, double.IsNaN(b) == false, double.IsInfinity(b) == false); energy = Kb * (b - b0) * (b - b0); force01 = 2 * Kb * (b - b0); spring01 = 2 * Kb; HDebug.AssertIf(force01 > 0, b0 < b); // positive force => attractive HDebug.AssertIf(force01 < 0, b < b0); // negative force => repulsive }
public static void Compute(Vector[] coords, out double energy, out double forceij, out double springij, double pchij, double ee) { /// !V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6] /// !epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j) /// !Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j /// /// V(rij) = (332 * pchij / ee) * rij^-1 /// F(rij) = ( -1) * (332 * pchij / ee) * rij^-2 /// K(rij) = (-2*-1) * (332 * pchij / ee) * rij^-3 double rij = (coords[1] - coords[0]).Dist; double rij2 = rij * rij; double rij3 = rij * rij2; energy = (332 * pchij / ee) / rij; forceij = (-1) * (332 * pchij / ee) / rij2; springij = (-2 * -1) * (332 * pchij / ee) / rij3; HDebug.AssertIf(forceij > 0, pchij < 0); // positive force => attractive HDebug.AssertIf(forceij < 0, pchij > 0); // negative force => repulsive }
public static void GetBFactor(Top topol, Eigenvec eigenvec, out string[] name, out int[] resSeq, out double[] BFactor , bool ignoreNegativeEigval = true ) { List <Gromacs.Top.Atom> atoms = topol.GetAtoms(); name = new string[atoms.Count]; resSeq = new int[atoms.Count]; BFactor = new double[atoms.Count]; for (int i = 0; i < atoms.Count; i++) { name[i] = atoms[i].atom; resSeq[i] = atoms[i].resnr; int count_lambda_0 = 0; foreach (var frame in eigenvec.frames) { if (frame.lambda != 0) { continue; } if (frame.step <= 6) { HDebug.Assert(frame.step == frame.frameidx); continue; } count_lambda_0++; Vector[] eigvec = frame.x; double eigval = frame.time; HDebug.AssertIf(eigval < 0, Math.Abs(eigval) < 0.00001); if (ignoreNegativeEigval) { if (eigval < 0) { continue; } } HDebug.Assert(BFactor.Length == eigvec.Length); BFactor[i] += LinAlg.VtV(eigvec[i], eigvec[i]) / eigval; } } }
public static int[] ListBondedDistFrom(this IList <Atom> atoms, IList <Atom> froms) { // build graph Graph <Atom, Bond> bondedgraph = atoms.BuildBondedGraph(); // build dijkstra Graph <Atom, Bond> .Dijkstra.Elem[] elems; { Dictionary <Graph <Atom, Bond> .Node, double> source2initdist = new Dictionary <Graph <Atom, Bond> .Node, double>(); foreach (var from in froms) { Graph <Atom, Bond> .Node fromnode = bondedgraph.GetNode(from); source2initdist.Add(fromnode, 0); } Dictionary <Graph <Atom, Bond> .Edge, double> edge_dist = new Dictionary <Graph <Atom, Bond> .Edge, double>(); foreach (var edge in bondedgraph.Edges) { edge_dist.Add(edge, 1); } elems = Graph <Atom, Bond> .Dijkstra.BuildMinSum(bondedgraph, source2initdist, edge_dist, IsTarget : null); } // build distances int[] dists; { int maxdist = -1; dists = new int[atoms.Count]; for (int i = 0; i < atoms.Count; i++) { Atom atom = atoms[i]; var node = bondedgraph.GetNode(atom); var path = Graph.Dijkstra.GetPathNode(elems, node); dists[i] = path.Length - 1; // this include "CA" atom, and the distance of "CA" itself is 0. HDebug.Assert(dists[i] >= 0); HDebug.AssertIf(atom.AtomName.Trim() == "CA", dists[i] == 0); maxdist = Math.Max(maxdist, dists[i]); } } return(dists); }
public static ValueTuple <double, double> GetFijKij(double a, double b, double c, double K0, double T0, double fij_sign = +1, double kij_sign0 = +1, double kij_sign1 = +1) { /// + /// |\ /// | \ /// a | \ c /// | \ /// |T \ /// +-----+ /// b /// /// V = K0 (T - T0)^2 /// F = dV/dT = 2 K0 (T - T0) /// K = (d^2 V)/(d T^2) = 2 K0 /// return { dV/dc, (d^2 V)/(d c^2) } double a2 = a * a; double b2 = b * b; double c2 = c * c; double c4 = c2 * c2; double ab = a * b; double ab2 = ab * ab; double T = acos((a2 + b2 - c2) / (2 * ab)); // θ = acos((a^2+b^2-c^2)/2ab) double V = K0 * (T - T0) * (T - T0); // V = K0 ( θ - θ0 )^2 double dV_dT = 2 * K0 * (T - T0); // ∂V/∂θ = 2K0 ( θ - θ0 ) double d2V_dT2 = 2 * K0; // (∂^2 V)/(∂θ^2 ) = 2K0 double dT_dc = 2 * c / sqrt((4 * ab2) - pow(a2 + b2 - c2, 2)); // ∂θ/∂c = 2c/√((2ab)^2-(a^2+b^2-c^2 )^2 ) double d2T_dc2 = 2 * (c4 - pow(a2 - b2, 2)) / pow((4 * ab2) - pow(a2 + b2 - c2, 2), 1.5); // (∂^2 θ)/(∂c^2 ) = 2(c^4-(a^2-b^2 )^2 )/((2ab)^2-(a^2+b^2-c^2 )^2 )^1.5 double dV_dc = 2 * K0 * (T - T0) * 2 * c / sqrt((4 * ab2) - pow(a2 + b2 - c2, 2)); // ∂V/∂c = 2K0(θ-θ0 ) ⋅ 2c/√((2ab)^2-(a^2+b^2-c^2 )^2 ) double d2V_dc2 = kij_sign0 * (2 * K0 * 4 * c2 / ((4 * ab2) - pow(a2 + b2 - c2, 2))) // (∂^2 V)/(∂c^2 ) = {2K_0⋅(4c^2)/((2ab)^2-(a^2+b^2-c^2 )^2 )} + kij_sign1 * (2 * K0 * (T - T0) * 2 * (c4 - pow(a2 - b2, 2)) // + {2K_0 (θ-θ_0 )⋅2(c^4-(a^2-b^2 )^2 ) / pow((4 * ab2) - pow(a2 + b2 - c2, 2), 1.5) // /((2ab)^2-(a^2+b^2-c^2 )^2 )^1.5 } ); double fij = dV_dc; double kij = d2V_dc2; HDebug.AssertIf(fij > 0, T0 < T); // positive force => attractive HDebug.AssertIf(fij < 0, T < T0); // negative force => repulsive return(new ValueTuple <double, double>(fij, kij)); }
static double GetPotentialUpdated_ProbToCheckWithGetPotential = 0;//1;//0.1; public double GetPotentialUpdated(List <ForceField.IForceField> frcflds , double?energy0, Vector[] coords0, Vector[] forces0 , Vector[] coords, Vector[] forces , ref Nonbondeds_v1 nonbondeds ) { if (GetPotentialUpdated_SelfTestDo == true) #region selftest { GetPotentialUpdated_SelfTest(frcflds, energy0, coords0, forces0, coords, forces); } #endregion bool[] updated = new bool[size]; if ((energy0 == null) || (nonbondeds == null)) { HDebug.AssertIf(energy0 == null, coords0 == null); HDebug.AssertIf(energy0 == null, forces0 == null); energy0 = 0; coords0 = null; forces0 = null; for (int i = 0; i < size; i++) { forces[i] = new double[3]; } for (int i = 0; i < size; i++) { updated[i] = true; } } else { HDebug.Assert(size == coords0.Length); HDebug.Assert(size == forces0.Length); HDebug.Assert(size == coords.Length); HDebug.Assert(size == forces.Length); for (int i = 0; i < size; i++) { forces[i] = forces0[i].Clone(); } int countskip = 0; //double[] dist2s = new double[size]; //for(int i=0; i<size; i++) // dist2s[i] = (coords0[i] - coords[i]).Dist2; //int[] idxsorted = dist2s.IdxSorted(); //for(int i=0; i<size; i++) // updated[i] = (dist2s[i] > (0.000001*0.000001)); //for(int i=size/2; i<size; i++) // updated[idxsorted[i]] = true; for (int i = 0; i < size; i++) { updated[i] = (coords0[i] != coords[i]); } for (int i = 0; i < size; i++) { countskip += (updated[i] == false) ? 1 : 0; } if ((size - countskip) * 10 > size) { energy0 = 0; coords0 = null; forces0 = null; for (int i = 0; i < size; i++) { forces[i] = new double[3]; } for (int i = 0; i < size; i++) { updated[i] = true; } } System.Console.Write(" countskip({0:000}) ", countskip); } Vector[] dforces = GetVectorsZero(); double denergy = 0; denergy += GetPotentialUpdated_ComputeCustomsBond(frcflds, updated, 0, coords0, coords, dforces); denergy += GetPotentialUpdated_ComputeCustomsAngle(frcflds, updated, 0, coords0, coords, dforces); denergy += GetPotentialUpdated_ComputeCustomsDihedral(frcflds, updated, 0, coords0, coords, dforces); denergy += GetPotentialUpdated_ComputeCustomsImproper(frcflds, updated, 0, coords0, coords, dforces); denergy += GetPotentialUpdated_ComputeCustomsNonbonded(frcflds, updated, 0, coords0, coords, dforces, ref nonbondeds); //energy += GetPotentialUpdated_ComputeCustomsCustoms (frcflds, updated, 0, coords0, forces0, coords, forces); double energy = energy0.Value + denergy; for (int i = 0; i < size; i++) { forces[i] += dforces[i]; } #region commented from threading //Nonbondeds lnonbondeds = nonbondeds; // //double energy = energy0.Value; // //object lockobj = new object(); //System.Threading.Tasks.ParallelOptions parallelOptions = new ParallelOptions(); ////parallelOptions.MaxDegreeOfParallelism = 1; //Parallel.ForEach(compunits_bonded, parallelOptions, delegate(GetForcesCompUnit compunit) //{ // if(compunit == null) // { // // in the first iteration, collect nonbonded components // GetForces_CollectCompUnitNonbonded(frcflds, updated, coords0, coords, ref lnonbondeds, compunits_nonbonded); // } // else // { // Triple<double, int[], Vector[]> denergy_idx_dforces = compunit.Compute(coords0, coords); // double denergy = denergy_idx_dforces.first; // int[] idx = denergy_idx_dforces.second; // Vector[] dforces = denergy_idx_dforces.third; // Debug.Assert(idx.Length == dforces.Length); // lock(lockobj) // { // energy += denergy; // for(int i=0; i<idx.Length; i++) // forces[idx[i]] += dforces[i]; // } // } //}); //nonbondeds = lnonbondeds; //Parallel.ForEach(compunits_nonbonded, parallelOptions, delegate(GetForcesCompUnit compunit) //{ // Triple<double, int[], Vector[]> denergy_idx_dforces = compunit.Compute(coords0, coords); // double denergy = denergy_idx_dforces.first; // int[] idx = denergy_idx_dforces.second; // Vector[] dforces = denergy_idx_dforces.third; // Debug.Assert(idx.Length == dforces.Length); // lock(lockobj) // { // energy += denergy; // for(int i=0; i<idx.Length; i++) // forces[idx[i]] += dforces[i]; // } //}); #endregion if (HDebug.IsDebuggerAttachedWithProb(GetPotentialUpdated_ProbToCheckWithGetPotential)) #region check force with GetPotential(...) { //Vector[] _forces0 = GetVectorsZero(); //Matrix _hessian0 = null; //double _energy0 = GetPotential(frcflds, coords0, ref _forces0, ref _hessian0, new Dictionary<string,object>()); //Debug.AssertTolerance(0.00000001, energy0 - _energy0); //Debug.AssertTolerance(0.00000001, Vector.Sub(forces0, _forces0)); Vector[] _forces = GetVectorsZero(); MatrixByArr _hessian = null; double _energy = GetPotential(frcflds, coords, ref _forces, ref _hessian, new Dictionary <string, object>()); HDebug.AssertTolerance(0.00000001, energy - _energy); HDebug.AssertToleranceVector(0.00000001, Vector.Sub(forces, _forces)); } #endregion //if(cache != null) //{ // if(cache.ContainsKey("energy_bonds ") == false) cache.Add("energy_bonds ", 0); cache["energy_bonds "] = energy_bonds ; // if(cache.ContainsKey("energy_angles ") == false) cache.Add("energy_angles ", 0); cache["energy_angles "] = energy_angles ; // if(cache.ContainsKey("energy_dihedrals ") == false) cache.Add("energy_dihedrals ", 0); cache["energy_dihedrals "] = energy_dihedrals ; // if(cache.ContainsKey("energy_impropers ") == false) cache.Add("energy_impropers ", 0); cache["energy_impropers "] = energy_impropers ; // if(cache.ContainsKey("energy_nonbondeds") == false) cache.Add("energy_nonbondeds", 0); cache["energy_nonbondeds"] = energy_nonbondeds; // if(cache.ContainsKey("energy_customs ") == false) cache.Add("energy_customs ", 0); cache["energy_customs "] = energy_customs ; //} return(energy); }
public static void Compute(Vector[] coords, out double energy, out double force02, out double spring02, double Ktheta, double Theta0, double Kub, double S0) { Func <double, double> sqrt = Math.Sqrt; Func <double, double> acos = Math.Acos; Func <double, double, double> pow = Math.Pow; /// ANGLES /// !V(angle) = Ktheta(Theta - Theta0)**2 /// !V(Urey-Bradley) = Kub(S - S0)**2 // ignore this term here... /// /// p1 /// /θ \ /// / \ /// b c /// / \ /// / \ /// p0 ----a----- p2 /// (+) --→ ←-- (+) /// ←-- (-) (-) --→ /// /// V = Kθ ( θ - θ0 ) ^ 2 /// d_V / d_θ = 2 Kθ ( θ - θ0 ) /// d2_V / d_θ2 = 2 Kθ /// /// θ = acos( (b^2 + c^2 - a^2)/(2*b*c) ) /// = acos( (b2 + c2 - a2 )/(2*b*c) ) /// = acos( cosθ ) ⇐ cosθ = (b^2 + c^2 - a^2)/(2*b*c) /// d_θ / d_a = a / (b c sqrt(1 - cosθ2)) ⇐ cosθ2 = cosθ * cosθ /// d2_θ / d_a2 = {a2/(b2 c2)} * {-cosθ / sqrt(1 - cosθ2)^3} + {1/(b c sqrt(1 - cosθ2))} /// /// energy = V /// force = d_V / d_a /// = {d_V / d_θ} * {d_θ / d_a} /// spring = d_V2 / d2_a /// = d_(d_V / d_a) / d_a /// = d_({d_V / d_θ } * {d_θ / d_a}) / d_a /// = {d_{d_V / d_θ } / d_a} * {d_θ / d_a} /// + {d_V / d_θ } * {d_{d_θ / d_a} / d_a} /// = {d2_V / d_θ2}*{d_θ / d_a} * {d_θ / d_a} /// + {d_V / d_θ } * {d2_θ / d_a2} /// = {d2_V / d_θ2}*{d_θ / d_a}*{d_θ / d_a} + {d_V / d_θ}*{d2_θ / d_a2} /////////////////////////////////////////////////////////////////////////////// Vector p0 = coords[0]; Vector p1 = coords[1]; Vector p2 = coords[2]; double a = (p0 - p2).Dist; double a2 = a * a; double b = (p0 - p1).Dist; double b2 = b * b; double c = (p1 - p2).Dist; double c2 = c * c; double KA = Ktheta; double A0 = Theta0; double cosA = (b2 + c2 - a2) / (2 * b * c); double cosA2 = cosA * cosA; double A = acos(cosA); double dA_da = a / (b * c * sqrt(1 - cosA2)); double d2A_da2 = (a2 / (b2 * c2)) * (-cosA / pow(sqrt(1 - cosA2), 3)) + (1 / (b * c * sqrt(1 - cosA2))); double V = KA * (A - A0) * (A - A0); double dV_dA = 2 * KA * (A - A0); double d2V_dA2 = 2 * KA; energy = V; force02 = dV_dA * dA_da; spring02 = d2V_dA2 * dA_da * dA_da + dV_dA * d2A_da2; HDebug.AssertIf(force02 > 0, A0 < A); // positive force => attractive HDebug.AssertIf(force02 < 0, A < A0); // negative force => repulsive }
public static Universe Build(Tinker.Xyz xyz, Tinker.Prm prm, Pdb pdb , double?tolCoordPdbXyz // 0.002 for default distance // (0.001 * sqrt(3) = 0.0017321, which is the largest tolerance between pdb and xyz) // null for not ordering by distance; ) { Universe univ = new Universe(); Dictionary <int, Prm.Atom> prm_id2atom = prm.atoms.ToIdDictionary(); Dictionary <int, Prm.Vdw> prm_cls2vdw = prm.vdws.ToClassDictionary(); Dictionary <int, Prm.Vdw14> prm_cls2vdw14 = prm.vdw14s.ToClassDictionary(); Dictionary <Tuple <int, int>, Prm.Bond> prm_cls2bond = prm.bonds.ToClassDictionary(); Dictionary <Tuple <int, int, int>, Prm.Angle> prm_cls2angle = prm.angles.ToClassDictionary(); Dictionary <Tuple <int, int, int>, Prm.Ureybrad> prm_cls2ureybrad = prm.ureybrads.ToClassDictionary(); Dictionary <Tuple <int, int, int, int>, Prm.Improper> prm_cls2improper = prm.impropers.ToClassDictionary(); Dictionary <Tuple <int, int, int, int>, Prm.Torsion> prm_cls2torsion = prm.torsions.ToClassDictionary(); Dictionary <int, Prm.Charge> prm_id2charge = prm.charges.ToIdDictionary(); Prm.Biotype[] prm_biotypes = prm.biotypes; Xyz.Atom[] xyz_atoms = xyz.atoms; Pdb.Atom[] pdb_atoms = (pdb != null) ? pdb.atoms : null; Dictionary <int, Xyz.Atom> xyz_id2atom = xyz_atoms.ToIdDictionary(); KDTree.KDTree <Tuple <int, Pdb.Atom> > coord2pdbatom = null; { if (pdb_atoms != null) { coord2pdbatom = new KDTree.KDTree <Tuple <int, Pdb.Atom> >(3); for (int ia = 0; ia < pdb_atoms.Length; ia++) { Pdb.Atom pdb_atom = pdb_atoms[ia]; Vector coord = pdb_atom.coord; coord2pdbatom.insert(coord.ToArray(), new Tuple <int, Pdb.Atom>(ia, pdb_atom)); } } } Atoms atoms = new Atoms(univ); /// Debug.Assert(pdb.atoms.Length == top_atoms.Count); for (int i = 0; i < xyz_atoms.Length; i++) { Xyz.Atom xyz_atom = xyz_atoms[i]; Pdb.Atom pdb_atom = null; // = (pdb_atoms != null) ? (pdb_atoms[i]) : null; if (coord2pdbatom != null) { Vector xyz_coord = xyz_atom.Coord; Tuple <int, Pdb.Atom> ia_atom = coord2pdbatom.nearest(xyz_coord); Vector pdb_coord = ia_atom.Item2.coord; if (tolCoordPdbXyz == null) { pdb_atom = pdb_atoms[i]; } else { if ((xyz_coord - pdb_coord).Dist < tolCoordPdbXyz) { pdb_atom = ia_atom.Item2; } else { //HDebug.Assert(false); pdb_atom = null; } } } if (pdb_atom != null) { string pdb_atom_type = pdb_atom.element.Trim(); string xyz_atom_type = xyz_atom.AtomType.Trim(); if (HDebug.IsDebuggerAttached && pdb_atom_type.Length > 0) // sometimes element is blank: " " { HDebug.AssertIf(pdb_atom_type[0] == xyz_atom_type[0]); } if (tolCoordPdbXyz != null) { HDebug.AssertTolerance(tolCoordPdbXyz.Value, xyz_atom.Coord - pdb_atom.coord); } } //if(pdb_atom != null) Debug.Assert(xyz_atom.Id == pdb_atom.serial); HDebug.Assert(i + 1 == xyz_atom.Id); Prm.Atom prm_atom = prm_id2atom [xyz_atom.AtomId]; Prm.Charge prm_charge = prm_id2charge[xyz_atom.AtomId]; Prm.Vdw prm_vdw = null; Prm.Vdw14 prm_vdw14 = null; if (prm_cls2vdw.ContainsKey(prm_atom.Class)) { prm_vdw = prm_cls2vdw [prm_atom.Class]; } if (prm_cls2vdw14.ContainsKey(prm_atom.Class)) { prm_vdw14 = prm_cls2vdw14[prm_atom.Class]; } if (pdb_atom != null) { if (pdb_atom.element.Trim() != "") { if (pdb_atom.element.Trim() != prm_atom.AtomElem) { throw new Exception(); } } } Atom uatom = new Atom(AtomId: xyz_atom.Id , AtomName: ((pdb_atom != null) ? (pdb_atom.name.Trim()) : ("?" + prm_atom.Type)) /// fix later , AtomType: prm_atom.Type , AtomElem: prm_atom.AtomElem , ResidueId: ((pdb_atom != null) ? (pdb_atom.resSeq) : (-1)) /// fix later , ResidueName: ((pdb_atom != null) ? (pdb_atom.resName.Trim()) : ("?res")) /// fix later , Charge: prm_charge.pch , Mass: prm_atom.Mass , epsilon: ((prm_vdw != null) ? prm_vdw.Epsilon : 0) , Rmin2: ((prm_vdw != null) ? prm_vdw.Rmin2 : 0) , eps_14: ((prm_vdw14 != null) ? prm_vdw14.Eps_14 : double.NaN) , Rmin2_14: ((prm_vdw14 != null) ? prm_vdw14.Rmin2_14 : double.NaN) , sources: new object[] { xyz_atom, pdb_atom, prm_atom, prm_charge } ); uatom.Coord = xyz_atom.Coord; atoms.Add(uatom); } // bonds Bonds bonds; { Dictionary <Tuple <Atom, Atom>, Bond> lbonds = new Dictionary <Tuple <Atom, Atom>, Bond>(); for (int i = 0; i < xyz_atoms.Length; i++) { int id0 = xyz_atoms[i].Id; HDebug.Assert(id0 == i + 1); int atm0 = xyz_atoms[i].AtomId; int cls0 = prm_id2atom[atm0].Class; Atom atom0 = atoms[id0 - 1]; HDebug.Assert(atom0.AtomId == id0); Tuple <int, int> cls; foreach (int id1 in xyz_atoms[i].BondedIds) { int atm1 = xyz_id2atom[id1].AtomId; int cls1 = prm_id2atom[atm1].Class; Atom atom1 = atoms[id1 - 1]; HDebug.Assert(atom1.AtomId == id1); HashSet <Prm.Bond> bondtypes = new HashSet <Prm.Bond>(); Atom[] iatom = null; cls = new Tuple <int, int>(cls0, cls1); if (prm_cls2bond.ContainsKey(cls)) { bondtypes.Add(prm_cls2bond[cls]); iatom = new Atom[] { atom0, atom1 }; } cls = new Tuple <int, int>(cls1, cls0); if (prm_cls2bond.ContainsKey(cls)) { bondtypes.Add(prm_cls2bond[cls]); iatom = new Atom[] { atom1, atom0 }; } HDebug.Assert(bondtypes.Count == 1); if (bondtypes.Count >= 1) { Prm.Bond bondtype = bondtypes.Last(); HDebug.Assert(bondtype != null); // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0) if (iatom.First().ID > iatom.Last().ID) { iatom = iatom.Reverse().ToArray(); } var key = new Tuple <Atom, Atom>(iatom[0], iatom[1]); Bond bond = new Bond(iatom[0], iatom[1], bondtype.Kb, bondtype.b0, bondtype); if (lbonds.ContainsKey(key) == false) { lbonds.Add(key, bond); } else { HDebug.Assert(bond.Kb == lbonds[key].Kb); HDebug.Assert(bond.b0 == lbonds[key].b0); } } } } bonds = new Bonds(); foreach (Bond bond in lbonds.Values) { HDebug.Assert(bond.atoms.Length == 2); HDebug.Assert(bond.atoms[0].ID < bond.atoms[1].ID); bonds.Add(bond); Atom atom0 = bond.atoms[0]; Atom atom1 = bond.atoms[1]; atom0.Bonds.Add(bond); atom0.Inter123.Add(atom1); atom0.Inter12.Add(atom1); atom1.Bonds.Add(bond); atom1.Inter123.Add(atom0); atom1.Inter12.Add(atom0); } } HashSet <Atom>[] inter12 = new HashSet <Atom> [xyz_atoms.Length]; HashSet <Tuple <Atom, Atom> >[] inter123 = new HashSet <Tuple <Atom, Atom> > [xyz_atoms.Length]; HashSet <Tuple <Atom, Atom, Atom> >[] inter1234 = new HashSet <Tuple <Atom, Atom, Atom> > [xyz_atoms.Length]; { HDebug.Assert(xyz_atoms.Length == atoms.Count); foreach (Atom atom in atoms) { inter12 [atom.ID] = new HashSet <Atom>(atom.Inter12); inter123 [atom.ID] = new HashSet <Tuple <Atom, Atom> >(); inter1234[atom.ID] = new HashSet <Tuple <Atom, Atom, Atom> >(); } // build inter123 and inter1234 for (int i = 0; i < xyz_atoms.Length; i++) { Atom atom0 = atoms[i]; HDebug.Assert(atom0.ID == i); foreach (Atom atom1 in inter12[atom0.ID]) { HDebug.Assert(atom0 != atom1); foreach (Atom atom2 in inter12[atom1.ID]) { HDebug.Assert(atom1 != atom2); if (atom0 == atom2) { continue; } inter123[atom0.ID].Add(new Tuple <Atom, Atom>(atom1, atom2)); foreach (Atom atom3 in inter12[atom2.ID]) { HDebug.Assert(atom2 != atom3); if (atom0 == atom2) { continue; } if (atom0 == atom3) { continue; } if (atom1 == atom3) { continue; } inter1234[atom0.ID].Add(new Tuple <Atom, Atom, Atom>(atom1, atom2, atom3)); } } } } } // angles Angles angles; { Dictionary <Tuple <Atom, Atom, Atom>, Angle> langles = new Dictionary <Tuple <Atom, Atom, Atom>, Angle>(); foreach (Atom atom0 in atoms) { int id0 = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1); int atm0 = xyz_atoms[atom0.ID].AtomId; int cls0 = prm_id2atom[atm0].Class; foreach (var atom123 in inter123[atom0.ID]) { Atom atom1 = atom123.Item1; int atm1 = xyz_atoms[atom1.ID].AtomId; int cls1 = prm_id2atom[atm1].Class; Atom atom2 = atom123.Item2; int atm2 = xyz_atoms[atom2.ID].AtomId; int cls2 = prm_id2atom[atm2].Class; Tuple <int, int, int> cls; Atom[] iatom = null; HashSet <Prm.Angle> angs = new HashSet <Prm.Angle>(); HashSet <Prm.Ureybrad> urbs = new HashSet <Prm.Ureybrad>(); cls = new Tuple <int, int, int>(cls0, cls1, cls2); if (prm_cls2angle.ContainsKey(cls)) { angs.Add(prm_cls2angle[cls]); iatom = new Atom[] { atom0, atom1, atom2 }; } if (prm_cls2ureybrad.ContainsKey(cls)) { urbs.Add(prm_cls2ureybrad[cls]); } cls = new Tuple <int, int, int>(cls2, cls1, cls0); if (prm_cls2angle.ContainsKey(cls)) { angs.Add(prm_cls2angle[cls]); iatom = new Atom[] { atom2, atom1, atom0 }; } if (prm_cls2ureybrad.ContainsKey(cls)) { urbs.Add(prm_cls2ureybrad[cls]); } HDebug.Assert(angs.Count == 1); HDebug.Assert(urbs.Count <= angs.Count); if (angs.Count >= 1) { Prm.Angle ang = angs.Last(); HDebug.Assert(ang != null); Prm.Ureybrad urb = null; if (urbs.Count >= 1) { urb = urbs.Last(); } // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0) if (iatom.First().ID > iatom.Last().ID) { iatom = iatom.Reverse().ToArray(); } var key = new Tuple <Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2]); Angle angle = new Angle(iatom[0], iatom[1], iatom[2] , Ktheta: ang.Ktheta , Theta0: ang.Theta0 , Kub: ((urb != null) ? urb.Kub : 0) , S0: ((urb != null) ? urb.S0 : 0) , sources: new object[] { ang, urb } ); if (langles.ContainsKey(key) == false) { langles.Add(key, angle); } else { HDebug.Assert(langles[key].Ktheta == angle.Ktheta , langles[key].Theta0 == angle.Theta0 , langles[key].Kub == angle.Kub , langles[key].S0 == angle.S0 ); } } } } angles = new Angles(); foreach (Angle angle in langles.Values) { HDebug.Assert(angle.atoms.Length == 3); HDebug.Assert(angle.atoms[0].ID < angle.atoms[2].ID); angles.Add(angle); Atom atom0 = angle.atoms[0]; Atom atom1 = angle.atoms[1]; Atom atom2 = angle.atoms[2]; atom0.Angles.Add(angle); atom0.Inter123.Add(atom1); atom0.Inter123.Add(atom2); atom1.Angles.Add(angle); atom1.Inter123.Add(atom2); atom1.Inter123.Add(atom0); atom2.Angles.Add(angle); atom2.Inter123.Add(atom0); atom2.Inter123.Add(atom1); } } // dihedrals Dihedrals dihedrals; { Dictionary <Tuple <Atom, Atom, Atom, Atom>, List <Dihedral> > ldihedrals = new Dictionary <Tuple <Atom, Atom, Atom, Atom>, List <Dihedral> >(); foreach (Atom atom0 in atoms) { int id0 = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1); int atm0 = xyz_atoms[atom0.ID].AtomId; int cls0 = prm_id2atom[atm0].Class; Tuple <int, int, int, int> cls; foreach (var atom1234 in inter1234[atom0.ID]) { Atom atom1 = atom1234.Item1; int atm1 = xyz_atoms[atom1.ID].AtomId; int cls1 = prm_id2atom[atm1].Class; Atom atom2 = atom1234.Item2; int atm2 = xyz_atoms[atom2.ID].AtomId; int cls2 = prm_id2atom[atm2].Class; Atom atom3 = atom1234.Item3; int atm3 = xyz_atoms[atom3.ID].AtomId; int cls3 = prm_id2atom[atm3].Class; HashSet <Prm.Torsion> tors = new HashSet <Prm.Torsion>(); Atom[] iatom = null; cls = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); if (prm_cls2torsion.ContainsKey(cls)) { tors.Add(prm_cls2torsion[cls]); iatom = new Atom[] { atom0, atom1, atom2, atom3 }; } cls = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); if (prm_cls2torsion.ContainsKey(cls)) { tors.Add(prm_cls2torsion[cls]); iatom = new Atom[] { atom3, atom2, atom1, atom0 }; } HDebug.Assert(tors.Count == 1); if (tors.Count >= 1) { // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0) if (iatom.First().ID > iatom.Last().ID) { iatom = iatom.Reverse().ToArray(); } var key = new Tuple <Atom, Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2], iatom[3]); if (ldihedrals.ContainsKey(key) == false) { ldihedrals.Add(key, new List <Dihedral>()); Prm.Torsion tor = tors.Last(); foreach (var tordat in tor.GetListData()) { Dihedral dihedral = new Dihedral(iatom[0], iatom[1], iatom[2], iatom[3] , Kchi: tordat.Kchi , n: tordat.n , delta: tordat.delta , sources: new object[] { tor } ); ldihedrals[key].Add(dihedral); HDebug.Assert(dihedral.n != 0); } } else { // do not check its contents because ... } } } } dihedrals = new Dihedrals(); foreach (var ldihedral in ldihedrals.Values) { foreach (Dihedral dihedral in ldihedral) { HDebug.Assert(dihedral.atoms.Length == 4); HDebug.Assert(dihedral.atoms[0].ID < dihedral.atoms[3].ID); dihedrals.Add(dihedral); dihedral.atoms[0].Dihedrals.Add(dihedral); dihedral.atoms[1].Dihedrals.Add(dihedral); dihedral.atoms[2].Dihedrals.Add(dihedral); dihedral.atoms[3].Dihedrals.Add(dihedral); } } } // impropers Impropers impropers = new Impropers(); { Dictionary <Tuple <Atom, Atom, Atom, Atom>, Improper> limpropers = new Dictionary <Tuple <Atom, Atom, Atom, Atom>, Improper>(); foreach (Atom atom0 in atoms) { /// #################################### /// ## ## /// ## Improper Dihedral Parameters ## /// ## ## /// #################################### /// /// ################################################################## /// ## ## /// ## Following CHARMM style, the improper for a trigonal atom ## /// ## D bonded to atoms A, B and C could be input as improper ## /// ## dihedral angle D-A-B-C. The actual angle computed by the ## /// ## program is then literally the dihedral D-A-B-C, which will ## /// ## always have as its ideal value zero degrees. In general ## /// ## D-A-B-C is different from D-B-A-C; the order of the three ## /// ## peripheral atoms matters. In the original CHARMM parameter ## /// ## files, the trigonal atom is often listed last; ie, as ## /// ## C-B-A-D instead of D-A-B-C. ## /// ## ## /// ## Some of the improper angles are "double counted" in the ## /// ## CHARMM protein parameter set. Since TINKER uses only one ## /// ## improper parameter per site, we have doubled these force ## /// ## constants in the TINKER version of the CHARMM parameters. ## /// ## Symmetric parameters, which are the origin of the "double ## /// ## counted" CHARMM values, are handled in the TINKER package ## /// ## by assigning all symmetric states and using the TINKER ## /// ## force constant divided by the symmetry number. ## /// ## ## /// ## ... ## /// ################################################################## int id0 = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1); int atm0 = xyz_atoms[atom0.ID].AtomId; int cls0 = prm_id2atom[atm0].Class; bool bAtom0InImpropers = false; foreach (var cls in prm_cls2improper.Keys) { if (cls.Item1 == cls0) { bAtom0InImpropers = true; } } if (bAtom0InImpropers == false) { continue; } Atom[] bondeds0 = inter12[atom0.ID].ToArray(); if (bondeds0.Length < 3) { continue; } for (int i = 0; i < bondeds0.Length - 2; i++) { Atom atom1 = bondeds0[i]; int atm1 = xyz_atoms[atom1.ID].AtomId; int cls1 = prm_id2atom[atm1].Class; for (int j = i + 1; j < bondeds0.Length - 1; j++) { Atom atom2 = bondeds0[j]; int atm2 = xyz_atoms[atom2.ID].AtomId; int cls2 = prm_id2atom[atm2].Class; for (int k = j + 1; k < bondeds0.Length; k++) { Atom atom3 = bondeds0[k]; int atm3 = xyz_atoms[atom3.ID].AtomId; int cls3 = prm_id2atom[atm3].Class; Tuple <int, int, int, int> cls; HashSet <Prm.Improper> imps = new HashSet <Prm.Improper>(); Atom[] iatom = null; cls = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom1, atom2, atom3 }; } cls = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom3, atom2, atom1, atom0 }; } cls = new Tuple <int, int, int, int>(cls0, cls1, cls3, cls2); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom1, atom3, atom2 }; } cls = new Tuple <int, int, int, int>(cls2, cls3, cls1, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom2, atom3, atom1, atom0 }; } cls = new Tuple <int, int, int, int>(cls0, cls2, cls1, cls3); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom2, atom1, atom3 }; } cls = new Tuple <int, int, int, int>(cls3, cls1, cls2, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom3, atom1, atom2, atom0 }; } cls = new Tuple <int, int, int, int>(cls0, cls2, cls3, cls1); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom2, atom3, atom1 }; } cls = new Tuple <int, int, int, int>(cls1, cls3, cls2, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom1, atom3, atom2, atom0 }; } cls = new Tuple <int, int, int, int>(cls0, cls3, cls1, cls2); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom3, atom1, atom2 }; } cls = new Tuple <int, int, int, int>(cls2, cls1, cls3, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom2, atom1, atom3, atom0 }; } cls = new Tuple <int, int, int, int>(cls0, cls3, cls2, cls1); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom3, atom2, atom1 }; } cls = new Tuple <int, int, int, int>(cls1, cls2, cls3, cls0); if (prm_cls2improper.ContainsKey(cls)) { imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom1, atom2, atom3, atom0 }; } HDebug.Assert(imps.Count <= 1); // for example, H-C-HHH has C-HHH connectivity but it is not improper... // so imps.count <= 1 if (imps.Count >= 1) { Prm.Improper imp = imps.Last(); // because iatoms contains the last case only. /////////////////////////////////////////////////////////////////////////////////////// // This bug was raised by Jae-Kyun Song at 2016-04-01 // // In 1AAC, (1501,C)-(1503,NC2)-(1502,NC2)-(1500,NC2) is reordered // // as (1500,NC2)-(1502,NC2)-(1503,NC2)-(1501,C) // // This bug was originally copied from dihedral code that is added to prevent adding // // duplicated interactions such as 1-2-3-4 and 4-3-2-1. // /////////////////////////////////////////////////////////////////////////////////////// /// old code // // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0) // if(iatom.First().ID > iatom.Last().ID) // iatom = iatom.Reverse().ToArray(); // var key = new Tuple<Atom, Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2], iatom[3]); /////////////////////////////////////////////////////////////////////////////////////// /// new code Tuple <Atom, Atom, Atom, Atom> key; { Atom key0 = iatom[0]; Atom[] key123 = (new Atom[] { iatom[1], iatom[2], iatom[3] }).SortByIDs(); key = new Tuple <Atom, Atom, Atom, Atom>(key0, key123[0], key123[1], key123[2]); } /////////////////////////////////////////////////////////////////////////////////////// Improper improper = new Improper(iatom[0], iatom[1], iatom[2], iatom[3] , Kpsi: imp.Kpsi , psi0: imp.psi0 , sources: new object[] { imp } ); if (limpropers.ContainsKey(key) == false) { limpropers.Add(key, improper); } else { HDebug.Assert(limpropers[key].Kpsi == improper.Kpsi , limpropers[key].psi0 == improper.psi0 ); } } } } } } foreach (var improper in limpropers.Values) { HDebug.Assert(improper.atoms.Length == 4); //HDebug.Assert(improper.atoms[0].ID < improper.atoms[3].ID); impropers.Add(improper); improper.atoms[0].Impropers.Add(improper); improper.atoms[1].Impropers.Add(improper); improper.atoms[2].Impropers.Add(improper); improper.atoms[3].Impropers.Add(improper); } } // 1-4 interactions for (int i = 0; i < atoms.Count; i++) { HashSet <Atom> Inter14 = new HashSet <Atom>(); BuildInter1toN(atoms[i], 4, Inter14); // find all atoms for 1-4 interaction Inter14.Remove(atoms[i]); // remove self foreach (Atom atom in atoms[i].Inter123) { Inter14.Remove(atom); // remove all 1-2, 1-3 interactions } atoms[i].Inter14 = Inter14; } Nonbonded14s nonbonded14s = new Nonbonded14s(); nonbonded14s.Build(atoms); //// nonbondeds //// do not make this list in advance, because it depends on the atom positions //Nonbondeds nonbondeds = new Nonbondeds(); //nonbondeds.Build(atoms); //Universe univ = new Universe(); univ.pdb = pdb; univ.refs.Add("xyz", xyz); univ.refs.Add("prm", prm); univ.refs.Add("pdb", pdb); univ.atoms = atoms; univ.bonds = bonds; univ.angles = angles; univ.dihedrals = dihedrals; univ.impropers = impropers; //univ.nonbondeds = nonbondeds ; // do not make this list in advance, because it depends on the atom positions univ.nonbonded14s = nonbonded14s; HDebug.Assert(univ.Verify()); if (HDebug.False) { List <Tuple <double, string, Bond> > lbnds = new List <Tuple <double, string, Bond> >(); foreach (Bond bnd in bonds) { lbnds.Add(new Tuple <double, string, Bond>(bnd.Kb , bnd.atoms[0].AtomType + "-" + bnd.atoms[1].AtomType , bnd)); } lbnds = lbnds.HSelectByIndex(lbnds.HListItem1().HIdxSorted().Reverse().ToArray()).ToList(); double avgKb = lbnds.HListItem1().Average(); List <Tuple <double, string, Angle> > langs = new List <Tuple <double, string, Angle> >(); List <Tuple <double, string, Angle> > langubs = new List <Tuple <double, string, Angle> >(); foreach (Angle ang in angles) { langs.Add(new Tuple <double, string, Angle>(ang.Ktheta , ang.atoms[0].AtomType + "-" + ang.atoms[1].AtomType + "-" + ang.atoms[2].AtomType , ang)); if (ang.Kub != 0) { langubs.Add(new Tuple <double, string, Angle>(ang.Kub , ang.atoms[0].AtomType + "-" + ang.atoms[1].AtomType + "-" + ang.atoms[2].AtomType , ang)); } } langs = langs.HSelectByIndex(langs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList(); langubs = langubs.HSelectByIndex(langubs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList(); double avgKtheta = langs.HListItem1().Average(); double avgKub = langubs.HListItem1().Average(); List <Tuple <double, string, Improper> > limps = new List <Tuple <double, string, Improper> >(); foreach (Improper imp in impropers) { limps.Add(new Tuple <double, string, Improper>(imp.Kpsi , imp.atoms[0].AtomType + "-" + imp.atoms[1].AtomType + "-" + imp.atoms[2].AtomType + "-" + imp.atoms[3].AtomType , imp)); } limps = limps.HSelectByIndex(limps.HListItem1().HIdxSorted().Reverse().ToArray()).ToList(); double avgKpsi = limps.HListItem1().Average(); List <Tuple <double, string, Dihedral> > ldihs = new List <Tuple <double, string, Dihedral> >(); foreach (Dihedral dih in dihedrals) { ldihs.Add(new Tuple <double, string, Dihedral>(dih.Kchi , dih.atoms[0].AtomType + "-" + dih.atoms[1].AtomType + "-" + dih.atoms[2].AtomType + "-" + dih.atoms[3].AtomType , dih)); } ldihs = ldihs.HSelectByIndex(ldihs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList(); double avgKchi = ldihs.HListItem1().Average(); } return(univ); }
public static HKijFij GetKijFijNbnd(bool vdW, bool elec , Vector coordi, double ri0, double qi, double ei , Vector coordj, double rj0, double qj, double ej , double D // dielectric constant: 80 for general (solvent), 1 for Tinker (NMA) ) { /// http://www.ks.uiuc.edu/Training/Tutorials/science/forcefield-tutorial/forcefield-html/node5.html /// http://www.charmmtutorial.org/index.php/The_Energy_Function /// /// NONBONDED /// /// charmm : V_nbnd = epsilon_ij ( (r0ij / rij)^12 - 2 * (r0ij / rij)^6 ) + (qi*qj)/(epsilon*rij) /// = epsilon_ij ( r0ij^12 * rij^-12 - 2 * r0ij^6 * rij^-6) + (qi*qj/epsilon) * rij^-1 /// frc_nbnd = epsilon_ij ( -12 * r0ij^12 * rij^-13 - (-6*2) * r0ij^6 * rij^-7) + (-1)*(qi*qj/epsilon) * rij^-2 /// = epsilon_ij ( -12 * r0ij^12 * rij^-13 + 12 * r0ij^6 * rij^-7) + -1*(qi*qj/epsilon) * rij^-2 /// spr_nbnd = epsilon_ij ( (-12*-13) * r0ij^12 * rij^-14 -(-6*-7*2) * r0ij^6 * rij^-8) + (-1*-2)*(qi*qj/epsilon) * rij^-3 /// = epsilon_ij ( 156 * r0ij^12 * rij^-14 + 84 * r0ij^6 * rij^-8) + 2*(qi*qj/epsilon) * rij^-3 /// /// V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6] /// /// epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j) /// Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j /// /// atom ignored epsilon Rmin/2 ignored eps,1-4 Rmin/2,1-4 /// /// V(electrostatic) : V(i,j) = (qi*qj)/(epsilon*rij) /// = 332*qi*qj/r_ij/D /// Where D is dielectric constant, for proteins. D is normally 80. (see equation (13) in the following pdf file). /// http://pharmacy.ucsd.edu/labs/gilson/ce_www1a.pdf /// epsilon = D/332 HDebug.AssertIf(elec, (double.IsNaN(D) == false) && (double.IsInfinity(D) == false)); // electric: conversion from electron**2/Angstrom to Kcal/mol double electric; electric = 332.063709; // tinker pmpb.c line 570 electric = 332.05382; // tinker pmpb.c line 716 electric = 332.063709; // tinker pmpb.c line 851 // units.f line 53 : c coulomb conversion from electron**2/Ang to kcal/mole // units.f line 82 : parameter (coulomb=332.063714d0) // initprm.f line 272 : electric = coulomb electric = 332.063714; // chgpot.f line 16 : c dielec dielectric constant for electrostatic interactions // initprm.f line 273 : dielec = 1.0d0 double dielec = 1.0; double rij = (coordi - coordj).Dist; double r0ij = (ri0 + rj0); double qij = qi * qj; double eij = Math.Sqrt(ei * ej); double eps = D / 332; double Kvdw = eij * (-12 * -13) * Math.Pow(r0ij / rij, 12) / (rij * rij) - eij * (-6 * -7 * 2) * Math.Pow(r0ij / rij, 6) / (rij * rij); double Kelec = 2 * (qij / eps) / (rij * rij * rij); double Fvdw = eij * (-12) * Math.Pow(r0ij / rij, 12) / rij - eij * (-6 * 2) * Math.Pow(r0ij / rij, 6) / rij; double Felec = (-1) * (qij / eps) / (rij * rij); double Evdw = eij * (1) * Math.Pow(r0ij / rij, 12) - eij * (2) * Math.Pow(r0ij / rij, 6); double Eelec = (1) * (qij / eps) / (rij); double ee = D; double Kvdw_stem = eij; //Math.Sqrt(atom0.epsilon * atom1.epsilon) double Kelec_stem = (332.0 / 60.0 * qij / ee / r0ij); //Debug.Assert(Kvdw + Kelec >= 0); double Kij = 0; double Fij = 0; if (vdW) { Kij += Kvdw; Fij += Fvdw; } if (elec) { Kij += Kelec; Fij += Felec; } //double pweng = Evdw + Eelec; //double pwfrc = Fvdw + Felec; //double pwspr = Kij; return(new HKijFij { Kij = Kij, Fij = Fij }); }
public static Tuple <Xyz, Prm> BuildFromNamd(Pdb pdb, Namd.Psf psf, Namd.Prm prm) { var univ = Universe.BuilderNamd.Build(psf, prm, pdb, null, null); /// Atom(Id,Class,Type,Desc,Mass) /// * Id : Vdw(Id,Rmin2,Epsilon) /// Charge(Id,pch) /// Biotype(BioId,Name,Resi,Id) /// * Class: Vdw14(Class,Rmin2_14,Eps_14) /// Bond(Class1,Class2,Kb,b0) /// Angle(Class1,Class2,Class3,Ktheta,Theta0) /// Ureybrad(Class1,Class2,Class3,Kub,S0) /// Improper(Class1,Class2,Class3,Class4,Kpsi,psi0) /// Torsion(Class1,Class2,Class3,Class4,Kchi0,delta0,n0,Kchi1,delta1,n1,Kchi2,delta2,n2) /// Type : Dictionary <Tuple <string, string, double, double, double, int>, int> key_id = new Dictionary <Tuple <string, string, double, double, double, int>, int>(); Dictionary <string, int> type_cls = new Dictionary <string, int>(); Dictionary <int, Prm.Atom> id_atom = new Dictionary <int, Prm.Atom>(); Dictionary <int, Prm.Vdw> cls_vdw = new Dictionary <int, Prm.Vdw>(); Dictionary <int, Prm.Charge> id_charge = new Dictionary <int, Prm.Charge>(); Dictionary <int, Prm.Biotype> id_biotype = new Dictionary <int, Prm.Biotype>(); Dictionary <int, Prm.Vdw14> cls_vdw14 = new Dictionary <int, Prm.Vdw14>(); Dictionary <int, Tuple <string, Vector, int, List <int> > > xyzid_info = new Dictionary <int, Tuple <string, Vector, int, List <int> > >(); /// 1 NH3 /// ------------------------------------------------------------------------------------------------------------------ /// pdb: "ATOM 1 N GLY A 2 24.776 -0.687 28.652 1.00 0.00 A N" /// namd-psf: " 1 A 2 GLY N NH3 -0.300000 14.0070 0" /// namd-prm: "NH3 0.000000 -0.200000 1.850000 ! ALLOW POL" /// tink-xyz: " 1 NH3 24.776000 -0.687000 28.652000 65 2 5 6 7" /// tink-prm: "atom 65 26 NH3 "Ammonium Nitrogen" 7 14.007 4" foreach (var uatom in univ.atoms) { HDebug.Assert(uatom.sources.Length == 3); Pdb.Atom pdbatom = uatom.sources.HFirstByType(null as Pdb.Atom); HDebug.Assert(pdbatom != null); Namd.Psf.Atom psfatom = uatom.sources.HFirstByType(null as Namd.Psf.Atom); HDebug.Assert(psfatom != null); Namd.Prm.Nonbonded prmnbnd = uatom.sources.HFirstByType(null as Namd.Prm.Nonbonded); HDebug.Assert(prmnbnd != null); string name = psfatom.AtomName.Trim(); string resn = psfatom.ResidueName.Trim(); string type = psfatom.AtomType.Trim(); double rmin2 = prmnbnd.Rmin2; double eps = prmnbnd.epsilon; double chrg = psfatom.Charge; int valnc = uatom.Bonds.Count; string desc = string.Format("{0}({1})-{2}", name, type, resn); var key = UnivAtomToTinkKey(uatom); if (key_id.ContainsKey(key) == false) { key_id.Add(key, key_id.Count + 1); } if (type_cls.ContainsKey(type) == false) { type_cls.Add(type, type_cls.Count + 1); } int tink_id = key_id[key]; int tink_cls = type_cls[type]; string tink_type = type; if (id_atom.ContainsKey(tink_id) == false) { Prm.Atom tink_atom = Prm.Atom.FromData (Id: tink_id , Class: tink_cls , Type: tink_type , Description: desc , AtomicNumber: null , Mass: psfatom.Mass , Valence: valnc ); id_atom.Add(tink_id, tink_atom); } else { Prm.Atom tink_atom = id_atom[tink_id]; tink_id = tink_atom.Id; tink_cls = tink_atom.Class; HDebug.Exception(tink_atom.Type == tink_type); HDebug.Exception(tink_atom.Description == desc); HDebug.Exception(Math.Abs(tink_atom.Mass - psfatom.Mass) < 0.001); HDebug.Exception(tink_atom.Valence == valnc); } if (cls_vdw.ContainsKey(tink_cls) == false) { Prm.Vdw tink_vdw = Prm.Vdw.FromData (Class: tink_cls , Rmin2: prmnbnd.Rmin2 , Epsilon: prmnbnd.epsilon ); cls_vdw.Add(tink_cls, tink_vdw); } else { Prm.Vdw tink_vdw = cls_vdw[tink_cls]; HDebug.Exception(tink_vdw.Rmin2 == prmnbnd.Rmin2); HDebug.Exception(tink_vdw.Epsilon == prmnbnd.epsilon); } HDebug.AssertIf(double.IsNaN(prmnbnd.Rmin2_14) == true, double.IsNaN(prmnbnd.eps_14) == true); HDebug.AssertIf(double.IsNaN(prmnbnd.Rmin2_14) == false, double.IsNaN(prmnbnd.eps_14) == false); if (double.IsNaN(prmnbnd.Rmin2_14) == false && double.IsNaN(prmnbnd.eps_14) == false) { if (cls_vdw14.ContainsKey(tink_cls) == false) { Prm.Vdw14 tink_vdw14 = Prm.Vdw14.FromData (Class: tink_cls , Rmin2_14: prmnbnd.Rmin2_14 , Eps_14: prmnbnd.eps_14 ); cls_vdw14.Add(tink_cls, tink_vdw14); } else { Prm.Vdw14 tink_vdw14 = cls_vdw14[tink_cls]; HDebug.Exception(tink_vdw14.Rmin2_14 == prmnbnd.Rmin2_14); HDebug.Exception(tink_vdw14.Eps_14 == prmnbnd.eps_14); } } else { HDebug.Exception(cls_vdw14.ContainsKey(tink_cls) == false); } if (id_charge.ContainsKey(tink_id) == false) { Prm.Charge tink_charge = Prm.Charge.FromData (Id: tink_id , pch: psfatom.Charge ); id_charge.Add(tink_id, tink_charge); } else { Prm.Charge tink_charge = id_charge[tink_id]; HDebug.Exception(tink_charge.pch == psfatom.Charge); } if (id_biotype.ContainsKey(tink_id) == false) { Prm.Biotype tink_biotype = Prm.Biotype.FromData (BioId: id_biotype.Count + 1 , Name: name , Resn: string.Format("{0}({1})-{2}", name, type, resn) , Id: tink_id ); id_biotype.Add(tink_id, tink_biotype); } else { Prm.Biotype tink_biotype = id_biotype[tink_id]; HDebug.Exception(tink_biotype.Name == name); HDebug.Exception(tink_biotype.Resn == string.Format("{0}({1})-{2}", name, type, resn)); HDebug.Exception(tink_biotype.Id == tink_id); } var xyzid = uatom.AtomId; var xyzinfo = new Tuple <string, Vector, int, List <int> > (tink_type // AtomType , uatom.Coord // X, Y, Z , tink_id // AtomId , new List <int>() ); xyzid_info.Add(xyzid, xyzinfo); } Dictionary <Tuple <int, int>, Prm.Bond> cls_bond = new Dictionary <Tuple <int, int>, Prm.Bond>(); foreach (var ubond in univ.bonds) { var key0 = UnivAtomToTinkKey(ubond.atoms[0]); string type0 = key0.Item2; int cls0 = type_cls[type0]; var key1 = UnivAtomToTinkKey(ubond.atoms[1]); string type1 = key1.Item2; int cls1 = type_cls[type1]; Tuple <int, int> cls01; if (cls0 < cls1) { cls01 = new Tuple <int, int>(cls0, cls1); } else { cls01 = new Tuple <int, int>(cls1, cls0); } if (cls_bond.ContainsKey(cls01) == false) { Prm.Bond tink_bond01 = Prm.Bond.FromData (Class1: cls01.Item1 , Class2: cls01.Item2 , Kb: ubond.Kb , b0: ubond.b0 ); cls_bond.Add(cls01, tink_bond01); } else { Prm.Bond tink_bond01 = cls_bond[cls01]; HDebug.Exception(Math.Abs(tink_bond01.Kb - ubond.Kb) < 0.01); HDebug.Exception(tink_bond01.b0 == ubond.b0); } int xyzid0 = ubond.atoms[0].AtomId; int xyzid1 = ubond.atoms[1].AtomId; xyzid_info[xyzid0].Item4.Add(xyzid1); xyzid_info[xyzid1].Item4.Add(xyzid0); } Dictionary <Tuple <int, int, int>, Prm.Angle> cls_angle = new Dictionary <Tuple <int, int, int>, Prm.Angle>(); Dictionary <Tuple <int, int, int>, Prm.Ureybrad> cls_ureybrad = new Dictionary <Tuple <int, int, int>, Prm.Ureybrad>(); foreach (var uangle in univ.angles) { var key0 = UnivAtomToTinkKey(uangle.atoms[0]); string type0 = key0.Item2; int cls0 = type_cls[type0]; var key1 = UnivAtomToTinkKey(uangle.atoms[1]); string type1 = key1.Item2; int cls1 = type_cls[type1]; var key2 = UnivAtomToTinkKey(uangle.atoms[2]); string type2 = key2.Item2; int cls2 = type_cls[type2]; Tuple <int, int, int> cls012; if (cls0 < cls2) { cls012 = new Tuple <int, int, int>(cls0, cls1, cls2); } else { cls012 = new Tuple <int, int, int>(cls2, cls1, cls0); } double uangle_Theta0 = 180.0 * uangle.Theta0 / Math.PI; if (cls_angle.ContainsKey(cls012) == false) { Prm.Angle tink_angle012 = Prm.Angle.FromData (Class1: cls012.Item1 , Class2: cls012.Item2 , Class3: cls012.Item3 , Ktheta: uangle.Ktheta , Theta0: uangle_Theta0 ); cls_angle.Add(cls012, tink_angle012); HDebug.Exception(cls_ureybrad.ContainsKey(cls012) == false); if (uangle.Kub != 0) { Prm.Ureybrad tink_ureybrad = Prm.Ureybrad.FromData (Class1: cls012.Item1 , Class2: cls012.Item2 , Class3: cls012.Item3 , Kub: uangle.Kub , S0: uangle.S0 ); cls_ureybrad.Add(cls012, tink_ureybrad); } } else { Prm.Angle tink_angle012 = cls_angle[cls012]; HDebug.Exception(tink_angle012.Ktheta == uangle.Ktheta); HDebug.Exception(Math.Abs(tink_angle012.Theta0 - uangle_Theta0) < 0.01); if (uangle.Kub != 0) { Prm.Ureybrad tink_ureybrad = cls_ureybrad[cls012]; HDebug.Exception(tink_ureybrad.Kub == uangle.Kub); HDebug.Exception(tink_ureybrad.S0 == uangle.S0); } else { HDebug.Exception(cls_ureybrad.ContainsKey(cls012) == false); } } } Dictionary <Tuple <int, int, int, int>, Prm.Improper> cls_improper = new Dictionary <Tuple <int, int, int, int>, Prm.Improper>(); foreach (var improper in univ.impropers) { var key0 = UnivAtomToTinkKey(improper.atoms[0]); string type0 = key0.Item2; int cls0 = type_cls[type0]; var key1 = UnivAtomToTinkKey(improper.atoms[1]); string type1 = key1.Item2; int cls1 = type_cls[type1]; var key2 = UnivAtomToTinkKey(improper.atoms[2]); string type2 = key2.Item2; int cls2 = type_cls[type2]; var key3 = UnivAtomToTinkKey(improper.atoms[3]); string type3 = key3.Item2; int cls3 = type_cls[type3]; Tuple <int, int, int, int> cls0123 = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); //if(cls0 < cls2) cls0123 = new Tuple<int, int, int, int>(cls0, cls1, cls2, cls3); //else cls0123 = new Tuple<int, int, int, int>(cls3, cls2, cls1, cls0); double improper_psi0 = 180.0 * improper.psi0 / Math.PI; if (cls_improper.ContainsKey(cls0123) == false) { Prm.Improper tink_improper = Prm.Improper.FromData (Class1: cls0 , Class2: cls1 , Class3: cls2 , Class4: cls3 , Kpsi: improper.Kpsi , psi0: improper_psi0 ); cls_improper.Add(cls0123, tink_improper); } else { Prm.Improper tink_improper = cls_improper[cls0123]; HDebug.Exception(tink_improper.Kpsi == improper.Kpsi); HDebug.Exception(Math.Abs(tink_improper.psi0 - improper_psi0) < 0.01); } } Dictionary <Tuple <int, int, int, int>, List <Universe.Dihedral> > cls_dihedrals = new Dictionary <Tuple <int, int, int, int>, List <Universe.Dihedral> >(); foreach (var atom in univ.atoms) { var inter1234s = atom.ListInterAtom1234(); foreach (var inter1234 in inter1234s) { HDebug.Assert(inter1234.Count == 4); var key0 = UnivAtomToTinkKey(inter1234[0]); string type0 = key0.Item2; int cls0 = type_cls[type0]; var key1 = UnivAtomToTinkKey(inter1234[1]); string type1 = key1.Item2; int cls1 = type_cls[type1]; var key2 = UnivAtomToTinkKey(inter1234[2]); string type2 = key2.Item2; int cls2 = type_cls[type2]; var key3 = UnivAtomToTinkKey(inter1234[3]); string type3 = key3.Item2; int cls3 = type_cls[type3]; Tuple <int, int, int, int> cls0123 = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); Tuple <int, int, int, int> cls3210 = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); if (cls_dihedrals.ContainsKey(cls0123) == false) { cls_dihedrals.Add(cls0123, new List <Universe.Dihedral>()); } if (cls_dihedrals.ContainsKey(cls3210) == false) { cls_dihedrals.Add(cls3210, new List <Universe.Dihedral>()); } } } foreach (var dihedral in univ.dihedrals) { var key0 = UnivAtomToTinkKey(dihedral.atoms[0]); string type0 = key0.Item2; int cls0 = type_cls[type0]; var key1 = UnivAtomToTinkKey(dihedral.atoms[1]); string type1 = key1.Item2; int cls1 = type_cls[type1]; var key2 = UnivAtomToTinkKey(dihedral.atoms[2]); string type2 = key2.Item2; int cls2 = type_cls[type2]; var key3 = UnivAtomToTinkKey(dihedral.atoms[3]); string type3 = key3.Item2; int cls3 = type_cls[type3]; Tuple <int, int, int, int> cls0123 = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); Tuple <int, int, int, int> cls3210 = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); cls_dihedrals[cls0123].Add(dihedral); cls_dihedrals[cls3210].Add(dihedral); } Dictionary <Tuple <int, int, int, int>, Prm.Torsion> cls_torsion = new Dictionary <Tuple <int, int, int, int>, Prm.Torsion>(); foreach (var cls0123 in cls_dihedrals.Keys) { Universe.Dihedral[] dihedrals = cls_dihedrals[cls0123].ToArray(); Dictionary <Tuple <double, double>, List <double> > delta_n_Kchis = new Dictionary <Tuple <double, double>, List <double> >(); foreach (var dihedral in dihedrals) { double dihedral_delta = 180.0 * dihedral.delta / Math.PI; var delta_n = new Tuple <double, double>(dihedral_delta, dihedral.n); if (delta_n_Kchis.ContainsKey(delta_n) == false) { delta_n_Kchis.Add(delta_n, new List <double>()); } delta_n_Kchis[delta_n].Add(dihedral.Kchi); } Tuple <double, double>[] lst_delta_n = delta_n_Kchis.Keys.ToArray(); HDebug.Exception(lst_delta_n.Length <= 3); double?Kchi0 = null; if (lst_delta_n.Length >= 1) { Kchi0 = delta_n_Kchis[lst_delta_n[0]].Mean(); } double?delta0 = null; if (lst_delta_n.Length >= 1) { delta0 = lst_delta_n[0].Item1; } double?n0 = null; if (lst_delta_n.Length >= 1) { n0 = lst_delta_n[0].Item2; } double?Kchi1 = null; if (lst_delta_n.Length >= 2) { Kchi1 = delta_n_Kchis[lst_delta_n[1]].Mean(); } double?delta1 = null; if (lst_delta_n.Length >= 2) { delta1 = lst_delta_n[1].Item1; } double?n1 = null; if (lst_delta_n.Length >= 2) { n1 = lst_delta_n[1].Item2; } double?Kchi2 = null; if (lst_delta_n.Length >= 3) { Kchi2 = delta_n_Kchis[lst_delta_n[2]].Mean(); } double?delta2 = null; if (lst_delta_n.Length >= 3) { delta2 = lst_delta_n[2].Item1; } double?n2 = null; if (lst_delta_n.Length >= 3) { n2 = lst_delta_n[2].Item2; } Prm.Torsion tink_torsion = Prm.Torsion.FromData (Class1: cls0123.Item1 , Class2: cls0123.Item2 , Class3: cls0123.Item3 , Class4: cls0123.Item4 , Kchi0: Kchi0 , delta0: delta0 , n0: n0 , Kchi1: Kchi1 , delta1: delta1 , n1: n1 , Kchi2: Kchi2 , delta2: delta2 , n2: n2 ); cls_torsion.Add(cls0123, tink_torsion); } List <string> prmlines; #region build lines { List <string> lines = new List <string>(); lines.Add(""); lines.Add(" ##############################"); lines.Add(" ## ##"); lines.Add(" ## Force Field Definition ##"); lines.Add(" ## ##"); lines.Add(" ##############################"); lines.Add(""); lines.Add(""); lines.Add("forcefield CHARMM22"); lines.Add(""); lines.Add("vdwtype LENNARD-JONES"); lines.Add("radiusrule ARITHMETIC"); lines.Add("radiustype R-MIN"); lines.Add("radiussize RADIUS"); lines.Add("epsilonrule GEOMETRIC"); lines.Add("vdw-14-scale 1.0"); lines.Add("chg-14-scale 1.0"); lines.Add("electric 332.0716"); lines.Add("dielectric 1.0"); lines.Add(""); lines.Add(""); lines.Add(" #############################"); lines.Add(" ## ##"); lines.Add(" ## Atom Type Definitions ##"); lines.Add(" ## ##"); lines.Add(" #############################"); lines.Add(""); lines.Add(""); foreach (int id in id_atom.Keys.ToArray().HSort()) { lines.Add(id_atom[id].line); } lines.Add(""); lines.Add(""); lines.Add(" ################################"); lines.Add(" ## ##"); lines.Add(" ## Van der Waals Parameters ##"); lines.Add(" ## ##"); lines.Add(" ################################"); lines.Add(""); lines.Add(""); foreach (int cls in cls_vdw.Keys.ToArray().HSort()) { lines.Add(cls_vdw[cls].line); } lines.Add(""); lines.Add(""); lines.Add(" ####################################"); lines.Add(" ## ##"); lines.Add(" ## 1-4 Van der Waals Parameters ##"); lines.Add(" ## ##"); lines.Add(" ####################################"); lines.Add(""); lines.Add(""); foreach (int cls in cls_vdw14.Keys.ToArray().HSort()) { lines.Add(cls_vdw14[cls].line); } lines.Add(""); lines.Add(""); lines.Add(" ##################################"); lines.Add(" ## ##"); lines.Add(" ## Bond Stretching Parameters ##"); lines.Add(" ## ##"); lines.Add(" ##################################"); lines.Add(""); lines.Add(""); foreach (var bond in cls_bond) { lines.Add(bond.Value.line); } lines.Add(""); lines.Add(""); lines.Add(" ################################"); lines.Add(" ## ##"); lines.Add(" ## Angle Bending Parameters ##"); lines.Add(" ## ##"); lines.Add(" ################################"); lines.Add(""); lines.Add(""); foreach (var angle in cls_angle) { lines.Add(angle.Value.line); } lines.Add(""); lines.Add(""); lines.Add(" ###############################"); lines.Add(" ## ##"); lines.Add(" ## Urey-Bradley Parameters ##"); lines.Add(" ## ##"); lines.Add(" ###############################"); lines.Add(""); lines.Add(""); foreach (var ureybrad in cls_ureybrad) { lines.Add(ureybrad.Value.line); } lines.Add(""); lines.Add(""); lines.Add(" ####################################"); lines.Add(" ## ##"); lines.Add(" ## Improper Dihedral Parameters ##"); lines.Add(" ## ##"); lines.Add(" ####################################"); lines.Add(""); lines.Add(""); foreach (var improper in cls_improper) { lines.Add(improper.Value.line); } lines.Add(""); lines.Add(""); lines.Add(" ############################"); lines.Add(" ## ##"); lines.Add(" ## Torsional Parameters ##"); lines.Add(" ## ##"); lines.Add(" ############################"); lines.Add(""); lines.Add(""); foreach (var torsion in cls_torsion) { lines.Add(torsion.Value.line); } lines.Add(""); lines.Add(""); lines.Add(" ########################################"); lines.Add(" ## ##"); lines.Add(" ## Atomic Partial Charge Parameters ##"); lines.Add(" ## ##"); lines.Add(" ########################################"); lines.Add(""); lines.Add(""); foreach (int id in id_charge.Keys.ToArray().HSort()) { lines.Add(id_charge[id].line); } lines.Add(""); lines.Add(""); lines.Add(" ########################################"); lines.Add(" ## ##"); lines.Add(" ## Biopolymer Atom Type Conversions ##"); lines.Add(" ## ##"); lines.Add(" ########################################"); lines.Add(""); lines.Add(""); foreach (int id in id_biotype.Keys.ToArray().HSort()) { lines.Add(id_biotype[id].line); } lines.Add(""); prmlines = lines; } #endregion Dictionary <string, string> atomtype_natomtype; { atomtype_natomtype = xyzid_info.Values.ToArray().HListItem1().HToHashSet().HToDictionaryAsKey(""); foreach (string atomtype in atomtype_natomtype.Keys.ToArray()) { string natomtype = atomtype; if (natomtype.Length > 3) { Dictionary <char, char> map = new Dictionary <char, char> { { '0', '1' }, { '1', '2' }, { '2', '3' }, { '3', '4' }, { '4', '5' }, { '5', '6' }, { '6', '7' }, { '7', '8' }, { '8', '9' }, { '9', 'A' }, { 'A', 'B' }, { 'B', 'C' }, { 'C', 'D' }, { 'D', 'E' }, { 'E', 'F' }, { 'F', 'G' }, { 'G', 'H' }, { 'H', 'I' }, { 'I', 'J' }, { 'J', 'K' }, { 'K', 'L' }, { 'L', 'M' }, { 'M', 'N' }, { 'N', 'O' }, { 'O', 'P' }, { 'P', 'Q' }, { 'Q', 'R' }, { 'R', 'S' }, { 'S', 'T' }, { 'T', 'U' }, { 'U', 'V' }, { 'V', 'W' }, { 'W', 'X' }, { 'X', 'Y' }, { 'Y', 'Z' }, { 'Z', '0' }, }; string temptype = atomtype.Substring(0, 3); foreach (var key in map.Keys.ToArray()) { if (map[key] == temptype[2]) { map[key] = ' '; // marking ending point as ' ' } } while (true) { if (temptype[2] == ' ') { HDebug.Exception(); } if ((atomtype_natomtype.ContainsKey(temptype) == false) && (atomtype_natomtype.ContainsValue(temptype) == false)) { natomtype = temptype; break; } temptype = temptype.Substring(0, 2) + map[temptype[2]]; } } atomtype_natomtype[atomtype] = natomtype; } } List <string> xyzlines; { xyzlines = new List <string>(); xyzlines.Add(Xyz.Header.FromData(xyzid_info.Count, "", "", "").line); foreach (var xyzid in xyzid_info.Keys.ToArray().HSort()) { int id = xyzid; string atomtype = xyzid_info[xyzid].Item1; atomtype = atomtype_natomtype[atomtype]; double x = xyzid_info[xyzid].Item2[0]; double y = xyzid_info[xyzid].Item2[1]; double z = xyzid_info[xyzid].Item2[2]; int atomid = xyzid_info[xyzid].Item3; int[] bondedids = xyzid_info[xyzid].Item4.ToArray(); xyzlines.Add(Xyz.Atom.FromData(id, atomtype, x, y, z, atomid, bondedids).line); } } { for (int i = 0; i < prmlines.Count; i++) { if (prmlines[i].StartsWith("atom ")) { var atom = Prm.Atom.FromLine(prmlines[i]); var natom = Prm.Atom.FromData (Id: atom.Id , Class: atom.Class , Type: atomtype_natomtype[atom.Type] , Description: atom.Description , AtomicNumber: atom.AtomicNumber , Mass: atom.Mass , Valence: atom.Valence ); prmlines[i] = natom.line; } } } Prm tink_prm = Prm.FromLines(prmlines); Xyz tink_xyz = Xyz.FromLines(xyzlines); return(new Tuple <Xyz, Prm>(tink_xyz, tink_prm)); }
public static void GetPwEnrgFrcSprNbnd(bool vdW, bool elec , Vector coordi, double ri0, double qi, double ei , Vector coordj, double rj0, double qj, double ej , double D // = 80 // dielectric constant , out double Eij , out double Fij , out double Kij ) { /// http://www.ks.uiuc.edu/Training/Tutorials/science/forcefield-tutorial/forcefield-html/node5.html /// http://www.charmmtutorial.org/index.php/The_Energy_Function /// /// NONBONDED /// /// charmm : V_nbnd = epsilon_ij ( (r0ij / rij)^12 - 2 * (r0ij / rij)^6 ) + (qi*qj)/(epsilon*rij) /// = epsilon_ij ( r0ij^12 * rij^-12 - 2 * r0ij^6 * rij^-6) + (qi*qj/epsilon) * rij^-1 /// frc_nbnd = epsilon_ij ( -12 * r0ij^12 * rij^-13 - (-6*2) * r0ij^6 * rij^-7) + (-1)*(qi*qj/epsilon) * rij^-2 /// spr_nbnd = epsilon_ij ( (-12*-13) * r0ij^12 * rij^-14 -(-6*-7*2) * r0ij^6 * rij^-8) + (-1*-2)*(qi*qj/epsilon) * rij^-3 /// = epsilon_ij ( 156 * r0ij^12 * rij^-14 + 84 * r0ij^6 * rij^-8) + 2*(qi*qj/epsilon) * rij^-3 /// /// V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6] /// /// epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j) /// Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j /// /// atom ignored epsilon Rmin/2 ignored eps,1-4 Rmin/2,1-4 /// /// V(electrostatic) : V(i,j) = (qi*qj)/(epsilon*rij) /// = 332*qi*qj/r_ij/D /// Where D is dielectric constant, for proteins. D is normally 80. (see equation (13) in the following pdf file). /// http://pharmacy.ucsd.edu/labs/gilson/ce_www1a.pdf /// epsilon = D/332 double rij2 = (coordi - coordj).Dist2; double rij = Math.Sqrt(rij2); double r0ij = (ri0 + rj0); double qij = qi * qj; double eij = Math.Sqrt(ei * ej); double eps = D / 332; Eij = 0; Fij = 0; Kij = 0; if (vdW) { double Evdw = eij * Math.Pow(r0ij / rij, 12) - eij * (2) * Math.Pow(r0ij / rij, 6); Eij += Evdw; double Fvdw = eij * (-12) * Math.Pow(r0ij / rij, 12) / rij - eij * (-6 * 2) * Math.Pow(r0ij / rij, 6) / rij; Fij += Fvdw; double Kvdw = eij * (-12 * -13) * Math.Pow(r0ij / rij, 12) / rij2 - eij * (-6 * -7 * 2) * Math.Pow(r0ij / rij, 6) / rij2; Kij += Kvdw; } if (elec) { double Eelec = (qij / eps) / (rij); Eij += Eelec; double Felec = (-1) * (qij / eps) / (rij * rij); Fij += Felec; double Kelec = (-2 * -1) * (qij / eps) / (rij * rij2); Kij += Kelec; HDebug.AssertIf(qij < 0, Felec > 0); /// attractive, positive pw-force HDebug.AssertIf(qij > 0, Felec < 0); /// repulsive , negative pw-force } if (HDebug.IsDebuggerAttached) { var KijFij = Hess.HessSpr.GetKijFijNbnd(vdW, elec , coordi, ri0, qi, ei , coordj, rj0, qj, ej , D ); HDebug.AssertTolerance(0.00000001, Kij - KijFij.Kij); HDebug.AssertTolerance(0.00000001, Fij - KijFij.Fij); } }