public static MixHessInfo GetHessMixModel(Universe univ, IList <Vector> coords, ILinAlg la , IList <ResInfo> lstResAllAtom, FnGetHess GetHess, out string errmsg , bool bGetIntmInfo, string strBkbnReso ) { FnGetHess lGetHess = delegate(Universe luniv, IList <Vector> lcoords, int[] lidxAll, int[] lidxBuffer, int[] lidxCoarse, int[] idxBackbone) { // double check if all three indices are disjoint HDebug.Assert(lidxAll.HUnion().Length == lidxAll.Length); HDebug.Assert(lidxBuffer.HUnion().Length == lidxBuffer.Length); HDebug.Assert(lidxCoarse.HUnion().Length == lidxCoarse.Length); HDebug.Assert(lidxAll.HListCommonT(lidxBuffer).Count == 0); HDebug.Assert(lidxBuffer.HListCommonT(lidxCoarse).Count == 0); HDebug.Assert(lidxCoarse.HListCommonT(lidxAll).Count == 0); if (HDebug.IsDebuggerAttached) { foreach (int idx in lidxAll) { HDebug.Assert(lcoords[idx] != null); } foreach (int idx in lidxBuffer) { HDebug.Assert(lcoords[idx] != null); } foreach (int idx in lidxCoarse) { HDebug.Assert(lcoords[idx] != null); } } var hessinfo = GetHess(luniv, lcoords, lidxAll, lidxBuffer, lidxCoarse, idxBackbone); return(hessinfo); }; bool bVerifySteps = false; // HDebug.IsDebuggerAttached; Vector bfactorFull = null; if (bVerifySteps && HDebug.IsDebuggerAttached) { int[] idxAll = HEnum.HEnumCount(coords.Count).ToArray(); var hessinfo = lGetHess(univ, coords, idxAll, new int[0], new int[0], new int[0]); var modes = hessinfo.GetModesMassReduced(); var modesPosZero = modes.SeparateTolerants(); HDebug.Assert(modesPosZero.Item2.Length == 6); bfactorFull = modesPosZero.Item1.GetBFactor().ToArray(); } IList <Pdb.Atom> pdbatoms = univ.atoms.ListPdbAtoms(); ResInfo[] resinfos = pdbatoms.ListResInfo(true); int[] idxCa; // idxs of Ca atoms int[] idxBkbn; // idxs of backbone atoms int[] idxSele; // idxs of all atoms of lstResAllAtom (selected) int[] idxCntk; // idxs of all atoms contacting idxSele { string[] nameBkbn; switch (strBkbnReso) { case "NCaC": nameBkbn = new string[] { "N", "CA", "C" }; break; case "NCaC-O": nameBkbn = new string[] { "N", "CA", "C", "O" }; break; case "NCaC-OHn": nameBkbn = new string[] { "N", "CA", "C", "O", "HN" }; break; case "NCaC-O-Ha": nameBkbn = new string[] { "N", "CA", "C", "O", "HA" }; break; case "NCaC-OHn-HaCb": nameBkbn = new string[] { "N", "CA", "C", "O", "HN", "HA", "CB" }; break; default: throw new NotImplementedException(); } idxCa = univ.atoms.ListPdbAtoms().IdxByName(true, "CA"); //idxBkbn = univ.atoms.ListPdbAtoms().IdxByName(true, "N", "CA", "C", "O", "HA"); idxBkbn = univ.atoms.ListPdbAtoms().IdxByName(true, nameBkbn); idxSele = resinfos.HIdxEqual(ResInfo.Equals, lstResAllAtom.ToArray()); Vector[] coordSele = coords.HSelectByIndex(idxSele); int[] idxCtof = coords.HIdxWithinCutoff(4.5, coordSele); ResInfo[] resCtof = resinfos.HSelectByIndex(idxCtof); resCtof = resCtof.HUnion(); // remove redundant residues resCtof = resCtof.HRemoveAll(lstResAllAtom.ToArray()).ToArray(); // remove active site residues idxCntk = resinfos.HIdxEqual(ResInfo.Equals, resCtof); bool plot = false; if (plot) #region verify by plotting { Pdb.ToFile(@"C:\temp\mix.pdb", pdbatoms, coords); Pymol.Py.CgoOld.WriteBlank(@"C:\temp\mix.py", false); Pymol.Py.CgoOld.WriteSphere(@"C:\temp\mix.py", "Ca", coords.HSelectByIndex(idxCa).HRemoveAllNull(), 0.3); Pymol.Py.CgoOld.WriteSphere(@"C:\temp\mix.py", "backbone", coords.HSelectByIndex(idxBkbn).HRemoveAllNull(), 0.3); Pymol.Py.CgoOld.WriteSphere(@"C:\temp\mix.py", "active", coordSele.HRemoveAllNull() , 0.3 , red: 1, green: 0, blue: 0); Pymol.Py.CgoOld.WriteSphere(@"C:\temp\mix.py", "connect", coords.HSelectByIndex(idxCntk).HRemoveAllNull() , 0.3 , red: 0, green: 0, blue: 1); HFile.WriteAllLines(@"C:\temp\mix.pml", new string[] { "load mix.pdb", "run mix.py", "reset", }); } #endregion } //idxBkbn = HEnum.HSequence(coords.Count).ToArray(); int[] idxFull = idxSele.HUnionWith(idxCntk).HUnionWith(idxBkbn); Vector[] coordsFull = coords.HCopyIdx(idxFull, null); var hessinfoFull = lGetHess(univ, coordsFull , idxAll: idxSele , idxBuffer: idxCntk.HRemoveAll(idxSele) , idxCoarse: idxBkbn.HRemoveAll(idxSele).HRemoveAll(idxCntk) , idxBackbone: idxBkbn ); HDebug.Assert(hessinfoFull.hess.IsComputable() == false); //{ // var modes = hessinfoFull.GetModesMassReduced(false, la); // var modesPosZero = modes.SeparateTolerants(); // Vector bf = modesPosZero.Item1.GetBFactor().ToArray(); // Vector nma = ext as Vector; // double corr = BFactor.Corr(bf, nma); //} var hessinfoSub = hessinfoFull.GetSubHessInfo(idxFull); HDebug.Assert(hessinfoSub.hess.IsComputable() == true); if (HDebug.IsDebuggerAttached) { Mode[] lmodes = hessinfoSub.GetModesMassReduced(); if (lmodes.SeparateTolerants().Item2.Length != 6) { HDebug.Assert(false); //throw new Exception(); } } if (bVerifySteps && HDebug.IsDebuggerAttached) { var modes = hessinfoSub.GetModesMassReduced(); var modesPosZero = modes.SeparateTolerants(); Vector bf0 = modesPosZero.Item1.GetBFactor().ToArray(); Vector bf = new double[coords.Count]; bf.SetValue(double.NaN); for (int i = 0; i < idxFull.Length; i++) { bf[idxFull[i]] = bf0[i]; } int[] idxCax = idxCa.HRemoveAll(idxSele).HRemoveAll(idxCntk); double corr = HBioinfo.BFactor.Corr(bf, bfactorFull, idxFull); double corrCa = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCa); double corrCax = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCax); double corrBkbn = HBioinfo.BFactor.Corr(bf, bfactorFull, idxBkbn); double corrSele = HBioinfo.BFactor.Corr(bf, bfactorFull, idxSele); double corrCntk = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCntk); } int[] idxMix; { Universe.Atom[] mixAtoms = hessinfoSub.atoms.HToType <object, Universe.Atom>(); Pdb.Atom[] mixPdbAtoms = mixAtoms.ListPdbAtoms(); ResInfo[] mixResinfos = mixPdbAtoms.ListResInfo(true); int[] mixIdxCa = mixPdbAtoms.IdxByName(true, "CA"); int[] mixIdxSele = mixResinfos.HIdxEqual(ResInfo.Equals, lstResAllAtom.ToArray()); idxMix = mixIdxCa.HUnionWith(mixIdxSele).HSort(); } HessMatrix hessMix = Hess.GetHessCoarseBlkmat(hessinfoSub.hess, idxMix, la); if (hessMix.IsComputable() == false) { // hessSub (=hessinfoSub.hess) is computable, but hessMix become in-computable. // This happens when 1. hessSub=[A,B;C,D] has more then 6 zero eigenvalues, // 2. the D matrix become singular, // 3. inv(D) is incomputable // 4. "A - B inv(D) C" becomes incomputable. errmsg = "hess(Sele,Cntk,Bkbn)->hess(Sele,Ca) becomes incomputable"; return(null); } MixHessInfo hessinfoMix = new MixHessInfo { hess = hessMix, mass = hessinfoSub.mass.ToArray().HSelectByIndex(idxMix), atoms = hessinfoSub.atoms.ToArray().HSelectByIndex(idxMix), coords = hessinfoSub.coords.ToArray().HSelectByIndex(idxMix), numZeroEigval = 6, }; if (bGetIntmInfo) { hessinfoMix.intmHessinfoAllMidBkbn = hessinfoSub; hessinfoMix.intmAtomCa = univ.atoms.ToArray().HSelectByIndex(idxCa); hessinfoMix.intmAtomAll = univ.atoms.ToArray().HSelectByIndex(idxSele); hessinfoMix.intmAtomMid = univ.atoms.ToArray().HSelectByIndex(idxCntk); hessinfoMix.intmAtomBkbn = univ.atoms.ToArray().HSelectByIndex(idxBkbn); } if (HDebug.IsDebuggerAttached) { Mode[] lmodes = hessinfoMix.GetModesMassReduced(); if (lmodes.SeparateTolerants().Item2.Length != 6) { throw new Exception(); } } if (bVerifySteps && HDebug.IsDebuggerAttached) { var modes = hessinfoMix.GetModesMassReduced(); var modesPosZero = modes.SeparateTolerants(); Vector bf0 = modesPosZero.Item1.GetBFactor().ToArray(); Vector bf = new double[coords.Count]; bf.SetValue(double.NaN); for (int i = 0; i < idxMix.Length; i++) { bf[idxFull[idxMix[i]]] = bf0[i]; } int[] idxCax = idxCa.HRemoveAll(idxSele).HRemoveAll(idxCntk); double corr = HBioinfo.BFactor.Corr(bf, bfactorFull, true); double corrCa = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCa); double corrCax = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCax); double corrBkbn = HBioinfo.BFactor.Corr(bf, bfactorFull, idxBkbn); double corrSele = HBioinfo.BFactor.Corr(bf, bfactorFull, idxSele); double corrCntk = HBioinfo.BFactor.Corr(bf, bfactorFull, idxCntk); } errmsg = null; return(hessinfoMix); }