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 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 <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 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; // } }