Compound.h

Go to the documentation of this file.
00001 #ifndef SimTK_MOLMODEL_COMPOUND_H_
00002 #define SimTK_MOLMODEL_COMPOUND_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-2008 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 "SimTKsimbody.h"
00037 
00038 #include "molmodel/internal/common.h"
00039 #include "TinkerDuMMForceFieldSubsystem.h"
00040 #include "molmodel/internal/Pdb.h"
00041 #include "molmodel/internal/Superpose.h"
00042 #include "molmodel/internal/units.h"
00043 #include <map>
00044 
00045 #include <iosfwd> // declare ostream without all the definitions
00046 
00047 namespace SimTK {
00048 class CompoundSystem;
00049 
00050 // Because of private data, put Compound implementation behind the curtain
00051 class Compound;
00052 class CompoundRep;
00053 
00054 // Make sure class is instantiated just once in the library
00055 // #ifndef DO_INSTANTIATE_COMPOUND_PIMPL_HANDLE
00056 //    template class SimTK_MOLMODEL_EXPORT PIMPLHandle<Compound, CompoundRep>;
00057 // #endif
00058 
00062 namespace BondMobility {
00070     enum Mobility {
00071         Free = 1, 
00072         Torsion = 2, 
00073         Rigid = 3 
00074     };
00075     static Mobility Default = Torsion;
00076 }
00077 
00084 class SimTK_MOLMODEL_EXPORT Compound : public PIMPLHandle<Compound,CompoundRep> {
00085 public:
00086 
00089 
00095     typedef String Name;
00096 
00110     typedef String AtomName;
00111 
00122     typedef String BondCenterName;
00123 
00130     typedef String DihedralName;
00131 
00142     typedef String BondCenterPathName;
00143 
00157     typedef String AtomPathName;
00158 
00159     // Unique classes which behave like type-safe ints. These are local
00160     // to Compound.
00161 
00167     SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(Compound,Index);
00168 
00169 
00175     SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(Compound,AtomIndex);
00176 
00182     SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(Compound,LocalAtomIndex);
00183 
00189     SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(Compound,BondCenterIndex);
00190 
00196     SimTK_DEFINE_UNIQUE_LOCAL_INDEX_TYPE(Compound,BondIndex);
00197 
00199     typedef std::map<AtomIndex, Vec3> AtomTargetLocations;
00200 
00201     class SingleAtom;
00202 
00204 
00205 
00208 
00214     Compound();
00215 
00223     explicit Compound(const Name& name 
00224         );
00225 
00229     int getNAtoms() const;
00230 
00232     size_t getNBondCenters() const;
00233 
00235     size_t getNBondCenters(Compound::AtomIndex atomIndex) const;
00236 
00238     size_t getNBonds() const;
00239 
00241     int getNSubcompounds() const;
00242 
00244     bool hasAtom(const AtomPathName& name 
00245         ) const;
00246 
00248     bool hasBondCenter(const BondCenterPathName& bondCenter 
00249         ) const;
00250 
00252     bool hasSubcompound(const Name& name 
00253         ) const;
00254 
00256     Compound::AtomIndex getBondAtomIndex(
00257         Compound::BondIndex bondIndex, 
00258         int which                      
00259         ) const;
00260 
00261 
00267     Compound& setBaseAtom(
00268         const Compound::AtomName& name,   
00269         const Element& element,           
00270         const Vec3& location = Vec3(0));  
00271 
00277     Compound& setBaseAtom(
00278         const Compound::AtomName& name,   
00279         const Biotype& biotype,           
00280         const Vec3& location = Vec3(0)    
00281         );  
00282 
00289     Compound& setBaseAtom(
00290         const Compound::SingleAtom& c, 
00291         const Transform& = Transform() 
00292         ); 
00293 
00299     Compound& setBaseCompound(
00300         const Compound::Name& n,         
00301         const Compound& c,               
00302         const Transform& = Transform()); 
00303 
00310     Compound& bondAtom(
00311         const Compound::SingleAtom& c, 
00312         const BondCenterPathName& parentBondName, 
00313         mdunits::Length distance, 
00314         Angle dihedral = 0, 
00315         BondMobility::Mobility = BondMobility::Default 
00316         );
00317 
00327     Compound& bondAtom(
00328         const Compound::SingleAtom& c, 
00329         const BondCenterPathName& parentBondName);
00330 
00336     Compound& bondCompound(
00337         const Compound::Name& n, 
00338         const Compound& c, 
00339         const BondCenterPathName& parentBondName, 
00340         mdunits::Length distance, 
00341         Angle dihedral = 180*Deg2Rad, 
00342         BondMobility::Mobility mobility = BondMobility::Default 
00343         );
00344 
00354     Compound& bondCompound(
00355         const Compound::Name& n, 
00356         const Compound& c,  
00357         const BondCenterPathName& parentBondName 
00358         );
00359 
00369     Compound& bondCompound(
00370         const Compound::Name& n, 
00371         const Compound& c, 
00372         const BondCenterPathName& parentBondName,  
00373         BondMobility::Mobility mobility 
00374         );
00375 
00383     Compound& setInboardBondCenter(
00384         const Compound::BondCenterName& centerName 
00385         );
00386 
00392     Compound& convertInboardBondCenterToOutboard();
00393 
00399     Compound& addFirstBondCenter(
00400         const Compound::BondCenterName& centerName, 
00401         const Compound::AtomPathName& atomName 
00402         );
00403 
00410     Compound& addSecondBondCenter(
00411         const Compound::BondCenterName& centerName, 
00412         const Compound::AtomName& atomName, 
00413         Angle bondAngle1 
00414         );
00415 
00426     Compound& addPlanarBondCenter(
00427         const Compound::BondCenterName& centerName, 
00428         const Compound::AtomName& atomName, 
00429         Angle bondAngle1, 
00430         Angle bondAngle2 
00431         );
00432 
00442     Compound& addRightHandedBondCenter(
00443         const Compound::BondCenterName& centerName, 
00444         const Compound::AtomName& atomName, 
00445         Angle bondAngle1, 
00446         Angle bondAngle2 
00447         );
00448 
00458     Compound& addLeftHandedBondCenter(
00459         const Compound::BondCenterName& centerName, 
00460         const Compound::AtomName& atomName, 
00461         Angle bondAngle1, 
00462         Angle bondAngle2 
00463         );
00464 
00476     Compound& addRingClosingBond(
00477         const Compound::BondCenterPathName& centerName1, 
00478         const Compound::BondCenterPathName& centerName2, 
00479         mdunits::Length bondLength, 
00480         Angle dihedral = 180*Deg2Rad, 
00481         BondMobility::Mobility mobility = BondMobility::Default 
00482         );
00483 
00495     Compound& addRingClosingBond(
00496         const Compound::BondCenterPathName& centerName1, 
00497         const Compound::BondCenterPathName& centerName2 
00498         );
00499 
00501     const Compound& getSubcompound(Compound::Index 
00502         ) const;
00503 
00505     Compound& updSubcompound(Compound::Index 
00506         );
00507 
00509     const Compound& getSubcompound(const Compound::Name& subcompoundName 
00510         ) const;
00511 
00513     Compound& updSubcompound(const Compound::Name& subcompoundName 
00514         );
00515 
00517     // end topology methods
00518 
00519 
00522 
00528     Vec3 calcDefaultAtomLocationInGroundFrame(const AtomPathName& atomName 
00529         ) const;
00530 
00531     Vec3 calcDefaultAtomLocationInCompoundFrame(const AtomPathName& atomName 
00532         ) const;
00533 
00543     Compound& setDefaultInboardBondLength(mdunits::Length 
00544         );
00545 
00554     Compound& setDefaultInboardDihedralAngle(Angle 
00555         );
00556 
00565     Compound& setDefaultBondAngle(
00566         Angle angle, 
00567         const AtomPathName& atom1, 
00568         const AtomPathName& atom2, 
00569         const AtomPathName& atom3 
00570         );
00571 
00577     Compound& setDefaultBondLength(
00578         mdunits::Length length, 
00579         const AtomPathName& atom1, 
00580         const AtomPathName& atom2 
00581         );
00582 
00588     Compound& setDefaultDihedralAngle(
00589         const DihedralName& dihedralName, 
00590         Angle angleInRadians 
00591         );
00592 
00593     Compound& setDefaultDihedralAngle(
00594                 Angle angle, 
00595                 Compound::AtomIndex atom1,
00596                 Compound::AtomIndex atom2,
00597                 Compound::AtomIndex atom3,
00598                 Compound::AtomIndex atom4
00599                 );
00600     
00601     Compound& setDefaultDihedralAngle(
00602                 Angle angle, 
00603                 Compound::AtomName atom1,
00604                 Compound::AtomName atom2,
00605                 Compound::AtomName atom3,
00606                 Compound::AtomName atom4
00607                 );
00608     
00614     Angle calcDefaultDihedralAngle(
00615         const DihedralName& dihedralName 
00616         ) const;
00617 
00625     Compound& setDihedralAngle(
00626         State& state, 
00627         const DihedralName& dihedralName, 
00628         Angle 
00629         );
00630 
00636     Angle calcDihedralAngle(
00637         const State& state, 
00638         const DihedralName& dihedralName 
00639         ) const;
00640 
00642     Transform calcDefaultAtomFrameInCompoundFrame(Compound::AtomIndex 
00643         ) const;
00644 
00648     Vec3 calcAtomLocationInGroundFrame(
00649         const State& state, 
00650         Compound::AtomIndex atomId 
00651         ) const;
00652 
00653     Vec3 calcAtomLocationInCompoundFrame(
00654         const State& state, 
00655         Compound::AtomIndex atomId 
00656         ) const;
00657 
00661     Vec3 calcAtomVelocityInGroundFrame(
00662         const State& state, 
00663         Compound::AtomIndex atomId  
00664         ) const;
00665 
00669     Vec3 calcAtomAccelerationInGroundFrame(
00670         const State& state, 
00671         Compound::AtomIndex atomId   
00672         ) const;
00673 
00677     Transform getSubcompoundFrameInParentFrame(
00678         const Compound::Name& subcompoundName 
00679         ) const;
00680 
00686     AtomTargetLocations createAtomTargets(const class PdbStructure& targetStructure) const;
00687     AtomTargetLocations createAtomTargets(const class PdbChain& targetChain) const;
00688     AtomTargetLocations createAtomTargets(const class PdbResidue& targetResidue) const;
00689 
00690     Compound& matchDefaultAtomChirality(const AtomTargetLocations& atomTargets);
00691     Compound& matchDefaultBondLengths(const AtomTargetLocations& atomTargets);
00692     Compound& matchDefaultBondAngles(const AtomTargetLocations& atomTargets);
00693     Compound& matchDefaultDihedralAngles(const AtomTargetLocations& atomTargets);
00694     Compound& matchDefaultTopLevelTransform(const AtomTargetLocations& atomTargets);
00695     TransformAndResidual getTransformAndResidual(const Compound::AtomTargetLocations& atomTargets) const;
00696     Compound& matchDefaultConfiguration(const AtomTargetLocations& atomTargets);
00697 
00699     const Compound& populateDefaultPdbChain(
00700         class PdbChain&, 
00701         int& defaultNextResidueNumber,
00702         const Transform& transform = Transform()) const;
00703 
00705     const Compound& populatePdbChain(
00706         const State& state, 
00707         class PdbChain&, 
00708         int& defaultNextResidueNumber,
00709         const Transform& transform = Transform()) const;
00710 
00716     std::ostream& writeDefaultPdb(
00717         std::ostream& os, 
00718         const Transform& transform = Transform()  
00719         ) const;
00720 
00726     std::ostream& writeDefaultPdb(
00727         char* outFileName, 
00728         const Transform& transform
00729         ) const;
00730 
00738     std::ostream& writeDefaultPdb(
00739         std::ostream& os, 
00740         int& nextAtomSerialNumber, 
00741         const Transform& transform = Transform() 
00742         ) const;
00743 
00749     std::ostream& writePdb(
00750         const State& state, 
00751         std::ostream& os,  
00752         const Transform& transform = Transform() 
00753         ) const;
00754 
00755 
00760     std::ostream& writePdb(
00761         const State& state, 
00762         char* outFileName,  
00763         const Transform& transform = Transform() 
00764         ) const;
00765 
00773     std::ostream& writePdb(
00774         const State& state, 
00775         std::ostream& os,  
00776         int& nextAtomSerialNumber,  
00777         const Transform& transform = Transform() 
00778         ) const;
00779 
00781     // end configuration section
00782 
00783 
00786 
00796     Compound& setCompoundName(const Name& 
00797         );
00798 
00799 
00801     const Name& getCompoundName() const;
00802 
00811     Compound& addCompoundSynonym(const Name& 
00812         );
00813 
00818     const AtomPathName getAtomName(Compound::AtomIndex 
00819         ) const;
00820 
00822     const Element& getAtomElement(Compound::AtomIndex 
00823         ) const;
00824 
00825     const Element& getAtomElement(const Compound::AtomName& 
00826         ) const;
00827 
00831     Compound& nameAtom(
00832         const Compound::AtomName& newName, 
00833         const AtomPathName& oldName 
00834         );
00835 
00839     Compound& nameAtom(
00840         const Compound::AtomName& newName,  
00841         const AtomPathName& oldName,  
00842         BiotypeIndex biotype 
00843         );
00844 
00855     Compound& defineDihedralAngle(
00856         const Compound::DihedralName& angleName, 
00857         const Compound::AtomPathName& atom1, 
00858         const Compound::AtomPathName& atom2, 
00859         const Compound::AtomPathName& atom3, 
00860         const Compound::AtomPathName& atom4, 
00861         Angle offset = 0*Deg2Rad 
00862         );
00863 
00878     Compound& defineDihedralAngle(
00879         const Compound::DihedralName& angleName, 
00880         const Compound::BondCenterPathName& bond1, 
00881         const Compound::BondCenterPathName& bond2, 
00882         Angle offset = 0*Deg2Rad 
00883         );
00884 
00890     Compound& setPdbResidueNumber(int resNum);
00891 
00893     int getPdbResidueNumber() const;
00894 
00900     Compound& setPdbResidueName(const String& resName);
00901 
00903     const String& getPdbResidueName() const;
00904 
00910     Compound& setPdbChainId(char chainId 
00911         );
00912 
00914     char getPdbChainId() const;
00915 
00921     Compound& nameBondCenter(
00922         Compound::BondCenterName newName, 
00923         BondCenterPathName oldName 
00924         );
00925 
00931     Compound& inheritAtomNames(const Compound::Name& 
00932         );
00933     
00939     Compound& inheritBondCenterNames(const Compound::Name& 
00940         );
00941 
00943     Compound::AtomIndex getAtomIndex(const Compound::AtomPathName& 
00944         ) const;
00945 
00947     // end nomenclature methods
00948 
00949 
00952 
00958     void setCompoundSystem(CompoundSystem& system, 
00959                            Compound::Index);       
00960 
00966     Compound& setBondMobility(
00967         BondMobility::Mobility mobility, 
00968         const AtomPathName& atom1, 
00969         const AtomPathName& atom2 
00970         );
00971 
00977     Compound& setBondMobility(
00978         BondMobility::Mobility mobility,  
00979         Compound::BondIndex bondIndex 
00980         );
00981 
00989     Compound  & setCompoundBondMobility(BondMobility::Mobility mobility);
00990 
00998     MobilizedBodyIndex getAtomMobilizedBodyIndex(Compound::AtomIndex 
00999         ) const;
01000 
01008     Vec3 getAtomLocationInMobilizedBodyFrame(Compound::AtomIndex 
01009         ) const;
01010 
01016     Compound& setBiotypeIndex(
01017         const Compound::AtomPathName& atomName, 
01018         BiotypeIndex biotype 
01019         );
01020     
01021     Compound& setAtomBiotype(
01022             const Compound::AtomPathName& atomName,
01023             const String& biotypeResidueName,
01024             const String& biotypeAtomName,
01025             SimTK::Ordinality::Residue ordinality = SimTK::Ordinality::Any
01026             )
01027     {
01028         Compound::AtomIndex atomIndex = getAtomIndex(atomName);
01029         
01030         if ( ! Biotype::exists(biotypeResidueName, biotypeAtomName, ordinality) )
01031             Biotype::defineBiotype(
01032                 getAtomElement(atomIndex),
01033                 getNBondCenters(atomIndex), 
01034                 biotypeResidueName, 
01035                 biotypeAtomName, 
01036                 ordinality
01037             );
01038         
01039         const Biotype& biotype = Biotype::get(biotypeResidueName, biotypeAtomName, ordinality);
01040         
01041         assert( biotype.getElement() == getAtomElement(atomIndex) );
01042         assert( biotype.getValence() == getNBondCenters(atomIndex) );
01043         
01044         BiotypeIndex biotypeIndex = biotype.getIndex();
01045         setBiotypeIndex(atomName, biotypeIndex);
01046 
01047         return *this;
01048     }
01049 
01051     BiotypeIndex getAtomBiotypeIndex(Compound::AtomIndex 
01052         ) const;
01053 
01054     // RUNTIME INTERFACE
01055 
01063     DuMM::AtomIndex getDuMMAtomIndex(Compound::AtomIndex) const;
01064 
01066     // end simulation methods
01067 
01069     Compound& setTopLevelTransform(const Transform& transform);
01070 
01072     const Transform& getTopLevelTransform() const;
01073 
01074 
01075 protected:
01076 
01080     void setDuMMAtomIndex(
01081         Compound::AtomIndex, 
01082         DuMM::AtomIndex 
01083         );
01084 
01085     explicit Compound(CompoundRep* ip);
01086     friend class CompoundSystem;
01087 };
01088 
01089 
01097 SimTK_MOLMODEL_EXPORT std::ostream& operator<<(std::ostream& o, const Compound& c);
01098 
01108 class  Compound::SingleAtom : public Compound {
01109 public:
01110     SingleAtom(
01111         const Compound::AtomName& atomName, 
01112         const Element& element 
01113         ) 
01114     {
01115         setBaseAtom( atomName, element );
01116 
01117         setCompoundName("SingleAtom"); // should be overridden by derived class constructors
01118     }
01119 };
01120 
01121 
01136 class  UnivalentAtom : public Compound::SingleAtom {
01137 public:
01138     UnivalentAtom(
01139         const Compound::AtomName& atomName, 
01140         const Element& element 
01141         ) 
01142         : Compound::SingleAtom(atomName, element)
01143     {
01144         addFirstBondCenter( "bond", atomName);
01145         setInboardBondCenter("bond");
01146 
01147         setCompoundName("UnivalentAtom"); // should be overridden by derived class constructors
01148     }
01149 };
01150 
01151 
01157 class  BivalentAtom : public Compound::SingleAtom {
01158 public:
01159     BivalentAtom(
01160         const Compound::AtomName& atomName,  
01161         const Element& element,  
01162         Angle angle = 180*Deg2Rad 
01163         ) 
01164         : Compound::SingleAtom(atomName, element)
01165     {        
01166         // BondCenter1 dihedral will be relative to BondCenter2
01167         addFirstBondCenter( "bond1", atomName);
01168         // conversely, bond center 2 dihedral is relative to bond center 1
01169         addSecondBondCenter( "bond2", atomName, angle);
01170         setInboardBondCenter("bond1"); // without loss of generality
01171 
01172         setCompoundName("BivalentAtom"); // should be overridden by derived class constructors
01173     }
01174 };
01175 
01176 
01183 class  TrivalentAtom : public Compound::SingleAtom {
01184 public:
01185     TrivalentAtom(
01186         const Compound::AtomName& atomName,   
01187         const Element& element,   
01188         Angle angle1 = 120*Deg2Rad, 
01189         Angle angle2 = 120*Deg2Rad 
01190         ) 
01191         : Compound::SingleAtom(atomName, element)
01192     {
01193         // BondCenter1 dihedral will be relative to BondCenter2
01194         addFirstBondCenter( "bond1", atomName );
01195         // bond centers 2 and 3 dihedrals relative to bond center 1
01196         addSecondBondCenter( "bond2", atomName,  angle1);
01197         addPlanarBondCenter( "bond3", atomName, angle2, 360*Deg2Rad - angle1 - angle2);
01198 
01199         // Choice of inboard bond may differ from bond priority - user may change this
01200         setInboardBondCenter("bond1");
01201 
01202         setCompoundName("TrivalentAtom"); // should be overridden by derived class constructors
01203     }
01204 };
01205 
01211 class  QuadrivalentAtom : public Compound::SingleAtom {
01212 public:
01213     QuadrivalentAtom(
01214         const Compound::AtomName& atomName, 
01215         const Element& element 
01216         ) 
01217         : Compound::SingleAtom(atomName, element)
01218     {
01219         static const Angle TetrahedralAngle = 109.47 * Deg2Rad;
01220 
01221         // BondCenter1 dihedral will be relative to BondCenter2
01222         // Using Rotation() constructor that takes x axis and approximate y axis
01223         addFirstBondCenter( "bond1", atomName );
01224         // bond centers 2, 3, and 4 dihedrals will be relative to bond1
01225         addSecondBondCenter( "bond2", atomName, TetrahedralAngle );
01226         addLeftHandedBondCenter( "bond3", atomName, TetrahedralAngle, TetrahedralAngle );
01227         addRightHandedBondCenter( "bond4", atomName, TetrahedralAngle, TetrahedralAngle );
01228 
01229         // Choice of inboard bond may differ from bond priority - user may change this
01230         setInboardBondCenter("bond1");
01231 
01232         // default dihedral should be left blank, so it could be
01233         // defined from the other side.
01234         // the ultimate default will be 180 degrees anyway.
01235         // setDefaultInboardDihedralAngle(180*Deg2Rad);
01236 
01237         setCompoundName("QuadrivalentAtom"); // should be overridden by derived class constructors
01238     }
01239         
01240     QuadrivalentAtom(
01241         const Compound::AtomName& atomName, 
01242         const Element& element, 
01243         Angle bond12Angle, 
01244         Angle bond13Angle, 
01245         Angle bond14Angle, 
01246         Angle dihedral3, 
01247         Angle dihedral4 
01248         ) 
01249         : Compound::SingleAtom(atomName, element)
01250     {
01251         // BondCenter1 dihedral will be relative to BondCenter2
01252         // Using Rotation() constructor that takes x axis and approximate y axis
01253         addFirstBondCenter( "bond1", atomName );
01254         // bond centers 2, 3, and 4 dihedrals will be relative to bond1
01255         addSecondBondCenter( "bond2", atomName, bond12Angle );
01256         
01257         // Compute bond23Angle and bond24Angle
01258         SimTK::Vec3 v1(0,0,1);
01259         SimTK::Vec3 v2 = SimTK::Rotation(bond12Angle, ZAxis) * SimTK::Vec3(0,0,1);
01260         SimTK::Vec3 v3 = SimTK::Rotation(dihedral3, YAxis) * SimTK::Rotation(bond12Angle, ZAxis) * SimTK::Vec3(0,0,1);
01261         SimTK::Vec3 v4 = SimTK::Rotation(dihedral4, YAxis) * SimTK::Rotation(bond12Angle, ZAxis) * SimTK::Vec3(0,0,1);
01262         
01263         Angle bond23Angle = std::acos(SimTK::dot(v2, v3));
01264         Angle bond24Angle = std::acos(SimTK::dot(v2, v4));
01265         
01266         // restrict angle range to (-Pi,Pi)
01267         while (dihedral3 >   Pi) dihedral3 -= 2.0*Pi;
01268         while (dihedral3 <= -Pi) dihedral3 += 2.0*Pi;
01269         while (dihedral4 >   Pi) dihedral4 -= 2.0*Pi;
01270         while (dihedral4 <= -Pi) dihedral4 += 2.0*Pi;
01271         
01272         if (dihedral3 > 0)
01273             addLeftHandedBondCenter( "bond3", atomName, bond13Angle, bond23Angle );
01274         else
01275             addRightHandedBondCenter( "bond3", atomName, bond13Angle, bond23Angle );
01276         
01277         if (dihedral4 > 0)
01278             addLeftHandedBondCenter( "bond4", atomName, bond14Angle, bond24Angle );
01279         else 
01280             addRightHandedBondCenter( "bond4", atomName, bond14Angle, bond24Angle );
01281 
01282         // Choice of inboard bond may differ from bond priority - user may change this
01283         setInboardBondCenter("bond1");
01284 
01285         // default dihedral should be left blank, so it could be
01286         // defined from the other side.
01287         // the ultimate default will be 180 degrees anyway.
01288         // setDefaultInboardDihedralAngle(180*Deg2Rad);
01289 
01290         setCompoundName("QuadrivalentAtom"); // should be overridden by derived class constructors
01291     }
01292 };
01293 
01294 
01298 class  AliphaticHydrogen : public UnivalentAtom {
01299 public:
01300     AliphaticHydrogen(AtomName atomName = "H" 
01301         ) 
01302         : UnivalentAtom(atomName, Element::Hydrogen())
01303     {
01304         setDefaultInboardBondLength(0.1112); // for bonding to aliphatic carbon
01305 
01306         setCompoundName("AliphaticHydrogenAtom");
01307     }
01308 };
01309 
01310 
01316 class  AliphaticCarbon : public QuadrivalentAtom {
01317 public:
01318     AliphaticCarbon(AtomName atomName = "C" 
01319         ) 
01320         : QuadrivalentAtom(atomName, Element::Carbon()) 
01321     {
01322         // In case this bonds to another aliphatic carbon
01323         setDefaultInboardBondLength(0.15620); // for bonding to another aliphatic carbon
01324 
01325         setCompoundName("AliphaticCarbon");
01326     }
01327 };
01328 
01329 
01333 class  MethyleneGroup : public Compound {
01334 public:
01335     MethyleneGroup() {
01336         static const mdunits::Length C_Hdistance = 0.1112; // nanometers
01337 
01338         setBaseAtom(AliphaticCarbon("C"));
01339         bondAtom(AliphaticHydrogen("H1"), "C/bond3");
01340         bondAtom(AliphaticHydrogen("H2"), "C/bond4");
01341         nameBondCenter("bond1", "C/bond1");
01342         nameBondCenter("bond2", "C/bond2");
01343 
01344         setDefaultInboardBondLength(0.15620); // for bonding to another aliphatic carbon
01345 
01346         setCompoundName("MethyleneGroup");
01347     }
01348 };
01349 
01350 
01354 class  MethylGroup : public Compound {
01355 public:
01356     MethylGroup() {
01357         setBaseAtom(AliphaticCarbon("C"));
01358         bondAtom(AliphaticHydrogen("H1"), "C/bond2");
01359         bondAtom(AliphaticHydrogen("H2"), "C/bond3");
01360         bondAtom(AliphaticHydrogen("H3"), "C/bond4");
01361         nameBondCenter("bond", "C/bond1");
01362 
01363         setDefaultInboardBondLength(0.15620); // for bonding to another aliphatic carbon
01364         setCompoundName("MethylGroup");
01365     }
01366 };
01367 
01374 class  AromaticSixMemberedCHGroup : public Compound {
01375 public:
01376     AromaticSixMemberedCHGroup() {
01377         static const mdunits::Length C_Hdistance = 0.1080; // in nanometers, from tinker amber99.dat
01378         static const mdunits::Length C_Cdistance = 0.1400; // in nanometers, from tinker amber99.dat
01379 
01380         setBaseAtom( TrivalentAtom("C", Element::Carbon(), 120*Deg2Rad, 120*Deg2Rad) );
01381         bondAtom( UnivalentAtom("H", Element::Hydrogen()), "C/bond3", C_Hdistance);
01382 
01383         // remember to change default length for bonding other other things
01384         setDefaultInboardBondLength(C_Cdistance); // for bonding to other aromatic CH
01385 
01386         setCompoundName("AromaticSixMemberedCHGroup");
01387     }
01388 };
01389 
01390 
01394 class  AlcoholOHGroup : public Compound {
01395 public:
01396     AlcoholOHGroup() {
01397         static const mdunits::Length O_Hdistance = 0.0960; // nanometers
01398 
01399         setBaseAtom( BivalentAtom("O", Element::Oxygen(), 108.50 * Deg2Rad) );
01400 
01401         bondAtom( UnivalentAtom("H", Element::Hydrogen()), "O/bond2", O_Hdistance );
01402         nameBondCenter("bond", "O/bond1");
01403 
01404         // In case of bonding to aliphatic carbon
01405         setDefaultInboardBondLength(0.1410); // for bonding to aliphatic carbon
01406 
01407         setCompoundName("AlcoholOHGroup");
01408     }
01409 };
01410 
01411 
01415 class  PrimaryAmineGroup : public Compound {
01416 public:
01417     PrimaryAmineGroup() {
01418         static const mdunits::Length H_Ndistance = 0.1010; // nanometers
01419         static const mdunits::Length N_Cdistance = 0.1471; // in nanometers, for bonding to aliphatic carbon
01420 
01421         setBaseAtom( QuadrivalentAtom("N", Element::Nitrogen()) );
01422         bondAtom( UnivalentAtom("H1", Element::Hydrogen()), "N/bond2", H_Ndistance);
01423         bondAtom( UnivalentAtom("H2", Element::Hydrogen()), "N/bond3", H_Ndistance);
01424         bondAtom( UnivalentAtom("H3", Element::Hydrogen()), "N/bond4", H_Ndistance);
01425 
01426         setDefaultInboardBondLength(N_Cdistance); // for bonding to aliphatic carbon
01427     }
01428 };
01429 
01430 
01434 class  CarboxylateGroup : public Compound {
01435 public:
01436     CarboxylateGroup() {
01437         // parameters from Tinker amber99.param
01438         static const mdunits::Length O_Cdistance = 0.1250; // nanometers
01439         static const mdunits::Length C_CtDistance = 0.15220; // nanometers
01440         static const Angle O_C_Oangle = 126*Deg2Rad;
01441 
01442         // we actually use the inboard-C-O angle during construction
01443         static const Angle O_C_CtAngle = 180*Deg2Rad - 0.5*O_C_Oangle;
01444 
01445         setBaseAtom( TrivalentAtom("C", Element::Carbon(), O_C_CtAngle, O_C_CtAngle) );
01446         bondAtom( UnivalentAtom("O1", Element::Oxygen()), "C/bond2", O_Cdistance);
01447         bondAtom( UnivalentAtom("O2", Element::Oxygen()), "C/bond3", O_Cdistance);
01448 
01449         setDefaultInboardBondLength(C_CtDistance);
01450 
01451         nameBondCenter("bond", "C/bond1");
01452     }
01453 };
01454 
01466 class  SimTK_MOLMODEL_EXPORT Molecule : public Compound {
01467 public:
01468     Molecule();
01469     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Molecule, CompoundRep, Compound);
01470 protected:
01471     Molecule(CompoundRep* rep);
01472 };
01473 
01474 
01478 class  Argon : public Molecule {
01479 public:
01480     Argon() {
01481         setPdbResidueName("AR ");
01482 
01483         setBaseAtom( "Ar", Biotype::Argon() );
01484 
01485         setCompoundName("Argon");
01486     }
01487 };
01488 
01489 
01493 class  Methane : public Molecule {
01494 public:
01495     Methane() 
01496     {
01497         setBaseCompound("methyl", MethylGroup());
01498         inheritAtomNames("methyl");
01499 
01500         // Ordinarily, methyl group bonds to aliphatic carbon,
01501         // and has a default bond length to match.
01502         // Here we turn off the methyl inboard bond, so the
01503         // AliphaticHydrogen will, as desired, dictate the bond length
01504         convertInboardBondCenterToOutboard();
01505 
01506         bondAtom(AliphaticHydrogen("H4"), "methyl/bond", 0.1112);
01507 
01508         setBiotypeIndex( "C", Biotype::MethaneC().getIndex() );
01509         setBiotypeIndex( "H1", Biotype::MethaneH().getIndex() );
01510         setBiotypeIndex( "H2", Biotype::MethaneH().getIndex() );
01511         setBiotypeIndex( "H3", Biotype::MethaneH().getIndex() );
01512         setBiotypeIndex( "H4", Biotype::MethaneH().getIndex() );
01513 
01514         setCompoundName("Methane");
01515 
01516 
01517     }
01518 };
01519 
01523 class  Ethane : public Molecule {
01524 public:
01525     Ethane() 
01526     {
01527         setPdbResidueName("EHN");
01528 
01529         setBaseCompound("methyl1", MethylGroup());
01530         nameAtom("C1", "methyl1/C", Biotype::EthaneC().getIndex() );
01531         nameAtom("H1", "methyl1/H1", Biotype::EthaneH().getIndex() );
01532         nameAtom("H2", "methyl1/H2", Biotype::EthaneH().getIndex() );
01533         nameAtom("H3", "methyl1/H3", Biotype::EthaneH().getIndex() );
01534 
01535         // This first methyl is a base, not a decoration
01536         convertInboardBondCenterToOutboard();
01537 
01538         bondCompound("methyl2", MethylGroup(), "methyl1/bond");
01539 
01540         nameAtom("C2", "methyl2/C", Biotype::EthaneC().getIndex() );
01541         nameAtom("H4", "methyl2/H1", Biotype::EthaneH().getIndex() );
01542         nameAtom("H5", "methyl2/H2", Biotype::EthaneH().getIndex() );
01543         nameAtom("H6", "methyl2/H3", Biotype::EthaneH().getIndex() );
01544 
01545         defineDihedralAngle("torsion", "H1", "C1", "C2", "H4");
01546 
01547         setDefaultTorsionAngle(180*Deg2Rad);
01548         // setBondRotatable(false, "C1", "C2");
01549 
01550         setCompoundName("Ethane");
01551 
01552     }
01553 
01559     Ethane& setDefaultTorsionAngle(Angle angle 
01560         ) {
01561         setDefaultDihedralAngle("torsion", angle);
01562 
01563         return *this;
01564     }
01565 
01569     Angle calcDefaultTorsionAngle() const {
01570         return calcDefaultDihedralAngle("torsion");
01571     }
01572 };
01573 
01580 class BiopolymerResidueRep;
01581 class SimTK_MOLMODEL_EXPORT BiopolymerResidue : public Compound {
01582 public:
01586     BiopolymerResidue(
01587         Compound::Name name, 
01588         String threeLetterCode, 
01589         char oneLetterCode 
01590         );
01591 
01595     BiopolymerResidue& setOneLetterCode(char olc 
01596         );
01597 
01601     BiopolymerResidue& setThreeLetterCode(const String& tlc 
01602         );
01603 
01607     BiopolymerResidue& setResidueName(const String& name 
01608         );
01609 
01619     bool assignBiotypes(
01620         Ordinality::Residue ordinality = Ordinality::Any 
01621         );
01622     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(BiopolymerResidue,BiopolymerResidueRep,Compound);
01623 };
01624 
01625 class BiopolymerRep;
01626 
01635 class SimTK_MOLMODEL_EXPORT Biopolymer : public Molecule
01636 {
01637 public:
01641     typedef String Sequence;
01642     
01646     Biopolymer();
01647 
01651     int getNResidues() const;
01652 
01658     const BiopolymerResidue& getResidue(
01659         Compound::Index residueIndex 
01660         ) const;
01661 
01667     BiopolymerResidue& updResidue(
01668         Compound::Index residueIndex 
01669         ); 
01670 
01674     const BiopolymerResidue& getResidue(
01675         Compound::Name residueName 
01676         ) const;
01677 
01681     BiopolymerResidue& updResidue(
01682         Compound::Name residueName 
01683         );
01684 
01690     Compound::Name getResidueName(
01691         int residueIndex 
01692         ) const;
01693 
01700     Biopolymer& renumberPdbResidues(int firstPdbResidueNumber); 
01701     
01702 
01710     void assignBiotypes();
01711 
01715     void appendResidue(
01716         const Compound::Name& resName, 
01717         const BiopolymerResidue& residue 
01718         );
01719 
01723     void appendResidue(
01724         const Compound::Name& resName, 
01725         const BiopolymerResidue& residue, 
01726         BondMobility::Mobility mobility 
01727         );
01728     SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Biopolymer, BiopolymerRep, Molecule);
01729 };
01730 
01731 
01732 } // namespace SimTK
01733 
01734 #endif // SimTK_MOLMODEL_COMPOUND_H_

Generated on Fri Sep 26 07:44:08 2008 for SimTKcore by  doxygen 1.5.6