Ejemplo n.º 1
0
        //public static Dictionary<string,AminoAcid> ToDictionaryBy3Letter(this IList<AminoAcid> acids, bool toupper)
        //{
        //    Dictionary<string,AminoAcid> dict = new Dictionary<string,AminoAcid>();
        //    foreach(AminoAcid acid in acids)
        //    {
        //        string name3 = acid.name3;
        //        if(toupper) name3 = name3.ToUpper();
        //        dict.Add(name3, acid);
        //    }
        //    return dict;
        //}
        //public static Dictionary<char, AminoAcid> ToDictionaryBy1Letter(this IList<AminoAcid> acids)
        //{
        //    Dictionary<char,AminoAcid> dict = new Dictionary<char, AminoAcid>();
        //    foreach(AminoAcid acid in acids)
        //        dict.Add(acid.name1, acid);
        //    return dict;
        //}
        //public static string[] HBioinfoConvertTo3Letter(              params char  [] resis1) { return HBioinfo.AminoAcids.Convert_1Letter_to_3Letter(         resis1); }
        //public static char  [] HBioinfoConvertTo1Letter(bool toupper, params string[] resis3) { return HBioinfo.AminoAcids.Convert_3Letter_to_1Letter(toupper, resis3); }

        public static IReadOnlyList <Acid> GerResAminoAcid(this Pdb.Atom atom)
        {
            string name3 = atom.resName;

            HDebug.Assert(name3.Length == 3);
            return(Acid.From3Letter(name3));
        }
Ejemplo n.º 2
0
        public static List <Top.Atom> SelectMatchToPdb(this IList <Top.Atom> atoms, IList <Pdb.Atom> pdbatoms)
        {
            Dictionary <int, Pdb.Atom> dict = new Dictionary <int, Pdb.Atom>(pdbatoms.Count);

            foreach (Pdb.Atom pdbatom in pdbatoms)
            {
                dict.Add(pdbatom.serial, pdbatom);
            }

            List <Top.Atom> select = new List <Top.Atom>();

            foreach (Top.Atom atom in atoms)
            {
                if (dict.ContainsKey(atom.cgnr))
                {
                    Pdb.Atom pdbatom = dict[atom.cgnr];
                    if ((atom.residu == pdbatom.resName) && (atom.resnr == pdbatom.resSeq))
                    {
                        HDebug.AssertOr(atom.atom.Trim() == pdbatom.name.Trim()
                                        , atom.atom.Trim() == (pdbatom.name.Substring(1) + pdbatom.name[0]).Trim() // (top) HG21 <=> 1HG2 (pdb)
                                        );
                        select.Add(atom);
                    }
                }
            }

            HDebug.Assert(pdbatoms.Count == select.Count);
            return(select);
        }
Ejemplo n.º 3
0
        public Pdb CloneWithFixResiToAla()
        {
            Atom[] atoms  = this.atoms;
            int    numfix = 0;
            Dictionary <Element, Atom> atom2natom = new Dictionary <Element, Atom>();

            {
                var resis = atoms.ListResidue();
                foreach (var resi in resis)
                {
                    if (resi.ResName == "ALA")
                    {
                        continue;
                    }
                    string[] names = resi.atoms.ListName().HTrim().HSort();
                    if (names.HConcat("-") == "C-CA-CB-N-O")
                    {
                        numfix++;
                        foreach (var atom in resi.atoms)
                        {
                            Pdb.Atom natom = Atom.FromData
                                             (
                                serial: atom.serial,
                                name: atom.name,
                                resName: "ALA",
                                chainID: atom.chainID,
                                resSeq: atom.resSeq,
                                x: atom.x,
                                y: atom.y,
                                z: atom.z,
                                altLoc: atom.altLoc,
                                iCode: atom.iCode,
                                occupancy: atom.occupancy,
                                tempFactor: atom.tempFactor,
                                element: atom.element,
                                charge: atom.charge
                                             );
                            atom2natom.Add(atom, natom);
                        }
                    }
                }
            }
            //atoms.group();
            Element[] newelements = new Element[elements.Length];
            for (int i = 0; i < elements.Length; i++)
            {
                Element element = elements[i];
                newelements[i] = element.UpdateElement();
                if (atom2natom.ContainsKey(element))
                {
                    newelements[i] = atom2natom[element].UpdateElement();
                }
            }
            return(new Pdb(newelements));
        }
Ejemplo n.º 4
0
        public static IEnumerable <List <Pdb.Atom> > BuildWaterBoxExt
            (Vector min
            , Vector max
            , double dist2water = 2.9 //2.8 // 2.7564;
            , bool randOrient   = true
            , string opt        = "water in uniform cube"
            )
        {
            double min_x = Math.Min(min[0], max[0]);
            double min_y = Math.Min(min[1], max[1]);
            double min_z = Math.Min(min[2], max[2]);
            double max_x = Math.Max(min[0], max[0]);
            double max_y = Math.Max(min[1], max[1]);
            double max_z = Math.Max(min[2], max[2]);
            double maxx  = max_x - min_x;
            double maxy  = max_y - min_y;
            double maxz  = max_z - min_z;

            Dictionary <int, List <Pdb.Atom> > atoms = new Dictionary <int, List <Pdb.Atom> >();

            foreach (var file_atom in EnumAtomsInWaterBox(maxx, maxy, maxz, dist2water, randOrient, opt))
            {
                int      file  = file_atom.Item1;
                var      atom  = file_atom.Item2;
                double   x     = atom.x;
                double   y     = atom.y;
                double   z     = atom.z;
                Pdb.Atom uatom = Pdb.Atom.FromString(atom.GetUpdatedLine(min_x + x, min_y + y, min_z + z));

                if (atoms.ContainsKey(file) == false)
                {
                    if (atoms.Count == 1)
                    {
                        yield return(atoms.First().Value);

                        atoms.Clear();
                    }
                    atoms.Add(file, new List <Pdb.Atom>());
                }

                atoms[file].Add(uatom);
            }

            if (atoms.Count == 1)
            {
                yield return(atoms.First().Value);

                atoms.Clear();
            }
        }
Ejemplo n.º 5
0
        public static char?GetResNameSyn(this Pdb.Atom atom)
        {
            var aa = atom.GerResAminoAcid();

            if (aa == null)
            {
                return(null);
            }
            if (aa.Count == 1)
            {
                return(aa[0].name1);
            }
            throw new NotImplementedException();
        }
        public static Pdb CopyPdbOccupancyForMergedPsf(Pdb copyto, Pdb copyfrom1, Pdb copyfrom2)
        {
            KDTreeDLL.KDTree <Pdb.Atom> kdtree = new KDTreeDLL.KDTree <Pdb.Atom>(3);
            foreach (var atom in copyfrom1.atoms)
            {
                kdtree.insert(atom.coord, atom);
            }
            foreach (var atom in copyfrom2.atoms)
            {
                kdtree.insert(atom.coord, atom);
            }

            Pdb pdb = copyto.Clone();

            List <string> nlines = new List <string>();

            for (int i = 0; i < pdb.elements.Length; i++)
            {
                var elemi = pdb.elements[i];
                if ((elemi is Pdb.Atom) == false)
                {
                    nlines.Add(elemi.line);
                }
                else
                {
                    var atomi = elemi as Pdb.Atom;
                    var atomx = kdtree.nearest(atomi.coord);
                    HDebug.Assert(atomi.coord[0] == atomx.coord[0]);
                    HDebug.Assert(atomi.coord[1] == atomx.coord[1]);
                    HDebug.Assert(atomi.coord[2] == atomx.coord[2]);
                    /// 55 - 60        Real(6.2)     occupancy    Occupancy.
                    char[] line = atomi.line.ToCharArray();
                    line[55 - 1] = atomx.line[55 - 1];
                    line[56 - 1] = atomx.line[56 - 1];
                    line[57 - 1] = atomx.line[57 - 1];
                    line[58 - 1] = atomx.line[58 - 1];
                    line[59 - 1] = atomx.line[59 - 1];
                    line[60 - 1] = atomx.line[60 - 1];
                    string nline = line.HToString();
                    nlines.Add(nline);
                    Pdb.Atom natomi = Pdb.Atom.FromString(nline);
                    pdb.elements[i] = natomi;
                }
            }
            return(pdb);
        }
Ejemplo n.º 7
0
            static Tuple <string, string, double, double, double, int> UnivAtomToTinkKey(Universe.Atom uatom)
            {
                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;

                var key = new Tuple <string, string, double, double, double, int>(name + "-" + resn, type, rmin2, eps, chrg, valnc);

                return(key);
            }
Ejemplo n.º 8
0
        public static List <Atom[]> GroupByResidue(this IList <Atom> atoms)
        {
            Dictionary <string, Atom[]> resi2atoms = new Dictionary <string, Atom[]>();

            foreach (var atom in atoms)
            {
                string key;
                if (atom._ResidueId != null)
                {
                    key = atom._ResidueId;
                }
                else
                {
                    Pdb.Atom pdbatom = atom.correspond_PdbAtom();
                    if (pdbatom != null)
                    {
                        key = string.Format("[{0},{1},{2}]", pdbatom.chainID, pdbatom.resSeq, pdbatom.iCode);
                    }
                    else
                    {
                        // if corresponding PDB atom cannot be found, then
                        // * if it is not hydrogen, then use AtomId
                        // * if it is     hydrogen, then use its connected atom's AtomId
                        Atom key_atom = null;
                        if (atom.AtomElem == "H")
                        {
                            key_atom = atom.Inter12.First();
                        }
                        else
                        {
                            key_atom = atom;
                        }

                        key = string.Format("ID-{0}", key_atom.AtomId);
                    }
                }
                if (resi2atoms.ContainsKey(key) == false)
                {
                    resi2atoms.Add(key, new Atom[0]);
                }
                resi2atoms[key] = resi2atoms[key].HAdd(atom);
            }
            return(resi2atoms.Values.ToList());
        }
Ejemplo n.º 9
0
            public int GetValence()
            {
                HDebug.Assert(false);
                Pdb.Atom PdbAtom = null;

                switch (PdbAtom.element)
                {
                case " H": return(1);

                case " N": return(3);

                case " C": return(4);

                case " O": return(2);
                    //case " S": return
                }
                HDebug.Assert(false);
                return(-1);
            }
Ejemplo n.º 10
0
        public static bool GetBFactorSelfTest(string pdbpath, double cutoff, double corr, int round, InfoPack extra)
        {
            if (HFile.Exists(pdbpath) == false)
            {
                return(false);
            }

            Pdb pdb = Pdb.FromFile(pdbpath);

            for (int i = 0; i < pdb.atoms.Length; i++)
            {
                HDebug.Assert(pdb.atoms[0].altLoc == pdb.atoms[i].altLoc);
                HDebug.Assert(pdb.atoms[0].chainID == pdb.atoms[i].chainID);
            }
            List <Pdb.Atom> atoms = new List <Pdb.Atom>();

            for (int i = 0; i < pdb.atoms.Length; i++)
            {
                Pdb.Atom atom = pdb.atoms[i];
                if (atom.name.Trim().ToUpper() == "CA")
                {
                    atoms.Add(atom);
                }
            }
            List <Vector> coords  = atoms.ListCoord();
            Matrix        hess    = Hess.GetHessAnm(coords, cutoff);
            InfoPack      lextra  = new InfoPack();
            Vector        bfactor = GetBFactor(hess, 0.00000001, null, lextra);

            if (extra != null)
            {
                extra["num_zero_eigvals"] = lextra["num_zero_eigvals"];
                extra["eigenvalues"]      = lextra["eigenvalues"];
            }

            double corr_comp = pdb.CorrBFactor(atoms.ListName(), atoms.ListResSeq(), bfactor.ToArray());

            corr_comp = Math.Round(corr_comp, round);
            HDebug.Assert(corr == corr_comp);
            return(corr == corr_comp);
        }
Ejemplo n.º 11
0
            public static Dictionary <Pdb.Atom, HashSet <Pdb.Atom> > BuildBonds(params Pdb.Atom[] atoms)
            {
                int    resSeq  = atoms[0].resSeq;
                string resName = atoms[0].resName;

                List <Tuple <string, string> > list_name1_name2 = BuildBonds(resName);

                Dictionary <Pdb.Atom, HashSet <Pdb.Atom> > bonds = new Dictionary <Pdb.Atom, HashSet <Pdb.Atom> >();

                foreach (Tuple <string, string> name1_name2 in list_name1_name2)
                {
                    string          name1  = name1_name2.Item1;
                    string          name2  = name1_name2.Item2;
                    List <Pdb.Atom> atom1s = atoms.SelectByName(name1.Trim());
                    List <Pdb.Atom> atom2s = atoms.SelectByName(name2.Trim());
                    if (atom1s.Count == 0 || atom2s.Count == 0)
                    {
                        continue;
                    }
                    HDebug.Assert(atom1s.Count == 1, atom2s.Count == 1);
                    Pdb.Atom atom1 = atom1s[0];
                    Pdb.Atom atom2 = atom2s[0];
                    HDebug.Assert(atom1.resSeq == atom2.resSeq);
                    HDebug.Assert(atom1.resName == atom2.resName);
                    if (bonds.ContainsKey(atom1) == false)
                    {
                        bonds.Add(atom1, new HashSet <Pdb.Atom>());
                    }
                    if (bonds.ContainsKey(atom2) == false)
                    {
                        bonds.Add(atom2, new HashSet <Pdb.Atom>());
                    }
                    bonds[atom1].Add(atom2);
                    bonds[atom2].Add(atom1);
                }

                HDebug.Assert(bonds.Count == atoms.Length);
                return(bonds);
            }
Ejemplo n.º 12
0
            public Atom(Namd.Psf.Atom PsfAtom, Namd.Prm.Nonbonded Nonbonded, Pdb.Atom PdbAtom)
            {
                //Debug.Assert(ID <= MaxID);
                //this._ID = ID;
                //this.PdbAtom = PdbAtom;
                //this.PsfAtom = PsfAtom;
                //this.PrmNonbonded = Nonbonded;

                this.AtomId      = PsfAtom.AtomId;
                this.AtomName    = PsfAtom.AtomName;
                this.AtomType    = PsfAtom.AtomType;
                this.AtomElem    = PdbAtom.element.Trim();
                this._ResidueId  = string.Format("({0},{1},{2})", PsfAtom.SegmentName, PsfAtom.ResidueId.Item1, PsfAtom.ResidueId.Item2);
                this.ResidueName = PsfAtom.ResidueName;
                this.Charge      = PsfAtom.Charge;
                this.Mass        = PsfAtom.Mass;
                this.epsilon     = Nonbonded.epsilon;
                this.Rmin2       = Nonbonded.Rmin2;
                this.eps_14      = Nonbonded.eps_14;
                this.Rmin2_14    = Nonbonded.Rmin2_14;
                this.sources     = new object[] { PdbAtom, PsfAtom, Nonbonded };
///             this.IsVirtual   = (PdbAtom.occupancy < 0) ? true : false;
            }
Ejemplo n.º 13
0
            public Pdb.Atom   correspond_PdbAtom()
            {
                Pdb.Atom pdbatom = sources_PdbAtom();
                if (pdbatom != null)
                {
                    return(pdbatom);
                }

                HashSet <Atom> visiteds = new HashSet <Atom>();

                visiteds.Add(this);
                List <Atom> tovisit = new List <Atom>();

                tovisit.AddRange(Inter12);
                tovisit.AddRange(Inter123);
                tovisit.AddRange(Inter14);

                foreach (var link in tovisit)
                {
                    if (visiteds.Contains(link))
                    {
                        continue;
                    }
                    pdbatom = link.sources_PdbAtom();
                    if (pdbatom != null)
                    {
                        return(pdbatom);
                    }
                    visiteds.Add(link);
                }

                return(null);

                //HDebug.Assert(false);
                throw new NotImplementedException();
            }
Ejemplo n.º 14
0
        public static IEnumerable <ValueTuple <int, Pdb.Atom> > EnumAtomsInWaterBox
            (double maxx
            , double maxy
            , double maxz
            , double dist2water = 2.9 //2.8 // 2.7564;
            , bool randOrient   = true
            , string opt        = "water in uniform cube"
            )
        {
            System.Random rand = null;
            if (randOrient)
            {
                rand = new System.Random();
            }
            //List<Pdb.Atom> atoms = new List<Pdb.Atom>();
            int file   = 1;
            int serial = 1;
            int resSeq = 1;

            IEnumerable <Vector> enumer = null;

            switch (opt)
            {
            case "water in uniform cube": enumer = Geometry.EnumPointsInVolume_UniformCube(maxx / dist2water, maxy / dist2water, maxz / dist2water); break;

            case "water in uniform tetrahedron": enumer = Geometry.EnumPointsInVolume_UniformTetrahedron(maxx / dist2water, maxy / dist2water, maxz / dist2water); break;
            }

            foreach (Vector pt in enumer)
            {
                resSeq++;
                double x = pt[0] * dist2water;
                double y = pt[1] * dist2water;
                double z = pt[2] * dist2water;
                //var atom = Pdb.Atom.FromData(i+1, "H", "HOH", '1', i+1, pt[0], pt[1], pt[2]);

                /// ATOM   8221  OH2 TIP32 547      11.474  41.299  26.099  1.00  0.00           O
                /// ATOM   8222  H1  TIP32 547      12.474  41.299  26.099  0.00  0.00           H
                /// ATOM   8223  H2  TIP32 547      11.148  42.245  26.099  0.00  0.00           H
                Vector[] pthoh = new Vector[]
                {
                    new double[] { 0.000000, 0.000000, 0.000000 },
                    new double[] { 0.000000, 0.000000, 0.957200 },
                    new double[] { 0.926627, 0.000000, 0.239987 },
                };
                if (randOrient != null)
                {
                    Vector axis = new double[]
                    { (rand.NextDouble() * 10) % 5
                      , (rand.NextDouble() * 10) % 5
                      , (rand.NextDouble() * 10) % 5 };
                    Trans3 trans = Trans3.FromRotate(axis.UnitVector(), rand.NextDouble() * Math.PI * 4);
                    trans.DoTransform(pthoh);
                }

                if ((serial >= 99990) || (resSeq >= 9990))
                {
                    file++;
                    serial = 1;
                    resSeq = 1;
                }

                serial++; Pdb.Atom OH2 = Pdb.Atom.FromData(serial, "OH2", "HOH", '1', resSeq + 1, x + pthoh[0][0], y + pthoh[0][1], z + pthoh[0][2], element: "O"); yield return(new ValueTuple <int, Pdb.Atom>(file, OH2)); //atoms.Add(OH2);

                serial++; Pdb.Atom H1 = Pdb.Atom.FromData(serial, "H1", "HOH", '1', resSeq + 1, x + pthoh[1][0], y + pthoh[1][1], z + pthoh[1][2], element: "H"); yield return(new ValueTuple <int, Pdb.Atom>(file, H1));    //atoms.Add(H1 );

                serial++; Pdb.Atom H2 = Pdb.Atom.FromData(serial, "H2", "HOH", '1', resSeq + 1, x + pthoh[2][0], y + pthoh[2][1], z + pthoh[2][2], element: "H"); yield return(new ValueTuple <int, Pdb.Atom>(file, H2));    //atoms.Add(H2 );
            }
        }
Ejemplo n.º 15
0
            public static Universe Build(Tinker.Xyz xyz, Tinker.Prm prm, Pdb pdb
                                         , double?tolCoordPdbXyz // 0.002 for default distance
                                                                 //    (0.001 * sqrt(3) = 0.0017321, which is the largest tolerance between pdb and xyz)
                                                                 // null  for not ordering by distance;
                                         )
            {
                Universe univ = new Universe();

                Dictionary <int, Prm.Atom>                            prm_id2atom      = prm.atoms.ToIdDictionary();
                Dictionary <int, Prm.Vdw>                             prm_cls2vdw      = prm.vdws.ToClassDictionary();
                Dictionary <int, Prm.Vdw14>                           prm_cls2vdw14    = prm.vdw14s.ToClassDictionary();
                Dictionary <Tuple <int, int>, Prm.Bond>               prm_cls2bond     = prm.bonds.ToClassDictionary();
                Dictionary <Tuple <int, int, int>, Prm.Angle>         prm_cls2angle    = prm.angles.ToClassDictionary();
                Dictionary <Tuple <int, int, int>, Prm.Ureybrad>      prm_cls2ureybrad = prm.ureybrads.ToClassDictionary();
                Dictionary <Tuple <int, int, int, int>, Prm.Improper> prm_cls2improper = prm.impropers.ToClassDictionary();
                Dictionary <Tuple <int, int, int, int>, Prm.Torsion>  prm_cls2torsion  = prm.torsions.ToClassDictionary();
                Dictionary <int, Prm.Charge>                          prm_id2charge    = prm.charges.ToIdDictionary();

                Prm.Biotype[] prm_biotypes = prm.biotypes;

                Xyz.Atom[] xyz_atoms = xyz.atoms;
                Pdb.Atom[] pdb_atoms = (pdb != null) ? pdb.atoms : null;
                Dictionary <int, Xyz.Atom> xyz_id2atom = xyz_atoms.ToIdDictionary();

                KDTree.KDTree <Tuple <int, Pdb.Atom> > coord2pdbatom = null;
                {
                    if (pdb_atoms != null)
                    {
                        coord2pdbatom = new KDTree.KDTree <Tuple <int, Pdb.Atom> >(3);
                        for (int ia = 0; ia < pdb_atoms.Length; ia++)
                        {
                            Pdb.Atom pdb_atom = pdb_atoms[ia];
                            Vector   coord    = pdb_atom.coord;
                            coord2pdbatom.insert(coord.ToArray(), new Tuple <int, Pdb.Atom>(ia, pdb_atom));
                        }
                    }
                }

                Atoms atoms = new Atoms(univ);

                /// Debug.Assert(pdb.atoms.Length == top_atoms.Count);
                for (int i = 0; i < xyz_atoms.Length; i++)
                {
                    Xyz.Atom xyz_atom = xyz_atoms[i];
                    Pdb.Atom pdb_atom = null; // = (pdb_atoms != null) ? (pdb_atoms[i]) : null;
                    if (coord2pdbatom != null)
                    {
                        Vector xyz_coord = xyz_atom.Coord;
                        Tuple <int, Pdb.Atom> ia_atom = coord2pdbatom.nearest(xyz_coord);
                        Vector pdb_coord = ia_atom.Item2.coord;
                        if (tolCoordPdbXyz == null)
                        {
                            pdb_atom = pdb_atoms[i];
                        }
                        else
                        {
                            if ((xyz_coord - pdb_coord).Dist < tolCoordPdbXyz)
                            {
                                pdb_atom = ia_atom.Item2;
                            }
                            else
                            {
                                //HDebug.Assert(false);
                                pdb_atom = null;
                            }
                        }
                    }
                    if (pdb_atom != null)
                    {
                        string pdb_atom_type = pdb_atom.element.Trim();
                        string xyz_atom_type = xyz_atom.AtomType.Trim();
                        if (HDebug.IsDebuggerAttached && pdb_atom_type.Length > 0)   // sometimes element is blank: " "
                        {
                            HDebug.AssertIf(pdb_atom_type[0] == xyz_atom_type[0]);
                        }
                        if (tolCoordPdbXyz != null)
                        {
                            HDebug.AssertTolerance(tolCoordPdbXyz.Value, xyz_atom.Coord - pdb_atom.coord);
                        }
                    }
                    //if(pdb_atom != null) Debug.Assert(xyz_atom.Id == pdb_atom.serial);

                    HDebug.Assert(i + 1 == xyz_atom.Id);
                    Prm.Atom   prm_atom   = prm_id2atom  [xyz_atom.AtomId];
                    Prm.Charge prm_charge = prm_id2charge[xyz_atom.AtomId];
                    Prm.Vdw    prm_vdw    = null;
                    Prm.Vdw14  prm_vdw14  = null;
                    if (prm_cls2vdw.ContainsKey(prm_atom.Class))
                    {
                        prm_vdw = prm_cls2vdw  [prm_atom.Class];
                    }
                    if (prm_cls2vdw14.ContainsKey(prm_atom.Class))
                    {
                        prm_vdw14 = prm_cls2vdw14[prm_atom.Class];
                    }

                    if (pdb_atom != null)
                    {
                        if (pdb_atom.element.Trim() != "")
                        {
                            if (pdb_atom.element.Trim() != prm_atom.AtomElem)
                            {
                                throw new Exception();
                            }
                        }
                    }

                    Atom uatom = new Atom(AtomId: xyz_atom.Id
                                          , AtomName: ((pdb_atom != null) ? (pdb_atom.name.Trim()) : ("?" + prm_atom.Type))     /// fix later
                                          , AtomType: prm_atom.Type
                                          , AtomElem: prm_atom.AtomElem
                                          , ResidueId: ((pdb_atom != null) ? (pdb_atom.resSeq) : (-1))                          /// fix later
                                          , ResidueName: ((pdb_atom != null) ? (pdb_atom.resName.Trim()) : ("?res"))            /// fix later
                                          , Charge: prm_charge.pch
                                          , Mass: prm_atom.Mass
                                          , epsilon: ((prm_vdw != null) ? prm_vdw.Epsilon    :          0)
                                          , Rmin2: ((prm_vdw != null) ? prm_vdw.Rmin2      :          0)
                                          , eps_14: ((prm_vdw14 != null) ? prm_vdw14.Eps_14   : double.NaN)
                                          , Rmin2_14: ((prm_vdw14 != null) ? prm_vdw14.Rmin2_14 : double.NaN)
                                          , sources: new object[] { xyz_atom, pdb_atom, prm_atom, prm_charge }
                                          );

                    uatom.Coord = xyz_atom.Coord;
                    atoms.Add(uatom);
                }


                // bonds
                Bonds bonds;

                {
                    Dictionary <Tuple <Atom, Atom>, Bond> lbonds = new Dictionary <Tuple <Atom, Atom>, Bond>();
                    for (int i = 0; i < xyz_atoms.Length; i++)
                    {
                        int  id0   = xyz_atoms[i].Id; HDebug.Assert(id0 == i + 1);
                        int  atm0  = xyz_atoms[i].AtomId;
                        int  cls0  = prm_id2atom[atm0].Class;
                        Atom atom0 = atoms[id0 - 1]; HDebug.Assert(atom0.AtomId == id0);

                        Tuple <int, int> cls;
                        foreach (int id1 in xyz_atoms[i].BondedIds)
                        {
                            int  atm1  = xyz_id2atom[id1].AtomId;
                            int  cls1  = prm_id2atom[atm1].Class;
                            Atom atom1 = atoms[id1 - 1]; HDebug.Assert(atom1.AtomId == id1);
                            HashSet <Prm.Bond> bondtypes = new HashSet <Prm.Bond>();
                            Atom[]             iatom     = null;
                            cls = new Tuple <int, int>(cls0, cls1); if (prm_cls2bond.ContainsKey(cls))
                            {
                                bondtypes.Add(prm_cls2bond[cls]); iatom = new Atom[] { atom0, atom1 };
                            }
                            cls = new Tuple <int, int>(cls1, cls0); if (prm_cls2bond.ContainsKey(cls))
                            {
                                bondtypes.Add(prm_cls2bond[cls]); iatom = new Atom[] { atom1, atom0 };
                            }
                            HDebug.Assert(bondtypes.Count == 1);
                            if (bondtypes.Count >= 1)
                            {
                                Prm.Bond bondtype = bondtypes.Last();
                                HDebug.Assert(bondtype != null);

                                // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0)
                                if (iatom.First().ID > iatom.Last().ID)
                                {
                                    iatom = iatom.Reverse().ToArray();
                                }

                                var  key  = new Tuple <Atom, Atom>(iatom[0], iatom[1]);
                                Bond bond = new Bond(iatom[0], iatom[1], bondtype.Kb, bondtype.b0, bondtype);
                                if (lbonds.ContainsKey(key) == false)
                                {
                                    lbonds.Add(key, bond);
                                }
                                else
                                {
                                    HDebug.Assert(bond.Kb == lbonds[key].Kb);
                                    HDebug.Assert(bond.b0 == lbonds[key].b0);
                                }
                            }
                        }
                    }
                    bonds = new Bonds();
                    foreach (Bond bond in lbonds.Values)
                    {
                        HDebug.Assert(bond.atoms.Length == 2);
                        HDebug.Assert(bond.atoms[0].ID < bond.atoms[1].ID);
                        bonds.Add(bond);
                        Atom atom0 = bond.atoms[0];
                        Atom atom1 = bond.atoms[1];
                        atom0.Bonds.Add(bond); atom0.Inter123.Add(atom1); atom0.Inter12.Add(atom1);
                        atom1.Bonds.Add(bond); atom1.Inter123.Add(atom0); atom1.Inter12.Add(atom0);
                    }
                }

                HashSet <Atom>[] inter12 = new HashSet <Atom> [xyz_atoms.Length];
                HashSet <Tuple <Atom, Atom>     >[]   inter123  = new HashSet <Tuple <Atom, Atom>     > [xyz_atoms.Length];
                HashSet <Tuple <Atom, Atom, Atom> >[] inter1234 = new HashSet <Tuple <Atom, Atom, Atom> > [xyz_atoms.Length];
                {
                    HDebug.Assert(xyz_atoms.Length == atoms.Count);
                    foreach (Atom atom in atoms)
                    {
                        inter12  [atom.ID] = new HashSet <Atom>(atom.Inter12);
                        inter123 [atom.ID] = new HashSet <Tuple <Atom, Atom>      >();
                        inter1234[atom.ID] = new HashSet <Tuple <Atom, Atom, Atom> >();
                    }

                    // build inter123 and inter1234
                    for (int i = 0; i < xyz_atoms.Length; i++)
                    {
                        Atom atom0 = atoms[i];
                        HDebug.Assert(atom0.ID == i);
                        foreach (Atom atom1 in inter12[atom0.ID])
                        {
                            HDebug.Assert(atom0 != atom1);
                            foreach (Atom atom2 in inter12[atom1.ID])
                            {
                                HDebug.Assert(atom1 != atom2);
                                if (atom0 == atom2)
                                {
                                    continue;
                                }
                                inter123[atom0.ID].Add(new Tuple <Atom, Atom>(atom1, atom2));
                                foreach (Atom atom3 in inter12[atom2.ID])
                                {
                                    HDebug.Assert(atom2 != atom3);
                                    if (atom0 == atom2)
                                    {
                                        continue;
                                    }
                                    if (atom0 == atom3)
                                    {
                                        continue;
                                    }
                                    if (atom1 == atom3)
                                    {
                                        continue;
                                    }
                                    inter1234[atom0.ID].Add(new Tuple <Atom, Atom, Atom>(atom1, atom2, atom3));
                                }
                            }
                        }
                    }
                }

                // angles
                Angles angles;
                {
                    Dictionary <Tuple <Atom, Atom, Atom>, Angle> langles = new Dictionary <Tuple <Atom, Atom, Atom>, Angle>();
                    foreach (Atom atom0 in atoms)
                    {
                        int id0  = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1);
                        int atm0 = xyz_atoms[atom0.ID].AtomId;
                        int cls0 = prm_id2atom[atm0].Class;

                        foreach (var atom123 in inter123[atom0.ID])
                        {
                            Atom atom1 = atom123.Item1; int atm1 = xyz_atoms[atom1.ID].AtomId; int cls1 = prm_id2atom[atm1].Class;
                            Atom atom2 = atom123.Item2; int atm2 = xyz_atoms[atom2.ID].AtomId; int cls2 = prm_id2atom[atm2].Class;

                            Tuple <int, int, int> cls;
                            Atom[] iatom = null;
                            HashSet <Prm.Angle>    angs = new HashSet <Prm.Angle>();
                            HashSet <Prm.Ureybrad> urbs = new HashSet <Prm.Ureybrad>();
                            cls = new Tuple <int, int, int>(cls0, cls1, cls2); if (prm_cls2angle.ContainsKey(cls))
                            {
                                angs.Add(prm_cls2angle[cls]); iatom = new Atom[] { atom0, atom1, atom2 };
                            }
                            if (prm_cls2ureybrad.ContainsKey(cls))
                            {
                                urbs.Add(prm_cls2ureybrad[cls]);
                            }
                            cls = new Tuple <int, int, int>(cls2, cls1, cls0); if (prm_cls2angle.ContainsKey(cls))
                            {
                                angs.Add(prm_cls2angle[cls]); iatom = new Atom[] { atom2, atom1, atom0 };
                            }
                            if (prm_cls2ureybrad.ContainsKey(cls))
                            {
                                urbs.Add(prm_cls2ureybrad[cls]);
                            }
                            HDebug.Assert(angs.Count == 1);
                            HDebug.Assert(urbs.Count <= angs.Count);
                            if (angs.Count >= 1)
                            {
                                Prm.Angle ang = angs.Last();
                                HDebug.Assert(ang != null);
                                Prm.Ureybrad urb = null;
                                if (urbs.Count >= 1)
                                {
                                    urb = urbs.Last();
                                }

                                // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0)
                                if (iatom.First().ID > iatom.Last().ID)
                                {
                                    iatom = iatom.Reverse().ToArray();
                                }

                                var   key   = new Tuple <Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2]);
                                Angle angle = new Angle(iatom[0], iatom[1], iatom[2]
                                                        , Ktheta: ang.Ktheta
                                                        , Theta0: ang.Theta0
                                                        , Kub: ((urb != null) ? urb.Kub : 0)
                                                        , S0: ((urb != null) ? urb.S0  : 0)
                                                        , sources: new object[] { ang, urb }
                                                        );
                                if (langles.ContainsKey(key) == false)
                                {
                                    langles.Add(key, angle);
                                }
                                else
                                {
                                    HDebug.Assert(langles[key].Ktheta == angle.Ktheta
                                                  , langles[key].Theta0 == angle.Theta0
                                                  , langles[key].Kub == angle.Kub
                                                  , langles[key].S0 == angle.S0
                                                  );
                                }
                            }
                        }
                    }
                    angles = new Angles();
                    foreach (Angle angle in langles.Values)
                    {
                        HDebug.Assert(angle.atoms.Length == 3);
                        HDebug.Assert(angle.atoms[0].ID < angle.atoms[2].ID);
                        angles.Add(angle);
                        Atom atom0 = angle.atoms[0];
                        Atom atom1 = angle.atoms[1];
                        Atom atom2 = angle.atoms[2];
                        atom0.Angles.Add(angle); atom0.Inter123.Add(atom1); atom0.Inter123.Add(atom2);
                        atom1.Angles.Add(angle); atom1.Inter123.Add(atom2); atom1.Inter123.Add(atom0);
                        atom2.Angles.Add(angle); atom2.Inter123.Add(atom0); atom2.Inter123.Add(atom1);
                    }
                }

                // dihedrals
                Dihedrals dihedrals;
                {
                    Dictionary <Tuple <Atom, Atom, Atom, Atom>, List <Dihedral> > ldihedrals = new Dictionary <Tuple <Atom, Atom, Atom, Atom>, List <Dihedral> >();
                    foreach (Atom atom0 in atoms)
                    {
                        int id0  = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1);
                        int atm0 = xyz_atoms[atom0.ID].AtomId;
                        int cls0 = prm_id2atom[atm0].Class;

                        Tuple <int, int, int, int> cls;
                        foreach (var atom1234 in inter1234[atom0.ID])
                        {
                            Atom atom1 = atom1234.Item1; int atm1 = xyz_atoms[atom1.ID].AtomId; int cls1 = prm_id2atom[atm1].Class;
                            Atom atom2 = atom1234.Item2; int atm2 = xyz_atoms[atom2.ID].AtomId; int cls2 = prm_id2atom[atm2].Class;
                            Atom atom3 = atom1234.Item3; int atm3 = xyz_atoms[atom3.ID].AtomId; int cls3 = prm_id2atom[atm3].Class;

                            HashSet <Prm.Torsion> tors = new HashSet <Prm.Torsion>();
                            Atom[] iatom = null;
                            cls = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); if (prm_cls2torsion.ContainsKey(cls))
                            {
                                tors.Add(prm_cls2torsion[cls]); iatom = new Atom[] { atom0, atom1, atom2, atom3 };
                            }
                            cls = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); if (prm_cls2torsion.ContainsKey(cls))
                            {
                                tors.Add(prm_cls2torsion[cls]); iatom = new Atom[] { atom3, atom2, atom1, atom0 };
                            }
                            HDebug.Assert(tors.Count == 1);
                            if (tors.Count >= 1)
                            {
                                // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0)
                                if (iatom.First().ID > iatom.Last().ID)
                                {
                                    iatom = iatom.Reverse().ToArray();
                                }

                                var key = new Tuple <Atom, Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2], iatom[3]);
                                if (ldihedrals.ContainsKey(key) == false)
                                {
                                    ldihedrals.Add(key, new List <Dihedral>());

                                    Prm.Torsion tor = tors.Last();
                                    foreach (var tordat in tor.GetListData())
                                    {
                                        Dihedral dihedral = new Dihedral(iatom[0], iatom[1], iatom[2], iatom[3]
                                                                         , Kchi: tordat.Kchi
                                                                         , n: tordat.n
                                                                         , delta: tordat.delta
                                                                         , sources: new object[] { tor }
                                                                         );
                                        ldihedrals[key].Add(dihedral);
                                        HDebug.Assert(dihedral.n != 0);
                                    }
                                }
                                else
                                {
                                    // do not check its contents because ...
                                }
                            }
                        }
                    }
                    dihedrals = new Dihedrals();
                    foreach (var ldihedral in ldihedrals.Values)
                    {
                        foreach (Dihedral dihedral in ldihedral)
                        {
                            HDebug.Assert(dihedral.atoms.Length == 4);
                            HDebug.Assert(dihedral.atoms[0].ID < dihedral.atoms[3].ID);
                            dihedrals.Add(dihedral);
                            dihedral.atoms[0].Dihedrals.Add(dihedral);
                            dihedral.atoms[1].Dihedrals.Add(dihedral);
                            dihedral.atoms[2].Dihedrals.Add(dihedral);
                            dihedral.atoms[3].Dihedrals.Add(dihedral);
                        }
                    }
                }

                // impropers
                Impropers impropers = new Impropers();

                {
                    Dictionary <Tuple <Atom, Atom, Atom, Atom>, Improper> limpropers = new Dictionary <Tuple <Atom, Atom, Atom, Atom>, Improper>();
                    foreach (Atom atom0 in atoms)
                    {
                        ///       ####################################
                        ///       ##                                ##
                        ///       ##  Improper Dihedral Parameters  ##
                        ///       ##                                ##
                        ///       ####################################
                        ///
                        ///    ##################################################################
                        ///    ##                                                              ##
                        ///    ##  Following CHARMM style, the improper for a trigonal atom    ##
                        ///    ##  D bonded to atoms A, B and C could be input as improper     ##
                        ///    ##  dihedral angle D-A-B-C. The actual angle computed by the    ##
                        ///    ##  program is then literally the dihedral D-A-B-C, which will  ##
                        ///    ##  always have as its ideal value zero degrees. In general     ##
                        ///    ##  D-A-B-C is different from D-B-A-C; the order of the three   ##
                        ///    ##  peripheral atoms matters. In the original CHARMM parameter  ##
                        ///    ##  files, the trigonal atom is often listed last; ie, as       ##
                        ///    ##  C-B-A-D instead of D-A-B-C.                                 ##
                        ///    ##                                                              ##
                        ///    ##  Some of the improper angles are "double counted" in the     ##
                        ///    ##  CHARMM protein parameter set. Since TINKER uses only one    ##
                        ///    ##  improper parameter per site, we have doubled these force    ##
                        ///    ##  constants in the TINKER version of the CHARMM parameters.   ##
                        ///    ##  Symmetric parameters, which are the origin of the "double   ##
                        ///    ##  counted" CHARMM values, are handled in the TINKER package   ##
                        ///    ##  by assigning all symmetric states and using the TINKER      ##
                        ///    ##  force constant divided by the symmetry number.              ##
                        ///    ##                                                              ##
                        ///    ##  ...                                                         ##
                        ///    ##################################################################

                        int id0  = xyz_atoms[atom0.ID].Id; HDebug.Assert(id0 == atom0.ID + 1);
                        int atm0 = xyz_atoms[atom0.ID].AtomId;
                        int cls0 = prm_id2atom[atm0].Class;

                        bool bAtom0InImpropers = false;
                        foreach (var cls in prm_cls2improper.Keys)
                        {
                            if (cls.Item1 == cls0)
                            {
                                bAtom0InImpropers = true;
                            }
                        }
                        if (bAtom0InImpropers == false)
                        {
                            continue;
                        }

                        Atom[] bondeds0 = inter12[atom0.ID].ToArray();
                        if (bondeds0.Length < 3)
                        {
                            continue;
                        }
                        for (int i = 0; i < bondeds0.Length - 2; i++)
                        {
                            Atom atom1 = bondeds0[i];
                            int  atm1  = xyz_atoms[atom1.ID].AtomId;
                            int  cls1  = prm_id2atom[atm1].Class;
                            for (int j = i + 1; j < bondeds0.Length - 1; j++)
                            {
                                Atom atom2 = bondeds0[j];
                                int  atm2  = xyz_atoms[atom2.ID].AtomId;
                                int  cls2  = prm_id2atom[atm2].Class;
                                for (int k = j + 1; k < bondeds0.Length; k++)
                                {
                                    Atom atom3 = bondeds0[k];
                                    int  atm3  = xyz_atoms[atom3.ID].AtomId;
                                    int  cls3  = prm_id2atom[atm3].Class;

                                    Tuple <int, int, int, int> cls;
                                    HashSet <Prm.Improper>     imps = new HashSet <Prm.Improper>();
                                    Atom[] iatom = null;
                                    cls = new Tuple <int, int, int, int>(cls0, cls1, cls2, cls3); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom1, atom2, atom3 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls3, cls2, cls1, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom3, atom2, atom1, atom0 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls0, cls1, cls3, cls2); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom1, atom3, atom2 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls2, cls3, cls1, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom2, atom3, atom1, atom0 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls0, cls2, cls1, cls3); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom2, atom1, atom3 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls3, cls1, cls2, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom3, atom1, atom2, atom0 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls0, cls2, cls3, cls1); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom2, atom3, atom1 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls1, cls3, cls2, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom1, atom3, atom2, atom0 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls0, cls3, cls1, cls2); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom3, atom1, atom2 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls2, cls1, cls3, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom2, atom1, atom3, atom0 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls0, cls3, cls2, cls1); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom0, atom3, atom2, atom1 };
                                    }
                                    cls = new Tuple <int, int, int, int>(cls1, cls2, cls3, cls0); if (prm_cls2improper.ContainsKey(cls))
                                    {
                                        imps.Add(prm_cls2improper[cls]); iatom = new Atom[] { atom1, atom2, atom3, atom0 };
                                    }
                                    HDebug.Assert(imps.Count <= 1); // for example, H-C-HHH has C-HHH connectivity but it is not improper...
                                                                    // so imps.count <= 1
                                    if (imps.Count >= 1)
                                    {
                                        Prm.Improper imp = imps.Last(); // because iatoms contains the last case only.

                                        ///////////////////////////////////////////////////////////////////////////////////////
                                        // This bug was raised by Jae-Kyun Song at 2016-04-01                                //
                                        // In 1AAC, (1501,C)-(1503,NC2)-(1502,NC2)-(1500,NC2) is reordered                   //
                                        //       as (1500,NC2)-(1502,NC2)-(1503,NC2)-(1501,C)                                //
                                        // This bug was originally copied from dihedral code that is added to prevent adding //
                                        // duplicated interactions such as 1-2-3-4 and 4-3-2-1.                              //
                                        ///////////////////////////////////////////////////////////////////////////////////////
                                        /// old code
                                        //  // sort atom id, in order to avoid duplication of bonds such that (0,1) and (1,0)
                                        //  if(iatom.First().ID > iatom.Last().ID)
                                        //      iatom = iatom.Reverse().ToArray();
                                        //  var key = new Tuple<Atom, Atom, Atom, Atom>(iatom[0], iatom[1], iatom[2], iatom[3]);
                                        ///////////////////////////////////////////////////////////////////////////////////////
                                        /// new code
                                        Tuple <Atom, Atom, Atom, Atom> key;
                                        {
                                            Atom   key0   = iatom[0];
                                            Atom[] key123 = (new Atom[] { iatom[1], iatom[2], iatom[3] }).SortByIDs();
                                            key = new Tuple <Atom, Atom, Atom, Atom>(key0, key123[0], key123[1], key123[2]);
                                        }
                                        ///////////////////////////////////////////////////////////////////////////////////////

                                        Improper improper = new Improper(iatom[0], iatom[1], iatom[2], iatom[3]
                                                                         , Kpsi: imp.Kpsi
                                                                         , psi0: imp.psi0
                                                                         , sources: new object[] { imp }
                                                                         );

                                        if (limpropers.ContainsKey(key) == false)
                                        {
                                            limpropers.Add(key, improper);
                                        }
                                        else
                                        {
                                            HDebug.Assert(limpropers[key].Kpsi == improper.Kpsi
                                                          , limpropers[key].psi0 == improper.psi0
                                                          );
                                        }
                                    }
                                }
                            }
                        }
                    }
                    foreach (var improper in limpropers.Values)
                    {
                        HDebug.Assert(improper.atoms.Length == 4);
                        //HDebug.Assert(improper.atoms[0].ID < improper.atoms[3].ID);
                        impropers.Add(improper);
                        improper.atoms[0].Impropers.Add(improper);
                        improper.atoms[1].Impropers.Add(improper);
                        improper.atoms[2].Impropers.Add(improper);
                        improper.atoms[3].Impropers.Add(improper);
                    }
                }

                // 1-4 interactions
                for (int i = 0; i < atoms.Count; i++)
                {
                    HashSet <Atom> Inter14 = new HashSet <Atom>();
                    BuildInter1toN(atoms[i], 4, Inter14); // find all atoms for 1-4 interaction
                    Inter14.Remove(atoms[i]);             // remove self
                    foreach (Atom atom in atoms[i].Inter123)
                    {
                        Inter14.Remove(atom);             // remove all 1-2, 1-3 interactions
                    }
                    atoms[i].Inter14 = Inter14;
                }
                Nonbonded14s nonbonded14s = new Nonbonded14s();

                nonbonded14s.Build(atoms);

                //// nonbondeds
                //// do not make this list in advance, because it depends on the atom positions
                //Nonbondeds nonbondeds = new Nonbondeds();
                //nonbondeds.Build(atoms);


                //Universe univ = new Universe();
                univ.pdb = pdb;
                univ.refs.Add("xyz", xyz);
                univ.refs.Add("prm", prm);
                univ.refs.Add("pdb", pdb);
                univ.atoms     = atoms;
                univ.bonds     = bonds;
                univ.angles    = angles;
                univ.dihedrals = dihedrals;
                univ.impropers = impropers;
                //univ.nonbondeds   = nonbondeds  ;  // do not make this list in advance, because it depends on the atom positions
                univ.nonbonded14s = nonbonded14s;

                HDebug.Assert(univ.Verify());
                if (HDebug.False)
                {
                    List <Tuple <double, string, Bond> > lbnds = new List <Tuple <double, string, Bond> >();
                    foreach (Bond bnd in bonds)
                    {
                        lbnds.Add(new Tuple <double, string, Bond>(bnd.Kb
                                                                   , bnd.atoms[0].AtomType + "-" + bnd.atoms[1].AtomType
                                                                   , bnd));
                    }
                    lbnds = lbnds.HSelectByIndex(lbnds.HListItem1().HIdxSorted().Reverse().ToArray()).ToList();
                    double avgKb = lbnds.HListItem1().Average();

                    List <Tuple <double, string, Angle> > langs   = new List <Tuple <double, string, Angle> >();
                    List <Tuple <double, string, Angle> > langubs = new List <Tuple <double, string, Angle> >();
                    foreach (Angle ang in angles)
                    {
                        langs.Add(new Tuple <double, string, Angle>(ang.Ktheta
                                                                    , ang.atoms[0].AtomType + "-" + ang.atoms[1].AtomType + "-" + ang.atoms[2].AtomType
                                                                    , ang));
                        if (ang.Kub != 0)
                        {
                            langubs.Add(new Tuple <double, string, Angle>(ang.Kub
                                                                          , ang.atoms[0].AtomType + "-" + ang.atoms[1].AtomType + "-" + ang.atoms[2].AtomType
                                                                          , ang));
                        }
                    }
                    langs   = langs.HSelectByIndex(langs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList();
                    langubs = langubs.HSelectByIndex(langubs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList();
                    double avgKtheta = langs.HListItem1().Average();
                    double avgKub    = langubs.HListItem1().Average();

                    List <Tuple <double, string, Improper> > limps = new List <Tuple <double, string, Improper> >();
                    foreach (Improper imp in impropers)
                    {
                        limps.Add(new Tuple <double, string, Improper>(imp.Kpsi
                                                                       , imp.atoms[0].AtomType + "-" + imp.atoms[1].AtomType + "-" + imp.atoms[2].AtomType + "-" + imp.atoms[3].AtomType
                                                                       , imp));
                    }
                    limps = limps.HSelectByIndex(limps.HListItem1().HIdxSorted().Reverse().ToArray()).ToList();
                    double avgKpsi = limps.HListItem1().Average();

                    List <Tuple <double, string, Dihedral> > ldihs = new List <Tuple <double, string, Dihedral> >();
                    foreach (Dihedral dih in dihedrals)
                    {
                        ldihs.Add(new Tuple <double, string, Dihedral>(dih.Kchi
                                                                       , dih.atoms[0].AtomType + "-" + dih.atoms[1].AtomType + "-" + dih.atoms[2].AtomType + "-" + dih.atoms[3].AtomType
                                                                       , dih));
                    }
                    ldihs = ldihs.HSelectByIndex(ldihs.HListItem1().HIdxSorted().Reverse().ToArray()).ToList();
                    double avgKchi = ldihs.HListItem1().Average();
                }
                return(univ);
            }
Ejemplo n.º 16
0
            public static HessInfoCoarseResiIter GetHessCoarseResiIter
                (Hess.HessInfo hessinfo
                , Vector[] coords
                , FuncGetIdxKeepListRemv GetIdxKeepListRemv
                , ILinAlg ila
                , double thres_zeroblk = 0.001
                , IterOption iteropt   = IterOption.Matlab_experimental
                , string[] options     = null
                )
            {
                bool rediag = true;

                HessMatrix H = null;

                List <int>[] lstNewIdxRemv = null;
                int          numca         = 0;

                double[] reMass   = null;
                object[] reAtoms  = null;
                Vector[] reCoords = null;
                Tuple <int[], int[][]> idxKeepRemv = null;

                //System.Console.WriteLine("begin re-indexing hess");
                {
                    object[] atoms = hessinfo.atoms;
                    idxKeepRemv = GetIdxKeepListRemv(atoms, coords);
                    int[]   idxKeep  = idxKeepRemv.Item1;
                    int[][] idxsRemv = idxKeepRemv.Item2;
                    {
                        List <int> check = new List <int>();
                        check.AddRange(idxKeep);
                        foreach (int[] idxRemv in idxsRemv)
                        {
                            check.AddRange(idxRemv);
                        }
                        check = check.HToHashSet().ToList();
                        if (check.Count != coords.Length)
                        {
                            throw new Exception("the re-index contains the duplicated atoms or the missing atoms");
                        }
                    }
                    List <int> idxs = new List <int>();
                    idxs.AddRange(idxKeep);
                    foreach (int[] idxRemv in idxsRemv)
                    {
                        idxs.AddRange(idxRemv);
                    }
                    HDebug.Assert(idxs.Count == idxs.HToHashSet().Count);

                    H        = hessinfo.hess.ReshapeByAtom(idxs);
                    numca    = idxKeep.Length;
                    reMass   = hessinfo.mass.ToArray().HSelectByIndex(idxs);
                    reAtoms  = hessinfo.atoms.ToArray().HSelectByIndex(idxs);
                    reCoords = coords.HSelectByIndex(idxs);

                    int nidx = idxKeep.Length;
                    lstNewIdxRemv = new List <int> [idxsRemv.Length];
                    for (int i = 0; i < idxsRemv.Length; i++)
                    {
                        lstNewIdxRemv[i] = new List <int>();
                        foreach (var idx in idxsRemv[i])
                        {
                            lstNewIdxRemv[i].Add(nidx);
                            nidx++;
                        }
                    }
                    HDebug.Assert(nidx == lstNewIdxRemv.Last().Last() + 1);
                    HDebug.Assert(nidx == idxs.Count);
                }
                GC.Collect(0);
                HDebug.Assert(numca == H.ColBlockSize - lstNewIdxRemv.HListCount().Sum());

                //if(bool.Parse("false"))
                {
                    if (bool.Parse("false"))
                    #region
                    {
                        int[]      idxKeep  = idxKeepRemv.Item1;
                        int[][]    idxsRemv = idxKeepRemv.Item2;
                        Pdb.Atom[] pdbatoms = hessinfo.atomsAsUniverseAtom.ListPdbAtoms();
                        Pdb.ToFile(@"C:\temp\coarse-keeps.pdb", pdbatoms.HSelectByIndex(idxKeep), false);
                        if (HFile.Exists(@"C:\temp\coarse-graining.pdb"))
                        {
                            HFile.Delete(@"C:\temp\coarse-graining.pdb");
                        }
                        foreach (int[] idxremv in idxsRemv.Reverse())
                        {
                            List <Pdb.Element> delatoms = new List <Pdb.Element>();
                            foreach (int idx in idxremv)
                            {
                                if (pdbatoms[idx] == null)
                                {
                                    continue;
                                }
                                string   line    = pdbatoms[idx].GetUpdatedLine(coords[idx]);
                                Pdb.Atom delatom = Pdb.Atom.FromString(line);
                                delatoms.Add(delatom);
                            }
                            Pdb.ToFile(@"C:\temp\coarse-graining.pdb", delatoms.ToArray(), true);
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        // export matrix to matlab, so the matrix can be checked in there.
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();
                        Matlab.Register(@"C:\temp\");
                        Matlab.PutSparseMatrix("H", H.GetMatrixSparse(), 3, 3);
                        Matlab.Execute("figure; spy(H)");
                        Matlab.Clear();
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        HDirectory.CreateDirectory(@"K:\temp\$coarse-graining\");
                        {   // export original hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in hessinfo.hess.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("hess = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("hess = float(hess);");
                            Matlab.Execute("figure; spy(hess)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-original.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                        {   // export reshuffled hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("H = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("H = float(H);");
                            Matlab.Execute("figure; spy(H)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-reshuffled.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();

                        HessMatrix A = H.SubMatrixByAtoms(false, idxca, idxca);
                        HessMatrix B = H.SubMatrixByAtoms(false, idxca, idxoth);
                        HessMatrix C = H.SubMatrixByAtoms(false, idxoth, idxca);
                        HessMatrix D = H.SubMatrixByAtoms(false, idxoth, idxoth);
                        Matlab.Clear();
                        Matlab.PutSparseMatrix("A", A.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("B", B.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("C", C.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("D", D.GetMatrixSparse(), 3, 3);
                        Matlab.Clear();
                    }
                    #endregion
                }

                List <HessCoarseResiIterInfo> iterinfos = null;
                {
                    object[] atoms = reAtoms; // reAtoms.HToType(null as Universe.Atom[]);
                    CGetHessCoarseResiIterImpl info = null;
                    switch (iteropt)
                    {
                    case IterOption.ILinAlg_20150329: info = GetHessCoarseResiIterImpl_ILinAlg_20150329(H, lstNewIdxRemv, thres_zeroblk, ila, false);                    break;

                    case IterOption.ILinAlg: info = GetHessCoarseResiIterImpl_ILinAlg(H, lstNewIdxRemv, thres_zeroblk, ila, false);                             break;

                    case IterOption.Matlab: info = GetHessCoarseResiIterImpl_Matlab(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options);              break;

                    case IterOption.Matlab_experimental: info = GetHessCoarseResiIterImpl_Matlab_experimental(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.Matlab_IterLowerTri: info = GetHessCoarseResiIterImpl_Matlab_IterLowerTri(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.LinAlg_IterLowerTri: info = GetHessCoarseResiIterImpl_LinAlg_IterLowerTri.Do(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;
                    }
                    ;
                    H         = info.H;
                    iterinfos = info.iterinfos;
                }
                //{
                //    var info = GetHessCoarseResiIterImpl_Matlab(H, lstNewIdxRemv, thres_zeroblk);
                //    H = info.H;
                //}
                GC.Collect(0);

                if (HDebug.IsDebuggerAttached)
                {
                    int   nidx  = 0;
                    int[] ikeep = idxKeepRemv.Item1;
                    foreach (int idx in ikeep)
                    {
                        bool equal = object.ReferenceEquals(hessinfo.atoms[idx], reAtoms[nidx]);
                        if (equal == false)
                        {
                            HDebug.Assert(false);
                        }
                        HDebug.Assert(equal);
                        nidx++;
                    }
                }

                if (rediag)
                {
                    H = H.CorrectHessDiag();
                }
                //System.Console.WriteLine("finish fixing diag");

                return(new HessInfoCoarseResiIter
                {
                    hess = H,
                    mass = reMass.HSelectCount(numca),
                    atoms = reAtoms.HSelectCount(numca),
                    coords = reCoords.HSelectCount(numca),
                    numZeroEigval = 6,
                    iterinfos = iterinfos,
                });
            }
Ejemplo n.º 17
0
        public List <Tuple <int, int> > GetIndex(Pdb pdb, char selAltLoc = 'A', bool includeHydrogen = true)
        {
            List <Tuple <int, int> > idxs = new List <Tuple <int, int> >();
            // (idx in univ.atoms, idx in pdb)
            List <int> lidxs = new List <int>();

            for (int i = 0; i < atoms.Count; i++)
            {
                Atom atm0 = atoms[i];

                if (includeHydrogen == false && atm0.IsHydrogen())
                {
                    continue;
                }
                lidxs.Clear();
                for (int j = 0; j < pdb.atoms.Length; j++)
                {
                    Pdb.Atom atm1 = pdb.atoms[j];
                    if (atm0.AtomName != atm1.name)
                    {
                        continue;
                    }
                    if (atm0.ResiduePdbId != atm1.resSeq)
                    {
                        continue;
                    }
                    lidxs.Add(j);
                }
                if (lidxs.Count == 1)
                {
                    int      j    = lidxs.First();
                    Pdb.Atom atm1 = pdb.atoms[j];
                    HDebug.Assert(atm1.altLoc == ' ' || atm1.altLoc == 'A');
                    idxs.Add(new Tuple <int, int>(i, j));
                }
                else if (lidxs.Count >= 2)
                {
                    // get index of the matching altLoc
                    int sel = -1;
                    foreach (int lidx in lidxs)
                    {
                        if (pdb.atoms[lidx].altLoc == selAltLoc)
                        {
                            sel = lidx;
                        }
                        else if (pdb.atoms[lidx].altLoc == '1' && selAltLoc == 'A')
                        {
                            sel = lidx;
                        }
                        else if (pdb.atoms[lidx].altLoc == '2' && selAltLoc == 'B')
                        {
                            sel = lidx;
                        }
                        else if (pdb.atoms[lidx].altLoc == '3' && selAltLoc == 'C')
                        {
                            sel = lidx;
                        }
                    }
                    // put it into idxs
                    HDebug.Assert(sel != -1);
                    int      j    = sel;
                    Pdb.Atom atm1 = pdb.atoms[j];
                    HDebug.Assert(atm1.altLoc == selAltLoc);
                    idxs.Add(new Tuple <int, int>(i, j));
                }
            }

            return(idxs);
        }
Ejemplo n.º 18
0
            public static bool SelfTest_1AAC()
            {
                Pdb.Atom[] atoms_ca = new Pdb.Atom[]
                {
                    #region 1AAC text of CA atoms
                    Pdb.Atom.FromString("ATOM      2  CA  ASP A   1      25.378 -18.141  21.012  1.00 23.28           C  "),
                    Pdb.Atom.FromString("ATOM     10  CA  LYS A   2      24.390 -18.799  17.407  1.00 12.32           C  "),
                    Pdb.Atom.FromString("ATOM     19  CA  ALA A   3      25.772 -15.617  15.840  1.00 10.31           C  "),
                    Pdb.Atom.FromString("ATOM     24  CA  THR A   4      28.837 -13.442  16.439  1.00  9.47           C  "),
                    Pdb.Atom.FromString("ATOM     31  CA  ILE A   5      28.913  -9.665  15.865  1.00  7.94           C  "),
                    Pdb.Atom.FromString("ATOM     39  CA  PRO A   6      31.906  -8.243  13.886  1.00  8.02           C  "),
                    Pdb.Atom.FromString("ATOM     46  CA  SER A   7      31.049  -4.632  14.810  1.00  7.70           C  "),
                    Pdb.Atom.FromString("ATOM     52  CA  GLU A   8      28.768  -3.589  17.658  1.00 10.01           C  "),
                    Pdb.Atom.FromString("ATOM     73  CA  PRO A  10      26.932   0.412  12.498  1.00  7.09           C  "),
                    Pdb.Atom.FromString("ATOM     80  CA  PHE A  11      29.488   1.217   9.844  1.00  6.81           C  "),
                    Pdb.Atom.FromString("ATOM     91  CA  ALA A  12      29.431   2.815   6.390  1.00  6.76           C  "),
                    Pdb.Atom.FromString("ATOM     96  CA  ALA A  13      28.012   1.036   3.320  1.00  8.60           C  "),
                    Pdb.Atom.FromString("ATOM    101  CA  ALA A  14      31.392   1.654   1.659  1.00 11.18           C  "),
                    Pdb.Atom.FromString("ATOM    106  CA  GLU A  15      33.092  -0.407   4.404  1.00  9.76           C  "),
                    Pdb.Atom.FromString("ATOM    115  CA  VAL A  16      31.115  -3.590   3.763  1.00 12.85           C  "),
                    Pdb.Atom.FromString("ATOM    122  CA  ALA A  17      33.429  -6.584   3.205  1.00 20.32           C  "),
                    Pdb.Atom.FromString("ATOM    127  CA  ASP A  18      34.080  -7.894  -0.306  1.00 27.64           C  "),
                    Pdb.Atom.FromString("ATOM    135  CA  GLY A  19      31.708 -10.634  -1.313  1.00 26.92           C  "),
                    Pdb.Atom.FromString("ATOM    139  CA  ALA A  20      29.393  -9.683   1.528  1.00 19.57           C  "),
                    Pdb.Atom.FromString("ATOM    144  CA  ILE A  21      25.881 -11.238   1.583  1.00 11.70           C  "),
                    Pdb.Atom.FromString("ATOM    152  CA  VAL A  22      23.847  -8.061   1.553  1.00  7.77           C  "),
                    Pdb.Atom.FromString("ATOM    159  CA  VAL A  23      20.196  -7.501   2.410  1.00  6.37           C  "),
                    Pdb.Atom.FromString("ATOM    166  CA  ASP A  24      19.093  -3.982   1.466  1.00  6.66           C  "),
                    Pdb.Atom.FromString("ATOM    174  CA  ILE A  25      16.500  -2.121   3.513  1.00  7.21           C  "),
                    Pdb.Atom.FromString("ATOM    182  CA  ALA A  26      14.398   0.375   1.556  1.00  8.41           C  "),
                    Pdb.Atom.FromString("ATOM    187  CA  LYS A  27      10.724   1.489   1.214  1.00  9.80           C  "),
                    Pdb.Atom.FromString("ATOM    201  CA  MET A  28      10.147   0.295   4.838  1.00  8.69           C  "),
                    Pdb.Atom.FromString("ATOM    209  CA  LYS A  29      10.882  -3.362   4.004  1.00  9.09           C  "),
                    Pdb.Atom.FromString("ATOM    223  CA  TYR A  30      13.753  -5.845   4.132  1.00  6.32           C  "),
                    Pdb.Atom.FromString("ATOM    235  CA  GLU A  31      14.275  -6.364   0.381  1.00  9.00           C  "),
                    Pdb.Atom.FromString("ATOM    244  CA  THR A  32      15.144 -10.026   0.769  1.00  7.30           C  "),
                    Pdb.Atom.FromString("ATOM    251  CA  PRO A  33      12.722 -11.107   3.546  1.00  8.68           C  "),
                    Pdb.Atom.FromString("ATOM    258  CA  GLU A  34      13.757 -14.780   3.406  1.00  9.28           C  "),
                    Pdb.Atom.FromString("ATOM    267  CA  LEU A  35      17.468 -15.255   2.972  1.00  7.34           C  "),
                    Pdb.Atom.FromString("ATOM    275  CA  HIS A  36      19.181 -18.672   2.822  1.00  6.97           C  "),
                    Pdb.Atom.FromString("ATOM    285  CA  VAL A  37      22.841 -18.828   3.840  1.00  7.29           C  "),
                    Pdb.Atom.FromString("ATOM    292  CA  LYS A  38      25.361 -21.456   5.044  1.00  9.55           C  "),
                    Pdb.Atom.FromString("ATOM    306  CA  VAL A  39      26.828 -21.965   8.529  1.00  9.09           C  "),
                    Pdb.Atom.FromString("ATOM    313  CA  GLY A  40      29.717 -19.533   8.887  1.00  8.81           C  "),
                    Pdb.Atom.FromString("ATOM    317  CA  ASP A  41      28.343 -16.891   6.520  1.00  8.19           C  "),
                    Pdb.Atom.FromString("ATOM    325  CA  THR A  42      28.196 -13.227   7.468  1.00  7.95           C  "),
                    Pdb.Atom.FromString("ATOM    332  CA  VAL A  43      24.989 -11.395   6.512  1.00  6.02           C  "),
                    Pdb.Atom.FromString("ATOM    339  CA  THR A  44      25.158  -7.607   6.224  1.00  5.34           C  "),
                    Pdb.Atom.FromString("ATOM    346  CA  TRP A  45      22.054  -5.421   6.244  1.00  4.51           C  "),
                    Pdb.Atom.FromString("ATOM    360  CA  ILE A  46      22.453  -1.974   4.623  1.00  5.55           C  "),
                    Pdb.Atom.FromString("ATOM    368  CA  ASN A  47      19.890   0.774   5.248  1.00  6.52           C  "),
                    Pdb.Atom.FromString("ATOM    376  CA  ARG A  48      19.350   2.559   1.939  1.00 10.21           C  "),
                    Pdb.Atom.FromString("ATOM    387  CA  GLU A  49      16.823   5.111   3.196  1.00 12.44           C  "),
                    Pdb.Atom.FromString("ATOM    396  CA  ALA A  50      16.764   8.058   5.564  1.00 13.39           C  "),
                    Pdb.Atom.FromString("ATOM    401  CA  MET A  51      14.386   6.508   8.133  1.00 12.52           C  "),
                    Pdb.Atom.FromString("ATOM    409  CA  PRO A  52      16.509   4.566  10.725  1.00  9.20           C  "),
                    Pdb.Atom.FromString("ATOM    416  CA  HIS A  53      16.032   0.778  10.889  1.00  6.43           C  "),
                    Pdb.Atom.FromString("ATOM    426  CA  ASN A  54      17.658  -2.107  12.766  1.00  5.06           C  "),
                    Pdb.Atom.FromString("ATOM    434  CA  VAL A  55      17.296  -5.891  13.052  1.00  5.44           C  "),
                    Pdb.Atom.FromString("ATOM    441  CA  HIS A  56      15.979  -7.379  16.316  1.00  4.53           C  "),
                    Pdb.Atom.FromString("ATOM    451  CA  PHE A  57      15.920 -11.061  17.243  1.00  5.94           C  "),
                    Pdb.Atom.FromString("ATOM    462  CA  VAL A  58      13.932 -11.794  20.435  1.00  7.60           C  "),
                    Pdb.Atom.FromString("ATOM    469  CA  ALA A  59      15.316 -13.765  23.405  1.00  7.37           C  "),
                    Pdb.Atom.FromString("ATOM    474  CA  GLY A  60      16.074 -17.393  22.787  1.00  9.00           C  "),
                    Pdb.Atom.FromString("ATOM    478  CA  VAL A  61      16.521 -17.029  18.997  1.00  8.51           C  "),
                    Pdb.Atom.FromString("ATOM    485  CA  LEU A  62      20.244 -16.290  18.543  1.00  9.65           C  "),
                    Pdb.Atom.FromString("ATOM    493  CA  GLY A  63      21.156 -16.644  22.197  1.00 10.26           C  "),
                    Pdb.Atom.FromString("ATOM    497  CA  GLU A  64      19.729 -16.413  25.651  1.00  9.18           C  "),
                    Pdb.Atom.FromString("ATOM    506  CA  ALA A  65      19.129 -12.671  25.468  1.00  8.86           C  "),
                    Pdb.Atom.FromString("ATOM    511  CA  ALA A  66      17.408 -10.687  22.723  1.00  7.22           C  "),
                    Pdb.Atom.FromString("ATOM    516  CA  LEU A  67      19.808  -9.283  20.128  1.00  9.01           C  "),
                    Pdb.Atom.FromString("ATOM    524  CA  LYS A  68      18.504  -5.777  19.473  1.00 10.06           C  "),
                    Pdb.Atom.FromString("ATOM    533  CA  GLY A  69      20.805  -4.416  16.788  1.00  8.06           C  "),
                    Pdb.Atom.FromString("ATOM    537  CA  PRO A  70      21.868  -0.715  16.656  1.00  8.23           C  "),
                    Pdb.Atom.FromString("ATOM    544  CA  MET A  71      19.807   1.769  14.640  1.00  8.56           C  "),
                    Pdb.Atom.FromString("ATOM    552  CA  MET A  72      21.337   2.189  11.156  1.00  8.26           C  "),
                    Pdb.Atom.FromString("ATOM    560  CA  LYS A  73      21.086   5.638   9.601  1.00  9.59           C  "),
                    Pdb.Atom.FromString("ATOM    574  CA  LYS A  74      21.097   6.084   5.777  1.00  9.46           C  "),
                    Pdb.Atom.FromString("ATOM    588  CA  GLU A  75      23.892   4.149   4.097  1.00  9.45           C  "),
                    Pdb.Atom.FromString("ATOM    602  CA  GLN A  76      24.997   2.451   7.267  1.00  6.02           C  "),
                    Pdb.Atom.FromString("ATOM    611  CA  ALA A  77      25.416  -1.310   7.631  1.00  5.75           C  "),
                    Pdb.Atom.FromString("ATOM    616  CA  TYR A  78      25.448  -3.978  10.318  1.00  4.90           C  "),
                    Pdb.Atom.FromString("ATOM    628  CA  SER A  79      26.700  -7.612  10.117  1.00  5.13           C  "),
                    Pdb.Atom.FromString("ATOM    634  CA  LEU A  80      26.024 -10.884  11.899  1.00  5.65           C  "),
                    Pdb.Atom.FromString("ATOM    642  CA  THR A  81      27.969 -14.123  11.320  1.00  6.53           C  "),
                    Pdb.Atom.FromString("ATOM    649  CA  PHE A  82      25.693 -17.171  11.780  1.00  5.24           C  "),
                    Pdb.Atom.FromString("ATOM    660  CA  THR A  83      27.363 -20.163  13.449  1.00  6.79           C  "),
                    Pdb.Atom.FromString("ATOM    667  CA  GLU A  84      24.599 -22.785  13.726  1.00  6.27           C  "),
                    Pdb.Atom.FromString("ATOM    676  CA  ALA A  85      21.975 -24.045  11.260  1.00  7.61           C  "),
                    Pdb.Atom.FromString("ATOM    681  CA  GLY A  86      18.324 -23.142  11.886  1.00  7.35           C  "),
                    Pdb.Atom.FromString("ATOM    685  CA  THR A  87      15.680 -20.519  11.055  1.00  8.50           C  "),
                    Pdb.Atom.FromString("ATOM    692  CA  TYR A  88      16.009 -17.145  12.731  1.00  7.35           C  "),
                    Pdb.Atom.FromString("ATOM    704  CA  ASP A  89      13.191 -14.620  12.557  1.00  7.28           C  "),
                    Pdb.Atom.FromString("ATOM    712  CA  TYR A  90      13.740 -10.922  13.122  1.00  5.26           C  "),
                    Pdb.Atom.FromString("ATOM    724  CA  HIS A  91      11.902  -7.619  12.935  1.00  4.80           C  "),
                    Pdb.Atom.FromString("ATOM    734  CA  CYS A  92      12.663  -3.894  13.049  1.00  5.44           C  "),
                    Pdb.Atom.FromString("ATOM    740  CA  THR A  93      12.228  -2.579  16.647  1.00  6.60           C  "),
                    Pdb.Atom.FromString("ATOM    747  CA  PRO A  94      10.460   0.815  15.821  1.00  7.51           C  "),
                    Pdb.Atom.FromString("ATOM    754  CA  HIS A  95       8.594  -0.728  12.857  1.00  7.46           C  "),
                    Pdb.Atom.FromString("ATOM    764  CA  PRO A  96       7.518  -4.286  13.932  1.00  7.59           C  "),
                    Pdb.Atom.FromString("ATOM    771  CA  PHE A  97       5.480  -4.778  10.739  1.00  7.30           C  "),
                    Pdb.Atom.FromString("ATOM    782  CA  MET A  98       8.923  -5.104   8.994  1.00  6.57           C  "),
                    Pdb.Atom.FromString("ATOM    790  CA  ARG A  99       9.707  -8.821   9.391  1.00  7.91           C  "),
                    Pdb.Atom.FromString("ATOM    808  CA  GLY A 100      12.343 -11.105   7.827  1.00  6.39           C  "),
                    Pdb.Atom.FromString("ATOM    812  CA  LYS A 101      14.085 -14.438   8.459  1.00  7.31           C  "),
                    Pdb.Atom.FromString("ATOM    826  CA  VAL A 102      17.523 -15.900   7.870  1.00  6.58           C  "),
                    Pdb.Atom.FromString("ATOM    833  CA  VAL A 103      17.552 -19.658   7.157  1.00  7.20           C  "),
                    Pdb.Atom.FromString("ATOM    840  CA  VAL A 104      21.061 -21.012   7.897  1.00  7.28           C  "),
                    Pdb.Atom.FromString("ATOM    847  CA  GLU A 105      21.699 -24.347   6.221  1.00 13.74           C  "),
                    #endregion
                };
                Pdb.Atom[] atoms_r6 = new Pdb.Atom[]
                {
                    Pdb.Atom.FromString("ATOM     42  CB  PRO A   6      31.929  -8.271  12.386  1.00  7.98           C  "),
                    Pdb.Atom.FromString("ATOM     43  CG  PRO A   6      30.972  -9.378  12.022  1.00  9.48           C  "),
                    Pdb.Atom.FromString("ATOM     44  CD  PRO A   6      29.880  -9.313  13.099  1.00  8.27           C  "),
                };

                {
                    HessMatrix hess = GetHessCa(atoms_ca.ListCoord());

                    InfoPack extra = new InfoPack();
                    //Vector bfactors = ENM.BFactorFromHessian(hess, null, 6, extra);
                    Vector bfactors          = Hess.GetBFactor(hess, null, 6, extra);
                    Vector eigvals           = (double[])extra["eigenvalues"];
                    int[]  idxsorted_eigvals = eigvals.ToArray().HAbs().HIdxSorted();
                    for (int i = 0; i < 6; i++)
                    {
                        eigvals[idxsorted_eigvals[i]] = 0;
                    }
                    for (int i = 0; i < eigvals.Size; i++)
                    {
                        if (eigvals[i] < 0)
                        {
                            // return false, if there exists negative eigenvalue
                            HDebug.Assert(false);
                            return(false);
                        }
                    }
                }
                {
                    List <Pdb.Atom> atoms = new List <Pdb.Atom>();
                    atoms.AddRange(atoms_ca);
                    atoms.AddRange(atoms_r6);
                    HDebug.Assert(atoms[5].resSeq == 6);

                    List <int> idxs_ca = new List <int>(); for (int i = 0; i < atoms_ca.Length; i++)
                    {
                        idxs_ca.Add(i);
                    }
                    List <int> idxs_r6 = new List <int>(); for (int i = atoms_ca.Length; i < atoms.Count; i++)
                    {
                        idxs_r6.Add(i);
                    }
                    idxs_r6.InsertRange(0, new int[] { 3, 4, 5 });

                    List <Tuple <int, int> > list12 = new List <Tuple <int, int> >();
                    for (int i = 1; i < idxs_ca.Count; i++)
                    {
                        list12.Add(new Tuple <int, int>(idxs_ca[i - 1], idxs_ca[i]));
                    }
                    for (int i = 3; i < idxs_r6.Count; i++)
                    {
                        list12.Add(new Tuple <int, int>(idxs_r6[i - 1], idxs_r6[i]));
                    }

                    List <Tuple <int, int, int> > list123 = new List <Tuple <int, int, int> >();
                    for (int i = 2; i < idxs_ca.Count; i++)
                    {
                        list123.Add(new Tuple <int, int, int>(idxs_ca[i - 2], idxs_ca[i - 1], idxs_ca[i]));
                    }
                    for (int i = 3; i < idxs_r6.Count; i++)
                    {
                        list123.Add(new Tuple <int, int, int>(idxs_r6[i - 2], idxs_r6[i - 1], idxs_r6[i]));
                    }

                    List <Tuple <int, int, int, int> > list1234 = new List <Tuple <int, int, int, int> >();
                    for (int i = 3; i < idxs_ca.Count; i++)
                    {
                        list1234.Add(new Tuple <int, int, int, int>(idxs_ca[i - 3], idxs_ca[i - 2], idxs_ca[i - 1], idxs_ca[i]));
                    }
                    for (int i = 3; i < idxs_r6.Count; i++)
                    {
                        list1234.Add(new Tuple <int, int, int, int>(idxs_r6[i - 3], idxs_r6[i - 2], idxs_r6[i - 1], idxs_r6[i]));
                    }

                    List <Tuple <int, int> > listNonbond = new List <Tuple <int, int> >();
                    for (int i = 0; i < idxs_ca.Count; i++)
                    {
                        for (int j = i + 4; j < idxs_ca.Count; j++)
                        {
                            listNonbond.Add(new Tuple <int, int>(idxs_ca[i], idxs_ca[j]));
                        }
                    }
                    for (int i = 0; i < idxs_r6.Count; i++)
                    {
                        for (int j = i + 4; j < idxs_r6.Count; j++)
                        {
                            listNonbond.Add(new Tuple <int, int>(idxs_r6[i], idxs_r6[j]));
                        }
                    }

                    List <Vector> coords  = atoms.ListCoord();
                    HessMatrix    hessian = HessMatrixSparse.ZerosSparse(atoms.Count * 3, atoms.Count * 3);

                    double Epsilon = 0.36;
                    double K_r     = 100 * Epsilon;
                    double K_theta = 20 * Epsilon;
                    double K_phi1  = 1 * Epsilon;
                    double K_phi3  = 0.5 * Epsilon;
                    for (int i = 0; i < list12.Count; i++)
                    {
                        FirstTerm(coords, K_r, hessian, list12[i].Item1, list12[i].Item2);
                    }
                    for (int i = 0; i < list123.Count; i++)
                    {
                        SecondTerm(coords, K_theta, hessian, list123[i].Item1, list123[i].Item2, list123[i].Item3);
                    }
                    for (int i = 0; i < list1234.Count; i++)
                    {
                        ThirdTerm(coords, K_phi1, K_phi3, hessian, list1234[i].Item1, list1234[i].Item2, list1234[i].Item3, list1234[i].Item4);
                    }
                    for (int i = 0; i < listNonbond.Count; i++)
                    {
                        FourthTerm(coords, Epsilon, hessian, listNonbond[i].Item1, listNonbond[i].Item2);
                    }

                    InfoPack extra = new InfoPack();
                    //Vector bfactors = ENM.BFactorFromHessian(hessian, null, 6, extra);
                    Vector bfactors          = Hess.GetBFactor(hessian, null, 6, extra);
                    Vector eigvals           = (double[])extra["eigenvalues"];
                    int[]  idxsorted_eigvals = eigvals.ToArray().HAbs().HIdxSorted();
                    for (int i = 0; i < 6; i++)
                    {
                        eigvals[idxsorted_eigvals[i]] = 0;
                    }
                    for (int i = 0; i < eigvals.Size; i++)
                    {
                        if (eigvals[i] < 0)
                        {
                            // return false, if there exists negative eigenvalue
                            HDebug.Assert(false);
                            return(false);
                        }
                    }
                }
                //{
                //    Debug.Assert(atoms_ca[5].resSeq == 6);
                //    Pdb.Atom[] atoms_resi6 = new Pdb.Atom[]
                //        {
                //            atoms_ca[5],
                //            Pdb.Atom.FromString("ATOM     42  CB  PRO A   6      31.929  -8.271  12.386  1.00  7.98           C  "),
                //            Pdb.Atom.FromString("ATOM     43  CG  PRO A   6      30.972  -9.378  12.022  1.00  9.48           C  "),
                //            Pdb.Atom.FromString("ATOM     44  CD  PRO A   6      29.880  -9.313  13.099  1.00  8.27           C  "),
                //        };
                //    Matrix hess_ca = GetHessCa(atoms_ca.ListCoord());
                //    Matrix hess_resi6 = GetHessCa(atoms_resi6.ListCoord());
                //
                //    int size_ca = atoms_ca.Length;
                //    int size_r6 = atoms_resi6.Length - 1;
                //    Matrix hess = new double[(size_ca+size_r6)*3,(size_ca+size_r6)*3];
                //    for(int c = 0; c < hess.ColSize; c++)
                //        for(int r = 0; r < hess.RowSize; r++)
                //            hess[c, r] = double.NaN;
                //    for(int c = 0; c < hess_ca.ColSize; c++)
                //        for(int r = 0; r < hess_ca.RowSize; r++)
                //            hess[c, r] = hess_ca[c, r];
                //    for(int c = 0; c < hess_resi6.ColSize; c++)
                //        for(int r = 0; r < hess_resi6.RowSize; r++)
                //        {
                //                 if(c <  3 && r <  3) { int c0=5      *3+ c   ; int r0=5      *3+ r   ; Debug.Assert(double.IsNaN(hess[c0, r0]) ==false); hess[c0, r0] = hess_resi6[c, r]; }
                //            else if(c <  3 && r >= 3) { int c0=5      *3+ c   ; int r0=size_ca*3+(r-3); Debug.Assert(double.IsNaN(hess[c0, r0]) == true); hess[c0, r0] = hess_resi6[c, r]; }
                //            else if(c >= 3 && r <  3) { int c0=size_ca*3+(c-3); int r0=5      *3+ r   ; Debug.Assert(double.IsNaN(hess[c0, r0]) == true); hess[c0, r0] = hess_resi6[c, r]; }
                //            else if(c >= 3 && r >= 3) { int c0=size_ca*3+(c-3); int r0=size_ca*3+(r-3); Debug.Assert(double.IsNaN(hess[c0, r0]) == true); hess[c0, r0] = hess_resi6[c, r]; }
                //            else Debug.Assert(false);
                //        }
                //    for(int j = size_ca * 3; j < (size_ca + size_r6) * 3; j++)
                //    {
                //        for(int i = 0; i < 5*3; i++)
                //        {
                //            Debug.Assert(double.IsNaN(hess[i, j]) == true); hess[i, j] = 0;
                //            Debug.Assert(double.IsNaN(hess[j, i]) == true); hess[j, i] = 0;
                //        }
                //        for(int i = 6*3; i < size_ca * 3; i++)
                //        {
                //            Debug.Assert(double.IsNaN(hess[i, j]) == true); hess[i, j] = 0;
                //            Debug.Assert(double.IsNaN(hess[j, i]) == true); hess[j, i] = 0;
                //        }
                //    }
                //    for(int c = 0; c < hess.ColSize; c++)
                //        for(int r = 0; r < hess.RowSize; r++)
                //            Debug.Assert(double.IsNaN(hess[c, r]) == false);
                //
                //    InfoPack extra = new InfoPack();
                //    Vector bfactors = ENM.BFactorFromHessian(hess, null, 6, extra);
                //    Vector eigvals = (double[])extra["eigenvalues"];
                //    int[] idxsorted_eigvals = eigvals.ToArray().Abs().IdxSorted();
                //    for(int i = 0; i < 6; i++) eigvals[idxsorted_eigvals[i]] = 0;
                //    for(int i = 0; i < eigvals.Size; i++)
                //        if(eigvals[i] < 0)
                //        {
                //            // return false, if there exists negative eigenvalue
                //            Debug.Assert(false);
                //            return false;
                //        }
                //}

                return(true);
            }
Ejemplo n.º 19
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));
            }
Ejemplo n.º 20
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,
            });
        }