Пример #1
0
            static public void MV(HessMatrixSparse M, Vector V, Vector mv, Vector bvec, Vector bmv)
            {
                HDebug.Exception(V.Size == M.RowSize);
                HDebug.Exception(mv.Size == M.ColSize); //Vector mv = new double[M.ColSize];
                HDebug.Exception(bvec.Size == 3);       //Vector bvec = new double[3];
                HDebug.Exception(bmv.Size == 3);        //Vector bmv = new double[3];
                foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in M.EnumBlocks())
                {
                    int bc   = bc_br_bval.Item1;
                    int br   = bc_br_bval.Item2;
                    var bmat = bc_br_bval.Item3;
                    bvec[0] = V[br * 3 + 0];
                    bvec[1] = V[br * 3 + 1];
                    bvec[2] = V[br * 3 + 2];
                    HTLib2.LinAlg.MV(bmat, bvec, bmv);
                    mv[bc * 3 + 0] += bmv[0];
                    mv[bc * 3 + 1] += bmv[1];
                    mv[bc * 3 + 2] += bmv[2];
                }

                if (HDebug.Selftest())
                {
                    Matlab.Clear();
                    Matlab.PutSparseMatrix("M", M.GetMatrixSparse(), 3, 3);
                    Matlab.PutVector("V", V);
                    Matlab.Execute("MV = M*V;");
                    Matlab.PutVector("MV1", mv);
                    Vector err     = Matlab.GetVector("MV-MV1");
                    double err_max = err.ToArray().HAbs().Max();
                    HDebug.Assert(err_max < 0.00000001);
                }
            }
Пример #2
0
        static void UpdateMassWeightedHess(HessMatrix hess, Vector mass)
        {
            if (hess.ColSize < 15000)
            {
                if (HDebug.Selftest())
                {
                    Matrix tmat0 = hess.ToArray();
                    UpdateMassWeightedHess(tmat0, mass);
                    HessMatrix tmat1 = hess.CloneHess();
                    UpdateMassWeightedHess(tmat1, mass);
                    double absmax = (tmat0 - tmat1).HAbsMax();
                    HDebug.Exception(absmax < 0.00000001);
                }
            }

            HDebug.Exception(mass.Size % 3 == 0);
            double[] mass03sqrt = new double[mass.Size / 3];
            for (int i = 0; i < mass03sqrt.Length; i++)
            {
                HDebug.Exception(mass[i * 3 + 0] == mass[i * 3 + 1]);
                HDebug.Exception(mass[i * 3 + 0] == mass[i * 3 + 2]);
                mass03sqrt[i] = mass[i * 3 + 0];
            }
            mass03sqrt = mass03sqrt.HSqrt();

            foreach (var bc_br_bval in hess.EnumBlocks().ToArray())
            {
                int bc   = bc_br_bval.Item1;
                int br   = bc_br_bval.Item2;
                var bval = bc_br_bval.Item3;
                bval = bval / (mass03sqrt[bc] * mass03sqrt[br]);

                hess.SetBlock(bc, br, bval);
            }
        }
Пример #3
0
        public static HessRTB GetHessRTBByBlockAsResidue(HessMatrix hess, Vector[] coords, double[] masses, Universe.Atom[] atoms, string opt)
        {
            int leng = coords.Length;

            HDebug.Exception
                (leng == hess.ColBlockSize
                , leng == hess.RowBlockSize
                , leng == coords.Length
                , leng == masses.Length
                , leng == atoms.Length
                , "length does not match"
                );

            List <int[]> blocks = new List <int[]>();

            foreach (var group in atoms.GroupByResidue())
            {
                List <int> block = new List <int>();
                foreach (var atom in group)
                {
                    block.Add(atom.ID);
                }
                blocks.Add(block.ToArray());
            }

            return(BuilderHessRTB.GetHessRTB(hess, coords, masses, blocks, opt));
        }
Пример #4
0
            public static Tuple <string, char, int, string, char> DecomposeMutationType(string muttype)
            {
                if (DecomposeMutationType_selftest)
                {
                    DecomposeMutationType_selftest = false;
                    var tdec = DecomposeMutationType("H64W");
                    HDebug.Exception(tdec.Item1.ToUpper() == "HIS");
                    HDebug.Exception(tdec.Item2 == 'H');
                    HDebug.Exception(tdec.Item3 == 64);
                    HDebug.Exception(tdec.Item4.ToUpper() == "TRP");
                    HDebug.Exception(tdec.Item5 == 'W');
                }
                //var aminoacids = HBioinfo.AminoAcids.ToDictionaryBy1Letter();
                Func <char, HBioinfo.Acid> aminoacids = delegate(char resn)
                {
                    return(HBioinfo.Acid.From1Letter(resn));
                };

                char   wt_resn1 = muttype.First(); string wt_resn3 = aminoacids(wt_resn1).name3;
                char   mut_resn1 = muttype.Last(); string mut_resn3 = aminoacids(mut_resn1).name3;
                string lwt_resi = muttype.Substring(1, muttype.Length - 2);
                int    wt_resi  = int.Parse(lwt_resi);

                return(new Tuple <string, char, int, string, char>
                           (wt_resn3, wt_resn1
                           , wt_resi
                           , mut_resn3, mut_resn1
                           ));
            }
Пример #5
0
        //public static OOverlapWeighted OverlapWeightedByFreq(IList<Mode> modes1, IList<Mode> modes2, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap)
        //{
        //    Vector weights = new double[modes1.Count];
        //    for(int i=0; i<weights.Size; i++)
        //        weights[i] = 1/Math.Sqrt(Math.Abs(modes1[i].eigval));
        //    weights /= weights.Sum();
        //
        //    return OverlapWeighted(modes1, modes2, weights.ToArray(), ila, bResetUnitVector, optSelectOverlap);
        //}
        public static OOverlapWeighted OverlapWeighted(IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2, IList <double> weights, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap)
        {
            Matrix soverlap = OverlapSigned(modes1, mass1, mass2, modes2, ila, bResetUnitVector);

            HDebug.Exception(modes1.Count == weights.Count);

            int[] idxOverlap1to2;
            switch (optSelectOverlap)
            {
            case "corresponding index":
                if (modes1.Count != modes2.Count)
                {
                    throw new HException();
                }
                idxOverlap1to2 = HEnum.HEnumCount(modes1.Count).ToArray();
                break;

            case "best matching overlap":
                idxOverlap1to2 = new int[modes1.Count];
                for (int im = 0; im < modes1.Count; im++)
                {
                    idxOverlap1to2[im] = 0;
                    for (int k = 0; k < modes2.Count; k++)
                    {
                        if (Math.Abs(soverlap[im, idxOverlap1to2[im]]) < Math.Abs(soverlap[im, k]))
                        {
                            idxOverlap1to2[im] = k;
                        }
                    }
                }
                break;

            default:
                throw new HException();
            }

            Vector overlap1to2       = new double[modes1.Count];
            Vector overlap1to2signed = new double[modes1.Count];
            double woverlap          = 0;

            for (int i = 0; i < modes1.Count; i++)
            {
                overlap1to2      [i] = Math.Abs(soverlap[i, idxOverlap1to2[i]]);
                overlap1to2signed[i] = soverlap[i, idxOverlap1to2[i]];
                woverlap            += weights[i] * overlap1to2[i];
            }

            return(new OOverlapWeighted
            {
                soverlap1to2 = soverlap,
                woverlap = woverlap,
                weights = weights.ToArray(),
                overlaps = overlap1to2.ToArray(),
                sgnoverlaps = overlap1to2signed.ToArray(),
                idxOverlap1to2 = idxOverlap1to2,
                modes1 = modes1.ToArray(),
                modes2 = modes2.ToArray(),
            });
        }
Пример #6
0
        public static MatrixSparse <double> GetCorrMatrix(this IList <Mode> modes, IEnumerable <Tuple <int, int> > enumCorrCR)
        {
            Vector[][] eigvecs = new Vector[modes.Count][];
            double[]   eigvals = new double[modes.Count];
            for (int i = 0; i < modes.Count; i++)
            {
                eigvals[i] = modes[i].eigval;
                eigvecs[i] = modes[i].GetEigvecsOfAtoms();
            }

            int size = modes[0].size;
            MatrixSparse <double> Dij = new MatrixSparse <double>(size, size);
            Vector Dii = new double[size];

            for (int i = 0; i < eigvals.Length; i++)
            {
                Vector[] eigvec = eigvecs[i];
                double   eigval = eigvals[i];

                for (int c = 0; c < size; c++)
                {
                    Dii[c] += (LinAlg.VtV(eigvec[c], eigvec[c]) / eigval);
                }
                foreach (var cr in enumCorrCR)
                {
                    int c = cr.Item1;
                    int r = cr.Item2;
                    Dij[c, r] += (LinAlg.VtV(eigvec[c], eigvec[r]) / eigval);
                }
            }
            foreach (var cr in enumCorrCR)
            {
                Dij[cr] = Dij[cr] / modes.Count;
            }
            Dii = Dii / modes.Count;

            // Cij
            foreach (var cr in enumCorrCR)
            {
                int c = cr.Item1;
                int r = cr.Item2;
                Dij[c, r] /= Math.Sqrt(Dii[c] * Dii[r]);
            }

            if (HDebug.IsDebuggerAttached)
            {
                Matrix tDij = GetCorrMatrix(modes);
                foreach (var cr in enumCorrCR)
                {
                    int    c   = cr.Item1;
                    int    r   = cr.Item2;
                    double err = Dij[c, r] - tDij[c, r];
                    HDebug.Exception(Math.Abs(err) < 0.00000001);
                }
            }

            return(Dij);
        }
Пример #7
0
            public string GetUpdatedLineChainID(char chainID)
            {
                HDebug.Exception(idxs_chainID[0] == idxs_chainID[1]);
                char[] line = this.line.ToArray();
                line[idxs_chainID[0] - 1] = chainID;
                string newline = new string(line);

                return(newline);
            }
Пример #8
0
        static void UpdateMassWeightedHess(Matrix hess, Vector mass)
        {
            if (HDebug.Selftest())
            //if(GetMassWeightedHess_selftest1)
            #region selftest
            {
                //HDebug.ToDo("replace examplt not to use blocked hessian matrix");
                //GetMassWeightedHess_selftest1 = false;
                MatrixByArr[,] _bhess = new MatrixByArr[2, 2];
                _bhess[0, 0]          = new double[3, 3] {
                    { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
                };
                _bhess[0, 1] = _bhess[0, 0] + 10;
                _bhess[1, 0] = _bhess[0, 0] + 20;
                _bhess[1, 1] = _bhess[0, 0] + 30;
                Vector _mass = new double[2] {
                    2, 3
                };
                MatrixByArr _hess = MatrixByArr.FromMatrixArray(_bhess);

                Matrix _mwhess = GetMassWeightedHess(_hess, _mass);
                MatrixByArr[,] _mwbhess = GetMassWeightedHess(_bhess, _mass);

                HDebug.AssertTolerance(0.00000001, MatrixByArr.FromMatrixArray(_mwbhess) - _mwhess.ToArray());
            }
            #endregion

            HDebug.Exception(hess.ColSize == mass.Size);
            HDebug.Assert(hess.ColSize == hess.RowSize);
            HDebug.Assert(hess.ColSize % 3 == 0);

            Vector mass05 = mass.ToArray().HSqrt();

            // mass weighted hessian
            // MH = M^(-1/2) * H * M^(-1/2)
            // MH_ij = H_IJ * sqrt(M[i] * M[j])
            {
                // mass weighted block hessian
                for (int i = 0; i < hess.ColSize; i++)
                {
                    for (int j = 0; j < hess.RowSize; j++)
                    {
                        //if(i == j) continue;
                        hess[i, j] = hess[i, j] / (mass05[i] * mass05[j]);
                        //mbhess[i, i] -= mbhess[i, j];
                    }
                }
            }
        }
Пример #9
0
        public HessMatrix SubMatrixByAtomsImpl(bool ignNegIdx, IList <int> idxAtoms)
        {
            if (SubMatrixByAtomsImpl_selftest)
            {
                SubMatrixByAtomsImpl_selftest = false;
                Vector[] tcoords = new Vector[] {
                    new Vector(1, 2, 3),
                    new Vector(1, 3, 2),
                    new Vector(1, 2, 9),
                };
                HessMatrix thess0  = Hess.GetHessAnm(tcoords);
                int[]      tidxs   = new int[] { 0, 2 };
                HessMatrix thess1a = thess0.SubMatrixByAtoms(false, tidxs);
                HessMatrix thess1b = new double[, ]
                {
                    { thess0[0, 0], thess0[0, 1], thess0[0, 2], thess0[0, 6], thess0[0, 7], thess0[0, 8] },
                    { thess0[1, 0], thess0[1, 1], thess0[1, 2], thess0[1, 6], thess0[1, 7], thess0[1, 8] },
                    { thess0[2, 0], thess0[2, 1], thess0[2, 2], thess0[2, 6], thess0[2, 7], thess0[2, 8] },
                    { thess0[6, 0], thess0[6, 1], thess0[6, 2], thess0[6, 6], thess0[6, 7], thess0[6, 8] },
                    { thess0[7, 0], thess0[7, 1], thess0[7, 2], thess0[7, 6], thess0[7, 7], thess0[7, 8] },
                    { thess0[8, 0], thess0[8, 1], thess0[8, 2], thess0[8, 6], thess0[8, 7], thess0[8, 8] },
                };

//                           thess1a = Hess.CorrectHessDiag(thess1a);                     // diagonal of original matrix contains the interaction between 0-1 and 1-2 also,
//                HessMatrix thess1b = Hess.GetHessAnm(tcoords.HSelectByIndex(tidxs));    // while new generated hessian matrix does not.
                Matrix tdiffhess     = thess1a - thess1b;
                double max_tdiffhess = tdiffhess.ToArray().HAbs().HMax();
                HDebug.Exception(0 == max_tdiffhess);
            }

            HessMatrix nhess = SubMatrixByAtomsImpl(ignNegIdx, idxAtoms, idxAtoms, true);

            if (HDebug.IsDebuggerAttached && idxAtoms.Count < 1000)
            {
                List <int> idx3Atoms = new List <int>();
                foreach (int idx in idxAtoms)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        idx3Atoms.Add(idx * 3 + i);
                    }
                }
                Matrix tnhess         = this.SubMatrix(idx3Atoms, idx3Atoms);
                double max2_tdiffhess = (nhess - tnhess).ToArray().HAbs().HMax();
                HDebug.AssertTolerance(0.00000001, max2_tdiffhess);
            }
            return(nhess);
        }
Пример #10
0
            public static Crd FromFile(string path)
            {
                string[] lines = HFile.ReadAllLines(path);

                int?        num_elems = null;
                List <Atom> elems     = null;

                foreach (string line in lines)
                {
                    if (line.StartsWith("*"))
                    {
                        // comment
                        continue;
                    }

                    // "    358272  EXT"
                    // "         1         1  TIP3      OH2           -79.8000000000      -20.4000000000       -4.2000000000  BWAT      1               0.0000000000"
                    //  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
                    //  0         1         2         3         4         5         6         7         8         9         10        11        12        13
                    // "  %8d  %8d  %-8s  %-8s  %18.10f  %18.10f  %18.10f  %-8s  %-8d  %18.10f"
                    if (elems == null)
                    {
                        // "    358272  EXT"
                        //  012345678901234
                        //  0         1
                        string[] tokens = new string[]
                        {
                            line.Substring(0, 10),
                            line.Substring(10),
                        };
                        num_elems = int.Parse(tokens[0]);
                        HDebug.Exception(tokens[1] == "  EXT");
                        elems = new List <Atom>(num_elems.Value);
                    }
                    else
                    {
                        elems.Add(new Atom {
                            line = line
                        });
                    }
                }
                HDebug.Assert(elems.Count == num_elems);

                return(new Crd
                {
                    atoms = elems.ToArray(),
                });
            }
Пример #11
0
            public static string GetMutationType(string wt_resn, int wt_resi, string mut_resn)
            {
                HDebug.Assert(GetMutationType("HIS", 64, "TRP") == "H64W"); // selftest

                //var aminoacids = HBioinfo.AminoAcids.ToDictionaryBy3Letter(true);
                Func <string, HBioinfo.Acid> aminoacids = delegate(string resn)
                {
                    var aa = HBioinfo.Acid.From3Letter(resn);
                    HDebug.Exception(aa.Count == 1);
                    return(aa[0]);
                };

                string muttype = string.Format("{0}{1}{2}", aminoacids(wt_resn).name1, wt_resi, aminoacids(mut_resn).name1);

                return(muttype);
            }
Пример #12
0
        public static Tuple <Sheet[], Atom[]>[] HSelectAtoms <Atom>(this IList <Sheet> sheets, IList <Atom> atoms)
            where Atom : IAtom
        {
            var chain_resi_atoms = atoms.GroupChainIDResSeq();
            var id_sheets        = sheets.HGroupBySheetID();

            List <Tuple <Sheet[], Atom[]> > list = new List <Tuple <Sheet[], Atom[]> >();

            foreach (string id in id_sheets.Keys)
            {
                Sheet[] idsheets = id_sheets[id];

                List <Atom> idsheets_atoms = new List <Atom>();
                foreach (var sheet in idsheets)
                {
                    HDebug.Exception(sheet.initChainID == sheet.endChainID);
                    char chain = sheet.initChainID;
                    if (chain_resi_atoms.ContainsKey(chain) == false)
                    {
                        continue;
                    }
                    var chainresi_atoms = chain_resi_atoms[chain];

                    int[] resis;
                    resis = new int[] { sheet.initSeqNum, sheet.endSeqNum };
                    resis = resis.HSort();
                    resis = HEnum.HEnumFromTo(resis[0], resis[1]).ToArray();

                    foreach (var resi in resis)
                    {
                        if (chainresi_atoms.ContainsKey(resi) == false)
                        {
                            continue;
                        }
                        idsheets_atoms.AddRange(chainresi_atoms[resi]);
                    }
                }

                list.Add(new Tuple <Sheet[], Atom[]>
                         (
                             idsheets,
                             idsheets_atoms.ToArray()
                         ));
            }

            return(list.ToArray());
        }
Пример #13
0
 public static void UpdateMassReduced(this IList <Mode> modes, IList <double> masses, HOptions options = null)
 {
     if (options == null)
     {
         options = "";
     }
     if (options.Contains("parallel"))
     {
         HDebug.Exception(new NotImplementedException("check"));
         int[] iter = new int[1] {
             0
         };
         System.Threading.Tasks.Parallel.For(0, modes.Count, delegate(int i)
         {
             Mode modei = modes[i];
             modes[i]   = null;
             modes[i]   = modei.GetMassReduced(masses);
             lock (iter)
             {
                 iter[0]++;
                 if (iter[0] % 1000 == 0)
                 {
                     System.GC.Collect(0);
                 }
             }
         });
         System.GC.Collect();
     }
     else
     {
         for (int i = 0; i < modes.Count; i++)
         {
             Mode modei = modes[i];
             modes[i] = null;
             modes[i] = modei.GetMassReduced(masses);
             if (i % 1000 == 0)
             {
                 System.GC.Collect(0);
             }
         }
         System.GC.Collect();
     }
 }
Пример #14
0
        public static IEnumerable <Tuple <int, int, double> > EnumHessAnmSpr(IList <Vector> coords, double cutoff, double sprcst)
        {
            if (HDebug.Selftest())
            {
                Vector[] _coords = Pdb.FromLines(SelftestData.lines_1L2Y_pdb).atoms.SelectByName("CA").ListCoord().ToArray().HSelectCount(10);
                HashSet <Tuple <int, int, double> > sprs0 = //EnumHessAnmSpr_obsolete(_coords, 7, 1).HToHashSet();
                                                            new HashSet <Tuple <int, int, double> >
                {
                    new Tuple <int, int, double>(0, 1, 1), new Tuple <int, int, double>(1, 0, 1), new Tuple <int, int, double>(0, 2, 1), new Tuple <int, int, double>(2, 0, 1), new Tuple <int, int, double>(0, 3, 1),
                    new Tuple <int, int, double>(3, 0, 1), new Tuple <int, int, double>(0, 4, 1), new Tuple <int, int, double>(4, 0, 1), new Tuple <int, int, double>(1, 2, 1), new Tuple <int, int, double>(2, 1, 1),
                    new Tuple <int, int, double>(1, 3, 1), new Tuple <int, int, double>(3, 1, 1), new Tuple <int, int, double>(1, 4, 1), new Tuple <int, int, double>(4, 1, 1), new Tuple <int, int, double>(1, 5, 1),
                    new Tuple <int, int, double>(5, 1, 1), new Tuple <int, int, double>(2, 3, 1), new Tuple <int, int, double>(3, 2, 1), new Tuple <int, int, double>(2, 4, 1), new Tuple <int, int, double>(4, 2, 1),
                    new Tuple <int, int, double>(2, 5, 1), new Tuple <int, int, double>(5, 2, 1), new Tuple <int, int, double>(2, 6, 1), new Tuple <int, int, double>(6, 2, 1), new Tuple <int, int, double>(3, 4, 1),
                    new Tuple <int, int, double>(4, 3, 1), new Tuple <int, int, double>(3, 5, 1), new Tuple <int, int, double>(5, 3, 1), new Tuple <int, int, double>(3, 6, 1), new Tuple <int, int, double>(6, 3, 1),
                    new Tuple <int, int, double>(3, 7, 1), new Tuple <int, int, double>(7, 3, 1), new Tuple <int, int, double>(4, 5, 1), new Tuple <int, int, double>(5, 4, 1), new Tuple <int, int, double>(4, 6, 1),
                    new Tuple <int, int, double>(6, 4, 1), new Tuple <int, int, double>(4, 7, 1), new Tuple <int, int, double>(7, 4, 1), new Tuple <int, int, double>(4, 8, 1), new Tuple <int, int, double>(8, 4, 1),
                    new Tuple <int, int, double>(5, 6, 1), new Tuple <int, int, double>(6, 5, 1), new Tuple <int, int, double>(5, 7, 1), new Tuple <int, int, double>(7, 5, 1), new Tuple <int, int, double>(5, 8, 1),
                    new Tuple <int, int, double>(8, 5, 1), new Tuple <int, int, double>(6, 7, 1), new Tuple <int, int, double>(7, 6, 1), new Tuple <int, int, double>(6, 8, 1), new Tuple <int, int, double>(8, 6, 1),
                    new Tuple <int, int, double>(6, 9, 1), new Tuple <int, int, double>(9, 6, 1), new Tuple <int, int, double>(7, 8, 1), new Tuple <int, int, double>(8, 7, 1), new Tuple <int, int, double>(7, 9, 1),
                    new Tuple <int, int, double>(9, 7, 1), new Tuple <int, int, double>(8, 9, 1), new Tuple <int, int, double>(9, 8, 1),
                };
                HashSet <Tuple <int, int, double> > sprs1 = EnumHessAnmSpr(_coords, 7, 1).HToHashSet();
                HDebug.Exception(sprs0.Count == sprs1.Count);
                foreach (var spr in sprs0)
                {
                    HDebug.Exception(sprs1.Contains(spr));
                }
            }

            KDTreeDLL.KDTree <object> kdtree = new KDTreeDLL.KDTree <object>(3);
            for (int i = 0; i < coords.Count; i++)
            {
                kdtree.insert(coords[i], i);
            }

            int    size        = coords.Count;
            double cutoff2     = cutoff * cutoff;
            int    num_springs = 0;

            for (int c = 0; c < coords.Count; c++)
            {
                Vector lowk = coords[c] - (new double[] { cutoff, cutoff, cutoff });
                Vector uppk = coords[c] + (new double[] { cutoff, cutoff, cutoff });
                foreach (int r in kdtree.range(lowk, uppk))
                {
                    if (c >= r)
                    {
                        continue;
                    }
                    double dist2 = (coords[c] - coords[r]).Dist2;
                    if (dist2 < cutoff2)
                    {
                        yield return(new Tuple <int, int, double>(c, r, sprcst));

                        yield return(new Tuple <int, int, double>(r, c, sprcst));

                        num_springs += 2;
                    }
                }
            }
            double ratio_springs = ((double)num_springs) / (size * size);
        }
Пример #15
0
        public static Matrix OverlapSigned(IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2, ILinAlg ila, bool bResetUnitVector)
        {
            Matrix mat1;
            Matrix mat2;
            string mat12opt = "memory-save";

            switch (mat12opt)
            {
            case "initial":
            {
                Vector[] eigvecs1 = new Vector[modes1.Count]; for (int i = 0; i < modes1.Count; i++)
                {
                    eigvecs1[i] = modes1[i].eigvec.Clone();
                }
                Vector[] eigvecs2 = new Vector[modes2.Count]; for (int i = 0; i < modes2.Count; i++)
                {
                    eigvecs2[i] = modes2[i].eigvec.Clone();
                }
                {
                    // 1. Hess
                    // 2. mwHess <- M^-0.5 * H * M^-0.5
                    // 3. [V,D]  <- eig(mwHess)
                    // 4. mrMode <- M^-0.5 * V
                    //
                    // overlap: vi . vj
                    // 1. vi <- M^0.5 * mrMode_i
                    // 2. vj <- M^0.5 * mrMode_j
                    // 3. vi.vj <- dot(vi,vj)
                    //
                    //         [ 2           ]   [4]   [2*4]   [ 8]
                    //         [   2         ]   [5]   [2*5]   [10]
                    // M * v = [     2       ] * [6] = [2*6] = [12]
                    //         [       3     ]   [7]   [3*7]   [21]
                    //         [         3   ]   [8]   [3*8]   [24]
                    //         [           3 ]   [9]   [3*9]   [27]
                    //
                    // V1 <- sqrt(M1) * V1
                    // V2 <- sqrt(M2) * V2
                    //                           1. get sqrt(mass)          2. for each eigenvector              3 eigveci[j] = eigvec[j] * sqrt_mass[j/3]
                    if (mass1 != null)
                    {
                        double[] mass1sqrt = mass1.HSqrt(); for (int i = 0; i < eigvecs1.Length; i++)
                        {
                            for (int j = 0; j < eigvecs1[i].Size; j++)
                            {
                                eigvecs1[i][j] *= mass1sqrt[j / 3];
                            }
                        }
                    }
                    if (mass2 != null)
                    {
                        double[] mass2sqrt = mass2.HSqrt(); for (int i = 0; i < eigvecs2.Length; i++)
                        {
                            for (int j = 0; j < eigvecs2[i].Size; j++)
                            {
                                eigvecs2[i][j] *= mass2sqrt[j / 3];
                            }
                        }
                    }
                }
                if (bResetUnitVector)
                {
                    for (int i = 0; i < modes1.Count; i++)
                    {
                        eigvecs1[i] = eigvecs1[i].UnitVector();
                    }
                    for (int i = 0; i < modes2.Count; i++)
                    {
                        eigvecs2[i] = eigvecs2[i].UnitVector();
                    }
                }

                mat1 = eigvecs1.ToMatrix(false); HDebug.Assert(mat1.ColSize == eigvecs1.Length); eigvecs1 = null; GC.Collect(0);
                mat2 = eigvecs2.ToMatrix(true); HDebug.Assert(mat2.RowSize == eigvecs2.Length); eigvecs2 = null; GC.Collect(0);
            }
            break;

            case "memory-save":
            {
                int vecsize = modes1[0].eigvec.Size;
                HDebug.Exception(vecsize == modes1[0].eigvec.Size);
                HDebug.Exception(vecsize == modes2[0].eigvec.Size);

                //Vector[] eigvecs1 = new Vector[modes1.Count]; for(int i=0; i<modes1.Count; i++) eigvecs1[i] = modes1[i].eigvec.Clone();
                //if(mass1 != null) { double[] mass1sqrt = mass1.HSqrt(); for(int i=0; i<modes1.Count; i++) for(int j=0; j<eigvecs1[i].Size; j++) eigvecs1[i][j] *= mass1sqrt[j/3]; }
                //if(bResetUnitVector) for(int i=0; i<modes1.Count; i++) eigvecs1[i] = eigvecs1[i].UnitVector();
                //mat1 = eigvecs1.ToMatrix(false); HDebug.Assert(mat1.ColSize == modes1.Count); eigvecs1 = null; GC.Collect(0);
                mat1 = Matrix.Zeros(modes1.Count, vecsize);
                double[] mass1sqrt = null; if (mass1 != null)
                {
                    mass1sqrt = mass1.HSqrt();
                }
                for (int i = 0; i < modes1.Count; i++)
                {
                    Vector eigvecs1i = modes1[i].eigvec.Clone();
                    if (mass1 != null)
                    {
                        for (int j = 0; j < eigvecs1i.Size; j++)
                        {
                            eigvecs1i[j] *= mass1sqrt[j / 3];
                        }
                    }
                    if (bResetUnitVector)
                    {
                        eigvecs1i = eigvecs1i.UnitVector();
                    }
                    for (int j = 0; j < eigvecs1i.Size; j++)
                    {
                        mat1[i, j] = eigvecs1i[j];
                    }
                }
                HDebug.Assert(mat1.ColSize == modes1.Count);
                GC.Collect(0);

                //Vector[] eigvecs2 = new Vector[modes2.Count]; for(int i=0; i<modes2.Count; i++) eigvecs2[i] = modes2[i].eigvec.Clone();
                //if(mass2 != null) { double[] mass2sqrt = mass2.HSqrt(); for(int i=0; i<modes2.Count; i++) for(int j=0; j<eigvecs2[i].Size; j++) eigvecs2[i][j] *= mass2sqrt[j/3]; }
                //if(bResetUnitVector) for(int i=0; i<modes2.Count; i++) eigvecs2[i] = eigvecs2[i].UnitVector();
                //mat2 = eigvecs2.ToMatrix(true ); HDebug.Assert(mat2.RowSize == modes2.Count); eigvecs2 = null; GC.Collect(0);
                mat2 = Matrix.Zeros(vecsize, modes2.Count);
                double[] mass2sqrt = null; if (mass2 != null)
                {
                    mass2sqrt = mass2.HSqrt();
                }
                for (int i = 0; i < modes2.Count; i++)
                {
                    Vector eigvecs2i = modes2[i].eigvec.Clone();
                    if (mass2 != null)
                    {
                        for (int j = 0; j < eigvecs2i.Size; j++)
                        {
                            eigvecs2i[j] *= mass2sqrt[j / 3];
                        }
                    }
                    if (bResetUnitVector)
                    {
                        eigvecs2i = eigvecs2i.UnitVector();
                    }
                    for (int j = 0; j < eigvecs2i.Size; j++)
                    {
                        mat2[j, i] = eigvecs2i[j];
                    }
                }
                HDebug.Assert(mat2.RowSize == modes2.Count);
                GC.Collect(0);
            }
            break;

            default:
                throw new NotImplementedException();
            }

            HDebug.Assert(mat1.RowSize == mat2.ColSize);
            Matrix overlap = null;

            if (ila != null)
            {
                overlap = ila.Mul(mat1, mat2);
            }
            else
            {
                overlap = Matlab.ila.Mul(mat1, mat2);
            }
            mat1 = mat2 = null;
            GC.Collect(0);
            //overlap.UpdateAbs();

            if (HDebug.IsDebuggerAttached)
            {
                double[] sum_c2 = new double[overlap.ColSize];
                double[] sum_r2 = new double[overlap.RowSize];
                for (int c = 0; c < overlap.ColSize; c++)
                {
                    for (int r = 0; r < overlap.RowSize; r++)
                    {
                        double v  = overlap[c, r];
                        double v2 = v * v;
                        HDebug.Assert(v2 <= 1.00000000001);
                        sum_c2[c] += v2;
                        sum_r2[r] += v2;
                    }
                }
                for (int c = 0; c < overlap.ColSize; c++)
                {
                    HDebug.AssertTolerance(0.00001, sum_c2[c] - 1.0);
                }
                for (int r = 0; r < overlap.RowSize; r++)
                {
                    HDebug.AssertTolerance(0.00001, sum_r2[r] - 1.0);
                }
            }

            return(overlap);
        }
Пример #16
0
            public static CPsfgen Psfgen
                (IList <Tuple <string, string, Pdb.IAtom[]> > lstSegFileAtoms // segname, filename, pdbatoms
                , string tempbase                                             //=null
                , string parameters                                           //=null
                , string namdversion                                          //="2.8"
                , IList <string> infiles
                , IList <string> outfiles
                , string topology
                , IList <string> psfgen_lines = null
                , string psfgen_workdir       = null
                , HOptions options            = null
                )
            {
                if (options == null)
                {
                    options = new HOptions((string)null);
                }
                Dictionary <System.IO.FileInfo, string[]> infile_lines = new Dictionary <System.IO.FileInfo, string[]>();

                foreach (string infile in infiles)
                {
                    infile_lines.Add(HFile.GetFileInfo(infile), HFile.ReadAllLines(infile));
                }

                string currpath = HEnvironment.CurrentDirectory;

                System.IO.DirectoryInfo tmpdir = null;
                if (psfgen_workdir != null)
                {
                    HEnvironment.CurrentDirectory = psfgen_workdir;
                }
                else
                {
                    tmpdir = HDirectory.CreateTempDirectory(tempbase);
                    HEnvironment.CurrentDirectory = tmpdir.FullName;
                }

                string[] lines = null;
                if ((psfgen_lines != null) && (psfgen_lines.Count > 0))
                {
                    lines = psfgen_lines.ToArray();
                }
                else
                {
                    lines = GetPsfgenLines
                                (custom_pdbalias: null
                                , custom_patches: null
                                );
                }

                if (topology != null)
                {
                    lines = lines.ToArray().HReplace("$topology$", topology);
                }

                List <string> psf_lines;
                List <string> pdb_lines;

                {
                    {
                        //foreach(var respath_filename in GetResourcePaths("2.8", "psfgen"))
                        foreach (var respath_filename in GetResourcePaths(namdversion, "psfgen"))
                        {
                            string respath  = respath_filename.Item1;
                            string filename = respath_filename.Item2;
                            HResource.CopyResourceTo <Tinker>(respath, filename);
                        }
                    }

                    //  Dictionary<string, Tuple<string, Pdb.IAtom[]>> segname_filename_pdbatoms = new Dictionary<string, Tuple<string, Pdb.IAtom[]>>();
                    //  //if(pdbs.Length != 1) throw new ArgumentException();
                    //  for(int i=0; i<lstSegFilePdb.Count; i++)
                    //  {
                    //      string  segnameprefix = lstSegFilePdb[i].Item1; if( segnameprefix == null)  segnameprefix = string.Format("{0:00}", i);
                    //      string filenameprefix = lstSegFilePdb[i].Item2; if(filenameprefix == null) filenameprefix = string.Format("{0:00}", i);
                    //      Pdb    pdb            = lstSegFilePdb[i].Item3;
                    //      List<Pdb.IAtom> pdb_atoms = new List<Pdb.IAtom>();
                    //      pdb_atoms.AddRange(pdb.atoms);
                    //      pdb_atoms.AddRange(pdb.hetatms);
                    //      char[] chains = pdb_atoms.ListChainID().HToHashSet().ToArray();
                    //
                    //      HDebug.AssertIf(chains.Length> 1, segnameprefix.Length <= 5);
                    //      HDebug.AssertIf(chains.Length<=1, segnameprefix.Length <= 6);
                    //      foreach(char chain in chains)
                    //      {
                    //          Pdb.IAtom[] chain_atoms = pdb_atoms.SelectByChainID(chain).SelectByAltLoc().ToArray();
                    //          string suffix = null;
                    //          if(('a' <= chain) && (chain <= 'z')) suffix = string.Format("L{0}", chain);
                    //          if(('A' <= chain) && (chain <= 'Z')) suffix = string.Format("U{0}", chain);
                    //          if(('0' <= chain) && (chain <= '9')) suffix = string.Format("N{0}", chain);
                    //          string  segname =  segnameprefix + ((chains.Length <= 1) ? "" : suffix);
                    //          string filename = filenameprefix + ((chains.Length <= 1) ? "" : suffix);
                    //          segname_filename_pdbatoms.Add(segname, new Tuple<string,Pdb.IAtom[]>(filename, chain_atoms));
                    //      }
                    //  }

                    foreach (var finfo_line in infile_lines)
                    {
                        string   inname  = finfo_line.Key.Name;
                        string[] inlines = finfo_line.Value;
                        HFile.WriteAllLines(inname, inlines);
                    }

                    HashSet <string> segnames = new HashSet <string>();
                    int segindex = 0;
                    foreach (var seg_file_atoms in lstSegFileAtoms)
                    {
                        string      segname     = seg_file_atoms.Item1;
                        string      filename    = seg_file_atoms.Item2;
                        Pdb.IAtom[] chain_atoms = seg_file_atoms.Item3.SelectByAltLoc().ToArray();
                        HDebug.Exception(chain_atoms.ListChainID().HToHashSet().Count == 1);
                        if (segname == null)
                        {
                            while (segindex <= 9999)
                            {
                                if (segnames.Contains(segindex.ToString()) == false)
                                {
                                    segname = segindex.ToString();
                                    segnames.Add(segname);
                                    break;
                                }
                                segindex++;
                            }
                        }
                        if (filename == null)
                        {
                            filename = segname;
                        }

                        Pdb.ToFile
                            (filename + ".pdb"
                            , chain_atoms.HToType <Pdb.IAtom, Pdb.Element>()
                            , false
                            );

                        for (int i = 0; i < lines.Length; i++)
                        {
                            if (lines[i].Contains("$segname$"))
                            {
                                string insert = lines[i];
                                insert = insert.Replace("$segname$", segname);
                                insert = insert.Replace("$segfilename$", filename);
                                lines  = lines.HInsert(i, insert);
                                i++;
                            }
                        }
                    }

                    lines = lines.HRemoveAllContains("$segname$");

                    HFile.WriteAllLines("prot.inp", lines);
                    string command0 = string.Format("psfgen < prot.inp");
                    bool   pause    = options.Contains("psfgen pause");
                    HProcess.StartAsBatchInConsole(null, pause, command0);

                    psf_lines = System.IO.File.ReadLines("prot.psf").ToList();
                    pdb_lines = System.IO.File.ReadLines("prot.pdb").ToList();
                }
                HEnvironment.CurrentDirectory = currpath;
                if (tmpdir != null)
                {
                    try{ tmpdir.Delete(true); } catch {}
                }

                return(new CPsfgen
                {
                    psf_lines = psf_lines,
                    pdb_lines = pdb_lines,
                });
            }
Пример #17
0
        public static CPsfgenExt PsfgenExt
            (IList <Tuple <string, string, Pdb.IAtom[]> > lstSegFileAtoms
            , string[] toplines
            , string[] parlines
            , Pdb alignto
            , string[] psfgen_lines
            , IList <string> minimize_conf_lines = null
            , HOptions options = null
            )
        {
            if (options == null)
            {
                options = new HOptions((string)null);
            }
            string tempbase       = @"C:\temp\";
            string psfgen_workdir = null;
            string topname        = "prot.top";
            string parname        = "prot.par";

            List <string> psf_lines = null;
            List <string> pdb_lines = null;

            using (var temp = new HTempDirectory(tempbase, null))
            {
                temp.EnterTemp();

                HFile.WriteAllLines(topname, toplines);
                HFile.WriteAllLines(parname, parlines);

                if ((HFile.Exists("prot.pdb") == false) || (HFile.Exists("prot.psf") == false))
                {
                    var psfgen = Namd.RunPsfgen
                                     (lstSegFileAtoms, tempbase, null, "2.10"
                                     , new string[] { topname }
                                     , new string[] {}
                                     , topname
                                     , psfgen_lines: psfgen_lines
                                     , psfgen_workdir: psfgen_workdir
                                     , options: options
                                     );

                    psf_lines = psfgen.psf_lines;
                    pdb_lines = psfgen.pdb_lines;
                    if (alignto != null)
                    {
                        HDebug.Exception("check!!!");
                        ////////////////////////////
                        Pdb prot = Pdb.FromLines(pdb_lines);
                        prot      = PsfgenExt_AlignTo(prot, alignto);
                        pdb_lines = prot.ToLines().ToList();
                    }
                    HFile.WriteAllLines("prot.pdb", pdb_lines);
                    HFile.WriteAllLines("prot.psf", psf_lines);
                }

                if (options.Contains("nomin") == false)
                {
                    if ((HFile.Exists("protmin.coor") == false) || (HFile.Exists("protmin.pdb") == false))
                    {
                        List <string> psfgen_pdb_lines = System.IO.File.ReadLines("prot.pdb").ToList();
                        List <string> psfgen_psf_lines = System.IO.File.ReadLines("prot.psf").ToList();

                        List <string> prm_lines = System.IO.File.ReadLines(parname).ToList();
                        string        Namd2_opt = null;
                        if (options.HSelectStartsWith("minimize option:").Length >= 1)
                        {
                            Namd2_opt = options.HSelectStartsWith("minimize option:").First().Replace("minimize option:", "");
                        }
                        var minpdb = Namd.Run.Namd2
                                         (psfgen_pdb_lines
                                         , psfgen_psf_lines
                                         , prm_lines
                                         , tempbase
                                         , "2.10"
                                         , ((Namd2_opt == null) ? "+p3" : Namd2_opt)
                                         , conf_lines: minimize_conf_lines
                                         );
                        HFile.WriteAllLines("protmin.coor", minpdb.coor_lines);

                        Pdb prot0 = Pdb.FromLines(psfgen_pdb_lines);
                        Pdb prot1 = Pdb.FromLines(minpdb.coor_lines);
                        HDebug.Exception(prot0.atoms.Length == prot1.atoms.Length);
                        HDebug.Exception(prot0.elements.Length == prot1.elements.Length);
                        // update conformation to minimized conformation
                        for (int i = 0; i < prot0.elements.Length; i++)
                        {
                            if (prot0.elements[i].GetType() != prot1.elements[i].GetType())
                            {
                                throw new HException("prot0.elements[i].GetType() != prot1.elements[i].GetType()");
                            }
                            if ((prot0.elements[i] is Pdb.IAtom) == false)
                            {
                                continue;
                            }
                            Pdb.IAtom iatom0 = prot0.elements[i] as Pdb.IAtom;
                            Pdb.IAtom iatom1 = prot1.elements[i] as Pdb.IAtom;
                            Vector    coord0 = iatom0.coord;
                            Vector    coord1 = iatom1.coord;
                            double    dist   = (coord0 - coord1).Dist;
                            if (iatom0.occupancy != 0)
                            {
                                if (dist != 0)
                                {
                                    throw new HException("iatom0.coord - iatom1.coord != 0");
                                }
                            }
                            if (dist != 0)
                            {
                                if (iatom0 is Pdb.Atom)
                                {
                                    string   nline0 = (iatom0 as Pdb.Atom).GetUpdatedLine(coord1);
                                    Pdb.Atom natom0 = Pdb.Atom.FromString(nline0);
                                    prot0.elements[i] = natom0;
                                    continue;
                                }
                                if (iatom0 is Pdb.Hetatm)
                                {
                                    string     nline0 = (iatom0 as Pdb.Hetatm).GetUpdatedLine(coord1);
                                    Pdb.Hetatm natom0 = Pdb.Hetatm.FromString(nline0);
                                    prot0.elements[i] = natom0;
                                    continue;
                                }
                            }
                        }
                        if ((prot0.elements[0] is Pdb.Remark) && (prot1.elements[0] is Pdb.Remark))
                        {
                            prot0.elements[0] = Pdb.Remark.FromString(prot1.elements[0].line);
                        }
                        prot0.ToFile("protmin.pdb");
                        pdb_lines = System.IO.File.ReadLines("protmin.pdb").ToList();
                    }
                }

                //{
                //    Pdb confpdb = GetConfPdb(options);
                //    var psf    = Namd.Psf.FromFile("prot.psf");
                //    var prm    = Namd.Prm.FromFile(parname);
                //    List<string> log = new List<string>();
                //    Universe  univ = Universe.BuilderNamd.Build(psf, prm, confpdb, true, new TextLogger(log));
                //    return univ;
                //}
                temp.QuitTemp();
            }

            return(new CPsfgenExt
            {
                psflines = psf_lines,
                pdblines = pdb_lines,
            });
        }
Пример #18
0
            public static Vector[] ToOrthonormal(Vector[] coords, double[] masses, int[] block, Vector[] PBlk)
            {
                if (HDebug.IsDebuggerAttached)
                #region check if elements in non-block are zeros.
                {
                    int leng = coords.Length;
                    foreach (int i in HEnum.HEnumCount(leng).HEnumExcept(block.HToHashSet()))
                    {
                        for (int r = 0; r < PBlk.Length; r++)
                        {
                            int c0 = i * 3;
                            HDebug.Assert(PBlk[r][c0 + 0] == 0);
                            HDebug.Assert(PBlk[r][c0 + 1] == 0);
                            HDebug.Assert(PBlk[r][c0 + 2] == 0);
                        }
                    }
                }
                #endregion

                Matrix Pmat = new double[block.Length * 3, PBlk.Length];
                for (int r = 0; r < PBlk.Length; r++)
                {
                    for (int i = 0; i < block.Length; i++)
                    {
                        int i0 = i * 3;
                        int c0 = block[i] * 3;
                        Pmat[i0 + 0, r] = PBlk[r][c0 + 0];
                        Pmat[i0 + 1, r] = PBlk[r][c0 + 1];
                        Pmat[i0 + 2, r] = PBlk[r][c0 + 2];
                    }
                }

                using (new Matlab.NamedLock(""))
                {
                    Matlab.PutValue("n", PBlk.Length);
                    Matlab.PutMatrix("P", Pmat);
                    Matlab.Execute("[U,S,V] = svd(P);");
                    Matlab.Execute("U = U(:,1:n);");
                    if (HDebug.IsDebuggerAttached)
                    {
                        Matlab.Execute("SV = S(1:n,1:n)*V';");
                        double err = Matlab.GetValue("max(max(abs(P - U*SV)))");
                        HDebug.Assert(Math.Abs(err) < 0.00000001);
                    }
                    Pmat = Matlab.GetMatrix("U");
                }

                Vector[] PBlkOrth = new Vector[PBlk.Length];
                for (int r = 0; r < PBlk.Length; r++)
                {
                    Vector PBlkOrth_r = new double[PBlk[r].Size];
                    for (int i = 0; i < block.Length; i++)
                    {
                        int i0 = i * 3;
                        int c0 = block[i] * 3;
                        PBlkOrth_r[c0 + 0] = Pmat[i0 + 0, r];
                        PBlkOrth_r[c0 + 1] = Pmat[i0 + 1, r];
                        PBlkOrth_r[c0 + 2] = Pmat[i0 + 2, r];
                    }
                    PBlkOrth[r] = PBlkOrth_r;
                }

                if (HDebug.IsDebuggerAttached)
                #region checi the orthonormal condition, and rot/trans condition (using ANM)
                {
                    {   // check if all trans/rot modes are orthonormal
                        for (int i = 0; i < PBlkOrth.Length; i++)
                        {
                            HDebug.Exception(Math.Abs(PBlkOrth[i].Dist - 1) < 0.00000001);
                            for (int j = i + 1; j < PBlkOrth.Length; j++)
                            {
                                double dot = LinAlg.VtV(PBlkOrth[i], PBlkOrth[j]);
                                HDebug.Exception(Math.Abs(dot) < 0.00000001);
                            }
                        }
                    }
                    {   // check if this is true rot/trans modes using ANM
                        Vector[] anmcoords = coords.HClone();
                        int      leng      = coords.Length;
                        foreach (int i in HEnum.HEnumCount(leng).HEnumExcept(block.HToHashSet()))
                        {
                            anmcoords[i] = null;
                        }
                        HessMatrix H = GetHessAnm(anmcoords, 100);
                        Matrix     PHP;
                        using (new Matlab.NamedLock(""))
                        {
                            Matlab.PutSparseMatrix("H", H.GetMatrixSparse(), 3, 3);
                            Matlab.PutMatrix("P", PBlkOrth.ToMatrix(true));
                            PHP = Matlab.GetMatrix("P'*H*P");
                        }
                        double maxerr = PHP.HAbsMax();
                        HDebug.Exception(Math.Abs(maxerr) < 0.00000001);
                    }
                }
                #endregion

                return(PBlkOrth);
            }
Пример #19
0
            public static HessRTB GetHessRTB(HessMatrix hess, Vector[] coords, double[] masses, IList <int[]> blocks, string opt)
            {
                #region check pre-condition
                {
                    HDebug.Assert(coords.Length == hess.ColBlockSize);                      // check hess matrix
                    HDebug.Assert(coords.Length == hess.RowBlockSize);                      // check hess matrix
                    HDebug.Assert(coords.Length == blocks.HMerge().HToHashSet().Count);     // check hess contains all blocks
                    HDebug.Assert(coords.Length == blocks.HMerge().Count);                  // no duplicated index in blocks
                }
                #endregion

                List <Vector> Ps = new List <Vector>();
                foreach (int[] block in blocks)
                {
                    List <Vector> PBlk = new List <Vector>();
                    switch (opt)
                    {
                    case "v1":
                        // GetRotate is incorrect
                        PBlk.AddRange(GetTrans(coords, masses, block));
                        PBlk.AddRange(GetRotate(coords, masses, block));
                        break;

                    case "v2":
                        PBlk.AddRange(GetRotTran(coords, masses, block));
                        break;

                    case null:
                        goto case "v2";
                    }
                    {
                        // PBlk = ToOrthonormal   (coords, masses, block, PBlk.ToArray()).ToList();
                        ///
                        ///     Effect of making orthonormal is not significant as below table, but consumes time by calling SVD
                        ///     Therefore, skip making orthonormal
                        ///     =========================================================================================================================================================
                        ///     model   | making orthonormal?|             | MSF corr   , check sparsity              , overlap weighted by eigval : overlap of mode 1-1, 2-2, 3-3, ...
                        ///     =========================================================================================================================================================
                        ///     NMA     | orthonormal by SVD | RTB         | corr 0.9234, spcty(all    NaN, ca    NaN), wovlp 0.5911 : 0.82,0.79,0.74,0.69,0.66,0.63,0.60,0.59,0.56,0.54)
                        ///             | orthogonal         | RTB         | corr 0.9230, spcty(all    NaN, ca    NaN), wovlp 0.5973 : 0.83,0.80,0.75,0.70,0.67,0.64,0.60,0.59,0.58,0.55)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     scrnNMA | orthonormal by SVD | RTB         | corr 0.9245, spcty(all    NaN, ca    NaN), wovlp 0.5794 : 0.83,0.78,0.73,0.68,0.65,0.62,0.60,0.58,0.55,0.55)
                        ///             | orthogonal         | RTB         | corr 0.9243, spcty(all    NaN, ca    NaN), wovlp 0.5844 : 0.83,0.78,0.73,0.68,0.66,0.62,0.60,0.58,0.55,0.55)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     sbNMA   | orthonormal by SVD | RTB         | corr 0.9777, spcty(all    NaN, ca    NaN), wovlp 0.6065 : 0.93,0.89,0.86,0.81,0.75,0.71,0.69,0.66,0.63,0.62)
                        ///             | orthogonal         | RTB         | corr 0.9776, spcty(all    NaN, ca    NaN), wovlp 0.6175 : 0.94,0.90,0.87,0.82,0.76,0.73,0.71,0.69,0.66,0.63)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     ssNMA   | orthonormal by SVD | RTB         | corr 0.9677, spcty(all    NaN, ca    NaN), wovlp 0.5993 : 0.92,0.87,0.83,0.77,0.72,0.69,0.66,0.63,0.60,0.59)
                        ///             | orthogonal         | RTB         | corr 0.9675, spcty(all    NaN, ca    NaN), wovlp 0.6076 : 0.92,0.88,0.84,0.78,0.73,0.70,0.67,0.64,0.62,0.60)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     eANM    | orthonormal by SVD | RTB         | corr 0.9870, spcty(all    NaN, ca    NaN), wovlp 0.5906 : 0.95,0.91,0.87,0.83,0.77,0.73,0.71,0.68,0.66,0.61)
                        ///             | orthogonal         | RTB         | corr 0.9869, spcty(all    NaN, ca    NaN), wovlp 0.6014 : 0.95,0.92,0.88,0.84,0.78,0.74,0.73,0.70,0.67,0.65)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     AA-ANM  | orthonormal by SVD | RTB         | corr 0.9593, spcty(all    NaN, ca    NaN), wovlp 0.4140 : 0.94,0.90,0.85,0.78,0.74,0.72,0.66,0.64,0.61,0.61)
                        ///             | orthogonal         | RTB         | corr 0.9589, spcty(all    NaN, ca    NaN), wovlp 0.4204 : 0.94,0.91,0.85,0.80,0.76,0.73,0.68,0.66,0.63,0.61)
                    }
                    Ps.AddRange(PBlk);
                }

                Matrix P = Matrix.FromColVectorList(Ps);

                Matrix PHP;
                Matrix PMP;
                using (new Matlab.NamedLock(""))
                {
                    if (hess is HessMatrixSparse)
                    {
                        Matlab.PutSparseMatrix("H", hess.GetMatrixSparse(), 3, 3);
                    }
                    else if (hess is HessMatrixDense)
                    {
                        Matlab.PutMatrix("H", hess, true);
                    }
                    else
                    {
                        HDebug.Exception();
                    }
                    Matlab.PutMatrix("P", P, true);
                    Matlab.PutVector("M", masses);
                    Matlab.Execute("M=diag(reshape([M,M,M]',length(M)*3,1));");
                    Matlab.Execute("PHP = P'*H*P; PHP = (PHP + PHP')/2;");
                    Matlab.Execute("PMP = P'*M*P; PMP = (PMP + PMP')/2;");
                    PHP = Matlab.GetMatrix("PHP", true);
                    PMP = Matlab.GetMatrix("PMP", true);
                }

                return(new HessRTB
                {
                    hess = hess,
                    coords = coords,
                    masses = masses,
                    blocks = blocks,
                    P = P,
                    PHP = PHP,
                    PMP = PMP,
                });
            }
Пример #20
0
            public static string LineFromData(string RecordName, int serial, string name, string resName, char chainID, int resSeq, double x, double y, double z, char?altLoc = null, char?iCode = null, double?occupancy = null, double?tempFactor = null, string element = null, string charge = null, string segment = null)
            {
                HDebug.Assert(0 <= serial, serial <= 99999);    //  7 - 11        Integer       serial       Atom  serial number.       => 00000-99999
                HDebug.Assert(0 <= resSeq, resSeq <= 9999);     // 23 - 26        Integer       resSeq       Residue sequence number.   =>  0000- 9999
                string _serial     = StringFormat("            {0}", serial); _serial = _serial.HSubEndStringCount(1 + idxs_serial    [1] - idxs_serial    [0]);
                string _name       = StringFormat("{0}            ", name); _name = _name.Substring(0, 1 + idxs_name      [1] - idxs_name      [0]);
                string _altLoc     = StringFormat("{0}            ", altLoc); _altLoc = _altLoc.Substring(0, 1 + idxs_altLoc    [1] - idxs_altLoc    [0]);
                string _resName    = StringFormat("{0}            ", resName); _resName = _resName.Substring(0, 1 + idxs_resName   [1] - idxs_resName   [0]);
                string _chainID    = StringFormat("{0}            ", chainID); _chainID = _chainID.Substring(0, 1 + idxs_chainID   [1] - idxs_chainID   [0]);
                string _resSeq     = StringFormat("            {0}", resSeq); _resSeq = _resSeq.HSubEndStringCount(1 + idxs_resSeq    [1] - idxs_resSeq    [0]);
                string _iCode      = StringFormat("{0}            ", iCode); _iCode = _iCode.Substring(0, 1 + idxs_iCode     [1] - idxs_iCode     [0]);
                string _x          = StringFormat("      {0:0.000}", x); _x = _x.HSubEndStringCount(1 + idxs_x         [1] - idxs_x         [0]);
                string _y          = StringFormat("      {0:0.000}", y); _y = _y.HSubEndStringCount(1 + idxs_y         [1] - idxs_y         [0]);
                string _z          = StringFormat("      {0:0.000}", z); _z = _z.HSubEndStringCount(1 + idxs_z         [1] - idxs_z         [0]);
                string _occupancy  = StringFormat("       {0:0.00}", occupancy); _occupancy = _occupancy.HSubEndStringCount(1 + idxs_occupancy [1] - idxs_occupancy [0]);
                string _tempFactor = StringFormat("       {0:0.00}", tempFactor); _tempFactor = _tempFactor.HSubEndStringCount(1 + idxs_tempFactor[1] - idxs_tempFactor[0]);
                string _segment    = StringFormat("{0,4}", segment); _segment = _segment.Substring(0, 1 + idxs_segment   [1] - idxs_segment   [0]);
                string _element    = StringFormat("{0}            ", element); _element = _element.Substring(0, 1 + idxs_element   [1] - idxs_element   [0]);
                string _charge     = StringFormat("{0}            ", charge); _charge = _charge.Substring(0, 1 + idxs_charge    [1] - idxs_charge    [0]);

                HDebug.Exception(RecordName.Length == 6);
                char[] chars = "RECORD__________________________________________________________________________"
                               .Replace("RECORD", RecordName)
                               .ToArray();
                for (int i = 0; i < _serial.Length; i++)
                {
                    int idx = idxs_serial    [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _serial    [i];
                }
                for (int i = 0; i < _name.Length; i++)
                {
                    int idx = idxs_name      [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _name      [i];
                }
                for (int i = 0; i < _altLoc.Length; i++)
                {
                    int idx = idxs_altLoc    [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _altLoc    [i];
                }
                for (int i = 0; i < _resName.Length; i++)
                {
                    int idx = idxs_resName   [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _resName   [i];
                }
                for (int i = 0; i < _chainID.Length; i++)
                {
                    int idx = idxs_chainID   [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _chainID   [i];
                }
                for (int i = 0; i < _resSeq.Length; i++)
                {
                    int idx = idxs_resSeq    [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _resSeq    [i];
                }
                for (int i = 0; i < _iCode.Length; i++)
                {
                    int idx = idxs_iCode     [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _iCode     [i];
                }
                for (int i = 0; i < _x.Length; i++)
                {
                    int idx = idxs_x         [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _x         [i];
                }
                for (int i = 0; i < _y.Length; i++)
                {
                    int idx = idxs_y         [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _y         [i];
                }
                for (int i = 0; i < _z.Length; i++)
                {
                    int idx = idxs_z         [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _z         [i];
                }
                for (int i = 0; i < _occupancy.Length; i++)
                {
                    int idx = idxs_occupancy [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _occupancy [i];
                }
                for (int i = 0; i < _tempFactor.Length; i++)
                {
                    int idx = idxs_tempFactor[0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _tempFactor[i];
                }
                for (int i = 0; i < _segment.Length; i++)
                {
                    int idx = idxs_segment   [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _segment   [i];
                }
                for (int i = 0; i < _element.Length; i++)
                {
                    int idx = idxs_element   [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _element   [i];
                }
                for (int i = 0; i < _charge.Length; i++)
                {
                    int idx = idxs_charge    [0] - 1 + i; HDebug.Assert(chars[idx] == '_'); chars[idx] = _charge    [i];
                }
                string line = (new string(chars)).Replace('_', ' ');

                return(line);
            }
Пример #21
0
            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));
            }
Пример #22
0
            public static void SelfTest(string pdbname, string psfname, string prmname, string xyzname)
            {
                using (var temp = new HTempDirectory(@"C:\temp\", null))
                {
                    temp.EnterTemp();
                    {
                        string resbase = "HTLib2.Bioinfo.HTLib2.Bioinfo.External.Tinker.Resources.selftest.";
                        HResource.CopyResourceTo <Tinker>(resbase + pdbname, pdbname);
                        HResource.CopyResourceTo <Tinker>(resbase + psfname, psfname);
                        HResource.CopyResourceTo <Tinker>(resbase + "par_all27_prot_lipid.inp", prmname);
                        if (xyzname != null)
                        {
                            HResource.CopyResourceTo <Tinker>(resbase + xyzname, xyzname);
                        }
                        HResource.CopyResourceTo <Tinker>(resbase + "charmm22.prm", "charmm22.prm");

                        {
                            var pdb = Pdb.FromFile(pdbname);
                            var psf = Namd.Psf.FromFile(psfname);
                            var prm = Namd.Prm.FromFile(prmname);

                            var xyz_prm = BuildFromNamd(pdb, psf, prm);
                            xyz_prm.Item1.ToFile("TinkFromNamd.xyz", false);
                            xyz_prm.Item2.ToFile("TinkFromNamd.prm");
                        }

                        if (xyzname != null)
                        {
                            var xyz0  = Xyz.FromFile("TinkFromNamd.xyz", false);
                            var prm0  = Prm.FromFile("TinkFromNamd.prm");
                            var grad0 = Run.Testgrad(xyz0, prm0, @"C:\temp\"
                                                     //, "VDWTERM     NONE"
                                                     //, "CHARGETERM  NONE"
                                                     //, "BONDTERM    NONE"
                                                     //, "ANGLETERM   NONE"
                                                     //, "UREYTERM    NONE"
                                                     //, "IMPROPTERM  NONE"
                                                     //, "TORSIONTERM NONE"
                                                     );
                            var forc0 = grad0.anlyts.GetForces(xyz0.atoms);

                            var xyz1  = Xyz.FromFile(xyzname, false);
                            var prm1  = Prm.FromFile("charmm22.prm");
                            var grad1 = Run.Testgrad(xyz1, prm1, @"C:\temp\"
                                                     //, "VDWTERM     NONE"
                                                     //, "CHARGETERM  NONE"
                                                     //, "BONDTERM    NONE"
                                                     //, "ANGLETERM   NONE"
                                                     //, "UREYTERM    NONE"
                                                     //, "IMPROPTERM  NONE"
                                                     //, "TORSIONTERM NONE"
                                                     );
                            var forc1 = grad1.anlyts.GetForces(xyz1.atoms);
                            {
                                KDTree.KDTree <object> kdtree = new KDTree.KDTree <object>(3);
                                var atoms0 = xyz0.atoms;
                                for (int i = 0; i < atoms0.Length; i++)
                                {
                                    kdtree.insert(atoms0[i].Coord, i);
                                }
                                var   atoms1  = xyz1.atoms;
                                int[] idx1to0 = new int[atoms1.Length];
                                for (int i1 = 0; i1 < atoms1.Length; i1++)
                                {
                                    Vector coord1 = atoms1[i1].Coord;
                                    int    i0     = (int)kdtree.nearest(coord1);
                                    Vector coord0 = atoms0[i0].Coord;
                                    kdtree.delete(coord0);
                                    idx1to0[i0] = i1;
                                }
                                atoms1 = atoms1.HSelectByIndex(idx1to0);
                                forc1  = forc1.HSelectByIndex(idx1to0);
                            }

                            Vector[] dforc     = VectorBlock.PwSub(forc0, forc1).ToArray();
                            double[] dforcl    = dforc.Dist();
                            double   max_dforc = dforc.Dist().Max();
                            HDebug.Exception(max_dforc < 1);       // 0.72682794387667848

                            {
                                double EB   = Math.Abs(grad0.enrgCmpnt.EB - grad1.enrgCmpnt.EB);    HDebug.Exception(EB < 0.1);
                                double EA   = Math.Abs(grad0.enrgCmpnt.EA - grad1.enrgCmpnt.EA);    HDebug.Exception(EA < 0.1);
                                double EBA  = Math.Abs(grad0.enrgCmpnt.EBA - grad1.enrgCmpnt.EBA);    HDebug.Exception(EBA < 0.1);
                                double EUB  = Math.Abs(grad0.enrgCmpnt.EUB - grad1.enrgCmpnt.EUB);    HDebug.Exception(EUB < 0.1);
                                double EAA  = Math.Abs(grad0.enrgCmpnt.EAA - grad1.enrgCmpnt.EAA);    HDebug.Exception(EAA < 0.1);
                                double EOPB = Math.Abs(grad0.enrgCmpnt.EOPB - grad1.enrgCmpnt.EOPB);    HDebug.Exception(EOPB < 0.1);
                                double EOPD = Math.Abs(grad0.enrgCmpnt.EOPD - grad1.enrgCmpnt.EOPD);    HDebug.Exception(EOPD < 0.1);
                                double EID  = Math.Abs(grad0.enrgCmpnt.EID - grad1.enrgCmpnt.EID);    HDebug.Exception(EID < 0.1);          // 0.0019000000000000128 : N-terminus (and C-terminus) information is/are inconsistent betweeen namd-charmm and tink-charmm22
                                double EIT  = Math.Abs(grad0.enrgCmpnt.EIT - grad1.enrgCmpnt.EIT);    HDebug.Exception(EIT < 0.1);
                                double ET   = Math.Abs(grad0.enrgCmpnt.ET - grad1.enrgCmpnt.ET);    HDebug.Exception(ET < 0.5);             // 0.33029999999999404   : N-terminus (and C-terminus) information is/are inconsistent betweeen namd-charmm and tink-charmm22
                                double EPT  = Math.Abs(grad0.enrgCmpnt.EPT - grad1.enrgCmpnt.EPT);    HDebug.Exception(EPT < 0.1);
                                double EBT  = Math.Abs(grad0.enrgCmpnt.EBT - grad1.enrgCmpnt.EBT);    HDebug.Exception(EBT < 0.1);
                                double ETT  = Math.Abs(grad0.enrgCmpnt.ETT - grad1.enrgCmpnt.ETT);    HDebug.Exception(ETT < 0.1);
                                double EV   = Math.Abs(grad0.enrgCmpnt.EV - grad1.enrgCmpnt.EV);    HDebug.Exception(EV < 0.1);
                                double EC   = Math.Abs(grad0.enrgCmpnt.EC - grad1.enrgCmpnt.EC);    HDebug.Exception(EC < 0.5);             // 0.37830000000002428
                                double ECD  = Math.Abs(grad0.enrgCmpnt.ECD - grad1.enrgCmpnt.ECD);    HDebug.Exception(ECD < 0.1);
                                double ED   = Math.Abs(grad0.enrgCmpnt.ED - grad1.enrgCmpnt.ED);    HDebug.Exception(ED < 0.1);
                                double EM   = Math.Abs(grad0.enrgCmpnt.EM - grad1.enrgCmpnt.EM);    HDebug.Exception(EM < 0.1);
                                double EP   = Math.Abs(grad0.enrgCmpnt.EP - grad1.enrgCmpnt.EP);    HDebug.Exception(EP < 0.1);
                                double ER   = Math.Abs(grad0.enrgCmpnt.ER - grad1.enrgCmpnt.ER);    HDebug.Exception(ER < 0.1);
                                double ES   = Math.Abs(grad0.enrgCmpnt.ES - grad1.enrgCmpnt.ES);    HDebug.Exception(ES < 0.1);
                                double ELF  = Math.Abs(grad0.enrgCmpnt.ELF - grad1.enrgCmpnt.ELF);    HDebug.Exception(ELF < 0.1);
                                double EG   = Math.Abs(grad0.enrgCmpnt.EG - grad1.enrgCmpnt.EG);    HDebug.Exception(EG < 0.1);
                                double EX   = Math.Abs(grad0.enrgCmpnt.EX - grad1.enrgCmpnt.EX);    HDebug.Exception(EX < 0.1);
                            }
                        }
                    }
                    temp.QuitTemp();
                }

                //{
                //    //string pathbase = @"C:\Users\htna.IASTATE\svn\htnasvn_htna\Research.bioinfo.prog.NAMD\1A6G\New folder\";
                //    string pathbase = @"C:\Users\htna.IASTATE\svn\htnasvn_htna\Research.bioinfo.prog.NAMD\1A6G\";
                //    string toplbase = @"C:\Users\htna.IASTATE\svn\htnasvn_htna\Research.bioinfo.prog.NAMD\top_all27_prot_lipid\";
                //    var pdb = Pdb     .FromFile(pathbase+"1A6G.psfgen.pdb");
                //    var psf = Namd.Psf.FromFile(pathbase+"1A6G.psfgen.psf");
                //    var prm = Namd.Prm.FromFile(toplbase+"par_all27_prot_na.prm");
                //
                //        pdb = Pdb     .FromFile(@"K:\Tim-8TIM,1TPH,1M6J\Tim-1M6J\1M6J.psfgen.pdb");
                //        psf = Namd.Psf.FromFile(@"K:\Tim-8TIM,1TPH,1M6J\Tim-1M6J\1M6J.psfgen.psf");
                //        prm = Namd.Prm.FromFile(@"K:\Tim-8TIM,1TPH,1M6J\Tim-1M6J\par_all27_prot_lipid.inp");
                //    var xyz_prm = BuildFromNamd(pdb, psf, prm);
                //    xyz_prm.Item1.ToFile(@"C:\temp\TinkFromNamd.xyz", false);
                //    xyz_prm.Item2.ToFile(@"C:\temp\TinkFromNamd.prm");
                //}
            }
            public static Tuple <int[], int[][]> GetIdxKeepListRemv_ResiCluster2(Universe.Atom[] atoms, Vector[] coords, double clus_width, int num_atom_merge, IList <Universe.Atom> keeps)
            {
                /// 1. group atoms (by residues) by blocks, whose dimensions are 18A
                ///    a. group atoms by residues
                ///    c. group residues whose Ca atoms are in a same block
                /// 2. sort blocks by its atom numbers
                ///    ex) 1,1,1,1,1, 1,1,2, 2,2, 2,3, 3, 3, 4, 4, 5
                /// 3. merge blocks into groups using threshold (500 atoms)
                ///    ex) [1,1,1,1,1], [1,1,2], [2,2], [2,3], [3], [3], [4], [4], [5]
                /// 4. reverse groups
                ///    ex) [5], [4], [4], [3], [3], [2,3], [2,2], [1,1,2], [1,1,1,1,1]
                /// 5. delete groups by the order of
                ///          9    8    7    6    5    4      3      2        1

                List <Universe.Atom> lkeeps = new List <Universe.Atom>();

                foreach (var keep in keeps)
                {
                    if (coords[keep.ID] != null)
                    {
                        lkeeps.Add(keep);
                    }
                }

                List <Universe.Atom[]> resis = atoms.GroupByResidue();

                Tuple <Universe.Atom[], Universe.Atom[]>[] resi_keeps_others = resis.HSplitByMatches(lkeeps.HToHashSet()).HToTuple();

                Dictionary <Tuple <int, int, int>, List <Tuple <Universe.Atom[], Universe.Atom[]> > > clus_key_resis;

                clus_key_resis = GetIdxKeepListRemv_GetClusters(atoms, coords, clus_width, resi_keeps_others);

                List <List <Tuple <Universe.Atom[], Universe.Atom[]> > > clus_resis;
                List <int> numresi;
                List <int> numatom;

                {
                    // determine #residues and #atoms in each block
                    clus_resis = clus_key_resis.Values.ToList();    // clusters(resis/CAs, residue atoms)
                    numresi    = clus_resis.HListCount().ToList();  // number of resis
                    numatom    = new List <int>();                  // number of atoms
                    {
                        foreach (var cresis in clus_resis)
                        {
                            IList <Universe.Atom[]> lresis = cresis.HListItem2();
                            var lnumatoms = lresis.HListCount();
                            numatom.Add(lnumatoms.Sum());
                        }
                    }

                    bool merge = true;
                    if (merge)
                    {
                        // sort by atom number
                        int[] idxsrt = numatom.HIdxSorted();
                        clus_resis = clus_resis.HSelectByIndex(idxsrt).ToList();
                        numresi    = numresi.HSelectByIndex(idxsrt).ToList();
                        numatom    = numatom.HSelectByIndex(idxsrt).ToList();

                        // merge clusters
                        for (int imrg = 0; imrg < clus_resis.Count - 1;)
                        {
                            // skip merging if number of atoms > threshold
                            if (numatom[imrg] > num_atom_merge)
                            {
                                imrg++; continue;
                            }
                            if (numatom[imrg] + numatom[imrg + 1] > num_atom_merge)
                            {
                                imrg++; continue;
                            }
                            // merge clusters: add imrg+1 into imrg
                            clus_resis[imrg].AddRange(clus_resis[imrg + 1]);
                            numresi   [imrg]    += numresi   [imrg + 1];
                            numatom   [imrg]    += numatom   [imrg + 1];
                            clus_resis[imrg + 1] = null;
                            clus_resis.RemoveAt(imrg + 1);
                            numresi.RemoveAt(imrg + 1);
                            numatom.RemoveAt(imrg + 1);
                        }

                        // reverse so
                        // from [1,1,1,1,1], [1,1,2], [2,2], [2,3], [3], [3], [4], [4], [5]
                        // to   [5], [4], [4], [3], [3], [2,3], [2,2], [1,1,2], [1,1,1,1,1]
                        // since the order of deleteing cluster is
                        //       9    8    7    6    5    4      3      2        1
                        clus_resis.Reverse();
                        numresi.Reverse();
                        numatom.Reverse();
                    }
                }

                if (HDebug.IsDebuggerAttached)
                {
                    HashSet <Universe.Atom> diffset = lkeeps.HToHashSet();
                    bool same = true;
                    for (int i = 0; i < resi_keeps_others.Length; i++)
                    {
                        var keeps_others = resi_keeps_others[i];
                        foreach (var keep in keeps_others.Item1)
                        {
                            if (diffset.Contains(keep))
                            {
                                diffset.Remove(keep);
                            }
                            else
                            {
                                same = false;
                            }
                        }
                    }
                    if (diffset.Count != 0)
                    {
                        same = false;
                    }
                    HDebug.Assert(same == true);
                }

                int max_num_remvs             = int.MinValue;
                int max_num_resis             = int.MinValue;
                List <Universe.Atom[]> remvss = new List <Universe.Atom[]>();

                foreach (var cresis in clus_resis)
                {
                    List <Universe.Atom> removs = new List <Universe.Atom>();
                    foreach (var keeps_others in cresis)
                    {
                        //Universe.Atom ca = keeps_others.Item1[0];
                        Universe.Atom[] others = keeps_others.Item2;
                        removs.AddRange(others);
                    }
                    remvss.Add(removs.ToArray());
                    max_num_remvs = Math.Max(max_num_remvs, removs.Count);
                    max_num_resis = Math.Max(max_num_resis, cresis.Count);
                }
                //System.Console.Write("MaxNumClus({0,4},{1,5})", max_num_resis, max_num_remvs);

                foreach (var keep in lkeeps)
                {
                    HDebug.Exception(coords[keep.ID] != null, "keeping atom must be non-null");
                }

                return(new Tuple <int[], int[][]>
                       (
                           lkeeps.ListIDs(),
                           remvss.ListIDs()
                       ));
            }