public static void Align(IList <Vector> C1 , ref List <Vector> C2 , HPack <List <Vector> > optMoveC2 = null , HPack <Trans3> outTrans = null , HPack <double> optRmsd = null ) { Trans3 trans = GetTrans(C1, C2); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); if (optMoveC2 != null) { optMoveC2.value = new List <Vector>(nC2.Length); for (int i = 0; i < nC2.Length; i++) { optMoveC2.value[i] = nC2[i] - C2[i]; } } if (optRmsd != null) { optRmsd.value = 0; for (int i = 0; i < nC2.Length; i++) { optRmsd.value += (nC2[i] - C1[i]).Dist2; } optRmsd.value /= nC2.Length; } C2 = new List <Vector>(nC2); if (outTrans != null) { outTrans.value = trans.Clone(); } }
public Pdb GetTransformed(Trans3 trans) { Element[] nelements = new Element[elements.Length]; for (int i = 0; i < elements.Length; i++) { if (typeof(Atom).IsInstanceOfType(elements[i])) { Atom atom = (Atom)elements[i]; Vector pt = atom.coord; pt = trans.DoTransform(pt); atom = Atom.FromString(atom.GetUpdatedLine(pt)); nelements[i] = atom; } else if (typeof(Hetatm).IsInstanceOfType(elements[i])) { Hetatm hetatm = (Hetatm)elements[i]; Vector pt = hetatm.coord; pt = trans.DoTransform(pt); hetatm = Hetatm.FromString(hetatm.GetUpdatedLine(pt)); nelements[i] = hetatm; } else { nelements[i] = elements[i].UpdateElement(); } } return(new Pdb(nelements)); }
public static void Align(IList <Vector> C1 , IList <Anisou> anisou1 , ref IList <Vector> C2 , ref IList <Anisou> anisou2 , HPack <Trans3> outTrans = null , HPack <double> optEnergy = null ) { Trans3 trans = GetTrans(C1, anisou1, C2, anisou2, optEnergy: optEnergy); C2 = new List <Vector>(C2); anisou2 = new List <Anisou>(anisou2); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); for (int i = 0; i < C2.Count; i++) { Vector p2i = C2[i]; Anisou a2i = anisou2[i]; Vector np2i = trans.DoTransform(p2i); Anisou na2i = a2i.Clone(); na2i.eigvecs[0] = (trans.DoTransform(p2i + a2i.eigvecs[0]) - np2i).UnitVector(); na2i.eigvecs[1] = (trans.DoTransform(p2i + a2i.eigvecs[1]) - np2i).UnitVector(); na2i.eigvecs[2] = (trans.DoTransform(p2i + a2i.eigvecs[2]) - np2i).UnitVector(); C2[i] = np2i; anisou2[i] = na2i; } if (outTrans != null) { outTrans.value = trans; } }
public static void Align(IList <Vector> C1 , IList <Anisou> anisou1 , ref List <Vector> C2 , HPack <List <Vector> > optMoveC2 = null , HPack <Trans3> outTrans = null , HPack <double> optEnergy = null ) { Trans3 trans = GetTrans(C1, anisou1, C2, optEnergy: optEnergy); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); if (optMoveC2 != null) { optMoveC2.value = new List <Vector>(nC2.Length); for (int i = 0; i < nC2.Length; i++) { optMoveC2.value.Add(nC2[i] - C2[i]); } } if (outTrans != null) { outTrans.value = trans; } C2 = new List <Vector>(nC2); }
public double GetRMSD(IList <int> atomidxs, IList <Vector> atomcoords) { List <Vector> coords = new List <Vector>(); foreach (int atomidx in atomidxs) { coords.Add(atoms[atomidx].Coord.Clone()); } Trans3 trans = ICP3.OptimalTransform(coords, atomcoords); List <double> SDs = new List <double>(); for (int i = 0; i < coords.Count; i++) { Vector moved = trans.DoTransform(coords[i]); Vector to = atomcoords[i]; double SD = (moved - to).Dist2; SDs.Add(SD); } double RMSD = Math.Sqrt(SDs.Average()); return(RMSD); }
public static void GetEnergies(AlignData data1, IList <Vector> coords2 , out double pot_rmsd, out double pot_enrg, out double pot_enrg_full, out double pot_enrg_anisou , Pdb pdb2 = null , string pdb2outpath = null ) { Anisou[] anisous1;// = data1.GetAnisous(); double[] bfactor1; { List <Mode> modes = new List <Mode>(data1.GetModes()); for (int i = 0; i < 6; i++) { modes.RemoveAt(0); } bfactor1 = HBioinfo.GetBFactor(modes.ToArray(), data1.masses); HDebug.Assert(data1.size == bfactor1.Length); anisous1 = Anisou.FromBFactor(bfactor1, scale: 10000 * 1000); } //Trans3 trans = MinAnisou.GetTrans(data1.coords, anisous1, coords2); Trans3 trans = GetTrans(data1.coords, bfactor1, coords2); List <Vector> coords2trans = new List <Vector>(trans.GetTransformed(coords2)); if (pdb2 != null && pdb2outpath != null) { data1.pdb.ToFile(pdb2outpath, coords2trans, anisous: anisous1.GetUs()); } pot_rmsd = data1.GetRmsdFrom(coords2trans); pot_enrg = data1.GetEnergyFromDiag(coords2trans); pot_enrg_full = data1.GetEnergyFromFull(coords2trans); pot_enrg_anisou = data1.GetEnergyFromAnisou(coords2trans); }
public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, HPack <double> optEnergy = null) { int size = C1.Count; HDebug.Assert(size == C1.Count, size == C2.Count); Vector[] C1s = C1.ToArray().Clone(3); Vector[] C2s = C2.ToArray().Clone(3); double[] W1s = new double[size * 3]; double[] enrgs = new double[size * 3]; for (int i = 0; i < size; i++) { HDebug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i * 3 + 0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0]; HDebug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i * 3 + 1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1]; HDebug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i * 3 + 2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2]; enrgs[i * 3 + 0] = enrgs[i * 3 + 1] = enrgs[i * 3 + 2] = double.NaN; } //Trans3 trans = ICP3.OptimalTransform(C2, C1); Trans3 trans = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s); int iter = 0; int iter_max = 1000; //double enrg = double.NaN; while (iter < iter_max) { iter++; Vector[] C2sUpdated = trans.GetTransformed(C2s); //for(int i=0; i<size; i++) System.Threading.Tasks.Parallel.For(0, size, delegate(int i) { for (int j = 0; j < 3; j++) { Vector planeNormal = anisou1[i].axes[j]; Vector planeBase = C1[i]; Vector query = C2sUpdated[i * 3 + j]; Vector closest = query - LinAlg.DotProd(planeNormal, query - planeBase) * planeNormal; HDebug.AssertTolerance(0.00001, LinAlg.DotProd(closest - planeBase, planeNormal)); C1s[i * 3 + j] = closest; enrgs[i * 3 + j] = W1s[i * 3 + j] * (query - closest).Dist2; } }); Trans3 dtrans = ICP3.OptimalTransformWeighted(C2sUpdated, C1s, W1s); trans = Trans3.AppendTrans(trans, dtrans); double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax(); if (max_dtrans_matrix < 0.0000001) { break; } } if (optEnergy != null) { optEnergy.value = enrgs.Sum() / size; } return(trans); }
public static void Align(IList <Vector> C1, IList <double> bfactor, ref List <Vector> C2) { Trans3 trans = GetTrans(C1, bfactor, C2); for (int i = 0; i < C2.Count; i++) { C2[i] = trans.DoTransform(C2[i]); } }
public static void Align(List <Pdb.Atom> atoms1, ref List <Pdb.Atom> atoms2) { PdbStatic.SelectCommonAtoms(ref atoms1, ref atoms2); List <Vector> coords1 = atoms1.ListCoord(); List <Vector> coords2 = atoms2.ListCoord(); Trans3 trans = GetTrans(coords1, coords2); List <Vector> coords2a = new List <Vector>(trans.GetTransformed(coords2)); atoms2 = atoms2.CloneByUpdateCoord(coords2a); }
public static Mode[] GetTransposed(this IList <Mode> modes, Trans3 trans) { if ((trans.ds != 1) || (trans.dt.Dist2 != 0)) // if trans is rot+sca+mov, { trans = new Trans3(new double[3], 1, trans.dr); // then redetermine trans as rot only } Mode[] nmodes = new Mode[modes.Count]; for (int i = 0; i < modes.Count; i++) { nmodes[i] = modes[i].GetTransposed(trans); } return(nmodes); }
public static void Align(IList <Vector> C1 , ref List <Vector> C2 , IList <double> weight , HPack <Trans3> outTrans = null ) { Trans3 trans = GetTrans(C1, C2, weight); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); C2 = new List <Vector>(nC2); if (outTrans != null) { outTrans.value = trans.Clone(); } }
public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null) { HDebug.Assert(C1.Count == C2.Count); int size = C1.Count; if (optIter != null) { optIter.value = 0; } Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation); Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1); if (optListWeightSum != null) { optListWeightSum.value = new List <double>(); } while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001) { if (optIter != null) { optIter.value++; } Vector[] C2trans = trans1.GetTransformed(C2).ToArray(); double[] weight = new double[size]; double[] dist2s = new double[size]; for (int i = 0; i < size; i++) { double dist2 = (C1[i] - C2trans[i]).Dist2; dist2 = HMath.Between(0.001, dist2, double.PositiveInfinity); weight[i] = 1 / dist2; dist2s[i] = dist2; } if (optListWeightSum != null) { optListWeightSum.value.Add(weight.Sum()); } trans0 = trans1; trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight); } return(trans1); }
public static void GetEnergies(AlignData data1, IList <Vector> coords2 , out double geo_rmsd, out double geo_enrg, out double geo_enrg_full, out double geo_enrg_anisou , Pdb pdb2, string pdb2outpath ) { Trans3 trans = GetTrans(data1.coords, coords2); List <Vector> coords2trans = new List <Vector>(trans.GetTransformed(coords2).ToArray()); if (pdb2 != null && pdb2outpath != null) { pdb2.ToFile(pdb2outpath, coords2); } geo_rmsd = data1.GetRmsdFrom(coords2trans); geo_enrg = data1.GetEnergyFromDiag(coords2trans); geo_enrg_full = data1.GetEnergyFromFull(coords2trans); geo_enrg_anisou = data1.GetEnergyFromAnisou(coords2trans); }
public static void Align(List <Vector> coords1 , ref List <Vector> coords2 , int maxiteration = int.MaxValue , HPack <List <Trans3[]> > outTrajTrans = null ) { List <Vector>[] ensemble = new List <Vector>[] { coords1.HClone(), coords2.HClone() }; Align(ref ensemble, maxiteration: maxiteration, outTrajTrans: outTrajTrans); Trans3 trans = MinRMSD.GetTrans(coords1, ensemble[0]); Vector[] ensemble0 = trans.GetTransformed(ensemble[0]).ToArray(); Vector[] ensemble1 = trans.GetTransformed(ensemble[1]).ToArray(); coords2 = new List <Vector>(ensemble1); }
public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2) { HDebug.Assert(C1.Count == C2.Count); int size = C1.Count; double[] pakdens1 = new double[size]; for (int i = 0; i < size - 1; i++) { for (int j = i + 1; j < size; j++) { double dist2 = (C1[i] - C1[j]).Dist2; pakdens1[i] += 1 / dist2; pakdens1[j] += 1 / dist2; } } Trans3 trans = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, pakdens1); return(trans); }
//public static Trans3 GetTrans(IList<Vector> C1, Matrix[] anisou1, IList<Vector> C2) //{ // int size = C1.Count; // Tuple<Vector[], double[]>[] eigs1 = new Tuple<Vector[], double[]>[size]; // { // for(int i=0; i<size; i++) // { // Vector[] eigvec; // double[] eigval; // Debug.Verify(NumericSolver.Eig(anisou1[i], out eigvec, out eigval)); // { // normalize eigval and eigvec // double l; // l = eigvec[0].Dist; eigvec[0] /= l; eigval[0] *= (l*l); eigval[0] = Math.Pow(eigval[0], 2); Debug.Assert(eigval[0] >= 0); // l = eigvec[1].Dist; eigvec[1] /= l; eigval[1] *= (l*l); eigval[1] = Math.Pow(eigval[1], 2); Debug.Assert(eigval[1] >= 0); // l = eigvec[2].Dist; eigvec[2] /= l; eigval[2] *= (l*l); eigval[2] = Math.Pow(eigval[2], 2); Debug.Assert(eigval[2] >= 0); // } // { // eigval[0] = 1 / eigval[0]; // eigval[1] = 1 / eigval[1]; // eigval[2] = 1 / eigval[2]; // } // eigs1[i] = new Tuple<Vector[], double[]>(eigvec, eigval); // } // } // return GetTrans(C1, eigs1, C2); //} public static void GetEnergies(AlignData data1, IList <Vector> coords2 , out double pot_rmsd, out double pot_enrg, out double pot_enrg_full, out double pot_enrg_anisou , Pdb pdb2 = null , string pdb2outpath = null ) { Anisou[] anisous1 = data1.GetAnisous(); Trans3 trans = GetTrans(data1.coords, anisous1, coords2); List <Vector> coords2trans = new List <Vector>(trans.GetTransformed(coords2)); if (pdb2 != null && pdb2outpath != null) { pdb2.ToFile(pdb2outpath, coords2trans); } //data1.pdb.ToFile(pdb2outpath, coords2trans, anisous: anisous1.GetUs()); pot_rmsd = data1.GetRmsdFrom(coords2trans); pot_enrg = data1.GetEnergyFromDiag(coords2trans); pot_enrg_full = data1.GetEnergyFromFull(coords2trans); pot_enrg_anisou = data1.GetEnergyFromAnisou(coords2trans); }
public static Trans3 GetTrans(IList <Vector> C1 , IList <Vector> C2 , IList <double> weight //, Pack<List<Vector>> C2new = null ) { if (HDebug.Selftest()) { double[] tweight = new double[weight.Count]; for (int i = 0; i < tweight.Length; i++) { tweight[i] = 0.2; } Trans3 ttrans0 = GetTrans(C1, C2, tweight); Trans3 ttrans1 = MinRMSD.GetTrans(C1, C2); HDebug.AssertTolerance(0.0001, ttrans0.ds - ttrans1.ds); HDebug.AssertTolerance(0.0001, ttrans0.dt - ttrans1.dt); HDebug.AssertTolerance(0.0001, new Vector(ttrans0.dr.ToArray()) - ttrans1.dr.ToArray()); HDebug.AssertTolerance(0.0001, (ttrans0.TransformMatrix - ttrans1.TransformMatrix)); } HDebug.Assert(C1.Count == C2.Count); HDebug.Assert(C1.Count == weight.Count); //Trans3 trans = ICP3.OptimalTransform(C2, C1); Trans3 trans = ICP3.OptimalTransformWeighted(C2, C1, weight); if (HDebug.IsDebuggerAttached) { Vector[] C2updated = trans.GetTransformed(C2).ToArray(); double RMSD0 = 0; double RMSD1 = 0; for (int i = 0; i < C1.Count; i++) { RMSD0 += (C1[i] - C2[i]).Dist2; RMSD1 += (C1[i] - C2updated[i]).Dist2; } //Debug.AssertTolerance(0.00000001, Math.Abs(RMSD1 - RMSD0)); } return(trans); }
public static Trans3 GetTrans(IList <Vector> C1 , IList <Vector> C2 // ref //, Pack<List<Vector>> C2new = null ) { HDebug.Assert(C1.Count == C2.Count); Trans3 trans = ICP3.OptimalTransform(C2, C1); if (HDebug.IsDebuggerAttached) { Vector[] C2updated = trans.GetTransformed(C2).ToArray(); double RMSD0 = 0; double RMSD1 = 0; for (int i = 0; i < C1.Count; i++) { RMSD0 += (C1[i] - C2[i]).Dist2; RMSD1 += (C1[i] - C2updated[i]).Dist2; } RMSD0 /= C1.Count; RMSD1 /= C1.Count; //HDebug.AssertTolerance(0.00000001, Math.Abs(RMSD1 - RMSD0)); } return(trans); }
public Mode GetTransposed(Trans3 trans) { /// trans(pt + mode) = R*(pt + mode) + T /// = R*pt + T + R*mode /// = (R*pt+T) + R*mode /// = trans(pt)+ R*mode Vector[] reigvec = GetEigvecsOfAtoms(); if ((trans.ds != 1) || (trans.dt.Dist2 != 0)) // if trans is rot+sca+mov, { trans = new Trans3(new double[3], 1, trans.dr); // then redetermine trans as rot only } for (int i = 0; i < reigvec.Length; i++) { reigvec[i] = trans.DoTransform(reigvec[i]); } return(new Mode { th = this.th, eigval = this.eigval, eigvec = reigvec.ToVector(), }); }
public static IEnumerable <ValueTuple <int, Pdb.Atom> > EnumAtomsInWaterBox (double maxx , double maxy , double maxz , double dist2water = 2.9 //2.8 // 2.7564; , bool randOrient = true , string opt = "water in uniform cube" ) { System.Random rand = null; if (randOrient) { rand = new System.Random(); } //List<Pdb.Atom> atoms = new List<Pdb.Atom>(); int file = 1; int serial = 1; int resSeq = 1; IEnumerable <Vector> enumer = null; switch (opt) { case "water in uniform cube": enumer = Geometry.EnumPointsInVolume_UniformCube(maxx / dist2water, maxy / dist2water, maxz / dist2water); break; case "water in uniform tetrahedron": enumer = Geometry.EnumPointsInVolume_UniformTetrahedron(maxx / dist2water, maxy / dist2water, maxz / dist2water); break; } foreach (Vector pt in enumer) { resSeq++; double x = pt[0] * dist2water; double y = pt[1] * dist2water; double z = pt[2] * dist2water; //var atom = Pdb.Atom.FromData(i+1, "H", "HOH", '1', i+1, pt[0], pt[1], pt[2]); /// ATOM 8221 OH2 TIP32 547 11.474 41.299 26.099 1.00 0.00 O /// ATOM 8222 H1 TIP32 547 12.474 41.299 26.099 0.00 0.00 H /// ATOM 8223 H2 TIP32 547 11.148 42.245 26.099 0.00 0.00 H Vector[] pthoh = new Vector[] { new double[] { 0.000000, 0.000000, 0.000000 }, new double[] { 0.000000, 0.000000, 0.957200 }, new double[] { 0.926627, 0.000000, 0.239987 }, }; if (randOrient != null) { Vector axis = new double[] { (rand.NextDouble() * 10) % 5 , (rand.NextDouble() * 10) % 5 , (rand.NextDouble() * 10) % 5 }; Trans3 trans = Trans3.FromRotate(axis.UnitVector(), rand.NextDouble() * Math.PI * 4); trans.DoTransform(pthoh); } if ((serial >= 99990) || (resSeq >= 9990)) { file++; serial = 1; resSeq = 1; } serial++; Pdb.Atom OH2 = Pdb.Atom.FromData(serial, "OH2", "HOH", '1', resSeq + 1, x + pthoh[0][0], y + pthoh[0][1], z + pthoh[0][2], element: "O"); yield return(new ValueTuple <int, Pdb.Atom>(file, OH2)); //atoms.Add(OH2); serial++; Pdb.Atom H1 = Pdb.Atom.FromData(serial, "H1", "HOH", '1', resSeq + 1, x + pthoh[1][0], y + pthoh[1][1], z + pthoh[1][2], element: "H"); yield return(new ValueTuple <int, Pdb.Atom>(file, H1)); //atoms.Add(H1 ); serial++; Pdb.Atom H2 = Pdb.Atom.FromData(serial, "H2", "HOH", '1', resSeq + 1, x + pthoh[2][0], y + pthoh[2][1], z + pthoh[2][2], element: "H"); yield return(new ValueTuple <int, Pdb.Atom>(file, H2)); //atoms.Add(H2 ); } }
public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null) { HDebug.Assert(false); HDebug.Assert(C1.Count == C2.Count); int size = C1.Count; if (optIter != null) { optIter.value = 0; } int iter = 0; Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation); Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1); if (optListWeightSum != null) { optListWeightSum.value = new List <double>(); } double maxdist = 0; for (int i = 0; i < size; i++) { Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist); } while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001) { iter++; if (optIter != null) { optIter.value++; } Vector[] C2trans = trans1.GetTransformed(C2).ToArray(); Vector dist2s = new double[size]; Vector dists = new double[size]; for (int i = 0; i < size; i++) { double dist2 = (C1[i] - C2trans[i]).Dist2; dist2 = HMath.Between(0.00001, dist2, double.PositiveInfinity); dist2s[i] = dist2; dists[i] = Math.Sqrt(dist2); } //int[] idxsort = dist2s.ToArray().IdxSorted().Reverse(); Vector weight = dists.Clone() / dists.ToArray().Max(); for (int i = 0; i < size; i++) { double w = weight[i]; //w = (w*2-1)*4; w = (w - 1) * 4; w = 1 / (1 + Math.Exp(-1 * w)); weight[i] = w; } //weight[idxsort[i]] = (i <= 6) ? 1 : 0; if (optListWeightSum != null) { optListWeightSum.value.Add(weight.Sum()); } trans0 = trans1; trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight.ToArray()); maxdist = 0; for (int i = 0; i < size; i++) { Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist); } } return(trans1); }
public static void Align(ref List <Vector>[] ensemble , int maxiteration = int.MaxValue , HPack <List <Trans3[]> > outTrajTrans = null ) { List <Vector>[] lensemble = ensemble.HClone <List <Vector> >(); int size = lensemble[0].Count; for (int i = 1; i < lensemble.Length; i++) { HDebug.Assert(size == lensemble[i].Count); } // initial alignment using RMSD Trans3[] transs = new Trans3[lensemble.Length]; transs[0] = Trans3.UnitTrans; Vector[] coords = new Vector[size]; Anisou[] anisous = new Anisou[size]; double anisou_eigvalthres = 0.00001 * 0.00001; double[] bfactors = new double[size]; { // set ensemble[0] as the initial mean structure for (int i = 0; i < size; i++) { coords[i] = lensemble[0][0].Clone(); } // set anisou as sphere (with radii as one) Anisou U0 = Anisou.FromMatrix(new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }); for (int i = 0; i < anisous.Length; i++) { anisous[i] = U0; } // set bfactor as one for (int i = 0; i < bfactors.Length; i++) { bfactors[i] = 1; } } //List<double>[] bfactorss = new List<double>[ensemble.Length]; //for(int i=0; i<bfactorss.Length; i++) // bfactorss[i] = new List<double>(bfactors); //Pdb.ToFile("ensemble.000.pdb", null, lensemble, bfactorss); System.Console.WriteLine("begin iterative alignment"); double move2 = double.PositiveInfinity; //double thres = 0.00001;// *size * lensemble.Length; double thres = 0.00001;// *size * lensemble.Length; //List<Pdb.Atom> atoms = null; //while(thres < move2) for (int iter = 0; iter < maxiteration; iter++) { transs = new Trans3[ensemble.Length]; move2 = Align(lensemble, coords, anisous, transs); if (outTrajTrans != null) { outTrajTrans.value.Add(transs); } System.Console.WriteLine(iter + "th alignment done: (move " + move2 + " Å)"); if (move2 < thres) { break; } DetermineMeanConf(lensemble, coords); DetermineThrmlFluc(lensemble, coords, anisous, null, anisou_eigvalthres); } ensemble = lensemble; }
public int QuasiNewton(List <ForceField.IForceField> frcflds , double threshold , double?k = null , double max_atom_movement = 0.01 , int?max_iteration = null , IMinimizeLogger logger = null // logger = new MinimizeLogger_PrintEnergyForceMag(logpath); , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); // double k = 0.0001; int iter = 0; // 0. Initial configuration of atoms Vector[] coords = univ.GetCoords(); Vector[] coords0 = univ.GetCoords(); bool[] atomsMovable = null; { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Dictionary <string, object> cache = new Dictionary <string, object>(); Vector[] forces = null; MatrixByArr hessian; double energy = 0; double[] dtor; double forces_NormInf; double forces_Norm1; double forces_Norm2; do { if (logger != null) { if (forces != null) { logger.log(iter, coords, energy, forces, atomsMovable); } { Vector[] coordsx = coords.HClone <Vector>(); Trans3 trans = ICP3.OptimalTransform(coordsx, coords0); trans.DoTransform(coordsx); logger.logTrajectory(univ, iter, coordsx); } } //GetPotentialAndTorForce(frcflds, coords // , out energy, out forces, out hessian, out dtor // , cache); { MatrixByArr J = Paper.TNM.GetJ(univ, coords, univ_rotinfos); Vector[] forces0 = univ.GetVectorsZero(); hessian = new double[size * 3, size *3]; energy = univ.GetPotential(frcflds, coords, ref forces0, ref hessian, cache); forces = univ.GetVectorsZero(); dtor = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J, forceProjectedByTorsional: forces); for (int i = 0; i < forces0.Length; i++) { forces0[i] = forces0[i] * 0.001; } dtor = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J); } forces_NormInf = NormInf(forces, atomsMovable); // NormInf(forces_prd, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); // Norm(1, forces_prd, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); // Norm(2, forces_prd, atomsMovable); if (forces_NormInf < 0.0001) { System.Environment.Exit(0); break; } coords = Paper.TNM.RotateTorsionals(coords, dtor, univ_rotinfos); iter++; }while(true); while (true) { // if(forces.IsComputable == false) // { // System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); // Environment.Exit(0); // } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(univ, iter, coords); //if(iter %10 == 0) //{ // System.IO.Directory.CreateDirectory("output"); // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache //energy = GetPotential(frcflds, coords, out forces, cache); // energy = univ.GetPotential(frcflds, coords, ref forces._vecs, ref hessian, cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { univ.SetCoords(coords); } //{ // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient //Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if (iter > 1) { // Debug.Assert(forces0 != null); // double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); // h = forces + r * h; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); // //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h,atomsMovable)); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } else { // // same to the steepest descent for the first iteration // h = forces; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); // //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); // // //double[] dangles = TNM.GetRotAngles(this, coords, kk * h, 1); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); // // // coords_prd = AddConditional(coords, kk * h, atomsMovable); } } // 5. Predict energy or forces on atoms iter++; //double energy_prd; Vectors forces_prd = univ.GetVectorsZero(); MatrixByArr hessian_prd = new double[size * 3, size *3]; //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; // GetPotentialAndTorForce(frcflds, coords_prd // , out energy_prd, out forces_prd._vecs, out hessian_prd // , cache); // // double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // // Vector[] dcoord_prd = univ.GetVectorsZero(); // // double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd); // // dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd); // //Vectors coords_prd2 = coords_prd.Clone(); // //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos); // // double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable); // double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable); // double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable); // // 6. Check if the predicted forces or energy will exceed over the limit // // , and goto 1 if no // // doSteepDeescent = true; // //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0)) // if((energy_prd < energy+0.1) && (forces_prd_NormInf < forces_NormInf+0.0001)) // { // energy0 = energy; // forces0 = forces; // coords = coords_prd; // forces = forces_prd; // hessian = hessian_prd; // energy = energy_prd; // forces_NormInf = forces_prd_NormInf; // forces_Norm1 = forces_prd_Norm1; // forces_Norm2 = forces_prd_Norm2; // continue; // } // if(logger != null) // logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); // // 7. Back to saved configuration // // 8. Move atoms with simple gradient // { // // same to the steepest descent // h = forces; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); // } // forces_prd = univ.GetVectorsZero(); // hessian_prd = new double[size*3, size*3]; // //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // GetPotentialAndTorForce(frcflds, coords_prd // , out energy_prd, out forces_prd._vecs, out hessian_prd // , cache); // forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // // energy0 = energy; // forces0 = forces; // coords = coords_prd; // forces = forces_prd; // energy = energy_prd; // forces_NormInf = forces_prd_NormInf; // forces_Norm1 = forces_prd_Norm1; // forces_Norm2 = forces_prd_Norm2; // // 9. goto 1 } }
public static void WriteResult(string pdbid, List <Pdb.Atom>[] ensemble, List <Trans3[]> trajtrans, string pathroot) { List <Pdb.Atom> atoms = ensemble[0]; int size = ensemble[0].Count; double bfactor0_min = double.PositiveInfinity; double bfactor0_max = double.NegativeInfinity; double anisou_eigvalthres = 0.00001 * 0.00001; { Trans3[] trans = trajtrans.First(); List <Vector>[] lensemble = new List <Vector> [ensemble.Length]; for (int i = 0; i < ensemble.Length; i++) { lensemble[i] = new List <Vector>(trans[i].GetTransformed(ensemble[i].ListCoord())); } Vector[] coords = new Vector[size]; Anisou[] anisous = new Anisou[size]; double[] bfactors = new double[size]; DetermineMeanConf(lensemble, coords); DetermineThrmlFluc(lensemble, coords, anisous, bfactors, anisou_eigvalthres); List <double>[] bfactorss = new List <double> [ensemble.Length]; for (int i = 0; i < bfactorss.Length; i++) { bfactorss[i] = new List <double>(bfactors); } List <int> idxCa = atoms.IndexOfAtoms(atoms.SelectByName("CA")); bfactor0_min = bfactors.HSelectByIndex(idxCa).HMinNth(idxCa.Count / 10); bfactor0_max = bfactors.HSelectByIndex(idxCa).HMaxNth(idxCa.Count / 10); Pdb.ToFile(pathroot + "ensemble.000.pdb", atoms, lensemble, bfactorss); Pdb.ToFile(pathroot + "ensemble.000.anisou.1.pdb", atoms, coords, anisous: anisous.GetUs(1), bfactors: bfactors, append: false); Pdb.ToFile(pathroot + "ensemble.000.anisou.10.pdb", atoms, coords, anisous: anisous.GetUs(10), bfactors: bfactors, append: false); Pdb.ToFile(pathroot + "ensemble.000.anisou.100.pdb", atoms, coords, anisous: anisous.GetUs(100), bfactors: bfactors, append: false); Pdb.ToFile(pathroot + "ensemble.000.anisou.1000.pdb", atoms, coords, anisous: anisous.GetUs(1000), bfactors: bfactors, append: false); Pdb.ToFile(pathroot + "ensemble.000.anisou.10000.pdb", atoms, coords, anisous: anisous.GetUs(10000), bfactors: bfactors, append: false); } int iter = trajtrans.Count - 1; double bfactorn_min = double.PositiveInfinity; double bfactorn_max = double.NegativeInfinity; { Trans3[] trans = new Trans3[ensemble.Length]; for (int j = 0; j < trans.Length; j++) { trans[j] = Trans3.UnitTrans; } for (int i = 0; i < trajtrans.Count; i++) { for (int j = 0; j < trans.Length; j++) { trans[j] = Trans3.AppendTrans(trans[j], trajtrans[i][j]); } } List <Vector>[] lensemble = new List <Vector> [ensemble.Length]; for (int i = 0; i < ensemble.Length; i++) { lensemble[i] = new List <Vector>(trans[i].GetTransformed(ensemble[i].ListCoord())); } Vector[] coords = new Vector[size]; Anisou[] anisous = new Anisou[size]; double[] bfactors = new double[size]; DetermineMeanConf(lensemble, coords); DetermineThrmlFluc(lensemble, coords, anisous, bfactors, anisou_eigvalthres); List <double>[] bfactorss = new List <double> [ensemble.Length]; for (int i = 0; i < bfactorss.Length; i++) { bfactorss[i] = new List <double>(bfactors); } List <int> idxCa = atoms.IndexOfAtoms(atoms.SelectByName("CA")); bfactorn_min = bfactors.HSelectByIndex(idxCa).HMinNth(idxCa.Count / 10); bfactorn_max = bfactors.HSelectByIndex(idxCa).HMaxNth(idxCa.Count / 10); Pdb.ToFile((pathroot + "ensemble.{finl}.pdb").Replace("{finl}", iter.ToString("000")), atoms, lensemble, bfactorss); Pdb.ToFile((pathroot + "ensemble.{finl}.anisou.1.pdb").Replace("{finl}", iter.ToString("000")), atoms, coords, anisous: anisous.GetUs(1), bfactors: bfactors, append: false); Pdb.ToFile((pathroot + "ensemble.{finl}.anisou.10.pdb").Replace("{finl}", iter.ToString("000")), atoms, coords, anisous: anisous.GetUs(10), bfactors: bfactors, append: false); Pdb.ToFile((pathroot + "ensemble.{finl}.anisou.100.pdb").Replace("{finl}", iter.ToString("000")), atoms, coords, anisous: anisous.GetUs(100), bfactors: bfactors, append: false); Pdb.ToFile((pathroot + "ensemble.{finl}.anisou.1000.pdb").Replace("{finl}", iter.ToString("000")), atoms, coords, anisous: anisous.GetUs(1000), bfactors: bfactors, append: false); Pdb.ToFile((pathroot + "ensemble.{finl}.anisou.10000.pdb").Replace("{finl}", iter.ToString("000")), atoms, coords, anisous: anisous.GetUs(10000), bfactors: bfactors, append: false); } { string[] lines = new string[] { @"load ensemble.{init}.pdb, {init}.align" , @"load ensemble.{init}.anisou.10.pdb, {init}.anisou.10" , @"load ensemble.{init}.anisou.100.pdb, {init}.anisou.100" , @"load ensemble.{init}.anisou.1000.pdb, {init}.anisou.1000" , @"load ensemble.{init}.anisou.10000.pdb, {init}.anisou.10000" , @"load ensemble.{finl}.pdb, {finl}.align" , @"load ensemble.{finl}.anisou.10.pdb, {finl}.anisou.10" , @"load ensemble.{finl}.anisou.100.pdb, {finl}.anisou.100" , @"load ensemble.{finl}.anisou.1000.pdb, {finl}.anisou.1000" , @"load ensemble.{finl}.anisou.10000.pdb, {finl}.anisou.10000" , @"load ..\theseus\{pdbid}_theseus_sup.pdb, theseus" , @"align theseus, {finl}.align" , @"orient {finl}.align" , @"zoom {finl}.align" , @"" , @"select sele, name ca and ({init}.anisou.* or {finl}.anisou.*)" , @"hide everything" , @"show ellipsoids, sele" , @"delete sele" , @"" , @"cartoon loop" , @"set cartoon_loop_radius, 0.1" , @"set all_states" , @"show cartoon, {init}.align or {finl}.align" , @"show cartoon, theseus" , @"disable all" , @"" , @"spectrum b, rainbow, minimum={bfactor-min}, maximum={bfactor-max}" , @"spectrum b, rainbow, minimum=0, maximum=50" , @"show line" , @"enable {init}.align; png ..\{pdbid}-{init}-line.png; disable {init}.align;" , @"enable {finl}.align; png ..\{pdbid}-{finl}-line.png; disable {finl}.align;" , @"hide line" , @"enable {init}.align; png ..\{pdbid}-{init}.png; disable {init}.align;" , @"enable {finl}.align; png ..\{pdbid}-{finl}.png; disable {finl}.align;" , @"enable theseus; png ..\{pdbid}-theseus.png; disable theseus;" , @"enable {init}.align" , @"enable {finl}.align" , @"enable theseus" }; lines = lines.HReplace("{init}", "000"); lines = lines.HReplace("{finl}", iter.ToString("000")); lines = lines.HReplace("{pdbid}", pdbid); lines = lines.HReplace("{bfactor-min}", bfactorn_min.ToString()); lines = lines.HReplace("{bfactor-max}", bfactorn_max.ToString()); string pmlpath = pathroot + "align.pml"; HFile.WriteAllLines(pmlpath, lines); { HFile.AppendAllLines(pmlpath, "quit"); string curdirectory = System.Environment.CurrentDirectory; string pmldirectory = pmlpath.Substring(0, pmlpath.LastIndexOf('\\') + 1); System.Environment.CurrentDirectory = pmldirectory; System.Diagnostics.ProcessStartInfo pymolStartInfo = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files (x86)\PyMOL\PyMOL\PymolWin.exe ", "\"" + pmlpath + "\""); pymolStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized; System.Diagnostics.Process pymol = System.Diagnostics.Process.Start(pymolStartInfo); //pymol.win pymol.WaitForExit(); System.Environment.CurrentDirectory = curdirectory; HFile.WriteAllLines(pmlpath, lines); } { List <string> lines_notheseus = new List <string>(); for (int i = 0; i < lines.Length; i++) { if (lines[i].Contains("theseus") == false) { lines_notheseus.Add(lines[i]); } } HFile.WriteAllLines(pathroot + "align.notheseus.pml", lines); } } }
public static Trans3 GetTrans(IList <Vector> C1, IList <double> bfactor, IList <Vector> C2) { Trans3 trans; double[] weight = new double[bfactor.Count]; { for (int i = 0; i < weight.Length; i++) { weight[i] = 1.0 / bfactor[i]; } } { int size = C1.Count; Vector MassCenter1 = new double[3]; Vector MassCenter2 = new double[3]; { double weight_sum = 0; for (int i = 0; i < size; i++) { weight_sum += weight[i]; MassCenter1 += weight[i] * C1[i]; MassCenter2 += weight[i] * C2[i]; } MassCenter1 = MassCenter1 / weight_sum; MassCenter2 = MassCenter2 / weight_sum; } Vector[] nc1 = new Vector[size]; Vector[] nc2 = new Vector[size]; { for (int i = 0; i < size; i++) { nc1[i] = C1[i] - MassCenter1; nc2[i] = C2[i] - MassCenter2; } } Quaternion rot = ICP3.OptimalRotationWeighted(nc2, nc1, weight); Quaternion urot = Quaternion.UnitRotation; Trans3 trans1 = new Trans3(-MassCenter2, 1, urot); Trans3 trans2 = new Trans3(new double[3], 1, rot); Trans3 trans3 = new Trans3(MassCenter1, 1, urot); trans = trans1; trans = Trans3.AppendTrans(Trans3.AppendTrans(trans1, trans2), trans3); HDebug.AssertTolerance(0.00000001, trans.DoTransform(MassCenter2) - MassCenter1); return(trans); } // /// original source // { // trans = ICP3.OptimalTransformWeighted(C2, C1, weight); // if(HDebug.IsDebuggerAttached) // { // Vector[] C2updated = trans.GetTransformed(C2).ToArray(); // double RMSD0 = 0; // double RMSD1 = 0; // for(int i=0; i<C1.Count; i++) // { // RMSD0 += (C1[i]-C2[i]).Dist2; // RMSD1 += (C1[i]-C2updated[i]).Dist2; // } // HDebug.Assert(RMSD1 <= RMSD0); // } // return trans; // } }
public int ConjugateGradient(List <ForceField.IForceField> frcflds , double threshold , double?k = null , double max_atom_movement = 0.01 , int?max_iteration = null , IMinimizeLogger logger = null // logger = new MinimizeLogger_PrintEnergyForceMag(logpath); , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); // double k = 0.0001; int iter = 0; // 0. Initial configuration of atoms Vector[] coords0 = univ.GetCoords(); Vectors coords = univ.GetCoords(); bool[] atomsMovable = null; if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = univ.GetVectorsZero(); Vectors forces = univ.GetVectorsZero(); Dictionary <string, object> cache; double energy; cache = new Dictionary <string, object>(); GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vectors forces0 = forces; double energy0 = energy; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); { // logger.logTrajectory(univ, iter, coords); Vector[] coordsx = coords._vecs.HClone <Vector>(); Trans3 trans = ICP3.OptimalTransform(coordsx, coords0); trans.DoTransform(coordsx); logger.logTrajectory(univ, iter, coordsx); } } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { univ.SetCoords((Vector[])coords); } { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if (iter >= 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } else { // same to the steepest descent for the first iteration h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } } // 5. Predict energy or forces on atoms iter++; double energy_prd; Vectors forces_prd = univ.GetVectorsZero(); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); // double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // Vector[] dcoord_prd = univ.GetVectorsZero(); // double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd); // dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd); //Vectors coords_prd2 = coords_prd.Clone(); //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos); double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } forces_prd = univ.GetVectorsZero(); //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }
public static void WriteCircles(string pmlpath , string objname , IList <Circle> lst_circle //, int numLinesInCircle = 50 //, double? linewidth = null //, double alpha=1.0, double red=1.0, double green=1.0, double blue=1.0 , bool append = false ) { StreamWriter file; if (append) { file = HFile.AppendText(pmlpath); } else { file = HFile.CreateText(pmlpath); } { //StreamWriter file = File.AppendText(pypath); file.WriteLine("from pymol.cgo import *"); file.WriteLine("from pymol import cmd"); file.WriteLine("obj = ["); foreach (var circle in lst_circle) { //Vector center = center_normal_radii_numseg_color_width.Item1; //Vector normal = center_normal_radii_numseg_color_width.Item2; //double radii = center_normal_radii_numseg_color_width.Item3; //int numLinesInCircle = center_normal_radii_numseg_color_width.Item4; //double? alpha = center_normal_radii_numseg_color_width.Item5.Item1; //double? red = center_normal_radii_numseg_color_width.Item5.Item2; //double? green = center_normal_radii_numseg_color_width.Item5.Item3; //double? blue = center_normal_radii_numseg_color_width.Item5.Item4; //double? linewidth = center_normal_radii_numseg_color_width.Item6; Trans3 trans = Trans3.GetTransformNoScale(new double[3] { 0, 0, 0 } , new double[3] { 0, 0, 1 } , circle.center , circle.center + circle.normal.UnitVector() ); Vector[] pts = new Vector[circle.numLinesInCircle + 1]; double di = (2 * Math.PI) / circle.numLinesInCircle; for (int i = 0; i < circle.numLinesInCircle; i++) { Vector lpt = new double[3] { circle.radii *Math.Cos(di * i), circle.radii *Math.Sin(di * i), 0 }; pts[i] = trans.DoTransform(lpt); } pts[circle.numLinesInCircle] = pts[0]; file.Write("BEGIN, LINE_STRIP, "); if (circle.linewidth != null) { file.Write("LINEWIDTH, {0:0.000}, ", circle.linewidth); } if (circle.alpha != null) { file.Write("ALPHA, {0:0.000},", circle.alpha); } if (circle.color != null) { file.Write("COLOR, {0:0.000}, {1:0.000}, {2:0.000}, ", circle.color.Item1, circle.color.Item2, circle.color.Item3); } for (int i = 0; i < pts.Length; i++) { if (i % 10 == 0) { file.WriteLine(); file.Write(" "); } file.Write("VERTEX, {0:0.000}, {1:0.000}, {2:0.000}, ", pts[i][0] + 0.000001, pts[i][1] + 0.000001, pts[i][2] + 0.000001); } file.WriteLine(); file.WriteLine(" END, "); } file.WriteLine("]"); // file.WriteLine("cmd.load_cgo(obj,\"channel_path\")"); file.WriteLine("cmd.load_cgo(obj,\"" + objname + "\")"); file.WriteLine(); } file.Close(); }
public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, IList <Anisou> anisou2, HPack <double> optEnergy = null) { int size = C1.Count; HDebug.Assert(size == C1.Count, size == C2.Count); Vector[] srcs = new Vector[size * 3 * 2]; // sources Vector[] tars = new Vector[size * 3 * 2]; // targets double[] weis = new double[size * 3 * 2]; // weights double[] engs = new double[size * 3 * 2]; // energies //for(int i=0; i<size; i++) //{ // Debug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i*3+0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0]; // Debug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i*3+1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1]; // Debug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i*3+2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2]; // enrgs[i*3+0] = enrgs[i*3+1] = enrgs[i*3+2] = double.NaN; //} //Trans3 trans = ICP3.OptimalTransform(C2, C1); Trans3 trans = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s); int iter = 0; int iter_max = 1000; //double enrg = double.NaN; while (iter < iter_max) { iter++; //for(int i=0; i<size; i++) System.Threading.Tasks.Parallel.For(0, size, delegate(int i) { for (int j = 0; j < 3; j++) { Vector p1 = C1[i]; Vector n1 = anisou1[i].axes[j]; double w1 = anisou1[i].eigvals[j]; w1 = (w1 <= 0) ? 0 : 1 / w1; Vector p2 = trans.DoTransform(C2[i]); Vector n2 = (trans.DoTransform(C2[i] + anisou2[i].axes[j]) - p2).UnitVector(); double w2 = anisou2[i].eigvals[j]; w2 = (w2 <= 0) ? 0 : 1 / w2; Vector clo12 = p2 - LinAlg.DotProd(n1, p2 - p1) * n1; // closest point from p1 to plane2 Vector clo21 = p1 - LinAlg.DotProd(n2, p1 - p2) * n2; // closest point from p1 to plane2 HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo12 - p1, n1)); HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo21 - p2, n2)); // p2 -> (pt closest to p2 on plane1 with w1) srcs[(i * 3 + j) * 2 + 0] = p2; tars[(i * 3 + j) * 2 + 0] = clo12; weis[(i * 3 + j) * 2 + 0] = w1; engs[(i * 3 + j) * 2 + 0] = w1 * (p2 - clo12).Dist2; // inverse of {p1 -> (pt closest to p1 on plane2 with w2)} // = (pt closest to p1 on plane2 with w2) -> p1 srcs[(i * 3 + j) * 2 + 1] = clo21; tars[(i * 3 + j) * 2 + 1] = p1; weis[(i * 3 + j) * 2 + 1] = w2; engs[(i * 3 + j) * 2 + 1] = w2 * (clo21 - p1).Dist2; } }); Trans3 dtrans = ICP3.OptimalTransformWeighted(srcs, tars, weis); trans = Trans3.AppendTrans(trans, dtrans); double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax(); if (max_dtrans_matrix < 0.0000001) { break; } } if (optEnergy != null) { optEnergy.value = engs.Sum() / size; } return(trans); }
public static void Align(List <Vector> coords1, ref List <Vector> coords2) { Trans3 trans = GetTrans(coords1, coords2); coords2 = new List <Vector>(trans.GetTransformed(coords2)); }