Molmodel

Protein.h

Go to the documentation of this file.
00001 #ifndef SimTK_MOLMODEL_PROTEIN_H_
00002 #define SimTK_MOLMODEL_PROTEIN_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Molmodel                            *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2007 Stanford University and the Authors.           *
00013  * Authors: Michael Sherman, Christopher Bruns                                *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00035 
00036 #include "molmodel/internal/common.h"
00037 #include "molmodel/internal/Compound.h"
00038 #include "molmodel/internal/CompoundSystem.h"
00039 
00040 namespace SimTK {
00041 
00043 class AcetylResidue : public BiopolymerResidue {
00044 public:
00045     AcetylResidue() : BiopolymerResidue("acetyl", "ACE", 'X')
00046     {
00047         setBaseCompound("methyl", MethylGroup());
00048         nameAtom("CH3", "methyl/C");
00049         nameAtom("1H", "methyl/H1");
00050         nameAtom("2H", "methyl/H2");
00051         nameAtom("3H", "methyl/H3");
00052 
00053         convertInboardBondCenterToOutboard();
00054         bondAtom(TrivalentAtom("C", Element::Carbon()), "methyl/bond", 0.15520);
00055         bondAtom(UnivalentAtom("O", Element::Oxygen()), "C/bond2", 0.12290);
00056         nameBondCenter("bondC", "C/bond3");
00057         nameBondCenter("bondNext", "bondC");
00058         
00059         setAtomBiotype("CH3", "Acetyl", "CH3", SimTK::Ordinality::Initial);
00060         setAtomBiotype("1H",  "Acetyl", "H", SimTK::Ordinality::Initial);
00061         setAtomBiotype("2H",  "Acetyl", "H", SimTK::Ordinality::Initial);
00062         setAtomBiotype("3H",  "Acetyl", "H", SimTK::Ordinality::Initial);
00063         setAtomBiotype("C",   "Acetyl", "C", SimTK::Ordinality::Initial);
00064         setAtomBiotype("O",   "Acetyl", "O", SimTK::Ordinality::Initial);    
00065     }
00066 };
00067 
00068 
00070 class NMethylAmideResidue : public BiopolymerResidue {
00071 public:
00072     NMethylAmideResidue() : BiopolymerResidue("N-methyl amide", "NAC", 'X')
00073     {
00074         // TODO - set nitrogen bond angles
00075         setBaseAtom(TrivalentAtom("N", Element::Nitrogen()));
00076         bondAtom(UnivalentAtom("HN", Element::Hydrogen()), "N/bond3", 0.1010);
00077         bondAtom(AliphaticCarbon("CH3"), "N/bond2", 0.1449);
00078         bondAtom(AliphaticHydrogen("1H"), "CH3/bond2");
00079         bondAtom(AliphaticHydrogen("2H"), "CH3/bond3");
00080         bondAtom(AliphaticHydrogen("3H"), "CH3/bond4");
00081 
00082         nameBondCenter("bondN", "N/bond1");
00083         nameBondCenter("bondPrevious", "bondN");
00084 
00085         // Define default bonding geometry to previous residue
00086         setDefaultInboardBondLength(0.1335);
00087 
00088         // Help with automated biotype resolution
00089         addCompoundSynonym("N-MeAmide");
00090 
00091         // zero and 180 degrees are poor choices for phi angle because each eclipses either N-H or N-C
00092         defineDihedralAngle("phi", "bondPrevious", "CH3/bond2", 30*Deg2Rad);
00093         
00094         setAtomBiotype("N",   "N-MeAmide", "N",   SimTK::Ordinality::Final);
00095         setAtomBiotype("HN",  "N-MeAmide", "HN",  SimTK::Ordinality::Final);
00096         setAtomBiotype("CH3", "N-MeAmide", "CH3", SimTK::Ordinality::Final);
00097         setAtomBiotype("1H",  "N-MeAmide", "H",   SimTK::Ordinality::Final);
00098         setAtomBiotype("2H",  "N-MeAmide", "H",   SimTK::Ordinality::Final);
00099         setAtomBiotype("3H",  "N-MeAmide", "H",   SimTK::Ordinality::Final);    
00100     }
00101 };
00102 
00103 static const Angle DefaultAlphaPhiAngle = -57 * Deg2Rad;
00104 static const Angle DefaultAlphaPsiAngle = -47 * Deg2Rad;
00105 static const Angle DefaultParallelBetaPhiAngle = -119 * Deg2Rad;
00106 static const Angle DefaultParallelBetaPsiAngle =  113 * Deg2Rad;
00107 static const Angle DefaultAntiparallelBetaPhiAngle = -139 * Deg2Rad;
00108 static const Angle DefaultAntiparallelBetaPsiAngle =  135 * Deg2Rad;
00109 
00129 class SimTK_MOLMODEL_EXPORT AminoAcidResidue : public BiopolymerResidue {
00130 public:
00131 
00133     static AminoAcidResidue create(
00134         char oneLetterCode 
00135         );
00136 
00137 
00139     static AminoAcidResidue create(
00140         const PdbResidue& 
00141         );
00142         
00143     explicit AminoAcidResidue(
00144         String name, 
00145         String threeLetterCode = "Unk", 
00146         char oneLetterCode = '?' 
00147         )
00148         : BiopolymerResidue(name, threeLetterCode, oneLetterCode)
00149     {
00150         static const mdunits::Length CA_Hdistance = 0.1090;
00151         static const mdunits::Length N_CAdistance = 0.1449;
00152         static const mdunits::Length CA_Cdistance = 0.1522;
00153         static const mdunits::Length  C_Odistance = 0.1229;
00154         static const mdunits::Length  C_Ndistance = 0.1335; // peptide bond
00155 
00156         // Amino nitrogen
00157         // We want the inboard bond center to be on the main chain nitrogen peptide bond
00158         // But we also want the CA and main chain H to be the reference for dihedrals.
00159         // To reconcile these two requirements, a bit of extra work is required.
00160         TrivalentAtom nAtom("N", Element::Nitrogen());
00161         // nAtom.convertInboardBondCenterToOutboard(); // free bond1 for use with HN
00162         // nAtom.setInboardBondCenter("bond3");  // lowest priority bond becomes inboard
00163 
00164         setBaseAtom(nAtom);
00165 
00166         // Alpha carbon
00167         bondAtom(QuadrivalentAtom("CA", Element::Carbon()), "N/bond2", N_CAdistance, DefaultAntiparallelBetaPhiAngle + 180*Deg2Rad); // phi
00168         bondAtom(UnivalentAtom("HA", Element::Hydrogen()), "CA/bond3", CA_Hdistance);
00169         nameBondCenter("bondCA", "CA/bond4");
00170 
00171         // Carbonyl
00172         bondAtom(TrivalentAtom("C", Element::Carbon()), "CA/bond2", CA_Cdistance, DefaultAntiparallelBetaPsiAngle + 180*Deg2Rad); // psi
00173         bondAtom(UnivalentAtom("O", Element::Oxygen()), "C/bond2", C_Odistance);
00174         nameBondCenter("bondC", "C/bond3");
00175         nameBondCenter("bondNext", "bondC");
00176 
00177         nameBondCenter("bondN", "N/bond1");
00178         nameBondCenter("bondPrevious", "bondN");
00179 
00180         // Define default bonding geometry to previous residue
00181         setDefaultInboardBondLength(C_Ndistance);
00182 
00183         defineDihedralAngle("psi", "N", "CA", "C", "O", 180*Deg2Rad);
00184         setDefaultPsiAngle(DefaultAntiparallelBetaPsiAngle);
00185 
00186         defineDihedralAngle("phi", "N/bond3", "CA/bond2", 180*Deg2Rad);
00187         setDefaultPhiAngle(DefaultAntiparallelBetaPhiAngle);
00188     }
00189 
00190 
00196     AminoAcidResidue& setDefaultPhiAngle(Angle phi) {
00197         setDefaultDihedralAngle("phi", phi);
00198 
00199         return *this;
00200     }
00201 
00202     AminoAcidResidue& setDefaultPsiAngle(Angle psi) {
00203         setDefaultDihedralAngle("psi", psi);
00204 
00205         return *this;
00206     }
00207 
00208     // Make intermediate classes inner classes of AminoAcidResidue
00209     // to avoid registration order problems in boost.python/Py++ wrapping
00210     class HNAminoAcidResidue;
00211     class BetaUnbranchedAminoAcidResidue;
00212     class BetaBranchedAminoAcidResidue;
00213 
00214     class Alanine;
00215     class Cysteine;
00216     class Aspartate;
00217     class Glutamate;
00218     class Phenylalanine;
00219     class Glycine;
00220     class Histidine;
00221     class Isoleucine;
00222     class Lysine;
00223     class Leucine;
00224     class Methionine;
00225     class Asparagine;
00226     class Proline;
00227     class Glutamine;
00228     class Arginine;
00229     class Serine;
00230     class Threonine;
00231     class Valine;
00232     class Tryptophan;
00233     class Tyrosine;
00234 };
00235 
00236 
00241 class  AminoAcidResidue::HNAminoAcidResidue : public AminoAcidResidue {
00242 public:
00243     explicit HNAminoAcidResidue(String name, String threeLetterCode = "Unk", char oneLetterCode = '?')
00244         : AminoAcidResidue(name, threeLetterCode, oneLetterCode)
00245     {
00246         static const mdunits::Length  H_Ndistance = 0.1010;
00247 
00248         bondAtom(UnivalentAtom("H", Element::Hydrogen()), "N/bond3", H_Ndistance);
00249         nameAtom("HN", "H"); // synonym
00250 
00251         // defineDihedralAngle("phi", "H", "N", "CA", "C", 180*Deg2Rad); // already defined
00252     }
00253 };
00254 
00255 
00256 // BetaunbranchedAminoAcidResidue is base class for AminoAcidResidues
00257 // posessing side chains that do not branch at the beta carbon
00258 class  AminoAcidResidue::BetaUnbranchedAminoAcidResidue : public AminoAcidResidue::HNAminoAcidResidue {
00259 public:
00260     BetaUnbranchedAminoAcidResidue(String name, String tlc, char olc)
00261         : AminoAcidResidue::HNAminoAcidResidue(name, tlc, olc) 
00262     {
00263         bondCompound("beta methylene", MethyleneGroup(), "bondCA");
00264         nameAtom("CB", "beta methylene/C");
00265         nameAtom("1HB", "beta methylene/H1");
00266         nameAtom("2HB", "beta methylene/H2");
00267         nameBondCenter("bondCB", "beta methylene/bond2");
00268 
00269         defineDihedralAngle("chi1", "CA/bond1", "beta methylene/bond2");
00270         setDefaultDihedralAngle("chi1", -60*Deg2Rad); // best for most amino acids
00271     }
00272 };
00273 
00274 
00275 // BetaunbranchedAminoAcidResidue is base class for AminoAcidResidues
00276 // posessing side chains that do not branch at the beta carbon
00277 class  AminoAcidResidue::BetaBranchedAminoAcidResidue : public AminoAcidResidue::HNAminoAcidResidue {
00278 public:
00279     BetaBranchedAminoAcidResidue(String name, String tlc, char olc)
00280         : AminoAcidResidue::HNAminoAcidResidue(name, tlc, olc) 
00281     {
00282         bondAtom(AliphaticCarbon("CB"), "bondCA");
00283 
00284         // To get correct chirality *and* priority in isoleucine and threonine,
00285         // place hydrogen on bond3
00286 
00287         bondAtom(AliphaticHydrogen("HB"), "CB/bond3");
00288         nameBondCenter("bondCB1", "CB/bond2");
00289         nameBondCenter("bondCB2", "CB/bond4");
00290 
00291         defineDihedralAngle("chi1", "CA/bond1", "CB/bond2");
00292         setDefaultDihedralAngle("chi1", -60*Deg2Rad); // best for most amino acids
00293     }
00294 };
00295 
00296 
00297 class  AminoAcidResidue::Alanine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00298 public:
00299     Alanine() 
00300         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("alanine", "Ala", 'A')
00301     {
00302         bondAtom(AliphaticHydrogen("3HB"), "bondCB");
00303         
00304         setAtomBiotype("N",   "Alanine", "N");
00305         setAtomBiotype("H",   "Alanine", "HN");
00306         setAtomBiotype("CA",  "Alanine", "CA");
00307         setAtomBiotype("C",   "Alanine", "C");
00308         setAtomBiotype("O",   "Alanine", "O");
00309         setAtomBiotype("HA",  "Alanine", "HA");
00310         setAtomBiotype("CB",  "Alanine", "CB");
00311         setAtomBiotype("1HB", "Alanine", "HB");    
00312         setAtomBiotype("2HB", "Alanine", "HB");    
00313         setAtomBiotype("3HB", "Alanine", "HB");    
00314     }
00315 };
00316 
00317 
00318 class  AminoAcidResidue::Cysteine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00319 public:
00320     Cysteine() 
00321         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("cysteine", "Cys", 'C')
00322     {
00323         // From amber99 parameters in Tinker param file amber99.dat
00324         static const mdunits::Length H_Sdistance = 0.1336;
00325         static const mdunits::Length S_Cdistance = 0.1810;
00326         static const Angle H_S_Cangle = 96.0*Deg2Rad;
00327         static const Angle S_C_Cangle = 108.6*Deg2Rad;
00328 
00329         bondAtom(BivalentAtom("SG", Element::Sulfur(), H_S_Cangle), "bondCB", S_Cdistance, 180*Deg2Rad);
00330         bondAtom(UnivalentAtom("HG", Element::Hydrogen()), "SG/bond2", H_Sdistance, 180*Deg2Rad);
00331 
00332         defineDihedralAngle("chi2", "HG", "SG", "CB", "CA");
00333 
00334         setDefaultBondAngle(108.60*Deg2Rad, "SG", "CB", "CA");
00335 
00336         // Synonym hints to help resolve biotypes from tinker files
00337         // eventually, these biotypes will be pre-defined and hard coded
00338         addCompoundSynonym("CYS (-SH)");
00339         addCompoundSynonym("cysteine (-SH)");
00340     }
00341 };
00342 
00343 class  AminoAcidResidue::Aspartate : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00344 public:
00345     Aspartate() 
00346         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("aspartate", "Asp", 'D')
00347     {
00348         bondCompound("sidechain carboxylate", CarboxylateGroup(), "bondCB");
00349         nameAtom("CG", "sidechain carboxylate/C");
00350         nameAtom("OD1", "sidechain carboxylate/O1");
00351         nameAtom("OD2", "sidechain carboxylate/O2");
00352 
00353         defineDihedralAngle("chi2", "OD1", "CG", "CB", "CA");
00354 
00355         // From Roland Dunbrack's side chain rotamer statistics
00356         // http://dunbrack.fccc.edu/bbdep/confanalysis.php
00357         setDefaultDihedralAngle("chi2", -15*Deg2Rad);
00358 
00359         // Synonym hints to help resolve biotypes from tinker files
00360         // eventually, these biotypes will be pre-defined and hard coded
00361         addCompoundSynonym("aspartic acid");
00362     }
00363 };
00364 
00365 class  AminoAcidResidue::Glutamate : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00366 public:
00367     Glutamate() 
00368         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("glutamate", "Glu", 'E')
00369     {
00370         bondAtom(AliphaticCarbon("CG"), "bondCB");
00371         bondAtom(AliphaticHydrogen("1HG"), "CG/bond3");
00372         bondAtom(AliphaticHydrogen("2HG"), "CG/bond4");
00373 
00374         bondCompound("sidechain carboxylate", CarboxylateGroup(), "CG/bond2");
00375         nameAtom("CD", "sidechain carboxylate/C");
00376         nameAtom("OE1", "sidechain carboxylate/O1");
00377         nameAtom("OE2", "sidechain carboxylate/O2");
00378 
00379         defineDihedralAngle("chi2", "CD", "CG", "CB", "CA");
00380         defineDihedralAngle("chi3", "OE1", "CD", "CG", "CB");
00381 
00382         setDefaultDihedralAngle("chi3", -15*Deg2Rad);
00383 
00384         // Synonym hints to help resolve biotypes from tinker files
00385         // eventually, these biotypes will be pre-defined and hard coded
00386         addCompoundSynonym("glutamic acid");
00387     }
00388 };
00389 
00390 
00391 class  AminoAcidResidue::Phenylalanine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00392 public:
00393     Phenylalanine()
00394         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("phenylalanine", "Phe", 'F')
00395     {
00396         static const mdunits::Length CB_CGdistance = 0.1510;
00397         static const mdunits::Length C_Hdistance = 0.1080; // from tinker amber99.dat
00398         static const mdunits::Length C_Cdistance = 0.1400; // from tinker amber99.dat
00399 
00400         // default angle for TrivalentAtom is 120 degrees, which is what we want
00401         // for a six-membered ring
00402         bondAtom( TrivalentAtom("CG", Element::Carbon()), "bondCB", CB_CGdistance, 180*Deg2Rad);
00403 
00404         bondAtom( TrivalentAtom("CD1", Element::Carbon()), "CG/bond2", C_Cdistance, 180*Deg2Rad );
00405         bondAtom( UnivalentAtom("HD1", Element::Hydrogen()), "CD1/bond3", C_Hdistance );
00406 
00407         // Start using hidedral of zero, to loop ring back to beginning
00408         bondAtom( TrivalentAtom("CE1", Element::Carbon()), "CD1/bond2", C_Cdistance, 0*Deg2Rad );
00409         bondAtom( UnivalentAtom("HE1", Element::Hydrogen()), "CE1/bond3", C_Hdistance );
00410 
00411         bondAtom( TrivalentAtom("CZ", Element::Carbon()), "CE1/bond2", C_Cdistance, 0*Deg2Rad );
00412         bondAtom( UnivalentAtom("HZ", Element::Hydrogen()), "CZ/bond3", C_Hdistance );
00413 
00414         bondAtom( TrivalentAtom("CE2", Element::Carbon()), "CZ/bond2", C_Cdistance, 0*Deg2Rad );
00415         bondAtom( UnivalentAtom("HE2", Element::Hydrogen()), "CE2/bond3", C_Hdistance );
00416 
00417         bondAtom( TrivalentAtom("CD2", Element::Carbon()), "CE2/bond2", C_Cdistance, 0*Deg2Rad );
00418         bondAtom( UnivalentAtom("HD2", Element::Hydrogen()), "CD2/bond3", C_Hdistance );
00419 
00420         addRingClosingBond("CD2/bond2", "CG/bond3", C_Cdistance, 0*Deg2Rad);
00421 
00422         defineDihedralAngle("chi2", "CD1", "CG", "CB", "CA");
00423 
00424         setDefaultDihedralAngle("chi2", 90*Deg2Rad); // from Dunbrack site
00425 
00426         setBondMobility(BondMobility::Rigid, "CG", "CD1");
00427         setBondMobility(BondMobility::Rigid, "CD1", "CE1");
00428         setBondMobility(BondMobility::Rigid, "CE1", "CZ");
00429         setBondMobility(BondMobility::Rigid, "CZ", "CE2");
00430         setBondMobility(BondMobility::Rigid, "CE2", "CD2");
00431         setBondMobility(BondMobility::Rigid, "CD2", "CG");
00432     }
00433 };
00434 
00435 
00436 class  AminoAcidResidue::Glycine : public AminoAcidResidue::HNAminoAcidResidue {
00437 public:
00438     Glycine() 
00439         : AminoAcidResidue::HNAminoAcidResidue("glycine", "Gly", 'G')
00440     {
00441         bondAtom(AliphaticHydrogen("2HA"), "bondCA");
00442         nameAtom("1HA", "HA");  // glycine names alpha hydrogen differently than others
00443     }
00444 };
00445 
00446 
00447 class  AminoAcidResidue::Histidine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00448 public:
00449     Histidine()
00450         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("histidine", "His", 'H')
00451     {
00452         // use average values for different protonation states
00453         static const mdunits::Length CB_CGdistance = 0.15040; // from tinker amber99.dat
00454         static const mdunits::Length CG_NDdistance = 0.13895; // average of protonation states 1385/1394
00455         static const mdunits::Length N_CEdistance = 0.13390; // average of protonation states 1343/1335
00456         static const mdunits::Length NE_CDdistance = 0.13875; // avg 1394/1381
00457         static const mdunits::Length CD_CGdistance = 0.1373; // avg 1371/1375
00458         static const mdunits::Length H_Cdistance = 0.1080;
00459         static const mdunits::Length H_Ndistance = 0.1010;
00460 
00461         // set angle to pentagonal angle 108, as amber parameters set 120 degrees as
00462         // "optimal" and let the forces fight it out.  Such a strategy will not
00463         // do for simple coordinate generation and for rigid body models.
00464         static const Angle ringAngle = 108.000 * Deg2Rad; // 108 degrees is exact
00465         static const Angle outerRingAngle = 180*Deg2Rad - 0.5*ringAngle;
00466 
00467         bondAtom( TrivalentAtom("CG", Element::Carbon(), outerRingAngle, outerRingAngle), "bondCB", CB_CGdistance);
00468 
00469         bondAtom( TrivalentAtom("ND1", Element::Nitrogen(), ringAngle, outerRingAngle), "CG/bond2", CG_NDdistance, 180*Deg2Rad);
00470         // optional proton depends upon protonation state
00471         bondAtom( UnivalentAtom("HD1", Element::Hydrogen()), "ND1/bond3", H_Ndistance);
00472 
00473         bondAtom( TrivalentAtom("CE1", Element::Carbon(), ringAngle, outerRingAngle), "ND1/bond2", N_CEdistance, 0*Deg2Rad);
00474         bondAtom( UnivalentAtom("HE1", Element::Hydrogen()), "CE1/bond3", H_Cdistance);
00475 
00476         bondAtom( TrivalentAtom("NE2", Element::Nitrogen(), ringAngle, outerRingAngle), "CE1/bond2", CG_NDdistance, 0*Deg2Rad);
00477         // optional proton depends upon protonation state
00478         bondAtom( UnivalentAtom("HE2", Element::Hydrogen()), "NE2/bond3", H_Ndistance);
00479 
00480         bondAtom( TrivalentAtom("CD2", Element::Carbon(), ringAngle, outerRingAngle), "NE2/bond2", N_CEdistance, 0*Deg2Rad);
00481         bondAtom( UnivalentAtom("HD2", Element::Hydrogen()), "CD2/bond3", H_Cdistance);
00482 
00483         addRingClosingBond("CD2/bond2", "CG/bond3", CD_CGdistance, 0*Deg2Rad);
00484 
00485         defineDihedralAngle("chi2", "ND1", "CG", "CB", "CA");
00486 
00487         setDefaultDihedralAngle("chi2", 90*Deg2Rad); // from Dunbrack site
00488 
00489         // Biotypes for histidine are tricky
00490         // Since both acidic protons are added above, this residue defaults to positive charge
00491         // There is more work to do to handle HIS protonation properly TODO
00492 
00493         // Synonym hints to help resolve biotypes from tinker files
00494         // eventually, these biotypes will be pre-defined and hard coded
00495         addCompoundSynonym("histidine (+)");
00496 
00497         // Make ring rigid for internal coordinate simulation
00498         setBondMobility(BondMobility::Rigid, "CG", "ND1");
00499         setBondMobility(BondMobility::Rigid, "ND1", "CE1");
00500         setBondMobility(BondMobility::Rigid, "CE1", "NE2");
00501         setBondMobility(BondMobility::Rigid, "NE2", "CD2");
00502         setBondMobility(BondMobility::Rigid, "CD2", "CG");
00503     }
00504 };
00505 
00506 
00507 // Unlike the case with Threonine, the chirality of Isoleucine comes out
00508 // correctly when built up from BetaBranchedAminoAcidResidue
00509 class  AminoAcidResidue::Isoleucine : public AminoAcidResidue::BetaBranchedAminoAcidResidue {
00510 public:
00511     Isoleucine()
00512         : AminoAcidResidue::BetaBranchedAminoAcidResidue("isoleucine", "Ile", 'I')
00513     {
00514         bondCompound("gamma methylene", MethyleneGroup(), "bondCB1");
00515         nameAtom("CG1", "gamma methylene/C");
00516         nameAtom("1HG1", "gamma methylene/H1");
00517         nameAtom("2HG1", "gamma methylene/H2");
00518 
00519         bondCompound("delta methyl", MethylGroup(), "gamma methylene/bond2");
00520         nameAtom("CD", "delta methyl/C");
00521         nameAtom("1HD", "delta methyl/H1");
00522         nameAtom("2HD", "delta methyl/H2");
00523         nameAtom("3HD", "delta methyl/H3");
00524 
00525         bondCompound("gamma methyl", MethylGroup(), "bondCB2");
00526         nameAtom("CG2", "gamma methyl/C");
00527         nameAtom("1HG2", "gamma methyl/H1");
00528         nameAtom("2HG2", "gamma methyl/H2");
00529         nameAtom("3HG2", "gamma methyl/H3");
00530 
00531         defineDihedralAngle("chi2", "CD", "CG1", "CB", "CA");
00532 
00533         setDefaultDihedralAngle("chi1", -70*Deg2Rad);
00534         setDefaultDihedralAngle("chi2", 170*Deg2Rad);
00535     }
00536 };
00537 
00538 
00539 class  AminoAcidResidue::Lysine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00540 public:
00541     Lysine()
00542         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("lysine", "Lys", 'K') 
00543     {
00544         bondAtom(AliphaticCarbon("CG"), "bondCB");
00545         bondAtom(AliphaticHydrogen("1HG"), "CG/bond3");
00546         bondAtom(AliphaticHydrogen("2HG"), "CG/bond4");
00547 
00548         bondAtom(AliphaticCarbon("CD"), "CG/bond2");
00549         bondAtom(AliphaticHydrogen("1HD"), "CD/bond3");
00550         bondAtom(AliphaticHydrogen("2HD"), "CD/bond4");
00551 
00552         bondAtom(AliphaticCarbon("CE"), "CD/bond2");
00553         bondAtom(AliphaticHydrogen("1HE"), "CE/bond3");
00554         bondAtom(AliphaticHydrogen("2HE"), "CE/bond4");
00555 
00556         bondCompound("zeta amine", PrimaryAmineGroup(), "CE/bond2");
00557         nameAtom("NZ", "zeta amine/N");
00558         nameAtom("1HZ", "zeta amine/H1");
00559         nameAtom("2HZ", "zeta amine/H2");
00560         nameAtom("3HZ", "zeta amine/H3");
00561 
00562         defineDihedralAngle("chi2", "CD", "CG", "CB", "CA");
00563         defineDihedralAngle("chi3", "CE", "CD", "CG", "CB");
00564         defineDihedralAngle("chi4", "NZ", "CE", "CD", "CG");
00565         defineDihedralAngle("chi5", "1HZ", "NZ", "CE", "CD");
00566     }
00567 };
00568 
00569     
00570 class  AminoAcidResidue::Leucine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00571 public:
00572     Leucine()
00573         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("leucine", "Leu", 'L')
00574     {
00575         bondAtom(AliphaticCarbon("CG"), "bondCB");
00576         bondAtom(AliphaticHydrogen("HG"), "CG/bond4");
00577 
00578         // It actually takes more lines of code to add a MethylGroup and rename the 
00579         // atoms, than it does to add the atoms individually
00580 
00581         // First delta methyl group
00582         bondAtom(AliphaticCarbon("CD1"), "CG/bond2");
00583         bondAtom(AliphaticHydrogen("1HD1"), "CD1/bond2");
00584         bondAtom(AliphaticHydrogen("2HD1"), "CD1/bond3");
00585         bondAtom(AliphaticHydrogen("3HD1"), "CD1/bond4");
00586 
00587         // Second delta methyl group
00588         bondAtom(AliphaticCarbon("CD2"), "CG/bond3");
00589         bondAtom(AliphaticHydrogen("1HD2"), "CD2/bond2");
00590         bondAtom(AliphaticHydrogen("2HD2"), "CD2/bond3");
00591         bondAtom(AliphaticHydrogen("3HD2"), "CD2/bond4");
00592 
00593         defineDihedralAngle("chi2", "CD1", "CG", "CB", "CA");
00594 
00595         setDefaultDihedralAngle("chi1", -70*Deg2Rad);
00596         setDefaultDihedralAngle("chi2", 170*Deg2Rad);
00597     }
00598 };
00599 
00600 
00601 class  AminoAcidResidue::Methionine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00602 public:
00603     Methionine()
00604         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("methionine", "Met", 'M') 
00605     {
00606         bondAtom(AliphaticCarbon("CG"), "bondCB");
00607         bondAtom(AliphaticHydrogen("1HG"), "CG/bond3");
00608         bondAtom(AliphaticHydrogen("2HG"), "CG/bond4");
00609 
00610         bondAtom( BivalentAtom("SD", Element::Sulfur(), 98.90*Deg2Rad), "CG/bond2", 0.1810, 180*Deg2Rad);
00611 
00612         bondAtom(AliphaticCarbon("CE"), "SD/bond2", 0.1810, 180*Deg2Rad);
00613         bondAtom(AliphaticHydrogen("1HE"), "CE/bond2");
00614         bondAtom(AliphaticHydrogen("2HE"), "CE/bond3");
00615         bondAtom(AliphaticHydrogen("3HE"), "CE/bond4");
00616 
00617         defineDihedralAngle("chi2", "SD", "CG", "CB", "CA");
00618         defineDihedralAngle("chi3", "CE", "SD", "CG", "CB");
00619         defineDihedralAngle("chi4", "1HE", "CE", "SD", "CG");
00620     }
00621 };
00622 
00623     
00624 class  AminoAcidResidue::Asparagine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00625 public:
00626     Asparagine() 
00627         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("asparagine", "Asn", 'N')
00628     {
00629         bondAtom(TrivalentAtom("CG", Element::Carbon(), 120.4*Deg2Rad, 116.6*Deg2Rad), "bondCB", 0.15220);
00630 
00631         bondAtom(UnivalentAtom("OD1", Element::Oxygen()), "CG/bond2", 0.12290);
00632 
00633         bondAtom(TrivalentAtom("ND2", Element::Nitrogen()), "CG/bond3", 0.13350);
00634         bondAtom(UnivalentAtom("1HD2", Element::Hydrogen()), "ND2/bond2", 0.1010);
00635         bondAtom(UnivalentAtom("2HD2", Element::Hydrogen()), "ND2/bond3", 0.1010);
00636 
00637         defineDihedralAngle("chi2", "OD1", "CG", "CB", "CA");
00638 
00639         // From Roland Dunbrack's side chain rotamer statistics
00640         // http://dunbrack.fccc.edu/bbdep/confanalysis.php
00641         setDefaultDihedralAngle("chi2", -20*Deg2Rad);
00642 
00643         // For internal coordinate simulation, make amide group rigid
00644         setBondMobility(BondMobility::Rigid, "CG", "ND2");
00645     }
00646 };
00647 
00648 
00649 class  AminoAcidResidue::Proline : public AminoAcidResidue {
00650 public:
00651     Proline() 
00652         : AminoAcidResidue("proline", "Pro", 'P')
00653     {
00654         // TODO check chirality of all these hydrogen names (in all residues)
00655 
00656         // beta methylene
00657         bondAtom(AliphaticCarbon("CB"), "bondCA");
00658         bondAtom(AliphaticHydrogen("1HB"), "CB/bond3");
00659         bondAtom(AliphaticHydrogen("2HB"), "CB/bond4");
00660 
00661         // gamma methylene
00662         bondAtom(AliphaticCarbon("CG"), "CB/bond2");
00663         bondAtom(AliphaticHydrogen("1HG"), "CG/bond3");
00664         bondAtom(AliphaticHydrogen("2HG"), "CG/bond4");
00665 
00666         // delta methylene
00667         bondAtom(AliphaticCarbon("CD"), "CG/bond2");
00668         bondAtom(AliphaticHydrogen("1HD"), "CD/bond3");
00669         bondAtom(AliphaticHydrogen("2HD"), "CD/bond4");
00670 
00671         addRingClosingBond("CD/bond2", "N/bond3", 0.14490);
00672 
00673         // defineDihedralAngle("phi", "CD", "N", "CA", "C", 180*Deg2Rad);
00674 
00675         defineDihedralAngle("chi1", "CG", "CB", "CA", "N");
00676         defineDihedralAngle("chi2", "CD", "CG", "CB", "CA");
00677         defineDihedralAngle("chi3", "N", "CD", "CG", "CB");
00678         defineDihedralAngle("chi4", "CA", "N", "CD", "CG"); // ring closing bond...
00679 
00680         // Ring strain decreases bond angles in the side chain
00681         // 102.9 chosen to match bond distance N-CD in beta down configuration
00682         // cmbruns
00683         setDefaultBondAngle(102.9*Deg2Rad, "N", "CA", "CB");
00684         setDefaultBondAngle(102.9*Deg2Rad, "CA", "CB", "CG");
00685         setDefaultBondAngle(102.9*Deg2Rad, "CB", "CG", "CD");
00686         setDefaultBondAngle(102.9*Deg2Rad, "CG", "CD", "N");
00687 
00688         setDefaultDownPucker();
00689         setDefaultPhiAngle(-70*Deg2Rad);
00690 
00691         // Fix phi angle for internal coordinate simulation
00692         setBondMobility(BondMobility::Rigid, "N", "CA");
00693     }
00694 
00695     // Up and down configurations are about equally abundant,
00696     // except in cis-proline, where down is preferred.
00697     // 
00698     // Ho, B.K.; Coutsias, E.A.; Seok, C.; & Dill, K.A. (2005) 
00699     // "The flexibility in the proline ring couples to the protein
00700     // backbone"  Protein Science: 14:1011-1018
00701 
00702     Proline& setDefaultUpPucker() { // red
00703         // Angles are estimated from figures in Ho et al
00704         // TODO get more accurate angles
00705         setDefaultDihedralAngle("chi1", -25*Deg2Rad);
00706         setDefaultDihedralAngle("chi2", 42*Deg2Rad);
00707         setDefaultDihedralAngle("chi3", -38*Deg2Rad);
00708         setDefaultDihedralAngle("chi4", 20*Deg2Rad);
00709 
00710         return *this;
00711     }
00712 
00713     Proline& setDefaultDownPucker() { // yellow, CG-endo
00714         // Angles from gaussian03 6-31G** restricted Hartree-Fock
00715         // minimization in beta main chain configuration
00716         setDefaultDihedralAngle("chi1", 32.8*Deg2Rad);
00717         setDefaultDihedralAngle("chi2", -35.9*Deg2Rad);
00718         setDefaultDihedralAngle("chi3", 25.0*Deg2Rad);
00719         setDefaultDihedralAngle("chi4", -16.9*Deg2Rad);
00720 
00721         // Angles are estimated from figures in Ho et al
00722         //setDefaultDihedralAngle("chi1", 30*Deg2Rad);
00723         //setDefaultDihedralAngle("chi2", -42*Deg2Rad);
00724         //setDefaultDihedralAngle("chi3", 38*Deg2Rad);
00725         //setDefaultDihedralAngle("chi4", -20*Deg2Rad);
00726 
00727         return *this;
00728     }
00729 
00730 };
00731 
00732 
00733 class  AminoAcidResidue::Glutamine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00734 public:
00735     Glutamine() 
00736         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("glutamine", "Gln", 'Q')
00737     {
00738         bondAtom( AliphaticCarbon("CG"), "bondCB" );
00739         bondAtom( AliphaticHydrogen("1HG"), "CG/bond3" ); 
00740         bondAtom( AliphaticHydrogen("2HG"), "CG/bond4" ); 
00741 
00742         bondAtom(TrivalentAtom("CD", Element::Carbon(), 120.4*Deg2Rad, 116.6*Deg2Rad), "CG/bond2", 0.15220);
00743 
00744         bondAtom(UnivalentAtom("OE1", Element::Oxygen()), "CD/bond2", 0.12290);
00745 
00746         bondAtom(TrivalentAtom("NE2", Element::Nitrogen()), "CD/bond3", 0.13350);
00747         bondAtom(UnivalentAtom("1HE2", Element::Hydrogen()), "NE2/bond2", 0.1010);
00748         bondAtom(UnivalentAtom("2HE2", Element::Hydrogen()), "NE2/bond3", 0.1010);
00749 
00750         defineDihedralAngle("chi2", "CD", "CG", "CB", "CA");
00751         defineDihedralAngle("chi3", "OE1", "CD", "CG", "CB");
00752 
00753         setDefaultDihedralAngle("chi3", -20*Deg2Rad);
00754 
00755         // For internal coordinate simulation, make amide group rigid
00756         setBondMobility(BondMobility::Rigid, "CD", "NE2");
00757 
00758     }
00759 };
00760 
00761 
00762 class  AminoAcidResidue::Arginine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00763 public:
00764     Arginine()
00765         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("arginine", "Arg", 'R') 
00766     {
00767         bondAtom(AliphaticCarbon("CG"), "bondCB");
00768         bondAtom(AliphaticHydrogen("1HG"), "CG/bond3");
00769         bondAtom(AliphaticHydrogen("2HG"), "CG/bond4");
00770 
00771         bondAtom(AliphaticCarbon("CD"), "CG/bond2");
00772         bondAtom(AliphaticHydrogen("1HD"), "CD/bond3");
00773         bondAtom(AliphaticHydrogen("2HD"), "CD/bond4");
00774 
00775         // TODO - set bond angle CB/CD/NE to 111.2
00776 
00777         bondAtom(TrivalentAtom("NE", Element::Nitrogen(), 123.2*Deg2Rad, 118.4*Deg2Rad), "CD/bond2", 0.1436, 180*Deg2Rad);
00778         bondAtom(UnivalentAtom("HE", Element::Hydrogen()), "NE/bond3", 0.1010);
00779 
00780         bondAtom(TrivalentAtom("CZ", Element::Carbon()), "NE/bond2", 0.1340, 180*Deg2Rad);
00781 
00782         bondAtom(TrivalentAtom("NH1", Element::Nitrogen()), "CZ/bond2", 0.1340, 180*Deg2Rad);
00783         bondAtom(UnivalentAtom("1HH1", Element::Hydrogen()), "NH1/bond2", 0.1010);
00784         bondAtom(UnivalentAtom("2HH1", Element::Hydrogen()), "NH1/bond3", 0.1010);
00785 
00786         bondAtom(TrivalentAtom("NH2", Element::Nitrogen()), "CZ/bond3", 0.1340, 180*Deg2Rad);
00787         bondAtom(UnivalentAtom("1HH2", Element::Hydrogen()), "NH2/bond2", 0.1010);
00788         bondAtom(UnivalentAtom("2HH2", Element::Hydrogen()), "NH2/bond3", 0.1010);
00789 
00790         defineDihedralAngle("chi2", "CD", "CG", "CB", "CA");
00791         defineDihedralAngle("chi3", "NE", "CD", "CG", "CB");
00792         defineDihedralAngle("chi4", "CZ", "NE", "CD", "CG");
00793         defineDihedralAngle("chi5", "NH1", "CZ", "NE", "CD");
00794 
00795         // TODO research default dihedral for chi4
00796 
00797         // Make guanidinium group rigid for internal coordinate simulation (resonance)
00798         setBondMobility(BondMobility::Rigid, "CZ", "NH1");
00799         setBondMobility(BondMobility::Rigid, "CZ", "NH2");
00800         setBondMobility(BondMobility::Rigid, "NE", "CZ");
00801     }
00802 };
00803 
00804     
00805 class  AminoAcidResidue::Serine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00806 public:
00807     Serine() 
00808         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("serine", "Ser", 'S')
00809     {
00810         // side chain hydroxyl group
00811         bondCompound("oh", AlcoholOHGroup(), "bondCB");
00812         nameAtom("OG", "oh/O", Biotype::SerineOG().getIndex() );
00813         nameAtom("HG", "oh/H", Biotype::SerineHG().getIndex() );
00814 
00815         defineDihedralAngle("chi2", "HG", "OG", "CB", "CA");
00816 
00817         // Set atom biotypes
00818         setBiotypeIndex("N", Biotype::SerineN().getIndex() );
00819         setBiotypeIndex("HN", Biotype::SerineHN().getIndex() );
00820         setBiotypeIndex("CA", Biotype::SerineCA().getIndex() );
00821         setBiotypeIndex("HA", Biotype::SerineHA().getIndex() );
00822         setBiotypeIndex("C", Biotype::SerineC().getIndex() );
00823         setBiotypeIndex("O", Biotype::SerineO().getIndex() );
00824     }
00825 };
00826 
00827 // Threonine has a chirality about the beta carbon, so care
00828 // must be observed when placing groups
00829 // Thus derive from AminoAcidResidue instead of from BetaBranchedAminoAcidResidue
00830 class  AminoAcidResidue::Threonine : public AminoAcidResidue::BetaBranchedAminoAcidResidue {
00831 public:
00832     Threonine()
00833         : AminoAcidResidue::BetaBranchedAminoAcidResidue("threonine", "Thr", 'T')
00834     {
00835         // hydroxyl has precedence over methyl and hydrogen
00836         // w.r.t. dihedral definition
00837         bondCompound("gamma hydroxyl", AlcoholOHGroup(), "bondCB1");
00838         nameAtom("OG1", "gamma hydroxyl/O");
00839         nameAtom("HG1", "gamma hydroxyl/H");
00840 
00841         // place methyl and hydrogen so as to get correct chirality
00842         // i.e. clockwise rotation of OG/H/CG when viewed down CA/CB bond
00843 
00844         bondCompound("gamma methyl", MethylGroup(), "bondCB2");
00845         nameAtom("CG2", "gamma methyl/C");
00846         nameAtom("1HG2", "gamma methyl/H1");
00847         nameAtom("2HG2", "gamma methyl/H2");
00848         nameAtom("3HG2", "gamma methyl/H3");
00849     }
00850 };
00851 
00852 
00853 // To get atom precedence correct, build custom side chain,
00854 // rather than deriving from BetaBranchedAminoAcidResidue
00855 class  AminoAcidResidue::Valine : public AminoAcidResidue::HNAminoAcidResidue {
00856 public:
00857     Valine()
00858         : AminoAcidResidue::HNAminoAcidResidue("valine", "Val", 'V')
00859     {
00860         bondAtom(AliphaticCarbon("CB"), "bondCA");
00861         bondAtom(AliphaticHydrogen("HB"), "CB/bond4");
00862 
00863         bondCompound("gamma methyl 1", MethylGroup(), "CB/bond2");
00864         nameAtom("CG1", "gamma methyl 1/C");
00865         nameAtom("1HG1", "gamma methyl 1/H1");
00866         nameAtom("2HG1", "gamma methyl 1/H2");
00867         nameAtom("3HG1", "gamma methyl 1/H3");
00868 
00869         bondCompound("gamma methyl 2", MethylGroup(), "CB/bond3");
00870         nameAtom("CG2", "gamma methyl 2/C");
00871         nameAtom("1HG2", "gamma methyl 2/H1");
00872         nameAtom("2HG2", "gamma methyl 2/H2");
00873         nameAtom("3HG2", "gamma methyl 2/H3");
00874 
00875         defineDihedralAngle("chi1", "CG1", "CB", "CA", "N");
00876 
00877         // definition of CG1 vs. CG2 makes preferred chi1 180 instead of -60 for valine
00878         setDefaultDihedralAngle("chi1", 180*Deg2Rad);
00879     }
00880 };
00881 
00882 
00883 class  AminoAcidResidue::Tryptophan : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00884 public:
00885     Tryptophan()
00886         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("tryptophan", "Trp", 'W')
00887     {
00888         bondAtom( TrivalentAtom("CG", Element::Carbon(), 125.0*Deg2Rad, 128.6*Deg2Rad), "bondCB", 0.14950);
00889 
00890         // 125.65 angle computed to place hydrogen symmetrically
00891         bondAtom( TrivalentAtom("CD1", Element::Carbon(), 108.7*Deg2Rad, 125.65*Deg2Rad), "CG/bond2", 0.13520, 180*Deg2Rad);
00892         bondAtom( UnivalentAtom("HD1", Element::Hydrogen()), "CD1/bond3", 0.1080);
00893 
00894         // 124.25 computed to center hydrogen
00895         bondAtom( TrivalentAtom("NE1", Element::Nitrogen(), 111.50*Deg2Rad, 124.25*Deg2Rad), "CD1/bond2", 0.13810, 0*Deg2Rad);
00896         bondAtom( UnivalentAtom("HE1", Element::Hydrogen()), "NE1/bond3", 0.1010);
00897 
00898         bondAtom( TrivalentAtom("CE2", Element::Carbon(), 104.4*Deg2Rad, 132.80*Deg2Rad), "NE1/bond2", 0.1380, 0*Deg2Rad);
00899 
00900         // 180 degrees to bulge back out for the six-membered ring
00901         bondAtom( TrivalentAtom("CZ2", Element::Carbon()), "CE2/bond3", 0.1400, 180*Deg2Rad);
00902         bondAtom( UnivalentAtom("HZ2", Element::Hydrogen()), "CZ2/bond3", 0.1080);
00903 
00904         bondAtom( TrivalentAtom("CH2", Element::Carbon()), "CZ2/bond2", 0.1400, 0*Deg2Rad);
00905         bondAtom( UnivalentAtom("HH2", Element::Hydrogen()), "CH2/bond3", 0.1080);
00906 
00907 
00908 
00909         bondAtom( TrivalentAtom("CD2", Element::Carbon(), 108.8*Deg2Rad, 122.7*Deg2Rad), "CE2/bond2", 0.1419, 0*Deg2Rad);
00910         addRingClosingBond("CD2/bond2", "CG/bond3", 0.1459);
00911 
00912         bondAtom( TrivalentAtom("CE3", Element::Carbon()), "CD2/bond3", 0.1404, 0*Deg2Rad);
00913         bondAtom( UnivalentAtom("HE3", Element::Hydrogen()), "CE3/bond3", 0.1080);
00914 
00915         bondAtom( TrivalentAtom("CZ3", Element::Carbon()), "CE3/bond2", 0.1400, 0*Deg2Rad);
00916         bondAtom( UnivalentAtom("HZ3", Element::Hydrogen()), "CZ3/bond3", 0.1080);
00917 
00918         addRingClosingBond("CZ3/bond2", "CH2/bond2", 0.1400);
00919 
00920         defineDihedralAngle("chi2", "CD1", "CG", "CB", "CA");
00921 
00922         setDefaultDihedralAngle("chi2", 90*Deg2Rad);
00923 
00924         setBondMobility(BondMobility::Rigid, "CG", "CD1");
00925         setBondMobility(BondMobility::Rigid, "CD1", "NE1");
00926         setBondMobility(BondMobility::Rigid, "NE1", "CE2");
00927         setBondMobility(BondMobility::Rigid, "CZ2", "CE2");
00928         setBondMobility(BondMobility::Rigid, "CH2", "CZ2");
00929         setBondMobility(BondMobility::Rigid, "CD2", "CE3");
00930         setBondMobility(BondMobility::Rigid, "CZ3", "CE3");
00931         setBondMobility(BondMobility::Rigid, "CZ3", "CH2");
00932     }
00933 };
00934 
00935 
00936 class  AminoAcidResidue::Tyrosine : public AminoAcidResidue::BetaUnbranchedAminoAcidResidue {
00937 public:
00938     Tyrosine()
00939         : AminoAcidResidue::BetaUnbranchedAminoAcidResidue("tyrosine", "Tyr", 'Y')
00940     {
00941         static const mdunits::Length CB_CGdistance = 0.1510;
00942         static const mdunits::Length C_Hdistance = 0.1080; // from tinker amber99.dat
00943         static const mdunits::Length C_Cdistance = 0.1400; // from tinker amber99.dat
00944         static const mdunits::Length CZ_Odistance = 0.1364; // from tinker amber99.dat
00945 
00946         // default angle for TrivalentAtom is 120 degrees, which is what we want
00947         // for a six-membered ring
00948         bondAtom( TrivalentAtom("CG", Element::Carbon()), "bondCB", CB_CGdistance, 180*Deg2Rad);
00949 
00950         bondAtom( TrivalentAtom("CD1", Element::Carbon()), "CG/bond2", C_Cdistance, 180*Deg2Rad );
00951         bondAtom( UnivalentAtom("HD1", Element::Hydrogen()), "CD1/bond3", C_Hdistance );
00952 
00953         // Start using hidedral of zero, to loop ring back to beginning
00954         bondAtom( TrivalentAtom("CE1", Element::Carbon()), "CD1/bond2", C_Cdistance, 0*Deg2Rad );
00955         bondAtom( UnivalentAtom("HE1", Element::Hydrogen()), "CE1/bond3", C_Hdistance );
00956 
00957         bondAtom( TrivalentAtom("CZ", Element::Carbon()), "CE1/bond2", C_Cdistance, 180*Deg2Rad );
00958         bondCompound( "oh", AlcoholOHGroup(), "CZ/bond2", CZ_Odistance );
00959         nameAtom("OH", "oh/O");
00960         nameAtom("HH", "oh/H");
00961 
00962         bondAtom( TrivalentAtom("CE2", Element::Carbon()), "CZ/bond3", C_Cdistance, 0*Deg2Rad );
00963         bondAtom( UnivalentAtom("HE2", Element::Hydrogen()), "CE2/bond3", C_Hdistance );
00964 
00965         bondAtom( TrivalentAtom("CD2", Element::Carbon()), "CE2/bond2", C_Cdistance, 0*Deg2Rad );
00966         bondAtom( UnivalentAtom("HD2", Element::Hydrogen()), "CD2/bond3", C_Hdistance );
00967 
00968         addRingClosingBond("CD2/bond2", "CG/bond3", 0.1459);
00969 
00970         defineDihedralAngle("chi2", "CD1", "CG", "CB", "CA");
00971 
00972         setDefaultDihedralAngle("chi2", 90*Deg2Rad); // from Dunbrack site
00973 
00974         setBondMobility(BondMobility::Rigid, "CG", "CD1");
00975         setBondMobility(BondMobility::Rigid, "CD1", "CE1");
00976         setBondMobility(BondMobility::Rigid, "CE1", "CZ");
00977         setBondMobility(BondMobility::Rigid, "CZ", "CE2");
00978         setBondMobility(BondMobility::Rigid, "CE2", "CD2");
00979         setBondMobility(BondMobility::Rigid, "CD2", "CG");
00980     }
00981 };
00982 
00983 
00984 class SimTK_MOLMODEL_EXPORT Protein : public Biopolymer {
00985 public:
00986 
00987     void loadFromPdbStructure(const PdbStructure& pdbStructure, SimTK::Real targetRms)
00988     {
00989         const PdbChain& pdbChain = pdbStructure.getModel(Pdb::ModelIndex(0)).getChain(Pdb::ChainIndex(0));
00990         loadFromPdbChain(pdbChain, targetRms);
00991     }
00992     
00993     void loadFromPdbChain(const PdbChain& pdbChain, SimTK::Real targetRms);
00994     
00995     explicit Protein(std::istream& pdbStream, SimTK::Real targetRms = 0.02)
00996     {
00997         PdbStructure pdbStructure(pdbStream);
00998         loadFromPdbStructure(pdbStructure, targetRms);
00999     }
01000     
01001     explicit Protein(const PdbStructure& pdbStructure, SimTK::Real targetRms = 0.02)
01002     {
01003         loadFromPdbStructure(pdbStructure, targetRms);
01004     }
01005     
01006     explicit Protein(const PdbChain& pdbChain, SimTK::Real targetRms)
01007     {
01008         loadFromPdbChain(pdbChain, targetRms);
01009     }
01010     
01011     explicit Protein(const Sequence& seq, const BondMobility::Mobility mobility= BondMobility::Rigid, bool addEndCaps = true  ) 
01012     {
01013         initialize(seq, mobility, addEndCaps);
01014     }
01015     
01016     explicit Protein( const Sequence& seq, CompoundSystem& system, Transform transform = Transform() ) 
01017     {
01018         initialize(seq, BondMobility::Rigid);
01019         system.adoptCompound(*this, transform);
01020     }
01021     
01022 protected:
01023     void initialize( const Sequence& seq, const BondMobility::Mobility mobility , bool addEndCaps = true) 
01024     {
01025         Biotype::initializePopularBiotypes();
01026         
01027         // TODO - provide alternatives for end caps
01028         String previousResidueName = "acetyl0";
01029         if (addEndCaps) appendResidue(previousResidueName, AcetylResidue());
01030 
01031         for (int resi = 0; resi < (int)seq.size(); ++resi)
01032         {
01033             AminoAcidResidue residue = AminoAcidResidue::create(seq[resi]);
01034             residue.setPdbResidueNumber(resi + 1);
01035             residue.assignBiotypes();
01036 
01037             // Name residue subcompound after its number in the sequence
01038             // name must be unique within the protein
01039             String residueName(resi);
01040             appendResidue( residueName, residue );
01041 
01042             // Rigidify peptide bond 
01043             if (getNumResidues() > 1) // First residue lacks a preceding peptide bond
01044             {
01045                 String omegaAngleName = String("omega") + String(resi);
01046 
01047                 defineDihedralAngle(
01048                     omegaAngleName, 
01049                     previousResidueName+"/C/bond1", 
01050                     residueName+"/N/bond2");
01051                 setDefaultDihedralAngle(omegaAngleName, 180*Deg2Rad);
01052 
01053                 // Make omega torsion rigid
01054                 String cAtomName = previousResidueName + "/" + "C";
01055                 String nAtomName = residueName + "/" + "N";
01056                 setBondMobility(mobility, cAtomName, nAtomName);
01057             }
01058 
01059             previousResidueName = residueName;
01060         }
01061 
01062         // Create C-terminal end cap, if we are producing end caps
01063         if (addEndCaps) {
01064             String cCapName = String("nme") + String((int)seq.size());
01065             appendResidue(cCapName, NMethylAmideResidue());
01066             // Rigidify end cap's omega angle (regardless of setting above).
01067             String omegaAngleName = String("omega") + String(cCapName);
01068             defineDihedralAngle(
01069                 omegaAngleName, 
01070                 previousResidueName+"/C/bond1", 
01071                 cCapName+"/N/bond2");
01072             setDefaultDihedralAngle(omegaAngleName, 180*Deg2Rad);
01073 
01074             // Make omega torsion rigid
01075             String cAtomName = previousResidueName + "/" + "C";
01076             String nAtomName = cCapName + "/" + "N";
01077             setBondMobility(BondMobility::Rigid, cAtomName, nAtomName);
01078         }
01079     }
01080 };
01081 
01082 
01083 } // namespace SimTK
01084 
01085 #endif // SimTK_MOLMODEL_PROTEIN_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines