diff --git a/CMakeLists.txt b/CMakeLists.txt index 5734b025910a9243ad0f9cdb799e2306066d9534..a5fee0b08f51801b05da44724d98512d8840f73f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ option(COMPILE_TESTS "whether unit tests should be compiled by default" OFF) option(ENABLE_STATIC "whether static libraries should be compiled" OFF) option(UBUNTU_LAYOUT "whether Debian/Ubuntu's lib and libexec directory layout should be used" OFF) option(HIDDEN_VISIBILITY "on gcc, use -fvisibility=hidden" OFF) +option(ENABLE_MM "whether openmm support is added" OFF) if (CXX) set(CMAKE_CXX_COMPILER ${CXX}) @@ -234,6 +235,10 @@ if(USE_NUMPY) find_package(Numpy REQUIRED) endif() +if(ENABLE_MM) + find_package(OpenMM REQUIRED) +endif() + if (ENABLE_IMG) find_package(FFTW REQUIRED) find_package(TIFF REQUIRED) @@ -290,6 +295,7 @@ include_directories(${Boost_INCLUDE_DIRS} ${EIGEN2_INCLUDE_DIRS} ${TIFF_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} + ${OPEN_MM_INCLUDE_DIRS} ) if(USE_NUMPY) include_directories(${PYTHON_NUMPY_INCLUDE_DIR}) diff --git a/cmake_support/FindOpenMM.cmake b/cmake_support/FindOpenMM.cmake new file mode 100644 index 0000000000000000000000000000000000000000..3c0890e392d343190b4abc376f81be5bdba19826 --- /dev/null +++ b/cmake_support/FindOpenMM.cmake @@ -0,0 +1,22 @@ +# Try to find OpenMM +# +# Once done this will define +# - Find OpenMM +# Find the native OpenMM includes and library +# +# OpenMM_INCLUDE_DIRS - OpenMM include dirs. +# OpenMM_LIBRARIES - List of libraries when using OpenMM. +# OpenMM_FOUND - True if OpenMM found. + +find_path (OPEN_MM_INCLUDE_DIR OpenMM.h) +find_library (OPEN_MM_LIBRARY NAMES OpenMM) + +set(OPEN_MM_LIBRARIES ${OPEN_MM_LIBRARY}) +set(OPEN_MM_INCLUDE_DIRS ${OPEN_MM_INCLUDE_DIR}) + +# handle the QUIETLY and REQUIRED arguments and set OpenMM_FOUND to TRUE if +# all listed variables are TRUE +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (OpenMM DEFAULT_MSG OPEN_MM_LIBRARY OPEN_MM_INCLUDE_DIR) + +mark_as_advanced (OPEN_MM_LIBRARY OPEN_MM_INCLUDE_DIR) diff --git a/modules/mol/CMakeLists.txt b/modules/mol/CMakeLists.txt index d417b44124dae1b87b844ec98109a7856b796e32..ac68189a49e54e7d4512519f238c88c4a30b6762 100644 --- a/modules/mol/CMakeLists.txt +++ b/modules/mol/CMakeLists.txt @@ -1,2 +1,5 @@ add_subdirectory(base) add_subdirectory(alg) +if (ENABLE_MM) + add_subdirectory(mm) +endif() diff --git a/modules/mol/mm/CMakeLists.txt b/modules/mol/mm/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4468b05a8c86e042baeebb9b56f19468d9f2e4b5 --- /dev/null +++ b/modules/mol/mm/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(src) +add_subdirectory(pymod) +add_subdirectory(tests) diff --git a/modules/mol/mm/examples/1AKI.pdb b/modules/mol/mm/examples/1AKI.pdb new file mode 100644 index 0000000000000000000000000000000000000000..0a32657dd9011a3213a5809e94e0c56f10150611 --- /dev/null +++ b/modules/mol/mm/examples/1AKI.pdb @@ -0,0 +1,1358 @@ +HEADER HYDROLASE 19-MAY-97 1AKI +TITLE THE STRUCTURE OF THE ORTHORHOMBIC FORM OF HEN EGG-WHITE +TITLE 2 LYSOZYME AT 1.5 ANGSTROMS RESOLUTION +COMPND MOL_ID: 1; +COMPND 2 MOLECULE: LYSOZYME; +COMPND 3 CHAIN: A; +COMPND 4 EC: 3.2.1.17 +SOURCE MOL_ID: 1; +SOURCE 2 ORGANISM_SCIENTIFIC: GALLUS GALLUS; +SOURCE 3 ORGANISM_COMMON: CHICKEN; +SOURCE 4 ORGANISM_TAXID: 9031; +SOURCE 5 CELL: EGG +KEYWDS HYDROLASE, GLYCOSIDASE +EXPDTA X-RAY DIFFRACTION +AUTHOR D.CARTER,J.HE,J.R.RUBLE,B.WRIGHT +REVDAT 2 24-FEB-09 1AKI 1 VERSN +REVDAT 1 19-NOV-97 1AKI 0 +JRNL AUTH P.J.ARTYMIUK,C.C.F.BLAKE,D.W.RICE,K.S.WILSON +JRNL TITL THE STRUCTURES OF THE MONOCLINIC AND ORTHORHOMBIC +JRNL TITL 2 FORMS OF HEN EGG-WHITE LYSOZYME AT 6 ANGSTROMS +JRNL TITL 3 RESOLUTION +JRNL REF ACTA CRYSTALLOGR.,SECT.B V. 38 778 1982 +JRNL REFN ISSN 0108-7681 +REMARK 1 +REMARK 2 +REMARK 2 RESOLUTION. 1.50 ANGSTROMS. +REMARK 3 +REMARK 3 REFINEMENT. +REMARK 3 PROGRAM : GPRLSA, X-PLOR +REMARK 3 AUTHORS : FUREY +REMARK 3 +REMARK 3 DATA USED IN REFINEMENT. +REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 1.50 +REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 10.00 +REMARK 3 DATA CUTOFF (SIGMA(F)) : 1.000 +REMARK 3 COMPLETENESS FOR RANGE (%) : 91.1 +REMARK 3 NUMBER OF REFLECTIONS : 16327 +REMARK 3 +REMARK 3 FIT TO DATA USED IN REFINEMENT. +REMARK 3 CROSS-VALIDATION METHOD : NULL +REMARK 3 FREE R VALUE TEST SET SELECTION : NULL +REMARK 3 R VALUE (WORKING + TEST SET) : NULL +REMARK 3 R VALUE (WORKING SET) : 0.212 +REMARK 3 FREE R VALUE : NULL +REMARK 3 FREE R VALUE TEST SET SIZE (%) : NULL +REMARK 3 FREE R VALUE TEST SET COUNT : NULL +REMARK 3 +REMARK 3 FIT/AGREEMENT OF MODEL WITH ALL DATA. +REMARK 3 R VALUE (WORKING + TEST SET, NO CUTOFF) : NULL +REMARK 3 R VALUE (WORKING SET, NO CUTOFF) : NULL +REMARK 3 FREE R VALUE (NO CUTOFF) : NULL +REMARK 3 FREE R VALUE TEST SET SIZE (%, NO CUTOFF) : NULL +REMARK 3 FREE R VALUE TEST SET COUNT (NO CUTOFF) : NULL +REMARK 3 TOTAL NUMBER OF REFLECTIONS (NO CUTOFF) : NULL +REMARK 3 +REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT. +REMARK 3 PROTEIN ATOMS : 1001 +REMARK 3 NUCLEIC ACID ATOMS : 0 +REMARK 3 HETEROGEN ATOMS : 0 +REMARK 3 SOLVENT ATOMS : 78 +REMARK 3 +REMARK 3 B VALUES. +REMARK 3 FROM WILSON PLOT (A**2) : NULL +REMARK 3 MEAN B VALUE (OVERALL, A**2) : NULL +REMARK 3 OVERALL ANISOTROPIC B VALUE. +REMARK 3 B11 (A**2) : NULL +REMARK 3 B22 (A**2) : NULL +REMARK 3 B33 (A**2) : NULL +REMARK 3 B12 (A**2) : NULL +REMARK 3 B13 (A**2) : NULL +REMARK 3 B23 (A**2) : NULL +REMARK 3 +REMARK 3 ESTIMATED COORDINATE ERROR. +REMARK 3 ESD FROM LUZZATI PLOT (A) : NULL +REMARK 3 ESD FROM SIGMAA (A) : NULL +REMARK 3 LOW RESOLUTION CUTOFF (A) : 10.00 +REMARK 3 +REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES. +REMARK 3 DISTANCE RESTRAINTS. RMS SIGMA +REMARK 3 BOND LENGTH (A) : 0.009 ; 0.010 +REMARK 3 ANGLE DISTANCE (A) : 0.003 ; 0.025 +REMARK 3 INTRAPLANAR 1-4 DISTANCE (A) : 0.024 ; 0.020 +REMARK 3 H-BOND OR METAL COORDINATION (A) : NULL ; NULL +REMARK 3 +REMARK 3 PLANE RESTRAINT (A) : 0.033 ; 0.030 +REMARK 3 CHIRAL-CENTER RESTRAINT (A**3) : 0.212 ; 0.200 +REMARK 3 +REMARK 3 NON-BONDED CONTACT RESTRAINTS. +REMARK 3 SINGLE TORSION (A) : 0.183 ; 0.300 +REMARK 3 MULTIPLE TORSION (A) : 0.159 ; 0.300 +REMARK 3 H-BOND (X...Y) (A) : 0.299 ; 0.300 +REMARK 3 H-BOND (X-H...Y) (A) : NULL ; NULL +REMARK 3 +REMARK 3 CONFORMATIONAL TORSION ANGLE RESTRAINTS. +REMARK 3 SPECIFIED (DEGREES) : NULL ; NULL +REMARK 3 PLANAR (DEGREES) : 7.900 ; 5.000 +REMARK 3 STAGGERED (DEGREES) : 17.800; 15.000 +REMARK 3 TRANSVERSE (DEGREES) : 18.900; 15.000 +REMARK 3 +REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. RMS SIGMA +REMARK 3 MAIN-CHAIN BOND (A**2) : 2.500 ; 3.000 +REMARK 3 MAIN-CHAIN ANGLE (A**2) : 2.900 ; 4.000 +REMARK 3 SIDE-CHAIN BOND (A**2) : 3.200 ; 4.000 +REMARK 3 SIDE-CHAIN ANGLE (A**2) : 3.600 ; 3.000 +REMARK 3 +REMARK 3 OTHER REFINEMENT REMARKS: NULL +REMARK 4 +REMARK 4 1AKI COMPLIES WITH FORMAT V. 3.15, 01-DEC-08 +REMARK 100 +REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY BNL. +REMARK 200 +REMARK 200 EXPERIMENTAL DETAILS +REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION +REMARK 200 DATE OF DATA COLLECTION : NOV-95 +REMARK 200 TEMPERATURE (KELVIN) : 298 +REMARK 200 PH : 4.48 +REMARK 200 NUMBER OF CRYSTALS USED : 1 +REMARK 200 +REMARK 200 SYNCHROTRON (Y/N) : N +REMARK 200 RADIATION SOURCE : ROTATING ANODE +REMARK 200 BEAMLINE : NULL +REMARK 200 X-RAY GENERATOR MODEL : RIGAKU RUH2R +REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M +REMARK 200 WAVELENGTH OR RANGE (A) : 1.5418 +REMARK 200 MONOCHROMATOR : GRAPHITE(002) +REMARK 200 OPTICS : NULL +REMARK 200 +REMARK 200 DETECTOR TYPE : IMAGE PLATE +REMARK 200 DETECTOR MANUFACTURER : RIGAKU RAXIS IIC +REMARK 200 INTENSITY-INTEGRATION SOFTWARE : RIGAKU +REMARK 200 DATA SCALING SOFTWARE : BIOTEX +REMARK 200 +REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 20571 +REMARK 200 RESOLUTION RANGE HIGH (A) : 1.500 +REMARK 200 RESOLUTION RANGE LOW (A) : 15.000 +REMARK 200 REJECTION CRITERIA (SIGMA(I)) : 1.000 +REMARK 200 +REMARK 200 OVERALL. +REMARK 200 COMPLETENESS FOR RANGE (%) : 91.1 +REMARK 200 DATA REDUNDANCY : 3.100 +REMARK 200 R MERGE (I) : 0.04400 +REMARK 200 R SYM (I) : NULL +REMARK 200 <I/SIGMA(I)> FOR THE DATA SET : 11.7000 +REMARK 200 +REMARK 200 IN THE HIGHEST RESOLUTION SHELL. +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : NULL +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : NULL +REMARK 200 COMPLETENESS FOR SHELL (%) : NULL +REMARK 200 DATA REDUNDANCY IN SHELL : NULL +REMARK 200 R MERGE FOR SHELL (I) : NULL +REMARK 200 R SYM FOR SHELL (I) : NULL +REMARK 200 <I/SIGMA(I)> FOR SHELL : NULL +REMARK 200 +REMARK 200 DIFFRACTION PROTOCOL: NULL +REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: MOLECULAR REPLACEMENT +REMARK 200 SOFTWARE USED: X-PLOR +REMARK 200 STARTING MODEL: PDB ENTRY 2LZH +REMARK 200 +REMARK 200 REMARK: NULL +REMARK 280 +REMARK 280 CRYSTAL +REMARK 280 SOLVENT CONTENT, VS (%): 42.84 +REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 2.15 +REMARK 280 +REMARK 280 CRYSTALLIZATION CONDITIONS: PH 4.48 +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY +REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: P 21 21 21 +REMARK 290 +REMARK 290 SYMOP SYMMETRY +REMARK 290 NNNMMM OPERATOR +REMARK 290 1555 X,Y,Z +REMARK 290 2555 -X+1/2,-Y,Z+1/2 +REMARK 290 3555 -X,Y+1/2,-Z+1/2 +REMARK 290 4555 X+1/2,-Y+1/2,-Z +REMARK 290 +REMARK 290 WHERE NNN -> OPERATOR NUMBER +REMARK 290 MMM -> TRANSLATION VECTOR +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS +REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM +REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY +REMARK 290 RELATED MOLECULES. +REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 29.53100 +REMARK 290 SMTRY2 2 0.000000 -1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 2 0.000000 0.000000 1.000000 15.25850 +REMARK 290 SMTRY1 3 -1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 3 0.000000 1.000000 0.000000 34.22550 +REMARK 290 SMTRY3 3 0.000000 0.000000 -1.000000 15.25850 +REMARK 290 SMTRY1 4 1.000000 0.000000 0.000000 29.53100 +REMARK 290 SMTRY2 4 0.000000 -1.000000 0.000000 34.22550 +REMARK 290 SMTRY3 4 0.000000 0.000000 -1.000000 0.00000 +REMARK 290 +REMARK 290 REMARK: NULL +REMARK 300 +REMARK 300 BIOMOLECULE: 1 +REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM +REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN +REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON +REMARK 300 BURIED SURFACE AREA. +REMARK 350 +REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN +REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE +REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS +REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND +REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN. +REMARK 350 +REMARK 350 BIOMOLECULE: 1 +REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: MONOMERIC +REMARK 350 APPLY THE FOLLOWING TO CHAINS: A +REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: CLOSE CONTACTS IN SAME ASYMMETRIC UNIT +REMARK 500 +REMARK 500 THE FOLLOWING ATOMS ARE IN CLOSE CONTACT. +REMARK 500 +REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI DISTANCE +REMARK 500 NH2 ARG A 45 NH2 ARG A 68 2.16 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: CLOSE CONTACTS +REMARK 500 +REMARK 500 THE FOLLOWING ATOMS THAT ARE RELATED BY CRYSTALLOGRAPHIC +REMARK 500 SYMMETRY ARE IN CLOSE CONTACT. AN ATOM LOCATED WITHIN 0.15 +REMARK 500 ANGSTROMS OF A SYMMETRY RELATED ATOM IS ASSUMED TO BE ON A +REMARK 500 SPECIAL POSITION AND IS, THEREFORE, LISTED IN REMARK 375 +REMARK 500 INSTEAD OF REMARK 500. ATOMS WITH NON-BLANK ALTERNATE +REMARK 500 LOCATION INDICATORS ARE NOT INCLUDED IN THE CALCULATIONS. +REMARK 500 +REMARK 500 DISTANCE CUTOFF: +REMARK 500 2.2 ANGSTROMS FOR CONTACTS NOT INVOLVING HYDROGEN ATOMS +REMARK 500 1.6 ANGSTROMS FOR CONTACTS INVOLVING HYDROGEN ATOMS +REMARK 500 +REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI SSYMOP DISTANCE +REMARK 500 OD1 ASN A 19 ND2 ASN A 39 1556 2.09 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: COVALENT BOND ANGLES +REMARK 500 +REMARK 500 THE STEREOCHEMICAL PARAMETERS OF THE FOLLOWING RESIDUES +REMARK 500 HAVE VALUES WHICH DEVIATE FROM EXPECTED VALUES BY MORE +REMARK 500 THAN 6*RMSD (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN +REMARK 500 IDENTIFIER; SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 STANDARD TABLE: +REMARK 500 FORMAT: (10X,I3,1X,A3,1X,A1,I4,A1,3(1X,A4,2X),12X,F5.1) +REMARK 500 +REMARK 500 EXPECTED VALUES PROTEIN: ENGH AND HUBER, 1999 +REMARK 500 EXPECTED VALUES NUCLEIC ACID: CLOWNEY ET AL 1996 +REMARK 500 +REMARK 500 M RES CSSEQI ATM1 ATM2 ATM3 +REMARK 500 ARG A 14 NE - CZ - NH1 ANGL. DEV. = -4.2 DEGREES +REMARK 500 ASP A 18 CB - CG - OD1 ANGL. DEV. = 6.1 DEGREES +REMARK 500 ARG A 21 CD - NE - CZ ANGL. DEV. = 13.6 DEGREES +REMARK 500 ARG A 21 NE - CZ - NH2 ANGL. DEV. = 5.1 DEGREES +REMARK 500 ARG A 45 NE - CZ - NH1 ANGL. DEV. = 4.6 DEGREES +REMARK 500 ARG A 45 NE - CZ - NH2 ANGL. DEV. = -5.7 DEGREES +REMARK 500 ASP A 66 CB - CG - OD1 ANGL. DEV. = 6.6 DEGREES +REMARK 500 ASP A 66 CB - CG - OD2 ANGL. DEV. = -7.2 DEGREES +REMARK 500 ARG A 68 NE - CZ - NH1 ANGL. DEV. = 8.8 DEGREES +REMARK 500 ARG A 68 NE - CZ - NH2 ANGL. DEV. = -6.5 DEGREES +REMARK 500 ARG A 73 NE - CZ - NH2 ANGL. DEV. = -4.4 DEGREES +REMARK 500 ASP A 87 CB - CG - OD1 ANGL. DEV. = 8.6 DEGREES +REMARK 500 ARG A 112 NE - CZ - NH1 ANGL. DEV. = 4.4 DEGREES +REMARK 500 ARG A 125 NE - CZ - NH2 ANGL. DEV. = -5.0 DEGREES +REMARK 500 ARG A 128 NE - CZ - NH1 ANGL. DEV. = 3.0 DEGREES +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: PLANAR GROUPS +REMARK 500 +REMARK 500 PLANAR GROUPS IN THE FOLLOWING RESIDUES HAVE A TOTAL +REMARK 500 RMS DISTANCE OF ALL ATOMS FROM THE BEST-FIT PLANE +REMARK 500 BY MORE THAN AN EXPECTED VALUE OF 6*RMSD, WITH AN +REMARK 500 RMSD 0.02 ANGSTROMS, OR AT LEAST ONE ATOM HAS +REMARK 500 AN RMSD GREATER THAN THIS VALUE +REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER; +REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 M RES CSSEQI RMS TYPE +REMARK 500 ARG A 14 0.12 SIDE_CHAIN +REMARK 500 ARG A 21 0.21 SIDE_CHAIN +REMARK 500 ARG A 68 0.15 SIDE_CHAIN +REMARK 500 ARG A 73 0.25 SIDE_CHAIN +REMARK 500 ARG A 112 0.15 SIDE_CHAIN +REMARK 500 ARG A 114 0.13 SIDE_CHAIN +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: MAIN CHAIN PLANARITY +REMARK 500 +REMARK 500 THE FOLLOWING RESIDUES HAVE A PSEUDO PLANARITY +REMARK 500 TORSION, C(I) - CA(I) - N(I+1) - O(I), GREATER +REMARK 500 10.0 DEGREES. (M=MODEL NUMBER; RES=RESIDUE NAME; +REMARK 500 C=CHAIN IDENTIFIER; SSEQ=SEQUENCE NUMBER; +REMARK 500 I=INSERTION CODE). +REMARK 500 +REMARK 500 M RES CSSEQI ANGLE +REMARK 500 ARG A 128 10.17 +REMARK 500 +REMARK 500 REMARK: NULL +DBREF 1AKI A 1 129 UNP P00698 LYSC_CHICK 19 147 +SEQRES 1 A 129 LYS VAL PHE GLY ARG CYS GLU LEU ALA ALA ALA MET LYS +SEQRES 2 A 129 ARG HIS GLY LEU ASP ASN TYR ARG GLY TYR SER LEU GLY +SEQRES 3 A 129 ASN TRP VAL CYS ALA ALA LYS PHE GLU SER ASN PHE ASN +SEQRES 4 A 129 THR GLN ALA THR ASN ARG ASN THR ASP GLY SER THR ASP +SEQRES 5 A 129 TYR GLY ILE LEU GLN ILE ASN SER ARG TRP TRP CYS ASN +SEQRES 6 A 129 ASP GLY ARG THR PRO GLY SER ARG ASN LEU CYS ASN ILE +SEQRES 7 A 129 PRO CYS SER ALA LEU LEU SER SER ASP ILE THR ALA SER +SEQRES 8 A 129 VAL ASN CYS ALA LYS LYS ILE VAL SER ASP GLY ASN GLY +SEQRES 9 A 129 MET ASN ALA TRP VAL ALA TRP ARG ASN ARG CYS LYS GLY +SEQRES 10 A 129 THR ASP VAL GLN ALA TRP ILE ARG GLY CYS ARG LEU +FORMUL 2 HOH *78(H2 O) +HELIX 1 1 ARG A 5 ARG A 14 1 10 +HELIX 2 2 TYR A 20 GLY A 22 5 3 +HELIX 3 3 LEU A 25 SER A 36 1 12 +HELIX 4 4 CYS A 80 LEU A 84 5 5 +HELIX 5 5 THR A 89 ASP A 101 1 13 +HELIX 6 6 GLY A 104 ALA A 107 5 4 +HELIX 7 7 VAL A 109 ARG A 114 1 6 +HELIX 8 8 VAL A 120 TRP A 123 5 4 +SHEET 1 A 2 THR A 43 ARG A 45 0 +SHEET 2 A 2 THR A 51 TYR A 53 -1 N ASP A 52 O ASN A 44 +SSBOND 1 CYS A 6 CYS A 127 1555 1555 1.97 +SSBOND 2 CYS A 30 CYS A 115 1555 1555 2.00 +SSBOND 3 CYS A 64 CYS A 80 1555 1555 1.99 +SSBOND 4 CYS A 76 CYS A 94 1555 1555 2.02 +CRYST1 59.062 68.451 30.517 90.00 90.00 90.00 P 21 21 21 4 +ORIGX1 1.000000 0.000000 0.000000 0.00000 +ORIGX2 0.000000 1.000000 0.000000 0.00000 +ORIGX3 0.000000 0.000000 1.000000 0.00000 +SCALE1 0.016931 0.000000 0.000000 0.00000 +SCALE2 0.000000 0.014609 0.000000 0.00000 +SCALE3 0.000000 0.000000 0.032769 0.00000 +ATOM 1 N LYS A 1 35.365 22.342 -11.980 1.00 22.28 N +ATOM 2 CA LYS A 1 35.892 21.073 -11.427 1.00 21.12 C +ATOM 3 C LYS A 1 34.741 20.264 -10.844 1.00 16.85 C +ATOM 4 O LYS A 1 33.945 20.813 -10.081 1.00 18.94 O +ATOM 5 CB LYS A 1 36.872 21.435 -10.306 1.00 20.78 C +ATOM 6 CG LYS A 1 37.453 20.248 -9.565 1.00 18.47 C +ATOM 7 CD LYS A 1 38.688 20.649 -8.775 1.00 20.32 C +ATOM 8 CE LYS A 1 39.057 19.508 -7.837 1.00 24.76 C +ATOM 9 NZ LYS A 1 40.423 19.771 -7.299 1.00 28.27 N +ATOM 10 N VAL A 2 34.739 18.961 -11.042 1.00 19.96 N +ATOM 11 CA VAL A 2 33.903 17.998 -10.333 1.00 18.10 C +ATOM 12 C VAL A 2 34.800 17.312 -9.294 1.00 19.39 C +ATOM 13 O VAL A 2 35.759 16.605 -9.665 1.00 22.14 O +ATOM 14 CB VAL A 2 33.140 17.034 -11.232 1.00 16.81 C +ATOM 15 CG1 VAL A 2 32.251 16.084 -10.434 1.00 21.92 C +ATOM 16 CG2 VAL A 2 32.294 17.714 -12.290 1.00 19.46 C +ATOM 17 N PHE A 3 34.491 17.546 -8.038 1.00 19.89 N +ATOM 18 CA PHE A 3 35.185 16.903 -6.918 1.00 17.43 C +ATOM 19 C PHE A 3 34.742 15.441 -6.771 1.00 15.70 C +ATOM 20 O PHE A 3 33.525 15.162 -6.862 1.00 18.52 O +ATOM 21 CB PHE A 3 34.967 17.632 -5.594 1.00 17.94 C +ATOM 22 CG PHE A 3 35.944 18.737 -5.375 1.00 16.78 C +ATOM 23 CD1 PHE A 3 35.666 20.050 -5.798 1.00 15.97 C +ATOM 24 CD2 PHE A 3 37.000 18.557 -4.473 1.00 19.95 C +ATOM 25 CE1 PHE A 3 36.577 21.076 -5.568 1.00 17.32 C +ATOM 26 CE2 PHE A 3 37.869 19.589 -4.157 1.00 17.65 C +ATOM 27 CZ PHE A 3 37.636 20.873 -4.666 1.00 17.91 C +ATOM 28 N GLY A 4 35.724 14.639 -6.331 1.00 16.79 N +ATOM 29 CA GLY A 4 35.366 13.280 -5.870 1.00 16.34 C +ATOM 30 C GLY A 4 34.924 13.420 -4.415 1.00 11.91 C +ATOM 31 O GLY A 4 35.303 14.403 -3.781 1.00 16.23 O +ATOM 32 N ARG A 5 34.053 12.538 -3.973 1.00 14.65 N +ATOM 33 CA ARG A 5 33.565 12.538 -2.588 1.00 15.91 C +ATOM 34 C ARG A 5 34.665 12.734 -1.556 1.00 15.38 C +ATOM 35 O ARG A 5 34.669 13.651 -0.704 1.00 13.15 O +ATOM 36 CB ARG A 5 32.765 11.262 -2.331 1.00 17.38 C +ATOM 37 CG ARG A 5 32.213 11.203 -0.920 1.00 13.79 C +ATOM 38 CD ARG A 5 31.375 10.001 -0.722 1.00 15.84 C +ATOM 39 NE ARG A 5 32.059 8.749 -0.958 1.00 18.74 N +ATOM 40 CZ ARG A 5 32.733 8.011 -0.097 1.00 15.19 C +ATOM 41 NH1 ARG A 5 32.836 8.332 1.187 1.00 17.50 N +ATOM 42 NH2 ARG A 5 33.245 6.836 -0.526 1.00 23.44 N +ATOM 43 N CYS A 6 35.674 11.853 -1.612 1.00 14.07 N +ATOM 44 CA CYS A 6 36.781 11.870 -0.654 1.00 14.62 C +ATOM 45 C CYS A 6 37.747 13.050 -0.777 1.00 10.99 C +ATOM 46 O CYS A 6 38.148 13.609 0.264 1.00 16.34 O +ATOM 47 CB CYS A 6 37.491 10.532 -0.621 1.00 16.90 C +ATOM 48 SG CYS A 6 36.540 9.205 0.140 1.00 18.61 S +ATOM 49 N GLU A 7 37.861 13.481 -2.019 1.00 14.24 N +ATOM 50 CA GLU A 7 38.685 14.686 -2.311 1.00 13.83 C +ATOM 51 C GLU A 7 38.049 15.926 -1.658 1.00 14.86 C +ATOM 52 O GLU A 7 38.744 16.729 -1.011 1.00 15.01 O +ATOM 53 CB GLU A 7 38.784 14.846 -3.818 1.00 14.85 C +ATOM 54 CG GLU A 7 39.540 16.051 -4.379 1.00 18.50 C +ATOM 55 CD GLU A 7 39.576 16.242 -5.870 1.00 20.16 C +ATOM 56 OE1 GLU A 7 38.672 15.644 -6.491 1.00 26.20 O +ATOM 57 OE2 GLU A 7 40.415 16.953 -6.381 1.00 25.49 O +ATOM 58 N LEU A 8 36.743 16.049 -1.819 1.00 15.18 N +ATOM 59 CA LEU A 8 35.964 17.158 -1.255 1.00 12.72 C +ATOM 60 C LEU A 8 36.051 17.132 0.266 1.00 9.45 C +ATOM 61 O LEU A 8 36.159 18.166 0.920 1.00 13.45 O +ATOM 62 CB LEU A 8 34.528 17.172 -1.811 1.00 14.31 C +ATOM 63 CG LEU A 8 33.718 18.354 -1.305 1.00 15.95 C +ATOM 64 CD1 LEU A 8 34.297 19.656 -1.841 1.00 16.56 C +ATOM 65 CD2 LEU A 8 32.246 18.143 -1.596 1.00 15.88 C +ATOM 66 N ALA A 9 35.754 15.980 0.828 1.00 14.24 N +ATOM 67 CA ALA A 9 35.838 15.757 2.284 1.00 13.25 C +ATOM 68 C ALA A 9 37.144 16.314 2.840 1.00 12.89 C +ATOM 69 O ALA A 9 37.151 16.978 3.897 1.00 14.78 O +ATOM 70 CB ALA A 9 35.656 14.287 2.623 1.00 13.89 C +ATOM 71 N ALA A 10 38.272 15.983 2.204 1.00 12.54 N +ATOM 72 CA ALA A 10 39.610 16.431 2.616 1.00 16.58 C +ATOM 73 C ALA A 10 39.736 17.944 2.459 1.00 15.35 C +ATOM 74 O ALA A 10 40.193 18.499 3.469 1.00 17.40 O +ATOM 75 CB ALA A 10 40.708 15.706 1.842 1.00 15.49 C +ATOM 76 N ALA A 11 39.227 18.519 1.385 1.00 13.54 N +ATOM 77 CA ALA A 11 39.264 19.982 1.223 1.00 15.23 C +ATOM 78 C ALA A 11 38.491 20.702 2.321 1.00 15.68 C +ATOM 79 O ALA A 11 38.946 21.658 2.953 1.00 16.87 O +ATOM 80 CB ALA A 11 38.869 20.421 -0.175 1.00 14.12 C +ATOM 81 N MET A 12 37.288 20.214 2.590 1.00 15.47 N +ATOM 82 CA MET A 12 36.398 20.781 3.612 1.00 13.69 C +ATOM 83 C MET A 12 36.990 20.715 5.007 1.00 12.55 C +ATOM 84 O MET A 12 36.906 21.637 5.840 1.00 17.69 O +ATOM 85 CB MET A 12 34.993 20.213 3.515 1.00 11.18 C +ATOM 86 CG MET A 12 34.320 20.724 2.265 1.00 15.06 C +ATOM 87 SD MET A 12 32.634 19.986 2.235 1.00 17.81 S +ATOM 88 CE MET A 12 31.788 21.135 1.138 1.00 18.08 C +ATOM 89 N LYS A 13 37.688 19.628 5.314 1.00 12.42 N +ATOM 90 CA LYS A 13 38.387 19.385 6.579 1.00 14.58 C +ATOM 91 C LYS A 13 39.460 20.467 6.731 1.00 14.55 C +ATOM 92 O LYS A 13 39.507 21.137 7.776 1.00 16.49 O +ATOM 93 CB LYS A 13 38.934 17.952 6.572 1.00 15.36 C +ATOM 94 CG LYS A 13 39.742 17.555 7.798 1.00 20.46 C +ATOM 95 CD LYS A 13 38.973 16.777 8.834 1.00 23.53 C +ATOM 96 CE LYS A 13 39.293 15.305 8.751 1.00 26.37 C +ATOM 97 NZ LYS A 13 38.077 14.461 8.946 1.00 30.88 N +ATOM 98 N ARG A 14 40.267 20.629 5.688 1.00 18.91 N +ATOM 99 CA ARG A 14 41.387 21.577 5.713 1.00 17.66 C +ATOM 100 C ARG A 14 40.927 23.017 5.881 1.00 16.78 C +ATOM 101 O ARG A 14 41.557 23.834 6.584 1.00 20.06 O +ATOM 102 CB ARG A 14 42.388 21.351 4.601 1.00 20.89 C +ATOM 103 CG ARG A 14 42.173 22.079 3.289 1.00 25.07 C +ATOM 104 CD ARG A 14 43.444 22.075 2.490 1.00 23.98 C +ATOM 105 NE ARG A 14 43.687 20.710 2.012 1.00 31.92 N +ATOM 106 CZ ARG A 14 43.098 20.255 0.892 1.00 26.04 C +ATOM 107 NH1 ARG A 14 42.695 21.186 0.018 1.00 33.46 N +ATOM 108 NH2 ARG A 14 42.949 18.957 0.689 1.00 25.91 N +ATOM 109 N HIE A 15 39.681 23.247 5.463 1.00 17.84 N +ATOM 110 CA HIE A 15 39.075 24.591 5.526 1.00 15.99 C +ATOM 111 C HIE A 15 38.310 24.861 6.814 1.00 17.70 C +ATOM 112 O HIE A 15 37.608 25.875 6.952 1.00 22.68 O +ATOM 113 CB HIE A 15 38.223 24.918 4.285 1.00 19.19 C +ATOM 114 CG HIE A 15 39.085 25.388 3.171 1.00 20.14 C +ATOM 115 ND1 HIE A 15 39.457 24.635 2.091 1.00 24.53 N +ATOM 116 CD2 HIE A 15 39.739 26.570 2.993 1.00 24.44 C +ATOM 117 CE1 HIE A 15 40.211 25.312 1.258 1.00 20.68 C +ATOM 118 NE2 HIE A 15 40.524 26.419 1.889 1.00 27.34 N +ATOM 119 N GLY A 16 38.296 23.927 7.720 1.00 17.50 N +ATOM 120 CA GLY A 16 37.765 24.025 9.072 1.00 18.71 C +ATOM 121 C GLY A 16 36.264 23.799 9.210 1.00 18.40 C +ATOM 122 O GLY A 16 35.646 24.400 10.127 1.00 21.57 O +ATOM 123 N LEU A 17 35.665 23.073 8.274 1.00 17.56 N +ATOM 124 CA LEU A 17 34.238 22.795 8.298 1.00 15.38 C +ATOM 125 C LEU A 17 33.845 21.682 9.266 1.00 18.28 C +ATOM 126 O LEU A 17 32.643 21.594 9.552 1.00 18.24 O +ATOM 127 CB LEU A 17 33.648 22.647 6.901 1.00 15.02 C +ATOM 128 CG LEU A 17 33.451 23.889 6.060 1.00 16.08 C +ATOM 129 CD1 LEU A 17 32.933 23.420 4.705 1.00 13.83 C +ATOM 130 CD2 LEU A 17 32.556 24.946 6.679 1.00 18.60 C +ATOM 131 N ASP A 18 34.785 20.814 9.605 1.00 16.36 N +ATOM 132 CA ASP A 18 34.492 19.722 10.526 1.00 16.25 C +ATOM 133 C ASP A 18 34.015 20.222 11.901 1.00 17.32 C +ATOM 134 O ASP A 18 34.826 20.778 12.658 1.00 20.27 O +ATOM 135 CB ASP A 18 35.557 18.633 10.598 1.00 19.37 C +ATOM 136 CG ASP A 18 35.017 17.408 11.311 1.00 20.25 C +ATOM 137 OD1 ASP A 18 33.805 17.154 11.455 1.00 21.00 O +ATOM 138 OD2 ASP A 18 35.925 16.603 11.662 1.00 27.06 O +ATOM 139 N ASN A 19 32.746 19.990 12.205 1.00 18.55 N +ATOM 140 CA ASN A 19 32.123 20.431 13.448 1.00 17.19 C +ATOM 141 C ASN A 19 31.854 21.941 13.497 1.00 16.61 C +ATOM 142 O ASN A 19 31.426 22.398 14.573 1.00 18.56 O +ATOM 143 CB ASN A 19 32.767 20.004 14.770 1.00 18.92 C +ATOM 144 CG ASN A 19 32.162 20.512 16.064 1.00 24.64 C +ATOM 145 OD1 ASN A 19 30.967 20.273 16.355 1.00 32.53 O +ATOM 146 ND2 ASN A 19 32.847 21.361 16.852 1.00 24.14 N +ATOM 147 N TYR A 20 31.969 22.650 12.406 1.00 16.84 N +ATOM 148 CA TYR A 20 31.707 24.099 12.411 1.00 15.54 C +ATOM 149 C TYR A 20 30.231 24.343 12.759 1.00 15.81 C +ATOM 150 O TYR A 20 29.288 23.874 12.118 1.00 16.89 O +ATOM 151 CB TYR A 20 32.070 24.736 11.066 1.00 18.16 C +ATOM 152 CG TYR A 20 32.061 26.250 11.144 1.00 20.28 C +ATOM 153 CD1 TYR A 20 33.141 26.886 11.760 1.00 21.42 C +ATOM 154 CD2 TYR A 20 30.979 27.004 10.691 1.00 20.44 C +ATOM 155 CE1 TYR A 20 33.206 28.277 11.794 1.00 22.24 C +ATOM 156 CE2 TYR A 20 31.018 28.399 10.779 1.00 21.36 C +ATOM 157 CZ TYR A 20 32.102 29.017 11.383 1.00 19.38 C +ATOM 158 OH TYR A 20 32.136 30.371 11.525 1.00 26.77 O +ATOM 159 N ARG A 21 30.088 25.142 13.803 1.00 18.43 N +ATOM 160 CA ARG A 21 28.774 25.553 14.319 1.00 15.68 C +ATOM 161 C ARG A 21 27.964 24.312 14.623 1.00 15.17 C +ATOM 162 O ARG A 21 26.733 24.333 14.606 1.00 18.36 O +ATOM 163 CB ARG A 21 28.014 26.565 13.453 1.00 19.21 C +ATOM 164 CG ARG A 21 28.507 27.995 13.535 1.00 21.50 C +ATOM 165 CD ARG A 21 28.110 28.755 14.765 1.00 25.00 C +ATOM 166 NE ARG A 21 29.319 29.321 15.324 1.00 30.37 N +ATOM 167 CZ ARG A 21 30.215 30.234 14.978 1.00 29.02 C +ATOM 168 NH1 ARG A 21 31.501 29.856 14.846 1.00 29.04 N +ATOM 169 NH2 ARG A 21 29.938 31.437 14.495 1.00 31.89 N +ATOM 170 N GLY A 22 28.689 23.250 14.998 1.00 17.81 N +ATOM 171 CA GLY A 22 28.103 22.021 15.519 1.00 17.72 C +ATOM 172 C GLY A 22 27.748 21.018 14.436 1.00 18.89 C +ATOM 173 O GLY A 22 27.085 20.022 14.784 1.00 23.26 O +ATOM 174 N TYR A 23 28.209 21.230 13.216 1.00 18.20 N +ATOM 175 CA TYR A 23 27.887 20.318 12.111 1.00 15.42 C +ATOM 176 C TYR A 23 29.124 19.533 11.628 1.00 16.30 C +ATOM 177 O TYR A 23 30.045 20.191 11.139 1.00 16.66 O +ATOM 178 CB TYR A 23 27.351 21.107 10.913 1.00 15.82 C +ATOM 179 CG TYR A 23 26.001 21.745 11.127 1.00 15.96 C +ATOM 180 CD1 TYR A 23 24.846 20.962 11.139 1.00 14.81 C +ATOM 181 CD2 TYR A 23 25.897 23.096 11.458 1.00 16.60 C +ATOM 182 CE1 TYR A 23 23.600 21.518 11.422 1.00 17.08 C +ATOM 183 CE2 TYR A 23 24.647 23.673 11.726 1.00 19.34 C +ATOM 184 CZ TYR A 23 23.518 22.881 11.701 1.00 19.21 C +ATOM 185 OH TYR A 23 22.289 23.438 11.912 1.00 25.61 O +ATOM 186 N SER A 24 29.029 18.223 11.810 1.00 15.35 N +ATOM 187 CA SER A 24 30.143 17.347 11.414 1.00 16.89 C +ATOM 188 C SER A 24 30.359 17.379 9.895 1.00 15.61 C +ATOM 189 O SER A 24 29.442 17.687 9.139 1.00 13.88 O +ATOM 190 CB SER A 24 29.922 15.934 11.907 1.00 17.54 C +ATOM 191 OG SER A 24 28.799 15.336 11.308 1.00 19.85 O +ATOM 192 N LEU A 25 31.593 17.028 9.540 1.00 16.08 N +ATOM 193 CA LEU A 25 32.035 17.092 8.138 1.00 13.16 C +ATOM 194 C LEU A 25 31.030 16.437 7.183 1.00 13.39 C +ATOM 195 O LEU A 25 30.874 16.924 6.056 1.00 15.34 O +ATOM 196 CB LEU A 25 33.410 16.409 8.084 1.00 13.47 C +ATOM 197 CG LEU A 25 34.015 16.477 6.689 1.00 12.91 C +ATOM 198 CD1 LEU A 25 34.174 17.929 6.289 1.00 13.04 C +ATOM 199 CD2 LEU A 25 35.398 15.810 6.752 1.00 14.54 C +ATOM 200 N GLY A 26 30.501 15.280 7.576 1.00 13.10 N +ATOM 201 CA GLY A 26 29.539 14.561 6.756 1.00 13.88 C +ATOM 202 C GLY A 26 28.338 15.378 6.277 1.00 12.12 C +ATOM 203 O GLY A 26 27.886 15.250 5.120 1.00 13.13 O +ATOM 204 N ASN A 27 27.905 16.281 7.161 1.00 12.16 N +ATOM 205 CA ASN A 27 26.827 17.227 6.857 1.00 14.74 C +ATOM 206 C ASN A 27 27.164 18.015 5.597 1.00 15.43 C +ATOM 207 O ASN A 27 26.317 18.208 4.720 1.00 15.27 O +ATOM 208 CB ASN A 27 26.484 18.126 8.054 1.00 12.34 C +ATOM 209 CG ASN A 27 25.681 17.267 9.048 1.00 12.22 C +ATOM 210 OD1 ASN A 27 24.511 16.933 8.820 1.00 17.40 O +ATOM 211 ND2 ASN A 27 26.348 17.052 10.169 1.00 18.27 N +ATOM 212 N TRP A 28 28.344 18.591 5.583 1.00 16.78 N +ATOM 213 CA TRP A 28 28.831 19.475 4.513 1.00 16.49 C +ATOM 214 C TRP A 28 28.940 18.741 3.183 1.00 12.99 C +ATOM 215 O TRP A 28 28.742 19.321 2.090 1.00 13.97 O +ATOM 216 CB TRP A 28 30.104 20.145 5.023 1.00 14.55 C +ATOM 217 CG TRP A 28 29.941 20.978 6.251 1.00 11.93 C +ATOM 218 CD1 TRP A 28 30.176 20.624 7.546 1.00 14.42 C +ATOM 219 CD2 TRP A 28 29.319 22.284 6.287 1.00 13.11 C +ATOM 220 NE1 TRP A 28 29.924 21.690 8.365 1.00 16.94 N +ATOM 221 CE2 TRP A 28 29.337 22.679 7.641 1.00 14.07 C +ATOM 222 CE3 TRP A 28 28.894 23.168 5.295 1.00 15.97 C +ATOM 223 CZ2 TRP A 28 28.913 23.943 8.038 1.00 18.07 C +ATOM 224 CZ3 TRP A 28 28.398 24.404 5.682 1.00 18.26 C +ATOM 225 CH2 TRP A 28 28.431 24.766 7.025 1.00 17.18 C +ATOM 226 N VAL A 29 29.572 17.543 3.261 1.00 13.00 N +ATOM 227 CA VAL A 29 29.729 16.711 2.047 1.00 14.15 C +ATOM 228 C VAL A 29 28.379 16.340 1.429 1.00 10.43 C +ATOM 229 O VAL A 29 28.166 16.496 0.228 1.00 13.40 O +ATOM 230 CB VAL A 29 30.649 15.492 2.359 1.00 12.76 C +ATOM 231 CG1 VAL A 29 30.782 14.596 1.136 1.00 15.37 C +ATOM 232 CG2 VAL A 29 32.010 16.050 2.772 1.00 14.18 C +ATOM 233 N CYS A 30 27.501 15.906 2.299 1.00 15.32 N +ATOM 234 CA CYS A 30 26.115 15.567 1.991 1.00 15.59 C +ATOM 235 C CYS A 30 25.388 16.723 1.302 1.00 12.37 C +ATOM 236 O CYS A 30 24.894 16.516 0.172 1.00 14.44 O +ATOM 237 CB CYS A 30 25.343 15.046 3.172 1.00 14.99 C +ATOM 238 SG CYS A 30 23.719 14.376 2.695 1.00 17.71 S +ATOM 239 N ALA A 31 25.533 17.913 1.870 1.00 16.06 N +ATOM 240 CA ALA A 31 24.949 19.130 1.305 1.00 15.82 C +ATOM 241 C ALA A 31 25.487 19.354 -0.115 1.00 15.34 C +ATOM 242 O ALA A 31 24.675 19.686 -0.998 1.00 16.00 O +ATOM 243 CB ALA A 31 25.167 20.335 2.200 1.00 14.90 C +ATOM 244 N ALA A 32 26.807 19.354 -0.286 1.00 11.93 N +ATOM 245 CA ALA A 32 27.461 19.536 -1.579 1.00 13.08 C +ATOM 246 C ALA A 32 26.943 18.538 -2.620 1.00 12.38 C +ATOM 247 O ALA A 32 26.767 18.857 -3.789 1.00 13.89 O +ATOM 248 CB ALA A 32 28.982 19.476 -1.398 1.00 14.17 C +ATOM 249 N LYS A 33 26.731 17.303 -2.193 1.00 15.16 N +ATOM 250 CA LYS A 33 26.261 16.216 -3.037 1.00 16.16 C +ATOM 251 C LYS A 33 24.903 16.555 -3.658 1.00 15.04 C +ATOM 252 O LYS A 33 24.806 16.511 -4.890 1.00 15.00 O +ATOM 253 CB LYS A 33 26.221 14.860 -2.351 1.00 16.71 C +ATOM 254 CG LYS A 33 25.697 13.696 -3.185 1.00 19.51 C +ATOM 255 CD LYS A 33 26.498 13.400 -4.446 1.00 17.12 C +ATOM 256 CE LYS A 33 25.686 12.464 -5.331 1.00 24.06 C +ATOM 257 NZ LYS A 33 26.423 11.979 -6.525 1.00 26.78 N +ATOM 258 N PHE A 34 23.972 16.946 -2.817 1.00 16.81 N +ATOM 259 CA PHE A 34 22.569 17.125 -3.247 1.00 17.51 C +ATOM 260 C PHE A 34 22.346 18.506 -3.836 1.00 18.19 C +ATOM 261 O PHE A 34 21.504 18.692 -4.759 1.00 20.21 O +ATOM 262 CB PHE A 34 21.626 16.673 -2.130 1.00 18.58 C +ATOM 263 CG PHE A 34 21.644 15.172 -1.965 1.00 22.22 C +ATOM 264 CD1 PHE A 34 21.209 14.353 -3.007 1.00 20.24 C +ATOM 265 CD2 PHE A 34 22.272 14.627 -0.851 1.00 20.00 C +ATOM 266 CE1 PHE A 34 21.372 12.961 -2.910 1.00 22.03 C +ATOM 267 CE2 PHE A 34 22.443 13.245 -0.743 1.00 21.96 C +ATOM 268 CZ PHE A 34 21.923 12.406 -1.737 1.00 20.77 C +ATOM 269 N GLU A 35 23.251 19.415 -3.451 1.00 15.27 N +ATOM 270 CA GLU A 35 23.178 20.789 -3.996 1.00 15.45 C +ATOM 271 C GLU A 35 23.661 20.944 -5.423 1.00 17.45 C +ATOM 272 O GLU A 35 23.014 21.514 -6.310 1.00 17.91 O +ATOM 273 CB GLU A 35 23.698 21.892 -3.107 1.00 14.42 C +ATOM 274 CG GLU A 35 22.994 22.212 -1.809 1.00 11.08 C +ATOM 275 CD GLU A 35 21.631 22.846 -1.864 1.00 13.55 C +ATOM 276 OE1 GLU A 35 21.408 23.360 -2.981 1.00 20.77 O +ATOM 277 OE2 GLU A 35 20.947 23.032 -0.874 1.00 22.72 O +ATOM 278 N SER A 36 24.867 20.483 -5.674 1.00 15.66 N +ATOM 279 CA SER A 36 25.626 20.615 -6.903 1.00 17.79 C +ATOM 280 C SER A 36 26.139 19.341 -7.569 1.00 16.97 C +ATOM 281 O SER A 36 26.750 19.464 -8.642 1.00 21.78 O +ATOM 282 CB SER A 36 26.830 21.528 -6.654 1.00 18.12 C +ATOM 283 OG SER A 36 27.747 20.951 -5.748 1.00 15.16 O +ATOM 284 N ASN A 37 25.957 18.222 -6.927 1.00 20.15 N +ATOM 285 CA ASN A 37 26.628 16.968 -7.297 1.00 20.85 C +ATOM 286 C ASN A 37 28.149 17.091 -7.302 1.00 19.72 C +ATOM 287 O ASN A 37 28.813 16.627 -8.254 1.00 20.79 O +ATOM 288 CB ASN A 37 26.028 16.490 -8.617 1.00 20.82 C +ATOM 289 CG ASN A 37 26.156 14.980 -8.782 1.00 23.63 C +ATOM 290 OD1 ASN A 37 26.640 14.266 -7.885 1.00 28.05 O +ATOM 291 ND2 ASN A 37 25.867 14.506 -9.990 1.00 29.61 N +ATOM 292 N PHE A 38 28.691 17.882 -6.383 1.00 16.12 N +ATOM 293 CA PHE A 38 30.129 18.115 -6.279 1.00 14.75 C +ATOM 294 C PHE A 38 30.717 18.903 -7.448 1.00 13.86 C +ATOM 295 O PHE A 38 31.923 18.794 -7.702 1.00 16.66 O +ATOM 296 CB PHE A 38 30.914 16.823 -6.047 1.00 17.09 C +ATOM 297 CG PHE A 38 30.487 16.006 -4.863 1.00 15.96 C +ATOM 298 CD1 PHE A 38 30.100 16.572 -3.655 1.00 15.43 C +ATOM 299 CD2 PHE A 38 30.507 14.603 -4.993 1.00 17.66 C +ATOM 300 CE1 PHE A 38 29.766 15.808 -2.558 1.00 16.83 C +ATOM 301 CE2 PHE A 38 30.136 13.814 -3.891 1.00 15.86 C +ATOM 302 CZ PHE A 38 29.835 14.410 -2.646 1.00 18.90 C +ATOM 303 N ASN A 39 29.936 19.792 -8.033 1.00 17.63 N +ATOM 304 CA ASN A 39 30.341 20.573 -9.199 1.00 16.77 C +ATOM 305 C ASN A 39 30.543 22.034 -8.823 1.00 17.13 C +ATOM 306 O ASN A 39 29.544 22.649 -8.423 1.00 17.24 O +ATOM 307 CB ASN A 39 29.406 20.300 -10.366 1.00 17.40 C +ATOM 308 CG ASN A 39 29.876 20.771 -11.716 1.00 16.96 C +ATOM 309 OD1 ASN A 39 30.579 21.750 -11.956 1.00 23.22 O +ATOM 310 ND2 ASN A 39 29.578 19.864 -12.653 1.00 26.35 N +ATOM 311 N THR A 40 31.766 22.492 -8.928 1.00 14.88 N +ATOM 312 CA THR A 40 32.139 23.869 -8.657 1.00 16.08 C +ATOM 313 C THR A 40 31.504 24.890 -9.589 1.00 16.31 C +ATOM 314 O THR A 40 31.316 26.054 -9.213 1.00 17.50 O +ATOM 315 CB THR A 40 33.684 24.103 -8.422 1.00 17.07 C +ATOM 316 OG1 THR A 40 34.270 24.156 -9.775 1.00 23.76 O +ATOM 317 CG2 THR A 40 34.414 23.119 -7.491 1.00 16.46 C +ATOM 318 N GLN A 41 31.001 24.430 -10.706 1.00 16.39 N +ATOM 319 CA GLN A 41 30.524 25.291 -11.812 1.00 16.67 C +ATOM 320 C GLN A 41 28.993 25.381 -11.874 1.00 15.44 C +ATOM 321 O GLN A 41 28.504 26.019 -12.837 1.00 18.55 O +ATOM 322 CB GLN A 41 31.047 24.817 -13.168 1.00 19.65 C +ATOM 323 CG GLN A 41 32.549 25.004 -13.279 1.00 21.26 C +ATOM 324 CD GLN A 41 32.763 26.236 -14.129 1.00 26.23 C +ATOM 325 OE1 GLN A 41 32.356 26.308 -15.291 1.00 24.68 O +ATOM 326 NE2 GLN A 41 33.276 27.231 -13.420 1.00 25.96 N +ATOM 327 N ALA A 42 28.329 24.640 -11.012 1.00 15.95 N +ATOM 328 CA ALA A 42 26.859 24.579 -11.061 1.00 17.42 C +ATOM 329 C ALA A 42 26.257 25.969 -10.807 1.00 18.93 C +ATOM 330 O ALA A 42 26.645 26.686 -9.884 1.00 17.00 O +ATOM 331 CB ALA A 42 26.355 23.604 -9.998 1.00 22.79 C +ATOM 332 N THR A 43 25.276 26.293 -11.643 1.00 18.30 N +ATOM 333 CA THR A 43 24.441 27.490 -11.476 1.00 17.73 C +ATOM 334 C THR A 43 22.976 27.112 -11.714 1.00 19.61 C +ATOM 335 O THR A 43 22.715 26.271 -12.594 1.00 22.06 O +ATOM 336 CB THR A 43 24.814 28.728 -12.375 1.00 17.58 C +ATOM 337 OG1 THR A 43 24.555 28.321 -13.756 1.00 20.94 O +ATOM 338 CG2 THR A 43 26.247 29.213 -12.184 1.00 18.26 C +ATOM 339 N ASN A 44 22.088 27.742 -10.971 1.00 19.77 N +ATOM 340 CA ASN A 44 20.640 27.497 -11.108 1.00 19.51 C +ATOM 341 C ASN A 44 19.903 28.842 -10.963 1.00 14.85 C +ATOM 342 O ASN A 44 20.169 29.600 -10.033 1.00 19.43 O +ATOM 343 CB ASN A 44 20.155 26.480 -10.080 1.00 19.93 C +ATOM 344 CG ASN A 44 18.646 26.315 -10.115 1.00 22.01 C +ATOM 345 OD1 ASN A 44 18.128 25.720 -11.078 1.00 29.53 O +ATOM 346 ND2 ASN A 44 17.906 26.927 -9.188 1.00 22.94 N +ATOM 347 N ARG A 45 19.058 29.117 -11.924 1.00 16.90 N +ATOM 348 CA ARG A 45 18.303 30.363 -12.015 1.00 18.37 C +ATOM 349 C ARG A 45 16.955 30.163 -11.326 1.00 18.76 C +ATOM 350 O ARG A 45 16.396 29.062 -11.425 1.00 20.87 O +ATOM 351 CB ARG A 45 18.143 30.836 -13.462 1.00 19.30 C +ATOM 352 CG ARG A 45 17.012 31.859 -13.557 1.00 23.98 C +ATOM 353 CD ARG A 45 17.502 33.134 -12.930 1.00 23.36 C +ATOM 354 NE ARG A 45 18.311 33.758 -13.981 1.00 29.56 N +ATOM 355 CZ ARG A 45 17.620 34.271 -15.020 1.00 27.18 C +ATOM 356 NH1 ARG A 45 16.287 34.331 -15.098 1.00 31.99 N +ATOM 357 NH2 ARG A 45 18.374 34.698 -16.030 1.00 32.43 N +ATOM 358 N ASN A 46 16.553 31.171 -10.554 1.00 18.13 N +ATOM 359 CA ASN A 46 15.304 31.071 -9.782 1.00 20.10 C +ATOM 360 C ASN A 46 14.261 32.063 -10.313 1.00 17.35 C +ATOM 361 O ASN A 46 14.617 33.104 -10.880 1.00 19.15 O +ATOM 362 CB ASN A 46 15.576 31.229 -8.295 1.00 20.05 C +ATOM 363 CG ASN A 46 16.543 30.240 -7.679 1.00 20.12 C +ATOM 364 OD1 ASN A 46 17.659 30.661 -7.346 1.00 21.21 O +ATOM 365 ND2 ASN A 46 16.125 28.975 -7.600 1.00 19.44 N +ATOM 366 N THR A 47 13.027 31.834 -9.887 1.00 19.96 N +ATOM 367 CA THR A 47 11.871 32.654 -10.246 1.00 19.12 C +ATOM 368 C THR A 47 12.001 34.107 -9.810 1.00 19.44 C +ATOM 369 O THR A 47 11.600 34.969 -10.606 1.00 23.16 O +ATOM 370 CB THR A 47 10.499 32.017 -9.789 1.00 17.70 C +ATOM 371 OG1 THR A 47 10.507 32.195 -8.342 1.00 23.76 O +ATOM 372 CG2 THR A 47 10.331 30.554 -10.188 1.00 22.66 C +ATOM 373 N ASP A 48 12.625 34.377 -8.683 1.00 19.25 N +ATOM 374 CA ASP A 48 12.885 35.716 -8.168 1.00 17.33 C +ATOM 375 C ASP A 48 14.010 36.505 -8.823 1.00 17.71 C +ATOM 376 O ASP A 48 14.246 37.621 -8.309 1.00 23.04 O +ATOM 377 CB ASP A 48 13.023 35.735 -6.640 1.00 18.02 C +ATOM 378 CG ASP A 48 14.367 35.174 -6.168 1.00 17.88 C +ATOM 379 OD1 ASP A 48 15.104 34.602 -6.991 1.00 18.55 O +ATOM 380 OD2 ASP A 48 14.750 35.442 -5.013 1.00 22.86 O +ATOM 381 N GLY A 49 14.650 36.018 -9.862 1.00 17.62 N +ATOM 382 CA GLY A 49 15.744 36.702 -10.546 1.00 17.27 C +ATOM 383 C GLY A 49 17.147 36.315 -10.096 1.00 16.80 C +ATOM 384 O GLY A 49 18.168 36.688 -10.694 1.00 20.27 O +ATOM 385 N SER A 50 17.173 35.661 -8.930 1.00 19.61 N +ATOM 386 CA SER A 50 18.435 35.225 -8.279 1.00 14.28 C +ATOM 387 C SER A 50 18.977 33.963 -8.941 1.00 18.09 C +ATOM 388 O SER A 50 18.273 33.255 -9.697 1.00 16.76 O +ATOM 389 CB SER A 50 18.272 35.089 -6.781 1.00 17.64 C +ATOM 390 OG SER A 50 17.530 33.930 -6.463 1.00 17.54 O +ATOM 391 N THR A 51 20.271 33.766 -8.734 1.00 16.00 N +ATOM 392 CA THR A 51 20.970 32.557 -9.202 1.00 13.82 C +ATOM 393 C THR A 51 21.718 31.969 -8.000 1.00 14.58 C +ATOM 394 O THR A 51 22.160 32.712 -7.119 1.00 13.28 O +ATOM 395 CB THR A 51 21.904 32.908 -10.419 1.00 12.66 C +ATOM 396 OG1 THR A 51 21.099 33.576 -11.407 1.00 17.65 O +ATOM 397 CG2 THR A 51 22.686 31.699 -10.952 1.00 14.39 C +ATOM 398 N ASP A 52 21.708 30.650 -7.927 1.00 14.66 N +ATOM 399 CA ASP A 52 22.528 29.900 -6.959 1.00 13.43 C +ATOM 400 C ASP A 52 23.843 29.488 -7.635 1.00 12.35 C +ATOM 401 O ASP A 52 23.847 29.066 -8.805 1.00 15.18 O +ATOM 402 CB ASP A 52 21.765 28.649 -6.554 1.00 14.12 C +ATOM 403 CG ASP A 52 20.396 28.991 -6.002 1.00 20.03 C +ATOM 404 OD1 ASP A 52 20.220 29.928 -5.237 1.00 21.30 O +ATOM 405 OD2 ASP A 52 19.517 28.144 -6.222 1.00 20.92 O +ATOM 406 N TYR A 53 24.924 29.734 -6.905 1.00 14.56 N +ATOM 407 CA TYR A 53 26.278 29.604 -7.450 1.00 13.61 C +ATOM 408 C TYR A 53 27.161 28.595 -6.708 1.00 12.70 C +ATOM 409 O TYR A 53 27.289 28.606 -5.486 1.00 13.36 O +ATOM 410 CB TYR A 53 26.993 30.972 -7.489 1.00 12.10 C +ATOM 411 CG TYR A 53 26.437 31.959 -8.487 1.00 11.48 C +ATOM 412 CD1 TYR A 53 26.843 32.003 -9.821 1.00 17.21 C +ATOM 413 CD2 TYR A 53 25.510 32.907 -8.050 1.00 14.42 C +ATOM 414 CE1 TYR A 53 26.291 32.922 -10.717 1.00 17.40 C +ATOM 415 CE2 TYR A 53 24.907 33.803 -8.932 1.00 12.97 C +ATOM 416 CZ TYR A 53 25.357 33.847 -10.252 1.00 15.91 C +ATOM 417 OH TYR A 53 24.864 34.804 -11.094 1.00 19.31 O +ATOM 418 N GLY A 54 27.751 27.721 -7.493 1.00 16.54 N +ATOM 419 CA GLY A 54 28.845 26.832 -7.121 1.00 15.67 C +ATOM 420 C GLY A 54 28.499 25.601 -6.290 1.00 10.78 C +ATOM 421 O GLY A 54 27.339 25.155 -6.255 1.00 13.16 O +ATOM 422 N ILE A 55 29.560 25.088 -5.684 1.00 15.43 N +ATOM 423 CA ILE A 55 29.452 23.795 -4.994 1.00 14.01 C +ATOM 424 C ILE A 55 28.424 23.748 -3.872 1.00 12.26 C +ATOM 425 O ILE A 55 27.770 22.697 -3.693 1.00 16.92 O +ATOM 426 CB ILE A 55 30.891 23.340 -4.563 1.00 16.64 C +ATOM 427 CG1 ILE A 55 30.785 21.812 -4.319 1.00 17.00 C +ATOM 428 CG2 ILE A 55 31.396 24.210 -3.390 1.00 18.87 C +ATOM 429 CD ILE A 55 32.101 21.018 -4.339 1.00 20.60 C +ATOM 430 N LEU A 56 28.216 24.881 -3.236 1.00 12.85 N +ATOM 431 CA LEU A 56 27.173 24.998 -2.203 1.00 14.96 C +ATOM 432 C LEU A 56 25.981 25.838 -2.659 1.00 11.08 C +ATOM 433 O LEU A 56 25.161 26.111 -1.774 1.00 16.40 O +ATOM 434 CB LEU A 56 27.816 25.424 -0.877 1.00 14.44 C +ATOM 435 CG LEU A 56 28.692 24.348 -0.204 1.00 14.92 C +ATOM 436 CD1 LEU A 56 29.331 24.997 1.008 1.00 18.78 C +ATOM 437 CD2 LEU A 56 27.808 23.177 0.192 1.00 19.47 C +ATOM 438 N GLN A 57 25.865 26.104 -3.946 1.00 14.17 N +ATOM 439 CA GLN A 57 24.668 26.785 -4.465 1.00 11.55 C +ATOM 440 C GLN A 57 24.277 27.940 -3.558 1.00 15.09 C +ATOM 441 O GLN A 57 23.116 28.031 -3.094 1.00 15.28 O +ATOM 442 CB GLN A 57 23.521 25.765 -4.549 1.00 13.56 C +ATOM 443 CG GLN A 57 23.733 24.790 -5.699 1.00 12.45 C +ATOM 444 CD GLN A 57 23.684 25.440 -7.069 1.00 14.21 C +ATOM 445 OE1 GLN A 57 22.574 25.602 -7.591 1.00 18.18 O +ATOM 446 NE2 GLN A 57 24.813 25.805 -7.651 1.00 14.86 N +ATOM 447 N ILE A 58 25.164 28.910 -3.428 1.00 14.04 N +ATOM 448 CA ILE A 58 24.930 30.118 -2.649 1.00 16.09 C +ATOM 449 C ILE A 58 24.204 31.163 -3.504 1.00 11.19 C +ATOM 450 O ILE A 58 24.555 31.405 -4.667 1.00 14.34 O +ATOM 451 CB ILE A 58 26.301 30.665 -2.134 1.00 14.90 C +ATOM 452 CG1 ILE A 58 26.751 29.724 -0.985 1.00 13.85 C +ATOM 453 CG2 ILE A 58 26.178 32.135 -1.693 1.00 15.47 C +ATOM 454 CD ILE A 58 28.246 29.954 -0.641 1.00 16.12 C +ATOM 455 N ASN A 59 23.145 31.671 -2.905 1.00 14.23 N +ATOM 456 CA ASN A 59 22.146 32.510 -3.590 1.00 10.60 C +ATOM 457 C ASN A 59 22.550 33.974 -3.730 1.00 13.03 C +ATOM 458 O ASN A 59 22.917 34.607 -2.740 1.00 18.49 O +ATOM 459 CB ASN A 59 20.805 32.306 -2.884 1.00 15.76 C +ATOM 460 CG ASN A 59 19.650 32.986 -3.588 1.00 15.71 C +ATOM 461 OD1 ASN A 59 19.464 34.171 -3.244 1.00 18.79 O +ATOM 462 ND2 ASN A 59 19.155 32.320 -4.612 1.00 16.44 N +ATOM 463 N SER A 60 22.268 34.485 -4.941 1.00 11.71 N +ATOM 464 CA SER A 60 22.570 35.910 -5.255 1.00 13.81 C +ATOM 465 C SER A 60 21.687 36.993 -4.642 1.00 15.28 C +ATOM 466 O SER A 60 22.054 38.177 -4.774 1.00 17.67 O +ATOM 467 CB SER A 60 22.643 36.139 -6.750 1.00 14.62 C +ATOM 468 OG SER A 60 21.432 36.007 -7.444 1.00 14.30 O +ATOM 469 N ARG A 61 20.526 36.660 -4.138 1.00 15.88 N +ATOM 470 CA ARG A 61 19.691 37.653 -3.434 1.00 18.54 C +ATOM 471 C ARG A 61 20.277 38.108 -2.106 1.00 19.97 C +ATOM 472 O ARG A 61 20.282 39.333 -1.876 1.00 26.30 O +ATOM 473 CB ARG A 61 18.267 37.195 -3.250 1.00 18.00 C +ATOM 474 CG ARG A 61 17.315 38.350 -2.959 1.00 20.10 C +ATOM 475 CD ARG A 61 16.063 37.657 -2.503 1.00 26.00 C +ATOM 476 NE ARG A 61 15.101 38.653 -2.063 1.00 29.28 N +ATOM 477 CZ ARG A 61 13.794 38.351 -2.111 1.00 29.36 C +ATOM 478 NH1 ARG A 61 13.439 37.257 -2.784 1.00 26.50 N +ATOM 479 NH2 ARG A 61 12.925 39.249 -1.646 1.00 32.93 N +ATOM 480 N TRP A 62 20.773 37.202 -1.273 1.00 16.51 N +ATOM 481 CA TRP A 62 21.321 37.563 0.032 1.00 16.06 C +ATOM 482 C TRP A 62 22.848 37.643 0.101 1.00 15.55 C +ATOM 483 O TRP A 62 23.323 38.396 0.968 1.00 18.96 O +ATOM 484 CB TRP A 62 20.833 36.611 1.134 1.00 17.91 C +ATOM 485 CG TRP A 62 19.360 36.361 1.096 1.00 18.99 C +ATOM 486 CD1 TRP A 62 18.719 35.247 0.643 1.00 20.47 C +ATOM 487 CD2 TRP A 62 18.326 37.305 1.427 1.00 20.79 C +ATOM 488 NE1 TRP A 62 17.360 35.457 0.609 1.00 21.70 N +ATOM 489 CE2 TRP A 62 17.090 36.696 1.096 1.00 21.11 C +ATOM 490 CE3 TRP A 62 18.333 38.584 1.965 1.00 19.84 C +ATOM 491 CZ2 TRP A 62 15.875 37.327 1.307 1.00 22.57 C +ATOM 492 CZ3 TRP A 62 17.115 39.208 2.186 1.00 23.93 C +ATOM 493 CH2 TRP A 62 15.906 38.611 1.814 1.00 19.55 C +ATOM 494 N TRP A 63 23.537 36.731 -0.584 1.00 16.01 N +ATOM 495 CA TRP A 63 24.906 36.398 -0.276 1.00 15.21 C +ATOM 496 C TRP A 63 26.089 36.924 -1.052 1.00 15.84 C +ATOM 497 O TRP A 63 27.142 37.177 -0.432 1.00 19.13 O +ATOM 498 CB TRP A 63 25.068 34.919 0.112 1.00 15.47 C +ATOM 499 CG TRP A 63 24.036 34.428 1.068 1.00 12.46 C +ATOM 500 CD1 TRP A 63 22.959 33.620 0.777 1.00 16.95 C +ATOM 501 CD2 TRP A 63 23.919 34.728 2.450 1.00 13.27 C +ATOM 502 NE1 TRP A 63 22.243 33.344 1.899 1.00 17.64 N +ATOM 503 CE2 TRP A 63 22.761 34.067 2.931 1.00 17.28 C +ATOM 504 CE3 TRP A 63 24.694 35.480 3.323 1.00 15.25 C +ATOM 505 CZ2 TRP A 63 22.393 34.133 4.278 1.00 18.56 C +ATOM 506 CZ3 TRP A 63 24.302 35.586 4.648 1.00 18.76 C +ATOM 507 CH2 TRP A 63 23.179 34.910 5.117 1.00 19.36 C +ATOM 508 N CYS A 64 25.962 36.914 -2.353 1.00 17.00 N +ATOM 509 CA CYS A 64 26.985 37.433 -3.271 1.00 15.76 C +ATOM 510 C CYS A 64 26.324 38.355 -4.286 1.00 15.97 C +ATOM 511 O CYS A 64 25.102 38.314 -4.475 1.00 13.75 O +ATOM 512 CB CYS A 64 27.638 36.265 -3.988 1.00 16.64 C +ATOM 513 SG CYS A 64 26.562 35.233 -5.007 1.00 17.83 S +ATOM 514 N ASN A 65 27.157 39.165 -4.908 1.00 17.73 N +ATOM 515 CA ASN A 65 26.700 40.134 -5.920 1.00 16.46 C +ATOM 516 C ASN A 65 26.985 39.646 -7.342 1.00 13.16 C +ATOM 517 O ASN A 65 28.130 39.316 -7.647 1.00 15.95 O +ATOM 518 CB ASN A 65 27.381 41.492 -5.712 1.00 19.19 C +ATOM 519 CG ASN A 65 26.910 42.423 -6.824 1.00 19.59 C +ATOM 520 OD1 ASN A 65 25.736 42.559 -7.141 1.00 23.26 O +ATOM 521 ND2 ASN A 65 27.914 42.938 -7.527 1.00 25.56 N +ATOM 522 N ASP A 66 25.920 39.484 -8.116 1.00 15.60 N +ATOM 523 CA ASP A 66 26.102 39.180 -9.545 1.00 15.28 C +ATOM 524 C ASP A 66 25.664 40.317 -10.460 1.00 15.23 C +ATOM 525 O ASP A 66 25.719 40.143 -11.673 1.00 17.91 O +ATOM 526 CB ASP A 66 25.462 37.858 -9.894 1.00 14.84 C +ATOM 527 CG ASP A 66 23.951 37.903 -9.833 1.00 12.12 C +ATOM 528 OD1 ASP A 66 23.288 38.898 -9.542 1.00 16.56 O +ATOM 529 OD2 ASP A 66 23.455 36.769 -10.048 1.00 16.91 O +ATOM 530 N GLY A 67 25.234 41.408 -9.860 1.00 18.13 N +ATOM 531 CA GLY A 67 24.817 42.607 -10.577 1.00 19.40 C +ATOM 532 C GLY A 67 23.544 42.553 -11.401 1.00 20.37 C +ATOM 533 O GLY A 67 23.191 43.542 -12.055 1.00 18.23 O +ATOM 534 N ARG A 68 22.822 41.441 -11.348 1.00 18.79 N +ATOM 535 CA ARG A 68 21.560 41.308 -12.092 1.00 19.77 C +ATOM 536 C ARG A 68 20.424 40.765 -11.243 1.00 18.48 C +ATOM 537 O ARG A 68 19.385 40.383 -11.795 1.00 21.54 O +ATOM 538 CB ARG A 68 21.746 40.454 -13.339 1.00 18.97 C +ATOM 539 CG ARG A 68 22.197 39.048 -12.946 1.00 18.77 C +ATOM 540 CD ARG A 68 22.477 38.187 -14.122 1.00 23.25 C +ATOM 541 NE ARG A 68 21.439 37.201 -14.281 1.00 29.75 N +ATOM 542 CZ ARG A 68 20.242 37.255 -14.855 1.00 28.71 C +ATOM 543 NH1 ARG A 68 19.503 38.311 -15.145 1.00 32.34 N +ATOM 544 NH2 ARG A 68 19.897 36.127 -15.497 1.00 33.10 N +ATOM 545 N THR A 69 20.590 40.896 -9.952 1.00 18.68 N +ATOM 546 CA THR A 69 19.607 40.408 -8.973 1.00 20.02 C +ATOM 547 C THR A 69 18.994 41.597 -8.224 1.00 16.46 C +ATOM 548 O THR A 69 19.683 42.241 -7.425 1.00 23.13 O +ATOM 549 CB THR A 69 20.208 39.384 -7.910 1.00 19.66 C +ATOM 550 OG1 THR A 69 20.851 38.334 -8.715 1.00 19.19 O +ATOM 551 CG2 THR A 69 19.123 38.863 -6.955 1.00 18.58 C +ATOM 552 N PRO A 70 17.687 41.741 -8.418 1.00 20.50 N +ATOM 553 CA PRO A 70 16.953 42.824 -7.733 1.00 21.73 C +ATOM 554 C PRO A 70 16.955 42.520 -6.242 1.00 22.11 C +ATOM 555 O PRO A 70 16.739 41.356 -5.886 1.00 27.13 O +ATOM 556 CB PRO A 70 15.557 42.749 -8.333 1.00 23.50 C +ATOM 557 CG PRO A 70 15.759 42.092 -9.671 1.00 24.66 C +ATOM 558 CD PRO A 70 16.887 41.095 -9.463 1.00 21.80 C +ATOM 559 N GLY A 71 17.163 43.493 -5.401 1.00 21.67 N +ATOM 560 CA GLY A 71 17.135 43.383 -3.947 1.00 24.03 C +ATOM 561 C GLY A 71 18.328 42.710 -3.287 1.00 26.98 C +ATOM 562 O GLY A 71 18.257 42.257 -2.126 1.00 32.77 O +ATOM 563 N SER A 72 19.418 42.627 -4.018 1.00 26.40 N +ATOM 564 CA SER A 72 20.665 41.976 -3.588 1.00 26.94 C +ATOM 565 C SER A 72 21.139 42.582 -2.276 1.00 24.66 C +ATOM 566 O SER A 72 21.055 43.819 -2.125 1.00 29.91 O +ATOM 567 CB SER A 72 21.659 42.002 -4.737 1.00 25.16 C +ATOM 568 OG SER A 72 23.015 41.835 -4.343 1.00 32.21 O +ATOM 569 N ARG A 73 21.646 41.775 -1.369 1.00 22.51 N +ATOM 570 CA ARG A 73 22.254 42.196 -0.113 1.00 22.60 C +ATOM 571 C ARG A 73 23.774 42.058 0.029 1.00 22.33 C +ATOM 572 O ARG A 73 24.425 42.749 0.849 1.00 27.92 O +ATOM 573 CB ARG A 73 21.615 41.555 1.127 1.00 20.14 C +ATOM 574 CG ARG A 73 20.187 41.983 1.439 1.00 22.29 C +ATOM 575 CD ARG A 73 20.209 43.299 2.123 1.00 26.95 C +ATOM 576 NE ARG A 73 18.928 43.771 2.617 1.00 33.74 N +ATOM 577 CZ ARG A 73 17.980 44.302 1.823 1.00 33.76 C +ATOM 578 NH1 ARG A 73 17.841 43.934 0.544 1.00 35.78 N +ATOM 579 NH2 ARG A 73 17.571 45.545 2.146 1.00 33.83 N +ATOM 580 N ASN A 74 24.346 41.143 -0.705 1.00 17.74 N +ATOM 581 CA ASN A 74 25.780 40.833 -0.695 1.00 18.87 C +ATOM 582 C ASN A 74 26.315 40.718 0.731 1.00 16.22 C +ATOM 583 O ASN A 74 27.255 41.471 1.060 1.00 20.87 O +ATOM 584 CB ASN A 74 26.565 41.786 -1.589 1.00 19.51 C +ATOM 585 CG ASN A 74 27.982 41.328 -1.909 1.00 16.31 C +ATOM 586 OD1 ASN A 74 28.318 40.169 -1.652 1.00 18.61 O +ATOM 587 ND2 ASN A 74 28.838 42.192 -2.436 1.00 19.22 N +ATOM 588 N LEU A 75 25.723 39.860 1.544 1.00 15.25 N +ATOM 589 CA LEU A 75 26.153 39.690 2.930 1.00 14.82 C +ATOM 590 C LEU A 75 27.518 39.011 3.085 1.00 16.78 C +ATOM 591 O LEU A 75 28.167 39.197 4.141 1.00 22.00 O +ATOM 592 CB LEU A 75 25.009 39.055 3.733 1.00 16.64 C +ATOM 593 CG LEU A 75 23.815 39.998 3.979 1.00 17.08 C +ATOM 594 CD1 LEU A 75 22.574 39.193 4.336 1.00 25.82 C +ATOM 595 CD2 LEU A 75 24.156 40.969 5.110 1.00 20.95 C +ATOM 596 N CYS A 76 27.973 38.312 2.061 1.00 17.66 N +ATOM 597 CA CYS A 76 29.299 37.680 2.111 1.00 16.46 C +ATOM 598 C CYS A 76 30.390 38.598 1.589 1.00 15.66 C +ATOM 599 O CYS A 76 31.573 38.229 1.568 1.00 17.59 O +ATOM 600 CB CYS A 76 29.396 36.303 1.477 1.00 17.61 C +ATOM 601 SG CYS A 76 28.595 34.961 2.361 1.00 18.07 S +ATOM 602 N ASN A 77 29.964 39.681 0.971 1.00 18.55 N +ATOM 603 CA ASN A 77 30.827 40.725 0.395 1.00 19.18 C +ATOM 604 C ASN A 77 31.711 40.163 -0.702 1.00 16.58 C +ATOM 605 O ASN A 77 32.947 40.331 -0.689 1.00 21.61 O +ATOM 606 CB ASN A 77 31.589 41.488 1.483 1.00 17.72 C +ATOM 607 CG ASN A 77 32.126 42.812 0.957 1.00 20.20 C +ATOM 608 OD1 ASN A 77 31.351 43.589 0.396 1.00 28.77 O +ATOM 609 ND2 ASN A 77 33.430 43.012 1.047 1.00 27.05 N +ATOM 610 N ILE A 78 31.149 39.408 -1.616 1.00 18.88 N +ATOM 611 CA ILE A 78 31.904 38.780 -2.713 1.00 20.14 C +ATOM 612 C ILE A 78 31.099 38.850 -4.013 1.00 17.08 C +ATOM 613 O ILE A 78 29.864 38.688 -3.972 1.00 16.28 O +ATOM 614 CB ILE A 78 32.183 37.255 -2.384 1.00 19.93 C +ATOM 615 CG1 ILE A 78 30.882 36.639 -1.851 1.00 21.17 C +ATOM 616 CG2 ILE A 78 33.437 37.003 -1.524 1.00 24.25 C +ATOM 617 CD ILE A 78 30.936 35.120 -1.546 1.00 25.54 C +ATOM 618 N PRO A 79 31.828 38.795 -5.108 1.00 16.64 N +ATOM 619 CA PRO A 79 31.195 38.634 -6.421 1.00 19.12 C +ATOM 620 C PRO A 79 30.792 37.146 -6.446 1.00 14.71 C +ATOM 621 O PRO A 79 31.576 36.273 -6.005 1.00 17.48 O +ATOM 622 CB PRO A 79 32.261 38.967 -7.445 1.00 18.74 C +ATOM 623 CG PRO A 79 33.555 39.029 -6.710 1.00 18.97 C +ATOM 624 CD PRO A 79 33.276 39.023 -5.215 1.00 16.79 C +ATOM 625 N CYS A 80 29.629 36.908 -7.033 1.00 13.55 N +ATOM 626 CA CYS A 80 29.167 35.522 -7.236 1.00 14.33 C +ATOM 627 C CYS A 80 30.150 34.716 -8.073 1.00 13.92 C +ATOM 628 O CYS A 80 30.214 33.484 -7.880 1.00 16.74 O +ATOM 629 CB CYS A 80 27.749 35.338 -7.747 1.00 16.10 C +ATOM 630 SG CYS A 80 26.471 36.160 -6.762 1.00 16.97 S +ATOM 631 N SER A 81 30.769 35.294 -9.083 1.00 15.04 N +ATOM 632 CA SER A 81 31.775 34.671 -9.933 1.00 15.64 C +ATOM 633 C SER A 81 32.907 34.027 -9.109 1.00 14.90 C +ATOM 634 O SER A 81 33.338 32.939 -9.561 1.00 21.08 O +ATOM 635 CB SER A 81 32.381 35.643 -10.953 1.00 18.65 C +ATOM 636 OG SER A 81 33.035 36.681 -10.235 1.00 20.86 O +ATOM 637 N ALA A 82 33.226 34.572 -7.950 1.00 15.59 N +ATOM 638 CA ALA A 82 34.272 33.963 -7.107 1.00 18.01 C +ATOM 639 C ALA A 82 33.869 32.604 -6.540 1.00 18.75 C +ATOM 640 O ALA A 82 34.703 31.798 -6.081 1.00 19.60 O +ATOM 641 CB ALA A 82 34.722 34.930 -6.020 1.00 20.54 C +ATOM 642 N LEU A 83 32.571 32.338 -6.519 1.00 15.36 N +ATOM 643 CA LEU A 83 31.973 31.093 -6.042 1.00 18.66 C +ATOM 644 C LEU A 83 32.060 29.962 -7.049 1.00 17.84 C +ATOM 645 O LEU A 83 31.671 28.815 -6.739 1.00 21.50 O +ATOM 646 CB LEU A 83 30.618 31.424 -5.431 1.00 17.11 C +ATOM 647 CG LEU A 83 30.511 32.364 -4.244 1.00 16.65 C +ATOM 648 CD1 LEU A 83 29.040 32.573 -3.857 1.00 18.78 C +ATOM 649 CD2 LEU A 83 31.277 31.872 -3.020 1.00 20.62 C +ATOM 650 N LEU A 84 32.473 30.271 -8.267 1.00 17.31 N +ATOM 651 CA LEU A 84 32.610 29.295 -9.347 1.00 16.38 C +ATOM 652 C LEU A 84 34.047 28.841 -9.570 1.00 19.37 C +ATOM 653 O LEU A 84 34.334 28.243 -10.622 1.00 23.48 O +ATOM 654 CB LEU A 84 31.914 29.793 -10.614 1.00 20.87 C +ATOM 655 CG LEU A 84 30.446 30.183 -10.573 1.00 14.26 C +ATOM 656 CD1 LEU A 84 30.014 30.771 -11.916 1.00 21.15 C +ATOM 657 CD2 LEU A 84 29.597 28.942 -10.329 1.00 18.96 C +ATOM 658 N SER A 85 34.942 29.197 -8.676 1.00 21.00 N +ATOM 659 CA SER A 85 36.340 28.754 -8.727 1.00 20.86 C +ATOM 660 C SER A 85 36.474 27.245 -8.497 1.00 19.65 C +ATOM 661 O SER A 85 35.765 26.640 -7.681 1.00 20.62 O +ATOM 662 CB SER A 85 37.109 29.482 -7.633 1.00 20.91 C +ATOM 663 OG SER A 85 38.484 29.212 -7.834 1.00 26.88 O +ATOM 664 N SER A 86 37.619 26.742 -8.943 1.00 22.57 N +ATOM 665 CA SER A 86 38.008 25.343 -8.700 1.00 20.44 C +ATOM 666 C SER A 86 38.388 25.153 -7.233 1.00 19.98 C +ATOM 667 O SER A 86 38.314 24.055 -6.671 1.00 23.62 O +ATOM 668 CB SER A 86 39.107 24.868 -9.650 1.00 23.76 C +ATOM 669 OG SER A 86 38.401 24.215 -10.691 1.00 30.29 O +ATOM 670 N ASP A 87 38.846 26.244 -6.668 1.00 19.74 N +ATOM 671 CA ASP A 87 39.282 26.393 -5.271 1.00 18.72 C +ATOM 672 C ASP A 87 37.999 26.657 -4.471 1.00 17.93 C +ATOM 673 O ASP A 87 37.490 27.762 -4.712 1.00 20.06 O +ATOM 674 CB ASP A 87 40.221 27.607 -5.212 1.00 21.65 C +ATOM 675 CG ASP A 87 40.762 28.041 -3.869 1.00 23.98 C +ATOM 676 OD1 ASP A 87 40.335 27.702 -2.742 1.00 26.26 O +ATOM 677 OD2 ASP A 87 41.785 28.802 -3.933 1.00 32.04 O +ATOM 678 N ILE A 88 37.732 25.850 -3.461 1.00 15.96 N +ATOM 679 CA ILE A 88 36.515 26.089 -2.658 1.00 16.22 C +ATOM 680 C ILE A 88 36.582 27.142 -1.563 1.00 14.43 C +ATOM 681 O ILE A 88 35.600 27.315 -0.801 1.00 16.28 O +ATOM 682 CB ILE A 88 35.993 24.736 -2.046 1.00 16.45 C +ATOM 683 CG1 ILE A 88 36.920 24.200 -0.934 1.00 15.71 C +ATOM 684 CG2 ILE A 88 35.587 23.743 -3.163 1.00 19.87 C +ATOM 685 CD ILE A 88 36.363 23.226 0.137 1.00 17.47 C +ATOM 686 N THR A 89 37.742 27.786 -1.369 1.00 14.21 N +ATOM 687 CA THR A 89 37.913 28.772 -0.306 1.00 16.87 C +ATOM 688 C THR A 89 36.736 29.761 -0.161 1.00 11.06 C +ATOM 689 O THR A 89 36.341 29.983 1.000 1.00 13.83 O +ATOM 690 CB THR A 89 39.267 29.591 -0.423 1.00 18.61 C +ATOM 691 OG1 THR A 89 40.339 28.592 -0.514 1.00 20.24 O +ATOM 692 CG2 THR A 89 39.419 30.553 0.766 1.00 17.79 C +ATOM 693 N ALA A 90 36.507 30.482 -1.242 1.00 17.37 N +ATOM 694 CA ALA A 90 35.479 31.555 -1.244 1.00 16.63 C +ATOM 695 C ALA A 90 34.125 31.066 -0.735 1.00 14.09 C +ATOM 696 O ALA A 90 33.366 31.671 0.065 1.00 15.68 O +ATOM 697 CB ALA A 90 35.366 32.212 -2.617 1.00 17.13 C +ATOM 698 N SER A 91 33.746 29.919 -1.296 1.00 13.62 N +ATOM 699 CA SER A 91 32.494 29.220 -1.024 1.00 11.35 C +ATOM 700 C SER A 91 32.429 28.817 0.467 1.00 11.70 C +ATOM 701 O SER A 91 31.407 29.057 1.110 1.00 14.31 O +ATOM 702 CB SER A 91 32.282 28.035 -1.917 1.00 13.48 C +ATOM 703 OG SER A 91 32.020 28.335 -3.260 1.00 14.66 O +ATOM 704 N VAL A 92 33.502 28.211 0.953 1.00 13.17 N +ATOM 705 CA VAL A 92 33.595 27.846 2.381 1.00 13.44 C +ATOM 706 C VAL A 92 33.477 29.105 3.261 1.00 12.00 C +ATOM 707 O VAL A 92 32.716 29.020 4.244 1.00 13.83 O +ATOM 708 CB VAL A 92 34.890 27.038 2.650 1.00 11.69 C +ATOM 709 CG1 VAL A 92 35.125 26.987 4.151 1.00 16.05 C +ATOM 710 CG2 VAL A 92 34.776 25.672 2.013 1.00 15.64 C +ATOM 711 N ASN A 93 34.199 30.163 2.912 1.00 15.12 N +ATOM 712 CA ASN A 93 34.160 31.413 3.685 1.00 15.10 C +ATOM 713 C ASN A 93 32.747 32.034 3.803 1.00 9.80 C +ATOM 714 O ASN A 93 32.361 32.393 4.908 1.00 16.51 O +ATOM 715 CB ASN A 93 35.168 32.472 3.247 1.00 16.33 C +ATOM 716 CG ASN A 93 36.582 32.083 3.642 1.00 19.02 C +ATOM 717 OD1 ASN A 93 37.546 32.671 3.120 1.00 29.57 O +ATOM 718 ND2 ASN A 93 36.710 31.188 4.631 1.00 24.29 N +ATOM 719 N CYS A 94 32.096 31.996 2.670 1.00 15.72 N +ATOM 720 CA CYS A 94 30.695 32.449 2.633 1.00 13.58 C +ATOM 721 C CYS A 94 29.778 31.527 3.424 1.00 13.05 C +ATOM 722 O CYS A 94 28.973 32.025 4.236 1.00 16.42 O +ATOM 723 CB CYS A 94 30.291 32.704 1.185 1.00 12.05 C +ATOM 724 SG CYS A 94 28.644 33.431 1.046 1.00 15.81 S +ATOM 725 N ALA A 95 29.945 30.225 3.263 1.00 13.56 N +ATOM 726 CA ALA A 95 29.134 29.227 3.969 1.00 15.63 C +ATOM 727 C ALA A 95 29.236 29.330 5.491 1.00 10.80 C +ATOM 728 O ALA A 95 28.222 29.180 6.179 1.00 12.93 O +ATOM 729 CB ALA A 95 29.495 27.794 3.612 1.00 14.09 C +ATOM 730 N LYS A 96 30.424 29.628 5.987 1.00 11.19 N +ATOM 731 CA LYS A 96 30.627 29.912 7.419 1.00 13.27 C +ATOM 732 C LYS A 96 29.802 31.115 7.906 1.00 13.38 C +ATOM 733 O LYS A 96 29.296 31.011 9.027 1.00 15.75 O +ATOM 734 CB LYS A 96 32.100 30.112 7.775 1.00 12.67 C +ATOM 735 CG LYS A 96 32.874 28.792 7.697 1.00 11.93 C +ATOM 736 CD LYS A 96 34.358 29.071 7.879 1.00 15.55 C +ATOM 737 CE LYS A 96 35.205 27.816 7.938 1.00 18.03 C +ATOM 738 NZ LYS A 96 36.610 28.242 8.169 1.00 20.72 N +ATOM 739 N LYS A 97 29.660 32.101 7.049 1.00 12.90 N +ATOM 740 CA LYS A 97 28.811 33.263 7.379 1.00 16.43 C +ATOM 741 C LYS A 97 27.333 32.905 7.386 1.00 18.88 C +ATOM 742 O LYS A 97 26.570 33.318 8.272 1.00 19.20 O +ATOM 743 CB LYS A 97 29.087 34.456 6.470 1.00 18.97 C +ATOM 744 CG LYS A 97 30.537 34.927 6.563 1.00 19.81 C +ATOM 745 CD LYS A 97 30.841 36.073 5.610 1.00 22.00 C +ATOM 746 CE LYS A 97 32.340 36.293 5.510 1.00 23.71 C +ATOM 747 NZ LYS A 97 32.569 37.524 4.708 1.00 29.75 N +ATOM 748 N ILE A 98 26.897 32.127 6.416 1.00 15.72 N +ATOM 749 CA ILE A 98 25.520 31.693 6.266 1.00 16.36 C +ATOM 750 C ILE A 98 25.030 30.871 7.453 1.00 16.70 C +ATOM 751 O ILE A 98 24.059 31.254 8.126 1.00 18.80 O +ATOM 752 CB ILE A 98 25.307 30.997 4.896 1.00 15.14 C +ATOM 753 CG1 ILE A 98 25.643 31.910 3.702 1.00 13.63 C +ATOM 754 CG2 ILE A 98 23.887 30.386 4.817 1.00 15.62 C +ATOM 755 CD ILE A 98 25.620 31.204 2.321 1.00 17.82 C +ATOM 756 N VAL A 99 25.875 29.966 7.915 1.00 16.73 N +ATOM 757 CA VAL A 99 25.488 29.009 8.955 1.00 18.71 C +ATOM 758 C VAL A 99 25.431 29.697 10.316 1.00 20.36 C +ATOM 759 O VAL A 99 24.737 29.212 11.233 1.00 25.30 O +ATOM 760 CB VAL A 99 26.398 27.774 8.859 1.00 16.94 C +ATOM 761 CG1 VAL A 99 27.811 28.138 9.279 1.00 19.19 C +ATOM 762 CG2 VAL A 99 25.834 26.594 9.632 1.00 18.97 C +ATOM 763 N SER A 100 26.205 30.752 10.409 1.00 17.04 N +ATOM 764 CA SER A 100 26.297 31.529 11.650 1.00 23.81 C +ATOM 765 C SER A 100 25.124 32.495 11.765 1.00 24.03 C +ATOM 766 O SER A 100 24.995 33.131 12.820 1.00 28.66 O +ATOM 767 CB SER A 100 27.647 32.194 11.723 1.00 19.71 C +ATOM 768 OG SER A 100 28.714 31.264 11.818 1.00 25.04 O +ATOM 769 N ASP A 101 24.307 32.599 10.750 1.00 25.78 N +ATOM 770 CA ASP A 101 23.162 33.495 10.650 1.00 26.98 C +ATOM 771 C ASP A 101 21.924 33.183 11.481 1.00 28.34 C +ATOM 772 O ASP A 101 21.132 34.143 11.678 1.00 31.88 O +ATOM 773 CB ASP A 101 22.806 33.854 9.207 1.00 27.75 C +ATOM 774 CG ASP A 101 22.426 35.320 9.009 1.00 30.86 C +ATOM 775 OD1 ASP A 101 23.248 36.223 9.266 1.00 34.67 O +ATOM 776 OD2 ASP A 101 21.276 35.519 8.551 1.00 32.70 O +ATOM 777 N GLY A 102 21.723 31.942 11.887 1.00 28.87 N +ATOM 778 CA GLY A 102 20.622 31.656 12.823 1.00 30.67 C +ATOM 779 C GLY A 102 19.812 30.413 12.505 1.00 27.92 C +ATOM 780 O GLY A 102 19.195 29.898 13.458 1.00 30.42 O +ATOM 781 N ASN A 103 19.805 30.005 11.244 1.00 29.26 N +ATOM 782 CA ASN A 103 19.076 28.799 10.848 1.00 25.22 C +ATOM 783 C ASN A 103 19.990 27.600 10.597 1.00 22.06 C +ATOM 784 O ASN A 103 19.472 26.579 10.117 1.00 24.23 O +ATOM 785 CB ASN A 103 17.976 29.046 9.824 1.00 24.87 C +ATOM 786 CG ASN A 103 16.708 28.245 10.063 1.00 27.08 C +ATOM 787 OD1 ASN A 103 16.513 27.577 11.098 1.00 30.30 O +ATOM 788 ND2 ASN A 103 15.672 28.428 9.240 1.00 30.15 N +ATOM 789 N GLY A 104 21.240 27.711 10.997 1.00 23.20 N +ATOM 790 CA GLY A 104 22.177 26.567 10.860 1.00 19.51 C +ATOM 791 C GLY A 104 22.173 26.142 9.388 1.00 15.58 C +ATOM 792 O GLY A 104 22.151 27.040 8.541 1.00 22.50 O +ATOM 793 N MET A 105 22.185 24.847 9.115 1.00 17.51 N +ATOM 794 CA MET A 105 22.278 24.370 7.724 1.00 16.07 C +ATOM 795 C MET A 105 20.915 24.309 7.063 1.00 13.35 C +ATOM 796 O MET A 105 20.902 23.921 5.871 1.00 15.50 O +ATOM 797 CB MET A 105 23.036 23.048 7.632 1.00 19.32 C +ATOM 798 CG MET A 105 24.519 23.221 7.871 1.00 17.10 C +ATOM 799 SD MET A 105 25.379 21.660 7.491 1.00 20.27 S +ATOM 800 CE MET A 105 25.369 21.706 5.703 1.00 20.03 C +ATOM 801 N ASN A 106 19.896 24.839 7.735 1.00 14.64 N +ATOM 802 CA ASN A 106 18.557 24.898 7.103 1.00 18.58 C +ATOM 803 C ASN A 106 18.566 25.831 5.892 1.00 18.20 C +ATOM 804 O ASN A 106 17.678 25.748 5.021 1.00 22.14 O +ATOM 805 CB ASN A 106 17.420 25.150 8.084 1.00 19.18 C +ATOM 806 CG ASN A 106 17.207 23.938 8.967 1.00 19.21 C +ATOM 807 OD1 ASN A 106 16.836 22.867 8.443 1.00 24.65 O +ATOM 808 ND2 ASN A 106 17.542 24.047 10.255 1.00 25.28 N +ATOM 809 N ALA A 107 19.617 26.647 5.800 1.00 18.54 N +ATOM 810 CA ALA A 107 19.824 27.514 4.634 1.00 18.74 C +ATOM 811 C ALA A 107 20.007 26.744 3.329 1.00 16.80 C +ATOM 812 O ALA A 107 19.734 27.292 2.260 1.00 20.63 O +ATOM 813 CB ALA A 107 21.060 28.374 4.877 1.00 19.47 C +ATOM 814 N TRP A 108 20.371 25.465 3.434 1.00 16.46 N +ATOM 815 CA TRP A 108 20.532 24.624 2.241 1.00 14.68 C +ATOM 816 C TRP A 108 19.317 23.688 2.110 1.00 17.55 C +ATOM 817 O TRP A 108 19.240 22.816 2.993 1.00 20.05 O +ATOM 818 CB TRP A 108 21.840 23.826 2.338 1.00 16.18 C +ATOM 819 CG TRP A 108 23.000 24.736 2.026 1.00 15.50 C +ATOM 820 CD1 TRP A 108 23.360 25.234 0.803 1.00 15.45 C +ATOM 821 CD2 TRP A 108 23.798 25.437 2.991 1.00 15.57 C +ATOM 822 NE1 TRP A 108 24.414 26.102 0.952 1.00 17.40 N +ATOM 823 CE2 TRP A 108 24.711 26.237 2.272 1.00 15.78 C +ATOM 824 CE3 TRP A 108 23.833 25.426 4.379 1.00 12.79 C +ATOM 825 CZ2 TRP A 108 25.682 26.985 2.917 1.00 15.77 C +ATOM 826 CZ3 TRP A 108 24.773 26.200 5.033 1.00 16.28 C +ATOM 827 CH2 TRP A 108 25.691 26.960 4.298 1.00 16.65 C +ATOM 828 N VAL A 109 18.487 23.925 1.101 1.00 15.35 N +ATOM 829 CA VAL A 109 17.265 23.096 1.025 1.00 19.96 C +ATOM 830 C VAL A 109 17.573 21.611 0.884 1.00 17.16 C +ATOM 831 O VAL A 109 16.923 20.811 1.587 1.00 20.77 O +ATOM 832 CB VAL A 109 16.146 23.660 0.145 1.00 21.94 C +ATOM 833 CG1 VAL A 109 16.607 23.905 -1.285 1.00 27.84 C +ATOM 834 CG2 VAL A 109 14.901 22.783 0.136 1.00 21.22 C +ATOM 835 N ALA A 110 18.562 21.308 0.075 1.00 20.97 N +ATOM 836 CA ALA A 110 18.972 19.935 -0.237 1.00 18.78 C +ATOM 837 C ALA A 110 19.502 19.244 1.006 1.00 18.30 C +ATOM 838 O ALA A 110 19.197 18.046 1.174 1.00 18.47 O +ATOM 839 CB ALA A 110 19.857 19.777 -1.455 1.00 20.83 C +ATOM 840 N TRP A 111 20.121 19.983 1.892 1.00 16.62 N +ATOM 841 CA TRP A 111 20.551 19.500 3.202 1.00 15.74 C +ATOM 842 C TRP A 111 19.343 19.085 4.046 1.00 19.12 C +ATOM 843 O TRP A 111 19.284 17.986 4.643 1.00 16.20 O +ATOM 844 CB TRP A 111 21.486 20.451 3.925 1.00 14.63 C +ATOM 845 CG TRP A 111 21.858 19.904 5.252 1.00 14.87 C +ATOM 846 CD1 TRP A 111 22.856 18.975 5.486 1.00 18.11 C +ATOM 847 CD2 TRP A 111 21.199 20.093 6.504 1.00 16.63 C +ATOM 848 NE1 TRP A 111 22.848 18.592 6.808 1.00 17.16 N +ATOM 849 CE2 TRP A 111 21.798 19.221 7.435 1.00 16.77 C +ATOM 850 CE3 TRP A 111 20.182 20.959 6.908 1.00 15.16 C +ATOM 851 CZ2 TRP A 111 21.492 19.284 8.784 1.00 17.69 C +ATOM 852 CZ3 TRP A 111 19.818 20.954 8.240 1.00 16.88 C +ATOM 853 CH2 TRP A 111 20.443 20.110 9.162 1.00 19.73 C +ATOM 854 N ARG A 112 18.438 20.038 4.228 1.00 17.47 N +ATOM 855 CA ARG A 112 17.185 19.830 4.955 1.00 19.60 C +ATOM 856 C ARG A 112 16.472 18.593 4.391 1.00 17.68 C +ATOM 857 O ARG A 112 16.000 17.792 5.220 1.00 22.77 O +ATOM 858 CB ARG A 112 16.214 20.990 4.944 1.00 17.57 C +ATOM 859 CG ARG A 112 16.592 22.438 5.091 1.00 25.27 C +ATOM 860 CD ARG A 112 15.368 23.296 5.135 1.00 21.23 C +ATOM 861 NE ARG A 112 14.776 23.555 3.836 1.00 28.06 N +ATOM 862 CZ ARG A 112 14.785 24.695 3.143 1.00 27.89 C +ATOM 863 NH1 ARG A 112 15.596 25.721 3.383 1.00 30.12 N +ATOM 864 NH2 ARG A 112 13.717 25.008 2.398 1.00 30.39 N +ATOM 865 N ASN A 113 16.307 18.521 3.074 1.00 19.43 N +ATOM 866 CA ASN A 113 15.464 17.463 2.491 1.00 20.16 C +ATOM 867 C ASN A 113 16.111 16.083 2.586 1.00 21.26 C +ATOM 868 O ASN A 113 15.454 15.054 2.808 1.00 24.90 O +ATOM 869 CB ASN A 113 14.966 17.779 1.085 1.00 20.43 C +ATOM 870 CG ASN A 113 14.003 18.961 1.018 1.00 16.63 C +ATOM 871 OD1 ASN A 113 13.454 19.344 2.059 1.00 25.68 O +ATOM 872 ND2 ASN A 113 13.840 19.555 -0.159 1.00 22.00 N +ATOM 873 N ARG A 114 17.401 16.041 2.355 1.00 19.72 N +ATOM 874 CA ARG A 114 18.156 14.836 2.042 1.00 21.43 C +ATOM 875 C ARG A 114 19.258 14.440 2.991 1.00 22.71 C +ATOM 876 O ARG A 114 19.505 13.217 3.097 1.00 24.85 O +ATOM 877 CB ARG A 114 18.622 14.910 0.576 1.00 21.05 C +ATOM 878 CG ARG A 114 17.395 14.614 -0.300 1.00 26.59 C +ATOM 879 CD ARG A 114 17.729 14.399 -1.731 1.00 26.92 C +ATOM 880 NE ARG A 114 18.153 15.677 -2.301 1.00 33.46 N +ATOM 881 CZ ARG A 114 17.826 16.080 -3.535 1.00 32.00 C +ATOM 882 NH1 ARG A 114 17.378 15.225 -4.456 1.00 36.02 N +ATOM 883 NH2 ARG A 114 17.735 17.388 -3.796 1.00 36.05 N +ATOM 884 N CYS A 115 19.743 15.372 3.773 1.00 17.56 N +ATOM 885 CA CYS A 115 20.843 15.041 4.708 1.00 15.08 C +ATOM 886 C CYS A 115 20.448 14.933 6.159 1.00 16.64 C +ATOM 887 O CYS A 115 20.972 14.116 6.940 1.00 21.71 O +ATOM 888 CB CYS A 115 21.991 16.018 4.426 1.00 15.21 C +ATOM 889 SG CYS A 115 22.563 16.009 2.739 1.00 19.35 S +ATOM 890 N LYS A 116 19.714 15.918 6.619 1.00 18.76 N +ATOM 891 CA LYS A 116 19.332 16.085 8.025 1.00 19.14 C +ATOM 892 C LYS A 116 18.634 14.821 8.518 1.00 21.91 C +ATOM 893 O LYS A 116 17.819 14.234 7.785 1.00 24.78 O +ATOM 894 CB LYS A 116 18.492 17.363 8.126 1.00 21.01 C +ATOM 895 CG LYS A 116 17.930 17.512 9.547 1.00 21.28 C +ATOM 896 CD LYS A 116 16.745 18.481 9.554 1.00 25.86 C +ATOM 897 CE LYS A 116 16.658 19.147 10.918 1.00 25.58 C +ATOM 898 NZ LYS A 116 15.454 20.010 11.047 1.00 34.69 N +ATOM 899 N GLY A 117 19.152 14.318 9.635 1.00 26.39 N +ATOM 900 CA GLY A 117 18.558 13.126 10.267 1.00 29.06 C +ATOM 901 C GLY A 117 19.018 11.781 9.733 1.00 28.29 C +ATOM 902 O GLY A 117 18.499 10.733 10.164 1.00 31.90 O +ATOM 903 N THR A 118 19.892 11.802 8.740 1.00 26.88 N +ATOM 904 CA THR A 118 20.473 10.578 8.171 1.00 22.31 C +ATOM 905 C THR A 118 21.868 10.375 8.761 1.00 21.43 C +ATOM 906 O THR A 118 22.321 11.119 9.650 1.00 22.31 O +ATOM 907 CB THR A 118 20.440 10.571 6.598 1.00 18.59 C +ATOM 908 OG1 THR A 118 21.560 11.404 6.161 1.00 22.71 O +ATOM 909 CG2 THR A 118 19.095 11.104 6.074 1.00 21.13 C +ATOM 910 N ASP A 119 22.392 9.213 8.431 1.00 21.20 N +ATOM 911 CA ASP A 119 23.768 8.830 8.756 1.00 22.61 C +ATOM 912 C ASP A 119 24.713 9.543 7.779 1.00 20.13 C +ATOM 913 O ASP A 119 25.178 8.950 6.780 1.00 20.57 O +ATOM 914 CB ASP A 119 23.934 7.313 8.738 1.00 21.00 C +ATOM 915 CG ASP A 119 25.347 6.900 9.121 1.00 25.32 C +ATOM 916 OD1 ASP A 119 26.051 7.633 9.830 1.00 27.93 O +ATOM 917 OD2 ASP A 119 25.715 5.746 8.804 1.00 27.31 O +ATOM 918 N VAL A 120 24.988 10.793 8.094 1.00 23.41 N +ATOM 919 CA VAL A 120 25.886 11.637 7.306 1.00 20.10 C +ATOM 920 C VAL A 120 27.342 11.199 7.304 1.00 18.51 C +ATOM 921 O VAL A 120 28.099 11.604 6.406 1.00 19.95 O +ATOM 922 CB VAL A 120 25.721 13.134 7.630 1.00 19.91 C +ATOM 923 CG1 VAL A 120 24.356 13.655 7.183 1.00 23.59 C +ATOM 924 CG2 VAL A 120 26.088 13.478 9.055 1.00 20.79 C +ATOM 925 N GLN A 121 27.701 10.430 8.306 1.00 21.83 N +ATOM 926 CA GLN A 121 29.021 9.783 8.389 1.00 21.12 C +ATOM 927 C GLN A 121 29.317 8.861 7.207 1.00 20.78 C +ATOM 928 O GLN A 121 30.480 8.669 6.820 1.00 19.66 O +ATOM 929 CB GLN A 121 29.088 9.048 9.728 1.00 24.21 C +ATOM 930 CG GLN A 121 30.530 8.965 10.167 1.00 26.13 C +ATOM 931 CD GLN A 121 30.615 8.877 11.674 1.00 26.94 C +ATOM 932 OE1 GLN A 121 31.368 9.632 12.283 1.00 31.43 O +ATOM 933 NE2 GLN A 121 29.884 7.871 12.151 1.00 28.26 N +ATOM 934 N ALA A 122 28.300 8.271 6.576 1.00 17.62 N +ATOM 935 CA ALA A 122 28.390 7.548 5.311 1.00 19.46 C +ATOM 936 C ALA A 122 29.186 8.290 4.227 1.00 17.98 C +ATOM 937 O ALA A 122 30.031 7.710 3.523 1.00 21.35 O +ATOM 938 CB ALA A 122 26.999 7.244 4.783 1.00 18.29 C +ATOM 939 N TRP A 123 29.021 9.616 4.240 1.00 18.07 N +ATOM 940 CA TRP A 123 29.703 10.502 3.283 1.00 16.76 C +ATOM 941 C TRP A 123 31.218 10.581 3.392 1.00 16.76 C +ATOM 942 O TRP A 123 31.905 10.942 2.412 1.00 20.08 O +ATOM 943 CB TRP A 123 29.027 11.872 3.347 1.00 19.49 C +ATOM 944 CG TRP A 123 27.621 11.735 2.850 1.00 17.43 C +ATOM 945 CD1 TRP A 123 26.485 11.608 3.588 1.00 19.42 C +ATOM 946 CD2 TRP A 123 27.241 11.547 1.481 1.00 17.47 C +ATOM 947 NE1 TRP A 123 25.405 11.458 2.774 1.00 18.86 N +ATOM 948 CE2 TRP A 123 25.827 11.391 1.479 1.00 17.28 C +ATOM 949 CE3 TRP A 123 27.947 11.468 0.283 1.00 20.03 C +ATOM 950 CZ2 TRP A 123 25.111 11.184 0.311 1.00 18.33 C +ATOM 951 CZ3 TRP A 123 27.222 11.329 -0.886 1.00 20.85 C +ATOM 952 CH2 TRP A 123 25.835 11.127 -0.869 1.00 20.45 C +ATOM 953 N ILE A 124 31.741 10.269 4.554 1.00 14.19 N +ATOM 954 CA ILE A 124 33.186 10.292 4.801 1.00 16.82 C +ATOM 955 C ILE A 124 33.863 8.955 5.024 1.00 18.45 C +ATOM 956 O ILE A 124 35.100 8.892 5.134 1.00 21.02 O +ATOM 957 CB ILE A 124 33.504 11.403 5.863 1.00 17.69 C +ATOM 958 CG1 ILE A 124 32.956 10.984 7.234 1.00 18.86 C +ATOM 959 CG2 ILE A 124 33.024 12.804 5.387 1.00 21.01 C +ATOM 960 CD ILE A 124 33.729 11.437 8.488 1.00 22.81 C +ATOM 961 N ARG A 125 33.080 7.898 5.131 1.00 21.05 N +ATOM 962 CA ARG A 125 33.594 6.534 5.320 1.00 19.12 C +ATOM 963 C ARG A 125 34.311 6.113 4.036 1.00 17.52 C +ATOM 964 O ARG A 125 33.843 6.337 2.906 1.00 23.44 O +ATOM 965 CB ARG A 125 32.476 5.551 5.650 1.00 19.54 C +ATOM 966 CG ARG A 125 32.117 5.596 7.145 1.00 22.40 C +ATOM 967 CD ARG A 125 31.277 4.392 7.482 1.00 24.05 C +ATOM 968 NE ARG A 125 30.282 4.754 8.466 1.00 28.08 N +ATOM 969 CZ ARG A 125 28.984 4.993 8.331 1.00 23.40 C +ATOM 970 NH1 ARG A 125 28.334 4.690 7.207 1.00 23.69 N +ATOM 971 NH2 ARG A 125 28.392 5.549 9.392 1.00 23.77 N +ATOM 972 N GLY A 126 35.497 5.568 4.243 1.00 18.80 N +ATOM 973 CA GLY A 126 36.291 5.058 3.102 1.00 21.28 C +ATOM 974 C GLY A 126 37.334 6.066 2.658 1.00 22.50 C +ATOM 975 O GLY A 126 38.220 5.729 1.855 1.00 23.59 O +ATOM 976 N CYS A 127 37.335 7.221 3.297 1.00 19.05 N +ATOM 977 CA CYS A 127 38.234 8.333 2.961 1.00 19.13 C +ATOM 978 C CYS A 127 39.422 8.382 3.925 1.00 22.50 C +ATOM 979 O CYS A 127 39.206 8.267 5.138 1.00 21.64 O +ATOM 980 CB CYS A 127 37.453 9.628 2.990 1.00 18.75 C +ATOM 981 SG CYS A 127 36.010 9.816 1.936 1.00 19.93 S +ATOM 982 N ARG A 128 40.586 8.695 3.393 1.00 23.60 N +ATOM 983 CA ARG A 128 41.774 8.960 4.217 1.00 28.29 C +ATOM 984 C ARG A 128 41.820 10.438 4.578 1.00 25.64 C +ATOM 985 O ARG A 128 41.976 11.291 3.694 1.00 30.98 O +ATOM 986 CB ARG A 128 43.047 8.304 3.707 1.00 30.82 C +ATOM 987 CG ARG A 128 43.231 6.886 4.280 1.00 34.25 C +ATOM 988 CD ARG A 128 43.833 6.911 5.651 1.00 33.59 C +ATOM 989 NE ARG A 128 45.246 7.263 5.636 1.00 37.63 N +ATOM 990 CZ ARG A 128 45.862 8.258 6.281 1.00 38.37 C +ATOM 991 NH1 ARG A 128 45.241 9.069 7.151 1.00 38.97 N +ATOM 992 NH2 ARG A 128 47.134 8.554 5.973 1.00 40.22 N +ATOM 993 N LEU A 129 41.289 10.715 5.771 1.00 26.05 N +ATOM 994 CA LEU A 129 41.094 12.084 6.273 1.00 26.89 C +ATOM 995 C LEU A 129 42.119 12.382 7.370 1.00 29.58 C +ATOM 996 O LEU A 129 41.730 12.276 8.559 1.00 33.54 O +ATOM 997 CB LEU A 129 39.635 12.335 6.646 1.00 26.31 C +ATOM 998 CG LEU A 129 38.689 12.917 5.620 1.00 23.49 C +ATOM 999 CD1 LEU A 129 39.112 12.657 4.191 1.00 26.43 C +ATOM 1000 CD2 LEU A 129 37.310 12.325 5.886 1.00 25.15 C +ATOM 1001 OXT LEU A 129 43.232 12.675 6.905 1.00 34.20 O +TER 1002 LEU A 129 +CONECT 48 981 +CONECT 238 889 +CONECT 513 630 +CONECT 601 724 +CONECT 630 513 +CONECT 724 601 +CONECT 889 238 +CONECT 981 48 +MASTER 290 0 0 8 2 0 0 6 1079 1 8 10 +END diff --git a/modules/mol/mm/examples/1AKI_original.pdb b/modules/mol/mm/examples/1AKI_original.pdb new file mode 100644 index 0000000000000000000000000000000000000000..5228267a3ffbba05f8205a1f504282a27a4265ba --- /dev/null +++ b/modules/mol/mm/examples/1AKI_original.pdb @@ -0,0 +1,1436 @@ +HEADER HYDROLASE 19-MAY-97 1AKI +TITLE THE STRUCTURE OF THE ORTHORHOMBIC FORM OF HEN EGG-WHITE +TITLE 2 LYSOZYME AT 1.5 ANGSTROMS RESOLUTION +COMPND MOL_ID: 1; +COMPND 2 MOLECULE: LYSOZYME; +COMPND 3 CHAIN: A; +COMPND 4 EC: 3.2.1.17 +SOURCE MOL_ID: 1; +SOURCE 2 ORGANISM_SCIENTIFIC: GALLUS GALLUS; +SOURCE 3 ORGANISM_COMMON: CHICKEN; +SOURCE 4 ORGANISM_TAXID: 9031; +SOURCE 5 CELL: EGG +KEYWDS HYDROLASE, GLYCOSIDASE +EXPDTA X-RAY DIFFRACTION +AUTHOR D.CARTER,J.HE,J.R.RUBLE,B.WRIGHT +REVDAT 2 24-FEB-09 1AKI 1 VERSN +REVDAT 1 19-NOV-97 1AKI 0 +JRNL AUTH P.J.ARTYMIUK,C.C.F.BLAKE,D.W.RICE,K.S.WILSON +JRNL TITL THE STRUCTURES OF THE MONOCLINIC AND ORTHORHOMBIC +JRNL TITL 2 FORMS OF HEN EGG-WHITE LYSOZYME AT 6 ANGSTROMS +JRNL TITL 3 RESOLUTION +JRNL REF ACTA CRYSTALLOGR.,SECT.B V. 38 778 1982 +JRNL REFN ISSN 0108-7681 +REMARK 1 +REMARK 2 +REMARK 2 RESOLUTION. 1.50 ANGSTROMS. +REMARK 3 +REMARK 3 REFINEMENT. +REMARK 3 PROGRAM : GPRLSA, X-PLOR +REMARK 3 AUTHORS : FUREY +REMARK 3 +REMARK 3 DATA USED IN REFINEMENT. +REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 1.50 +REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 10.00 +REMARK 3 DATA CUTOFF (SIGMA(F)) : 1.000 +REMARK 3 COMPLETENESS FOR RANGE (%) : 91.1 +REMARK 3 NUMBER OF REFLECTIONS : 16327 +REMARK 3 +REMARK 3 FIT TO DATA USED IN REFINEMENT. +REMARK 3 CROSS-VALIDATION METHOD : NULL +REMARK 3 FREE R VALUE TEST SET SELECTION : NULL +REMARK 3 R VALUE (WORKING + TEST SET) : NULL +REMARK 3 R VALUE (WORKING SET) : 0.212 +REMARK 3 FREE R VALUE : NULL +REMARK 3 FREE R VALUE TEST SET SIZE (%) : NULL +REMARK 3 FREE R VALUE TEST SET COUNT : NULL +REMARK 3 +REMARK 3 FIT/AGREEMENT OF MODEL WITH ALL DATA. +REMARK 3 R VALUE (WORKING + TEST SET, NO CUTOFF) : NULL +REMARK 3 R VALUE (WORKING SET, NO CUTOFF) : NULL +REMARK 3 FREE R VALUE (NO CUTOFF) : NULL +REMARK 3 FREE R VALUE TEST SET SIZE (%, NO CUTOFF) : NULL +REMARK 3 FREE R VALUE TEST SET COUNT (NO CUTOFF) : NULL +REMARK 3 TOTAL NUMBER OF REFLECTIONS (NO CUTOFF) : NULL +REMARK 3 +REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT. +REMARK 3 PROTEIN ATOMS : 1001 +REMARK 3 NUCLEIC ACID ATOMS : 0 +REMARK 3 HETEROGEN ATOMS : 0 +REMARK 3 SOLVENT ATOMS : 78 +REMARK 3 +REMARK 3 B VALUES. +REMARK 3 FROM WILSON PLOT (A**2) : NULL +REMARK 3 MEAN B VALUE (OVERALL, A**2) : NULL +REMARK 3 OVERALL ANISOTROPIC B VALUE. +REMARK 3 B11 (A**2) : NULL +REMARK 3 B22 (A**2) : NULL +REMARK 3 B33 (A**2) : NULL +REMARK 3 B12 (A**2) : NULL +REMARK 3 B13 (A**2) : NULL +REMARK 3 B23 (A**2) : NULL +REMARK 3 +REMARK 3 ESTIMATED COORDINATE ERROR. +REMARK 3 ESD FROM LUZZATI PLOT (A) : NULL +REMARK 3 ESD FROM SIGMAA (A) : NULL +REMARK 3 LOW RESOLUTION CUTOFF (A) : 10.00 +REMARK 3 +REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES. +REMARK 3 DISTANCE RESTRAINTS. RMS SIGMA +REMARK 3 BOND LENGTH (A) : 0.009 ; 0.010 +REMARK 3 ANGLE DISTANCE (A) : 0.003 ; 0.025 +REMARK 3 INTRAPLANAR 1-4 DISTANCE (A) : 0.024 ; 0.020 +REMARK 3 H-BOND OR METAL COORDINATION (A) : NULL ; NULL +REMARK 3 +REMARK 3 PLANE RESTRAINT (A) : 0.033 ; 0.030 +REMARK 3 CHIRAL-CENTER RESTRAINT (A**3) : 0.212 ; 0.200 +REMARK 3 +REMARK 3 NON-BONDED CONTACT RESTRAINTS. +REMARK 3 SINGLE TORSION (A) : 0.183 ; 0.300 +REMARK 3 MULTIPLE TORSION (A) : 0.159 ; 0.300 +REMARK 3 H-BOND (X...Y) (A) : 0.299 ; 0.300 +REMARK 3 H-BOND (X-H...Y) (A) : NULL ; NULL +REMARK 3 +REMARK 3 CONFORMATIONAL TORSION ANGLE RESTRAINTS. +REMARK 3 SPECIFIED (DEGREES) : NULL ; NULL +REMARK 3 PLANAR (DEGREES) : 7.900 ; 5.000 +REMARK 3 STAGGERED (DEGREES) : 17.800; 15.000 +REMARK 3 TRANSVERSE (DEGREES) : 18.900; 15.000 +REMARK 3 +REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. RMS SIGMA +REMARK 3 MAIN-CHAIN BOND (A**2) : 2.500 ; 3.000 +REMARK 3 MAIN-CHAIN ANGLE (A**2) : 2.900 ; 4.000 +REMARK 3 SIDE-CHAIN BOND (A**2) : 3.200 ; 4.000 +REMARK 3 SIDE-CHAIN ANGLE (A**2) : 3.600 ; 3.000 +REMARK 3 +REMARK 3 OTHER REFINEMENT REMARKS: NULL +REMARK 4 +REMARK 4 1AKI COMPLIES WITH FORMAT V. 3.15, 01-DEC-08 +REMARK 100 +REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY BNL. +REMARK 200 +REMARK 200 EXPERIMENTAL DETAILS +REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION +REMARK 200 DATE OF DATA COLLECTION : NOV-95 +REMARK 200 TEMPERATURE (KELVIN) : 298 +REMARK 200 PH : 4.48 +REMARK 200 NUMBER OF CRYSTALS USED : 1 +REMARK 200 +REMARK 200 SYNCHROTRON (Y/N) : N +REMARK 200 RADIATION SOURCE : ROTATING ANODE +REMARK 200 BEAMLINE : NULL +REMARK 200 X-RAY GENERATOR MODEL : RIGAKU RUH2R +REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M +REMARK 200 WAVELENGTH OR RANGE (A) : 1.5418 +REMARK 200 MONOCHROMATOR : GRAPHITE(002) +REMARK 200 OPTICS : NULL +REMARK 200 +REMARK 200 DETECTOR TYPE : IMAGE PLATE +REMARK 200 DETECTOR MANUFACTURER : RIGAKU RAXIS IIC +REMARK 200 INTENSITY-INTEGRATION SOFTWARE : RIGAKU +REMARK 200 DATA SCALING SOFTWARE : BIOTEX +REMARK 200 +REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 20571 +REMARK 200 RESOLUTION RANGE HIGH (A) : 1.500 +REMARK 200 RESOLUTION RANGE LOW (A) : 15.000 +REMARK 200 REJECTION CRITERIA (SIGMA(I)) : 1.000 +REMARK 200 +REMARK 200 OVERALL. +REMARK 200 COMPLETENESS FOR RANGE (%) : 91.1 +REMARK 200 DATA REDUNDANCY : 3.100 +REMARK 200 R MERGE (I) : 0.04400 +REMARK 200 R SYM (I) : NULL +REMARK 200 <I/SIGMA(I)> FOR THE DATA SET : 11.7000 +REMARK 200 +REMARK 200 IN THE HIGHEST RESOLUTION SHELL. +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : NULL +REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : NULL +REMARK 200 COMPLETENESS FOR SHELL (%) : NULL +REMARK 200 DATA REDUNDANCY IN SHELL : NULL +REMARK 200 R MERGE FOR SHELL (I) : NULL +REMARK 200 R SYM FOR SHELL (I) : NULL +REMARK 200 <I/SIGMA(I)> FOR SHELL : NULL +REMARK 200 +REMARK 200 DIFFRACTION PROTOCOL: NULL +REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: MOLECULAR REPLACEMENT +REMARK 200 SOFTWARE USED: X-PLOR +REMARK 200 STARTING MODEL: PDB ENTRY 2LZH +REMARK 200 +REMARK 200 REMARK: NULL +REMARK 280 +REMARK 280 CRYSTAL +REMARK 280 SOLVENT CONTENT, VS (%): 42.84 +REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 2.15 +REMARK 280 +REMARK 280 CRYSTALLIZATION CONDITIONS: PH 4.48 +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY +REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: P 21 21 21 +REMARK 290 +REMARK 290 SYMOP SYMMETRY +REMARK 290 NNNMMM OPERATOR +REMARK 290 1555 X,Y,Z +REMARK 290 2555 -X+1/2,-Y,Z+1/2 +REMARK 290 3555 -X,Y+1/2,-Z+1/2 +REMARK 290 4555 X+1/2,-Y+1/2,-Z +REMARK 290 +REMARK 290 WHERE NNN -> OPERATOR NUMBER +REMARK 290 MMM -> TRANSLATION VECTOR +REMARK 290 +REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS +REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM +REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY +REMARK 290 RELATED MOLECULES. +REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 29.53100 +REMARK 290 SMTRY2 2 0.000000 -1.000000 0.000000 0.00000 +REMARK 290 SMTRY3 2 0.000000 0.000000 1.000000 15.25850 +REMARK 290 SMTRY1 3 -1.000000 0.000000 0.000000 0.00000 +REMARK 290 SMTRY2 3 0.000000 1.000000 0.000000 34.22550 +REMARK 290 SMTRY3 3 0.000000 0.000000 -1.000000 15.25850 +REMARK 290 SMTRY1 4 1.000000 0.000000 0.000000 29.53100 +REMARK 290 SMTRY2 4 0.000000 -1.000000 0.000000 34.22550 +REMARK 290 SMTRY3 4 0.000000 0.000000 -1.000000 0.00000 +REMARK 290 +REMARK 290 REMARK: NULL +REMARK 300 +REMARK 300 BIOMOLECULE: 1 +REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM +REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN +REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON +REMARK 300 BURIED SURFACE AREA. +REMARK 350 +REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN +REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE +REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS +REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND +REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN. +REMARK 350 +REMARK 350 BIOMOLECULE: 1 +REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: MONOMERIC +REMARK 350 APPLY THE FOLLOWING TO CHAINS: A +REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000 +REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000 +REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000 +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: CLOSE CONTACTS IN SAME ASYMMETRIC UNIT +REMARK 500 +REMARK 500 THE FOLLOWING ATOMS ARE IN CLOSE CONTACT. +REMARK 500 +REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI DISTANCE +REMARK 500 NH2 ARG A 45 NH2 ARG A 68 2.16 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: CLOSE CONTACTS +REMARK 500 +REMARK 500 THE FOLLOWING ATOMS THAT ARE RELATED BY CRYSTALLOGRAPHIC +REMARK 500 SYMMETRY ARE IN CLOSE CONTACT. AN ATOM LOCATED WITHIN 0.15 +REMARK 500 ANGSTROMS OF A SYMMETRY RELATED ATOM IS ASSUMED TO BE ON A +REMARK 500 SPECIAL POSITION AND IS, THEREFORE, LISTED IN REMARK 375 +REMARK 500 INSTEAD OF REMARK 500. ATOMS WITH NON-BLANK ALTERNATE +REMARK 500 LOCATION INDICATORS ARE NOT INCLUDED IN THE CALCULATIONS. +REMARK 500 +REMARK 500 DISTANCE CUTOFF: +REMARK 500 2.2 ANGSTROMS FOR CONTACTS NOT INVOLVING HYDROGEN ATOMS +REMARK 500 1.6 ANGSTROMS FOR CONTACTS INVOLVING HYDROGEN ATOMS +REMARK 500 +REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI SSYMOP DISTANCE +REMARK 500 OD1 ASN A 19 ND2 ASN A 39 1556 2.09 +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: COVALENT BOND ANGLES +REMARK 500 +REMARK 500 THE STEREOCHEMICAL PARAMETERS OF THE FOLLOWING RESIDUES +REMARK 500 HAVE VALUES WHICH DEVIATE FROM EXPECTED VALUES BY MORE +REMARK 500 THAN 6*RMSD (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN +REMARK 500 IDENTIFIER; SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 STANDARD TABLE: +REMARK 500 FORMAT: (10X,I3,1X,A3,1X,A1,I4,A1,3(1X,A4,2X),12X,F5.1) +REMARK 500 +REMARK 500 EXPECTED VALUES PROTEIN: ENGH AND HUBER, 1999 +REMARK 500 EXPECTED VALUES NUCLEIC ACID: CLOWNEY ET AL 1996 +REMARK 500 +REMARK 500 M RES CSSEQI ATM1 ATM2 ATM3 +REMARK 500 ARG A 14 NE - CZ - NH1 ANGL. DEV. = -4.2 DEGREES +REMARK 500 ASP A 18 CB - CG - OD1 ANGL. DEV. = 6.1 DEGREES +REMARK 500 ARG A 21 CD - NE - CZ ANGL. DEV. = 13.6 DEGREES +REMARK 500 ARG A 21 NE - CZ - NH2 ANGL. DEV. = 5.1 DEGREES +REMARK 500 ARG A 45 NE - CZ - NH1 ANGL. DEV. = 4.6 DEGREES +REMARK 500 ARG A 45 NE - CZ - NH2 ANGL. DEV. = -5.7 DEGREES +REMARK 500 ASP A 66 CB - CG - OD1 ANGL. DEV. = 6.6 DEGREES +REMARK 500 ASP A 66 CB - CG - OD2 ANGL. DEV. = -7.2 DEGREES +REMARK 500 ARG A 68 NE - CZ - NH1 ANGL. DEV. = 8.8 DEGREES +REMARK 500 ARG A 68 NE - CZ - NH2 ANGL. DEV. = -6.5 DEGREES +REMARK 500 ARG A 73 NE - CZ - NH2 ANGL. DEV. = -4.4 DEGREES +REMARK 500 ASP A 87 CB - CG - OD1 ANGL. DEV. = 8.6 DEGREES +REMARK 500 ARG A 112 NE - CZ - NH1 ANGL. DEV. = 4.4 DEGREES +REMARK 500 ARG A 125 NE - CZ - NH2 ANGL. DEV. = -5.0 DEGREES +REMARK 500 ARG A 128 NE - CZ - NH1 ANGL. DEV. = 3.0 DEGREES +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: PLANAR GROUPS +REMARK 500 +REMARK 500 PLANAR GROUPS IN THE FOLLOWING RESIDUES HAVE A TOTAL +REMARK 500 RMS DISTANCE OF ALL ATOMS FROM THE BEST-FIT PLANE +REMARK 500 BY MORE THAN AN EXPECTED VALUE OF 6*RMSD, WITH AN +REMARK 500 RMSD 0.02 ANGSTROMS, OR AT LEAST ONE ATOM HAS +REMARK 500 AN RMSD GREATER THAN THIS VALUE +REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER; +REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE). +REMARK 500 +REMARK 500 M RES CSSEQI RMS TYPE +REMARK 500 ARG A 14 0.12 SIDE_CHAIN +REMARK 500 ARG A 21 0.21 SIDE_CHAIN +REMARK 500 ARG A 68 0.15 SIDE_CHAIN +REMARK 500 ARG A 73 0.25 SIDE_CHAIN +REMARK 500 ARG A 112 0.15 SIDE_CHAIN +REMARK 500 ARG A 114 0.13 SIDE_CHAIN +REMARK 500 +REMARK 500 REMARK: NULL +REMARK 500 +REMARK 500 GEOMETRY AND STEREOCHEMISTRY +REMARK 500 SUBTOPIC: MAIN CHAIN PLANARITY +REMARK 500 +REMARK 500 THE FOLLOWING RESIDUES HAVE A PSEUDO PLANARITY +REMARK 500 TORSION, C(I) - CA(I) - N(I+1) - O(I), GREATER +REMARK 500 10.0 DEGREES. (M=MODEL NUMBER; RES=RESIDUE NAME; +REMARK 500 C=CHAIN IDENTIFIER; SSEQ=SEQUENCE NUMBER; +REMARK 500 I=INSERTION CODE). +REMARK 500 +REMARK 500 M RES CSSEQI ANGLE +REMARK 500 ARG A 128 10.17 +REMARK 500 +REMARK 500 REMARK: NULL +DBREF 1AKI A 1 129 UNP P00698 LYSC_CHICK 19 147 +SEQRES 1 A 129 LYS VAL PHE GLY ARG CYS GLU LEU ALA ALA ALA MET LYS +SEQRES 2 A 129 ARG HIS GLY LEU ASP ASN TYR ARG GLY TYR SER LEU GLY +SEQRES 3 A 129 ASN TRP VAL CYS ALA ALA LYS PHE GLU SER ASN PHE ASN +SEQRES 4 A 129 THR GLN ALA THR ASN ARG ASN THR ASP GLY SER THR ASP +SEQRES 5 A 129 TYR GLY ILE LEU GLN ILE ASN SER ARG TRP TRP CYS ASN +SEQRES 6 A 129 ASP GLY ARG THR PRO GLY SER ARG ASN LEU CYS ASN ILE +SEQRES 7 A 129 PRO CYS SER ALA LEU LEU SER SER ASP ILE THR ALA SER +SEQRES 8 A 129 VAL ASN CYS ALA LYS LYS ILE VAL SER ASP GLY ASN GLY +SEQRES 9 A 129 MET ASN ALA TRP VAL ALA TRP ARG ASN ARG CYS LYS GLY +SEQRES 10 A 129 THR ASP VAL GLN ALA TRP ILE ARG GLY CYS ARG LEU +FORMUL 2 HOH *78(H2 O) +HELIX 1 1 ARG A 5 ARG A 14 1 10 +HELIX 2 2 TYR A 20 GLY A 22 5 3 +HELIX 3 3 LEU A 25 SER A 36 1 12 +HELIX 4 4 CYS A 80 LEU A 84 5 5 +HELIX 5 5 THR A 89 ASP A 101 1 13 +HELIX 6 6 GLY A 104 ALA A 107 5 4 +HELIX 7 7 VAL A 109 ARG A 114 1 6 +HELIX 8 8 VAL A 120 TRP A 123 5 4 +SHEET 1 A 2 THR A 43 ARG A 45 0 +SHEET 2 A 2 THR A 51 TYR A 53 -1 N ASP A 52 O ASN A 44 +SSBOND 1 CYS A 6 CYS A 127 1555 1555 1.97 +SSBOND 2 CYS A 30 CYS A 115 1555 1555 2.00 +SSBOND 3 CYS A 64 CYS A 80 1555 1555 1.99 +SSBOND 4 CYS A 76 CYS A 94 1555 1555 2.02 +CRYST1 59.062 68.451 30.517 90.00 90.00 90.00 P 21 21 21 4 +ORIGX1 1.000000 0.000000 0.000000 0.00000 +ORIGX2 0.000000 1.000000 0.000000 0.00000 +ORIGX3 0.000000 0.000000 1.000000 0.00000 +SCALE1 0.016931 0.000000 0.000000 0.00000 +SCALE2 0.000000 0.014609 0.000000 0.00000 +SCALE3 0.000000 0.000000 0.032769 0.00000 +ATOM 1 N LYS A 1 35.365 22.342 -11.980 1.00 22.28 N +ATOM 2 CA LYS A 1 35.892 21.073 -11.427 1.00 21.12 C +ATOM 3 C LYS A 1 34.741 20.264 -10.844 1.00 16.85 C +ATOM 4 O LYS A 1 33.945 20.813 -10.081 1.00 18.94 O +ATOM 5 CB LYS A 1 36.872 21.435 -10.306 1.00 20.78 C +ATOM 6 CG LYS A 1 37.453 20.248 -9.565 1.00 18.47 C +ATOM 7 CD LYS A 1 38.688 20.649 -8.775 1.00 20.32 C +ATOM 8 CE LYS A 1 39.057 19.508 -7.837 1.00 24.76 C +ATOM 9 NZ LYS A 1 40.423 19.771 -7.299 1.00 28.27 N +ATOM 10 N VAL A 2 34.739 18.961 -11.042 1.00 19.96 N +ATOM 11 CA VAL A 2 33.903 17.998 -10.333 1.00 18.10 C +ATOM 12 C VAL A 2 34.800 17.312 -9.294 1.00 19.39 C +ATOM 13 O VAL A 2 35.759 16.605 -9.665 1.00 22.14 O +ATOM 14 CB VAL A 2 33.140 17.034 -11.232 1.00 16.81 C +ATOM 15 CG1 VAL A 2 32.251 16.084 -10.434 1.00 21.92 C +ATOM 16 CG2 VAL A 2 32.294 17.714 -12.290 1.00 19.46 C +ATOM 17 N PHE A 3 34.491 17.546 -8.038 1.00 19.89 N +ATOM 18 CA PHE A 3 35.185 16.903 -6.918 1.00 17.43 C +ATOM 19 C PHE A 3 34.742 15.441 -6.771 1.00 15.70 C +ATOM 20 O PHE A 3 33.525 15.162 -6.862 1.00 18.52 O +ATOM 21 CB PHE A 3 34.967 17.632 -5.594 1.00 17.94 C +ATOM 22 CG PHE A 3 35.944 18.737 -5.375 1.00 16.78 C +ATOM 23 CD1 PHE A 3 35.666 20.050 -5.798 1.00 15.97 C +ATOM 24 CD2 PHE A 3 37.000 18.557 -4.473 1.00 19.95 C +ATOM 25 CE1 PHE A 3 36.577 21.076 -5.568 1.00 17.32 C +ATOM 26 CE2 PHE A 3 37.869 19.589 -4.157 1.00 17.65 C +ATOM 27 CZ PHE A 3 37.636 20.873 -4.666 1.00 17.91 C +ATOM 28 N GLY A 4 35.724 14.639 -6.331 1.00 16.79 N +ATOM 29 CA GLY A 4 35.366 13.280 -5.870 1.00 16.34 C +ATOM 30 C GLY A 4 34.924 13.420 -4.415 1.00 11.91 C +ATOM 31 O GLY A 4 35.303 14.403 -3.781 1.00 16.23 O +ATOM 32 N ARG A 5 34.053 12.538 -3.973 1.00 14.65 N +ATOM 33 CA ARG A 5 33.565 12.538 -2.588 1.00 15.91 C +ATOM 34 C ARG A 5 34.665 12.734 -1.556 1.00 15.38 C +ATOM 35 O ARG A 5 34.669 13.651 -0.704 1.00 13.15 O +ATOM 36 CB ARG A 5 32.765 11.262 -2.331 1.00 17.38 C +ATOM 37 CG ARG A 5 32.213 11.203 -0.920 1.00 13.79 C +ATOM 38 CD ARG A 5 31.375 10.001 -0.722 1.00 15.84 C +ATOM 39 NE ARG A 5 32.059 8.749 -0.958 1.00 18.74 N +ATOM 40 CZ ARG A 5 32.733 8.011 -0.097 1.00 15.19 C +ATOM 41 NH1 ARG A 5 32.836 8.332 1.187 1.00 17.50 N +ATOM 42 NH2 ARG A 5 33.245 6.836 -0.526 1.00 23.44 N +ATOM 43 N CYS A 6 35.674 11.853 -1.612 1.00 14.07 N +ATOM 44 CA CYS A 6 36.781 11.870 -0.654 1.00 14.62 C +ATOM 45 C CYS A 6 37.747 13.050 -0.777 1.00 10.99 C +ATOM 46 O CYS A 6 38.148 13.609 0.264 1.00 16.34 O +ATOM 47 CB CYS A 6 37.491 10.532 -0.621 1.00 16.90 C +ATOM 48 SG CYS A 6 36.540 9.205 0.140 1.00 18.61 S +ATOM 49 N GLU A 7 37.861 13.481 -2.019 1.00 14.24 N +ATOM 50 CA GLU A 7 38.685 14.686 -2.311 1.00 13.83 C +ATOM 51 C GLU A 7 38.049 15.926 -1.658 1.00 14.86 C +ATOM 52 O GLU A 7 38.744 16.729 -1.011 1.00 15.01 O +ATOM 53 CB GLU A 7 38.784 14.846 -3.818 1.00 14.85 C +ATOM 54 CG GLU A 7 39.540 16.051 -4.379 1.00 18.50 C +ATOM 55 CD GLU A 7 39.576 16.242 -5.870 1.00 20.16 C +ATOM 56 OE1 GLU A 7 38.672 15.644 -6.491 1.00 26.20 O +ATOM 57 OE2 GLU A 7 40.415 16.953 -6.381 1.00 25.49 O +ATOM 58 N LEU A 8 36.743 16.049 -1.819 1.00 15.18 N +ATOM 59 CA LEU A 8 35.964 17.158 -1.255 1.00 12.72 C +ATOM 60 C LEU A 8 36.051 17.132 0.266 1.00 9.45 C +ATOM 61 O LEU A 8 36.159 18.166 0.920 1.00 13.45 O +ATOM 62 CB LEU A 8 34.528 17.172 -1.811 1.00 14.31 C +ATOM 63 CG LEU A 8 33.718 18.354 -1.305 1.00 15.95 C +ATOM 64 CD1 LEU A 8 34.297 19.656 -1.841 1.00 16.56 C +ATOM 65 CD2 LEU A 8 32.246 18.143 -1.596 1.00 15.88 C +ATOM 66 N ALA A 9 35.754 15.980 0.828 1.00 14.24 N +ATOM 67 CA ALA A 9 35.838 15.757 2.284 1.00 13.25 C +ATOM 68 C ALA A 9 37.144 16.314 2.840 1.00 12.89 C +ATOM 69 O ALA A 9 37.151 16.978 3.897 1.00 14.78 O +ATOM 70 CB ALA A 9 35.656 14.287 2.623 1.00 13.89 C +ATOM 71 N ALA A 10 38.272 15.983 2.204 1.00 12.54 N +ATOM 72 CA ALA A 10 39.610 16.431 2.616 1.00 16.58 C +ATOM 73 C ALA A 10 39.736 17.944 2.459 1.00 15.35 C +ATOM 74 O ALA A 10 40.193 18.499 3.469 1.00 17.40 O +ATOM 75 CB ALA A 10 40.708 15.706 1.842 1.00 15.49 C +ATOM 76 N ALA A 11 39.227 18.519 1.385 1.00 13.54 N +ATOM 77 CA ALA A 11 39.264 19.982 1.223 1.00 15.23 C +ATOM 78 C ALA A 11 38.491 20.702 2.321 1.00 15.68 C +ATOM 79 O ALA A 11 38.946 21.658 2.953 1.00 16.87 O +ATOM 80 CB ALA A 11 38.869 20.421 -0.175 1.00 14.12 C +ATOM 81 N MET A 12 37.288 20.214 2.590 1.00 15.47 N +ATOM 82 CA MET A 12 36.398 20.781 3.612 1.00 13.69 C +ATOM 83 C MET A 12 36.990 20.715 5.007 1.00 12.55 C +ATOM 84 O MET A 12 36.906 21.637 5.840 1.00 17.69 O +ATOM 85 CB MET A 12 34.993 20.213 3.515 1.00 11.18 C +ATOM 86 CG MET A 12 34.320 20.724 2.265 1.00 15.06 C +ATOM 87 SD MET A 12 32.634 19.986 2.235 1.00 17.81 S +ATOM 88 CE MET A 12 31.788 21.135 1.138 1.00 18.08 C +ATOM 89 N LYS A 13 37.688 19.628 5.314 1.00 12.42 N +ATOM 90 CA LYS A 13 38.387 19.385 6.579 1.00 14.58 C +ATOM 91 C LYS A 13 39.460 20.467 6.731 1.00 14.55 C +ATOM 92 O LYS A 13 39.507 21.137 7.776 1.00 16.49 O +ATOM 93 CB LYS A 13 38.934 17.952 6.572 1.00 15.36 C +ATOM 94 CG LYS A 13 39.742 17.555 7.798 1.00 20.46 C +ATOM 95 CD LYS A 13 38.973 16.777 8.834 1.00 23.53 C +ATOM 96 CE LYS A 13 39.293 15.305 8.751 1.00 26.37 C +ATOM 97 NZ LYS A 13 38.077 14.461 8.946 1.00 30.88 N +ATOM 98 N ARG A 14 40.267 20.629 5.688 1.00 18.91 N +ATOM 99 CA ARG A 14 41.387 21.577 5.713 1.00 17.66 C +ATOM 100 C ARG A 14 40.927 23.017 5.881 1.00 16.78 C +ATOM 101 O ARG A 14 41.557 23.834 6.584 1.00 20.06 O +ATOM 102 CB ARG A 14 42.388 21.351 4.601 1.00 20.89 C +ATOM 103 CG ARG A 14 42.173 22.079 3.289 1.00 25.07 C +ATOM 104 CD ARG A 14 43.444 22.075 2.490 1.00 23.98 C +ATOM 105 NE ARG A 14 43.687 20.710 2.012 1.00 31.92 N +ATOM 106 CZ ARG A 14 43.098 20.255 0.892 1.00 26.04 C +ATOM 107 NH1 ARG A 14 42.695 21.186 0.018 1.00 33.46 N +ATOM 108 NH2 ARG A 14 42.949 18.957 0.689 1.00 25.91 N +ATOM 109 N HIS A 15 39.681 23.247 5.463 1.00 17.84 N +ATOM 110 CA HIS A 15 39.075 24.591 5.526 1.00 15.99 C +ATOM 111 C HIS A 15 38.310 24.861 6.814 1.00 17.70 C +ATOM 112 O HIS A 15 37.608 25.875 6.952 1.00 22.68 O +ATOM 113 CB HIS A 15 38.223 24.918 4.285 1.00 19.19 C +ATOM 114 CG HIS A 15 39.085 25.388 3.171 1.00 20.14 C +ATOM 115 ND1 HIS A 15 39.457 24.635 2.091 1.00 24.53 N +ATOM 116 CD2 HIS A 15 39.739 26.570 2.993 1.00 24.44 C +ATOM 117 CE1 HIS A 15 40.211 25.312 1.258 1.00 20.68 C +ATOM 118 NE2 HIS A 15 40.524 26.419 1.889 1.00 27.34 N +ATOM 119 N GLY A 16 38.296 23.927 7.720 1.00 17.50 N +ATOM 120 CA GLY A 16 37.765 24.025 9.072 1.00 18.71 C +ATOM 121 C GLY A 16 36.264 23.799 9.210 1.00 18.40 C +ATOM 122 O GLY A 16 35.646 24.400 10.127 1.00 21.57 O +ATOM 123 N LEU A 17 35.665 23.073 8.274 1.00 17.56 N +ATOM 124 CA LEU A 17 34.238 22.795 8.298 1.00 15.38 C +ATOM 125 C LEU A 17 33.845 21.682 9.266 1.00 18.28 C +ATOM 126 O LEU A 17 32.643 21.594 9.552 1.00 18.24 O +ATOM 127 CB LEU A 17 33.648 22.647 6.901 1.00 15.02 C +ATOM 128 CG LEU A 17 33.451 23.889 6.060 1.00 16.08 C +ATOM 129 CD1 LEU A 17 32.933 23.420 4.705 1.00 13.83 C +ATOM 130 CD2 LEU A 17 32.556 24.946 6.679 1.00 18.60 C +ATOM 131 N ASP A 18 34.785 20.814 9.605 1.00 16.36 N +ATOM 132 CA ASP A 18 34.492 19.722 10.526 1.00 16.25 C +ATOM 133 C ASP A 18 34.015 20.222 11.901 1.00 17.32 C +ATOM 134 O ASP A 18 34.826 20.778 12.658 1.00 20.27 O +ATOM 135 CB ASP A 18 35.557 18.633 10.598 1.00 19.37 C +ATOM 136 CG ASP A 18 35.017 17.408 11.311 1.00 20.25 C +ATOM 137 OD1 ASP A 18 33.805 17.154 11.455 1.00 21.00 O +ATOM 138 OD2 ASP A 18 35.925 16.603 11.662 1.00 27.06 O +ATOM 139 N ASN A 19 32.746 19.990 12.205 1.00 18.55 N +ATOM 140 CA ASN A 19 32.123 20.431 13.448 1.00 17.19 C +ATOM 141 C ASN A 19 31.854 21.941 13.497 1.00 16.61 C +ATOM 142 O ASN A 19 31.426 22.398 14.573 1.00 18.56 O +ATOM 143 CB ASN A 19 32.767 20.004 14.770 1.00 18.92 C +ATOM 144 CG ASN A 19 32.162 20.512 16.064 1.00 24.64 C +ATOM 145 OD1 ASN A 19 30.967 20.273 16.355 1.00 32.53 O +ATOM 146 ND2 ASN A 19 32.847 21.361 16.852 1.00 24.14 N +ATOM 147 N TYR A 20 31.969 22.650 12.406 1.00 16.84 N +ATOM 148 CA TYR A 20 31.707 24.099 12.411 1.00 15.54 C +ATOM 149 C TYR A 20 30.231 24.343 12.759 1.00 15.81 C +ATOM 150 O TYR A 20 29.288 23.874 12.118 1.00 16.89 O +ATOM 151 CB TYR A 20 32.070 24.736 11.066 1.00 18.16 C +ATOM 152 CG TYR A 20 32.061 26.250 11.144 1.00 20.28 C +ATOM 153 CD1 TYR A 20 33.141 26.886 11.760 1.00 21.42 C +ATOM 154 CD2 TYR A 20 30.979 27.004 10.691 1.00 20.44 C +ATOM 155 CE1 TYR A 20 33.206 28.277 11.794 1.00 22.24 C +ATOM 156 CE2 TYR A 20 31.018 28.399 10.779 1.00 21.36 C +ATOM 157 CZ TYR A 20 32.102 29.017 11.383 1.00 19.38 C +ATOM 158 OH TYR A 20 32.136 30.371 11.525 1.00 26.77 O +ATOM 159 N ARG A 21 30.088 25.142 13.803 1.00 18.43 N +ATOM 160 CA ARG A 21 28.774 25.553 14.319 1.00 15.68 C +ATOM 161 C ARG A 21 27.964 24.312 14.623 1.00 15.17 C +ATOM 162 O ARG A 21 26.733 24.333 14.606 1.00 18.36 O +ATOM 163 CB ARG A 21 28.014 26.565 13.453 1.00 19.21 C +ATOM 164 CG ARG A 21 28.507 27.995 13.535 1.00 21.50 C +ATOM 165 CD ARG A 21 28.110 28.755 14.765 1.00 25.00 C +ATOM 166 NE ARG A 21 29.319 29.321 15.324 1.00 30.37 N +ATOM 167 CZ ARG A 21 30.215 30.234 14.978 1.00 29.02 C +ATOM 168 NH1 ARG A 21 31.501 29.856 14.846 1.00 29.04 N +ATOM 169 NH2 ARG A 21 29.938 31.437 14.495 1.00 31.89 N +ATOM 170 N GLY A 22 28.689 23.250 14.998 1.00 17.81 N +ATOM 171 CA GLY A 22 28.103 22.021 15.519 1.00 17.72 C +ATOM 172 C GLY A 22 27.748 21.018 14.436 1.00 18.89 C +ATOM 173 O GLY A 22 27.085 20.022 14.784 1.00 23.26 O +ATOM 174 N TYR A 23 28.209 21.230 13.216 1.00 18.20 N +ATOM 175 CA TYR A 23 27.887 20.318 12.111 1.00 15.42 C +ATOM 176 C TYR A 23 29.124 19.533 11.628 1.00 16.30 C +ATOM 177 O TYR A 23 30.045 20.191 11.139 1.00 16.66 O +ATOM 178 CB TYR A 23 27.351 21.107 10.913 1.00 15.82 C +ATOM 179 CG TYR A 23 26.001 21.745 11.127 1.00 15.96 C +ATOM 180 CD1 TYR A 23 24.846 20.962 11.139 1.00 14.81 C +ATOM 181 CD2 TYR A 23 25.897 23.096 11.458 1.00 16.60 C +ATOM 182 CE1 TYR A 23 23.600 21.518 11.422 1.00 17.08 C +ATOM 183 CE2 TYR A 23 24.647 23.673 11.726 1.00 19.34 C +ATOM 184 CZ TYR A 23 23.518 22.881 11.701 1.00 19.21 C +ATOM 185 OH TYR A 23 22.289 23.438 11.912 1.00 25.61 O +ATOM 186 N SER A 24 29.029 18.223 11.810 1.00 15.35 N +ATOM 187 CA SER A 24 30.143 17.347 11.414 1.00 16.89 C +ATOM 188 C SER A 24 30.359 17.379 9.895 1.00 15.61 C +ATOM 189 O SER A 24 29.442 17.687 9.139 1.00 13.88 O +ATOM 190 CB SER A 24 29.922 15.934 11.907 1.00 17.54 C +ATOM 191 OG SER A 24 28.799 15.336 11.308 1.00 19.85 O +ATOM 192 N LEU A 25 31.593 17.028 9.540 1.00 16.08 N +ATOM 193 CA LEU A 25 32.035 17.092 8.138 1.00 13.16 C +ATOM 194 C LEU A 25 31.030 16.437 7.183 1.00 13.39 C +ATOM 195 O LEU A 25 30.874 16.924 6.056 1.00 15.34 O +ATOM 196 CB LEU A 25 33.410 16.409 8.084 1.00 13.47 C +ATOM 197 CG LEU A 25 34.015 16.477 6.689 1.00 12.91 C +ATOM 198 CD1 LEU A 25 34.174 17.929 6.289 1.00 13.04 C +ATOM 199 CD2 LEU A 25 35.398 15.810 6.752 1.00 14.54 C +ATOM 200 N GLY A 26 30.501 15.280 7.576 1.00 13.10 N +ATOM 201 CA GLY A 26 29.539 14.561 6.756 1.00 13.88 C +ATOM 202 C GLY A 26 28.338 15.378 6.277 1.00 12.12 C +ATOM 203 O GLY A 26 27.886 15.250 5.120 1.00 13.13 O +ATOM 204 N ASN A 27 27.905 16.281 7.161 1.00 12.16 N +ATOM 205 CA ASN A 27 26.827 17.227 6.857 1.00 14.74 C +ATOM 206 C ASN A 27 27.164 18.015 5.597 1.00 15.43 C +ATOM 207 O ASN A 27 26.317 18.208 4.720 1.00 15.27 O +ATOM 208 CB ASN A 27 26.484 18.126 8.054 1.00 12.34 C +ATOM 209 CG ASN A 27 25.681 17.267 9.048 1.00 12.22 C +ATOM 210 OD1 ASN A 27 24.511 16.933 8.820 1.00 17.40 O +ATOM 211 ND2 ASN A 27 26.348 17.052 10.169 1.00 18.27 N +ATOM 212 N TRP A 28 28.344 18.591 5.583 1.00 16.78 N +ATOM 213 CA TRP A 28 28.831 19.475 4.513 1.00 16.49 C +ATOM 214 C TRP A 28 28.940 18.741 3.183 1.00 12.99 C +ATOM 215 O TRP A 28 28.742 19.321 2.090 1.00 13.97 O +ATOM 216 CB TRP A 28 30.104 20.145 5.023 1.00 14.55 C +ATOM 217 CG TRP A 28 29.941 20.978 6.251 1.00 11.93 C +ATOM 218 CD1 TRP A 28 30.176 20.624 7.546 1.00 14.42 C +ATOM 219 CD2 TRP A 28 29.319 22.284 6.287 1.00 13.11 C +ATOM 220 NE1 TRP A 28 29.924 21.690 8.365 1.00 16.94 N +ATOM 221 CE2 TRP A 28 29.337 22.679 7.641 1.00 14.07 C +ATOM 222 CE3 TRP A 28 28.894 23.168 5.295 1.00 15.97 C +ATOM 223 CZ2 TRP A 28 28.913 23.943 8.038 1.00 18.07 C +ATOM 224 CZ3 TRP A 28 28.398 24.404 5.682 1.00 18.26 C +ATOM 225 CH2 TRP A 28 28.431 24.766 7.025 1.00 17.18 C +ATOM 226 N VAL A 29 29.572 17.543 3.261 1.00 13.00 N +ATOM 227 CA VAL A 29 29.729 16.711 2.047 1.00 14.15 C +ATOM 228 C VAL A 29 28.379 16.340 1.429 1.00 10.43 C +ATOM 229 O VAL A 29 28.166 16.496 0.228 1.00 13.40 O +ATOM 230 CB VAL A 29 30.649 15.492 2.359 1.00 12.76 C +ATOM 231 CG1 VAL A 29 30.782 14.596 1.136 1.00 15.37 C +ATOM 232 CG2 VAL A 29 32.010 16.050 2.772 1.00 14.18 C +ATOM 233 N CYS A 30 27.501 15.906 2.299 1.00 15.32 N +ATOM 234 CA CYS A 30 26.115 15.567 1.991 1.00 15.59 C +ATOM 235 C CYS A 30 25.388 16.723 1.302 1.00 12.37 C +ATOM 236 O CYS A 30 24.894 16.516 0.172 1.00 14.44 O +ATOM 237 CB CYS A 30 25.343 15.046 3.172 1.00 14.99 C +ATOM 238 SG CYS A 30 23.719 14.376 2.695 1.00 17.71 S +ATOM 239 N ALA A 31 25.533 17.913 1.870 1.00 16.06 N +ATOM 240 CA ALA A 31 24.949 19.130 1.305 1.00 15.82 C +ATOM 241 C ALA A 31 25.487 19.354 -0.115 1.00 15.34 C +ATOM 242 O ALA A 31 24.675 19.686 -0.998 1.00 16.00 O +ATOM 243 CB ALA A 31 25.167 20.335 2.200 1.00 14.90 C +ATOM 244 N ALA A 32 26.807 19.354 -0.286 1.00 11.93 N +ATOM 245 CA ALA A 32 27.461 19.536 -1.579 1.00 13.08 C +ATOM 246 C ALA A 32 26.943 18.538 -2.620 1.00 12.38 C +ATOM 247 O ALA A 32 26.767 18.857 -3.789 1.00 13.89 O +ATOM 248 CB ALA A 32 28.982 19.476 -1.398 1.00 14.17 C +ATOM 249 N LYS A 33 26.731 17.303 -2.193 1.00 15.16 N +ATOM 250 CA LYS A 33 26.261 16.216 -3.037 1.00 16.16 C +ATOM 251 C LYS A 33 24.903 16.555 -3.658 1.00 15.04 C +ATOM 252 O LYS A 33 24.806 16.511 -4.890 1.00 15.00 O +ATOM 253 CB LYS A 33 26.221 14.860 -2.351 1.00 16.71 C +ATOM 254 CG LYS A 33 25.697 13.696 -3.185 1.00 19.51 C +ATOM 255 CD LYS A 33 26.498 13.400 -4.446 1.00 17.12 C +ATOM 256 CE LYS A 33 25.686 12.464 -5.331 1.00 24.06 C +ATOM 257 NZ LYS A 33 26.423 11.979 -6.525 1.00 26.78 N +ATOM 258 N PHE A 34 23.972 16.946 -2.817 1.00 16.81 N +ATOM 259 CA PHE A 34 22.569 17.125 -3.247 1.00 17.51 C +ATOM 260 C PHE A 34 22.346 18.506 -3.836 1.00 18.19 C +ATOM 261 O PHE A 34 21.504 18.692 -4.759 1.00 20.21 O +ATOM 262 CB PHE A 34 21.626 16.673 -2.130 1.00 18.58 C +ATOM 263 CG PHE A 34 21.644 15.172 -1.965 1.00 22.22 C +ATOM 264 CD1 PHE A 34 21.209 14.353 -3.007 1.00 20.24 C +ATOM 265 CD2 PHE A 34 22.272 14.627 -0.851 1.00 20.00 C +ATOM 266 CE1 PHE A 34 21.372 12.961 -2.910 1.00 22.03 C +ATOM 267 CE2 PHE A 34 22.443 13.245 -0.743 1.00 21.96 C +ATOM 268 CZ PHE A 34 21.923 12.406 -1.737 1.00 20.77 C +ATOM 269 N GLU A 35 23.251 19.415 -3.451 1.00 15.27 N +ATOM 270 CA GLU A 35 23.178 20.789 -3.996 1.00 15.45 C +ATOM 271 C GLU A 35 23.661 20.944 -5.423 1.00 17.45 C +ATOM 272 O GLU A 35 23.014 21.514 -6.310 1.00 17.91 O +ATOM 273 CB GLU A 35 23.698 21.892 -3.107 1.00 14.42 C +ATOM 274 CG GLU A 35 22.994 22.212 -1.809 1.00 11.08 C +ATOM 275 CD GLU A 35 21.631 22.846 -1.864 1.00 13.55 C +ATOM 276 OE1 GLU A 35 21.408 23.360 -2.981 1.00 20.77 O +ATOM 277 OE2 GLU A 35 20.947 23.032 -0.874 1.00 22.72 O +ATOM 278 N SER A 36 24.867 20.483 -5.674 1.00 15.66 N +ATOM 279 CA SER A 36 25.626 20.615 -6.903 1.00 17.79 C +ATOM 280 C SER A 36 26.139 19.341 -7.569 1.00 16.97 C +ATOM 281 O SER A 36 26.750 19.464 -8.642 1.00 21.78 O +ATOM 282 CB SER A 36 26.830 21.528 -6.654 1.00 18.12 C +ATOM 283 OG SER A 36 27.747 20.951 -5.748 1.00 15.16 O +ATOM 284 N ASN A 37 25.957 18.222 -6.927 1.00 20.15 N +ATOM 285 CA ASN A 37 26.628 16.968 -7.297 1.00 20.85 C +ATOM 286 C ASN A 37 28.149 17.091 -7.302 1.00 19.72 C +ATOM 287 O ASN A 37 28.813 16.627 -8.254 1.00 20.79 O +ATOM 288 CB ASN A 37 26.028 16.490 -8.617 1.00 20.82 C +ATOM 289 CG ASN A 37 26.156 14.980 -8.782 1.00 23.63 C +ATOM 290 OD1 ASN A 37 26.640 14.266 -7.885 1.00 28.05 O +ATOM 291 ND2 ASN A 37 25.867 14.506 -9.990 1.00 29.61 N +ATOM 292 N PHE A 38 28.691 17.882 -6.383 1.00 16.12 N +ATOM 293 CA PHE A 38 30.129 18.115 -6.279 1.00 14.75 C +ATOM 294 C PHE A 38 30.717 18.903 -7.448 1.00 13.86 C +ATOM 295 O PHE A 38 31.923 18.794 -7.702 1.00 16.66 O +ATOM 296 CB PHE A 38 30.914 16.823 -6.047 1.00 17.09 C +ATOM 297 CG PHE A 38 30.487 16.006 -4.863 1.00 15.96 C +ATOM 298 CD1 PHE A 38 30.100 16.572 -3.655 1.00 15.43 C +ATOM 299 CD2 PHE A 38 30.507 14.603 -4.993 1.00 17.66 C +ATOM 300 CE1 PHE A 38 29.766 15.808 -2.558 1.00 16.83 C +ATOM 301 CE2 PHE A 38 30.136 13.814 -3.891 1.00 15.86 C +ATOM 302 CZ PHE A 38 29.835 14.410 -2.646 1.00 18.90 C +ATOM 303 N ASN A 39 29.936 19.792 -8.033 1.00 17.63 N +ATOM 304 CA ASN A 39 30.341 20.573 -9.199 1.00 16.77 C +ATOM 305 C ASN A 39 30.543 22.034 -8.823 1.00 17.13 C +ATOM 306 O ASN A 39 29.544 22.649 -8.423 1.00 17.24 O +ATOM 307 CB ASN A 39 29.406 20.300 -10.366 1.00 17.40 C +ATOM 308 CG ASN A 39 29.876 20.771 -11.716 1.00 16.96 C +ATOM 309 OD1 ASN A 39 30.579 21.750 -11.956 1.00 23.22 O +ATOM 310 ND2 ASN A 39 29.578 19.864 -12.653 1.00 26.35 N +ATOM 311 N THR A 40 31.766 22.492 -8.928 1.00 14.88 N +ATOM 312 CA THR A 40 32.139 23.869 -8.657 1.00 16.08 C +ATOM 313 C THR A 40 31.504 24.890 -9.589 1.00 16.31 C +ATOM 314 O THR A 40 31.316 26.054 -9.213 1.00 17.50 O +ATOM 315 CB THR A 40 33.684 24.103 -8.422 1.00 17.07 C +ATOM 316 OG1 THR A 40 34.270 24.156 -9.775 1.00 23.76 O +ATOM 317 CG2 THR A 40 34.414 23.119 -7.491 1.00 16.46 C +ATOM 318 N GLN A 41 31.001 24.430 -10.706 1.00 16.39 N +ATOM 319 CA GLN A 41 30.524 25.291 -11.812 1.00 16.67 C +ATOM 320 C GLN A 41 28.993 25.381 -11.874 1.00 15.44 C +ATOM 321 O GLN A 41 28.504 26.019 -12.837 1.00 18.55 O +ATOM 322 CB GLN A 41 31.047 24.817 -13.168 1.00 19.65 C +ATOM 323 CG GLN A 41 32.549 25.004 -13.279 1.00 21.26 C +ATOM 324 CD GLN A 41 32.763 26.236 -14.129 1.00 26.23 C +ATOM 325 OE1 GLN A 41 32.356 26.308 -15.291 1.00 24.68 O +ATOM 326 NE2 GLN A 41 33.276 27.231 -13.420 1.00 25.96 N +ATOM 327 N ALA A 42 28.329 24.640 -11.012 1.00 15.95 N +ATOM 328 CA ALA A 42 26.859 24.579 -11.061 1.00 17.42 C +ATOM 329 C ALA A 42 26.257 25.969 -10.807 1.00 18.93 C +ATOM 330 O ALA A 42 26.645 26.686 -9.884 1.00 17.00 O +ATOM 331 CB ALA A 42 26.355 23.604 -9.998 1.00 22.79 C +ATOM 332 N THR A 43 25.276 26.293 -11.643 1.00 18.30 N +ATOM 333 CA THR A 43 24.441 27.490 -11.476 1.00 17.73 C +ATOM 334 C THR A 43 22.976 27.112 -11.714 1.00 19.61 C +ATOM 335 O THR A 43 22.715 26.271 -12.594 1.00 22.06 O +ATOM 336 CB THR A 43 24.814 28.728 -12.375 1.00 17.58 C +ATOM 337 OG1 THR A 43 24.555 28.321 -13.756 1.00 20.94 O +ATOM 338 CG2 THR A 43 26.247 29.213 -12.184 1.00 18.26 C +ATOM 339 N ASN A 44 22.088 27.742 -10.971 1.00 19.77 N +ATOM 340 CA ASN A 44 20.640 27.497 -11.108 1.00 19.51 C +ATOM 341 C ASN A 44 19.903 28.842 -10.963 1.00 14.85 C +ATOM 342 O ASN A 44 20.169 29.600 -10.033 1.00 19.43 O +ATOM 343 CB ASN A 44 20.155 26.480 -10.080 1.00 19.93 C +ATOM 344 CG ASN A 44 18.646 26.315 -10.115 1.00 22.01 C +ATOM 345 OD1 ASN A 44 18.128 25.720 -11.078 1.00 29.53 O +ATOM 346 ND2 ASN A 44 17.906 26.927 -9.188 1.00 22.94 N +ATOM 347 N ARG A 45 19.058 29.117 -11.924 1.00 16.90 N +ATOM 348 CA ARG A 45 18.303 30.363 -12.015 1.00 18.37 C +ATOM 349 C ARG A 45 16.955 30.163 -11.326 1.00 18.76 C +ATOM 350 O ARG A 45 16.396 29.062 -11.425 1.00 20.87 O +ATOM 351 CB ARG A 45 18.143 30.836 -13.462 1.00 19.30 C +ATOM 352 CG ARG A 45 17.012 31.859 -13.557 1.00 23.98 C +ATOM 353 CD ARG A 45 17.502 33.134 -12.930 1.00 23.36 C +ATOM 354 NE ARG A 45 18.311 33.758 -13.981 1.00 29.56 N +ATOM 355 CZ ARG A 45 17.620 34.271 -15.020 1.00 27.18 C +ATOM 356 NH1 ARG A 45 16.287 34.331 -15.098 1.00 31.99 N +ATOM 357 NH2 ARG A 45 18.374 34.698 -16.030 1.00 32.43 N +ATOM 358 N ASN A 46 16.553 31.171 -10.554 1.00 18.13 N +ATOM 359 CA ASN A 46 15.304 31.071 -9.782 1.00 20.10 C +ATOM 360 C ASN A 46 14.261 32.063 -10.313 1.00 17.35 C +ATOM 361 O ASN A 46 14.617 33.104 -10.880 1.00 19.15 O +ATOM 362 CB ASN A 46 15.576 31.229 -8.295 1.00 20.05 C +ATOM 363 CG ASN A 46 16.543 30.240 -7.679 1.00 20.12 C +ATOM 364 OD1 ASN A 46 17.659 30.661 -7.346 1.00 21.21 O +ATOM 365 ND2 ASN A 46 16.125 28.975 -7.600 1.00 19.44 N +ATOM 366 N THR A 47 13.027 31.834 -9.887 1.00 19.96 N +ATOM 367 CA THR A 47 11.871 32.654 -10.246 1.00 19.12 C +ATOM 368 C THR A 47 12.001 34.107 -9.810 1.00 19.44 C +ATOM 369 O THR A 47 11.600 34.969 -10.606 1.00 23.16 O +ATOM 370 CB THR A 47 10.499 32.017 -9.789 1.00 17.70 C +ATOM 371 OG1 THR A 47 10.507 32.195 -8.342 1.00 23.76 O +ATOM 372 CG2 THR A 47 10.331 30.554 -10.188 1.00 22.66 C +ATOM 373 N ASP A 48 12.625 34.377 -8.683 1.00 19.25 N +ATOM 374 CA ASP A 48 12.885 35.716 -8.168 1.00 17.33 C +ATOM 375 C ASP A 48 14.010 36.505 -8.823 1.00 17.71 C +ATOM 376 O ASP A 48 14.246 37.621 -8.309 1.00 23.04 O +ATOM 377 CB ASP A 48 13.023 35.735 -6.640 1.00 18.02 C +ATOM 378 CG ASP A 48 14.367 35.174 -6.168 1.00 17.88 C +ATOM 379 OD1 ASP A 48 15.104 34.602 -6.991 1.00 18.55 O +ATOM 380 OD2 ASP A 48 14.750 35.442 -5.013 1.00 22.86 O +ATOM 381 N GLY A 49 14.650 36.018 -9.862 1.00 17.62 N +ATOM 382 CA GLY A 49 15.744 36.702 -10.546 1.00 17.27 C +ATOM 383 C GLY A 49 17.147 36.315 -10.096 1.00 16.80 C +ATOM 384 O GLY A 49 18.168 36.688 -10.694 1.00 20.27 O +ATOM 385 N SER A 50 17.173 35.661 -8.930 1.00 19.61 N +ATOM 386 CA SER A 50 18.435 35.225 -8.279 1.00 14.28 C +ATOM 387 C SER A 50 18.977 33.963 -8.941 1.00 18.09 C +ATOM 388 O SER A 50 18.273 33.255 -9.697 1.00 16.76 O +ATOM 389 CB SER A 50 18.272 35.089 -6.781 1.00 17.64 C +ATOM 390 OG SER A 50 17.530 33.930 -6.463 1.00 17.54 O +ATOM 391 N THR A 51 20.271 33.766 -8.734 1.00 16.00 N +ATOM 392 CA THR A 51 20.970 32.557 -9.202 1.00 13.82 C +ATOM 393 C THR A 51 21.718 31.969 -8.000 1.00 14.58 C +ATOM 394 O THR A 51 22.160 32.712 -7.119 1.00 13.28 O +ATOM 395 CB THR A 51 21.904 32.908 -10.419 1.00 12.66 C +ATOM 396 OG1 THR A 51 21.099 33.576 -11.407 1.00 17.65 O +ATOM 397 CG2 THR A 51 22.686 31.699 -10.952 1.00 14.39 C +ATOM 398 N ASP A 52 21.708 30.650 -7.927 1.00 14.66 N +ATOM 399 CA ASP A 52 22.528 29.900 -6.959 1.00 13.43 C +ATOM 400 C ASP A 52 23.843 29.488 -7.635 1.00 12.35 C +ATOM 401 O ASP A 52 23.847 29.066 -8.805 1.00 15.18 O +ATOM 402 CB ASP A 52 21.765 28.649 -6.554 1.00 14.12 C +ATOM 403 CG ASP A 52 20.396 28.991 -6.002 1.00 20.03 C +ATOM 404 OD1 ASP A 52 20.220 29.928 -5.237 1.00 21.30 O +ATOM 405 OD2 ASP A 52 19.517 28.144 -6.222 1.00 20.92 O +ATOM 406 N TYR A 53 24.924 29.734 -6.905 1.00 14.56 N +ATOM 407 CA TYR A 53 26.278 29.604 -7.450 1.00 13.61 C +ATOM 408 C TYR A 53 27.161 28.595 -6.708 1.00 12.70 C +ATOM 409 O TYR A 53 27.289 28.606 -5.486 1.00 13.36 O +ATOM 410 CB TYR A 53 26.993 30.972 -7.489 1.00 12.10 C +ATOM 411 CG TYR A 53 26.437 31.959 -8.487 1.00 11.48 C +ATOM 412 CD1 TYR A 53 26.843 32.003 -9.821 1.00 17.21 C +ATOM 413 CD2 TYR A 53 25.510 32.907 -8.050 1.00 14.42 C +ATOM 414 CE1 TYR A 53 26.291 32.922 -10.717 1.00 17.40 C +ATOM 415 CE2 TYR A 53 24.907 33.803 -8.932 1.00 12.97 C +ATOM 416 CZ TYR A 53 25.357 33.847 -10.252 1.00 15.91 C +ATOM 417 OH TYR A 53 24.864 34.804 -11.094 1.00 19.31 O +ATOM 418 N GLY A 54 27.751 27.721 -7.493 1.00 16.54 N +ATOM 419 CA GLY A 54 28.845 26.832 -7.121 1.00 15.67 C +ATOM 420 C GLY A 54 28.499 25.601 -6.290 1.00 10.78 C +ATOM 421 O GLY A 54 27.339 25.155 -6.255 1.00 13.16 O +ATOM 422 N ILE A 55 29.560 25.088 -5.684 1.00 15.43 N +ATOM 423 CA ILE A 55 29.452 23.795 -4.994 1.00 14.01 C +ATOM 424 C ILE A 55 28.424 23.748 -3.872 1.00 12.26 C +ATOM 425 O ILE A 55 27.770 22.697 -3.693 1.00 16.92 O +ATOM 426 CB ILE A 55 30.891 23.340 -4.563 1.00 16.64 C +ATOM 427 CG1 ILE A 55 30.785 21.812 -4.319 1.00 17.00 C +ATOM 428 CG2 ILE A 55 31.396 24.210 -3.390 1.00 18.87 C +ATOM 429 CD1 ILE A 55 32.101 21.018 -4.339 1.00 20.60 C +ATOM 430 N LEU A 56 28.216 24.881 -3.236 1.00 12.85 N +ATOM 431 CA LEU A 56 27.173 24.998 -2.203 1.00 14.96 C +ATOM 432 C LEU A 56 25.981 25.838 -2.659 1.00 11.08 C +ATOM 433 O LEU A 56 25.161 26.111 -1.774 1.00 16.40 O +ATOM 434 CB LEU A 56 27.816 25.424 -0.877 1.00 14.44 C +ATOM 435 CG LEU A 56 28.692 24.348 -0.204 1.00 14.92 C +ATOM 436 CD1 LEU A 56 29.331 24.997 1.008 1.00 18.78 C +ATOM 437 CD2 LEU A 56 27.808 23.177 0.192 1.00 19.47 C +ATOM 438 N GLN A 57 25.865 26.104 -3.946 1.00 14.17 N +ATOM 439 CA GLN A 57 24.668 26.785 -4.465 1.00 11.55 C +ATOM 440 C GLN A 57 24.277 27.940 -3.558 1.00 15.09 C +ATOM 441 O GLN A 57 23.116 28.031 -3.094 1.00 15.28 O +ATOM 442 CB GLN A 57 23.521 25.765 -4.549 1.00 13.56 C +ATOM 443 CG GLN A 57 23.733 24.790 -5.699 1.00 12.45 C +ATOM 444 CD GLN A 57 23.684 25.440 -7.069 1.00 14.21 C +ATOM 445 OE1 GLN A 57 22.574 25.602 -7.591 1.00 18.18 O +ATOM 446 NE2 GLN A 57 24.813 25.805 -7.651 1.00 14.86 N +ATOM 447 N ILE A 58 25.164 28.910 -3.428 1.00 14.04 N +ATOM 448 CA ILE A 58 24.930 30.118 -2.649 1.00 16.09 C +ATOM 449 C ILE A 58 24.204 31.163 -3.504 1.00 11.19 C +ATOM 450 O ILE A 58 24.555 31.405 -4.667 1.00 14.34 O +ATOM 451 CB ILE A 58 26.301 30.665 -2.134 1.00 14.90 C +ATOM 452 CG1 ILE A 58 26.751 29.724 -0.985 1.00 13.85 C +ATOM 453 CG2 ILE A 58 26.178 32.135 -1.693 1.00 15.47 C +ATOM 454 CD1 ILE A 58 28.246 29.954 -0.641 1.00 16.12 C +ATOM 455 N ASN A 59 23.145 31.671 -2.905 1.00 14.23 N +ATOM 456 CA ASN A 59 22.146 32.510 -3.590 1.00 10.60 C +ATOM 457 C ASN A 59 22.550 33.974 -3.730 1.00 13.03 C +ATOM 458 O ASN A 59 22.917 34.607 -2.740 1.00 18.49 O +ATOM 459 CB ASN A 59 20.805 32.306 -2.884 1.00 15.76 C +ATOM 460 CG ASN A 59 19.650 32.986 -3.588 1.00 15.71 C +ATOM 461 OD1 ASN A 59 19.464 34.171 -3.244 1.00 18.79 O +ATOM 462 ND2 ASN A 59 19.155 32.320 -4.612 1.00 16.44 N +ATOM 463 N SER A 60 22.268 34.485 -4.941 1.00 11.71 N +ATOM 464 CA SER A 60 22.570 35.910 -5.255 1.00 13.81 C +ATOM 465 C SER A 60 21.687 36.993 -4.642 1.00 15.28 C +ATOM 466 O SER A 60 22.054 38.177 -4.774 1.00 17.67 O +ATOM 467 CB SER A 60 22.643 36.139 -6.750 1.00 14.62 C +ATOM 468 OG SER A 60 21.432 36.007 -7.444 1.00 14.30 O +ATOM 469 N ARG A 61 20.526 36.660 -4.138 1.00 15.88 N +ATOM 470 CA ARG A 61 19.691 37.653 -3.434 1.00 18.54 C +ATOM 471 C ARG A 61 20.277 38.108 -2.106 1.00 19.97 C +ATOM 472 O ARG A 61 20.282 39.333 -1.876 1.00 26.30 O +ATOM 473 CB ARG A 61 18.267 37.195 -3.250 1.00 18.00 C +ATOM 474 CG ARG A 61 17.315 38.350 -2.959 1.00 20.10 C +ATOM 475 CD ARG A 61 16.063 37.657 -2.503 1.00 26.00 C +ATOM 476 NE ARG A 61 15.101 38.653 -2.063 1.00 29.28 N +ATOM 477 CZ ARG A 61 13.794 38.351 -2.111 1.00 29.36 C +ATOM 478 NH1 ARG A 61 13.439 37.257 -2.784 1.00 26.50 N +ATOM 479 NH2 ARG A 61 12.925 39.249 -1.646 1.00 32.93 N +ATOM 480 N TRP A 62 20.773 37.202 -1.273 1.00 16.51 N +ATOM 481 CA TRP A 62 21.321 37.563 0.032 1.00 16.06 C +ATOM 482 C TRP A 62 22.848 37.643 0.101 1.00 15.55 C +ATOM 483 O TRP A 62 23.323 38.396 0.968 1.00 18.96 O +ATOM 484 CB TRP A 62 20.833 36.611 1.134 1.00 17.91 C +ATOM 485 CG TRP A 62 19.360 36.361 1.096 1.00 18.99 C +ATOM 486 CD1 TRP A 62 18.719 35.247 0.643 1.00 20.47 C +ATOM 487 CD2 TRP A 62 18.326 37.305 1.427 1.00 20.79 C +ATOM 488 NE1 TRP A 62 17.360 35.457 0.609 1.00 21.70 N +ATOM 489 CE2 TRP A 62 17.090 36.696 1.096 1.00 21.11 C +ATOM 490 CE3 TRP A 62 18.333 38.584 1.965 1.00 19.84 C +ATOM 491 CZ2 TRP A 62 15.875 37.327 1.307 1.00 22.57 C +ATOM 492 CZ3 TRP A 62 17.115 39.208 2.186 1.00 23.93 C +ATOM 493 CH2 TRP A 62 15.906 38.611 1.814 1.00 19.55 C +ATOM 494 N TRP A 63 23.537 36.731 -0.584 1.00 16.01 N +ATOM 495 CA TRP A 63 24.906 36.398 -0.276 1.00 15.21 C +ATOM 496 C TRP A 63 26.089 36.924 -1.052 1.00 15.84 C +ATOM 497 O TRP A 63 27.142 37.177 -0.432 1.00 19.13 O +ATOM 498 CB TRP A 63 25.068 34.919 0.112 1.00 15.47 C +ATOM 499 CG TRP A 63 24.036 34.428 1.068 1.00 12.46 C +ATOM 500 CD1 TRP A 63 22.959 33.620 0.777 1.00 16.95 C +ATOM 501 CD2 TRP A 63 23.919 34.728 2.450 1.00 13.27 C +ATOM 502 NE1 TRP A 63 22.243 33.344 1.899 1.00 17.64 N +ATOM 503 CE2 TRP A 63 22.761 34.067 2.931 1.00 17.28 C +ATOM 504 CE3 TRP A 63 24.694 35.480 3.323 1.00 15.25 C +ATOM 505 CZ2 TRP A 63 22.393 34.133 4.278 1.00 18.56 C +ATOM 506 CZ3 TRP A 63 24.302 35.586 4.648 1.00 18.76 C +ATOM 507 CH2 TRP A 63 23.179 34.910 5.117 1.00 19.36 C +ATOM 508 N CYS A 64 25.962 36.914 -2.353 1.00 17.00 N +ATOM 509 CA CYS A 64 26.985 37.433 -3.271 1.00 15.76 C +ATOM 510 C CYS A 64 26.324 38.355 -4.286 1.00 15.97 C +ATOM 511 O CYS A 64 25.102 38.314 -4.475 1.00 13.75 O +ATOM 512 CB CYS A 64 27.638 36.265 -3.988 1.00 16.64 C +ATOM 513 SG CYS A 64 26.562 35.233 -5.007 1.00 17.83 S +ATOM 514 N ASN A 65 27.157 39.165 -4.908 1.00 17.73 N +ATOM 515 CA ASN A 65 26.700 40.134 -5.920 1.00 16.46 C +ATOM 516 C ASN A 65 26.985 39.646 -7.342 1.00 13.16 C +ATOM 517 O ASN A 65 28.130 39.316 -7.647 1.00 15.95 O +ATOM 518 CB ASN A 65 27.381 41.492 -5.712 1.00 19.19 C +ATOM 519 CG ASN A 65 26.910 42.423 -6.824 1.00 19.59 C +ATOM 520 OD1 ASN A 65 25.736 42.559 -7.141 1.00 23.26 O +ATOM 521 ND2 ASN A 65 27.914 42.938 -7.527 1.00 25.56 N +ATOM 522 N ASP A 66 25.920 39.484 -8.116 1.00 15.60 N +ATOM 523 CA ASP A 66 26.102 39.180 -9.545 1.00 15.28 C +ATOM 524 C ASP A 66 25.664 40.317 -10.460 1.00 15.23 C +ATOM 525 O ASP A 66 25.719 40.143 -11.673 1.00 17.91 O +ATOM 526 CB ASP A 66 25.462 37.858 -9.894 1.00 14.84 C +ATOM 527 CG ASP A 66 23.951 37.903 -9.833 1.00 12.12 C +ATOM 528 OD1 ASP A 66 23.288 38.898 -9.542 1.00 16.56 O +ATOM 529 OD2 ASP A 66 23.455 36.769 -10.048 1.00 16.91 O +ATOM 530 N GLY A 67 25.234 41.408 -9.860 1.00 18.13 N +ATOM 531 CA GLY A 67 24.817 42.607 -10.577 1.00 19.40 C +ATOM 532 C GLY A 67 23.544 42.553 -11.401 1.00 20.37 C +ATOM 533 O GLY A 67 23.191 43.542 -12.055 1.00 18.23 O +ATOM 534 N ARG A 68 22.822 41.441 -11.348 1.00 18.79 N +ATOM 535 CA ARG A 68 21.560 41.308 -12.092 1.00 19.77 C +ATOM 536 C ARG A 68 20.424 40.765 -11.243 1.00 18.48 C +ATOM 537 O ARG A 68 19.385 40.383 -11.795 1.00 21.54 O +ATOM 538 CB ARG A 68 21.746 40.454 -13.339 1.00 18.97 C +ATOM 539 CG ARG A 68 22.197 39.048 -12.946 1.00 18.77 C +ATOM 540 CD ARG A 68 22.477 38.187 -14.122 1.00 23.25 C +ATOM 541 NE ARG A 68 21.439 37.201 -14.281 1.00 29.75 N +ATOM 542 CZ ARG A 68 20.242 37.255 -14.855 1.00 28.71 C +ATOM 543 NH1 ARG A 68 19.503 38.311 -15.145 1.00 32.34 N +ATOM 544 NH2 ARG A 68 19.897 36.127 -15.497 1.00 33.10 N +ATOM 545 N THR A 69 20.590 40.896 -9.952 1.00 18.68 N +ATOM 546 CA THR A 69 19.607 40.408 -8.973 1.00 20.02 C +ATOM 547 C THR A 69 18.994 41.597 -8.224 1.00 16.46 C +ATOM 548 O THR A 69 19.683 42.241 -7.425 1.00 23.13 O +ATOM 549 CB THR A 69 20.208 39.384 -7.910 1.00 19.66 C +ATOM 550 OG1 THR A 69 20.851 38.334 -8.715 1.00 19.19 O +ATOM 551 CG2 THR A 69 19.123 38.863 -6.955 1.00 18.58 C +ATOM 552 N PRO A 70 17.687 41.741 -8.418 1.00 20.50 N +ATOM 553 CA PRO A 70 16.953 42.824 -7.733 1.00 21.73 C +ATOM 554 C PRO A 70 16.955 42.520 -6.242 1.00 22.11 C +ATOM 555 O PRO A 70 16.739 41.356 -5.886 1.00 27.13 O +ATOM 556 CB PRO A 70 15.557 42.749 -8.333 1.00 23.50 C +ATOM 557 CG PRO A 70 15.759 42.092 -9.671 1.00 24.66 C +ATOM 558 CD PRO A 70 16.887 41.095 -9.463 1.00 21.80 C +ATOM 559 N GLY A 71 17.163 43.493 -5.401 1.00 21.67 N +ATOM 560 CA GLY A 71 17.135 43.383 -3.947 1.00 24.03 C +ATOM 561 C GLY A 71 18.328 42.710 -3.287 1.00 26.98 C +ATOM 562 O GLY A 71 18.257 42.257 -2.126 1.00 32.77 O +ATOM 563 N SER A 72 19.418 42.627 -4.018 1.00 26.40 N +ATOM 564 CA SER A 72 20.665 41.976 -3.588 1.00 26.94 C +ATOM 565 C SER A 72 21.139 42.582 -2.276 1.00 24.66 C +ATOM 566 O SER A 72 21.055 43.819 -2.125 1.00 29.91 O +ATOM 567 CB SER A 72 21.659 42.002 -4.737 1.00 25.16 C +ATOM 568 OG SER A 72 23.015 41.835 -4.343 1.00 32.21 O +ATOM 569 N ARG A 73 21.646 41.775 -1.369 1.00 22.51 N +ATOM 570 CA ARG A 73 22.254 42.196 -0.113 1.00 22.60 C +ATOM 571 C ARG A 73 23.774 42.058 0.029 1.00 22.33 C +ATOM 572 O ARG A 73 24.425 42.749 0.849 1.00 27.92 O +ATOM 573 CB ARG A 73 21.615 41.555 1.127 1.00 20.14 C +ATOM 574 CG ARG A 73 20.187 41.983 1.439 1.00 22.29 C +ATOM 575 CD ARG A 73 20.209 43.299 2.123 1.00 26.95 C +ATOM 576 NE ARG A 73 18.928 43.771 2.617 1.00 33.74 N +ATOM 577 CZ ARG A 73 17.980 44.302 1.823 1.00 33.76 C +ATOM 578 NH1 ARG A 73 17.841 43.934 0.544 1.00 35.78 N +ATOM 579 NH2 ARG A 73 17.571 45.545 2.146 1.00 33.83 N +ATOM 580 N ASN A 74 24.346 41.143 -0.705 1.00 17.74 N +ATOM 581 CA ASN A 74 25.780 40.833 -0.695 1.00 18.87 C +ATOM 582 C ASN A 74 26.315 40.718 0.731 1.00 16.22 C +ATOM 583 O ASN A 74 27.255 41.471 1.060 1.00 20.87 O +ATOM 584 CB ASN A 74 26.565 41.786 -1.589 1.00 19.51 C +ATOM 585 CG ASN A 74 27.982 41.328 -1.909 1.00 16.31 C +ATOM 586 OD1 ASN A 74 28.318 40.169 -1.652 1.00 18.61 O +ATOM 587 ND2 ASN A 74 28.838 42.192 -2.436 1.00 19.22 N +ATOM 588 N LEU A 75 25.723 39.860 1.544 1.00 15.25 N +ATOM 589 CA LEU A 75 26.153 39.690 2.930 1.00 14.82 C +ATOM 590 C LEU A 75 27.518 39.011 3.085 1.00 16.78 C +ATOM 591 O LEU A 75 28.167 39.197 4.141 1.00 22.00 O +ATOM 592 CB LEU A 75 25.009 39.055 3.733 1.00 16.64 C +ATOM 593 CG LEU A 75 23.815 39.998 3.979 1.00 17.08 C +ATOM 594 CD1 LEU A 75 22.574 39.193 4.336 1.00 25.82 C +ATOM 595 CD2 LEU A 75 24.156 40.969 5.110 1.00 20.95 C +ATOM 596 N CYS A 76 27.973 38.312 2.061 1.00 17.66 N +ATOM 597 CA CYS A 76 29.299 37.680 2.111 1.00 16.46 C +ATOM 598 C CYS A 76 30.390 38.598 1.589 1.00 15.66 C +ATOM 599 O CYS A 76 31.573 38.229 1.568 1.00 17.59 O +ATOM 600 CB CYS A 76 29.396 36.303 1.477 1.00 17.61 C +ATOM 601 SG CYS A 76 28.595 34.961 2.361 1.00 18.07 S +ATOM 602 N ASN A 77 29.964 39.681 0.971 1.00 18.55 N +ATOM 603 CA ASN A 77 30.827 40.725 0.395 1.00 19.18 C +ATOM 604 C ASN A 77 31.711 40.163 -0.702 1.00 16.58 C +ATOM 605 O ASN A 77 32.947 40.331 -0.689 1.00 21.61 O +ATOM 606 CB ASN A 77 31.589 41.488 1.483 1.00 17.72 C +ATOM 607 CG ASN A 77 32.126 42.812 0.957 1.00 20.20 C +ATOM 608 OD1 ASN A 77 31.351 43.589 0.396 1.00 28.77 O +ATOM 609 ND2 ASN A 77 33.430 43.012 1.047 1.00 27.05 N +ATOM 610 N ILE A 78 31.149 39.408 -1.616 1.00 18.88 N +ATOM 611 CA ILE A 78 31.904 38.780 -2.713 1.00 20.14 C +ATOM 612 C ILE A 78 31.099 38.850 -4.013 1.00 17.08 C +ATOM 613 O ILE A 78 29.864 38.688 -3.972 1.00 16.28 O +ATOM 614 CB ILE A 78 32.183 37.255 -2.384 1.00 19.93 C +ATOM 615 CG1 ILE A 78 30.882 36.639 -1.851 1.00 21.17 C +ATOM 616 CG2 ILE A 78 33.437 37.003 -1.524 1.00 24.25 C +ATOM 617 CD1 ILE A 78 30.936 35.120 -1.546 1.00 25.54 C +ATOM 618 N PRO A 79 31.828 38.795 -5.108 1.00 16.64 N +ATOM 619 CA PRO A 79 31.195 38.634 -6.421 1.00 19.12 C +ATOM 620 C PRO A 79 30.792 37.146 -6.446 1.00 14.71 C +ATOM 621 O PRO A 79 31.576 36.273 -6.005 1.00 17.48 O +ATOM 622 CB PRO A 79 32.261 38.967 -7.445 1.00 18.74 C +ATOM 623 CG PRO A 79 33.555 39.029 -6.710 1.00 18.97 C +ATOM 624 CD PRO A 79 33.276 39.023 -5.215 1.00 16.79 C +ATOM 625 N CYS A 80 29.629 36.908 -7.033 1.00 13.55 N +ATOM 626 CA CYS A 80 29.167 35.522 -7.236 1.00 14.33 C +ATOM 627 C CYS A 80 30.150 34.716 -8.073 1.00 13.92 C +ATOM 628 O CYS A 80 30.214 33.484 -7.880 1.00 16.74 O +ATOM 629 CB CYS A 80 27.749 35.338 -7.747 1.00 16.10 C +ATOM 630 SG CYS A 80 26.471 36.160 -6.762 1.00 16.97 S +ATOM 631 N SER A 81 30.769 35.294 -9.083 1.00 15.04 N +ATOM 632 CA SER A 81 31.775 34.671 -9.933 1.00 15.64 C +ATOM 633 C SER A 81 32.907 34.027 -9.109 1.00 14.90 C +ATOM 634 O SER A 81 33.338 32.939 -9.561 1.00 21.08 O +ATOM 635 CB SER A 81 32.381 35.643 -10.953 1.00 18.65 C +ATOM 636 OG SER A 81 33.035 36.681 -10.235 1.00 20.86 O +ATOM 637 N ALA A 82 33.226 34.572 -7.950 1.00 15.59 N +ATOM 638 CA ALA A 82 34.272 33.963 -7.107 1.00 18.01 C +ATOM 639 C ALA A 82 33.869 32.604 -6.540 1.00 18.75 C +ATOM 640 O ALA A 82 34.703 31.798 -6.081 1.00 19.60 O +ATOM 641 CB ALA A 82 34.722 34.930 -6.020 1.00 20.54 C +ATOM 642 N LEU A 83 32.571 32.338 -6.519 1.00 15.36 N +ATOM 643 CA LEU A 83 31.973 31.093 -6.042 1.00 18.66 C +ATOM 644 C LEU A 83 32.060 29.962 -7.049 1.00 17.84 C +ATOM 645 O LEU A 83 31.671 28.815 -6.739 1.00 21.50 O +ATOM 646 CB LEU A 83 30.618 31.424 -5.431 1.00 17.11 C +ATOM 647 CG LEU A 83 30.511 32.364 -4.244 1.00 16.65 C +ATOM 648 CD1 LEU A 83 29.040 32.573 -3.857 1.00 18.78 C +ATOM 649 CD2 LEU A 83 31.277 31.872 -3.020 1.00 20.62 C +ATOM 650 N LEU A 84 32.473 30.271 -8.267 1.00 17.31 N +ATOM 651 CA LEU A 84 32.610 29.295 -9.347 1.00 16.38 C +ATOM 652 C LEU A 84 34.047 28.841 -9.570 1.00 19.37 C +ATOM 653 O LEU A 84 34.334 28.243 -10.622 1.00 23.48 O +ATOM 654 CB LEU A 84 31.914 29.793 -10.614 1.00 20.87 C +ATOM 655 CG LEU A 84 30.446 30.183 -10.573 1.00 14.26 C +ATOM 656 CD1 LEU A 84 30.014 30.771 -11.916 1.00 21.15 C +ATOM 657 CD2 LEU A 84 29.597 28.942 -10.329 1.00 18.96 C +ATOM 658 N SER A 85 34.942 29.197 -8.676 1.00 21.00 N +ATOM 659 CA SER A 85 36.340 28.754 -8.727 1.00 20.86 C +ATOM 660 C SER A 85 36.474 27.245 -8.497 1.00 19.65 C +ATOM 661 O SER A 85 35.765 26.640 -7.681 1.00 20.62 O +ATOM 662 CB SER A 85 37.109 29.482 -7.633 1.00 20.91 C +ATOM 663 OG SER A 85 38.484 29.212 -7.834 1.00 26.88 O +ATOM 664 N SER A 86 37.619 26.742 -8.943 1.00 22.57 N +ATOM 665 CA SER A 86 38.008 25.343 -8.700 1.00 20.44 C +ATOM 666 C SER A 86 38.388 25.153 -7.233 1.00 19.98 C +ATOM 667 O SER A 86 38.314 24.055 -6.671 1.00 23.62 O +ATOM 668 CB SER A 86 39.107 24.868 -9.650 1.00 23.76 C +ATOM 669 OG SER A 86 38.401 24.215 -10.691 1.00 30.29 O +ATOM 670 N ASP A 87 38.846 26.244 -6.668 1.00 19.74 N +ATOM 671 CA ASP A 87 39.282 26.393 -5.271 1.00 18.72 C +ATOM 672 C ASP A 87 37.999 26.657 -4.471 1.00 17.93 C +ATOM 673 O ASP A 87 37.490 27.762 -4.712 1.00 20.06 O +ATOM 674 CB ASP A 87 40.221 27.607 -5.212 1.00 21.65 C +ATOM 675 CG ASP A 87 40.762 28.041 -3.869 1.00 23.98 C +ATOM 676 OD1 ASP A 87 40.335 27.702 -2.742 1.00 26.26 O +ATOM 677 OD2 ASP A 87 41.785 28.802 -3.933 1.00 32.04 O +ATOM 678 N ILE A 88 37.732 25.850 -3.461 1.00 15.96 N +ATOM 679 CA ILE A 88 36.515 26.089 -2.658 1.00 16.22 C +ATOM 680 C ILE A 88 36.582 27.142 -1.563 1.00 14.43 C +ATOM 681 O ILE A 88 35.600 27.315 -0.801 1.00 16.28 O +ATOM 682 CB ILE A 88 35.993 24.736 -2.046 1.00 16.45 C +ATOM 683 CG1 ILE A 88 36.920 24.200 -0.934 1.00 15.71 C +ATOM 684 CG2 ILE A 88 35.587 23.743 -3.163 1.00 19.87 C +ATOM 685 CD1 ILE A 88 36.363 23.226 0.137 1.00 17.47 C +ATOM 686 N THR A 89 37.742 27.786 -1.369 1.00 14.21 N +ATOM 687 CA THR A 89 37.913 28.772 -0.306 1.00 16.87 C +ATOM 688 C THR A 89 36.736 29.761 -0.161 1.00 11.06 C +ATOM 689 O THR A 89 36.341 29.983 1.000 1.00 13.83 O +ATOM 690 CB THR A 89 39.267 29.591 -0.423 1.00 18.61 C +ATOM 691 OG1 THR A 89 40.339 28.592 -0.514 1.00 20.24 O +ATOM 692 CG2 THR A 89 39.419 30.553 0.766 1.00 17.79 C +ATOM 693 N ALA A 90 36.507 30.482 -1.242 1.00 17.37 N +ATOM 694 CA ALA A 90 35.479 31.555 -1.244 1.00 16.63 C +ATOM 695 C ALA A 90 34.125 31.066 -0.735 1.00 14.09 C +ATOM 696 O ALA A 90 33.366 31.671 0.065 1.00 15.68 O +ATOM 697 CB ALA A 90 35.366 32.212 -2.617 1.00 17.13 C +ATOM 698 N SER A 91 33.746 29.919 -1.296 1.00 13.62 N +ATOM 699 CA SER A 91 32.494 29.220 -1.024 1.00 11.35 C +ATOM 700 C SER A 91 32.429 28.817 0.467 1.00 11.70 C +ATOM 701 O SER A 91 31.407 29.057 1.110 1.00 14.31 O +ATOM 702 CB SER A 91 32.282 28.035 -1.917 1.00 13.48 C +ATOM 703 OG SER A 91 32.020 28.335 -3.260 1.00 14.66 O +ATOM 704 N VAL A 92 33.502 28.211 0.953 1.00 13.17 N +ATOM 705 CA VAL A 92 33.595 27.846 2.381 1.00 13.44 C +ATOM 706 C VAL A 92 33.477 29.105 3.261 1.00 12.00 C +ATOM 707 O VAL A 92 32.716 29.020 4.244 1.00 13.83 O +ATOM 708 CB VAL A 92 34.890 27.038 2.650 1.00 11.69 C +ATOM 709 CG1 VAL A 92 35.125 26.987 4.151 1.00 16.05 C +ATOM 710 CG2 VAL A 92 34.776 25.672 2.013 1.00 15.64 C +ATOM 711 N ASN A 93 34.199 30.163 2.912 1.00 15.12 N +ATOM 712 CA ASN A 93 34.160 31.413 3.685 1.00 15.10 C +ATOM 713 C ASN A 93 32.747 32.034 3.803 1.00 9.80 C +ATOM 714 O ASN A 93 32.361 32.393 4.908 1.00 16.51 O +ATOM 715 CB ASN A 93 35.168 32.472 3.247 1.00 16.33 C +ATOM 716 CG ASN A 93 36.582 32.083 3.642 1.00 19.02 C +ATOM 717 OD1 ASN A 93 37.546 32.671 3.120 1.00 29.57 O +ATOM 718 ND2 ASN A 93 36.710 31.188 4.631 1.00 24.29 N +ATOM 719 N CYS A 94 32.096 31.996 2.670 1.00 15.72 N +ATOM 720 CA CYS A 94 30.695 32.449 2.633 1.00 13.58 C +ATOM 721 C CYS A 94 29.778 31.527 3.424 1.00 13.05 C +ATOM 722 O CYS A 94 28.973 32.025 4.236 1.00 16.42 O +ATOM 723 CB CYS A 94 30.291 32.704 1.185 1.00 12.05 C +ATOM 724 SG CYS A 94 28.644 33.431 1.046 1.00 15.81 S +ATOM 725 N ALA A 95 29.945 30.225 3.263 1.00 13.56 N +ATOM 726 CA ALA A 95 29.134 29.227 3.969 1.00 15.63 C +ATOM 727 C ALA A 95 29.236 29.330 5.491 1.00 10.80 C +ATOM 728 O ALA A 95 28.222 29.180 6.179 1.00 12.93 O +ATOM 729 CB ALA A 95 29.495 27.794 3.612 1.00 14.09 C +ATOM 730 N LYS A 96 30.424 29.628 5.987 1.00 11.19 N +ATOM 731 CA LYS A 96 30.627 29.912 7.419 1.00 13.27 C +ATOM 732 C LYS A 96 29.802 31.115 7.906 1.00 13.38 C +ATOM 733 O LYS A 96 29.296 31.011 9.027 1.00 15.75 O +ATOM 734 CB LYS A 96 32.100 30.112 7.775 1.00 12.67 C +ATOM 735 CG LYS A 96 32.874 28.792 7.697 1.00 11.93 C +ATOM 736 CD LYS A 96 34.358 29.071 7.879 1.00 15.55 C +ATOM 737 CE LYS A 96 35.205 27.816 7.938 1.00 18.03 C +ATOM 738 NZ LYS A 96 36.610 28.242 8.169 1.00 20.72 N +ATOM 739 N LYS A 97 29.660 32.101 7.049 1.00 12.90 N +ATOM 740 CA LYS A 97 28.811 33.263 7.379 1.00 16.43 C +ATOM 741 C LYS A 97 27.333 32.905 7.386 1.00 18.88 C +ATOM 742 O LYS A 97 26.570 33.318 8.272 1.00 19.20 O +ATOM 743 CB LYS A 97 29.087 34.456 6.470 1.00 18.97 C +ATOM 744 CG LYS A 97 30.537 34.927 6.563 1.00 19.81 C +ATOM 745 CD LYS A 97 30.841 36.073 5.610 1.00 22.00 C +ATOM 746 CE LYS A 97 32.340 36.293 5.510 1.00 23.71 C +ATOM 747 NZ LYS A 97 32.569 37.524 4.708 1.00 29.75 N +ATOM 748 N ILE A 98 26.897 32.127 6.416 1.00 15.72 N +ATOM 749 CA ILE A 98 25.520 31.693 6.266 1.00 16.36 C +ATOM 750 C ILE A 98 25.030 30.871 7.453 1.00 16.70 C +ATOM 751 O ILE A 98 24.059 31.254 8.126 1.00 18.80 O +ATOM 752 CB ILE A 98 25.307 30.997 4.896 1.00 15.14 C +ATOM 753 CG1 ILE A 98 25.643 31.910 3.702 1.00 13.63 C +ATOM 754 CG2 ILE A 98 23.887 30.386 4.817 1.00 15.62 C +ATOM 755 CD1 ILE A 98 25.620 31.204 2.321 1.00 17.82 C +ATOM 756 N VAL A 99 25.875 29.966 7.915 1.00 16.73 N +ATOM 757 CA VAL A 99 25.488 29.009 8.955 1.00 18.71 C +ATOM 758 C VAL A 99 25.431 29.697 10.316 1.00 20.36 C +ATOM 759 O VAL A 99 24.737 29.212 11.233 1.00 25.30 O +ATOM 760 CB VAL A 99 26.398 27.774 8.859 1.00 16.94 C +ATOM 761 CG1 VAL A 99 27.811 28.138 9.279 1.00 19.19 C +ATOM 762 CG2 VAL A 99 25.834 26.594 9.632 1.00 18.97 C +ATOM 763 N SER A 100 26.205 30.752 10.409 1.00 17.04 N +ATOM 764 CA SER A 100 26.297 31.529 11.650 1.00 23.81 C +ATOM 765 C SER A 100 25.124 32.495 11.765 1.00 24.03 C +ATOM 766 O SER A 100 24.995 33.131 12.820 1.00 28.66 O +ATOM 767 CB SER A 100 27.647 32.194 11.723 1.00 19.71 C +ATOM 768 OG SER A 100 28.714 31.264 11.818 1.00 25.04 O +ATOM 769 N ASP A 101 24.307 32.599 10.750 1.00 25.78 N +ATOM 770 CA ASP A 101 23.162 33.495 10.650 1.00 26.98 C +ATOM 771 C ASP A 101 21.924 33.183 11.481 1.00 28.34 C +ATOM 772 O ASP A 101 21.132 34.143 11.678 1.00 31.88 O +ATOM 773 CB ASP A 101 22.806 33.854 9.207 1.00 27.75 C +ATOM 774 CG ASP A 101 22.426 35.320 9.009 1.00 30.86 C +ATOM 775 OD1 ASP A 101 23.248 36.223 9.266 1.00 34.67 O +ATOM 776 OD2 ASP A 101 21.276 35.519 8.551 1.00 32.70 O +ATOM 777 N GLY A 102 21.723 31.942 11.887 1.00 28.87 N +ATOM 778 CA GLY A 102 20.622 31.656 12.823 1.00 30.67 C +ATOM 779 C GLY A 102 19.812 30.413 12.505 1.00 27.92 C +ATOM 780 O GLY A 102 19.195 29.898 13.458 1.00 30.42 O +ATOM 781 N ASN A 103 19.805 30.005 11.244 1.00 29.26 N +ATOM 782 CA ASN A 103 19.076 28.799 10.848 1.00 25.22 C +ATOM 783 C ASN A 103 19.990 27.600 10.597 1.00 22.06 C +ATOM 784 O ASN A 103 19.472 26.579 10.117 1.00 24.23 O +ATOM 785 CB ASN A 103 17.976 29.046 9.824 1.00 24.87 C +ATOM 786 CG ASN A 103 16.708 28.245 10.063 1.00 27.08 C +ATOM 787 OD1 ASN A 103 16.513 27.577 11.098 1.00 30.30 O +ATOM 788 ND2 ASN A 103 15.672 28.428 9.240 1.00 30.15 N +ATOM 789 N GLY A 104 21.240 27.711 10.997 1.00 23.20 N +ATOM 790 CA GLY A 104 22.177 26.567 10.860 1.00 19.51 C +ATOM 791 C GLY A 104 22.173 26.142 9.388 1.00 15.58 C +ATOM 792 O GLY A 104 22.151 27.040 8.541 1.00 22.50 O +ATOM 793 N MET A 105 22.185 24.847 9.115 1.00 17.51 N +ATOM 794 CA MET A 105 22.278 24.370 7.724 1.00 16.07 C +ATOM 795 C MET A 105 20.915 24.309 7.063 1.00 13.35 C +ATOM 796 O MET A 105 20.902 23.921 5.871 1.00 15.50 O +ATOM 797 CB MET A 105 23.036 23.048 7.632 1.00 19.32 C +ATOM 798 CG MET A 105 24.519 23.221 7.871 1.00 17.10 C +ATOM 799 SD MET A 105 25.379 21.660 7.491 1.00 20.27 S +ATOM 800 CE MET A 105 25.369 21.706 5.703 1.00 20.03 C +ATOM 801 N ASN A 106 19.896 24.839 7.735 1.00 14.64 N +ATOM 802 CA ASN A 106 18.557 24.898 7.103 1.00 18.58 C +ATOM 803 C ASN A 106 18.566 25.831 5.892 1.00 18.20 C +ATOM 804 O ASN A 106 17.678 25.748 5.021 1.00 22.14 O +ATOM 805 CB ASN A 106 17.420 25.150 8.084 1.00 19.18 C +ATOM 806 CG ASN A 106 17.207 23.938 8.967 1.00 19.21 C +ATOM 807 OD1 ASN A 106 16.836 22.867 8.443 1.00 24.65 O +ATOM 808 ND2 ASN A 106 17.542 24.047 10.255 1.00 25.28 N +ATOM 809 N ALA A 107 19.617 26.647 5.800 1.00 18.54 N +ATOM 810 CA ALA A 107 19.824 27.514 4.634 1.00 18.74 C +ATOM 811 C ALA A 107 20.007 26.744 3.329 1.00 16.80 C +ATOM 812 O ALA A 107 19.734 27.292 2.260 1.00 20.63 O +ATOM 813 CB ALA A 107 21.060 28.374 4.877 1.00 19.47 C +ATOM 814 N TRP A 108 20.371 25.465 3.434 1.00 16.46 N +ATOM 815 CA TRP A 108 20.532 24.624 2.241 1.00 14.68 C +ATOM 816 C TRP A 108 19.317 23.688 2.110 1.00 17.55 C +ATOM 817 O TRP A 108 19.240 22.816 2.993 1.00 20.05 O +ATOM 818 CB TRP A 108 21.840 23.826 2.338 1.00 16.18 C +ATOM 819 CG TRP A 108 23.000 24.736 2.026 1.00 15.50 C +ATOM 820 CD1 TRP A 108 23.360 25.234 0.803 1.00 15.45 C +ATOM 821 CD2 TRP A 108 23.798 25.437 2.991 1.00 15.57 C +ATOM 822 NE1 TRP A 108 24.414 26.102 0.952 1.00 17.40 N +ATOM 823 CE2 TRP A 108 24.711 26.237 2.272 1.00 15.78 C +ATOM 824 CE3 TRP A 108 23.833 25.426 4.379 1.00 12.79 C +ATOM 825 CZ2 TRP A 108 25.682 26.985 2.917 1.00 15.77 C +ATOM 826 CZ3 TRP A 108 24.773 26.200 5.033 1.00 16.28 C +ATOM 827 CH2 TRP A 108 25.691 26.960 4.298 1.00 16.65 C +ATOM 828 N VAL A 109 18.487 23.925 1.101 1.00 15.35 N +ATOM 829 CA VAL A 109 17.265 23.096 1.025 1.00 19.96 C +ATOM 830 C VAL A 109 17.573 21.611 0.884 1.00 17.16 C +ATOM 831 O VAL A 109 16.923 20.811 1.587 1.00 20.77 O +ATOM 832 CB VAL A 109 16.146 23.660 0.145 1.00 21.94 C +ATOM 833 CG1 VAL A 109 16.607 23.905 -1.285 1.00 27.84 C +ATOM 834 CG2 VAL A 109 14.901 22.783 0.136 1.00 21.22 C +ATOM 835 N ALA A 110 18.562 21.308 0.075 1.00 20.97 N +ATOM 836 CA ALA A 110 18.972 19.935 -0.237 1.00 18.78 C +ATOM 837 C ALA A 110 19.502 19.244 1.006 1.00 18.30 C +ATOM 838 O ALA A 110 19.197 18.046 1.174 1.00 18.47 O +ATOM 839 CB ALA A 110 19.857 19.777 -1.455 1.00 20.83 C +ATOM 840 N TRP A 111 20.121 19.983 1.892 1.00 16.62 N +ATOM 841 CA TRP A 111 20.551 19.500 3.202 1.00 15.74 C +ATOM 842 C TRP A 111 19.343 19.085 4.046 1.00 19.12 C +ATOM 843 O TRP A 111 19.284 17.986 4.643 1.00 16.20 O +ATOM 844 CB TRP A 111 21.486 20.451 3.925 1.00 14.63 C +ATOM 845 CG TRP A 111 21.858 19.904 5.252 1.00 14.87 C +ATOM 846 CD1 TRP A 111 22.856 18.975 5.486 1.00 18.11 C +ATOM 847 CD2 TRP A 111 21.199 20.093 6.504 1.00 16.63 C +ATOM 848 NE1 TRP A 111 22.848 18.592 6.808 1.00 17.16 N +ATOM 849 CE2 TRP A 111 21.798 19.221 7.435 1.00 16.77 C +ATOM 850 CE3 TRP A 111 20.182 20.959 6.908 1.00 15.16 C +ATOM 851 CZ2 TRP A 111 21.492 19.284 8.784 1.00 17.69 C +ATOM 852 CZ3 TRP A 111 19.818 20.954 8.240 1.00 16.88 C +ATOM 853 CH2 TRP A 111 20.443 20.110 9.162 1.00 19.73 C +ATOM 854 N ARG A 112 18.438 20.038 4.228 1.00 17.47 N +ATOM 855 CA ARG A 112 17.185 19.830 4.955 1.00 19.60 C +ATOM 856 C ARG A 112 16.472 18.593 4.391 1.00 17.68 C +ATOM 857 O ARG A 112 16.000 17.792 5.220 1.00 22.77 O +ATOM 858 CB ARG A 112 16.214 20.990 4.944 1.00 17.57 C +ATOM 859 CG ARG A 112 16.592 22.438 5.091 1.00 25.27 C +ATOM 860 CD ARG A 112 15.368 23.296 5.135 1.00 21.23 C +ATOM 861 NE ARG A 112 14.776 23.555 3.836 1.00 28.06 N +ATOM 862 CZ ARG A 112 14.785 24.695 3.143 1.00 27.89 C +ATOM 863 NH1 ARG A 112 15.596 25.721 3.383 1.00 30.12 N +ATOM 864 NH2 ARG A 112 13.717 25.008 2.398 1.00 30.39 N +ATOM 865 N ASN A 113 16.307 18.521 3.074 1.00 19.43 N +ATOM 866 CA ASN A 113 15.464 17.463 2.491 1.00 20.16 C +ATOM 867 C ASN A 113 16.111 16.083 2.586 1.00 21.26 C +ATOM 868 O ASN A 113 15.454 15.054 2.808 1.00 24.90 O +ATOM 869 CB ASN A 113 14.966 17.779 1.085 1.00 20.43 C +ATOM 870 CG ASN A 113 14.003 18.961 1.018 1.00 16.63 C +ATOM 871 OD1 ASN A 113 13.454 19.344 2.059 1.00 25.68 O +ATOM 872 ND2 ASN A 113 13.840 19.555 -0.159 1.00 22.00 N +ATOM 873 N ARG A 114 17.401 16.041 2.355 1.00 19.72 N +ATOM 874 CA ARG A 114 18.156 14.836 2.042 1.00 21.43 C +ATOM 875 C ARG A 114 19.258 14.440 2.991 1.00 22.71 C +ATOM 876 O ARG A 114 19.505 13.217 3.097 1.00 24.85 O +ATOM 877 CB ARG A 114 18.622 14.910 0.576 1.00 21.05 C +ATOM 878 CG ARG A 114 17.395 14.614 -0.300 1.00 26.59 C +ATOM 879 CD ARG A 114 17.729 14.399 -1.731 1.00 26.92 C +ATOM 880 NE ARG A 114 18.153 15.677 -2.301 1.00 33.46 N +ATOM 881 CZ ARG A 114 17.826 16.080 -3.535 1.00 32.00 C +ATOM 882 NH1 ARG A 114 17.378 15.225 -4.456 1.00 36.02 N +ATOM 883 NH2 ARG A 114 17.735 17.388 -3.796 1.00 36.05 N +ATOM 884 N CYS A 115 19.743 15.372 3.773 1.00 17.56 N +ATOM 885 CA CYS A 115 20.843 15.041 4.708 1.00 15.08 C +ATOM 886 C CYS A 115 20.448 14.933 6.159 1.00 16.64 C +ATOM 887 O CYS A 115 20.972 14.116 6.940 1.00 21.71 O +ATOM 888 CB CYS A 115 21.991 16.018 4.426 1.00 15.21 C +ATOM 889 SG CYS A 115 22.563 16.009 2.739 1.00 19.35 S +ATOM 890 N LYS A 116 19.714 15.918 6.619 1.00 18.76 N +ATOM 891 CA LYS A 116 19.332 16.085 8.025 1.00 19.14 C +ATOM 892 C LYS A 116 18.634 14.821 8.518 1.00 21.91 C +ATOM 893 O LYS A 116 17.819 14.234 7.785 1.00 24.78 O +ATOM 894 CB LYS A 116 18.492 17.363 8.126 1.00 21.01 C +ATOM 895 CG LYS A 116 17.930 17.512 9.547 1.00 21.28 C +ATOM 896 CD LYS A 116 16.745 18.481 9.554 1.00 25.86 C +ATOM 897 CE LYS A 116 16.658 19.147 10.918 1.00 25.58 C +ATOM 898 NZ LYS A 116 15.454 20.010 11.047 1.00 34.69 N +ATOM 899 N GLY A 117 19.152 14.318 9.635 1.00 26.39 N +ATOM 900 CA GLY A 117 18.558 13.126 10.267 1.00 29.06 C +ATOM 901 C GLY A 117 19.018 11.781 9.733 1.00 28.29 C +ATOM 902 O GLY A 117 18.499 10.733 10.164 1.00 31.90 O +ATOM 903 N THR A 118 19.892 11.802 8.740 1.00 26.88 N +ATOM 904 CA THR A 118 20.473 10.578 8.171 1.00 22.31 C +ATOM 905 C THR A 118 21.868 10.375 8.761 1.00 21.43 C +ATOM 906 O THR A 118 22.321 11.119 9.650 1.00 22.31 O +ATOM 907 CB THR A 118 20.440 10.571 6.598 1.00 18.59 C +ATOM 908 OG1 THR A 118 21.560 11.404 6.161 1.00 22.71 O +ATOM 909 CG2 THR A 118 19.095 11.104 6.074 1.00 21.13 C +ATOM 910 N ASP A 119 22.392 9.213 8.431 1.00 21.20 N +ATOM 911 CA ASP A 119 23.768 8.830 8.756 1.00 22.61 C +ATOM 912 C ASP A 119 24.713 9.543 7.779 1.00 20.13 C +ATOM 913 O ASP A 119 25.178 8.950 6.780 1.00 20.57 O +ATOM 914 CB ASP A 119 23.934 7.313 8.738 1.00 21.00 C +ATOM 915 CG ASP A 119 25.347 6.900 9.121 1.00 25.32 C +ATOM 916 OD1 ASP A 119 26.051 7.633 9.830 1.00 27.93 O +ATOM 917 OD2 ASP A 119 25.715 5.746 8.804 1.00 27.31 O +ATOM 918 N VAL A 120 24.988 10.793 8.094 1.00 23.41 N +ATOM 919 CA VAL A 120 25.886 11.637 7.306 1.00 20.10 C +ATOM 920 C VAL A 120 27.342 11.199 7.304 1.00 18.51 C +ATOM 921 O VAL A 120 28.099 11.604 6.406 1.00 19.95 O +ATOM 922 CB VAL A 120 25.721 13.134 7.630 1.00 19.91 C +ATOM 923 CG1 VAL A 120 24.356 13.655 7.183 1.00 23.59 C +ATOM 924 CG2 VAL A 120 26.088 13.478 9.055 1.00 20.79 C +ATOM 925 N GLN A 121 27.701 10.430 8.306 1.00 21.83 N +ATOM 926 CA GLN A 121 29.021 9.783 8.389 1.00 21.12 C +ATOM 927 C GLN A 121 29.317 8.861 7.207 1.00 20.78 C +ATOM 928 O GLN A 121 30.480 8.669 6.820 1.00 19.66 O +ATOM 929 CB GLN A 121 29.088 9.048 9.728 1.00 24.21 C +ATOM 930 CG GLN A 121 30.530 8.965 10.167 1.00 26.13 C +ATOM 931 CD GLN A 121 30.615 8.877 11.674 1.00 26.94 C +ATOM 932 OE1 GLN A 121 31.368 9.632 12.283 1.00 31.43 O +ATOM 933 NE2 GLN A 121 29.884 7.871 12.151 1.00 28.26 N +ATOM 934 N ALA A 122 28.300 8.271 6.576 1.00 17.62 N +ATOM 935 CA ALA A 122 28.390 7.548 5.311 1.00 19.46 C +ATOM 936 C ALA A 122 29.186 8.290 4.227 1.00 17.98 C +ATOM 937 O ALA A 122 30.031 7.710 3.523 1.00 21.35 O +ATOM 938 CB ALA A 122 26.999 7.244 4.783 1.00 18.29 C +ATOM 939 N TRP A 123 29.021 9.616 4.240 1.00 18.07 N +ATOM 940 CA TRP A 123 29.703 10.502 3.283 1.00 16.76 C +ATOM 941 C TRP A 123 31.218 10.581 3.392 1.00 16.76 C +ATOM 942 O TRP A 123 31.905 10.942 2.412 1.00 20.08 O +ATOM 943 CB TRP A 123 29.027 11.872 3.347 1.00 19.49 C +ATOM 944 CG TRP A 123 27.621 11.735 2.850 1.00 17.43 C +ATOM 945 CD1 TRP A 123 26.485 11.608 3.588 1.00 19.42 C +ATOM 946 CD2 TRP A 123 27.241 11.547 1.481 1.00 17.47 C +ATOM 947 NE1 TRP A 123 25.405 11.458 2.774 1.00 18.86 N +ATOM 948 CE2 TRP A 123 25.827 11.391 1.479 1.00 17.28 C +ATOM 949 CE3 TRP A 123 27.947 11.468 0.283 1.00 20.03 C +ATOM 950 CZ2 TRP A 123 25.111 11.184 0.311 1.00 18.33 C +ATOM 951 CZ3 TRP A 123 27.222 11.329 -0.886 1.00 20.85 C +ATOM 952 CH2 TRP A 123 25.835 11.127 -0.869 1.00 20.45 C +ATOM 953 N ILE A 124 31.741 10.269 4.554 1.00 14.19 N +ATOM 954 CA ILE A 124 33.186 10.292 4.801 1.00 16.82 C +ATOM 955 C ILE A 124 33.863 8.955 5.024 1.00 18.45 C +ATOM 956 O ILE A 124 35.100 8.892 5.134 1.00 21.02 O +ATOM 957 CB ILE A 124 33.504 11.403 5.863 1.00 17.69 C +ATOM 958 CG1 ILE A 124 32.956 10.984 7.234 1.00 18.86 C +ATOM 959 CG2 ILE A 124 33.024 12.804 5.387 1.00 21.01 C +ATOM 960 CD1 ILE A 124 33.729 11.437 8.488 1.00 22.81 C +ATOM 961 N ARG A 125 33.080 7.898 5.131 1.00 21.05 N +ATOM 962 CA ARG A 125 33.594 6.534 5.320 1.00 19.12 C +ATOM 963 C ARG A 125 34.311 6.113 4.036 1.00 17.52 C +ATOM 964 O ARG A 125 33.843 6.337 2.906 1.00 23.44 O +ATOM 965 CB ARG A 125 32.476 5.551 5.650 1.00 19.54 C +ATOM 966 CG ARG A 125 32.117 5.596 7.145 1.00 22.40 C +ATOM 967 CD ARG A 125 31.277 4.392 7.482 1.00 24.05 C +ATOM 968 NE ARG A 125 30.282 4.754 8.466 1.00 28.08 N +ATOM 969 CZ ARG A 125 28.984 4.993 8.331 1.00 23.40 C +ATOM 970 NH1 ARG A 125 28.334 4.690 7.207 1.00 23.69 N +ATOM 971 NH2 ARG A 125 28.392 5.549 9.392 1.00 23.77 N +ATOM 972 N GLY A 126 35.497 5.568 4.243 1.00 18.80 N +ATOM 973 CA GLY A 126 36.291 5.058 3.102 1.00 21.28 C +ATOM 974 C GLY A 126 37.334 6.066 2.658 1.00 22.50 C +ATOM 975 O GLY A 126 38.220 5.729 1.855 1.00 23.59 O +ATOM 976 N CYS A 127 37.335 7.221 3.297 1.00 19.05 N +ATOM 977 CA CYS A 127 38.234 8.333 2.961 1.00 19.13 C +ATOM 978 C CYS A 127 39.422 8.382 3.925 1.00 22.50 C +ATOM 979 O CYS A 127 39.206 8.267 5.138 1.00 21.64 O +ATOM 980 CB CYS A 127 37.453 9.628 2.990 1.00 18.75 C +ATOM 981 SG CYS A 127 36.010 9.816 1.936 1.00 19.93 S +ATOM 982 N ARG A 128 40.586 8.695 3.393 1.00 23.60 N +ATOM 983 CA ARG A 128 41.774 8.960 4.217 1.00 28.29 C +ATOM 984 C ARG A 128 41.820 10.438 4.578 1.00 25.64 C +ATOM 985 O ARG A 128 41.976 11.291 3.694 1.00 30.98 O +ATOM 986 CB ARG A 128 43.047 8.304 3.707 1.00 30.82 C +ATOM 987 CG ARG A 128 43.231 6.886 4.280 1.00 34.25 C +ATOM 988 CD ARG A 128 43.833 6.911 5.651 1.00 33.59 C +ATOM 989 NE ARG A 128 45.246 7.263 5.636 1.00 37.63 N +ATOM 990 CZ ARG A 128 45.862 8.258 6.281 1.00 38.37 C +ATOM 991 NH1 ARG A 128 45.241 9.069 7.151 1.00 38.97 N +ATOM 992 NH2 ARG A 128 47.134 8.554 5.973 1.00 40.22 N +ATOM 993 N LEU A 129 41.289 10.715 5.771 1.00 26.05 N +ATOM 994 CA LEU A 129 41.094 12.084 6.273 1.00 26.89 C +ATOM 995 C LEU A 129 42.119 12.382 7.370 1.00 29.58 C +ATOM 996 O LEU A 129 41.730 12.276 8.559 1.00 33.54 O +ATOM 997 CB LEU A 129 39.635 12.335 6.646 1.00 26.31 C +ATOM 998 CG LEU A 129 38.689 12.917 5.620 1.00 23.49 C +ATOM 999 CD1 LEU A 129 39.112 12.657 4.191 1.00 26.43 C +ATOM 1000 CD2 LEU A 129 37.310 12.325 5.886 1.00 25.15 C +ATOM 1001 OXT LEU A 129 43.232 12.675 6.905 1.00 34.20 O +TER 1002 LEU A 129 +HETATM 1003 O HOH A 130 23.434 40.063 -6.661 1.00 19.48 O +HETATM 1004 O HOH A 131 31.994 26.416 -6.047 0.90 22.43 O +HETATM 1005 O HOH A 132 30.250 13.337 9.787 0.98 20.93 O +HETATM 1006 O HOH A 133 22.384 42.331 -8.165 0.90 21.85 O +HETATM 1007 O HOH A 134 29.239 27.621 -3.670 1.00 17.47 O +HETATM 1008 O HOH A 135 29.464 37.761 -10.492 0.98 20.05 O +HETATM 1009 O HOH A 136 20.807 36.305 -11.082 1.00 18.47 O +HETATM 1010 O HOH A 137 41.318 17.849 -1.378 0.98 20.99 O +HETATM 1011 O HOH A 138 34.697 29.056 -4.039 0.89 22.31 O +HETATM 1012 O HOH A 139 26.871 17.298 13.496 1.00 20.31 O +HETATM 1013 O HOH A 140 32.131 11.050 -5.817 0.97 21.39 O +HETATM 1014 O HOH A 141 23.468 40.040 -2.372 0.91 23.40 O +HETATM 1015 O HOH A 142 21.390 45.524 -11.035 0.96 20.63 O +HETATM 1016 O HOH A 143 34.490 26.578 -5.741 0.75 22.11 O +HETATM 1017 O HOH A 144 16.422 34.139 -3.527 0.91 20.71 O +HETATM 1018 O HOH A 145 21.374 29.926 8.946 0.83 24.21 O +HETATM 1019 O HOH A 146 41.048 12.539 -0.011 0.70 22.71 O +HETATM 1020 O HOH A 147 32.794 35.686 2.558 0.78 20.71 O +HETATM 1021 O HOH A 148 49.648 8.964 6.343 0.83 21.93 O +HETATM 1022 O HOH A 149 14.452 34.901 -13.339 0.69 23.89 O +HETATM 1023 O HOH A 150 22.930 10.839 4.044 0.92 22.02 O +HETATM 1024 O HOH A 151 16.012 18.490 -2.200 0.85 24.37 O +HETATM 1025 O HOH A 152 12.130 21.587 3.044 0.78 24.35 O +HETATM 1026 O HOH A 153 15.684 38.922 -5.813 0.76 24.50 O +HETATM 1027 O HOH A 154 10.652 24.228 3.428 0.80 21.12 O +HETATM 1028 O HOH A 155 44.070 17.975 2.852 0.80 21.64 O +HETATM 1029 O HOH A 156 32.029 13.080 -8.110 0.85 20.63 O +HETATM 1030 O HOH A 157 36.425 19.613 15.174 0.56 23.44 O +HETATM 1031 O HOH A 158 37.941 30.505 -3.686 0.79 21.54 O +HETATM 1032 O HOH A 159 30.710 42.741 -6.289 0.72 22.79 O +HETATM 1033 O HOH A 160 23.922 44.367 -7.653 0.62 22.78 O +HETATM 1034 O HOH A 161 33.829 34.252 0.626 0.73 20.81 O +HETATM 1035 O HOH A 162 29.613 40.730 -9.602 0.78 22.12 O +HETATM 1036 O HOH A 163 23.563 7.995 4.406 0.58 22.93 O +HETATM 1037 O HOH A 164 31.511 42.362 -4.183 0.73 22.01 O +HETATM 1038 O HOH A 165 21.882 29.536 -15.013 0.81 22.04 O +HETATM 1039 O HOH A 166 37.763 20.913 9.782 0.86 21.57 O +HETATM 1040 O HOH A 167 42.338 17.481 5.165 0.65 22.17 O +HETATM 1041 O HOH A 168 23.344 39.739 -4.358 0.72 21.56 O +HETATM 1042 O HOH A 169 22.984 29.224 13.124 0.75 22.56 O +HETATM 1043 O HOH A 170 30.778 7.794 -3.514 0.65 21.58 O +HETATM 1044 O HOH A 171 42.965 14.657 4.991 0.63 23.91 O +HETATM 1045 O HOH A 172 36.927 17.948 -13.093 0.62 23.36 O +HETATM 1046 O HOH A 173 35.412 25.852 -11.575 0.58 23.42 O +HETATM 1047 O HOH A 174 37.428 32.540 -5.787 0.62 21.98 O +HETATM 1048 O HOH A 175 37.317 8.592 7.456 0.64 22.92 O +HETATM 1049 O HOH A 176 9.314 36.705 -11.546 0.69 23.77 O +HETATM 1050 O HOH A 177 39.972 23.760 -2.655 0.86 18.96 O +HETATM 1051 O HOH A 178 22.128 30.274 -0.543 0.76 18.78 O +HETATM 1052 O HOH A 179 22.244 15.813 10.000 0.68 19.66 O +HETATM 1053 O HOH A 180 40.729 9.223 0.292 0.64 20.15 O +HETATM 1054 O HOH A 181 12.500 15.267 4.097 0.56 20.12 O +HETATM 1055 O HOH A 182 20.372 28.618 -2.353 0.64 20.17 O +HETATM 1056 O HOH A 183 22.793 15.462 -6.673 0.63 20.60 O +HETATM 1057 O HOH A 184 23.138 31.809 15.121 0.55 20.90 O +HETATM 1058 O HOH A 185 22.671 38.691 8.245 0.48 21.16 O +HETATM 1059 O HOH A 186 33.966 33.112 6.837 0.59 19.45 O +HETATM 1060 O HOH A 187 19.572 25.423 -1.420 0.53 19.94 O +HETATM 1061 O HOH A 188 14.790 15.672 7.259 0.52 21.22 O +HETATM 1062 O HOH A 189 19.112 28.022 -14.647 0.49 19.83 O +HETATM 1063 O HOH A 190 17.302 39.059 -12.453 0.52 20.14 O +HETATM 1064 O HOH A 191 16.198 14.502 5.577 0.46 20.78 O +HETATM 1065 O HOH A 192 17.345 46.346 -7.080 0.50 18.13 O +HETATM 1066 O HOH A 193 14.992 31.300 -4.242 0.46 17.90 O +HETATM 1067 O HOH A 194 28.196 44.775 -3.148 0.44 18.15 O +HETATM 1068 O HOH A 195 29.479 13.863 -9.107 0.44 18.30 O +HETATM 1069 O HOH A 196 23.613 44.811 2.608 0.45 17.66 O +HETATM 1070 O HOH A 197 40.572 22.184 -6.358 0.42 18.06 O +HETATM 1071 O HOH A 198 12.475 31.860 -6.226 0.47 17.85 O +HETATM 1072 O HOH A 199 16.684 13.594 -5.832 0.31 18.51 O +HETATM 1073 O HOH A 200 27.534 38.059 -12.862 0.48 18.19 O +HETATM 1074 O HOH A 201 25.892 35.973 11.563 0.46 18.15 O +HETATM 1075 O HOH A 202 24.790 25.182 16.063 0.46 17.64 O +HETATM 1076 O HOH A 203 12.580 21.214 5.006 0.51 17.97 O +HETATM 1077 O HOH A 204 19.687 23.750 -4.851 0.37 18.08 O +HETATM 1078 O HOH A 205 27.098 35.956 -12.358 0.39 18.71 O +HETATM 1079 O HOH A 206 37.255 9.634 10.002 0.46 18.39 O +HETATM 1080 O HOH A 207 43.755 23.843 8.038 0.38 17.96 O +CONECT 48 981 +CONECT 238 889 +CONECT 513 630 +CONECT 601 724 +CONECT 630 513 +CONECT 724 601 +CONECT 889 238 +CONECT 981 48 +MASTER 290 0 0 8 2 0 0 6 1079 1 8 10 +END diff --git a/modules/mol/mm/examples/1CRN.pdb b/modules/mol/mm/examples/1CRN.pdb new file mode 100644 index 0000000000000000000000000000000000000000..13ca618d438ae60a55a8ce1c532cd23bf545e200 --- /dev/null +++ b/modules/mol/mm/examples/1CRN.pdb @@ -0,0 +1,329 @@ +ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N +ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C +ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C +ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O +ATOM 5 CB THR A 1 18.170 12.703 5.337 1.00 13.02 C +ATOM 6 OG1 THR A 1 19.334 12.829 4.463 1.00 15.06 O +ATOM 7 CG2 THR A 1 18.150 11.546 6.304 1.00 14.23 C +ATOM 8 N THR A 2 15.115 11.555 5.265 1.00 7.81 N +ATOM 9 CA THR A 2 13.856 11.469 6.066 1.00 8.31 C +ATOM 10 C THR A 2 14.164 10.785 7.379 1.00 5.80 C +ATOM 11 O THR A 2 14.993 9.862 7.443 1.00 6.94 O +ATOM 12 CB THR A 2 12.732 10.711 5.261 1.00 10.32 C +ATOM 13 OG1 THR A 2 13.308 9.439 4.926 1.00 12.81 O +ATOM 14 CG2 THR A 2 12.484 11.442 3.895 1.00 11.90 C +ATOM 15 N CYS A 3 13.488 11.241 8.417 1.00 5.24 N +ATOM 16 CA CYS A 3 13.660 10.707 9.787 1.00 5.39 C +ATOM 17 C CYS A 3 12.269 10.431 10.323 1.00 4.45 C +ATOM 18 O CYS A 3 11.393 11.308 10.185 1.00 6.54 O +ATOM 19 CB CYS A 3 14.368 11.748 10.691 1.00 5.99 C +ATOM 20 SG CYS A 3 15.885 12.426 10.016 1.00 7.01 S +ATOM 21 N CYS A 4 12.019 9.272 10.928 1.00 3.90 N +ATOM 22 CA CYS A 4 10.646 8.991 11.408 1.00 4.24 C +ATOM 23 C CYS A 4 10.654 8.793 12.919 1.00 3.72 C +ATOM 24 O CYS A 4 11.659 8.296 13.491 1.00 5.30 O +ATOM 25 CB CYS A 4 10.057 7.752 10.682 1.00 4.41 C +ATOM 26 SG CYS A 4 9.837 8.018 8.904 1.00 4.72 S +ATOM 27 N PRO A 5 9.561 9.108 13.563 1.00 3.96 N +ATOM 28 CA PRO A 5 9.448 9.034 15.012 1.00 4.25 C +ATOM 29 C PRO A 5 9.288 7.670 15.606 1.00 4.96 C +ATOM 30 O PRO A 5 9.490 7.519 16.819 1.00 7.44 O +ATOM 31 CB PRO A 5 8.230 9.957 15.345 1.00 5.11 C +ATOM 32 CG PRO A 5 7.338 9.786 14.114 1.00 5.24 C +ATOM 33 CD PRO A 5 8.366 9.804 12.958 1.00 5.20 C +ATOM 34 N SER A 6 8.875 6.686 14.796 1.00 4.83 N +ATOM 35 CA SER A 6 8.673 5.314 15.279 1.00 4.45 C +ATOM 36 C SER A 6 8.753 4.376 14.083 1.00 4.99 C +ATOM 37 O SER A 6 8.726 4.858 12.923 1.00 4.61 O +ATOM 38 CB SER A 6 7.340 5.121 15.996 1.00 5.05 C +ATOM 39 OG SER A 6 6.274 5.220 15.031 1.00 6.39 O +ATOM 40 N ILE A 7 8.881 3.075 14.358 1.00 4.94 N +ATOM 41 CA ILE A 7 8.912 2.083 13.258 1.00 6.33 C +ATOM 42 C ILE A 7 7.581 2.090 12.506 1.00 5.32 C +ATOM 43 O ILE A 7 7.670 2.031 11.245 1.00 6.85 O +ATOM 44 CB ILE A 7 9.207 0.677 13.924 1.00 8.43 C +ATOM 45 CG1 ILE A 7 10.714 0.702 14.312 1.00 9.78 C +ATOM 46 CG2 ILE A 7 8.811 -0.477 12.969 1.00 11.70 C +ATOM 47 CD1 ILE A 7 11.185 -0.516 15.142 1.00 9.92 C +ATOM 48 N VAL A 8 6.458 2.162 13.159 1.00 5.02 N +ATOM 49 CA VAL A 8 5.145 2.209 12.453 1.00 6.93 C +ATOM 50 C VAL A 8 5.115 3.379 11.461 1.00 5.39 C +ATOM 51 O VAL A 8 4.664 3.268 10.343 1.00 6.30 O +ATOM 52 CB VAL A 8 3.995 2.354 13.478 1.00 9.64 C +ATOM 53 CG1 VAL A 8 2.716 2.891 12.869 1.00 13.85 C +ATOM 54 CG2 VAL A 8 3.758 1.032 14.208 1.00 11.97 C +ATOM 55 N ALA A 9 5.606 4.546 11.941 1.00 3.73 N +ATOM 56 CA ALA A 9 5.598 5.767 11.082 1.00 3.56 C +ATOM 57 C ALA A 9 6.441 5.527 9.850 1.00 4.13 C +ATOM 58 O ALA A 9 6.052 5.933 8.744 1.00 4.36 O +ATOM 59 CB ALA A 9 6.022 6.977 11.891 1.00 4.80 C +ATOM 60 N ARG A 10 7.647 4.909 10.005 1.00 3.73 N +ATOM 61 CA ARG A 10 8.496 4.609 8.837 1.00 3.38 C +ATOM 62 C ARG A 10 7.798 3.609 7.876 1.00 3.47 C +ATOM 63 O ARG A 10 7.878 3.778 6.651 1.00 4.67 O +ATOM 64 CB ARG A 10 9.847 4.020 9.305 1.00 3.95 C +ATOM 65 CG ARG A 10 10.752 3.607 8.149 1.00 4.55 C +ATOM 66 CD ARG A 10 11.226 4.699 7.244 1.00 5.89 C +ATOM 67 NE ARG A 10 12.143 5.571 8.035 1.00 6.20 N +ATOM 68 CZ ARG A 10 12.758 6.609 7.443 1.00 7.52 C +ATOM 69 NH1 ARG A 10 12.539 6.932 6.158 1.00 10.68 N +ATOM 70 NH2 ARG A 10 13.601 7.322 8.202 1.00 9.48 N +ATOM 71 N SER A 11 7.186 2.582 8.445 1.00 5.19 N +ATOM 72 CA SER A 11 6.500 1.584 7.565 1.00 4.60 C +ATOM 73 C SER A 11 5.382 2.313 6.773 1.00 4.84 C +ATOM 74 O SER A 11 5.213 2.016 5.557 1.00 5.84 O +ATOM 75 CB SER A 11 5.908 0.462 8.400 1.00 5.91 C +ATOM 76 OG SER A 11 6.990 -0.272 9.012 1.00 8.38 O +ATOM 77 N ASN A 12 4.648 3.182 7.446 1.00 3.54 N +ATOM 78 CA ASN A 12 3.545 3.935 6.751 1.00 4.57 C +ATOM 79 C ASN A 12 4.107 4.851 5.691 1.00 4.14 C +ATOM 80 O ASN A 12 3.536 5.001 4.617 1.00 5.52 O +ATOM 81 CB ASN A 12 2.663 4.677 7.748 1.00 6.42 C +ATOM 82 CG ASN A 12 1.802 3.735 8.610 1.00 8.25 C +ATOM 83 OD1 ASN A 12 1.567 2.613 8.165 1.00 12.72 O +ATOM 84 ND2 ASN A 12 1.394 4.252 9.767 1.00 9.92 N +ATOM 85 N PHE A 13 5.259 5.498 6.005 1.00 3.43 N +ATOM 86 CA PHE A 13 5.929 6.358 5.055 1.00 3.49 C +ATOM 87 C PHE A 13 6.304 5.578 3.799 1.00 3.40 C +ATOM 88 O PHE A 13 6.136 6.072 2.653 1.00 4.07 O +ATOM 89 CB PHE A 13 7.183 6.994 5.754 1.00 5.48 C +ATOM 90 CG PHE A 13 7.884 8.006 4.883 1.00 5.57 C +ATOM 91 CD1 PHE A 13 8.906 7.586 4.027 1.00 6.99 C +ATOM 92 CD2 PHE A 13 7.532 9.373 4.983 1.00 6.52 C +ATOM 93 CE1 PHE A 13 9.560 8.539 3.194 1.00 8.20 C +ATOM 94 CE2 PHE A 13 8.176 10.281 4.145 1.00 6.34 C +ATOM 95 CZ PHE A 13 9.141 9.845 3.292 1.00 6.84 C +ATOM 96 N ASN A 14 6.900 4.390 3.989 1.00 3.64 N +ATOM 97 CA ASN A 14 7.331 3.607 2.791 1.00 4.31 C +ATOM 98 C ASN A 14 6.116 3.210 1.915 1.00 3.98 C +ATOM 99 O ASN A 14 6.240 3.144 0.684 1.00 6.22 O +ATOM 100 CB ASN A 14 8.145 2.404 3.240 1.00 5.81 C +ATOM 101 CG ASN A 14 9.555 2.856 3.730 1.00 6.82 C +ATOM 102 OD1 ASN A 14 10.013 3.895 3.323 1.00 9.43 O +ATOM 103 ND2 ASN A 14 10.120 1.956 4.539 1.00 8.21 N +ATOM 104 N VAL A 15 4.993 2.927 2.571 1.00 3.76 N +ATOM 105 CA VAL A 15 3.782 2.599 1.742 1.00 3.98 C +ATOM 106 C VAL A 15 3.296 3.871 1.004 1.00 3.80 C +ATOM 107 O VAL A 15 2.947 3.817 -0.189 1.00 4.85 O +ATOM 108 CB VAL A 15 2.698 1.953 2.608 1.00 4.71 C +ATOM 109 CG1 VAL A 15 1.384 1.826 1.806 1.00 6.67 C +ATOM 110 CG2 VAL A 15 3.174 0.533 3.005 1.00 6.26 C +ATOM 111 N CYS A 16 3.321 4.987 1.720 1.00 3.79 N +ATOM 112 CA CYS A 16 2.890 6.285 1.126 1.00 3.54 C +ATOM 113 C CYS A 16 3.687 6.597 -0.111 1.00 3.48 C +ATOM 114 O CYS A 16 3.200 7.147 -1.103 1.00 4.63 O +ATOM 115 CB CYS A 16 3.039 7.369 2.240 1.00 4.58 C +ATOM 116 SG CYS A 16 2.559 9.014 1.649 1.00 5.66 S +ATOM 117 N ARG A 17 4.997 6.227 -0.100 1.00 3.99 N +ATOM 118 CA ARG A 17 5.895 6.489 -1.213 1.00 3.83 C +ATOM 119 C ARG A 17 5.738 5.560 -2.409 1.00 3.79 C +ATOM 120 O ARG A 17 6.228 5.901 -3.507 1.00 5.39 O +ATOM 121 CB ARG A 17 7.370 6.507 -0.731 1.00 4.11 C +ATOM 122 CG ARG A 17 7.717 7.687 0.206 1.00 4.69 C +ATOM 123 CD ARG A 17 7.949 8.947 -0.615 1.00 5.10 C +ATOM 124 NE ARG A 17 9.212 8.856 -1.337 1.00 4.71 N +ATOM 125 CZ ARG A 17 9.537 9.533 -2.431 1.00 5.28 C +ATOM 126 NH1 ARG A 17 8.659 10.350 -3.032 1.00 6.67 N +ATOM 127 NH2 ARG A 17 10.793 9.491 -2.899 1.00 6.41 N +ATOM 128 N LEU A 18 5.051 4.411 -2.204 1.00 4.70 N +ATOM 129 CA LEU A 18 4.933 3.431 -3.326 1.00 5.46 C +ATOM 130 C LEU A 18 4.397 4.014 -4.620 1.00 5.13 C +ATOM 131 O LEU A 18 4.988 3.755 -5.687 1.00 5.55 O +ATOM 132 CB LEU A 18 4.196 2.184 -2.863 1.00 6.47 C +ATOM 133 CG LEU A 18 4.960 1.178 -1.991 1.00 7.43 C +ATOM 134 CD1 LEU A 18 3.907 0.097 -1.634 1.00 8.70 C +ATOM 135 CD2 LEU A 18 6.129 0.606 -2.768 1.00 9.39 C +ATOM 136 N PRO A 19 3.329 4.795 -4.543 1.00 4.28 N +ATOM 137 CA PRO A 19 2.792 5.376 -5.797 1.00 5.38 C +ATOM 138 C PRO A 19 3.573 6.540 -6.322 1.00 6.30 C +ATOM 139 O PRO A 19 3.260 7.045 -7.422 1.00 9.62 O +ATOM 140 CB PRO A 19 1.358 5.766 -5.472 1.00 5.87 C +ATOM 141 CG PRO A 19 1.223 5.694 -3.993 1.00 6.47 C +ATOM 142 CD PRO A 19 2.421 4.941 -3.408 1.00 6.45 C +ATOM 143 N GLY A 20 4.565 7.047 -5.559 1.00 4.94 N +ATOM 144 CA GLY A 20 5.366 8.191 -6.018 1.00 5.39 C +ATOM 145 C GLY A 20 5.007 9.481 -5.280 1.00 5.03 C +ATOM 146 O GLY A 20 5.535 10.510 -5.730 1.00 7.34 O +ATOM 147 N THR A 21 4.181 9.438 -4.262 1.00 4.10 N +ATOM 148 CA THR A 21 3.767 10.609 -3.513 1.00 3.94 C +ATOM 149 C THR A 21 5.017 11.397 -3.042 1.00 3.96 C +ATOM 150 O THR A 21 5.947 10.757 -2.523 1.00 5.82 O +ATOM 151 CB THR A 21 2.992 10.188 -2.225 1.00 4.13 C +ATOM 152 OG1 THR A 21 2.051 9.144 -2.623 1.00 5.45 O +ATOM 153 CG2 THR A 21 2.260 11.349 -1.551 1.00 5.41 C +ATOM 154 N PRO A 22 4.971 12.703 -3.176 1.00 5.04 N +ATOM 155 CA PRO A 22 6.143 13.513 -2.696 1.00 4.69 C +ATOM 156 C PRO A 22 6.400 13.233 -1.225 1.00 4.19 C +ATOM 157 O PRO A 22 5.485 13.061 -0.382 1.00 4.47 O +ATOM 158 CB PRO A 22 5.703 14.969 -2.920 1.00 7.12 C +ATOM 159 CG PRO A 22 4.676 14.893 -3.996 1.00 7.03 C +ATOM 160 CD PRO A 22 3.964 13.567 -3.811 1.00 4.90 C +ATOM 161 N GLU A 23 7.728 13.297 -0.921 1.00 5.16 N +ATOM 162 CA GLU A 23 8.114 13.103 0.500 1.00 5.31 C +ATOM 163 C GLU A 23 7.427 14.073 1.410 1.00 4.11 C +ATOM 164 O GLU A 23 7.036 13.682 2.540 1.00 5.11 O +ATOM 165 CB GLU A 23 9.648 13.285 0.660 1.00 6.16 C +ATOM 166 CG GLU A 23 10.440 12.093 0.063 1.00 7.48 C +ATOM 167 CD GLU A 23 11.941 12.170 0.391 1.00 9.40 C +ATOM 168 OE1 GLU A 23 12.416 13.225 0.681 1.00 10.40 O +ATOM 169 OE2 GLU A 23 12.539 11.070 0.292 1.00 13.32 O +ATOM 170 N ALA A 24 7.212 15.334 0.966 1.00 4.56 N +ATOM 171 CA ALA A 24 6.614 16.317 1.913 1.00 4.49 C +ATOM 172 C ALA A 24 5.212 15.936 2.350 1.00 4.10 C +ATOM 173 O ALA A 24 4.782 16.166 3.495 1.00 5.64 O +ATOM 174 CB ALA A 24 6.605 17.695 1.246 1.00 5.80 C +ATOM 175 N ILE A 25 4.445 15.318 1.405 1.00 4.37 N +ATOM 176 CA ILE A 25 3.074 14.894 1.756 1.00 5.44 C +ATOM 177 C ILE A 25 3.085 13.643 2.645 1.00 4.32 C +ATOM 178 O ILE A 25 2.315 13.523 3.578 1.00 4.72 O +ATOM 179 CB ILE A 25 2.204 14.637 0.462 1.00 6.42 C +ATOM 180 CG1 ILE A 25 1.815 16.048 -0.129 1.00 7.50 C +ATOM 181 CG2 ILE A 25 0.903 13.864 0.811 1.00 7.65 C +ATOM 182 CD1 ILE A 25 0.756 16.761 0.757 1.00 7.80 C +ATOM 183 N CYS A 26 4.032 12.764 2.313 1.00 3.92 N +ATOM 184 CA CYS A 26 4.180 11.549 3.187 1.00 4.37 C +ATOM 185 C CYS A 26 4.632 11.944 4.596 1.00 3.95 C +ATOM 186 O CYS A 26 4.227 11.252 5.547 1.00 4.74 O +ATOM 187 CB CYS A 26 5.038 10.518 2.539 1.00 4.63 C +ATOM 188 SG CYS A 26 4.349 9.794 1.022 1.00 5.61 S +ATOM 189 N ALA A 27 5.408 13.012 4.694 1.00 3.89 N +ATOM 190 CA ALA A 27 5.879 13.502 6.026 1.00 4.43 C +ATOM 191 C ALA A 27 4.696 13.908 6.882 1.00 4.26 C +ATOM 192 O ALA A 27 4.528 13.422 8.025 1.00 5.44 O +ATOM 193 CB ALA A 27 6.880 14.615 5.830 1.00 5.36 C +ATOM 194 N THR A 28 3.827 14.802 6.358 1.00 4.53 N +ATOM 195 CA THR A 28 2.691 15.221 7.194 1.00 5.08 C +ATOM 196 C THR A 28 1.672 14.132 7.434 1.00 4.62 C +ATOM 197 O THR A 28 0.947 14.112 8.468 1.00 7.80 O +ATOM 198 CB THR A 28 1.986 16.520 6.614 1.00 6.03 C +ATOM 199 OG1 THR A 28 1.664 16.221 5.230 1.00 7.19 O +ATOM 200 CG2 THR A 28 2.914 17.739 6.700 1.00 7.34 C +ATOM 201 N TYR A 29 1.621 13.190 6.511 1.00 5.01 N +ATOM 202 CA TYR A 29 0.715 12.045 6.657 1.00 6.60 C +ATOM 203 C TYR A 29 1.125 11.125 7.815 1.00 4.92 C +ATOM 204 O TYR A 29 0.286 10.632 8.545 1.00 7.13 O +ATOM 205 CB TYR A 29 0.755 11.229 5.322 1.00 9.66 C +ATOM 206 CG TYR A 29 -0.203 10.044 5.354 1.00 11.56 C +ATOM 207 CD1 TYR A 29 -1.547 10.337 5.645 1.00 12.85 C +ATOM 208 CD2 TYR A 29 0.193 8.750 5.100 1.00 14.44 C +ATOM 209 CE1 TYR A 29 -2.496 9.329 5.673 1.00 16.61 C +ATOM 210 CE2 TYR A 29 -0.801 7.705 5.156 1.00 17.11 C +ATOM 211 CZ TYR A 29 -2.079 8.031 5.430 1.00 19.99 C +ATOM 212 OH TYR A 29 -3.097 7.057 5.458 1.00 28.98 O +ATOM 213 N THR A 30 2.470 10.984 7.995 1.00 5.31 N +ATOM 214 CA THR A 30 2.986 9.994 8.950 1.00 5.70 C +ATOM 215 C THR A 30 3.609 10.505 10.230 1.00 6.28 C +ATOM 216 O THR A 30 3.766 9.715 11.186 1.00 8.77 O +ATOM 217 CB THR A 30 4.076 9.103 8.225 1.00 6.55 C +ATOM 218 OG1 THR A 30 5.125 10.027 7.824 1.00 6.57 O +ATOM 219 CG2 THR A 30 3.493 8.324 7.035 1.00 7.29 C +ATOM 220 N GLY A 31 3.984 11.764 10.241 1.00 4.99 N +ATOM 221 CA GLY A 31 4.769 12.336 11.360 1.00 5.50 C +ATOM 222 C GLY A 31 6.255 12.243 11.106 1.00 4.19 C +ATOM 223 O GLY A 31 7.037 12.750 11.954 1.00 6.12 O +ATOM 224 N CYS A 32 6.710 11.631 9.992 1.00 4.30 N +ATOM 225 CA CYS A 32 8.140 11.694 9.635 1.00 4.89 C +ATOM 226 C CYS A 32 8.500 13.141 9.206 1.00 5.50 C +ATOM 227 O CYS A 32 7.581 13.949 8.944 1.00 5.82 O +ATOM 228 CB CYS A 32 8.504 10.686 8.530 1.00 4.66 C +ATOM 229 SG CYS A 32 8.048 8.987 8.881 1.00 5.33 S +ATOM 230 N ILE A 33 9.793 13.410 9.173 1.00 6.02 N +ATOM 231 CA ILE A 33 10.280 14.760 8.823 1.00 5.24 C +ATOM 232 C ILE A 33 11.346 14.658 7.743 1.00 5.16 C +ATOM 233 O ILE A 33 11.971 13.583 7.552 1.00 7.19 O +ATOM 234 CB ILE A 33 10.790 15.535 10.085 1.00 5.49 C +ATOM 235 CG1 ILE A 33 12.059 14.803 10.671 1.00 6.85 C +ATOM 236 CG2 ILE A 33 9.684 15.686 11.138 1.00 6.45 C +ATOM 237 CD1 ILE A 33 12.733 15.676 11.781 1.00 8.94 C +ATOM 238 N ILE A 34 11.490 15.773 7.038 1.00 5.52 N +ATOM 239 CA ILE A 34 12.552 15.877 6.036 1.00 6.82 C +ATOM 240 C ILE A 34 13.590 16.917 6.560 1.00 6.92 C +ATOM 241 O ILE A 34 13.168 18.006 6.945 1.00 9.22 O +ATOM 242 CB ILE A 34 11.987 16.360 4.681 1.00 8.11 C +ATOM 243 CG1 ILE A 34 10.914 15.338 4.163 1.00 9.59 C +ATOM 244 CG2 ILE A 34 13.131 16.517 3.629 1.00 9.73 C +ATOM 245 CD1 ILE A 34 10.151 16.024 2.938 1.00 13.41 C +ATOM 246 N ILE A 35 14.856 16.493 6.536 1.00 7.06 N +ATOM 247 CA ILE A 35 15.930 17.454 6.941 1.00 7.52 C +ATOM 248 C ILE A 35 16.913 17.550 5.819 1.00 6.63 C +ATOM 249 O ILE A 35 17.097 16.660 4.970 1.00 7.90 O +ATOM 250 CB ILE A 35 16.622 16.995 8.285 1.00 8.07 C +ATOM 251 CG1 ILE A 35 17.360 15.651 8.067 1.00 9.41 C +ATOM 252 CG2 ILE A 35 15.592 16.974 9.434 1.00 9.46 C +ATOM 253 CD1 ILE A 35 18.298 15.206 9.219 1.00 9.85 C +ATOM 254 N PRO A 36 17.664 18.669 5.806 1.00 8.07 N +ATOM 255 CA PRO A 36 18.635 18.861 4.738 1.00 8.78 C +ATOM 256 C PRO A 36 19.925 18.042 4.949 1.00 8.31 C +ATOM 257 O PRO A 36 20.593 17.742 3.945 1.00 9.09 O +ATOM 258 CB PRO A 36 18.945 20.364 4.783 1.00 9.67 C +ATOM 259 CG PRO A 36 18.238 20.937 5.908 1.00 10.15 C +ATOM 260 CD PRO A 36 17.371 19.900 6.596 1.00 9.53 C +ATOM 261 N GLY A 37 20.172 17.730 6.217 1.00 8.48 N +ATOM 262 CA GLY A 37 21.452 16.969 6.513 1.00 9.20 C +ATOM 263 C GLY A 37 21.143 15.478 6.427 1.00 10.41 C +ATOM 264 O GLY A 37 20.138 15.023 5.878 1.00 12.06 O +ATOM 265 N ALA A 38 22.055 14.701 7.032 1.00 9.24 N +ATOM 266 CA ALA A 38 22.019 13.242 7.020 1.00 9.24 C +ATOM 267 C ALA A 38 21.944 12.628 8.396 1.00 9.60 C +ATOM 268 O ALA A 38 21.869 11.387 8.435 1.00 13.65 O +ATOM 269 CB ALA A 38 23.246 12.697 6.275 1.00 10.43 C +ATOM 270 N THR A 39 21.894 13.435 9.436 1.00 8.70 N +ATOM 271 CA THR A 39 21.936 12.911 10.809 1.00 9.46 C +ATOM 272 C THR A 39 20.615 13.191 11.521 1.00 8.32 C +ATOM 273 O THR A 39 20.357 14.317 11.948 1.00 9.89 O +ATOM 274 CB THR A 39 23.131 13.601 11.593 1.00 10.72 C +ATOM 275 OG1 THR A 39 24.284 13.401 10.709 1.00 11.66 O +ATOM 276 CG2 THR A 39 23.340 12.935 12.962 1.00 11.81 C +ATOM 277 N CYS A 40 19.827 12.110 11.642 1.00 7.64 N +ATOM 278 CA CYS A 40 18.504 12.312 12.298 1.00 8.05 C +ATOM 279 C CYS A 40 18.684 12.451 13.784 1.00 7.63 C +ATOM 280 O CYS A 40 19.533 11.718 14.362 1.00 9.64 O +ATOM 281 CB CYS A 40 17.582 11.117 11.996 1.00 7.80 C +ATOM 282 SG CYS A 40 17.199 10.929 10.237 1.00 7.30 S +ATOM 283 N PRO A 41 17.880 13.266 14.426 1.00 8.00 N +ATOM 284 CA PRO A 41 17.924 13.421 15.877 1.00 8.96 C +ATOM 285 C PRO A 41 17.392 12.206 16.594 1.00 9.06 C +ATOM 286 O PRO A 41 16.652 11.368 16.033 1.00 8.82 O +ATOM 287 CB PRO A 41 17.076 14.658 16.145 1.00 10.39 C +ATOM 288 CG PRO A 41 16.098 14.689 14.997 1.00 10.99 C +ATOM 289 CD PRO A 41 16.859 14.150 13.779 1.00 10.49 C +ATOM 290 N GLY A 42 17.728 12.124 17.884 1.00 7.55 N +ATOM 291 CA GLY A 42 17.334 10.956 18.691 1.00 8.00 C +ATOM 292 C GLY A 42 15.875 10.688 18.871 1.00 7.22 C +ATOM 293 O GLY A 42 15.434 9.550 19.166 1.00 8.41 O +ATOM 294 N ASP A 43 15.036 11.747 18.715 1.00 5.54 N +ATOM 295 CA ASP A 43 13.564 11.573 18.836 1.00 5.85 C +ATOM 296 C ASP A 43 12.936 11.227 17.470 1.00 5.87 C +ATOM 297 O ASP A 43 11.720 11.040 17.428 1.00 7.29 O +ATOM 298 CB ASP A 43 12.933 12.737 19.580 1.00 6.72 C +ATOM 299 CG ASP A 43 13.140 14.094 18.958 1.00 8.59 C +ATOM 300 OD1 ASP A 43 14.109 14.303 18.212 1.00 9.59 O +ATOM 301 OD2 ASP A 43 12.267 14.963 19.265 1.00 11.45 O +ATOM 302 N TYR A 44 13.725 11.174 16.425 1.00 5.22 N +ATOM 303 CA TYR A 44 13.257 10.745 15.081 1.00 5.56 C +ATOM 304 C TYR A 44 14.275 9.687 14.612 1.00 4.61 C +ATOM 305 O TYR A 44 14.930 9.862 13.568 1.00 6.04 O +ATOM 306 CB TYR A 44 13.200 11.914 14.071 1.00 5.41 C +ATOM 307 CG TYR A 44 12.000 12.819 14.399 1.00 5.34 C +ATOM 308 CD1 TYR A 44 12.119 13.853 15.332 1.00 6.59 C +ATOM 309 CD2 TYR A 44 10.775 12.617 13.762 1.00 5.94 C +ATOM 310 CE1 TYR A 44 11.045 14.675 15.610 1.00 5.97 C +ATOM 311 CE2 TYR A 44 9.676 13.433 14.048 1.00 5.17 C +ATOM 312 CZ TYR A 44 9.802 14.456 14.996 1.00 5.96 C +ATOM 313 OH TYR A 44 8.740 15.265 15.269 1.00 8.60 O +ATOM 314 N ALA A 45 14.342 8.640 15.422 1.00 4.76 N +ATOM 315 CA ALA A 45 15.445 7.667 15.246 1.00 5.89 C +ATOM 316 C ALA A 45 15.171 6.533 14.280 1.00 6.67 C +ATOM 317 O ALA A 45 16.093 5.705 14.039 1.00 7.56 O +ATOM 318 CB ALA A 45 15.680 7.099 16.682 1.00 6.82 C +ATOM 319 N ASN A 46 13.966 6.502 13.739 1.00 5.80 N +ATOM 320 CA ASN A 46 13.512 5.395 12.878 1.00 6.15 C +ATOM 321 C ASN A 46 13.311 5.853 11.455 1.00 6.61 C +ATOM 322 O ASN A 46 13.733 6.929 11.026 1.00 7.18 O +ATOM 323 CB ASN A 46 12.266 4.769 13.501 1.00 7.27 C +ATOM 324 CG ASN A 46 12.538 4.304 14.922 1.00 7.98 C +ATOM 325 OD1 ASN A 46 11.982 4.849 15.886 1.00 11.00 O +ATOM 326 ND2 ASN A 46 13.407 3.298 15.015 1.00 10.32 N +ATOM 327 OXT ASN A 46 12.703 4.973 10.746 1.00 7.86 O +TER 328 ASN A 46 +END diff --git a/modules/mol/mm/examples/ethanol.pdb b/modules/mol/mm/examples/ethanol.pdb new file mode 100644 index 0000000000000000000000000000000000000000..4d16716e8bd096575463cc1c3bb0a13d435873d2 --- /dev/null +++ b/modules/mol/mm/examples/ethanol.pdb @@ -0,0 +1,10 @@ +ATOM 1 C1 ETH A 1 -0.246 0.000 1.285 1.00 0.00 C +ATOM 2 C2 ETH A 1 0.566 0.000 -0.011 1.00 0.00 C +ATOM 3 O ETH A 1 -0.322 0.000 -1.130 1.00 0.00 O +ATOM 4 H11 ETH A 1 0.376 0.000 2.068 1.00 0.00 H +ATOM 5 H12 ETH A 1 -0.847 0.866 1.302 1.00 0.00 H +ATOM 6 H13 ETH A 1 -0.847 -0.866 1.302 1.00 0.00 H +ATOM 7 H21 ETH A 1 1.142 0.816 -0.043 1.00 0.00 H +ATOM 8 H22 ETH A 1 1.142 -0.816 -0.043 1.00 0.00 H +ATOM 9 OH ETH A 1 0.209 0.000 -1.977 1.00 0.00 H +END diff --git a/modules/mol/mm/examples/ethanol_example.py b/modules/mol/mm/examples/ethanol_example.py new file mode 100644 index 0000000000000000000000000000000000000000..f76253adcc377cbfd9102c2e0a44a057da2069ae --- /dev/null +++ b/modules/mol/mm/examples/ethanol_example.py @@ -0,0 +1,198 @@ +from ost.mol.mm import * +from PyQt4 import QtCore + +class Anim(QtCore.QTimer): + def __init__(self,sim,go): + QtCore.QTimer.__init__(self) + self.ent=sim.GetEntity() + self.sim=sim + self.go = go + self.ed = ent.EditXCS() + QtCore.QObject.connect(self, QtCore.SIGNAL("timeout()"), self.OnTimer) + + + def OnTimer(self): + self.sim.Steps(1) + positions = sim.GetPositions() + for a, pos in zip(self.ent.atoms,positions): + self.ed.SetAtomPos(a,pos) + self.go.UpdatePositions() + + +#Let's create an ethanol without its hydrogens +ent = ost.mol.CreateEntity() +ed = ent.EditXCS() +chain = ed.InsertChain('A') +res = ed.AppendResidue(chain,"ETH") +c1 = ed.InsertAtom(res,"C1",geom.Vec3(-0.246,0.0,1.285),"C") +c2 = ed.InsertAtom(res,"C2",geom.Vec3(0.566,0.0,-0.011),"C") +o = ed.InsertAtom(res,"O",geom.Vec3(-0.322,0.0,-1.130),"O") +ed.Connect(c1,c2) +ed.Connect(c2,o) + + +ff = Forcefield() + +#generate hydrogen constructor and add it to the forcefield +h_constructor = GromacsHydrogenConstructor() +h_constructor.AddHydrogenRule(3,4,["H11","H12","H13"],["C1","C2","O"]) +h_constructor.AddHydrogenRule(2,6,["H21","H22"],["C2","O","C1"]) +h_constructor.AddHydrogenRule(1,2,["OH"],["O","C2","C1"]) +ff.AddHydrogenConstructor("ETH",h_constructor) + +#generate buildingblock and add it to the forcefield +building_block = BuildingBlock() +building_block.AddAtom("C1","C",-0.18) +building_block.AddAtom("C2","C",0.145) +building_block.AddAtom("O","O",-0.683) +building_block.AddAtom("H11","H",0.06) +building_block.AddAtom("H12","H",0.06) +building_block.AddAtom("H13","H",0.06) +building_block.AddAtom("H21","H",0.06) +building_block.AddAtom("H22","H",0.06) +building_block.AddAtom("OH","OH",0.418) + +bonds = list() +for i in range(8): + bonds.append(MMInteraction(FuncType.HarmonicBond)) + +bonds[0].SetNames(["H11","C1"]) +bonds[1].SetNames(["H12","C1"]) +bonds[2].SetNames(["H13","C1"]) +bonds[3].SetNames(["C1","C2"]) +bonds[4].SetNames(["C2","H21"]) +bonds[5].SetNames(["C2","H22"]) +bonds[6].SetNames(["O","C2"]) +bonds[7].SetNames(["O","OH"]) + +for b in bonds: + building_block.AddBond(b) + +ff.AddBuildingBlock("ETH",building_block) + +#add masses to the forcefield +ff.AddMass("C",12.011) +ff.AddMass("O",15.999) +ff.AddMass("H",1.008) +ff.AddMass("OH",1.008) + +#generate bonds and add them to the forcefield +h_c_bond = MMInteraction(FuncType.HarmonicBond) +c_c_bond = MMInteraction(FuncType.HarmonicBond) +c_o_bond = MMInteraction(FuncType.HarmonicBond) +o_h_bond = MMInteraction(FuncType.HarmonicBond) + +h_c_bond.SetTypes(["H","C"]) +c_c_bond.SetTypes(["C","C"]) +c_o_bond.SetTypes(["C","O"]) +o_h_bond.SetTypes(["O","OH"]) + +h_c_bond.SetParam([0.1111,269449.6]) +c_c_bond.SetParam([0.153,186188.0]) +c_o_bond.SetParam([0.142,358150.4]) +o_h_bond.SetParam([0.096,456056.0]) + +ff.AddBond(h_c_bond) +ff.AddBond(c_c_bond) +ff.AddBond(c_o_bond) +ff.AddBond(o_h_bond) + +#generate angles and add them to the forcefield +h_c_h_angle = MMInteraction(FuncType.UreyBradleyAngle) +h_c_c_angle = MMInteraction(FuncType.UreyBradleyAngle) +h_c_o_angle = MMInteraction(FuncType.UreyBradleyAngle) +c_c_o_angle = MMInteraction(FuncType.UreyBradleyAngle) +c_o_h_angle = MMInteraction(FuncType.UreyBradleyAngle) + +h_c_h_angle.SetTypes(["H","C","H"]) +h_c_c_angle.SetTypes(["H","C","C"]) +h_c_o_angle.SetTypes(["H","C","O"]) +c_c_o_angle.SetTypes(["C","C","O"]) +c_o_h_angle.SetTypes(["C","O","OH"]) + +h_c_h_angle.SetParam([1.892,297.064,0.1802,4518.72]) +h_c_c_angle.SetParam([1.922,289.5328,0.2179,18853.104]) +h_c_o_angle.SetParam([1.900,384.0912,0.0,0.0]) +c_c_o_angle.SetParam([1.920,633.4576,0.0,0.0]) +c_o_h_angle.SetParam([1.850,481.16,0.0,0.0]) + +ff.AddAngle(h_c_h_angle) +ff.AddAngle(h_c_c_angle) +ff.AddAngle(h_c_o_angle) +ff.AddAngle(c_c_o_angle) +ff.AddAngle(c_o_h_angle) + +#generate dihedrals and add them to the forcefield +x_c_c_x_dihedral = MMInteraction(FuncType.PeriodicDihedral) +c_c_o_h_dihedral_one = MMInteraction(FuncType.PeriodicDihedral) +c_c_o_h_dihedral_two = MMInteraction(FuncType.PeriodicDihedral) +c_c_o_h_dihedral_three = MMInteraction(FuncType.PeriodicDihedral) +x_c_o_x_dihedral = MMInteraction(FuncType.PeriodicDihedral) + +x_c_c_x_dihedral.SetTypes(["X","C","C","X"]) +c_c_o_h_dihedral_one.SetTypes(["C","C","O","OH"]) +c_c_o_h_dihedral_two.SetTypes(["C","C","O","OH"]) +c_c_o_h_dihedral_three.SetTypes(["C","C","O","OH"]) +x_c_o_x_dihedral.SetTypes(["X","C","O","X"]) + +x_c_c_x_dihedral.SetParam([3,0.0,0.66944]) +c_c_o_h_dihedral_one.SetParam([1,0.0,5.4392]) +c_c_o_h_dihedral_two.SetParam([2,0.0,1.2552]) +c_c_o_h_dihedral_three.SetParam([3,0.0,1.75728]) +x_c_o_x_dihedral.SetParam([3,0.0,0.58576]) + +ff.AddDihedral(x_c_c_x_dihedral) +ff.AddDihedral(c_c_o_h_dihedral_one) +ff.AddDihedral(c_c_o_h_dihedral_two) +ff.AddDihedral(c_c_o_h_dihedral_three) +ff.AddDihedral(x_c_o_x_dihedral) + +#add lj parameters +c_lj = MMInteraction(FuncType.LJ) +o_lj = MMInteraction(FuncType.LJ) +h_lj = MMInteraction(FuncType.LJ) +oh_lj = MMInteraction(FuncType.LJ) + +c_lj.SetTypes(["C"]) +o_lj.SetTypes(["O"]) +h_lj.SetTypes(["H"]) +oh_lj.SetTypes(["OH"]) + +c_lj.SetParam([0.37,0.28]) +o_lj.SetParam([0.32,0.64]) +h_lj.SetParam([0.24,0.09]) +oh_lj.SetParam([0.04,0.2]) + +ff.AddLJ(c_lj) +ff.AddLJ(o_lj) +ff.AddLJ(h_lj) +ff.AddLJ(oh_lj) + +#we do not explicitely set the 1,4 interactions, +#we rather decrease it by a certain factor +ff.SetFudgeLJ(0.5) +ff.SetFudgeQQ(0.5) + +#construct settings +settings = MMSettings() +settings.init_temperature = 310 +settings.forcefield = ff + +#construct integrator with tiny timesteps +settings.integrator = VerletIntegrator(0.0001) + + +#create the simulation +sim = Simulation(ent,settings) + +io.SavePDB(sim.GetEntity(),'ethanol.pdb') + + +go = gfx.Entity("ethanol",sim.GetEntity()) +go.SetRenderMode(gfx.CUSTOM) +scene.Add(go) + +anim = Anim(sim,go) +anim.start(2) + + diff --git a/modules/mol/mm/examples/ethanol_example_using_topology.py b/modules/mol/mm/examples/ethanol_example_using_topology.py new file mode 100644 index 0000000000000000000000000000000000000000..8cca033a9eba699b4558c013f20822d97aef721a --- /dev/null +++ b/modules/mol/mm/examples/ethanol_example_using_topology.py @@ -0,0 +1,155 @@ +from ost.mol.mm import * +from PyQt4 import QtCore +from math import sqrt +from math import sin + +class Anim(QtCore.QTimer): + def __init__(self,sim,go,cc_bond_index): + QtCore.QTimer.__init__(self) + self.ent=sim.GetEntity() + self.sim=sim + self.go = go + self.ed = ent.EditXCS() + self.bond_index = cc_bond_index + top = sim.GetTopology() + param = top.GetHarmonicBondParameters(cc_bond_index) + self.bond_length = param[2] + self.force_constant = param[3] + self.steps = 0 + self.counter = 0 + QtCore.QObject.connect(self, QtCore.SIGNAL("timeout()"), self.OnTimer) + + def OnTimer(self): + if self.steps % 20 == 0: + sim.ResetHarmonicBond(self.bond_index,sin(self.counter*3.1416/100)*self.bond_length*0.75 + self.bond_length,self.force_constant) + self.counter += 1 + + self.sim.Steps(1) + positions = sim.GetPositions() + for a, pos in zip(self.ent.atoms,positions): + self.ed.SetAtomPos(a,pos) + self.go.UpdatePositions() + self.steps+=1 + + +#create topology by only defining masses + +prof = io.IOProfile(dialect='PDB', fault_tolerant=False, + quack_mode=False, processor=conop.HeuristicProcessor()) + +ent = io.LoadPDB('ethanol.pdb', profile=prof) +masses = [12.011,12.011,15.999,1.008,1.008,1.008,1.008,1.008,1.008] +top = Topology(ent,masses) + +#all per atom parameters have to be set at once... +charges = [-0.18,0.145,-0.683,0.06,0.06,0.06,0.06,0.06,0.418] +sigmas = [0.37,0.37,0.32,0.24,0.24,0.24,0.24,0.24,0.04] +epsilons = [0.28,0.28,0.64,0.09,0.09,0.09,0.09,0.09,0.2] + +top.SetCharges(charges) +top.SetSigmas(sigmas) +top.SetEpsilons(epsilons) + +#we can set the fudge parameters for 1,4 interactions also in the topology +top.SetFudgeQQ(0.5) +top.SetFudgeLJ(0.5) + +#add the bonds +top.AddHarmonicBond(0,1,0.153,186188.0) #C-C +top.AddHarmonicBond(0,3,0.1111,269449.6) #C-H +top.AddHarmonicBond(0,4,0.1111,269449.6) #C-H +top.AddHarmonicBond(0,5,0.1111,269449.6) #C-H +top.AddHarmonicBond(1,6,0.1111,269449.6) #C-H +top.AddHarmonicBond(1,7,0.1111,269449.6) #C-H +top.AddHarmonicBond(1,2,0.142,358150.4) #C-O +top.AddHarmonicBond(2,8,0.096,456056.0) #O-H + +#add the angles +top.AddUreyBradleyAngle(3,0,4,1.892,297.064,0.1802,4518.72) #H-C-H +top.AddUreyBradleyAngle(3,0,5,1.892,297.064,0.1802,4518.72) #H-C-H +top.AddUreyBradleyAngle(4,0,5,1.892,297.064,0.1802,4518.72) #H-C-H +top.AddUreyBradleyAngle(3,0,1,1.922,289.5328,0.2179,18853.104) #H-C-C +top.AddUreyBradleyAngle(4,0,1,1.922,289.5328,0.2179,18853.104) #H-C-C +top.AddUreyBradleyAngle(5,0,1,1.922,289.5328,0.2179,18853.104) #H-C-C +top.AddUreyBradleyAngle(0,1,6,1.922,289.5328,0.2179,18853.104) #H-C-C +top.AddUreyBradleyAngle(0,1,7,1.922,289.5328,0.2179,18853.104) #H-C-C +top.AddUreyBradleyAngle(0,1,2,1.920,633.4576,0.0,0.0) #C-C-O +top.AddUreyBradleyAngle(6,1,2,1.900,384.0912,0.0,0.0) #H-C-O +top.AddUreyBradleyAngle(7,1,2,1.900,384.0912,0.0,0.0) #H-C-O +top.AddUreyBradleyAngle(6,1,7,1.892,297.064,0.1802,4518.72) #H-C-H +top.AddUreyBradleyAngle(1,2,8,1.850,481.16,0.0,0.0) #C-O-H + + +#add the dihedrals +top.AddPeriodicDihedral(3,0,1,6,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(3,0,1,7,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(3,0,1,2,3,0.0,0.66944) #H-C-C-O +top.AddPeriodicDihedral(4,0,1,6,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(4,0,1,7,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(4,0,1,2,3,0.0,0.66944) #H-C-C-O +top.AddPeriodicDihedral(5,0,1,6,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(5,0,1,7,3,0.0,0.66944) #H-C-C-H +top.AddPeriodicDihedral(5,0,1,2,3,0.0,0.66944) #H-C-C-O +top.AddPeriodicDihedral(6,1,2,8,3,0.0,0.58576) #H-C-O-H +top.AddPeriodicDihedral(7,1,2,8,3,0.0,0.58576) #H-C-O-H +top.AddPeriodicDihedral(0,1,2,8,1,0.0,5.4392) #C-C-O-H +top.AddPeriodicDihedral(0,1,2,8,2,0.0,1.2552) #C-C-O-H +top.AddPeriodicDihedral(0,1,2,8,3,0.0,1.75728) #C-C-O-H + +#we have to manually set the exclusions for the nonbonded interaction... + +#1,2 interactions +top.AddExclusion(3,0) +top.AddExclusion(4,0) +top.AddExclusion(5,0) +top.AddExclusion(0,1) +top.AddExclusion(1,6) +top.AddExclusion(1,7) +top.AddExclusion(1,2) +top.AddExclusion(2,8) + +#1,3 interactions +top.AddExclusion(3,4) +top.AddExclusion(3,5) +top.AddExclusion(4,5) +top.AddExclusion(3,1) +top.AddExclusion(4,1) +top.AddExclusion(5,1) +top.AddExclusion(0,6) +top.AddExclusion(0,7) +top.AddExclusion(0,2) +top.AddExclusion(6,2) +top.AddExclusion(7,2) +top.AddExclusion(1,8) + +#add lj-pairs, note, that the fudge parameters still get applied during system setup +top.AddLJPair(3,6,0.5*(sigmas[3]+sigmas[6]),sqrt(epsilons[3]*epsilons[6])) +top.AddLJPair(3,7,0.5*(sigmas[3]+sigmas[7]),sqrt(epsilons[3]*epsilons[7])) +top.AddLJPair(3,2,0.5*(sigmas[3]+sigmas[2]),sqrt(epsilons[3]*epsilons[2])) +top.AddLJPair(4,6,0.5*(sigmas[4]+sigmas[6]),sqrt(epsilons[4]*epsilons[6])) +top.AddLJPair(4,7,0.5*(sigmas[4]+sigmas[7]),sqrt(epsilons[4]*epsilons[7])) +top.AddLJPair(4,2,0.5*(sigmas[4]+sigmas[2]),sqrt(epsilons[4]*epsilons[2])) +top.AddLJPair(5,6,0.5*(sigmas[5]+sigmas[6]),sqrt(epsilons[5]*epsilons[6])) +top.AddLJPair(5,7,0.5*(sigmas[5]+sigmas[7]),sqrt(epsilons[5]*epsilons[7])) +top.AddLJPair(5,2,0.5*(sigmas[5]+sigmas[2]),sqrt(epsilons[5]*epsilons[2])) +top.AddLJPair(6,8,0.5*(sigmas[6]+sigmas[8]),sqrt(epsilons[6]*epsilons[8])) +top.AddLJPair(7,8,0.5*(sigmas[7]+sigmas[8]),sqrt(epsilons[7]*epsilons[8])) +top.AddLJPair(0,8,0.5*(sigmas[0]+sigmas[8]),sqrt(epsilons[0]*epsilons[8])) + +settings = MMSettings() +settings.init_temperature = 310 +settings.integrator = VerletIntegrator(0.0001) + +#let's extract the cc_bond_index to have some fun with it +cc_bond_index = top.GetHarmonicBondIndices(0,1)[0] + +#create the simulation +sim = Simulation(top,settings) +go = gfx.Entity("ethanol",sim.GetEntity()) +go.SetRenderMode(gfx.CUSTOM) +scene.Add(go) + +anim = Anim(sim,go,cc_bond_index) +anim.start(2) + + diff --git a/modules/mol/mm/examples/gb_example.py b/modules/mol/mm/examples/gb_example.py new file mode 100644 index 0000000000000000000000000000000000000000..61a563e2e8d7621d147832e94c11a38943266cef --- /dev/null +++ b/modules/mol/mm/examples/gb_example.py @@ -0,0 +1,51 @@ +from ost.mol import mm +from PyQt4 import QtCore + +class Anim(QtCore.QTimer): + def __init__(self,sim,ent,go): + QtCore.QTimer.__init__(self) + self.ent=ent + self.sim=sim + self.go = go + self.ed = ent.EditXCS(ost.mol.BUFFERED_EDIT) + QtCore.QObject.connect(self, QtCore.SIGNAL("timeout()"), self.OnTimer) + + + def OnTimer(self): + self.sim.Steps(5) + positions = sim.GetPositions() + for a, pos in zip(self.ent.atoms,positions): + self.ed.SetAtomPos(a,pos) + self.ed.UpdateICS() + self.go.UpdatePositions() + + +prot=ost.mol.CreateEntityFromView(io.LoadPDB('1CRN.pdb').Select('peptide=true'),True) + +settings = mm.MMSettings() + +settings.integrator = mm.LangevinIntegrator(310,1,0.002) +settings.constrain_bonds = True +settings.constrain_hbonds = True +settings.constrain_hangles = True +#settings.add_gbsa = True +#settings.add_thermostat = True +#settings.thermostat_temperature = 310.0 +#settings.thermostat_collision_frequency = 1 +settings.init_temperature = 0 +settings.forcefield = mm.LoadCHARMMForcefield() +settings.platform = mm.Platform.CPU +#settings.nonbonded_cutoff = 10.0 +settings.nonbonded_method = mm.NonbondedMethod.CutoffNonPeriodic + +sim = mm.Simulation(prot,settings) +sim.MinimizeEnergy(type = "lbfgs",tolerance = 1.0, max_iterations = 200) +sim.UpdateTopologyPositions() + +ent = sim.GetEntity() +go = gfx.Entity("crambin",ent) +scene.Add(go) + +anim = Anim(sim,ent,go) +anim.start(1) + diff --git a/modules/mol/mm/examples/gb_example_traj.dcd b/modules/mol/mm/examples/gb_example_traj.dcd new file mode 100644 index 0000000000000000000000000000000000000000..913d8d33f5f4f0a55f44002966ec332007c7dffe Binary files /dev/null and b/modules/mol/mm/examples/gb_example_traj.dcd differ diff --git a/modules/mol/mm/examples/gb_example_traj.pdb b/modules/mol/mm/examples/gb_example_traj.pdb new file mode 100644 index 0000000000000000000000000000000000000000..afb415a36cb19b045dff9136144b7355face8c46 --- /dev/null +++ b/modules/mol/mm/examples/gb_example_traj.pdb @@ -0,0 +1,643 @@ +ATOM 1 N THR 1 17.047 14.099 3.625 1.00 13.79 A N +ATOM 2 CA THR 1 16.967 12.784 4.338 1.00 10.80 A C +ATOM 3 C THR 1 15.685 12.755 5.133 1.00 9.19 A C +ATOM 4 O THR 1 15.268 13.825 5.594 1.00 9.85 A O +ATOM 5 CB THR 1 18.170 12.703 5.337 1.00 13.02 A C +ATOM 6 OG1 THR 1 19.334 12.829 4.463 1.00 15.06 A O +ATOM 7 CG2 THR 1 18.150 11.546 6.304 1.00 14.23 A C +ATOM 8 HA THR 1 16.993 12.024 3.689 1.00 0.00 A H +ATOM 9 HB THR 1 18.153 13.430 6.024 1.00 0.00 A H +ATOM 10 HG1 THR 1 20.169 12.789 5.012 1.00 0.00 A H +ATOM 11 HG21 THR 1 18.958 11.589 6.892 1.00 0.00 A H +ATOM 12 HG22 THR 1 17.275 11.615 6.888 1.00 0.00 A H +ATOM 13 HG23 THR 1 18.155 10.649 5.751 1.00 0.00 A H +ATOM 14 H1 THR 1 17.892 14.138 3.091 1.00 0.00 A H +ATOM 15 H2 THR 1 16.213 14.183 2.986 1.00 0.00 A H +ATOM 16 H3 THR 1 17.040 14.869 4.345 1.00 0.00 A H +ATOM 17 N THR 2 15.115 11.555 5.265 1.00 7.81 A N +ATOM 18 CA THR 2 13.856 11.469 6.066 1.00 8.31 A C +ATOM 19 C THR 2 14.164 10.785 7.379 1.00 5.80 A C +ATOM 20 O THR 2 14.993 9.862 7.443 1.00 6.94 A O +ATOM 21 CB THR 2 12.732 10.711 5.261 1.00 10.32 A C +ATOM 22 OG1 THR 2 13.308 9.439 4.926 1.00 12.81 A O +ATOM 23 CG2 THR 2 12.484 11.442 3.895 1.00 11.90 A C +ATOM 24 HN THR 2 15.516 10.742 4.843 1.00 0.00 A H +ATOM 25 HA THR 2 13.507 12.387 6.253 1.00 0.00 A H +ATOM 26 HB THR 2 11.884 10.657 5.788 1.00 0.00 A H +ATOM 27 HG1 THR 2 12.645 8.898 4.409 1.00 0.00 A H +ATOM 28 HG21 THR 2 11.771 10.961 3.384 1.00 0.00 A H +ATOM 29 HG22 THR 2 12.179 12.430 4.097 1.00 0.00 A H +ATOM 30 HG23 THR 2 13.384 11.439 3.347 1.00 0.00 A H +ATOM 31 N CYS2 3 13.488 11.241 8.417 1.00 5.24 A N +ATOM 32 CA CYS2 3 13.660 10.707 9.787 1.00 5.39 A C +ATOM 33 C CYS2 3 12.269 10.431 10.323 1.00 4.45 A C +ATOM 34 O CYS2 3 11.393 11.308 10.185 1.00 6.54 A O +ATOM 35 CB CYS2 3 14.368 11.748 10.691 1.00 5.99 A C +ATOM 36 SG CYS2 3 15.885 12.426 10.016 1.00 7.01 A S +ATOM 37 HN CYS2 3 12.830 11.980 8.271 1.00 0.00 A H +ATOM 38 HA CYS2 3 14.221 9.880 9.776 1.00 0.00 A H +ATOM 39 HB1 CYS2 3 13.733 12.504 10.850 1.00 0.00 A H +ATOM 40 HB2 CYS2 3 14.585 11.307 11.562 1.00 0.00 A H +ATOM 41 N CYS2 4 12.019 9.272 10.928 1.00 3.90 A N +ATOM 42 CA CYS2 4 10.646 8.991 11.408 1.00 4.24 A C +ATOM 43 C CYS2 4 10.654 8.793 12.919 1.00 3.72 A C +ATOM 44 O CYS2 4 11.659 8.296 13.491 1.00 5.30 A O +ATOM 45 CB CYS2 4 10.057 7.752 10.682 1.00 4.41 A C +ATOM 46 SG CYS2 4 9.837 8.018 8.904 1.00 4.72 A S +ATOM 47 HN CYS2 4 12.748 8.600 11.057 1.00 0.00 A H +ATOM 48 HA CYS2 4 10.060 9.774 11.196 1.00 0.00 A H +ATOM 49 HB1 CYS2 4 10.677 6.979 10.815 1.00 0.00 A H +ATOM 50 HB2 CYS2 4 9.167 7.538 11.085 1.00 0.00 A H +ATOM 51 N PRO 5 9.561 9.108 13.563 1.00 3.96 A N +ATOM 52 CA PRO 5 9.448 9.034 15.012 1.00 4.25 A C +ATOM 53 C PRO 5 9.288 7.670 15.606 1.00 4.96 A C +ATOM 54 O PRO 5 9.490 7.519 16.819 1.00 7.44 A O +ATOM 55 CB PRO 5 8.230 9.957 15.345 1.00 5.11 A C +ATOM 56 CG PRO 5 7.338 9.786 14.114 1.00 5.24 A C +ATOM 57 CD PRO 5 8.366 9.804 12.958 1.00 5.20 A C +ATOM 58 HA PRO 5 10.312 9.323 15.424 1.00 0.00 A H +ATOM 59 HB1 PRO 5 7.762 9.653 16.175 1.00 0.00 A H +ATOM 60 HB2 PRO 5 8.517 10.909 15.454 1.00 0.00 A H +ATOM 61 HG1 PRO 5 6.842 8.918 14.144 1.00 0.00 A H +ATOM 62 HG2 PRO 5 6.686 10.540 14.031 1.00 0.00 A H +ATOM 63 HD1 PRO 5 8.023 9.304 12.163 1.00 0.00 A H +ATOM 64 HD2 PRO 5 8.592 10.741 12.691 1.00 0.00 A H +ATOM 65 N SER 6 8.875 6.686 14.796 1.00 4.83 A N +ATOM 66 CA SER 6 8.673 5.314 15.279 1.00 4.45 A C +ATOM 67 C SER 6 8.753 4.376 14.083 1.00 4.99 A C +ATOM 68 O SER 6 8.726 4.858 12.923 1.00 4.61 A O +ATOM 69 CB SER 6 7.340 5.121 15.996 1.00 5.05 A C +ATOM 70 OG SER 6 6.274 5.220 15.031 1.00 6.39 A O +ATOM 71 HN SER 6 8.699 6.892 13.833 1.00 0.00 A H +ATOM 72 HA SER 6 9.386 5.114 15.951 1.00 0.00 A H +ATOM 73 HB1 SER 6 7.319 4.220 16.429 1.00 0.00 A H +ATOM 74 HB2 SER 6 7.228 5.829 16.694 1.00 0.00 A H +ATOM 75 HG1 SER 6 5.395 5.095 15.491 1.00 0.00 A H +ATOM 76 N ILE 7 8.881 3.075 14.358 1.00 4.94 A N +ATOM 77 CA ILE 7 8.912 2.083 13.258 1.00 6.33 A C +ATOM 78 C ILE 7 7.581 2.090 12.506 1.00 5.32 A C +ATOM 79 O ILE 7 7.670 2.031 11.245 1.00 6.85 A O +ATOM 80 CB ILE 7 9.207 0.677 13.924 1.00 8.43 A C +ATOM 81 CG1 ILE 7 10.714 0.702 14.312 1.00 9.78 A C +ATOM 82 CG2 ILE 7 8.811 -0.477 12.969 1.00 11.70 A C +ATOM 83 CD ILE 7 11.185 -0.516 15.142 1.00 9.92 A C +ATOM 84 HN ILE 7 8.956 2.770 15.307 1.00 0.00 A H +ATOM 85 HA ILE 7 9.620 2.297 12.585 1.00 0.00 A H +ATOM 86 HB ILE 7 8.659 0.511 14.744 1.00 0.00 A H +ATOM 87 HG11 ILE 7 11.253 0.733 13.470 1.00 0.00 A H +ATOM 88 HG12 ILE 7 10.885 1.529 14.847 1.00 0.00 A H +ATOM 89 HG21 ILE 7 9.005 -1.354 13.408 1.00 0.00 A H +ATOM 90 HG22 ILE 7 7.781 -0.398 12.761 1.00 0.00 A H +ATOM 91 HG23 ILE 7 9.375 -0.385 12.083 1.00 0.00 A H +ATOM 92 HD1 ILE 7 12.159 -0.422 15.348 1.00 0.00 A H +ATOM 93 HD2 ILE 7 10.629 -0.545 16.037 1.00 0.00 A H +ATOM 94 HD3 ILE 7 11.019 -1.389 14.576 1.00 0.00 A H +ATOM 95 N VAL 8 6.458 2.162 13.159 1.00 5.02 A N +ATOM 96 CA VAL 8 5.145 2.209 12.453 1.00 6.93 A C +ATOM 97 C VAL 8 5.115 3.379 11.461 1.00 5.39 A C +ATOM 98 O VAL 8 4.664 3.268 10.343 1.00 6.30 A O +ATOM 99 CB VAL 8 3.995 2.354 13.478 1.00 9.64 A C +ATOM 100 CG1 VAL 8 2.716 2.891 12.869 1.00 13.85 A C +ATOM 101 CG2 VAL 8 3.758 1.032 14.208 1.00 11.97 A C +ATOM 102 HN VAL 8 6.476 2.186 14.159 1.00 0.00 A H +ATOM 103 HA VAL 8 5.023 1.355 11.947 1.00 0.00 A H +ATOM 104 HB VAL 8 4.286 3.040 14.145 1.00 0.00 A H +ATOM 105 HG11 VAL 8 2.014 2.962 13.577 1.00 0.00 A H +ATOM 106 HG12 VAL 8 2.915 3.843 12.462 1.00 0.00 A H +ATOM 107 HG13 VAL 8 2.401 2.226 12.115 1.00 0.00 A H +ATOM 108 HG21 VAL 8 3.013 1.143 14.866 1.00 0.00 A H +ATOM 109 HG22 VAL 8 3.503 0.299 13.495 1.00 0.00 A H +ATOM 110 HG23 VAL 8 4.645 0.765 14.711 1.00 0.00 A H +ATOM 111 N ALA 9 5.606 4.546 11.941 1.00 3.73 A N +ATOM 112 CA ALA 9 5.598 5.767 11.082 1.00 3.56 A C +ATOM 113 C ALA 9 6.441 5.527 9.850 1.00 4.13 A C +ATOM 114 O ALA 9 6.052 5.933 8.744 1.00 4.36 A O +ATOM 115 CB ALA 9 6.022 6.977 11.891 1.00 4.80 A C +ATOM 116 HN ALA 9 5.974 4.590 12.870 1.00 0.00 A H +ATOM 117 HA ALA 9 4.672 5.963 10.759 1.00 0.00 A H +ATOM 118 HB1 ALA 9 6.013 7.788 11.307 1.00 0.00 A H +ATOM 119 HB2 ALA 9 5.343 7.100 12.688 1.00 0.00 A H +ATOM 120 HB3 ALA 9 6.996 6.808 12.258 1.00 0.00 A H +ATOM 121 N ARG 10 7.647 4.909 10.005 1.00 3.73 A N +ATOM 122 CA ARG 10 8.496 4.609 8.837 1.00 3.38 A C +ATOM 123 C ARG 10 7.798 3.609 7.876 1.00 3.47 A C +ATOM 124 O ARG 10 7.878 3.778 6.651 1.00 4.67 A O +ATOM 125 CB ARG 10 9.847 4.020 9.305 1.00 3.95 A C +ATOM 126 CG ARG 10 10.752 3.607 8.149 1.00 4.55 A C +ATOM 127 CD ARG 10 11.226 4.699 7.244 1.00 5.89 A C +ATOM 128 NE ARG 10 12.143 5.571 8.035 1.00 6.20 A N +ATOM 129 CZ ARG 10 12.758 6.609 7.443 1.00 7.52 A C +ATOM 130 NH1 ARG 10 12.539 6.932 6.158 1.00 10.68 A N +ATOM 131 NH2 ARG 10 13.601 7.322 8.202 1.00 9.48 A N +ATOM 132 HN ARG 10 7.959 4.656 10.921 1.00 0.00 A H +ATOM 133 HA ARG 10 8.654 5.464 8.342 1.00 0.00 A H +ATOM 134 HB1 ARG 10 10.323 4.710 9.851 1.00 0.00 A H +ATOM 135 HB2 ARG 10 9.665 3.215 9.870 1.00 0.00 A H +ATOM 136 HG1 ARG 10 11.560 3.165 8.539 1.00 0.00 A H +ATOM 137 HG2 ARG 10 10.248 2.948 7.591 1.00 0.00 A H +ATOM 138 HD1 ARG 10 11.715 4.308 6.464 1.00 0.00 A H +ATOM 139 HD2 ARG 10 10.447 5.232 6.915 1.00 0.00 A H +ATOM 140 HE ARG 10 12.300 5.383 9.005 1.00 0.00 A H +ATOM 141 HH11 ARG 10 11.900 6.393 5.609 1.00 0.00 A H +ATOM 142 HH12 ARG 10 13.015 7.711 5.750 1.00 0.00 A H +ATOM 143 HH21 ARG 10 13.746 7.071 9.159 1.00 0.00 A H +ATOM 144 HH22 ARG 10 14.085 8.105 7.811 1.00 0.00 A H +ATOM 145 N SER 11 7.186 2.582 8.445 1.00 5.19 A N +ATOM 146 CA SER 11 6.500 1.584 7.565 1.00 4.60 A C +ATOM 147 C SER 11 5.382 2.313 6.773 1.00 4.84 A C +ATOM 148 O SER 11 5.213 2.016 5.557 1.00 5.84 A O +ATOM 149 CB SER 11 5.908 0.462 8.400 1.00 5.91 A C +ATOM 150 OG SER 11 6.990 -0.272 9.012 1.00 8.38 A O +ATOM 151 HN SER 11 7.182 2.475 9.439 1.00 0.00 A H +ATOM 152 HA SER 11 7.160 1.182 6.930 1.00 0.00 A H +ATOM 153 HB1 SER 11 5.316 0.845 9.109 1.00 0.00 A H +ATOM 154 HB2 SER 11 5.374 -0.149 7.815 1.00 0.00 A H +ATOM 155 HG1 SER 11 6.617 -1.016 9.567 1.00 0.00 A H +ATOM 156 N ASN 12 4.648 3.182 7.446 1.00 3.54 A N +ATOM 157 CA ASN 12 3.545 3.935 6.751 1.00 4.57 A C +ATOM 158 C ASN 12 4.107 4.851 5.691 1.00 4.14 A C +ATOM 159 O ASN 12 3.536 5.001 4.617 1.00 5.52 A O +ATOM 160 CB ASN 12 2.663 4.677 7.748 1.00 6.42 A C +ATOM 161 CG ASN 12 1.802 3.735 8.610 1.00 8.25 A C +ATOM 162 OD1 ASN 12 1.567 2.613 8.165 1.00 12.72 A O +ATOM 163 ND2 ASN 12 1.394 4.252 9.767 1.00 9.92 A N +ATOM 164 HN ASN 12 4.825 3.339 8.417 1.00 0.00 A H +ATOM 165 HA ASN 12 2.957 3.271 6.289 1.00 0.00 A H +ATOM 166 HB1 ASN 12 3.250 5.215 8.353 1.00 0.00 A H +ATOM 167 HB2 ASN 12 2.056 5.289 7.242 1.00 0.00 A H +ATOM 168 HD21 ASN 12 1.651 5.186 10.016 1.00 0.00 A H +ATOM 169 HD22 ASN 12 0.830 3.707 10.387 1.00 0.00 A H +ATOM 170 N PHE 13 5.259 5.498 6.005 1.00 3.43 A N +ATOM 171 CA PHE 13 5.929 6.358 5.055 1.00 3.49 A C +ATOM 172 C PHE 13 6.304 5.578 3.799 1.00 3.40 A C +ATOM 173 O PHE 13 6.136 6.072 2.653 1.00 4.07 A O +ATOM 174 CB PHE 13 7.183 6.994 5.754 1.00 5.48 A C +ATOM 175 CG PHE 13 7.884 8.006 4.883 1.00 5.57 A C +ATOM 176 CD1 PHE 13 8.906 7.586 4.027 1.00 6.99 A C +ATOM 177 CD2 PHE 13 7.532 9.373 4.983 1.00 6.52 A C +ATOM 178 CE1 PHE 13 9.560 8.539 3.194 1.00 8.20 A C +ATOM 179 CE2 PHE 13 8.176 10.281 4.145 1.00 6.34 A C +ATOM 180 CZ PHE 13 9.141 9.845 3.292 1.00 6.84 A C +ATOM 181 HN PHE 13 5.654 5.377 6.916 1.00 0.00 A H +ATOM 182 HA PHE 13 5.319 7.094 4.762 1.00 0.00 A H +ATOM 183 HB1 PHE 13 6.885 7.447 6.595 1.00 0.00 A H +ATOM 184 HB2 PHE 13 7.828 6.264 5.979 1.00 0.00 A H +ATOM 185 HD1 PHE 13 9.176 6.624 3.999 1.00 0.00 A H +ATOM 186 HD2 PHE 13 6.840 9.679 5.637 1.00 0.00 A H +ATOM 187 HE1 PHE 13 10.291 8.270 2.566 1.00 0.00 A H +ATOM 188 HE2 PHE 13 7.929 11.250 4.171 1.00 0.00 A H +ATOM 189 HZ PHE 13 9.575 10.520 2.696 1.00 0.00 A H +ATOM 190 N ASN 14 6.900 4.390 3.989 1.00 3.64 A N +ATOM 191 CA ASN 14 7.331 3.607 2.791 1.00 4.31 A C +ATOM 192 C ASN 14 6.116 3.210 1.915 1.00 3.98 A C +ATOM 193 O ASN 14 6.240 3.144 0.684 1.00 6.22 A O +ATOM 194 CB ASN 14 8.145 2.404 3.240 1.00 5.81 A C +ATOM 195 CG ASN 14 9.555 2.856 3.730 1.00 6.82 A C +ATOM 196 OD1 ASN 14 10.013 3.895 3.323 1.00 9.43 A O +ATOM 197 ND2 ASN 14 10.120 1.956 4.539 1.00 8.21 A N +ATOM 198 HN ASN 14 7.052 4.037 4.912 1.00 0.00 A H +ATOM 199 HA ASN 14 7.915 4.177 2.213 1.00 0.00 A H +ATOM 200 HB1 ASN 14 7.668 1.944 3.988 1.00 0.00 A H +ATOM 201 HB2 ASN 14 8.250 1.772 2.472 1.00 0.00 A H +ATOM 202 HD21 ASN 14 9.635 1.110 4.762 1.00 0.00 A H +ATOM 203 HD22 ASN 14 11.028 2.128 4.922 1.00 0.00 A H +ATOM 204 N VAL 15 4.993 2.927 2.571 1.00 3.76 A N +ATOM 205 CA VAL 15 3.782 2.599 1.742 1.00 3.98 A C +ATOM 206 C VAL 15 3.296 3.871 1.004 1.00 3.80 A C +ATOM 207 O VAL 15 2.947 3.817 -0.189 1.00 4.85 A O +ATOM 208 CB VAL 15 2.698 1.953 2.608 1.00 4.71 A C +ATOM 209 CG1 VAL 15 1.384 1.826 1.806 1.00 6.67 A C +ATOM 210 CG2 VAL 15 3.174 0.533 3.005 1.00 6.26 A C +ATOM 211 HN VAL 15 4.956 2.932 3.570 1.00 0.00 A H +ATOM 212 HA VAL 15 4.019 1.925 1.042 1.00 0.00 A H +ATOM 213 HB VAL 15 2.537 2.517 3.418 1.00 0.00 A H +ATOM 214 HG11 VAL 15 0.683 1.403 2.380 1.00 0.00 A H +ATOM 215 HG12 VAL 15 1.077 2.791 1.514 1.00 0.00 A H +ATOM 216 HG13 VAL 15 1.567 1.225 0.959 1.00 0.00 A H +ATOM 217 HG21 VAL 15 2.477 0.094 3.572 1.00 0.00 A H +ATOM 218 HG22 VAL 15 3.326 -0.026 2.124 1.00 0.00 A H +ATOM 219 HG23 VAL 15 4.075 0.622 3.545 1.00 0.00 A H +ATOM 220 N CYS2 16 3.321 4.987 1.720 1.00 3.79 A N +ATOM 221 CA CYS2 16 2.890 6.285 1.126 1.00 3.54 A C +ATOM 222 C CYS2 16 3.687 6.597 -0.111 1.00 3.48 A C +ATOM 223 O CYS2 16 3.200 7.147 -1.103 1.00 4.63 A O +ATOM 224 CB CYS2 16 3.039 7.369 2.240 1.00 4.58 A C +ATOM 225 SG CYS2 16 2.559 9.014 1.649 1.00 5.66 A S +ATOM 226 HN CYS2 16 3.633 4.958 2.670 1.00 0.00 A H +ATOM 227 HA CYS2 16 1.937 6.253 0.824 1.00 0.00 A H +ATOM 228 HB1 CYS2 16 2.456 7.120 3.013 1.00 0.00 A H +ATOM 229 HB2 CYS2 16 3.993 7.398 2.538 1.00 0.00 A H +ATOM 230 N ARG 17 4.997 6.227 -0.100 1.00 3.99 A N +ATOM 231 CA ARG 17 5.895 6.489 -1.213 1.00 3.83 A C +ATOM 232 C ARG 17 5.738 5.560 -2.409 1.00 3.79 A C +ATOM 233 O ARG 17 6.228 5.901 -3.507 1.00 5.39 A O +ATOM 234 CB ARG 17 7.370 6.507 -0.731 1.00 4.11 A C +ATOM 235 CG ARG 17 7.717 7.687 0.206 1.00 4.69 A C +ATOM 236 CD ARG 17 7.949 8.947 -0.615 1.00 5.10 A C +ATOM 237 NE ARG 17 9.212 8.856 -1.337 1.00 4.71 A N +ATOM 238 CZ ARG 17 9.537 9.533 -2.431 1.00 5.28 A C +ATOM 239 NH1 ARG 17 8.659 10.350 -3.032 1.00 6.67 A N +ATOM 240 NH2 ARG 17 10.793 9.491 -2.899 1.00 6.41 A N +ATOM 241 HN ARG 17 5.356 5.756 0.706 1.00 0.00 A H +ATOM 242 HA ARG 17 5.629 7.392 -1.550 1.00 0.00 A H +ATOM 243 HB1 ARG 17 7.550 5.654 -0.241 1.00 0.00 A H +ATOM 244 HB2 ARG 17 7.962 6.561 -1.535 1.00 0.00 A H +ATOM 245 HG1 ARG 17 6.960 7.840 0.842 1.00 0.00 A H +ATOM 246 HG2 ARG 17 8.546 7.469 0.721 1.00 0.00 A H +ATOM 247 HD1 ARG 17 7.202 9.056 -1.270 1.00 0.00 A H +ATOM 248 HD2 ARG 17 7.975 9.738 -0.004 1.00 0.00 A H +ATOM 249 HE ARG 17 9.897 8.225 -0.974 1.00 0.00 A H +ATOM 250 HH11 ARG 17 7.739 10.458 -2.656 1.00 0.00 A H +ATOM 251 HH12 ARG 17 8.925 10.851 -3.856 1.00 0.00 A H +ATOM 252 HH21 ARG 17 11.486 8.949 -2.423 1.00 0.00 A H +ATOM 253 HH22 ARG 17 11.037 10.002 -3.724 1.00 0.00 A H +ATOM 254 N LEU 18 5.051 4.411 -2.204 1.00 4.70 A N +ATOM 255 CA LEU 18 4.933 3.431 -3.326 1.00 5.46 A C +ATOM 256 C LEU 18 4.397 4.014 -4.620 1.00 5.13 A C +ATOM 257 O LEU 18 4.988 3.755 -5.687 1.00 5.55 A O +ATOM 258 CB LEU 18 4.196 2.184 -2.863 1.00 6.47 A C +ATOM 259 CG LEU 18 4.960 1.178 -1.991 1.00 7.43 A C +ATOM 260 CD1 LEU 18 3.907 0.097 -1.634 1.00 8.70 A C +ATOM 261 CD2 LEU 18 6.129 0.606 -2.768 1.00 9.39 A C +ATOM 262 HN LEU 18 4.630 4.222 -1.317 1.00 0.00 A H +ATOM 263 HA LEU 18 5.863 3.161 -3.574 1.00 0.00 A H +ATOM 264 HB1 LEU 18 3.399 2.486 -2.340 1.00 0.00 A H +ATOM 265 HB2 LEU 18 3.892 1.697 -3.682 1.00 0.00 A H +ATOM 266 HG LEU 18 5.353 1.584 -1.166 1.00 0.00 A H +ATOM 267 HD11 LEU 18 4.330 -0.604 -1.060 1.00 0.00 A H +ATOM 268 HD12 LEU 18 3.117 0.561 -1.113 1.00 0.00 A H +ATOM 269 HD13 LEU 18 3.555 -0.334 -2.529 1.00 0.00 A H +ATOM 270 HD21 LEU 18 6.622 -0.048 -2.195 1.00 0.00 A H +ATOM 271 HD22 LEU 18 5.754 0.122 -3.626 1.00 0.00 A H +ATOM 272 HD23 LEU 18 6.768 1.399 -3.041 1.00 0.00 A H +ATOM 273 N PRO 19 3.329 4.795 -4.543 1.00 4.28 A N +ATOM 274 CA PRO 19 2.792 5.376 -5.797 1.00 5.38 A C +ATOM 275 C PRO 19 3.573 6.540 -6.322 1.00 6.30 A C +ATOM 276 O PRO 19 3.260 7.045 -7.422 1.00 9.62 A O +ATOM 277 CB PRO 19 1.358 5.766 -5.472 1.00 5.87 A C +ATOM 278 CG PRO 19 1.223 5.694 -3.993 1.00 6.47 A C +ATOM 279 CD PRO 19 2.421 4.941 -3.408 1.00 6.45 A C +ATOM 280 HA PRO 19 2.853 4.706 -6.537 1.00 0.00 A H +ATOM 281 HB1 PRO 19 1.173 6.696 -5.791 1.00 0.00 A H +ATOM 282 HB2 PRO 19 0.720 5.131 -5.908 1.00 0.00 A H +ATOM 283 HG1 PRO 19 1.194 6.619 -3.615 1.00 0.00 A H +ATOM 284 HG2 PRO 19 0.379 5.212 -3.758 1.00 0.00 A H +ATOM 285 HD1 PRO 19 2.850 5.468 -2.674 1.00 0.00 A H +ATOM 286 HD2 PRO 19 2.143 4.047 -3.057 1.00 0.00 A H +ATOM 287 N GLY 20 4.565 7.047 -5.559 1.00 4.94 A N +ATOM 288 CA GLY 20 5.366 8.191 -6.018 1.00 5.39 A C +ATOM 289 C GLY 20 5.007 9.481 -5.280 1.00 5.03 A C +ATOM 290 O GLY 20 5.535 10.510 -5.730 1.00 7.34 A O +ATOM 291 HN GLY 20 4.758 6.638 -4.667 1.00 0.00 A H +ATOM 292 HA1 GLY 20 6.333 7.990 -5.863 1.00 0.00 A H +ATOM 293 HA2 GLY 20 5.206 8.324 -6.996 1.00 0.00 A H +ATOM 294 N THR 21 4.181 9.438 -4.262 1.00 4.10 A N +ATOM 295 CA THR 21 3.767 10.609 -3.513 1.00 3.94 A C +ATOM 296 C THR 21 5.017 11.397 -3.042 1.00 3.96 A C +ATOM 297 O THR 21 5.947 10.757 -2.523 1.00 5.82 A O +ATOM 298 CB THR 21 2.992 10.188 -2.225 1.00 4.13 A C +ATOM 299 OG1 THR 21 2.051 9.144 -2.623 1.00 5.45 A O +ATOM 300 CG2 THR 21 2.260 11.349 -1.551 1.00 5.41 A C +ATOM 301 HN THR 21 3.816 8.548 -3.987 1.00 0.00 A H +ATOM 302 HA THR 21 3.187 11.164 -4.110 1.00 0.00 A H +ATOM 303 HB THR 21 3.644 9.861 -1.541 1.00 0.00 A H +ATOM 304 HG1 THR 21 1.530 8.842 -1.825 1.00 0.00 A H +ATOM 305 HG21 THR 21 1.786 11.016 -0.736 1.00 0.00 A H +ATOM 306 HG22 THR 21 2.971 12.079 -1.281 1.00 0.00 A H +ATOM 307 HG23 THR 21 1.564 11.747 -2.236 1.00 0.00 A H +ATOM 308 N PRO 22 4.971 12.703 -3.176 1.00 5.04 A N +ATOM 309 CA PRO 22 6.143 13.513 -2.696 1.00 4.69 A C +ATOM 310 C PRO 22 6.400 13.233 -1.225 1.00 4.19 A C +ATOM 311 O PRO 22 5.485 13.061 -0.382 1.00 4.47 A O +ATOM 312 CB PRO 22 5.703 14.969 -2.920 1.00 7.12 A C +ATOM 313 CG PRO 22 4.676 14.893 -3.996 1.00 7.03 A C +ATOM 314 CD PRO 22 3.964 13.567 -3.811 1.00 4.90 A C +ATOM 315 HA PRO 22 6.995 13.300 -3.174 1.00 0.00 A H +ATOM 316 HB1 PRO 22 5.310 15.351 -2.084 1.00 0.00 A H +ATOM 317 HB2 PRO 22 6.478 15.531 -3.211 1.00 0.00 A H +ATOM 318 HG1 PRO 22 4.027 15.649 -3.910 1.00 0.00 A H +ATOM 319 HG2 PRO 22 5.113 14.929 -4.895 1.00 0.00 A H +ATOM 320 HD1 PRO 22 3.164 13.673 -3.220 1.00 0.00 A H +ATOM 321 HD2 PRO 22 3.679 13.191 -4.693 1.00 0.00 A H +ATOM 322 N GLU 23 7.728 13.297 -0.921 1.00 5.16 A N +ATOM 323 CA GLU 23 8.114 13.103 0.500 1.00 5.31 A C +ATOM 324 C GLU 23 7.427 14.073 1.410 1.00 4.11 A C +ATOM 325 O GLU 23 7.036 13.682 2.540 1.00 5.11 A O +ATOM 326 CB GLU 23 9.648 13.285 0.660 1.00 6.16 A C +ATOM 327 CG GLU 23 10.440 12.093 0.063 1.00 7.48 A C +ATOM 328 CD GLU 23 11.941 12.170 0.391 1.00 9.40 A C +ATOM 329 OE1 GLU 23 12.416 13.225 0.681 1.00 10.40 A O +ATOM 330 OE2 GLU 23 12.539 11.070 0.292 1.00 13.32 A O +ATOM 331 HN GLU 23 8.415 13.468 -1.627 1.00 0.00 A H +ATOM 332 HA GLU 23 7.836 12.177 0.754 1.00 0.00 A H +ATOM 333 HB1 GLU 23 9.924 14.124 0.191 1.00 0.00 A H +ATOM 334 HB2 GLU 23 9.864 13.361 1.633 1.00 0.00 A H +ATOM 335 HG1 GLU 23 10.072 11.242 0.437 1.00 0.00 A H +ATOM 336 HG2 GLU 23 10.327 12.097 -0.931 1.00 0.00 A H +ATOM 337 N ALA 24 7.212 15.334 0.966 1.00 4.56 A N +ATOM 338 CA ALA 24 6.614 16.317 1.913 1.00 4.49 A C +ATOM 339 C ALA 24 5.212 15.936 2.350 1.00 4.10 A C +ATOM 340 O ALA 24 4.782 16.166 3.495 1.00 5.64 A O +ATOM 341 CB ALA 24 6.605 17.695 1.246 1.00 5.80 A C +ATOM 342 HN ALA 24 7.447 15.598 0.031 1.00 0.00 A H +ATOM 343 HA ALA 24 7.174 16.328 2.742 1.00 0.00 A H +ATOM 344 HB1 ALA 24 6.206 18.365 1.871 1.00 0.00 A H +ATOM 345 HB2 ALA 24 7.599 17.962 1.019 1.00 0.00 A H +ATOM 346 HB3 ALA 24 6.028 17.635 0.366 1.00 0.00 A H +ATOM 347 N ILE 25 4.445 15.318 1.405 1.00 4.37 A N +ATOM 348 CA ILE 25 3.074 14.894 1.756 1.00 5.44 A C +ATOM 349 C ILE 25 3.085 13.643 2.645 1.00 4.32 A C +ATOM 350 O ILE 25 2.315 13.523 3.578 1.00 4.72 A O +ATOM 351 CB ILE 25 2.204 14.637 0.462 1.00 6.42 A C +ATOM 352 CG1 ILE 25 1.815 16.048 -0.129 1.00 7.50 A C +ATOM 353 CG2 ILE 25 0.903 13.864 0.811 1.00 7.65 A C +ATOM 354 CD ILE 25 0.756 16.761 0.757 1.00 7.80 A C +ATOM 355 HN ILE 25 4.806 15.154 0.487 1.00 0.00 A H +ATOM 356 HA ILE 25 2.657 15.642 2.273 1.00 0.00 A H +ATOM 357 HB ILE 25 2.726 14.090 -0.193 1.00 0.00 A H +ATOM 358 HG11 ILE 25 2.635 16.618 -0.178 1.00 0.00 A H +ATOM 359 HG12 ILE 25 1.440 15.924 -1.048 1.00 0.00 A H +ATOM 360 HG21 ILE 25 0.371 13.714 -0.022 1.00 0.00 A H +ATOM 361 HG22 ILE 25 1.170 12.939 1.240 1.00 0.00 A H +ATOM 362 HG23 ILE 25 0.346 14.441 1.495 1.00 0.00 A H +ATOM 363 HD1 ILE 25 0.531 17.650 0.357 1.00 0.00 A H +ATOM 364 HD2 ILE 25 -0.106 16.156 0.798 1.00 0.00 A H +ATOM 365 HD3 ILE 25 1.162 16.892 1.721 1.00 0.00 A H +ATOM 366 N CYS2 26 4.032 12.764 2.313 1.00 3.92 A N +ATOM 367 CA CYS2 26 4.180 11.549 3.187 1.00 4.37 A C +ATOM 368 C CYS2 26 4.632 11.944 4.596 1.00 3.95 A C +ATOM 369 O CYS2 26 4.227 11.252 5.547 1.00 4.74 A O +ATOM 370 CB CYS2 26 5.038 10.518 2.539 1.00 4.63 A C +ATOM 371 SG CYS2 26 4.349 9.794 1.022 1.00 5.61 A S +ATOM 372 HN CYS2 26 4.619 12.907 1.516 1.00 0.00 A H +ATOM 373 HA CYS2 26 3.285 11.116 3.298 1.00 0.00 A H +ATOM 374 HB1 CYS2 26 5.914 10.942 2.311 1.00 0.00 A H +ATOM 375 HB2 CYS2 26 5.186 9.779 3.196 1.00 0.00 A H +ATOM 376 N ALA 27 5.408 13.012 4.694 1.00 3.89 A N +ATOM 377 CA ALA 27 5.879 13.502 6.026 1.00 4.43 A C +ATOM 378 C ALA 27 4.696 13.908 6.882 1.00 4.26 A C +ATOM 379 O ALA 27 4.528 13.422 8.025 1.00 5.44 A O +ATOM 380 CB ALA 27 6.880 14.615 5.830 1.00 5.36 A C +ATOM 381 HN ALA 27 5.683 13.498 3.865 1.00 0.00 A H +ATOM 382 HA ALA 27 6.347 12.769 6.519 1.00 0.00 A H +ATOM 383 HB1 ALA 27 7.194 14.942 6.721 1.00 0.00 A H +ATOM 384 HB2 ALA 27 7.694 14.237 5.277 1.00 0.00 A H +ATOM 385 HB3 ALA 27 6.409 15.398 5.305 1.00 0.00 A H +ATOM 386 N THR 28 3.827 14.802 6.358 1.00 4.53 A N +ATOM 387 CA THR 28 2.691 15.221 7.194 1.00 5.08 A C +ATOM 388 C THR 28 1.672 14.132 7.434 1.00 4.62 A C +ATOM 389 O THR 28 0.947 14.112 8.468 1.00 7.80 A O +ATOM 390 CB THR 28 1.986 16.520 6.614 1.00 6.03 A C +ATOM 391 OG1 THR 28 1.664 16.221 5.230 1.00 7.19 A O +ATOM 392 CG2 THR 28 2.914 17.739 6.700 1.00 7.34 A C +ATOM 393 HN THR 28 3.952 15.165 5.435 1.00 0.00 A H +ATOM 394 HA THR 28 3.090 15.437 8.085 1.00 0.00 A H +ATOM 395 HB THR 28 1.167 16.747 7.141 1.00 0.00 A H +ATOM 396 HG1 THR 28 1.215 17.011 4.814 1.00 0.00 A H +ATOM 397 HG21 THR 28 2.446 18.541 6.329 1.00 0.00 A H +ATOM 398 HG22 THR 28 3.159 17.901 7.712 1.00 0.00 A H +ATOM 399 HG23 THR 28 3.783 17.537 6.138 1.00 0.00 A H +ATOM 400 N TYR 29 1.621 13.190 6.511 1.00 5.01 A N +ATOM 401 CA TYR 29 0.715 12.045 6.657 1.00 6.60 A C +ATOM 402 C TYR 29 1.125 11.125 7.815 1.00 4.92 A C +ATOM 403 O TYR 29 0.286 10.632 8.545 1.00 7.13 A O +ATOM 404 CB TYR 29 0.755 11.229 5.322 1.00 9.66 A C +ATOM 405 CG TYR 29 -0.203 10.044 5.354 1.00 11.56 A C +ATOM 406 CD1 TYR 29 -1.547 10.337 5.645 1.00 12.85 A C +ATOM 407 CD2 TYR 29 0.193 8.750 5.100 1.00 14.44 A C +ATOM 408 CE1 TYR 29 -2.496 9.329 5.673 1.00 16.61 A C +ATOM 409 CE2 TYR 29 -0.801 7.705 5.156 1.00 17.11 A C +ATOM 410 CZ TYR 29 -2.079 8.031 5.430 1.00 19.99 A C +ATOM 411 OH TYR 29 -3.097 7.057 5.458 1.00 28.98 A O +ATOM 412 HN TYR 29 2.206 13.257 5.703 1.00 0.00 A H +ATOM 413 HA TYR 29 -0.203 12.388 6.857 1.00 0.00 A H +ATOM 414 HB1 TYR 29 0.499 11.832 4.566 1.00 0.00 A H +ATOM 415 HB2 TYR 29 1.685 10.890 5.178 1.00 0.00 A H +ATOM 416 HD1 TYR 29 -1.820 11.281 5.833 1.00 0.00 A H +ATOM 417 HD2 TYR 29 1.146 8.539 4.882 1.00 0.00 A H +ATOM 418 HE1 TYR 29 -3.456 9.533 5.864 1.00 0.00 A H +ATOM 419 HE2 TYR 29 -0.545 6.752 4.994 1.00 0.00 A H +ATOM 420 HH TYR 29 -2.703 6.157 5.273 1.00 0.00 A H +ATOM 421 N THR 30 2.470 10.984 7.995 1.00 5.31 A N +ATOM 422 CA THR 30 2.986 9.994 8.950 1.00 5.70 A C +ATOM 423 C THR 30 3.609 10.505 10.230 1.00 6.28 A C +ATOM 424 O THR 30 3.766 9.715 11.186 1.00 8.77 A O +ATOM 425 CB THR 30 4.076 9.103 8.225 1.00 6.55 A C +ATOM 426 OG1 THR 30 5.125 10.027 7.824 1.00 6.57 A O +ATOM 427 CG2 THR 30 3.493 8.324 7.035 1.00 7.29 A C +ATOM 428 HN THR 30 3.106 11.555 7.476 1.00 0.00 A H +ATOM 429 HA THR 30 2.164 9.501 9.237 1.00 0.00 A H +ATOM 430 HB THR 30 4.432 8.393 8.833 1.00 0.00 A H +ATOM 431 HG1 THR 30 5.852 9.524 7.356 1.00 0.00 A H +ATOM 432 HG21 THR 30 4.214 7.777 6.609 1.00 0.00 A H +ATOM 433 HG22 THR 30 2.727 7.694 7.392 1.00 0.00 A H +ATOM 434 HG23 THR 30 3.108 9.016 6.340 1.00 0.00 A H +ATOM 435 N GLY 31 3.984 11.764 10.241 1.00 4.99 A N +ATOM 436 CA GLY 31 4.769 12.336 11.360 1.00 5.50 A C +ATOM 437 C GLY 31 6.255 12.243 11.106 1.00 4.19 A C +ATOM 438 O GLY 31 7.037 12.750 11.954 1.00 6.12 A O +ATOM 439 HN GLY 31 3.733 12.353 9.473 1.00 0.00 A H +ATOM 440 HA1 GLY 31 4.519 13.298 11.473 1.00 0.00 A H +ATOM 441 HA2 GLY 31 4.552 11.835 12.198 1.00 0.00 A H +ATOM 442 N CYS2 32 6.710 11.631 9.992 1.00 4.30 A N +ATOM 443 CA CYS2 32 8.140 11.694 9.635 1.00 4.89 A C +ATOM 444 C CYS2 32 8.500 13.141 9.206 1.00 5.50 A C +ATOM 445 O CYS2 32 7.581 13.949 8.944 1.00 5.82 A O +ATOM 446 CB CYS2 32 8.504 10.686 8.530 1.00 4.66 A C +ATOM 447 SG CYS2 32 8.048 8.987 8.881 1.00 5.33 A S +ATOM 448 HN CYS2 32 6.073 11.131 9.405 1.00 0.00 A H +ATOM 449 HA CYS2 32 8.676 11.442 10.441 1.00 0.00 A H +ATOM 450 HB1 CYS2 32 8.040 10.965 7.689 1.00 0.00 A H +ATOM 451 HB2 CYS2 32 9.494 10.720 8.392 1.00 0.00 A H +ATOM 452 N ILE 33 9.793 13.410 9.173 1.00 6.02 A N +ATOM 453 CA ILE 33 10.280 14.760 8.823 1.00 5.24 A C +ATOM 454 C ILE 33 11.346 14.658 7.743 1.00 5.16 A C +ATOM 455 O ILE 33 11.971 13.583 7.552 1.00 7.19 A O +ATOM 456 CB ILE 33 10.790 15.535 10.085 1.00 5.49 A C +ATOM 457 CG1 ILE 33 12.059 14.803 10.671 1.00 6.85 A C +ATOM 458 CG2 ILE 33 9.684 15.686 11.138 1.00 6.45 A C +ATOM 459 CD ILE 33 12.733 15.676 11.781 1.00 8.94 A C +ATOM 460 HN ILE 33 10.452 12.689 9.388 1.00 0.00 A H +ATOM 461 HA ILE 33 9.516 15.293 8.459 1.00 0.00 A H +ATOM 462 HB ILE 33 11.051 16.462 9.814 1.00 0.00 A H +ATOM 463 HG11 ILE 33 11.781 13.927 11.065 1.00 0.00 A H +ATOM 464 HG12 ILE 33 12.716 14.643 9.934 1.00 0.00 A H +ATOM 465 HG21 ILE 33 10.042 16.184 11.928 1.00 0.00 A H +ATOM 466 HG22 ILE 33 8.884 16.221 10.707 1.00 0.00 A H +ATOM 467 HG23 ILE 33 9.369 14.724 11.431 1.00 0.00 A H +ATOM 468 HD1 ILE 33 13.534 15.198 12.141 1.00 0.00 A H +ATOM 469 HD2 ILE 33 13.024 16.594 11.352 1.00 0.00 A H +ATOM 470 HD3 ILE 33 12.032 15.835 12.552 1.00 0.00 A H +ATOM 471 N ILE 34 11.490 15.773 7.038 1.00 5.52 A N +ATOM 472 CA ILE 34 12.552 15.877 6.036 1.00 6.82 A C +ATOM 473 C ILE 34 13.590 16.917 6.560 1.00 6.92 A C +ATOM 474 O ILE 34 13.168 18.006 6.945 1.00 9.22 A O +ATOM 475 CB ILE 34 11.987 16.360 4.681 1.00 8.11 A C +ATOM 476 CG1 ILE 34 10.914 15.338 4.163 1.00 9.59 A C +ATOM 477 CG2 ILE 34 13.131 16.517 3.629 1.00 9.73 A C +ATOM 478 CD ILE 34 10.151 16.024 2.938 1.00 13.41 A C +ATOM 479 HN ILE 34 10.872 16.544 7.192 1.00 0.00 A H +ATOM 480 HA ILE 34 12.972 14.981 5.894 1.00 0.00 A H +ATOM 481 HB ILE 34 11.558 17.254 4.812 1.00 0.00 A H +ATOM 482 HG11 ILE 34 11.362 14.497 3.859 1.00 0.00 A H +ATOM 483 HG12 ILE 34 10.265 15.125 4.893 1.00 0.00 A H +ATOM 484 HG21 ILE 34 12.745 16.830 2.761 1.00 0.00 A H +ATOM 485 HG22 ILE 34 13.823 17.225 3.992 1.00 0.00 A H +ATOM 486 HG23 ILE 34 13.596 15.580 3.500 1.00 0.00 A H +ATOM 487 HD1 ILE 34 9.458 15.396 2.584 1.00 0.00 A H +ATOM 488 HD2 ILE 34 9.693 16.908 3.284 1.00 0.00 A H +ATOM 489 HD3 ILE 34 10.857 16.243 2.186 1.00 0.00 A H +ATOM 490 N ILE 35 14.856 16.493 6.536 1.00 7.06 A N +ATOM 491 CA ILE 35 15.930 17.454 6.941 1.00 7.52 A C +ATOM 492 C ILE 35 16.913 17.550 5.819 1.00 6.63 A C +ATOM 493 O ILE 35 17.097 16.660 4.970 1.00 7.90 A O +ATOM 494 CB ILE 35 16.622 16.995 8.285 1.00 8.07 A C +ATOM 495 CG1 ILE 35 17.360 15.651 8.067 1.00 9.41 A C +ATOM 496 CG2 ILE 35 15.592 16.974 9.434 1.00 9.46 A C +ATOM 497 CD ILE 35 18.298 15.206 9.219 1.00 9.85 A C +ATOM 498 HN ILE 35 15.080 15.560 6.255 1.00 0.00 A H +ATOM 499 HA ILE 35 15.537 18.356 7.118 1.00 0.00 A H +ATOM 500 HB ILE 35 17.323 17.653 8.560 1.00 0.00 A H +ATOM 501 HG11 ILE 35 16.670 14.938 7.940 1.00 0.00 A H +ATOM 502 HG12 ILE 35 17.911 15.734 7.237 1.00 0.00 A H +ATOM 503 HG21 ILE 35 16.041 16.682 10.279 1.00 0.00 A H +ATOM 504 HG22 ILE 35 15.202 17.947 9.550 1.00 0.00 A H +ATOM 505 HG23 ILE 35 14.825 16.297 9.181 1.00 0.00 A H +ATOM 506 HD1 ILE 35 18.724 14.333 8.983 1.00 0.00 A H +ATOM 507 HD2 ILE 35 19.039 15.945 9.350 1.00 0.00 A H +ATOM 508 HD3 ILE 35 17.722 15.101 10.096 1.00 0.00 A H +ATOM 509 N PRO 36 17.664 18.669 5.806 1.00 8.07 A N +ATOM 510 CA PRO 36 18.635 18.861 4.738 1.00 8.78 A C +ATOM 511 C PRO 36 19.925 18.042 4.949 1.00 8.31 A C +ATOM 512 O PRO 36 20.593 17.742 3.945 1.00 9.09 A O +ATOM 513 CB PRO 36 18.945 20.364 4.783 1.00 9.67 A C +ATOM 514 CG PRO 36 18.238 20.937 5.908 1.00 10.15 A C +ATOM 515 CD PRO 36 17.371 19.900 6.596 1.00 9.53 A C +ATOM 516 HA PRO 36 18.272 18.552 3.859 1.00 0.00 A H +ATOM 517 HB1 PRO 36 19.929 20.504 4.895 1.00 0.00 A H +ATOM 518 HB2 PRO 36 18.641 20.798 3.935 1.00 0.00 A H +ATOM 519 HG1 PRO 36 18.903 21.293 6.564 1.00 0.00 A H +ATOM 520 HG2 PRO 36 17.658 21.684 5.583 1.00 0.00 A H +ATOM 521 HD1 PRO 36 17.633 19.787 7.554 1.00 0.00 A H +ATOM 522 HD2 PRO 36 16.403 20.144 6.542 1.00 0.00 A H +ATOM 523 N GLY 37 20.172 17.730 6.217 1.00 8.48 A N +ATOM 524 CA GLY 37 21.452 16.969 6.513 1.00 9.20 A C +ATOM 525 C GLY 37 21.143 15.478 6.427 1.00 10.41 A C +ATOM 526 O GLY 37 20.138 15.023 5.878 1.00 12.06 A O +ATOM 527 HN GLY 37 19.539 17.986 6.948 1.00 0.00 A H +ATOM 528 HA1 GLY 37 22.153 17.210 5.842 1.00 0.00 A H +ATOM 529 HA2 GLY 37 21.777 17.196 7.431 1.00 0.00 A H +ATOM 530 N ALA 38 22.055 14.701 7.032 1.00 9.24 A N +ATOM 531 CA ALA 38 22.019 13.242 7.020 1.00 9.24 A C +ATOM 532 C ALA 38 21.944 12.628 8.396 1.00 9.60 A C +ATOM 533 O ALA 38 21.869 11.387 8.435 1.00 13.65 A O +ATOM 534 CB ALA 38 23.246 12.697 6.275 1.00 10.43 A C +ATOM 535 HN ALA 38 22.804 15.149 7.520 1.00 0.00 A H +ATOM 536 HA ALA 38 21.177 12.983 6.547 1.00 0.00 A H +ATOM 537 HB1 ALA 38 23.216 11.697 6.270 1.00 0.00 A H +ATOM 538 HB2 ALA 38 23.226 13.063 5.287 1.00 0.00 A H +ATOM 539 HB3 ALA 38 24.113 13.029 6.774 1.00 0.00 A H +ATOM 540 N THR 39 21.894 13.435 9.436 1.00 8.70 A N +ATOM 541 CA THR 39 21.936 12.911 10.809 1.00 9.46 A C +ATOM 542 C THR 39 20.615 13.191 11.521 1.00 8.32 A C +ATOM 543 O THR 39 20.357 14.317 11.948 1.00 9.89 A O +ATOM 544 CB THR 39 23.131 13.601 11.593 1.00 10.72 A C +ATOM 545 OG1 THR 39 24.284 13.401 10.709 1.00 11.66 A O +ATOM 546 CG2 THR 39 23.340 12.935 12.962 1.00 11.81 A C +ATOM 547 HN THR 39 21.826 14.422 9.289 1.00 0.00 A H +ATOM 548 HA THR 39 22.079 11.922 10.782 1.00 0.00 A H +ATOM 549 HB THR 39 22.968 14.568 11.791 1.00 0.00 A H +ATOM 550 HG1 THR 39 25.098 13.808 11.124 1.00 0.00 A H +ATOM 551 HG21 THR 39 24.096 13.384 13.439 1.00 0.00 A H +ATOM 552 HG22 THR 39 22.452 13.035 13.520 1.00 0.00 A H +ATOM 553 HG23 THR 39 23.565 11.917 12.807 1.00 0.00 A H +ATOM 554 N CYS2 40 19.827 12.110 11.642 1.00 7.64 A N +ATOM 555 CA CYS2 40 18.504 12.312 12.298 1.00 8.05 A C +ATOM 556 C CYS2 40 18.684 12.451 13.784 1.00 7.63 A C +ATOM 557 O CYS2 40 19.533 11.718 14.362 1.00 9.64 A O +ATOM 558 CB CYS2 40 17.582 11.117 11.996 1.00 7.80 A C +ATOM 559 SG CYS2 40 17.199 10.929 10.237 1.00 7.30 A S +ATOM 560 HN CYS2 40 20.114 11.212 11.308 1.00 0.00 A H +ATOM 561 HA CYS2 40 18.088 13.147 11.939 1.00 0.00 A H +ATOM 562 HB1 CYS2 40 18.032 10.282 12.313 1.00 0.00 A H +ATOM 563 HB2 CYS2 40 16.725 11.244 12.495 1.00 0.00 A H +ATOM 564 N PRO 41 17.880 13.266 14.426 1.00 8.00 A N +ATOM 565 CA PRO 41 17.924 13.421 15.877 1.00 8.96 A C +ATOM 566 C PRO 41 17.392 12.206 16.594 1.00 9.06 A C +ATOM 567 O PRO 41 16.652 11.368 16.033 1.00 8.82 A O +ATOM 568 CB PRO 41 17.076 14.658 16.145 1.00 10.39 A C +ATOM 569 CG PRO 41 16.098 14.689 14.997 1.00 10.99 A C +ATOM 570 CD PRO 41 16.859 14.150 13.779 1.00 10.49 A C +ATOM 571 HA PRO 41 18.859 13.521 16.218 1.00 0.00 A H +ATOM 572 HB1 PRO 41 16.596 14.577 17.018 1.00 0.00 A H +ATOM 573 HB2 PRO 41 17.642 15.482 16.151 1.00 0.00 A H +ATOM 574 HG1 PRO 41 15.308 14.109 15.198 1.00 0.00 A H +ATOM 575 HG2 PRO 41 15.790 15.625 14.828 1.00 0.00 A H +ATOM 576 HD1 PRO 41 16.257 13.629 13.174 1.00 0.00 A H +ATOM 577 HD2 PRO 41 17.291 14.889 13.263 1.00 0.00 A H +ATOM 578 N GLY 42 17.728 12.124 17.884 1.00 7.55 A N +ATOM 579 CA GLY 42 17.334 10.956 18.691 1.00 8.00 A C +ATOM 580 C GLY 42 15.875 10.688 18.871 1.00 7.22 A C +ATOM 581 O GLY 42 15.434 9.550 19.166 1.00 8.41 A O +ATOM 582 HN GLY 42 18.253 12.863 18.307 1.00 0.00 A H +ATOM 583 HA1 GLY 42 17.734 10.148 18.259 1.00 0.00 A H +ATOM 584 HA2 GLY 42 17.729 11.077 19.602 1.00 0.00 A H +ATOM 585 N ASP 43 15.036 11.747 18.715 1.00 5.54 A N +ATOM 586 CA ASP 43 13.564 11.573 18.836 1.00 5.85 A C +ATOM 587 C ASP 43 12.936 11.227 17.470 1.00 5.87 A C +ATOM 588 O ASP 43 11.720 11.040 17.428 1.00 7.29 A O +ATOM 589 CB ASP 43 12.933 12.737 19.580 1.00 6.72 A C +ATOM 590 CG ASP 43 13.140 14.094 18.958 1.00 8.59 A C +ATOM 591 OD1 ASP 43 14.109 14.303 18.212 1.00 9.59 A O +ATOM 592 OD2 ASP 43 12.267 14.963 19.265 1.00 11.45 A O +ATOM 593 HN ASP 43 15.413 12.652 18.517 1.00 0.00 A H +ATOM 594 HA ASP 43 13.363 10.779 19.410 1.00 0.00 A H +ATOM 595 HB1 ASP 43 11.949 12.570 19.635 1.00 0.00 A H +ATOM 596 HB2 ASP 43 13.319 12.759 20.502 1.00 0.00 A H +ATOM 597 N TYR 44 13.725 11.174 16.425 1.00 5.22 A N +ATOM 598 CA TYR 44 13.257 10.745 15.081 1.00 5.56 A C +ATOM 599 C TYR 44 14.275 9.687 14.612 1.00 4.61 A C +ATOM 600 O TYR 44 14.930 9.862 13.568 1.00 6.04 A O +ATOM 601 CB TYR 44 13.200 11.914 14.071 1.00 5.41 A C +ATOM 602 CG TYR 44 12.000 12.819 14.399 1.00 5.34 A C +ATOM 603 CD1 TYR 44 12.119 13.853 15.332 1.00 6.59 A C +ATOM 604 CD2 TYR 44 10.775 12.617 13.762 1.00 5.94 A C +ATOM 605 CE1 TYR 44 11.045 14.675 15.610 1.00 5.97 A C +ATOM 606 CE2 TYR 44 9.676 13.433 14.048 1.00 5.17 A C +ATOM 607 CZ TYR 44 9.802 14.456 14.996 1.00 5.96 A C +ATOM 608 OH TYR 44 8.740 15.265 15.269 1.00 8.60 A O +ATOM 609 HN TYR 44 14.684 11.434 16.537 1.00 0.00 A H +ATOM 610 HA TYR 44 12.324 10.389 15.134 1.00 0.00 A H +ATOM 611 HB1 TYR 44 14.045 12.446 14.130 1.00 0.00 A H +ATOM 612 HB2 TYR 44 13.099 11.550 13.145 1.00 0.00 A H +ATOM 613 HD1 TYR 44 12.989 13.999 15.802 1.00 0.00 A H +ATOM 614 HD2 TYR 44 10.682 11.880 13.093 1.00 0.00 A H +ATOM 615 HE1 TYR 44 11.154 15.432 16.254 1.00 0.00 A H +ATOM 616 HE2 TYR 44 8.805 13.287 13.578 1.00 0.00 A H +ATOM 617 HH TYR 44 7.945 14.960 14.745 1.00 0.00 A H +ATOM 618 N ALA 45 14.342 8.640 15.422 1.00 4.76 A N +ATOM 619 CA ALA 45 15.445 7.667 15.246 1.00 5.89 A C +ATOM 620 C ALA 45 15.171 6.533 14.280 1.00 6.67 A C +ATOM 621 O ALA 45 16.093 5.705 14.039 1.00 7.56 A O +ATOM 622 CB ALA 45 15.680 7.099 16.682 1.00 6.82 A C +ATOM 623 HN ALA 45 13.659 8.509 16.140 1.00 0.00 A H +ATOM 624 HA ALA 45 16.233 8.130 14.839 1.00 0.00 A H +ATOM 625 HB1 ALA 45 16.418 6.425 16.657 1.00 0.00 A H +ATOM 626 HB2 ALA 45 15.943 7.898 17.318 1.00 0.00 A H +ATOM 627 HB3 ALA 45 14.788 6.644 17.011 1.00 0.00 A H +ATOM 628 N ASN 46 13.966 6.502 13.739 1.00 5.80 A N +ATOM 629 CA ASN 46 13.512 5.395 12.878 1.00 6.15 A C +ATOM 630 C ASN 46 13.311 5.853 11.455 1.00 6.61 A C +ATOM 631 OT1 ASN 46 13.733 6.929 11.026 1.00 7.18 A O +ATOM 632 CB ASN 46 12.266 4.769 13.501 1.00 7.27 A C +ATOM 633 CG ASN 46 12.538 4.304 14.922 1.00 7.98 A C +ATOM 634 OD1 ASN 46 11.982 4.849 15.886 1.00 11.00 A O +ATOM 635 ND2 ASN 46 13.407 3.298 15.015 1.00 10.32 A N +ATOM 636 OT2 ASN 46 12.703 4.973 10.746 1.00 7.86 A O +ATOM 637 HN ASN 46 13.338 7.259 13.921 1.00 0.00 A H +ATOM 638 HA ASN 46 14.216 4.687 12.825 1.00 0.00 A H +ATOM 639 HB1 ASN 46 11.532 5.448 13.515 1.00 0.00 A H +ATOM 640 HB2 ASN 46 11.984 3.984 12.949 1.00 0.00 A H +ATOM 641 HD21 ASN 46 13.819 2.915 14.188 1.00 0.00 A H +ATOM 642 HD22 ASN 46 13.647 2.926 15.912 1.00 0.00 A H +END diff --git a/modules/mol/mm/examples/gb_example_view_trajectory.py b/modules/mol/mm/examples/gb_example_view_trajectory.py new file mode 100644 index 0000000000000000000000000000000000000000..2075c4c4535593ae2d2c21f033a9a194eed0c36d --- /dev/null +++ b/modules/mol/mm/examples/gb_example_view_trajectory.py @@ -0,0 +1,5 @@ +from ost.gui import traj + +t = io.LoadCHARMMTraj("gb_example_traj.pdb","gb_example_traj.dcd") +w = traj.TrajWidget(t) +w.show() diff --git a/modules/mol/mm/examples/gb_example_writing_trajectory.py b/modules/mol/mm/examples/gb_example_writing_trajectory.py new file mode 100644 index 0000000000000000000000000000000000000000..a6a18cd5e5836e38164d392e38dc3265b07c4f94 --- /dev/null +++ b/modules/mol/mm/examples/gb_example_writing_trajectory.py @@ -0,0 +1,31 @@ +from ost.mol.mm import * + +prot=io.LoadPDB('1CRN.pdb') + +#set up the simulation +settings = MMSettings() +settings.integrator = LangevinIntegrator(310,1,0.002) +settings.add_gbsa = True +settings.forcefield = LoadCHARMMForcefield() +settings.nonbonded_cutoff = 8.0 +settings.nonbonded_method = NonbondedMethod.CutoffNonPeriodic +settings.platform = Platform.CPU + +sim = Simulation(prot,settings) + +#minimize it +sim.MinimizeEnergy(type = "steep",tolerance = 1.0, max_iterations = 200) + +#create a trajectory observer and register it to the simulation +observer = TrajWriter(10,"gb_example_traj.pdb","gb_example_traj.dcd") +sim.Register(observer) + +#run the simulation +sim.Steps(10000) + +#Trajectory Observer needs to finalize, otherwise you might get a corrupt dcd file +observer.Finalize() + + + + diff --git a/modules/mol/mm/pymod/CMakeLists.txt b/modules/mol/mm/pymod/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..825dda3a463a4591d67f02558f65179dcddeddcb --- /dev/null +++ b/modules/mol/mm/pymod/CMakeLists.txt @@ -0,0 +1,22 @@ +set(OST_MOL_MM_PYMOD_SOURCES + export_forcefield.cc + export_settings.cc + export_simulation.cc + export_openmm.cc + export_observers.cc + export_gromacs_reader.cc + export_interaction.cc + export_buildingblock.cc + export_block_modifiers.cc + export_topology.cc + wrap_mol_mm.cc +) + +set(OST_MOL_MM_PYMOD_MODULES + "__init__.py" +) + +if (NOT ENABLE_STATIC) + pymod(NAME mol_mm OUTPUT_DIR ost/mol/mm CPP ${OST_MOL_MM_PYMOD_SOURCES} + PY ${OST_MOL_MM_PYMOD_MODULES}) +endif() diff --git a/modules/mol/mm/pymod/__init__.py b/modules/mol/mm/pymod/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5c1138cd0354113ea8d1744912a0cc0868202d2b --- /dev/null +++ b/modules/mol/mm/pymod/__init__.py @@ -0,0 +1,9 @@ +import os.path +from _ost_mol_mm import * +import ost + +def LoadAMBERForcefield(): + return Forcefield.Load(os.path.join(ost.GetSharedDataPath(),'forcefields','AMBER03.dat')) + +def LoadCHARMMForcefield(): + return Forcefield.Load(os.path.join(ost.GetSharedDataPath(),'forcefields','CHARMM27.dat')) diff --git a/modules/mol/mm/pymod/export_block_modifiers.cc b/modules/mol/mm/pymod/export_block_modifiers.cc new file mode 100644 index 0000000000000000000000000000000000000000..d26cf2f30e4def0958fa42fd4da25cae30aa606f --- /dev/null +++ b/modules/mol/mm/pymod/export_block_modifiers.cc @@ -0,0 +1,63 @@ +#include <boost/python.hpp> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> + +using namespace boost::python; + +namespace{ + +template<typename T> +std::vector<T> ListToVec(boost::python::list& l){ + std::vector<T> vec; + for (int i = 0; i < boost::python::len(l); ++i){ + vec.push_back(boost::python::extract<T>(l[i])); + } + return vec; +} + + +void WrapAddHydrogenRule(ost::mol::mm::GromacsHydrogenConstructorPtr p, int number, int method, + boost::python::list hydrogen_names, boost::python::list anchors){ + std::vector<String> v_hydrogen_names = ListToVec<String>(hydrogen_names); + std::vector<String> v_anchors = ListToVec<String>(anchors); + p->AddHydrogenRule(number,method,v_hydrogen_names,v_anchors); +} + + +} + + +void export_BlockModifiers() +{ + + class_<ost::mol::mm::HydrogenConstructor, boost::noncopyable>("HydrogenConstructor",no_init); + boost::python::register_ptr_to_python<ost::mol::mm::HydrogenConstructorPtr>(); + + class_<ost::mol::mm::BlockModifier, boost::noncopyable>("BlockModifier",no_init); + boost::python::register_ptr_to_python<ost::mol::mm::BlockModifierPtr>(); + + class_<ost::mol::mm::GromacsHydrogenConstructor, bases<ost::mol::mm::HydrogenConstructor> >("GromacsHydrogenConstructor", init<>()) + .def("ApplyOnBuildingBlock",&ost::mol::mm::GromacsHydrogenConstructor::ApplyOnBuildingBlock) + .def("ApplyOnResidue",&ost::mol::mm::GromacsHydrogenConstructor::ApplyOnResidue) + .def("AddHydrogenRule",&WrapAddHydrogenRule) + ; + + class_<ost::mol::mm::GromacsBlockModifier, bases<ost::mol::mm::BlockModifier> >("GromacsBlockModifier", init<>()) + .def("ApplyOnBuildingBlock",&ost::mol::mm::GromacsBlockModifier::ApplyOnBuildingBlock) + .def("ApplyOnResidue",&ost::mol::mm::GromacsBlockModifier::ApplyOnResidue) + .def("AddReplaceRule",&ost::mol::mm::GromacsBlockModifier::AddReplaceRule) + .def("AddAddRule",&ost::mol::mm::GromacsBlockModifier::AddAddRule) + .def("AddBond",&ost::mol::mm::GromacsBlockModifier::AddBond) + .def("AddAngle",&ost::mol::mm::GromacsBlockModifier::AddAngle) + .def("AddDihedral",&ost::mol::mm::GromacsBlockModifier::AddDihedral) + .def("AddImproper",&ost::mol::mm::GromacsBlockModifier::AddImproper) + .def("AddCMap",&ost::mol::mm::GromacsBlockModifier::AddDeleteAtom) + .def("AddDeleteAtom",&ost::mol::mm::GromacsBlockModifier::AddDeleteAtom) + ; + + + boost::python::register_ptr_to_python<ost::mol::mm::GromacsHydrogenConstructorPtr>(); + boost::python::register_ptr_to_python<ost::mol::mm::GromacsBlockModifierPtr>(); + +} + diff --git a/modules/mol/mm/pymod/export_buildingblock.cc b/modules/mol/mm/pymod/export_buildingblock.cc new file mode 100644 index 0000000000000000000000000000000000000000..b9388cb81bd76c4caec097ea8faee138d583d52c --- /dev/null +++ b/modules/mol/mm/pymod/export_buildingblock.cc @@ -0,0 +1,89 @@ +#include <ost/log.hh> +#include <boost/python.hpp> +#include <ost/mol/mm/buildingblock.hh> +#include <vector> + +using namespace boost::python; + +namespace{ + +template<typename T> +boost::python::list VecToList(std::vector<T>& vec){ + boost::python::list l; + for(typename std::vector<T>::iterator it=vec.begin();it!=vec.end();++it){ + l.append(*it); + } + return l; +} + +bool WrapMatch(ost::mol::mm::BuildingBlockPtr p, const ost::mol::ResidueHandle& res, bool match_connectivity){ + String match_fail_info; + bool match = p->Match(res,match_connectivity,match_fail_info); + if(!match){ + std::stringstream ss; + ss << "Residue "<< res.GetQualifiedName() << " does not match the building"; + ss << "block. "<<match_fail_info; + LOG_INFO(ss.str()); + } + return match; +} + +boost::python::list WrapGetAtoms(ost::mol::mm::BuildingBlockPtr p){ + std::vector<String> atoms = p->GetAtoms(); + return VecToList<String>(atoms); +} + +boost::python::list WrapGetTypes(ost::mol::mm::BuildingBlockPtr p){ + std::vector<String> types = p->GetTypes(); + return VecToList<String>(types); +} + +boost::python::list WrapGetCharges(ost::mol::mm::BuildingBlockPtr p){ + std::vector<Real> charges = p->GetCharges(); + return VecToList<Real>(charges); +} + +boost::python::list WrapGetMasses(ost::mol::mm::BuildingBlockPtr p){ + std::vector<Real> masses = p->GetMasses(); + return VecToList<Real>(masses); +} + + +} + +void export_Buildingblock() +{ + class_<ost::mol::mm::BuildingBlock>("BuildingBlock",init<>()) + .def("Match",&WrapMatch,(arg("res"),arg("match_connectivity")=true)) + .def("Connect",&ost::mol::mm::BuildingBlock::Connect) + .def("GetAtoms",&WrapGetAtoms) + .def("GetTypes",&WrapGetTypes) + .def("GetCharges",&WrapGetCharges) + .def("GetMasses",&WrapGetMasses) + .def("GetType",&ost::mol::mm::BuildingBlock::GetType) + .def("GetCharge",&ost::mol::mm::BuildingBlock::GetCharge) + .def("GetMass",&ost::mol::mm::BuildingBlock::GetMass) + .def("GetBonds",&ost::mol::mm::BuildingBlock::GetBonds) + .def("GetAngles",&ost::mol::mm::BuildingBlock::GetAngles) + .def("GetDihedrals",&ost::mol::mm::BuildingBlock::GetDihedrals) + .def("GetImpropers",&ost::mol::mm::BuildingBlock::GetImpropers) + .def("GetCMaps",&ost::mol::mm::BuildingBlock::GetCMaps) + .def("GetExclusions",&ost::mol::mm::BuildingBlock::GetExclusions) + .def("GetConstraints",&ost::mol::mm::BuildingBlock::GetConstraints) + .def("AddAtom",&ost::mol::mm::BuildingBlock::AddAtom,(arg("name"),arg("type"),arg("charge"),arg("mass")=std::numeric_limits<Real>::quiet_NaN())) + .def("AddBond",&ost::mol::mm::BuildingBlock::AddBond,(arg("bond"),arg("replace_existing")=false)) + .def("AddAngle",&ost::mol::mm::BuildingBlock::AddAngle,(arg("angle"),arg("replace_existing")=false)) + .def("AddDihedral",&ost::mol::mm::BuildingBlock::AddDihedral,(arg("dihedral"),arg("replace_existing")=false)) + .def("AddImproper",&ost::mol::mm::BuildingBlock::AddImproper,(arg("improper"),arg("replace_existing")=false)) + .def("AddExclusion",&ost::mol::mm::BuildingBlock::AddExclusion,(arg("exclusion"),arg("replace_existing")=false)) + .def("AddCMap",&ost::mol::mm::BuildingBlock::AddBond,(arg("cmap"),arg("replace_existing")=false)) + .def("AddConstraint",&ost::mol::mm::BuildingBlock::AddConstraint,(arg("constraint"),arg("replace_existing")=false)) + .def("RemoveAtom",&ost::mol::mm::BuildingBlock::RemoveAtom) + .def("ReplaceAtom",&ost::mol::mm::BuildingBlock::ReplaceAtom) + .def("RemoveInteractionsToNext",&ost::mol::mm::BuildingBlock::RemoveInteractionsToNext) + .def("RemoveInteractionsToPrev",&ost::mol::mm::BuildingBlock::RemoveInteractionsToPrev) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::BuildingBlockPtr>(); + +} \ No newline at end of file diff --git a/modules/mol/mm/pymod/export_forcefield.cc b/modules/mol/mm/pymod/export_forcefield.cc new file mode 100644 index 0000000000000000000000000000000000000000..750159c6f4478575324a8a7bf7348f18c735fb9c --- /dev/null +++ b/modules/mol/mm/pymod/export_forcefield.cc @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <boost/python.hpp> +#include <boost/shared_ptr.hpp> +#include <ost/mol/mm/forcefield.hh> + +using namespace boost::python; + +namespace{ + + + ost::mol::mm::MMInteractionPtr GetLJOneType(ost::mol::mm::ForcefieldPtr p, String type){ + return p->GetLJ(type); + } + + ost::mol::mm::MMInteractionPtr GetLJTwoTypes(ost::mol::mm::ForcefieldPtr p, String type1, String type2, bool pair){ + return p->GetLJ(type1,type2,pair); + } + +} + + +void export_Forcefield() +{ + + class_<ost::mol::mm::Forcefield>("Forcefield", init<>()) + .def("Load",&ost::mol::mm::Forcefield::Load).staticmethod("Load") + .def("Save",&ost::mol::mm::Forcefield::Save) + .def("GetBuildingBlock",&ost::mol::mm::Forcefield::GetBuildingBlock) + .def("GetAtomType",&ost::mol::mm::Forcefield::GetAtomType) + .def("GetHydrogenConstructor",&ost::mol::mm::Forcefield::GetHydrogenConstructor) + .def("GetNTerModifier",&ost::mol::mm::Forcefield::GetNTerModifier,(arg("residue_name"),arg("ter_name")="")) + .def("GetCTerModifier",&ost::mol::mm::Forcefield::GetCTerModifier,(arg("residue_name"),arg("ter_name")="")) + .def("GetBond",&ost::mol::mm::Forcefield::GetBond) + .def("GetAngle",&ost::mol::mm::Forcefield::GetAngle) + .def("GetDihedrals",&ost::mol::mm::Forcefield::GetDihedrals) + .def("GetImpropers",&ost::mol::mm::Forcefield::GetImpropers) + .def("GetCMap",&ost::mol::mm::Forcefield::GetCMap) + .def("GetImplicitGenborn",&ost::mol::mm::Forcefield::GetImplicitGenborn) + .def("GetLJ",&GetLJOneType) + .def("GetLJ",&GetLJTwoTypes) + .def("GetConstraint",&ost::mol::mm::Forcefield::GetConstraint) + .def("GetMass",&ost::mol::mm::Forcefield::GetMass) + .def("GetFudgeLJ",&ost::mol::mm::Forcefield::GetFudgeLJ) + .def("GetFudgeQQ",&ost::mol::mm::Forcefield::GetFudgeQQ) + .def("AddBuildingBlock",&ost::mol::mm::Forcefield::AddBuildingBlock) + .def("AddBond",&ost::mol::mm::Forcefield::AddBond) + .def("AddAngle",&ost::mol::mm::Forcefield::AddAngle) + .def("AddDihedral",&ost::mol::mm::Forcefield::AddDihedral) + .def("AddImproper",&ost::mol::mm::Forcefield::AddImproper) + .def("AddCMap",&ost::mol::mm::Forcefield::AddCMap) + .def("AddImplicitGenborn",&ost::mol::mm::Forcefield::AddImplicitGenborn) + .def("AddLJ",&ost::mol::mm::Forcefield::AddLJ) + .def("AddLJPair",&ost::mol::mm::Forcefield::AddLJPair) + .def("AddMass",&ost::mol::mm::Forcefield::AddMass) + .def("AddResidueRenamingRule",&ost::mol::mm::Forcefield::AddResidueRenamingRule) + .def("AddAtomRenamingRule",&ost::mol::mm::Forcefield::AddAtomRenamingRule) + .def("AddHydrogenConstructor",&ost::mol::mm::Forcefield::AddHydrogenConstructor) + .def("AddBlockModifier",&ost::mol::mm::Forcefield::AddBlockModifier) + .def("SetStandardCTer",&ost::mol::mm::Forcefield::SetStandardCTer) + .def("SetStandardNTer",&ost::mol::mm::Forcefield::SetStandardNTer) + .def("SetFudgeLJ",&ost::mol::mm::Forcefield::SetFudgeLJ) + .def("SetFudgeQQ",&ost::mol::mm::Forcefield::SetFudgeQQ) + .def("SetGenPairs",&ost::mol::mm::Forcefield::SetGenPairs) + .def("AssignFFSpecificNames",&ost::mol::mm::Forcefield::AssignFFSpecificNames,(arg("ent"),arg("reverse")=true)) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::ForcefieldPtr>(); + +} diff --git a/modules/mol/mm/pymod/export_gromacs_reader.cc b/modules/mol/mm/pymod/export_gromacs_reader.cc new file mode 100644 index 0000000000000000000000000000000000000000..fe41bfccb8ae798815d09c676a967fb8a0a849b9 --- /dev/null +++ b/modules/mol/mm/pymod/export_gromacs_reader.cc @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <boost/python.hpp> +#include <ost/mol/mm/gromacs_reader.hh> +#include <ost/mol/residue_handle.hh> + +using namespace boost::python; +using namespace ost::mol::mm; + + +void export_GromacsReader() +{ + class_<ost::mol::mm::GromacsReader>("GromacsReader",init<String>()) + .def("ReadGromacsForcefield",&ost::mol::mm::GromacsReader::ReadGromacsForcefield) + .def("SetPreprocessorDefinition",&ost::mol::mm::GromacsReader::SetPreprocessorDefinition) + .def("GetForcefield",&ost::mol::mm::GromacsReader::GetForcefield) + .def("SetForcefield",&ost::mol::mm::GromacsReader::SetForcefield) + .def("ReadResidueDatabase",&ost::mol::mm::GromacsReader::ReadResidueDatabase) + .def("ReadITP",&ost::mol::mm::GromacsReader::ReadITP) + .def("ReadCHARMMPRM",&ost::mol::mm::GromacsReader::ReadCHARMMPRM) + .def("ReadCHARMMRTF",&ost::mol::mm::GromacsReader::ReadCHARMMRTF) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::GromacsReaderPtr>(); +} \ No newline at end of file diff --git a/modules/mol/mm/pymod/export_index.cc b/modules/mol/mm/pymod/export_index.cc new file mode 100644 index 0000000000000000000000000000000000000000..ace9ccbd2aaee6e4f97980adf72695be8796f535 --- /dev/null +++ b/modules/mol/mm/pymod/export_index.cc @@ -0,0 +1,55 @@ +#include <boost/python.hpp> +#include <ost/mol/mm/index.hh> + +using namespace boost::python; + +namespace{ + +template<typename T> +int Get(T index, uint i){ + return index[i]; +} + +template<typename T> +void Set(T& index, uint i, uint v){ + index[i] = v; +} +} + +void export_Index() +{ + class_<ost::mol::mm::Index<1> >("Index1", init<uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<1> >) + .def("__setitem__",Set<ost::mol::mm::Index<1> >) + ; + + class_<ost::mol::mm::Index<2> >("Index2", init<uint, uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<2> >) + .def("__setitem__",Set<ost::mol::mm::Index<2> >) + ; + + class_<ost::mol::mm::Index<3> >("Index3", init<uint, uint, uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<3> >) + .def("__setitem__",Set<ost::mol::mm::Index<3> >) + ; + + class_<ost::mol::mm::Index<4> >("Index4", init<uint, uint, uint,uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<4> >) + .def("__setitem__",Set<ost::mol::mm::Index<4> >) + ; + + class_<ost::mol::mm::Index<5> >("Index5", init<uint, uint, uint, uint, uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<5> >) + .def("__setitem__",Set<ost::mol::mm::Index<5> >) + ; + + class_<ost::mol::mm::Index<6> >("Index6", init<uint, uint, uint, uint, uint, uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<6> >) + .def("__setitem__",Set<ost::mol::mm::Index<6> >) + ; + + class_<ost::mol::mm::Index<7> >("Index7", init<uint, uint, uint, uint, uint, uint, uint>()) + .def("__getitem__",Get<ost::mol::mm::Index<7> >) + .def("__setitem__",Set<ost::mol::mm::Index<7> >) + ; +} diff --git a/modules/mol/mm/pymod/export_interaction.cc b/modules/mol/mm/pymod/export_interaction.cc new file mode 100644 index 0000000000000000000000000000000000000000..d95c80d740bbe7f860d4ec2b01338f8398112122 --- /dev/null +++ b/modules/mol/mm/pymod/export_interaction.cc @@ -0,0 +1,109 @@ +#include <vector> + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include <ost/mol/mm/mm_interaction.hh> + + +using namespace boost::python; + +namespace{ + +template<typename T> +boost::python::list VecToList(std::vector<T>& vec){ + boost::python::list l; + for(typename std::vector<T>::iterator it=vec.begin();it!=vec.end();++it){ + l.append(*it); + } + return l; +} + +template<typename T> +std::vector<T> ListToVec(boost::python::list& l){ + std::vector<T> vec; + for (int i = 0; i < boost::python::len(l); ++i){ + vec.push_back(boost::python::extract<T>(l[i])); + } + return vec; +} + +boost::python::list WrapGetNames(ost::mol::mm::MMInteractionPtr p){ + std::vector<String> names = p->GetNames(); + return VecToList<String>(names); +} + +boost::python::list WrapGetTypes(ost::mol::mm::MMInteractionPtr p){ + std::vector<String> types = p->GetTypes(); + return VecToList<String>(types); +} + +boost::python::list WrapGetParam(ost::mol::mm::MMInteractionPtr p){ + std::vector<Real> param = p->GetParam(); + return VecToList<Real>(param); +} + +void WrapSetNames(ost::mol::mm::MMInteractionPtr p, boost::python::list l){ + std::vector<String> names = ListToVec<String>(l); + p->SetNames(names); +} + +void WrapSetTypes(ost::mol::mm::MMInteractionPtr p, boost::python::list l){ + std::vector<String> types = ListToVec<String>(l); + p->SetTypes(types); +} + +void WrapSetParam(ost::mol::mm::MMInteractionPtr p, boost::python::list l){ + std::vector<Real> param = ListToVec<Real>(l); + p->SetParam(param); +} + +} + +void export_MMInteraction() +{ + + enum_<ost::mol::mm::FuncType>("FuncType") + .value("Invalid", ost::mol::mm::Invalid) + .value("HarmonicBond", ost::mol::mm::HarmonicBond) + .value("HarmonicAngle", ost::mol::mm::HarmonicAngle) + .value("UreyBradleyAngle", ost::mol::mm::UreyBradleyAngle) + .value("PeriodicDihedral", ost::mol::mm::PeriodicDihedral) + .value("PeriodicImproper", ost::mol::mm::PeriodicImproper) + .value("HarmonicImproper", ost::mol::mm::HarmonicImproper) + .value("CMap", ost::mol::mm::CMap) + .value("LJ", ost::mol::mm::LJ) + .value("LJPair", ost::mol::mm::LJPair) + .value("GBSA", ost::mol::mm::GBSA) + .value("DistanceConstraint", ost::mol::mm::DistanceConstraint) + .value("Exclusion", ost::mol::mm::Exclusion) + .value("HarmonicPositionRestraint", ost::mol::mm::HarmonicPositionRestraint) + .value("HarmonicDistanceRestraint", ost::mol::mm::HarmonicDistanceRestraint) + ; + + class_<ost::mol::mm::MMInteraction>("MMInteraction",init<ost::mol::mm::FuncType>()) + .def("SetTypes",&WrapSetTypes) + .def("SetNames",&WrapSetNames) + .def("SetParam",&WrapSetParam) + .def("GetTypes",&WrapGetTypes) + .def("GetNames",&WrapGetNames) + .def("GetParam",&WrapGetParam) + .def("GetAtoms",&ost::mol::mm::MMInteraction::GetAtoms) + .def("GetFuncType",&ost::mol::mm::MMInteraction::GetFuncType) + .def("ReplaceAtom",&ost::mol::mm::MMInteraction::ReplaceAtom) + .def("MatchTypes",&ost::mol::mm::MMInteraction::MatchTypes) + .def("MatchNames",&ost::mol::mm::MMInteraction::MatchNames) + .def("HasName",&ost::mol::mm::MMInteraction::HasName) + .def("HasType",&ost::mol::mm::MMInteraction::HasType) + .def("IsParametrized",&ost::mol::mm::MMInteraction::IsParametrized) + .def("HasTypeWildcard",&ost::mol::mm::MMInteraction::HasTypeWildcard) + .def("HasNameWildcard",&ost::mol::mm::MMInteraction::HasNameWildcard) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::MMInteractionPtr>(); + + class_<std::vector<ost::mol::mm::MMInteractionPtr> >("MMInteractionList", init<>()) + .def(vector_indexing_suite<std::vector<ost::mol::mm::MMInteractionPtr>, true>()) + ; + +} diff --git a/modules/mol/mm/pymod/export_mm.cc b/modules/mol/mm/pymod/export_mm.cc new file mode 100644 index 0000000000000000000000000000000000000000..7a4e4ab5ce887f1b4dd3590a350c9562c9560202 --- /dev/null +++ b/modules/mol/mm/pymod/export_mm.cc @@ -0,0 +1,189 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <OpenMM.h> +#include <boost/python.hpp> +#include <boost/shared_ptr.hpp> +#include <ost/mol/mm/force_field.hh> +#include <ost/mol/mm/simulation.hh> +#include <ost/mol/mm/mm_algorithms.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/mm/mm_settings.hh> + +using namespace boost::python; +using namespace ost::mol::mm; + +namespace{ + +std::vector<std::pair<String, ost::mol::ResNum> > list_to_vec(boost::python::list& l){ + std::vector<std::pair<String,ost::mol::ResNum> > return_vec; + boost::python::tuple t; + String s; + ost::mol::ResNum rn; + for(int i = 0; i < boost::python::len(l); ++i){ + t = boost::python::extract<boost::python::tuple>(l[0]); + s = boost::python::extract<String>(t[0]); + rn = boost::python::extract<ost::mol::ResNum>(t[1]); + return_vec.push_back(std::make_pair(s,rn)); + } + return return_vec; +} + +ost::mol::mm::SimulationPtr WrapSimulationConstructor(ost::mol::EntityHandle& e, ost::mol::mm::ForcefieldPtr ff, + ost::mol::mm::IntegratorPtr integrator, ost::mol::mm::MMSettingsPtr settings, + list& d_protonated_his, + list& e_protonated_his, + list& positive_his, + list& neutral_glutamates, + list& neutral_aspartates){ + + std::vector<std::pair<String,ost::mol::ResNum> > v_d_protonated_his = list_to_vec(d_protonated_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_e_protonated_his = list_to_vec(e_protonated_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_positive_his = list_to_vec(positive_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_neutral_glutamates = list_to_vec(neutral_glutamates); + std::vector<std::pair<String,ost::mol::ResNum> > v_neutral_aspartates = list_to_vec(neutral_aspartates); + + ost::mol::mm::SimulationPtr p(new ost::mol::mm::Simulation(e,ff,integrator, settings, + v_d_protonated_his, + v_e_protonated_his, + v_positive_his, + v_neutral_glutamates, + v_neutral_aspartates)); + return p; +} + +ost::mol::mm::SimulationPtr WrapSimulationConstructorNoSettings(ost::mol::EntityHandle& e, ost::mol::mm::ForcefieldPtr ff, + ost::mol::mm::IntegratorPtr integrator, + list& d_protonated_his, + list& e_protonated_his, + list& positive_his, + list& neutral_glutamates, + list& neutral_aspartates){ + + ost::mol::mm::MMSettingsPtr p(new ost::mol::mm::MMSettings); + return WrapSimulationConstructor(e,ff,integrator,p, + d_protonated_his, + e_protonated_his, + positive_his, + neutral_glutamates, + neutral_aspartates); + + +} + +void WrapAssignFFSpecificNames(ost::mol::mm::ForcefieldPtr p, + ost::mol::EntityHandle& e, + boost::python::list& d_protonated_his, + boost::python::list& e_protonated_his, + boost::python::list& positive_his, + boost::python::list& neutral_glutamates, + boost::python::list& neutral_aspartates){ + + std::vector<std::pair<String,ost::mol::ResNum> > v_d_protonated_his = list_to_vec(d_protonated_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_e_protonated_his = list_to_vec(e_protonated_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_positive_his = list_to_vec(positive_his); + std::vector<std::pair<String,ost::mol::ResNum> > v_neutral_glutamates = list_to_vec(neutral_glutamates); + std::vector<std::pair<String,ost::mol::ResNum> > v_neutral_aspartates = list_to_vec(neutral_aspartates); + + p->AssignFFSpecificNames(e,v_d_protonated_his, + v_e_protonated_his, + v_positive_his, + v_neutral_glutamates, + v_neutral_aspartates); + +} + +} + + + +void export_MM() +{ + + //export the settings + + class_<ost::mol::mm::MMSettings>("MMSettings",init<>()) + .def_readwrite("add_bonds",&ost::mol::mm::MMSettings::add_bonds) + .def_readwrite("add_angles",&ost::mol::mm::MMSettings::add_angles) + .def_readwrite("add_dihedrals",&ost::mol::mm::MMSettings::add_dihedrals) + .def_readwrite("add_impropers",&ost::mol::mm::MMSettings::add_impropers) + .def_readwrite("add_cmaps",&ost::mol::mm::MMSettings::add_cmaps) + .def_readwrite("add_exclusions",&ost::mol::mm::MMSettings::add_exclusions) + .def_readwrite("add_nonbonded",&ost::mol::mm::MMSettings::add_nonbonded) + .def_readwrite("kill_electrostatics",&ost::mol::mm::MMSettings::kill_electrostatics) + .def_readwrite("nonbonded_method",&ost::mol::mm::MMSettings::nonbonded_method) + .def_readwrite("nonbonded_cutoff",&ost::mol::mm::MMSettings::nonbonded_cutoff) + .def_readwrite("rigid_water",&ost::mol::mm::MMSettings::rigid_water) + .def_readwrite("removeCMMMotion",&ost::mol::mm::MMSettings::removeCMMMotion) + .def_readwrite("constraints",&ost::mol::mm::MMSettings::constraints) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::MMSettingsPtr>(); + + //we have to tell boost, that the Integrator class is around... + class_<OpenMM::Integrator, boost::noncopyable>("Integrator",no_init); + //We do not export any further function for the Verlet integrator, since we want + //to perform the steps via the simulation... + class_<OpenMM::VerletIntegrator, bases<OpenMM::Integrator> >("VerletIntegrator", init<Real>()); + boost::python::register_ptr_to_python<ost::mol::mm::IntegratorPtr>(); + boost::python::register_ptr_to_python<ost::mol::mm::VerletIntegratorPtr>(); + + class_<ost::mol::mm::Forcefield>("Forcefield", init<const String&>()) + .def("AssignFFSpecificNames", &WrapAssignFFSpecificNames, (arg("entity"), + arg("d_protonated_his") = boost::python::list(), + arg("e_protonated_his") = boost::python::list(), + arg("positive_his") = boost::python::list(), + arg("neutral_glutamates") = boost::python::list(), + arg("neutral_aspartates") = boost::python::list())) + .def("AddHydrogens", &ost::mol::mm::Forcefield::AddHydrogens) + .def("ReadResidueDatabase", &ost::mol::mm::Forcefield::ReadResidueDatabase) + ; + + class_<ost::mol::mm::Simulation>("Simulation",no_init) + .def("__init__",boost::python::make_constructor(&WrapSimulationConstructor,default_call_policies(), + (arg("entity"),arg("forcefield"), + arg("integrator"),arg("settings"), + arg("d_protonated_his") = boost::python::list(), + arg("e_protonated_his") = boost::python::list(), + arg("positive_his") = boost::python::list(), + arg("neutral_glutamates") = boost::python::list(), + arg("neutral_aspartates") = boost::python::list()))) + .def("__init__",boost::python::make_constructor(&WrapSimulationConstructorNoSettings,default_call_policies(), + (arg("entity"),arg("forcefield"), + arg("integrator"), + arg("d_protonated_his") = boost::python::list(), + arg("e_protonated_his") = boost::python::list(), + arg("positive_his") = boost::python::list(), + arg("neutral_glutamates") = boost::python::list(), + arg("neutral_aspartates") = boost::python::list()))) + .def("GetEntity",&ost::mol::mm::Simulation::GetEntity) + .def("GetMMEntity",&ost::mol::mm::Simulation::GetMMEntity) + .def("UpdatePositions",&ost::mol::mm::Simulation::UpdatePositions) + .def("MinimizeEnergy",&ost::mol::mm::Simulation::MinimizeEnergy, (arg("tolerance")=1.0,arg("max_iterations")=1000)) + .def("GetTimeSteps",&ost::mol::mm::Simulation::GetTimeSteps) + .def("Steps",&ost::mol::mm::Simulation::Steps, (arg("steps")=1)) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::SimulationPtr>(); + + //functions from mm_algorithms + def("Minimize",&ost::mol::mm::Minimize, (arg("ent"), arg("ff"))); + +} + + diff --git a/modules/mol/mm/pymod/export_observers.cc b/modules/mol/mm/pymod/export_observers.cc new file mode 100644 index 0000000000000000000000000000000000000000..1fa316c6986279c9a0e907159ec458484b4376e3 --- /dev/null +++ b/modules/mol/mm/pymod/export_observers.cc @@ -0,0 +1,25 @@ +#include <boost/python.hpp> +#include <boost/shared_ptr.hpp> +#include <ost/mol/mm/mm_observer.hh> + +using namespace boost::python; + + +void export_Observers() +{ + + class_<ost::mol::mm::MMObserver, boost::noncopyable>("MMObserver", no_init); + + class_<ost::mol::mm::TrajObserver, bases<ost::mol::mm::MMObserver> >("TrajObserver", init<int>()) + .def("GetTraj", &ost::mol::mm::TrajObserver::GetTraj) + ; + + //noncopyable, because TrajWriter contains a unique ofstream + class_<ost::mol::mm::TrajWriter, boost::noncopyable, bases<ost::mol::mm::MMObserver> >("TrajWriter", init<int, String, String>()) + .def("Finalize", &ost::mol::mm::TrajWriter::Finalize) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::MMObserverPtr>(); + boost::python::register_ptr_to_python<ost::mol::mm::TrajObserverPtr>(); + boost::python::register_ptr_to_python<ost::mol::mm::TrajWriterPtr>(); +} \ No newline at end of file diff --git a/modules/mol/mm/pymod/export_openmm.cc b/modules/mol/mm/pymod/export_openmm.cc new file mode 100644 index 0000000000000000000000000000000000000000..7c97b7964854d551106ff1d07f68da85915194f9 --- /dev/null +++ b/modules/mol/mm/pymod/export_openmm.cc @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <OpenMM.h> +#include <boost/python.hpp> +#include <ost/mol/mm/simulation.hh> + +using namespace boost::python; +using namespace ost::mol::mm; + + +void export_OpenMM() +{ + + //we have to tell boost, that the Integrator class is around... + class_<OpenMM::Integrator, boost::noncopyable>("Integrator",no_init) + .def("GetConstraintTolerance",&OpenMM::Integrator::getConstraintTolerance) + .def("SetConstraintTolerance",&OpenMM::Integrator::setConstraintTolerance) + + ; + boost::python::register_ptr_to_python<ost::mol::mm::IntegratorPtr>(); + + + class_<OpenMM::VerletIntegrator, bases<OpenMM::Integrator> >("VerletIntegrator", init<Real>()); + boost::python::register_ptr_to_python<ost::mol::mm::VerletIntegratorPtr>(); + + + class_<OpenMM::BrownianIntegrator, bases<OpenMM::Integrator> >("BrownianIntegrator", init<Real,Real,Real>()) + .def("GetTemperature",&OpenMM::BrownianIntegrator::getTemperature) + .def("SetTemperature",&OpenMM::BrownianIntegrator::setTemperature) + .def("GetFriction",&OpenMM::BrownianIntegrator::getFriction) + .def("SetFriction",&OpenMM::BrownianIntegrator::setFriction) + .def("GetRandomNumberSeed",&OpenMM::BrownianIntegrator::getRandomNumberSeed) + .def("SetRandomNumberSeed",&OpenMM::BrownianIntegrator::setRandomNumberSeed) + ; + boost::python::register_ptr_to_python<ost::mol::mm::BrownianIntegratorPtr>(); + + + class_<OpenMM::LangevinIntegrator, bases<OpenMM::Integrator> >("LangevinIntegrator", init<Real,Real,Real>()) + .def("GetTemperature",&OpenMM::LangevinIntegrator::getTemperature) + .def("SetTemperature",&OpenMM::LangevinIntegrator::setTemperature) + .def("GetFriction",&OpenMM::LangevinIntegrator::getFriction) + .def("SetFriction",&OpenMM::LangevinIntegrator::setFriction) + .def("GetRandomNumberSeed",&OpenMM::LangevinIntegrator::getRandomNumberSeed) + .def("SetRandomNumberSeed",&OpenMM::LangevinIntegrator::setRandomNumberSeed) + ; + boost::python::register_ptr_to_python<ost::mol::mm::LangevinIntegratorPtr>(); + + + class_<OpenMM::VariableVerletIntegrator, bases<OpenMM::Integrator> >("VariableVerletIntegrator",init<Real>()) + .def("GetErrorTolerance", &OpenMM::VariableVerletIntegrator::getErrorTolerance) + .def("SetErrorTolerance", &OpenMM::VariableVerletIntegrator::setErrorTolerance) + ; + boost::python::register_ptr_to_python<ost::mol::mm::VariableVerletIntegratorPtr>(); + + + class_<OpenMM::VariableLangevinIntegrator, bases<OpenMM::Integrator> >("VaribaleLangevinIntegrator", init<Real,Real,Real>()) + .def("GetTemperature",&OpenMM::VariableLangevinIntegrator::getTemperature) + .def("SetTemperature",&OpenMM::VariableLangevinIntegrator::setTemperature) + .def("GetFriction",&OpenMM::VariableLangevinIntegrator::getFriction) + .def("SetFriction",&OpenMM::VariableLangevinIntegrator::setFriction) + .def("GetRandomNumberSeed",&OpenMM::VariableLangevinIntegrator::getRandomNumberSeed) + .def("SetRandomNumberSeed",&OpenMM::VariableLangevinIntegrator::setRandomNumberSeed) + .def("GetErrorTolerance",&OpenMM::VariableLangevinIntegrator::getErrorTolerance) + .def("SetErrorTolerance",&OpenMM::VariableLangevinIntegrator::setErrorTolerance) + ; + boost::python::register_ptr_to_python<ost::mol::mm::VariableLangevinIntegratorPtr>(); + + enum_<OpenMM::NonbondedForce::NonbondedMethod>("NonbondedMethod") + .value("NoCutoff", OpenMM::NonbondedForce::NoCutoff) + .value("CutoffNonPeriodic", OpenMM::NonbondedForce::CutoffNonPeriodic) + .value("CutoffPeriodic", OpenMM::NonbondedForce::CutoffPeriodic) + .value("Ewald", OpenMM::NonbondedForce::Ewald) + .value("PME", OpenMM::NonbondedForce::PME) + ; + + +} \ No newline at end of file diff --git a/modules/mol/mm/pymod/export_settings.cc b/modules/mol/mm/pymod/export_settings.cc new file mode 100644 index 0000000000000000000000000000000000000000..9d65cacd869e955fa5bb9235853ae69cc5907ce3 --- /dev/null +++ b/modules/mol/mm/pymod/export_settings.cc @@ -0,0 +1,92 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <boost/python.hpp> +#include <ost/mol/mm/mm_settings.hh> + +using namespace boost::python; + + +void export_MMSettings() +{ + + enum_<ost::mol::mm::Platform>("Platform") + .value("Reference", ost::mol::mm::Reference) + .value("OpenCL", ost::mol::mm::OpenCL) + .value("CUDA", ost::mol::mm::CUDA) + .value("CPU", ost::mol::mm::CPU) + ; + + //export the termini exceptions object + class_<ost::mol::mm::TerminiExceptions>("TerminiExceptions",init<>()) + .def("SetException", &ost::mol::mm::TerminiExceptions::SetException) + .def("HasException", &ost::mol::mm::TerminiExceptions::HasException) + .def("GetException", &ost::mol::mm::TerminiExceptions::GetException) + ; + + + //export the settings + + class_<ost::mol::mm::MMSettings>("MMSettings",init<>()) + .def_readwrite("add_bonds",&ost::mol::mm::MMSettings::add_bonds) + .def_readwrite("add_angles",&ost::mol::mm::MMSettings::add_angles) + .def_readwrite("add_dihedrals",&ost::mol::mm::MMSettings::add_dihedrals) + .def_readwrite("add_impropers",&ost::mol::mm::MMSettings::add_impropers) + .def_readwrite("add_cmaps",&ost::mol::mm::MMSettings::add_cmaps) + .def_readwrite("add_exclusions",&ost::mol::mm::MMSettings::add_exclusions) + .def_readwrite("add_nonbonded",&ost::mol::mm::MMSettings::add_nonbonded) + .def_readwrite("add_gbsa",&ost::mol::mm::MMSettings::add_gbsa) + .def_readwrite("constrain_hbonds",&ost::mol::mm::MMSettings::constrain_hbonds) + .def_readwrite("constrain_hangles",&ost::mol::mm::MMSettings::constrain_hangles) + .def_readwrite("constrain_bonds",&ost::mol::mm::MMSettings::constrain_bonds) + .def_readwrite("rigid_water",&ost::mol::mm::MMSettings::rigid_water) + .def_readwrite("strict_interactions",&ost::mol::mm::MMSettings::strict_interactions) + .def_readwrite("ideal_bond_length_constraints",&ost::mol::mm::MMSettings::ideal_bond_length_constraints) + .def_readwrite("fix_heavy_atoms",&ost::mol::mm::MMSettings::fix_heavy_atoms) + .def_readwrite("kill_electrostatics",&ost::mol::mm::MMSettings::kill_electrostatics) + .def_readwrite("generate_disulfid_bonds",&ost::mol::mm::MMSettings::generate_disulfid_bonds) + .def_readwrite("nonbonded_method",&ost::mol::mm::MMSettings::nonbonded_method) + .def_readwrite("nonbonded_cutoff",&ost::mol::mm::MMSettings::nonbonded_cutoff) + .def_readwrite("remove_cmm_motion",&ost::mol::mm::MMSettings::remove_cmm_motion) + .def_readwrite("periodic_box_extents",&ost::mol::mm::MMSettings::periodic_box_extents) + .def_readwrite("init_temperature",&ost::mol::mm::MMSettings::init_temperature) + .def_readwrite("forcefield",&ost::mol::mm::MMSettings::forcefield) + .def_readwrite("termini_exceptions",&ost::mol::mm::MMSettings::termini_exceptions) + .def_readwrite("platform",&ost::mol::mm::MMSettings::platform) + .def_readwrite("add_thermostat",&ost::mol::mm::MMSettings::add_thermostat) + .def_readwrite("thermostat_temperature",&ost::mol::mm::MMSettings::thermostat_temperature) + .def_readwrite("thermostat_collision_frequency",&ost::mol::mm::MMSettings::thermostat_collision_frequency) + .def_readwrite("add_barostat",&ost::mol::mm::MMSettings::add_barostat) + .def_readwrite("barostat_temperature",&ost::mol::mm::MMSettings::barostat_temperature) + .def_readwrite("barostat_pressure",&ost::mol::mm::MMSettings::barostat_pressure) + .def_readwrite("barostat_frequency",&ost::mol::mm::MMSettings::barostat_frequency) + .def_readwrite("integrator",&ost::mol::mm::MMSettings::integrator) + .def_readwrite("solvent_dielectric",&ost::mol::mm::MMSettings::solvent_dielectric) + .def_readwrite("solute_dielectric",&ost::mol::mm::MMSettings::solute_dielectric) + .def_readwrite("reaction_field_dielectric",&ost::mol::mm::MMSettings::reaction_field_dielectric) + .def_readwrite("use_dispersion_correction",&ost::mol::mm::MMSettings::use_dispersion_correction) + .def_readwrite("openmm_plugin_directory",&ost::mol::mm::MMSettings::openmm_plugin_directory) + .def_readwrite("custom_plugin_directory",&ost::mol::mm::MMSettings::custom_plugin_directory) + + ; + + boost::python::register_ptr_to_python<ost::mol::mm::MMSettingsPtr>(); + boost::python::register_ptr_to_python<ost::mol::mm::TerminiExceptionsPtr>(); + +} + diff --git a/modules/mol/mm/pymod/export_simulation.cc b/modules/mol/mm/pymod/export_simulation.cc new file mode 100644 index 0000000000000000000000000000000000000000..92b96b0839eb245830f2db1e636d697ffa498b63 --- /dev/null +++ b/modules/mol/mm/pymod/export_simulation.cc @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <boost/python.hpp> +#include <ost/mol/mm/simulation.hh> + +using namespace boost::python; + + + +namespace{ + + +template<typename T> +std::vector<T> ListToVec(const boost::python::list& l){ + std::vector<T> vec; + + for (int i = 0; i < boost::python::len(l); ++i){ + vec.push_back(boost::python::extract<T>(l[i])); + } + return vec; +} + +void WrapAddPositionConstraints(ost::mol::mm::SimulationPtr p, const boost::python::list& l){ + std::vector<uint> vec = ListToVec<uint>(l); + p->AddPositionConstraints(vec); +} + +} + + +void export_Simulation() +{ + + class_<ost::mol::mm::Simulation>("Simulation",no_init) + .def(init<ost::mol::EntityHandle, ost::mol::mm::MMSettingsPtr>()) + .def(init<ost::mol::mm::TopologyPtr,ost::mol::mm::MMSettingsPtr>()) + .def("Steps",&ost::mol::mm::Simulation::Steps) + .def("GetPositions",&ost::mol::mm::Simulation::GetPositions,(arg("enforce_periodic_box")=false, arg("in_angstrom")=true)) + .def("GetVelocities",&ost::mol::mm::Simulation::GetVelocities) + .def("GetForces",&ost::mol::mm::Simulation::GetForces) + .def("SetPositions",&ost::mol::mm::Simulation::SetPositions,(arg("positions"),arg("in_angstrom")=true)) + .def("SetVelocities",&ost::mol::mm::Simulation::SetVelocities) + .def("GetEntity",&ost::mol::mm::Simulation::GetEntity) + .def("GetEntityStandardNaming",&ost::mol::mm::Simulation::GetEntityStandardNaming) + .def("MinimizeEnergy",&ost::mol::mm::Simulation::MinimizeEnergy, (arg("type")="steep",arg("tolerance")=1.0,arg("max_iterations")=1000)) + .def("GetEnergy",&ost::mol::mm::Simulation::GetEnergy) + .def("GetPotentialEnergy",&ost::mol::mm::Simulation::GetPotentialEnergy) + .def("GetKineticEnergy",&ost::mol::mm::Simulation::GetKineticEnergy) + .def("Register",&ost::mol::mm::Simulation::Register) + .def("UpdateTopologyPositions",&ost::mol::mm::Simulation::UpdateTopologyPositions, (arg("enforce_periodic_box")=false)) + .def("GetTopology",&ost::mol::mm::Simulation::GetTopology) + .def("ResetHarmonicBond",&ost::mol::mm::Simulation::ResetHarmonicBond) + .def("ResetHarmonicAngle",&ost::mol::mm::Simulation::ResetHarmonicAngle) + .def("ResetUreyBradleyAngle",&ost::mol::mm::Simulation::ResetUreyBradleyAngle) + .def("ResetPeriodicDihedral",&ost::mol::mm::Simulation::ResetPeriodicDihedral) + .def("ResetPeriodicImproper",&ost::mol::mm::Simulation::ResetPeriodicImproper) + .def("ResetHarmonicImproper",&ost::mol::mm::Simulation::ResetHarmonicImproper) + .def("ResetLJPair",&ost::mol::mm::Simulation::ResetLJPair) + .def("ResetDistanceConstraint",&ost::mol::mm::Simulation::ResetDistanceConstraint) + .def("ResetHarmonicPositionRestraint",&ost::mol::mm::Simulation::ResetHarmonicPositionRestraint,(arg("index"),arg("ref_position"),arg("k"),arg("x_scale")=1.0,arg("y_scale")=1.0,arg("z_scale")=1.0)) + .def("ResetHarmonicDistanceRestraint",&ost::mol::mm::Simulation::ResetHarmonicDistanceRestraint) + .def("ResetLJ",&ost::mol::mm::Simulation::ResetLJ) + .def("ResetGBSA",&ost::mol::mm::Simulation::ResetGBSA) + .def("ResetCharge",&ost::mol::mm::Simulation::ResetCharge) + .def("ResetMass",&ost::mol::mm::Simulation::ResetMass) + .def("AddPositionConstraint",&ost::mol::mm::Simulation::AddPositionConstraint) + .def("AddPositionConstraints",&WrapAddPositionConstraints) + .def("ResetPositionConstraints",&ost::mol::mm::Simulation::ResetPositionConstraints) + .def("GetPeriodicBoxExtents",&ost::mol::mm::Simulation::GetPeriodicBoxExtents) + .def("SetPeriodicBoxExtents",&ost::mol::mm::Simulation::SetPeriodicBoxExtents,(arg("extents"))) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::SimulationPtr>(); +} diff --git a/modules/mol/mm/pymod/export_topology.cc b/modules/mol/mm/pymod/export_topology.cc new file mode 100644 index 0000000000000000000000000000000000000000..bd0defb9a72d7c6bf60259a231db03eb12fa3a85 --- /dev/null +++ b/modules/mol/mm/pymod/export_topology.cc @@ -0,0 +1,432 @@ +#include <boost/python.hpp> +#include <ost/mol/mm/topology.hh> +#include <ost/mol/mm/topology_creator.hh> +#include <ost/mol/entity_handle.hh> +#include <vector> + +using namespace boost::python; +namespace{ + + template<typename T> + int Get(T index, int i){ + return index[i]; + } + + template<typename T> + void Set(T& index, int i, int v){ + index[i] = v; + } + + template<typename T> + std::vector<T> ListToVec(const boost::python::list& l){ + + std::vector<T> vec; + for (int i = 0; i < boost::python::len(l); ++i){ + vec.push_back(boost::python::extract<T>(l[i])); + } + return vec; + } + + template<typename T> + boost::python::list VecToList(std::vector<T>& vec){ + boost::python::list l; + for(typename std::vector<T>::iterator it=vec.begin();it!=vec.end();++it){ + l.append(*it); + } + return l; + } + + ost::mol::mm::TopologyPtr WrapTopologyConstructor(ost::mol::EntityHandle& handle, + const boost::python::list& masses_list){ + std::vector<Real> masses_vector = ListToVec<Real>(masses_list); + ost::mol::mm::TopologyPtr p(new ost::mol::mm::Topology(handle,masses_vector)); + return p; + } + + void WrapAddCMap(ost::mol::mm::TopologyPtr p, int index_one, int index_two, int index_three, + int index_four, int index_five, uint dimension, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->AddCMap(index_one,index_two,index_three,index_four,index_five,dimension,v); + } + + void WrapSetSigmas(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetSigmas(v); + } + + void WrapSetEpsilons(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetEpsilons(v); + } + + void WrapSetGBSARadii(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetGBSARadii(v); + } + + void WrapSetOBCScalings(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetOBCScalings(v); + } + + void WrapSetCharges(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetCharges(v); + } + + void WrapSetMasses(ost::mol::mm::TopologyPtr p, const boost::python::list& l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetMasses(v); + } + + + boost::python::list WrapGetSigmas(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetSigmas(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + boost::python::list WrapGetEpsilons(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetEpsilons(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + boost::python::list WrapGetGBSARadii(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetGBSARadii(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + boost::python::list WrapGetOBCScalings(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetOBCScalings(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + boost::python::list WrapGetCharges(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetCharges(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + boost::python::list WrapGetMasses(ost::mol::mm::TopologyPtr p){ + std::vector<Real> v = p->GetMasses(); + boost::python::list l = VecToList<Real>(v); + return l; + } + + + boost::python::tuple WrapGetHarmonicBondParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2; + Real b,k; + p->GetHarmonicBondParameters(index,i1,i2,b,k); + return boost::python::make_tuple(i1,i2,b,k); + } + + boost::python::tuple WrapGetHarmonicAngleParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2,i3; + Real a,k; + p->GetHarmonicAngleParameters(index,i1,i2,i3,a,k); + return boost::python::make_tuple(i1,i2,i3,a,k); + } + + boost::python::tuple WrapGetUreyBradleyAngleParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2,i3; + Real a,a_k,b,b_k; + p->GetUreyBradleyAngleParameters(index,i1,i2,i3,a,a_k,b,b_k); + return boost::python::make_tuple(i1,i2,i3,a,a_k,b,b_k); + } + + boost::python::tuple WrapGetPeriodicDihedralParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2,i3,i4; + int m; + Real ph,k; + p->GetPeriodicDihedralParameters(index,i1,i2,i3,i4,m,ph,k); + return boost::python::make_tuple(i1,i2,i3,i4,m,ph,k); + } + + boost::python::tuple WrapGetPeriodicImproperParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2,i3,i4; + int m; + Real ph,k; + p->GetPeriodicImproperParameters(index,i1,i2,i3,i4,m,ph,k); + return boost::python::make_tuple(i1,i2,i3,i4,m,ph,k); + } + + boost::python::tuple WrapGetHarmonicImproperParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2,i3,i4; + Real a,k; + p->GetHarmonicImproperParameters(index,i1,i2,i3,i4,a,k); + return boost::python::make_tuple(i1,i2,i3,i4,a,k); + } + + boost::python::tuple WrapGetCMapParam(ost::mol::mm::TopologyPtr p, uint index){ + std::vector<Real> map; + int dimension; + uint i1,i2,i3,i4,i5; + p->GetCMapParameters(index,i1,i2,i3,i4,i5,dimension,map); + boost::python::list l = VecToList<Real>(map); + return boost::python::make_tuple(i1,i2,i3,i4,i5,dimension,l); + } + + boost::python::tuple WrapGetLJPairParam(ost::mol::mm::TopologyPtr p, uint index){ + uint i1,i2; + Real s,e; + p->GetLJPairParameters(index,i1,i2,s,e); + return boost::python::make_tuple(i1,i2,s,e); + } + + boost::python::tuple WrapGetDistanceConstraintParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2; + Real d; + p->GetDistanceConstraintParameters(index,i1,i2,d); + return boost::python::make_tuple(i1,i2,d); + } + + boost::python::tuple WrapGetHarmonicPositionRestraintParam(ost::mol::mm::TopologyPtr p,uint index){ + uint atom_index; + geom::Vec3 ref_pos; + Real k; + Real x_scale, y_scale, z_scale; + p->GetHarmonicPositionRestraintParameters(index,atom_index,ref_pos,k,x_scale,y_scale,z_scale); + return boost::python::make_tuple(atom_index,ref_pos,k,x_scale,y_scale,z_scale); + } + + boost::python::tuple WrapGetHarmonicDistanceRestraintParam(ost::mol::mm::TopologyPtr p,uint index){ + uint i1,i2; + Real l,k; + p->GetHarmonicDistanceRestraintParameters(index,i1,i2,l,k); + return boost::python::make_tuple(i1,i2,l,k); + } + + void WrapSetCMapParameters(ost::mol::mm::TopologyPtr p, uint index, int dimension, boost::python::list l){ + std::vector<Real> v = ListToVec<Real>(l); + p->SetCMapParameters(index,dimension,v); + } + + boost::python::list GetHarmonicBondIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2){ + std::vector<uint> return_vec = p->GetHarmonicBondIndices(i1,i2); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicBondIndicesSingleIndex(ost::mol::mm::TopologyPtr p, int i){ + std::vector<uint> return_vec = p->GetHarmonicBondIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicAngleIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3){ + std::vector<uint> return_vec = p->GetHarmonicAngleIndices(i1,i2,i3); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicAngleIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetHarmonicAngleIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetUreyBradleyAngleIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3){ + std::vector<uint> return_vec = p->GetUreyBradleyAngleIndices(i1,i2,i3); + return VecToList<uint>(return_vec); + } + + boost::python::list GetUreyBradleyAngleIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetUreyBradleyAngleIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetPeriodicDihedralIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3, int i4){ + std::vector<uint> return_vec = p->GetPeriodicDihedralIndices(i1,i2,i3,i4); + return VecToList<uint>(return_vec); + } + + boost::python::list GetPeriodicDihedralIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetPeriodicDihedralIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetPeriodicImproperIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3, uint i4){ + std::vector<uint> return_vec = p->GetPeriodicImproperIndices(i1,i2,i3,i4); + return VecToList<uint>(return_vec); + } + + boost::python::list GetPeriodicImproperIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetPeriodicImproperIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicImproperIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3, uint i4){ + std::vector<uint> return_vec = p->GetHarmonicImproperIndices(i1,i2,i3,i4); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicImproperIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetHarmonicImproperIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetCMapIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2, uint i3, uint i4, uint i5){ + std::vector<uint> return_vec = p->GetCMapIndices(i1,i2,i3,i4,i5); + return VecToList<uint>(return_vec); + } + + boost::python::list GetCMapIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetCMapIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetLJPairIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetLJPairIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetDistanceConstraintIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetDistanceConstraintIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicDistanceRestraintIndices(ost::mol::mm::TopologyPtr p, uint i1, uint i2){ + std::vector<uint> return_vec = p->GetHarmonicDistanceRestraintIndices(i1,i2); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicDistanceRestraintIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetHarmonicDistanceRestraintIndices(i); + return VecToList<uint>(return_vec); + } + + boost::python::list GetHarmonicPositionRestraintIndicesSingleIndex(ost::mol::mm::TopologyPtr p, uint i){ + std::vector<uint> return_vec = p->GetHarmonicPositionRestraintIndices(i); + return VecToList<uint>(return_vec); + } + +} + +long GetIndexA(ost::mol::mm::TopologyPtr top,ost::mol::AtomHandle& at) { return top->GetAtomIndex(at); } +long GetIndexB(ost::mol::mm::TopologyPtr top,int r_idx,const String& aname) { return top->GetAtomIndex(r_idx,aname); } + + +void export_Topology() +{ + + class_<ost::mol::mm::TopologyCreator>("TopologyCreator",no_init) + .def("Create",&ost::mol::mm::TopologyCreator::Create).staticmethod("Create") + ; + + class_<ost::mol::mm::Topology>("Topology",no_init) +// .def(init<ost::mol::EntityHandle&,ost::mol::mm::MMSettingsPtr>()) +// .def(init<ost::mol::EntityHandle&, std::vector<Real>&>()) + + .def("__init__",make_constructor(&WrapTopologyConstructor)) + .def("GetEntity",&ost::mol::mm::Topology::GetEntity) + //interaction adding functions + .def("AddHarmonicBond",&ost::mol::mm::Topology::AddHarmonicBond) + .def("AddHarmonicAngle",&ost::mol::mm::Topology::AddHarmonicAngle) + .def("AddUreyBradleyAngle",&ost::mol::mm::Topology::AddUreyBradleyAngle) + .def("AddPeriodicDihedral",&ost::mol::mm::Topology::AddPeriodicDihedral) + .def("AddPeriodicImproper",&ost::mol::mm::Topology::AddPeriodicImproper) + .def("AddHarmonicImproper",&ost::mol::mm::Topology::AddHarmonicImproper) + .def("AddCMap",&WrapAddCMap) + .def("AddLJPair",&ost::mol::mm::Topology::AddLJPair) + .def("AddDistanceConstraint",&ost::mol::mm::Topology::AddDistanceConstraint) + .def("AddExclusion",&ost::mol::mm::Topology::AddExclusion) + .def("AddPositionConstraint",&ost::mol::mm::Topology::AddPositionConstraint) + .def("ResetPositionConstraints",&ost::mol::mm::Topology::ResetPositionConstraints) + .def("ResetExclusions",&ost::mol::mm::Topology::ResetExclusions) + .def("AddHarmonicPositionRestraint",&ost::mol::mm::Topology::AddHarmonicPositionRestraint,(arg("index"),arg("ref_position"),arg("k"),arg("x_scale")=1.0,arg("y_scale")=1.0,arg("z_scale")=1.0)) + .def("AddHarmonicDistanceRestraint",&ost::mol::mm::Topology::AddHarmonicDistanceRestraint) + //single atom parameter getter and setter functions + .def("SetSigmas",&WrapSetSigmas) + .def("SetSigma",&ost::mol::mm::Topology::SetSigma) + .def("SetEpsilons",&WrapSetEpsilons) + .def("SetEpsilon",&ost::mol::mm::Topology::SetEpsilon) + .def("SetGBSARadii",&WrapSetGBSARadii) + .def("SetGBSARadius",&ost::mol::mm::Topology::SetGBSARadius) + .def("SetOBCScalings",&WrapSetOBCScalings) + .def("SetOBCScaling",&ost::mol::mm::Topology::SetOBCScaling) + .def("SetCharges",&WrapSetCharges) + .def("SetCharge",&ost::mol::mm::Topology::SetCharge) + .def("SetMasses",&WrapSetMasses) + .def("SetMass",&ost::mol::mm::Topology::SetMass) + .def("GetSigmas",&WrapGetSigmas) + .def("GetEpsilons",&WrapGetEpsilons) + .def("GetGBSARadii",&WrapGetGBSARadii) + .def("GetOBCScalings",&WrapGetOBCScalings) + .def("GetCharges",&WrapGetCharges) + .def("GetMasses",&WrapGetMasses) + .def("GetCharge",&ost::mol::mm::Topology::GetCharge) + .def("GetMass",&ost::mol::mm::Topology::GetMass) + .def("GetOBCScaling",&ost::mol::mm::Topology::GetOBCScaling) + .def("GetGBSARadius",&ost::mol::mm::Topology::GetGBSARadius) + //getter and setter functions for nonbonded fudge parameters + .def("SetFudgeLJ",&ost::mol::mm::Topology::SetFudgeLJ) + .def("SetFudgeQQ",&ost::mol::mm::Topology::SetFudgeQQ) + .def("GetFudgeLJ",&ost::mol::mm::Topology::GetFudgeLJ) + .def("GetFudgeQQ",&ost::mol::mm::Topology::GetFudgeQQ) + //getter functions for interaction parameters + .def("GetHarmonicBondParameters",&WrapGetHarmonicBondParam) + .def("GetHarmonicAngleParameters",&WrapGetHarmonicAngleParam) + .def("GetUreyBradleyAngleParameters",&WrapGetUreyBradleyAngleParam) + .def("GetPeriodicDihedralParameters",&WrapGetPeriodicDihedralParam) + .def("GetPeriodicImproperParameters",&WrapGetPeriodicImproperParam) + .def("GetHarmonicImproperParameters",&WrapGetHarmonicImproperParam) + .def("GetCMapParameters",&WrapGetCMapParam) + .def("GetLJPairParameters",&WrapGetLJPairParam) + .def("GetDistanceConstraintParameters",&WrapGetDistanceConstraintParam) + .def("GetHarmonicPositionRestraintParameters",&WrapGetHarmonicPositionRestraintParam) + .def("GetHarmonicDistanceRestraintParameters",&WrapGetHarmonicDistanceRestraintParam) + //setter functions for interaction parameters + .def("SetHarmonicBondParameters",&ost::mol::mm::Topology::SetHarmonicBondParameters) + .def("SetHarmonicAngleParameters",&ost::mol::mm::Topology::SetHarmonicAngleParameters) + .def("SetUreyBradleyAngleParameters",&ost::mol::mm::Topology::SetUreyBradleyAngleParameters) + .def("SetPeriodicDihedralParameters",&ost::mol::mm::Topology::SetPeriodicDihedralParameters) + .def("SetPeriodicImproperParameters",&ost::mol::mm::Topology::SetPeriodicImproperParameters) + .def("SetHarmonicImproperParameters",&ost::mol::mm::Topology::SetHarmonicImproperParameters) + .def("SetCMapParameters",&WrapSetCMapParameters) + .def("SetLJPairParameters",&ost::mol::mm::Topology::SetLJPairParameters) + .def("SetDistanceConstraintParameters",&ost::mol::mm::Topology::SetDistanceConstraintParameters) + .def("SetHarmonicPositionRestraintParameters",&ost::mol::mm::Topology::SetHarmonicPositionRestraintParameters) + .def("SetHarmonicDistanceRestraintParameters",&ost::mol::mm::Topology::SetHarmonicDistanceRestraintParameters) + //functions to find interactions certain atoms are involved in + .def("GetHarmonicBondIndices",&GetHarmonicBondIndices) + .def("GetHarmonicBondIndices",&GetHarmonicBondIndicesSingleIndex) + .def("GetHarmonicAngleIndices",&GetHarmonicAngleIndices) + .def("GetHarmonicAngleIndices",&GetHarmonicAngleIndicesSingleIndex) + .def("GetUreyBradleyAngleIndices",&GetUreyBradleyAngleIndices) + .def("GetUreyBradleyAngleIndices",&GetUreyBradleyAngleIndicesSingleIndex) + .def("GetPeriodicDihedralIndices",&GetPeriodicDihedralIndices) + .def("GetPeriodicDihedralIndices",&GetPeriodicDihedralIndicesSingleIndex) + .def("GetPeriodicImproperIndices",&GetPeriodicImproperIndices) + .def("GetPeriodicImproperIndices",&GetPeriodicImproperIndicesSingleIndex) + .def("GetHarmonicImproperIndices",&GetHarmonicImproperIndices) + .def("GetHarmonicImproperIndices",&GetHarmonicImproperIndicesSingleIndex) + .def("GetDistanceConstraintIndex",&ost::mol::mm::Topology::GetDistanceConstraintIndex) + .def("GetDistanceConstraintIndices",&GetDistanceConstraintIndicesSingleIndex) + .def("GetCMapIndices",&GetCMapIndices) + .def("GetCMapIndices",&GetCMapIndicesSingleIndex) + .def("GetLJPairIndex",&ost::mol::mm::Topology::GetLJPairIndex) + .def("GetLJPairIndices",&GetLJPairIndicesSingleIndex) + .def("GetHarmonicDistanceRestraintIndices",&GetHarmonicDistanceRestraintIndices) + .def("GetHarmonicDistanceRestraintIndices",&GetHarmonicDistanceRestraintIndicesSingleIndex) + .def("GetHarmonicPositionRestraintIndices",&GetHarmonicPositionRestraintIndicesSingleIndex) + + //functions to get amount of data in topology + .def("GetNumAtoms",&ost::mol::mm::Topology::GetNumAtoms) + .def("GetNumHarmonicBonds",&ost::mol::mm::Topology::GetNumHarmonicBonds) + .def("GetNumHarmonicAngles",&ost::mol::mm::Topology::GetNumHarmonicAngles) + .def("GetNumPeriodicDihedrals",&ost::mol::mm::Topology::GetNumPeriodicDihedrals) + .def("GetNumPeriodicImpropers",&ost::mol::mm::Topology::GetNumPeriodicImpropers) + .def("GetNumHarmonicImpropers",&ost::mol::mm::Topology::GetNumHarmonicImpropers) + .def("GetNumCMaps",&ost::mol::mm::Topology::GetNumCMaps) + .def("GetNumLJPairs",&ost::mol::mm::Topology::GetNumLJPairs) + .def("GetNumDistanceConstraints",&ost::mol::mm::Topology::GetNumDistanceConstraints) + .def("GetNumExclusions",&ost::mol::mm::Topology::GetNumExclusions) + .def("GetNumHarmonicPositionRestraints",&ost::mol::mm::Topology::GetNumHarmonicPositionRestraints) + .def("GetNumHarmonicDistanceRestraints",&ost::mol::mm::Topology::GetNumHarmonicDistanceRestraints) + //get internal indices + .def("GetAtomIndex",&GetIndexA) + .def("GetAtomIndex",&GetIndexB) + ; + + boost::python::register_ptr_to_python<ost::mol::mm::TopologyPtr>(); +} diff --git a/modules/mol/mm/pymod/wrap_mol_mm.cc b/modules/mol/mm/pymod/wrap_mol_mm.cc new file mode 100644 index 0000000000000000000000000000000000000000..a0d16cdc5be6ce53a35f9a3fbb8d1d65a73f418c --- /dev/null +++ b/modules/mol/mm/pymod/wrap_mol_mm.cc @@ -0,0 +1,31 @@ +#include <boost/python.hpp> + + +using namespace boost::python; + + +void export_MMSettings(); +void export_Simulation(); +void export_OpenMM(); +void export_Observers(); +void export_GromacsReader(); +void export_MMInteraction(); +void export_Buildingblock(); +void export_Forcefield(); +void export_BlockModifiers(); +void export_Topology(); + + +BOOST_PYTHON_MODULE(_ost_mol_mm) +{ + export_Forcefield(); + export_MMSettings(); + export_Simulation(); + export_OpenMM(); + export_Observers(); + export_GromacsReader(); + export_MMInteraction(); + export_Buildingblock(); + export_BlockModifiers(); + export_Topology(); +} diff --git a/modules/mol/mm/src/AMBER03.dat b/modules/mol/mm/src/AMBER03.dat new file mode 100644 index 0000000000000000000000000000000000000000..69e7d22171f447229ce354d731773876fcba7bd4 Binary files /dev/null and b/modules/mol/mm/src/AMBER03.dat differ diff --git a/modules/mol/mm/src/CHARMM27.dat b/modules/mol/mm/src/CHARMM27.dat new file mode 100644 index 0000000000000000000000000000000000000000..9a9459fb0c9882ff4db05a70560389124a73f2e6 Binary files /dev/null and b/modules/mol/mm/src/CHARMM27.dat differ diff --git a/modules/mol/mm/src/CMakeLists.txt b/modules/mol/mm/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..94c9b323d36d5e54c8679c76b5cf96950bce3460 --- /dev/null +++ b/modules/mol/mm/src/CMakeLists.txt @@ -0,0 +1,56 @@ +set(OST_MOL_MM_HEADERS + forcefield.hh + gromacs_reader.hh + buildingblock.hh + block_modifiers.hh + gromacs_block_modifiers.hh + mm_interaction.hh + mm_settings.hh + simulation.hh + mm_modeller.hh + mm_observer.hh + state_extractor.hh + system_creator.hh + topology_creator.hh + index.hh + topology.hh + steep.hh + +) + +set(OST_MOL_MM_SOURCES + forcefield.cc + gromacs_reader.cc + buildingblock.cc + gromacs_block_modifiers.cc + mm_interaction.cc + simulation.cc + mm_modeller.cc + state_extractor.cc + mm_observer.cc + system_creator.cc + topology_creator.cc + topology.cc + steep.cc +) + +set(MOL_MM_DEPS ost_mol ost_io) + + +module(NAME mol_mm SOURCES ${OST_MOL_MM_SOURCES} + HEADERS ${OST_MOL_MM_HEADERS} + HEADER_OUTPUT_DIR ost/mol/mm + DEPENDS_ON ${MOL_MM_DEPS} + LINK ${BOOST_PROGRAM_OPTIONS}) + +target_link_libraries(ost_mol_mm ${OPEN_MM_LIBRARIES}) + +copy_if_different("${CMAKE_CURRENT_SOURCE_DIR}" "${STAGE_DIR}/share/openstructure/forcefields" + "AMBER03.dat" "AMBER_03_FORCEFIELD" + "ost_mol_mm") +install(FILES "AMBER03.dat" DESTINATION "share/openstructure/forcefields/") + +copy_if_different("${CMAKE_CURRENT_SOURCE_DIR}" "${STAGE_DIR}/share/openstructure/forcefields" + "CHARMM27.dat" "CHARMM_27_FORCEFIELD" + "ost_mol_mm") +install(FILES "CHARMM27.dat" DESTINATION "share/openstructure/forcefields/") diff --git a/modules/mol/mm/src/block_modifiers.hh b/modules/mol/mm/src/block_modifiers.hh new file mode 100644 index 0000000000000000000000000000000000000000..9174c514a570eb87eea853358f9ecb92dc12ed72 --- /dev/null +++ b/modules/mol/mm/src/block_modifiers.hh @@ -0,0 +1,55 @@ +#ifndef BLOCK_MODIFIERS +#define BLOCK_MODIFIERS + +#include <ost/mol/residue_handle.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <boost/shared_ptr.hpp> +#include <ost/mol/xcs_editor.hh> +#include <ost/io/binary_data_source.hh> +#include <ost/io/binary_data_sink.hh> + +namespace ost{ namespace mol{ namespace mm{ + +class HydrogenConstructor; +class TerminiConstructor; +class BlockModifier; + +typedef boost::shared_ptr<HydrogenConstructor> HydrogenConstructorPtr; +typedef boost::shared_ptr<TerminiConstructor> TerminiConstructorPtr; +typedef boost::shared_ptr<BlockModifier> BlockModifierPtr; + +typedef enum { + GromacsBlockModifiers +} BlockModifierType; + +class HydrogenConstructor{ +public: + HydrogenConstructor() { } + virtual void ApplyOnBuildingBlock(BuildingBlockPtr p) = 0; + virtual void ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed) = 0; + virtual void OnSave(ost::io::BinaryDataSink& ds) = 0; + virtual BlockModifierType GetBlockModifierType() = 0; +}; + +class TerminiConstructor{ +public: + TerminiConstructor() { } + virtual void ApplyOnBuildingBlock(BuildingBlockPtr p) = 0; + virtual void ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed) = 0; + virtual void OnSave(ost::io::BinaryDataSink& ds) = 0; + virtual BlockModifierType GetBlockModifierType() = 0; +}; + +class BlockModifier{ +public: + BlockModifier() { } + virtual void ApplyOnBuildingBlock(BuildingBlockPtr p) = 0; + virtual void ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed) = 0; + virtual void OnSave(ost::io::BinaryDataSink& ds) = 0; + virtual BlockModifierType GetBlockModifierType() = 0; +}; + + +}}} //ns + +#endif \ No newline at end of file diff --git a/modules/mol/mm/src/buildingblock.cc b/modules/mol/mm/src/buildingblock.cc new file mode 100644 index 0000000000000000000000000000000000000000..3d6a8b2b1b2cecc5d08784fd48dfd989928a1685 --- /dev/null +++ b/modules/mol/mm/src/buildingblock.cc @@ -0,0 +1,687 @@ +#include <ost/mol/mm/buildingblock.hh> + +namespace ost{ namespace mol{ namespace mm{ + +BuildingBlock::BuildingBlock(const BuildingBlock& block){ + + atoms_ = block.GetAtoms(); + types_ = block.GetTypes(); + charges_ = block.GetCharges(); + masses_ = block.GetMasses(); + + //We have to force to create new interactions with new!!! + //There would be to danger to mess around with an interaction, + //that is associated with another building block. + + std::vector<MMInteractionPtr> bonds = block.GetBonds(); + std::vector<MMInteractionPtr> angles = block.GetAngles(); + std::vector<MMInteractionPtr> dihedrals = block.GetDihedrals(); + std::vector<MMInteractionPtr> impropers = block.GetImpropers(); + std::vector<MMInteractionPtr> exclusions = block.GetExclusions(); + std::vector<MMInteractionPtr> cmaps = block.GetCMaps(); + std::vector<MMInteractionPtr> constraints = block.GetConstraints(); + + for(std::vector<MMInteractionPtr>::iterator i = bonds.begin(); + i != bonds.end(); ++i){ + bonds_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = angles.begin(); + i != angles.end(); ++i){ + angles_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = dihedrals.begin(); + i != dihedrals.end(); ++i){ + dihedrals_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = impropers.begin(); + i != impropers.end(); ++i){ + impropers_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = exclusions.begin(); + i != exclusions.end(); ++i){ + exclusions_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = cmaps.begin(); + i != cmaps.end(); ++i){ + cmaps_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } + for(std::vector<MMInteractionPtr>::iterator i = constraints.begin(); + i != constraints.end(); ++i){ + constraints_.push_back(MMInteractionPtr(new MMInteraction(**i))); + } +} + +int BuildingBlock::GetAtomIndex(const String& atom_name) const{ + + uint ind = std::find(atoms_.begin(),atoms_.end(),atom_name) - atoms_.begin(); + + if(ind<atoms_.size()){ + return ind; + } + return -1; +} + +bool BuildingBlock::Match(const ost::mol::ResidueHandle& handle, bool match_connectivity, String& info) const{ + + //check for size + if(uint(handle.GetAtomCount()) != atoms_.size()){ + std::stringstream ss; + ss << "Expected "<<atoms_.size()<<" atoms, got "<<handle.GetAtomCount(); + info = ss.str(); + return false; + } + + //check for presence of particular atoms + for(std::vector<String>::const_iterator i = atoms_.begin(); i!=atoms_.end(); ++i){ + if(!handle.FindAtom(*i).IsValid()){ + std::stringstream ss; + ss << "Buildingblock has atom of name " << *i; + ss << ", which is not present in residue"; + info = ss.str(); + return false; + } + } + + if(!match_connectivity) return true; + + //check connectivity by extracting all unique bonds from handle, + //also bonds to other residues. + std::set<std::pair<String,String> > raw_bonds_handle; + std::vector<MMInteractionPtr> bonds_handle; + ost::mol::AtomHandleList atom_list = handle.GetAtomList(); + ost::mol::ResidueHandle prev = handle.GetPrev(); + ost::mol::ResidueHandle next = handle.GetNext(); + ost::mol::AtomHandle atom_one; + ost::mol::AtomHandle atom_two; + String name_one; + String name_two; + std::vector<String> names; + names.push_back(""); + names.push_back(""); + ost::mol::BondHandleList bond_list; + + for(ost::mol::AtomHandleList::iterator i = atom_list.begin(); + i != atom_list.end(); ++i){ + bond_list = i->GetBondList(); + for(ost::mol::BondHandleList::iterator j = bond_list.begin(); + j != bond_list.end(); ++j){ + atom_one = j->GetFirst(); + atom_two = j->GetSecond(); + name_one = atom_one.GetName(); + name_two = atom_two.GetName(); + + if(atom_one.GetResidue() == prev) name_one = "-"+name_one; + else if(atom_one.GetResidue() == next) name_one = "+"+name_one; + else if(atom_one.GetResidue() != handle) continue; //in the building block + //there can only be atoms + //to previous or subsequent + //residues. So we don't check + //cases as they occur for example + //in disulfid bridges + if(atom_two.GetResidue() == prev) name_two = "-"+name_two; + else if(atom_two.GetResidue() == next) name_two = "+"+name_two; + else if(atom_two.GetResidue() != handle) continue; //dito + + if(atom_one.GetIndex()<atom_two.GetIndex()) raw_bonds_handle.insert(std::make_pair(name_one,name_two)); + else raw_bonds_handle.insert(std::make_pair(name_two,name_one)); + + } + } + + for(std::set<std::pair<String,String> >::iterator i = raw_bonds_handle.begin(); + i != raw_bonds_handle.end(); ++i){ + MMInteractionPtr p(new MMInteraction(HarmonicBond)); + names[0] = i->first; + names[1] = i->second; + p->SetNames(names); + bonds_handle.push_back(p); + } + + bool found; + //let's first check for bonds + for(std::vector<MMInteractionPtr>::const_iterator i = bonds_.begin(); + i!=bonds_.end(); ++i){ + found = false; + for(std::vector<MMInteractionPtr>::iterator j = bonds_handle.begin(); + j != bonds_handle.end(); ++j){ + if((*j)->MatchNames((*i)->GetNames())){ + found = true; + std::vector<String> names = (*j)->GetNames(); + raw_bonds_handle.erase(std::make_pair(names[0],names[1])); + break; + } + } + if(!found){ + std::stringstream ss; + std::vector<String> names_for_info = (*i)->GetNames(); + ss << "Buildingblock defines bond between \"" <<names_for_info[0]; + ss << "\" and \"" << names_for_info[1] << "\". Those atoms are not connected in your residue"; + info = ss.str(); + return false; + } + } + //If there is a distance constraint matching a remaining raw bond, we also + //remove it from raw bonds + for(std::vector<MMInteractionPtr>::const_iterator i = constraints_.begin(); + i != constraints_.end(); ++i){ + for(std::vector<MMInteractionPtr>::iterator j = bonds_handle.begin(); + j != bonds_handle.end(); ++j){ + if((*j)->MatchNames((*i)->GetNames())){ + std::vector<String> names = (*j)->GetNames(); + raw_bonds_handle.erase(std::make_pair(names[0],names[1])); + break; + } + } + } + //we finally check whether there is an additional internal bond in the + //residue. Note, that a remaining bond to another residue (starting with +/-) + //is not a criterium for failing the match procedure + for(std::set<std::pair<String,String> >::iterator i = raw_bonds_handle.begin(); + i != raw_bonds_handle.end(); ++i){ + if( i->first.at(0) == '+' || i->first.at(0) == '-') continue; + if( i->second.at(0) == '+' || i->second.at(0) == '-') continue; + std::stringstream ss; + ss << "Your residue has a bond between atoms of name \"" << i->first << "\" and \""; + ss << i->second << "\", which is not defined in the buildingblock"; + info = ss.str(); + return false; + } + return true; +} + +void BuildingBlock::Connect(ost::mol::ResidueHandle& handle, ost::mol::XCSEditor& ed){ + + if(!handle.IsValid()) throw ost::Error("Invalid Residue encountered in connecting procedure!"); + + ost::mol::ResidueHandle prev = handle.GetPrev(); + ost::mol::ResidueHandle next = handle.GetNext(); + + //Let's build the connectivity + ost::mol::AtomHandle atom1,atom2; + std::vector<String> names; + String name1, name2; + + + for(std::vector<MMInteractionPtr>::iterator i = bonds_.begin(); + i != bonds_.end(); ++i){ + + names = (*i)->GetNames(); + name1 = names[0]; + name2 = names[1]; + + if(name1[0] == '-'){ + if(!prev.IsValid()) throw ost::Error("Cannot access previous residue in connecting procedure!"); + atom1 = prev.FindAtom(name1.substr(1)); + } + else if(name1[0] == '+'){ + if(!next.IsValid()) throw ost::Error("Cannot access next residue in connecting procedure!"); + atom1 = next.FindAtom(name1.substr(1)); + } + else{ + atom1 = handle.FindAtom(name1); + } + + if(name2[0] == '-'){ + if(!prev.IsValid()) throw ost::Error("Cannot access previous residue in connecting procedure!"); + atom2 = prev.FindAtom(name2.substr(1)); + } + else if(name2[0] == '+'){ + if(!next.IsValid()) throw ost::Error("Cannot access next residue in connecting procedure!"); + atom2 = next.FindAtom(name2.substr(1)); + } + else{ + atom2 = handle.FindAtom(name2); + } + + if(!atom1.IsValid() || !atom2.IsValid()) throw ost::Error("Could not find required atom in connecting procedure!"); + + ed.Connect(atom1,atom2); + } +} + +String BuildingBlock::GetType(const String& name) const{ + int index = this->GetAtomIndex(name); + if(index!=-1) return types_[index]; + std::stringstream ss; + ss << "Could not find requested atom of name \""<<name; + ss << "\" in buildingblock!"; + throw ost::Error(ss.str()); +} + +Real BuildingBlock::GetCharge(const String& name) const{ + int index = this->GetAtomIndex(name); + if(index!=-1) return charges_[index]; + std::stringstream ss; + ss << "Could not find requested atom of name \""<<name; + ss << "\" in buildingblock!"; + throw ost::Error(ss.str()); +} + +Real BuildingBlock::GetMass(const String& name) const{ + int index = this->GetAtomIndex(name); + if(index!=-1) return masses_[index]; + std::stringstream ss; + ss << "Could not find requested atom of name \""<<name; + ss << "\" in buildingblock!"; + throw ost::Error(ss.str()); +} + + +void BuildingBlock::AddBond(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < bonds_.size(); ++i){ + if(bonds_[i]->MatchNames(names)){ + bonds_.erase(bonds_.begin() + i); + --i; + } + } + } + bonds_.push_back(p); +} + +void BuildingBlock::AddAngle(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < angles_.size(); ++i){ + if(angles_[i]->MatchNames(names)){ + angles_.erase(angles_.begin() + i); + --i; + } + } + } + angles_.push_back(p); +} + +void BuildingBlock::AddDihedral(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < dihedrals_.size(); ++i){ + if(dihedrals_[i]->MatchNames(names)){ + dihedrals_.erase(dihedrals_.begin() + i); + --i; + } + } + } + dihedrals_.push_back(p); +} + +void BuildingBlock::AddImproper(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < impropers_.size(); ++i){ + if(impropers_[i]->MatchNames(names)){ + impropers_.erase(impropers_.begin() + i); + --i; + } + } + } + impropers_.push_back(p); +} + +void BuildingBlock::AddExclusion(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < exclusions_.size(); ++i){ + if(exclusions_[i]->MatchNames(names)){ + exclusions_.erase(exclusions_.begin() + i); + --i; + } + } + } + exclusions_.push_back(p); +} + +void BuildingBlock::AddCMap(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < cmaps_.size(); ++i){ + if(cmaps_[i]->MatchNames(names)){ + cmaps_.erase(cmaps_.begin() + i); + --i; + } + } + } + cmaps_.push_back(p); +} + +void BuildingBlock::AddConstraint(MMInteractionPtr p, bool replace_existing){ + this->CheckInteractionToAdd(p); + if(replace_existing){ + std::vector<String> names = p->GetNames(); + for(uint i = 0; i < constraints_.size(); ++i){ + if(constraints_[i]->MatchNames(names)){ + constraints_.erase(constraints_.begin() + i); + --i; + } + } + } + constraints_.push_back(p); +} + +void BuildingBlock::RemoveAtom(const String& name){ + int index = this->GetAtomIndex(name); + if(index != -1){ + atoms_.erase(atoms_.begin()+index); + types_.erase(types_.begin()+index); + charges_.erase(charges_.begin()+index); + masses_.erase(masses_.begin()+index); + } + + //All interactions, that contain this atom get deleted as well + //note, that we're looking at all interactions independently whether tere + //really is such an atom in the building block + for(uint i = 0; i < bonds_.size(); ++i){ + if(bonds_[i]->HasName(name)){ + bonds_.erase(bonds_.begin()+i); + --i; + } + } + for(uint i = 0; i < angles_.size(); ++i){ + if(angles_[i]->HasName(name)){ + angles_.erase(angles_.begin()+i); + --i; + } + } + for(uint i = 0; i < dihedrals_.size(); ++i){ + if(dihedrals_[i]->HasName(name)){ + dihedrals_.erase(dihedrals_.begin()+i); + --i; + } + } + for(uint i = 0; i < impropers_.size(); ++i){ + if(impropers_[i]->HasName(name)){ + impropers_.erase(impropers_.begin()+i); + --i; + } + } + for(uint i = 0; i < exclusions_.size(); ++i){ + if(exclusions_[i]->HasName(name)){ + exclusions_.erase(exclusions_.begin()+i); + --i; + } + } + for(uint i = 0; i < cmaps_.size(); ++i){ + if(cmaps_[i]->HasName(name)){ + cmaps_.erase(cmaps_.begin()+i); + --i; + } + } + for(uint i = 0; i < constraints_.size(); ++i){ + if(constraints_[i]->HasName(name)){ + constraints_.erase(constraints_.begin()+i); + --i; + } + } +} + +void BuildingBlock::ReplaceAtom(const String& name,const String& new_name, + const String& new_type, Real new_charge, Real new_mass){ + + int index = this->GetAtomIndex(name); + if(index != -1){ + atoms_[index] = new_name; + types_[index] = new_type; + charges_[index] = new_charge; + masses_[index] = new_mass; + + //we don't want to search every interaction associated with this + //atom, so we call the ReplaceAtom method for every interaction + //nothing will happen, if the atom of interest is not part of + //that interaction. + + for(std::vector<MMInteractionPtr>::iterator i = bonds_.begin(); + i!=bonds_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + + for(std::vector<MMInteractionPtr>::iterator i = angles_.begin(); + i!=angles_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + + for(std::vector<MMInteractionPtr>::iterator i = dihedrals_.begin(); + i!=dihedrals_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + + for(std::vector<MMInteractionPtr>::iterator i = impropers_.begin(); + i!=impropers_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + + for(std::vector<MMInteractionPtr>::iterator i = exclusions_.begin(); + i!=exclusions_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + + for(std::vector<MMInteractionPtr>::iterator i = cmaps_.begin(); + i!=cmaps_.end(); ++i){ + (*i)->ReplaceAtom(name, new_name, new_type); + } + } +} + +void BuildingBlock::AddAtom(const String& name, const String& type, Real charge, Real mass){ + if (std::find(atoms_.begin(),atoms_.end(),name) != atoms_.end()) return; + atoms_.push_back(name); + types_.push_back(type); + charges_.push_back(charge); + masses_.push_back(mass); +} + +void BuildingBlock::RemoveInteractionsToPrev(){ + std::vector<String> names; + bool has_prev_atom; + + for(uint i = 0; i < bonds_.size(); ++i){ + has_prev_atom = false; + names = bonds_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + bonds_.erase(bonds_.begin()+i); + --i; + } + } + + for(uint i = 0; i < angles_.size(); ++i){ + has_prev_atom = false; + names = angles_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + angles_.erase(angles_.begin()+i); + --i; + } + } + + for(uint i = 0; i < dihedrals_.size(); ++i){ + has_prev_atom = false; + names = dihedrals_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + dihedrals_.erase(dihedrals_.begin()+i); + --i; + } + } + + for(uint i = 0; i < impropers_.size(); ++i){ + has_prev_atom = false; + names = impropers_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + impropers_.erase(impropers_.begin()+i); + --i; + } + } + + for(uint i = 0; i < exclusions_.size(); ++i){ + has_prev_atom = false; + names = exclusions_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + exclusions_.erase(exclusions_.begin()+i); + --i; + } + } + + for(uint i = 0; i < cmaps_.size(); ++i){ + has_prev_atom = false; + names = cmaps_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '-'){ + has_prev_atom = true; + break; + } + } + if(has_prev_atom){ + cmaps_.erase(cmaps_.begin()+i); + --i; + } + } +} + +void BuildingBlock::RemoveInteractionsToNext(){ + std::vector<String> names; + bool has_next_atom; + + for(uint i = 0; i < bonds_.size(); ++i){ + has_next_atom = false; + names = bonds_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + bonds_.erase(bonds_.begin()+i); + --i; + } + } + + for(uint i = 0; i < angles_.size(); ++i){ + has_next_atom = false; + names = angles_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + angles_.erase(angles_.begin()+i); + --i; + } + } + + for(uint i = 0; i < dihedrals_.size(); ++i){ + has_next_atom = false; + names = dihedrals_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + dihedrals_.erase(dihedrals_.begin()+i); + --i; + } + } + + for(uint i = 0; i < impropers_.size(); ++i){ + has_next_atom = false; + names = impropers_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + impropers_.erase(impropers_.begin()+i); + --i; + } + } + + for(uint i = 0; i < exclusions_.size(); ++i){ + has_next_atom = false; + names = exclusions_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + exclusions_.erase(exclusions_.begin()+i); + --i; + } + } + + for(uint i = 0; i < cmaps_.size(); ++i){ + has_next_atom = false; + names = cmaps_[i]->GetNames(); + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + if((*j)[0] == '+'){ + has_next_atom = true; + break; + } + } + if(has_next_atom){ + cmaps_.erase(cmaps_.begin()+i); + --i; + } + } +} + +void BuildingBlock::CheckInteractionToAdd(MMInteractionPtr p) const{ + if(p->GetNames().empty()){ + throw ost::Error("Expect interaction to have names properly set!"); + } +} + +}}}//ns diff --git a/modules/mol/mm/src/buildingblock.hh b/modules/mol/mm/src/buildingblock.hh new file mode 100644 index 0000000000000000000000000000000000000000..f1cacdb516952ac7fc05f91e4357a9cd5035c7e8 --- /dev/null +++ b/modules/mol/mm/src/buildingblock.hh @@ -0,0 +1,248 @@ +#ifndef OST_FORCE_FIELD_BUILDING_BLOCK_HH +#define OST_FORCE_FIELD_BUILDING_BLOCK_HH + +#include <vector> +#include <limits> +#include <set> + +#include <boost/shared_ptr.hpp> + +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/message.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/geom/vec3.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class BuildingBlock; +typedef boost::shared_ptr<BuildingBlock> BuildingBlockPtr; + +class BuildingBlock{ +public: + BuildingBlock() { } + + //copy constructor needs to be defined explicitely, since the forces + //have to be newly created + BuildingBlock(const BuildingBlock& block); + + bool Match(const ost::mol::ResidueHandle& handle, bool match_connectivity, String& info) const; + + void Connect(ost::mol::ResidueHandle& handle, ost::mol::XCSEditor& ed); + + //getter functionality for all buildingblock members + + std::vector<String> GetAtoms() const { return atoms_; } + + std::vector<String> GetTypes() const { return types_; } + + std::vector<Real> GetCharges() const { return charges_; } + + std::vector<Real> GetMasses() const { return masses_; } + + String GetType(const String& name) const; + + Real GetCharge(const String& name) const; + + Real GetMass(const String& name) const; + + std::vector<MMInteractionPtr> GetBonds() const { return bonds_; } + + std::vector<MMInteractionPtr> GetAngles() const { return angles_; } + + std::vector<MMInteractionPtr> GetDihedrals() const { return dihedrals_; } + + std::vector<MMInteractionPtr> GetImpropers() const { return impropers_; } + + std::vector<MMInteractionPtr> GetCMaps() const { return cmaps_; } + + std::vector<MMInteractionPtr> GetExclusions() const { return exclusions_; } + + std::vector<MMInteractionPtr> GetConstraints() const { return constraints_;} + + //Add data to building block + + void AddAtom(const String& name, const String& type, Real charge, Real mass = std::numeric_limits<Real>::quiet_NaN()); + + void AddBond(MMInteractionPtr p, bool replace_existing = false); + + void AddAngle(MMInteractionPtr p, bool replace_existing = false); + + void AddDihedral(MMInteractionPtr p, bool replace_existing = false); + + void AddImproper(MMInteractionPtr p, bool replace_existing = false); + + void AddExclusion(MMInteractionPtr p, bool replace_existing = false); + + void AddCMap(MMInteractionPtr p, bool replace_existing = false); + + void AddConstraint(MMInteractionPtr p, bool replace_existing = false); + + //modifiers + + //removes atom and all interactions associated to it + void RemoveAtom(const String& name); + + //replaces atom in all interactions + void ReplaceAtom(const String& name,const String& new_name, + const String& new_type, Real new_charge, + Real new_mass = std::numeric_limits<Real>::quiet_NaN()); + + + //remove all interactions to previous or next residue + void RemoveInteractionsToPrev(); + + void RemoveInteractionsToNext(); + + template <typename DS> + void Serialize(DS& ds){ + int num_atoms = atoms_.size(); + ds & num_atoms; + + if(ds.IsSource()){ + atoms_ = std::vector<String>(num_atoms); + types_ = std::vector<String>(num_atoms); + charges_ = std::vector<Real>(num_atoms); + masses_ = std::vector<Real>(num_atoms); + } + + for(unsigned int i = 0; i < num_atoms; ++i){ + ds & atoms_[i]; + ds & types_[i]; + ds & charges_[i]; + ds & masses_[i]; + } + + int num_bonds = bonds_.size(); + int num_angles = angles_.size(); + int num_dihedrals = dihedrals_.size(); + int num_impropers = impropers_.size(); + int num_exclusions = exclusions_.size(); + int num_cmaps = cmaps_.size(); + int num_constraints = constraints_.size(); + + ds & num_bonds; + ds & num_angles; + ds & num_dihedrals; + ds & num_impropers; + ds & num_exclusions; + ds & num_cmaps; + ds & num_constraints; + + for(unsigned int i = 0; i < num_bonds; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + bonds_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = bonds_[i]->GetFuncType(); + ds & func_type; + } + ds & *(bonds_[i]); + } + + for(unsigned int i = 0; i < num_angles; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + angles_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = angles_[i]->GetFuncType(); + ds & func_type; + } + ds & *(angles_[i]); + } + + for(unsigned int i = 0; i < num_dihedrals; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + dihedrals_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = dihedrals_[i]->GetFuncType(); + ds & func_type; + } + ds & *(dihedrals_[i]); + } + + for(unsigned int i = 0; i < num_impropers; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + impropers_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = impropers_[i]->GetFuncType(); + ds & func_type; + } + ds & *(impropers_[i]); + } + + for(unsigned int i = 0; i < num_exclusions; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + exclusions_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = exclusions_[i]->GetFuncType(); + ds & func_type; + } + ds & *(exclusions_[i]); + } + + for(unsigned int i = 0; i < num_cmaps; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + cmaps_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = cmaps_[i]->GetFuncType(); + ds & func_type; + } + ds & *(cmaps_[i]); + } + + for(unsigned int i = 0; i < num_constraints; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + constraints_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = constraints_[i]->GetFuncType(); + ds & func_type; + } + ds & *(constraints_[i]); + } + } + + +private: + + int GetAtomIndex(const String& atom_name) const; + void CheckInteractionToAdd(MMInteractionPtr p) const; + + std::vector<String> atoms_; + std::vector<String> types_; + std::vector<Real> charges_; + std::vector<Real> masses_; + std::vector<MMInteractionPtr> bonds_; + std::vector<MMInteractionPtr> angles_; + std::vector<MMInteractionPtr> dihedrals_; + std::vector<MMInteractionPtr> impropers_; + std::vector<MMInteractionPtr> exclusions_; + std::vector<MMInteractionPtr> cmaps_; + std::vector<MMInteractionPtr> constraints_; +}; + +}}} + +#endif diff --git a/modules/mol/mm/src/forcefield.cc b/modules/mol/mm/src/forcefield.cc new file mode 100644 index 0000000000000000000000000000000000000000..93f1c882746f3e33b063657b3bcec8c94fef5a5c --- /dev/null +++ b/modules/mol/mm/src/forcefield.cc @@ -0,0 +1,977 @@ +#include <ost/mol/mm/forcefield.hh> + +namespace ost{ namespace mol{ namespace mm{ + +ForcefieldPtr Forcefield::Load(const String& filename){ + + + if (!boost::filesystem::exists(filename)) { + std::stringstream ss; + ss << "Could not open forcefield. File '" + << filename << "' does not exist"; + throw ost::io::IOException(ss.str()); + } + + std::ifstream stream(filename.c_str(), std::ios_base::binary); + ost::io::BinaryDataSource ds(stream); + ForcefieldPtr ff_p(new Forcefield); + + bool gen_pairs; + Real fudge_LJ; + Real fudge_QQ; + ds & gen_pairs; + ds & fudge_LJ; + ds & fudge_QQ; + + ff_p->SetGenPairs(gen_pairs); + ff_p->SetFudgeLJ(fudge_LJ); + ff_p->SetFudgeQQ(fudge_QQ); + + int num_atom_masses; + ds & num_atom_masses; + + String atom_name; + Real mass; + for(int i = 0; i < num_atom_masses; ++i){ + ds & atom_name; + ds & mass; + ff_p->AddMass(atom_name,mass); + } + + int num_building_blocks; + ds & num_building_blocks; + String block_name; + for(int i = 0; i < num_building_blocks; ++i){ + ds & block_name; + BuildingBlockPtr p(new BuildingBlock); + ds & *p; + ff_p->AddBuildingBlock(block_name,p); + } + + int func_type; + int num_bonds; + ds & num_bonds; + for(int i = 0; i < num_bonds; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddBond(p); + } + + int num_angles; + ds & num_angles; + for(int i = 0; i < num_angles; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddAngle(p); + } + + int num_lj_pairs; + ds & num_lj_pairs; + for(int i = 0; i < num_lj_pairs; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddLJPair(p); + } + + int num_constraints; + ds & num_constraints; + for(int i = 0; i < num_constraints; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddConstraint(p); + } + + int num_cmaps; + ds & num_cmaps; + for(int i = 0; i < num_cmaps; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddCMap(p); + } + + int num_genborn; + ds & num_genborn; + for(int i = 0; i < num_genborn; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddImplicitGenborn(p); + } + + int num_ljs; + ds & num_ljs; + for(int i = 0; i < num_ljs; ++i){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddLJ(p); + } + + + int num_dihedrals; + ds & num_dihedrals; + int temp_num; + for(int i = 0; i < num_dihedrals; ++i){ + ds & temp_num; + for(int j = 0; j < temp_num; ++j){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddDihedral(p); + } + } + + int num_impropers; + ds & num_impropers; + for(int i = 0; i < num_impropers; ++i){ + ds & temp_num; + for(int j = 0; j < temp_num; ++j){ + ds & func_type; + MMInteractionPtr p(new MMInteraction(FuncType(func_type))); + ds & *p; + ff_p->AddImproper(p); + } + } + + int num_atom_renamings; + ds & num_atom_renamings; + String res_name, old_name, new_name; + for(int i = 0; i < num_atom_renamings; ++i){ + ds & res_name; + ds & temp_num; + for(int j = 0; j < temp_num; ++j){ + ds & old_name; + ds & new_name; + ff_p->AddAtomRenamingRule(res_name,old_name,new_name); + } + } + + int num_res_renaming; + ds & num_res_renaming; + for(int i = 0; i < num_res_renaming; ++i){ + ds & res_name; + ResidueNamesPtr p(new ResidueNames); + ds & *p; + ff_p->AddResidueRenamingRule(res_name, p->main, p->nter, p->cter, p->twoter); + } + + int num_hydrogen_constructors; + int block_modifier_type; + String block_modifier_name; + ds & num_hydrogen_constructors; + for(int i = 0; i < num_hydrogen_constructors; ++i){ + ds & block_modifier_type; + ds & block_modifier_name; + switch(block_modifier_type){ + case GromacsBlockModifiers:{ + GromacsHydrogenConstructorPtr p(new GromacsHydrogenConstructor); + ds & *p; + ff_p->AddHydrogenConstructor(block_modifier_name,p); + break; + } + default:{ + throw ost::Error("Invalid Block Modifier type encountered when loading hydrogen constructor!"); + } + + } + } + + int num_block_modifiers; + ds & num_block_modifiers; + String modifier_name; + + for(int i = 0; i < num_block_modifiers; ++i){ + ds & block_modifier_type; + switch(block_modifier_type){ + case GromacsBlockModifiers:{ + GromacsBlockModifierPtr p(new GromacsBlockModifier); + ds & modifier_name; + ds & *p; + ff_p->AddBlockModifier(modifier_name,p); + break; + } + default:{ + throw ost::Error("Invalid Block Modifier type encountered when loading!"); + } + } + + } + + int num_standard_n_termini; + int num_standard_c_termini; + + ds & num_standard_n_termini; + ds & num_standard_c_termini; + + for(int i = 0; i < num_standard_n_termini; ++i){ + ds & res_name; + ds & modifier_name; + ff_p->SetStandardNTer(res_name,modifier_name); + } + + for(int i = 0; i < num_standard_c_termini; ++i){ + ds & res_name; + ds & modifier_name; + ff_p->SetStandardCTer(res_name,modifier_name); + } + + return ff_p; +} + +void Forcefield::Save(const String& filename){ + std::ofstream stream(filename.c_str(), std::ios_base::binary); + io::BinaryDataSink ds(stream); + + + ds & gen_pairs_; + ds & fudge_LJ_; + ds & fudge_QQ_; + + int num_atom_masses = atom_masses_.size(); + ds & num_atom_masses; + for(boost::unordered_map<String,Real>::iterator i = atom_masses_.begin(); + i != atom_masses_.end(); ++i){ + ds & i->first; + ds & i->second; + } + + int num_building_blocks = building_blocks_.size(); + ds & num_building_blocks; + for(boost::unordered_map<String,BuildingBlockPtr>::iterator i = building_blocks_.begin(); + i != building_blocks_.end(); ++i){ + ds & i->first; + ds & *(i->second); + } + + + int func_type; + int num_bonds = bonds_.size(); + ds & num_bonds; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = bonds_.begin(); + i != bonds_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_angles = angles_.size(); + ds & num_angles; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = angles_.begin(); + i != angles_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_lj_pairs = lj_14_pairs_.size(); + ds & num_lj_pairs; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = lj_14_pairs_.begin(); + i != lj_14_pairs_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_constraints = constraints_.size(); + ds & num_constraints; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = constraints_.begin(); + i != constraints_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_cmaps = cmaps_.size(); + ds & num_cmaps; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = cmaps_.begin(); + i != cmaps_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_genborn = implicit_genborn_.size(); + ds & num_genborn; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = implicit_genborn_.begin(); + i != implicit_genborn_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_ljs = ljs_.size(); + ds & num_ljs; + for(boost::unordered_map<String,MMInteractionPtr>::iterator i = ljs_.begin(); + i != ljs_.end(); ++i){ + func_type = int(i->second->GetFuncType()); + ds & func_type; + ds & *(i->second); + } + + int num_dihedrals = dihedrals_.size(); + int vector_size; + ds & num_dihedrals; + for(boost::unordered_map<String,std::vector<MMInteractionPtr> >::iterator i = dihedrals_.begin(); + i != dihedrals_.end(); ++i){ + vector_size = i->second.size(); + ds & vector_size; + for(std::vector<MMInteractionPtr>::iterator j = i->second.begin(); + j != i->second.end(); ++j){ + func_type = int((*j)->GetFuncType()); + ds & func_type; + ds & **j; + } + } + + int num_impropers = improper_dihedrals_.size(); + ds & num_impropers; + for(boost::unordered_map<String,std::vector<MMInteractionPtr> >::iterator i = improper_dihedrals_.begin(); + i != improper_dihedrals_.end(); ++i){ + vector_size = i->second.size(); + ds & vector_size; + for(std::vector<MMInteractionPtr>::iterator j = i->second.begin(); + j != i->second.end(); ++j){ + func_type = int((*j)->GetFuncType()); + ds & func_type; + ds & **j; + } + } + + + int num_atom_renamings = atom_renaming_ff_specific_.size(); + ds & num_atom_renamings; + for(boost::unordered_map<String,std::vector<std::pair<String,String> > >::iterator i = atom_renaming_ff_specific_.begin(); + i != atom_renaming_ff_specific_.end(); ++i){ + ds & i->first; + vector_size = i->second.size(); + ds & vector_size; + for(std::vector<std::pair<String,String> >::iterator j = i->second.begin(); + j != i->second.end(); ++j){ + ds & j->first; + ds & j->second; + } + } + + int num_res_renaming = res_renaming_ff_specific_.size(); + ds & num_res_renaming; + for(boost::unordered_map<String,ResidueNamesPtr>::iterator i = res_renaming_ff_specific_.begin(); + i != res_renaming_ff_specific_.end(); ++i){ + ds & i->first; + ds & *(i->second); + } + + int num_hydrogen_constructors = hydrogen_constructors_.size(); + ds & num_hydrogen_constructors; + for(boost::unordered_map<String,HydrogenConstructorPtr>::iterator i = hydrogen_constructors_.begin(); + i != hydrogen_constructors_.end(); ++i){ + func_type = int(i->second->GetBlockModifierType()); + ds & func_type; + ds & i->first; + i->second->OnSave(ds); + } + + int num_block_modifiers = block_modifiers_.size(); + ds & num_block_modifiers; + for(boost::unordered_map<String,BlockModifierPtr>::iterator i = block_modifiers_.begin(); + i != block_modifiers_.end(); ++i){ + func_type = int(i->second->GetBlockModifierType()); + ds & func_type; + ds & i->first; + i->second->OnSave(ds); + } + + int num_standard_n_termini = standard_c_termini_.size(); + int num_standard_c_termini = standard_n_termini_.size(); + ds & num_standard_n_termini; + ds & num_standard_c_termini; + + for(boost::unordered_map<String, String>::iterator i = standard_n_termini_.begin(); + i != standard_n_termini_.end(); ++i){ + ds & i->first; + ds & i->second; + } + + for(boost::unordered_map<String, String>::iterator i = standard_c_termini_.begin(); + i != standard_c_termini_.end(); ++i){ + ds & i->first; + ds & i->second; + } + +} + +BuildingBlockPtr Forcefield::GetBuildingBlock(const String& name) const{ + boost::unordered_map<String,BuildingBlockPtr>::const_iterator i = building_blocks_.find(name); + if(i == building_blocks_.end()){ + std::stringstream ss; + ss << "Forcefield does not contain requested building block "; + ss << "\"" << name << "\""; + throw ost::Error(ss.str()); + } + BuildingBlockPtr ff_p = i->second; + //let's create a new building block to avoid messing around with the + //force field building blocks + BuildingBlockPtr p(new BuildingBlock(*ff_p)); + return p; +} + +BlockModifierPtr Forcefield::GetBlockModifier(const String& modifier_name) const{ + boost::unordered_map<String,BlockModifierPtr>::const_iterator i = block_modifiers_.find(modifier_name); + if(i == block_modifiers_.end()) return BlockModifierPtr(); + return i->second; +} + +String Forcefield::GetAtomType(const String& res_name, const String& atom_name) const{ + BuildingBlockPtr block = this->GetBuildingBlock(res_name); + return block->GetType(atom_name); +} + +HydrogenConstructorPtr Forcefield::GetHydrogenConstructor(const String& name) const{ + boost::unordered_map<String,HydrogenConstructorPtr>::const_iterator i = hydrogen_constructors_.find(name); + if(i != hydrogen_constructors_.end()) return i->second; + return HydrogenConstructorPtr(); +} + +BlockModifierPtr Forcefield::GetNTerModifier(const String& res_name, const String& ter_name) const{ + String temp = ter_name; + if(temp == ""){ + boost::unordered_map<String,String>::const_iterator it = standard_n_termini_.find(res_name); + if(it != standard_n_termini_.end()) temp = it->second; + else return BlockModifierPtr(); + } + return this->GetBlockModifier(temp); +} + +BlockModifierPtr Forcefield::GetCTerModifier(const String& res_name, const String& ter_name) const{ + String temp = ter_name; + if(temp == ""){ + boost::unordered_map<String,String>::const_iterator it = standard_c_termini_.find(res_name); + if(it != standard_c_termini_.end()) temp = it->second; + else return BlockModifierPtr(); + } + return this->GetBlockModifier(temp); +} + +MMInteractionPtr Forcefield::GetBond(const String& type1, const String& type2) const{ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + bonds_.find(this->AtomTypesToKeyword(types)); + if(i != bonds_.end()) return i->second; + throw ost::Error("Forcefield does not contain bond for requested atom types!"); +} + +MMInteractionPtr Forcefield::GetAngle(const String& type1, const String& type2, + const String& type3) const{ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + types.push_back(type3); + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + angles_.find(this->AtomTypesToKeyword(types)); + if(i != angles_.end()) return i->second; + throw ost::Error("Forcefield does not contain angle for requested atom types!"); +} + +std::vector<MMInteractionPtr> Forcefield::GetDihedrals(const String& type1, + const String& type2, + const String& type3, + const String& type4) const{ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + types.push_back(type3); + types.push_back(type4); + + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator i = + dihedrals_.find(this->AtomTypesToKeyword(types)); + + if(i != dihedrals_.end()) return i->second; + + //if we reach this point, we have to look for all dihedrals with wildcards... + std::vector<MMInteractionPtr> dihedrals; + std::vector<String> types_with_wildcards; + + //lets first check single wildcards + for(int i = 0; i < 4; ++i){ + types_with_wildcards = types; + types_with_wildcards[i] = "X"; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator j = + dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(j != dihedrals_.end()) dihedrals.insert(dihedrals.end(),j->second.begin(),j->second.end()); + } + + //we check for two wildcards + for(int i = 0; i < 4; ++i){ + for(int j = i+1; j < 4; ++j){ + types_with_wildcards = types; + types_with_wildcards[i] = "X"; + types_with_wildcards[j] = "X"; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator k = + dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(k != dihedrals_.end()) dihedrals.insert(dihedrals.end(),k->second.begin(),k->second.end()); + } + } + + //as stupid as it may sound, we also look for dihedrals with 3 wildcards + std::vector<String> all_wildcards; + for(int i = 0; i < 4; ++i){ + all_wildcards.push_back("X"); + } + for(int i = 0; i < 4; ++i){ + types_with_wildcards = all_wildcards; + types_with_wildcards[i] = types[i]; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator j = + dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(j != dihedrals_.end()) dihedrals.insert(dihedrals.end(),j->second.begin(),j->second.end()); + } + + if(!dihedrals.empty()) return dihedrals; + throw ost::Error("Forcefield does not contain any dihedrals for requested atom types!"); +} + +std::vector<MMInteractionPtr> Forcefield::GetImpropers(const String& type1, + const String& type2, + const String& type3, + const String& type4) const{ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + types.push_back(type3); + types.push_back(type4); + + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator i = + improper_dihedrals_.find(this->AtomTypesToKeyword(types)); + + if(i != improper_dihedrals_.end()) return i->second; + + //if we reach this point, we have to look for all dihedrals with wildcards... + std::vector<MMInteractionPtr> impropers; + std::vector<String> types_with_wildcards; + + //lets first check single wildcards + for(int i = 0; i < 4; ++i){ + types_with_wildcards = types; + types_with_wildcards[i] = "X"; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator j = + improper_dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(j != improper_dihedrals_.end()) impropers.insert(impropers.end(),j->second.begin(),j->second.end()); + } + + //we check for two wildcards + for(int i = 0; i < 4; ++i){ + for(int j = i+1; j < 4; ++j){ + types_with_wildcards = types; + types_with_wildcards[i] = "X"; + types_with_wildcards[j] = "X"; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator k = + improper_dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(k != improper_dihedrals_.end()) impropers.insert(impropers.end(),k->second.begin(),k->second.end()); + } + } + + //as stupid as it may sound, we also look for dihedrals with 3 wildcards + std::vector<String> all_wildcards; + for(int i = 0; i < 4; ++i){ + all_wildcards.push_back("X"); + } + for(int i = 0; i < 4; ++i){ + types_with_wildcards = all_wildcards; + types_with_wildcards[i] = types[i]; + boost::unordered_map<String,std::vector<MMInteractionPtr> >::const_iterator j = + improper_dihedrals_.find(this->AtomTypesToKeyword(types_with_wildcards)); + if(j != improper_dihedrals_.end()) impropers.insert(impropers.end(),j->second.begin(),j->second.end()); + } + + if(!impropers.empty()) return impropers; + + throw ost::Error("Forcefield does not contain any impropers for requested atom types!"); +} + +MMInteractionPtr Forcefield::GetCMap(const String& type1, const String& type2, + const String& type3, const String& type4, + const String& type5) const{ + + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + types.push_back(type3); + types.push_back(type4); + types.push_back(type5); + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + cmaps_.find(this->AtomTypesToKeyword(types,false)); + if(i != cmaps_.end()) return i->second; + + throw ost::Error("Forcefield does not contain cmap for requested atom types!"); +} + +MMInteractionPtr Forcefield::GetImplicitGenborn(const String& type) const{ + + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + implicit_genborn_.find(type); + if(i != implicit_genborn_.end()) return i->second; + throw ost::Error("Forcefield does not contain implicit genborn parameters for requested atom type!"); +} + +MMInteractionPtr Forcefield::GetLJ(const String& type) const{ + + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + ljs_.find(type); + + if(i != ljs_.end()){ + return i->second; + } + throw ost::Error("Forcefield does not contain lennard jones parameters for requested atom types!"); +} + +MMInteractionPtr Forcefield::GetLJ(const String& type1, + const String& type2, + bool pair) const{ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + + if(pair){ + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + lj_14_pairs_.find(this->AtomTypesToKeyword(types)); + if(i == lj_14_pairs_.end()){ + if(!gen_pairs_){ + std::stringstream ss; + ss << "was not able to find lj parameters between atoms of type "; + ss << type1 << " and " << type2 << " with gen_pairs "; + ss << "set to no!"; + throw ost::Error(ss.str()); + } + } + else{ + return i->second; + } + } + + MMInteractionPtr temp1, temp2; + temp1 = this->GetLJ(type1); + temp2 = this->GetLJ(type2); + if(temp1 && temp2){ + MMInteraction* interaction_ptr; + if(pair) interaction_ptr = new MMInteraction(LJPair); + else interaction_ptr = new MMInteraction(LJ); + MMInteractionPtr return_ptr(interaction_ptr); + std::vector<Real> param1, param2, param; + param1 = temp1->GetParam(); + param2 = temp2->GetParam(); + param.push_back(0.5*(param1[0]+param2[0])); + param.push_back(sqrt(param1[1]*param2[1])); + return_ptr->SetTypes(types); + return_ptr->SetParam(param); + return return_ptr; + } + + throw ost::Error("Forcefield does not contain lennard jones parameters for requested atom types!"); + +} + +MMInteractionPtr Forcefield::GetConstraint(const String& type1, + const String& type2){ + std::vector<String> types; + types.push_back(type1); + types.push_back(type2); + boost::unordered_map<String,MMInteractionPtr>::const_iterator i = + constraints_.find(this->AtomTypesToKeyword(types)); + if(i != constraints_.end()) return i->second; + throw ost::Error("Forcefield does not contain constraint for requested atom types!"); +} + +Real Forcefield::GetMass(const String& atom_type) const{ + boost::unordered_map<String,Real>::const_iterator it = atom_masses_.find(atom_type); + if(it == atom_masses_.end()){ + std::stringstream ss; + ss << "There is no mass defined for atom of type " << atom_type; + throw ost::Error(ss.str()); + } + return it->second; +} + +void Forcefield::AddBond(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"BOND"); + std::vector<String> types = p->GetTypes(); + bonds_[this->AtomTypesToKeyword(types)] = p; +} + +void Forcefield::AddAngle(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"ANGLE"); + std::vector<String> types = p->GetTypes(); + angles_[this->AtomTypesToKeyword(types)] = p; +} + +void Forcefield::AddDihedral(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"DIHEDRAL"); + std::vector<String> types = p->GetTypes(); + String keyword = this->AtomTypesToKeyword(types); + if(dihedrals_.find(keyword) == dihedrals_.end()){ + dihedrals_[keyword] = std::vector<MMInteractionPtr>(); + } + dihedrals_[keyword].push_back(p); +} + +void Forcefield::AddImproper(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"IMPROPER"); + std::vector<String> types = p->GetTypes(); + String keyword = this->AtomTypesToKeyword(types); + if(improper_dihedrals_.find(keyword) == improper_dihedrals_.end()){ + improper_dihedrals_[keyword] = std::vector<MMInteractionPtr>(); + } + improper_dihedrals_[keyword].push_back(p); +} + +void Forcefield::AddCMap(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"CMAP"); + std::vector<String> types = p->GetTypes(); + cmaps_[this->AtomTypesToKeyword(types,false)] = p; +} + +void Forcefield::AddImplicitGenborn(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"IMPLICIT_GENBORN"); + std::vector<String> types = p->GetTypes(); + implicit_genborn_[this->AtomTypesToKeyword(types)] = p; +} + +void Forcefield::AddLJ(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"LJ"); + std::vector<String> types = p->GetTypes(); + ljs_[types[0]] = p; +} + +void Forcefield::AddLJPair(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"LJ_PAIR"); + std::vector<String> types = p->GetTypes(); + lj_14_pairs_[this->AtomTypesToKeyword(types)] = p; +} + +void Forcefield::AddConstraint(MMInteractionPtr p){ + this->CheckInteractionToAdd(p,"CONSTRAINT"); + std::vector<String> types = p->GetTypes(); + constraints_[this->AtomTypesToKeyword(types)] = p; +} + +void Forcefield::AddResidueRenamingRule(const String& name, + const String& ff_main_name, + const String& ff_n_ter_name, + const String& ff_c_ter_name, + const String& ff_two_ter_name){ + ResidueNamesPtr p(new ResidueNames(ff_main_name, + ff_n_ter_name, + ff_c_ter_name, + ff_two_ter_name)); + res_renaming_ff_specific_[name] = p; +} + +void Forcefield::AddAtomRenamingRule(const String& res_name, + const String& old_atom_name, + const String& new_atom_name){ + if(atom_renaming_ff_specific_.find(res_name) == atom_renaming_ff_specific_.end()){ + std::vector<std::pair<String,String> > new_vec; + atom_renaming_ff_specific_[res_name] = new_vec; + } + + atom_renaming_ff_specific_[res_name].push_back(std::make_pair(old_atom_name,new_atom_name)); +} + +void Forcefield::AssignFFSpecificNames(ost::mol::EntityHandle& handle, bool reverse) const{ + + //the whole FF specific renaming procedure assumes a standard naming, + //in our case the gromacs defined standard naming + + ost::mol::XCSEditor ed = handle.EditXCS(); + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + ost::mol::AtomHandleList atom_list; + ost::mol::AtomHandle atom; + ost::mol::ResidueHandle residue; + + if(!reverse){ + + ost::mol::ResidueHandle next,prev; + bool n_ter,c_ter; + //ost::mol::AtomHandle peptide_n,peptide_c,nucleotide_p,nucleotide_o; + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + + if(res_renaming_ff_specific_.find(i->GetName()) == res_renaming_ff_specific_.end()){ + continue; + } + + n_ter = false; + c_ter = false; + + //peptide_n = i->FindAtom("N"); + //nucleotide_p = i->FindAtom("P"); + + prev = i->GetPrev(); + next = i->GetNext(); + + if(!prev.IsValid()){ + n_ter = true; + } + //else{ + //peptide_c = prev.FindAtom("C"); + //nucleotide_o = prev.FindAtom("O3"); + + //if(!ost::mol::BondExists(peptide_n,peptide_c) && !ost::mol::BondExists(nucleotide_p,nucleotide_o)){ + //n_ter = true; + //} + //} + + if(!next.IsValid()){ + c_ter = true; + } + //else{ + //peptide_n = next.FindAtom("N"); + //peptide_c = i->FindAtom("C"); + //nucleotide_p = next.FindAtom("P"); + //nucleotide_o = i->FindAtom("O3"); + + //if(!ost::mol::BondExists(peptide_n,peptide_c) && !ost::mol::BondExists(nucleotide_p,nucleotide_o)){ + //c_ter = true; + //} + //} + if(c_ter && n_ter){ + ed.RenameResidue(*i,res_renaming_ff_specific_.find(i->GetName())->second->twoter); + continue; + } + if(n_ter){ + ed.RenameResidue(*i,res_renaming_ff_specific_.find(i->GetName())->second->nter); + continue; + } + if(c_ter){ + ed.RenameResidue(*i,res_renaming_ff_specific_.find(i->GetName())->second->cter); + continue; + } + ed.RenameResidue(*i,res_renaming_ff_specific_.find(i->GetName())->second->main); + } + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin();i!=res_list.end();++i){ + boost::unordered_map<String,std::vector<std::pair<String,String> > >::const_iterator map_it = atom_renaming_ff_specific_.find(i->GetName()); + if(map_it!=atom_renaming_ff_specific_.end()){ + for(std::vector<std::pair<String,String> >::const_iterator j = map_it->second.begin(); + j!=map_it->second.end();++j){ + atom = i->FindAtom(j->first); + if(atom.IsValid()) ed.RenameAtom(atom,j->second); + } + } + } + return; + } + + //it seems, that we have to do the reverse ff renaming => ff specific to gromacs standard + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin();i!=res_list.end();++i){ + boost::unordered_map<String,std::vector<std::pair<String,String> > >::const_iterator map_it = atom_renaming_ff_specific_.find(i->GetName()); + if(map_it!=atom_renaming_ff_specific_.end()){ + for(std::vector<std::pair<String,String> >::const_iterator j = map_it->second.begin(); + j!=map_it->second.end();++j){ + atom = i->FindAtom(j->second); + if(atom.IsValid()) ed.RenameAtom(atom,j->first); + } + } + } + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); i != res_list.end(); ++i){ + for(boost::unordered_map<String,ResidueNamesPtr>::const_iterator j = res_renaming_ff_specific_.begin(); + j != res_renaming_ff_specific_.end(); ++j){ + if(j->second->Contains(i->GetName())){ + ed.RenameResidue(*i,j->first); + break; + } + } + } +} + +String Forcefield::AtomTypesToKeyword(std::vector<String>& types, bool allow_reordering) const{ + bool revert = false; + int num_types = types.size(); + + int comparisons = num_types/2; //integer division => truncate + for(int i = 0; i < comparisons; ++i){ + //note, that in case of equality the next iteration gets entered + if(types[i] < types[num_types - i - 1]) break; + else if(types[i] > types[num_types - i - 1]){ + revert = true; + break; + } + } + + if(revert && allow_reordering) std::reverse(types.begin(),types.end()); + std::stringstream ss; + std::vector<String>::iterator i = types.begin(); + ss << *i++; + for (; i != types.end(); ++i) { + ss << "_" << *i; + } + return ss.str(); +} + +void Forcefield::CheckInteractionToAdd(MMInteractionPtr p, const String& interaction_type) const{ + bool valid = true; + if(p->GetTypes().empty()) valid = false; + if(!p->IsParametrized()) valid = false; + if(!valid){ + throw ost::Error("Expect interaction to have types and parameters properly set!"); + } + if(interaction_type == "BOND"){ + if(p->GetFuncType() != HarmonicBond){ + throw ost::Error("Invalid function type encountered when adding bond!"); + } return; + } + if(interaction_type == "ANGLE"){ + if(p->GetFuncType() != HarmonicAngle && p->GetFuncType() != UreyBradleyAngle){ + throw ost::Error("Invalid function type encountered when adding angle!"); + } return; + } + if(interaction_type == "DIHEDRAL"){ + if(p->GetFuncType() != PeriodicDihedral){ + throw ost::Error("Invalid function type encountered when adding dihedral!"); + } return; + } + if(interaction_type == "IMPROPER"){ + if(p->GetFuncType() != PeriodicImproper && p->GetFuncType() != HarmonicImproper){ + throw ost::Error("Invalid function type encountered when adding improper!"); + } return; + } + if(interaction_type == "CMAP"){ + if(p->GetFuncType() != CMap){ + throw ost::Error("Invalid function type encountered when adding cmap!"); + } return; + } + if(interaction_type == "IMPLICIT_GENBORN"){ + if(p->GetFuncType() != GBSA){ + throw ost::Error("Invalid function type encountered when adding implicit genborn!"); + } return; + } + if(interaction_type == "LJ"){ + if(p->GetFuncType() != LJ){ + throw ost::Error("Invalid function type encountered when adding lj!"); + } return; + } + if(interaction_type == "LJ_PAIR"){ + if(p->GetFuncType() != LJPair){ + throw ost::Error("Invalid function type encountered when adding lj pair!"); + } return; + } + if(interaction_type == "CONSTRAINT"){ + if(p->GetFuncType() != DistanceConstraint){ + throw ost::Error("Invalid function type encountered when adding constraint!"); + } return; + } + + std::stringstream ss; + ss << "Cannot validate added interaction of type "<< interaction_type << "!"; + throw ost::Error(ss.str()); + +} + +}}}//ns diff --git a/modules/mol/mm/src/forcefield.hh b/modules/mol/mm/src/forcefield.hh new file mode 100644 index 0000000000000000000000000000000000000000..e5d39ad321e8774a91388618481396241762a70b --- /dev/null +++ b/modules/mol/mm/src/forcefield.hh @@ -0,0 +1,204 @@ +#ifndef OST_FORCE_FIELD_HH +#define OST_FORCE_FIELD_HH + +#include <vector> +#include <algorithm> + + +#include <boost/shared_ptr.hpp> +#include <boost/unordered_map.hpp> + +#include <ost/message.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> + +namespace ost { namespace mol{ namespace mm{ + +struct ResidueNames; +class Forcefield; + +typedef boost::shared_ptr<ResidueNames> ResidueNamesPtr; +typedef boost::shared_ptr<ost::mol::mm::Forcefield> ForcefieldPtr; + +struct ResidueNames{ + + ResidueNames() { }; + + ResidueNames(String a, String b, String c, String d): + main(a),nter(b),cter(c),twoter(d) { } + + String main; + String nter; + String cter; + String twoter; + + bool Contains(const String& name){ + return name == main || name == nter || name == cter || name == twoter; + } + + template <typename DS> + void Serialize(DS& ds){ + ds & main; + ds & nter; + ds & cter; + ds & twoter; + } +}; + + +class Forcefield { +public: + + Forcefield(): gen_pairs_(true), fudge_LJ_(1.0),fudge_QQ_(1.0) { } + + static ForcefieldPtr Load(const String& filename); + + void Save(const String& filename); + + //Getter functions + + BuildingBlockPtr GetBuildingBlock(const String& name) const; + + BlockModifierPtr GetBlockModifier(const String& modifier_name) const; + + String GetAtomType(const String& res_name, const String& atom_name) const; + + HydrogenConstructorPtr GetHydrogenConstructor(const String& name) const; + + BlockModifierPtr GetNTerModifier(const String& res_name, const String& ter_name = "") const; + + BlockModifierPtr GetCTerModifier(const String& res_name, const String& ter_name = "") const; + + MMInteractionPtr GetBond(const String& type1, + const String& type2) const; + + MMInteractionPtr GetAngle(const String& type1, + const String& type2, + const String& type3) const; + + std::vector<MMInteractionPtr> GetDihedrals(const String& type1, + const String& type2, + const String& type3, + const String& type4) const; + + std::vector<MMInteractionPtr> GetImpropers(const String& type1, + const String& type2, + const String& type3, + const String& type4) const; + + MMInteractionPtr GetCMap(const String& type1, + const String& type2, + const String& type3, + const String& type4, + const String& type5) const; + + MMInteractionPtr GetImplicitGenborn(const String& type1) const; + + MMInteractionPtr GetLJ(const String& type1, + const String& type2, + bool pair=false) const; + + MMInteractionPtr GetLJ(const String& type) const; + + MMInteractionPtr GetConstraint(const String& type1, + const String& type2); + + Real GetMass(const String& type) const; + + Real GetFudgeLJ() const { return fudge_LJ_; } + + Real GetFudgeQQ() const { return fudge_QQ_; } + + //functions to add interactions and settings + + void AddBuildingBlock(const String& name, BuildingBlockPtr p) { building_blocks_[name] = p; } + + void AddBond(MMInteractionPtr p); + + void AddAngle(MMInteractionPtr p); + + void AddDihedral(MMInteractionPtr p); + + void AddImproper(MMInteractionPtr p); + + void AddCMap(MMInteractionPtr p); + + void AddImplicitGenborn(MMInteractionPtr p); + + void AddLJ(MMInteractionPtr p); + + void AddLJPair(MMInteractionPtr p); + + void AddConstraint(MMInteractionPtr p); + + void AddMass(const String& type, Real mass) { atom_masses_[type] = mass; } + + void SetFudgeLJ(Real f_lj) { fudge_LJ_ = f_lj; } + + void SetFudgeQQ(Real f_qq) { fudge_QQ_ = f_qq; } + + void SetGenPairs(bool gen_pairs) { gen_pairs_ = gen_pairs; } + + void AddResidueRenamingRule(const String& name, + const String& ff_main_name, + const String& ff_n_ter_name, + const String& ff_c_ter_name, + const String& ff_two_ter_name); + + void AddAtomRenamingRule(const String& res_name, + const String& old_atom_name, + const String& new_atom_name); + + void AddHydrogenConstructor(const String& residue_name, HydrogenConstructorPtr p){ + hydrogen_constructors_[residue_name] = p; + } + + void AddBlockModifier(const String& modifier_name, + BlockModifierPtr p) { block_modifiers_[modifier_name] = p; } + + void SetStandardCTer(const String& res_name, const String& ter_name) { standard_c_termini_[res_name] = ter_name; } + + void SetStandardNTer(const String& res_name, const String& ter_name) { standard_n_termini_[res_name] = ter_name; } + + + //Renaming to the forcefield specific names (residues/atoms) + void AssignFFSpecificNames(ost::mol::EntityHandle& handle, bool reverse=false) const; + +private: + + String AtomTypesToKeyword(std::vector<String>& types, bool allow_reordering = true) const; + void CheckInteractionToAdd(MMInteractionPtr p, const String& interaction_type) const; + + //this is all nonbonded stuff + bool gen_pairs_; + Real fudge_LJ_; + Real fudge_QQ_; + + boost::unordered_map<String, Real> atom_masses_; + boost::unordered_map<String, BuildingBlockPtr> building_blocks_; + boost::unordered_map<String, BlockModifierPtr> block_modifiers_; + + //the standard interactions + boost::unordered_map<String,MMInteractionPtr> bonds_; + boost::unordered_map<String,MMInteractionPtr> angles_; + boost::unordered_map<String,MMInteractionPtr> lj_14_pairs_; + boost::unordered_map<String,MMInteractionPtr> constraints_; + boost::unordered_map<String,MMInteractionPtr> cmaps_; + boost::unordered_map<String,MMInteractionPtr> implicit_genborn_; + boost::unordered_map<String,MMInteractionPtr> ljs_; + boost::unordered_map<String,std::vector<MMInteractionPtr> > dihedrals_; + boost::unordered_map<String,std::vector<MMInteractionPtr> > improper_dihedrals_; + + boost::unordered_map<String, std::vector<std::pair<String,String> > > atom_renaming_ff_specific_; + boost::unordered_map<String, ResidueNamesPtr> res_renaming_ff_specific_; + + boost::unordered_map<String, HydrogenConstructorPtr> hydrogen_constructors_; + boost::unordered_map<String, String> standard_n_termini_; + boost::unordered_map<String, String> standard_c_termini_; +}; + +}}}//ns + +#endif diff --git a/modules/mol/mm/src/gromacs_block_modifiers.cc b/modules/mol/mm/src/gromacs_block_modifiers.cc new file mode 100644 index 0000000000000000000000000000000000000000..0a8f74c96d19e172a350e55e5fcc99834e9f00b4 --- /dev/null +++ b/modules/mol/mm/src/gromacs_block_modifiers.cc @@ -0,0 +1,506 @@ +#include <ost/mol/mm/gromacs_block_modifiers.hh> + +namespace ost{ namespace mol{ namespace mm{ + +std::vector<geom::Vec3> GromacsPositionRuleEvaluator::EvaluatePosRule(int rule, + int number, + const std::vector<geom::Vec3>& anchors){ + + std::vector<geom::Vec3> positions; + + switch(rule){ + + case 1:{ + geom::Vec3 i_j = geom::Normalize(anchors[0]-anchors[1]); + geom::Vec3 i_k = geom::Normalize(anchors[0]-anchors[2]); + geom::Vec3 temp = geom::Normalize(i_j+i_k); + positions.push_back(anchors[0]+temp); + break; + } + + case 2:{ + Real x = 0.333806859234; + Real y = 0.942641491092; + + geom::Vec3 i = anchors[0]; + geom::Vec3 j = anchors[1]; + geom::Vec3 k = anchors[2]; + + geom::Vec3 j_i = geom::Normalize(i-j); + geom::Vec3 q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + positions.push_back(i+x*j_i+y*q); + break; + } + + case 3:{ + Real x = 0.5; + Real y = 0.866025403784; + + geom::Vec3 i = anchors[0]; + geom::Vec3 j = anchors[1]; + geom::Vec3 k = anchors[2]; + + geom::Vec3 j_i = geom::Normalize(i-j); + geom::Vec3 q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + positions.push_back(i+x*j_i-y*q); + positions.push_back(i+x*j_i+y*q); + break; + } + + case 4:{ + Real x = 0.333313247568; + Real y = 0.942816142732; + Real z = 0.866025403784; + + + geom::Vec3 i = anchors[0]; + geom::Vec3 j = anchors[1]; + geom::Vec3 k = anchors[2]; + + geom::Vec3 j_i = geom::Normalize(i-j); + geom::Vec3 q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + geom::Vec3 n1 = i+x*j_i+y*q; + + geom::Vec3 temp = geom::Normalize(geom::Cross(j_i,n1-i)); + + geom::Vec3 n2 = i+x*j_i-0.5*q+z*temp; + geom::Vec3 n3 = i+x*j_i-0.5*q-z*temp; + + positions.push_back(n1); + positions.push_back(n2); + if(number==3) positions.push_back(n3); + break; + } + + case 5:{ + geom::Vec3 i = anchors[0]; + geom::Vec3 i_j = geom::Normalize(i-anchors[1]); + geom::Vec3 i_k = geom::Normalize(i-anchors[2]); + geom::Vec3 i_l = geom::Normalize(i-anchors[3]); + geom::Vec3 temp = geom::Normalize(i_j+i_k+i_l); + positions.push_back(i+temp); + break; + } + + case 6:{ + Real x = 0.81649043092; + Real y = 0.577358966516; + + geom::Vec3 i = anchors[0]; + geom::Vec3 i_j = geom::Normalize(i-anchors[1]); + geom::Vec3 i_k = geom::Normalize(i-anchors[2]); + geom::Vec3 temp_one = geom::Normalize(i_j+i_k); + geom::Vec3 temp_two = geom::Normalize(geom::Cross(i_j,i_k)); + positions.push_back(i+y*temp_one+x*temp_two); + positions.push_back(i+y*temp_one-x*temp_two); + break; + } + + case 7:{ + //not implemented yet, do nothing + break; + } + + case 8:{ + Real x = 1.36*0.522498564716; + Real y = 1.36*0.852640164354; + + geom::Vec3 i = anchors[0]; + geom::Vec3 j = anchors[1]; + geom::Vec3 k = anchors[2]; + + geom::Vec3 j_i = geom::Normalize(i-j); + geom::Vec3 q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + positions.push_back(i+x*j_i-y*q); + positions.push_back(i+x*j_i+y*q); + break; + } + + case 9:{ + Real x1 = 1.23*0.51503807491; + Real x2 = 1.25*0.422618261741; + Real y1 = 1.23*0.857167300702; + Real y2 = 1.25*0.906307787037; + + geom::Vec3 i = anchors[0]; + geom::Vec3 j = anchors[1]; + geom::Vec3 k = anchors[2]; + + geom::Vec3 j_i = geom::Normalize(i-j); + geom::Vec3 q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + positions.push_back(i+x1*j_i-y1*q); + positions.push_back(i+x2*j_i+y2*q); + + //we have to construct a third position hanging at the second one... + + Real x = 0.333806859234; + Real y = 0.942641491092; + + std::vector<geom::Vec3> new_anchors; + new_anchors.push_back(positions[2]); + new_anchors.push_back(anchors[0]); + new_anchors.push_back(anchors[1]); + + i = new_anchors[0]; + j = new_anchors[1]; + k = new_anchors[2]; + + j_i = geom::Normalize(i-j); + q = geom::Normalize(geom::Cross(geom::Cross(k-j,j_i),j_i)); + + positions.push_back(i+x*j_i+y*q); + break; + } + + case 10:{ + //not implemented yet, do nothing + break; + } + + case 11:{ + //not implemented yet, do nothing + break; + } + + default:{ + break; + } + } + return positions; +} + + +void GromacsHydrogenConstructor::ApplyOnBuildingBlock(BuildingBlockPtr p){ + //we assume, that the hydrogens are already correct in the building block... +} + +void GromacsHydrogenConstructor::ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed){ + + if(!res.IsValid()) return; + + int number; + int method; + String prefix; + + std::vector<String> anchor_names; + ost::mol::AtomHandleList anchor_atoms; + + std::vector<String> hydrogen_names; + std::vector<geom::Vec3> hydrogen_positions; + std::vector<geom::Vec3> anchor_positions; + + bool hydrogens_present; + + for(uint a=0;a<add_number_.size();++a){ + + hydrogen_names = hydrogen_names_[a]; + + /* + bool hydrogens_present = true; + for(std::vector<String>::iterator i = hydrogen_names.begin(); + i != hydrogen_names.end(); ++i){ + if(!res.FindAtom(*i).IsValid()){ + hydrogens_present = false; + break; + } + } + + if(hydrogens_present) continue; + */ + number = add_number_[a]; + method = methods_[a]; + anchor_names = anchor_atom_names_[a]; + + hydrogen_positions.clear(); + anchor_positions.clear(); + anchor_atoms.clear(); + + + + String atom_name; + ost::mol::ResidueHandle temp_res; + ost::mol::AtomHandle atom; + bool found_anchors = true; + + for(std::vector<String>::iterator it = anchor_names.begin();it!=anchor_names.end();++it){ + + temp_res = res; + atom_name = *it; + + if(atom_name[0] == '-'){ + atom_name.erase(0,1); + temp_res = res.GetPrev(); + if(!temp_res.IsValid()){ + //happens in case of termini... In this case the adding definitions + //are taken from the termini database... + found_anchors = false; + break; + } + } + if(atom_name[0] == '+'){ + atom_name.erase(0,1); + temp_res = res.GetNext(); + if(!temp_res.IsValid()){ + //happens in case of termini... In this case the adding definitions + //are taken from the termini database... + found_anchors = false; + break; + } + } + + atom = temp_res.FindAtom(atom_name); + if(!atom.IsValid()){ + std::stringstream ss; + ss << "cannot find required anchor atom " << atom_name << " in residue "; + ss << res.GetQualifiedName() << " to add hydrogen!"; + throw ost::Error(ss.str()); + } + + anchor_atoms.push_back(atom); + anchor_positions.push_back(atom.GetPos()); + } + + if(!found_anchors){ + continue; + } + + hydrogen_positions = GromacsPositionRuleEvaluator::EvaluatePosRule(method, + number, + anchor_positions); + + for(int b=0;b<number;++b){ + //only add hydrogen if not already present! + atom = res.FindAtom(hydrogen_names[b]); + if(!atom.IsValid()){ + atom = ed.InsertAtom(res,hydrogen_names[b],hydrogen_positions[b],"H"); + } + //ed.Connect(atom, anchor_atoms[0]); + } + } +} + + +void GromacsHydrogenConstructor::AddHydrogenRule(uint number, int method, + const std::vector<String>& hydrogen_names, + const std::vector<String>& anchors){ + + if(number != hydrogen_names.size()){ + std::stringstream ss; + ss << "Tried to add hydrogen rule to hydrogen constructor with add number "; + ss << number << ", but "<< hydrogen_names.size() << "hydrogen names"; + } + + hydrogen_names_.push_back(hydrogen_names); + add_number_.push_back(number); + methods_.push_back(method); + anchor_atom_names_.push_back(anchors); +} + +void GromacsBlockModifier::AddReplaceRule(const String& name, const String& new_name, + const String& new_type, Real new_charge){ + replace_old_atom_name_.push_back(name); + replace_new_atom_name_.push_back(new_name); + replace_new_atom_type_.push_back(new_type); + replace_new_charge_.push_back(new_charge); +} + +void GromacsBlockModifier::AddAddRule(int number, int method, + const std::vector<String>& atom_names, + const std::vector<String>& anchors, + const String& type, Real charge){ + add_add_number_.push_back(number); + add_methods_.push_back(method); + add_atom_names_.push_back(atom_names); + add_anchor_atom_names_.push_back(anchors); + add_atom_types_.push_back(type); + add_charges_.push_back(charge); +} + +void GromacsBlockModifier::ApplyOnBuildingBlock(BuildingBlockPtr p){ + + //let's resolve the replace statement + for(uint i = 0; i < replace_old_atom_name_.size(); ++i){ + p->ReplaceAtom(replace_old_atom_name_[i], replace_new_atom_name_[i], + replace_new_atom_type_[i], replace_new_charge_[i]); + + } + //let's resolve the add statement + for(uint i = 0; i < add_add_number_.size(); ++i){ + String type = add_atom_types_[i]; + Real charge = add_charges_[i]; + std::vector<String> anchor_atoms = add_anchor_atom_names_[i]; + std::vector<String> names = add_atom_names_[i]; + + //let's add the stuff to the buildingblock + for(std::vector<String>::iterator j = names.begin(); + j != names.end(); ++j){ + p->AddAtom(*j,type,charge); + //the bond, that connects the newly added atom to its anchor is not necessarily + //defined. Let's add it here. Note, that nothing happens, if this specific bond + //is already part of the building block. + MMInteractionPtr b_p(new MMInteraction(p->GetBonds()[0]->GetFuncType())); + std::vector<String> bond_names; + std::vector<String> bond_types; + bond_names.push_back(anchor_atoms[0]); + bond_names.push_back(*j); + bond_types.push_back(p->GetType(anchor_atoms[0])); + bond_types.push_back(type); + b_p->SetNames(bond_names); + b_p->SetTypes(bond_types); + p->AddBond(b_p); + } + } + + //let's resolve the delete statement + for(std::vector<String>::iterator i = delete_atom_names_.begin(); + i != delete_atom_names_.end(); ++i){ + p->RemoveAtom(*i); + } + + //we simply add the new interactions to the building block + for(std::vector<MMInteractionPtr>::iterator i = bonds_.begin(); + i != bonds_.end(); ++i){ + p->AddBond(*i, true); + } + + for(std::vector<MMInteractionPtr>::iterator i = angles_.begin(); + i != angles_.end(); ++i){ + p->AddAngle(*i, true); + } + + for(std::vector<MMInteractionPtr>::iterator i = dihedrals_.begin(); + i != dihedrals_.end(); ++i){ + p->AddDihedral(*i, true); + } + + for(std::vector<MMInteractionPtr>::iterator i = impropers_.begin(); + i != impropers_.end(); ++i){ + p->AddImproper(*i, true); + } + + for(std::vector<MMInteractionPtr>::iterator i = cmaps_.begin(); + i != cmaps_.end(); ++i){ + p->AddCMap(*i, true); + } +} + +void GromacsBlockModifier::ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed){ + + //let's resolve the replace statement + for(uint i = 0; i < replace_old_atom_name_.size(); ++i){ + ost::mol::AtomHandle at = res.FindAtom(replace_old_atom_name_[i]); + if(at.IsValid()){ + ed.RenameAtom(at,replace_new_atom_name_[i]); + } + } + + + //let's resolve the add statement + for(uint i = 0; i < add_add_number_.size(); ++i){ + int number = add_add_number_[i]; + int method = add_methods_[i]; + std::vector<String> anchor_names = add_anchor_atom_names_[i]; + //String type = add_atom_types_[i]; + std::vector<geom::Vec3> anchor_positions; + ost::mol::AtomHandleList anchor_atoms; + std::vector<String> names = add_atom_names_[i]; + + for(std::vector<String>::iterator j = anchor_names.begin(); + j != anchor_names.end(); ++j){ + ost::mol::AtomHandle at = res.FindAtom(*j); + if(!at.IsValid()){ + std::stringstream ss; + ss << "Cannot find anchor atom required to construct termini"; + ss << " in provided residue!"; + throw ost::Error(ss.str()); + } + anchor_positions.push_back(at.GetPos()); + anchor_atoms.push_back(at); + } + std::vector<geom::Vec3> positions = GromacsPositionRuleEvaluator::EvaluatePosRule(method, + number, + anchor_positions); + + String ele = "H"; + if(method == 8 || method == 9){ + ele = "O"; + } + for(int j=0; j<number; ++j){ + ost::mol::AtomHandle at = res.FindAtom(names[j]); + if(!at.IsValid()) at = ed.InsertAtom(res,names[j],positions[j],ele); + ed.Connect(at, anchor_atoms[0]); + } + } + //let's resolve the delete statement + for(std::vector<String>::iterator i = delete_atom_names_.begin(); + i != delete_atom_names_.end(); ++i){ + ost::mol::AtomHandle at = res.FindAtom(*i); + if(at.IsValid()){ + ed.DeleteAtom(at); + } + } +} + + +void GromacsBlockModifier::CheckInteractionToAdd(MMInteractionPtr p, const String& interaction_type) const{ + if(p->GetNames().empty()) throw ost::Error("Expect interaction to have names properly set!"); + + if(interaction_type == "BOND"){ + if(p->GetFuncType() != HarmonicBond){ + throw ost::Error("Invalid function type encountered when adding bond!"); + } return; + } + if(interaction_type == "ANGLE"){ + if(p->GetFuncType() != HarmonicAngle && p->GetFuncType() != UreyBradleyAngle){ + throw ost::Error("Invalid function type encountered when adding angle!"); + } return; + } + if(interaction_type == "DIHEDRAL"){ + if(p->GetFuncType() != PeriodicDihedral){ + throw ost::Error("Invalid function type encountered when adding dihedral!"); + } return; + } + if(interaction_type == "IMPROPER"){ + if(p->GetFuncType() != PeriodicImproper && p->GetFuncType() != HarmonicImproper){ + throw ost::Error("Invalid function type encountered when adding improper!"); + } return; + } + if(interaction_type == "CMAP"){ + if(p->GetFuncType() != CMap){ + throw ost::Error("Invalid function type encountered when adding cmap!"); + } return; + } + + std::stringstream ss; + ss << "Cannot validate added interaction of type "<< interaction_type << "!"; + throw ost::Error(ss.str()); + +} + + + + +}}}//ns + + + + + + + + + + + + + + + + + + diff --git a/modules/mol/mm/src/gromacs_block_modifiers.hh b/modules/mol/mm/src/gromacs_block_modifiers.hh new file mode 100644 index 0000000000000000000000000000000000000000..e5621f9e772b4ea3cf9d9bdb8783302695d9d7e5 --- /dev/null +++ b/modules/mol/mm/src/gromacs_block_modifiers.hh @@ -0,0 +1,309 @@ +#ifndef GROMCACS_BLOCK_MODIFIERS +#define GROMCACS_BLOCK_MODIFIERS + + +#include <boost/shared_ptr.hpp> + +#include <ost/message.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/geom/vec3.hh> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/buildingblock.hh> + + +namespace ost{ namespace mol{ namespace mm{ + +class GromacsHydrogenConstructor; +class GromacsTerminiConstructor; +class GromacsBlockModifier; + +typedef boost::shared_ptr<GromacsHydrogenConstructor> GromacsHydrogenConstructorPtr; +typedef boost::shared_ptr<GromacsTerminiConstructor> GromacsTerminiConstructorPtr; +typedef boost::shared_ptr<GromacsBlockModifier> GromacsBlockModifierPtr; + +class GromacsPositionRuleEvaluator{ + +public: + static std::vector<geom::Vec3> EvaluatePosRule(int rule, int number, + const std::vector<geom::Vec3>& anchors); +}; + +class GromacsHydrogenConstructor : public HydrogenConstructor{ + +public: + + GromacsHydrogenConstructor() { } + + virtual void ApplyOnBuildingBlock(BuildingBlockPtr); + + virtual void ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed); + + void AddHydrogenRule(uint number, int method, + const std::vector<String>& hydrogen_names, + const std::vector<String>& anchors); + + virtual void OnSave(ost::io::BinaryDataSink& ds) { ds << *this; } + + virtual BlockModifierType GetBlockModifierType() { return GromacsBlockModifiers; } + + template <typename DS> + void Serialize(DS& ds){ + int num_hydrogen_add_rules = add_number_.size(); + ds & num_hydrogen_add_rules; + + if(ds.IsSource()){ + add_number_ = std::vector<int>(num_hydrogen_add_rules); + methods_ = std::vector<int>(num_hydrogen_add_rules); + hydrogen_names_ = std::vector<std::vector<String> >(num_hydrogen_add_rules); + anchor_atom_names_ = std::vector<std::vector<String> >(num_hydrogen_add_rules); + } + + for(int i = 0; i < num_hydrogen_add_rules; ++i){ + ds & add_number_[i]; + ds & methods_[i]; + int num_hydrogen_names = hydrogen_names_[i].size(); + int num_anchor_names = anchor_atom_names_[i].size(); + ds & num_hydrogen_names; + ds & num_anchor_names; + if(ds.IsSource()){ + hydrogen_names_[i] = std::vector<String>(num_hydrogen_names); + anchor_atom_names_[i] = std::vector<String>(num_anchor_names); + } + + for(int j = 0; j < num_hydrogen_names; ++j){ + ds & hydrogen_names_[i][j]; + } + for(int j = 0; j < num_anchor_names; ++j){ + ds & anchor_atom_names_[i][j]; + } + } + } + +private: + std::vector<int> add_number_; + std::vector<int> methods_; + std::vector<std::vector<String> > hydrogen_names_; + std::vector<std::vector<String> > anchor_atom_names_; +}; + + +class GromacsBlockModifier : public BlockModifier{ + +public: + + GromacsBlockModifier() { } + + virtual void ApplyOnBuildingBlock(BuildingBlockPtr p); + + virtual void ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& ed); + + void AddReplaceRule(const String& name, const String& new_name, + const String& new_type, Real new_charge); + + void AddAddRule(int number, int method, + const std::vector<String>& atom_names, + const std::vector<String>& anchors, + const String& type, Real charge); + + void AddBond(MMInteractionPtr p) { this->CheckInteractionToAdd(p,"BOND"); + bonds_.push_back(p); } + + void AddAngle(MMInteractionPtr p) { this->CheckInteractionToAdd(p,"ANGLE"); + angles_.push_back(p); } + + void AddDihedral(MMInteractionPtr p) { this->CheckInteractionToAdd(p,"DIHEDRAL"); + dihedrals_.push_back(p); } + + void AddImproper(MMInteractionPtr p) { this->CheckInteractionToAdd(p,"IMPROPER"); + impropers_.push_back(p); } + + void AddCMap(MMInteractionPtr p) { this->CheckInteractionToAdd(p,"CMAP"); + cmaps_.push_back(p); } + + void AddDeleteAtom(const String& atom_name) { delete_atom_names_.push_back(atom_name); } + + virtual void OnSave(ost::io::BinaryDataSink& ds) { ds << *this; } + + virtual BlockModifierType GetBlockModifierType() { return GromacsBlockModifiers; } + + template <typename DS> + void Serialize(DS& ds){ + + int num_bonds = bonds_.size(); + int num_angles = angles_.size(); + int num_dihedrals = dihedrals_.size(); + int num_impropers = impropers_.size(); + int num_cmaps = cmaps_.size(); + + ds & num_bonds; + ds & num_angles; + ds & num_dihedrals; + ds & num_impropers; + ds & num_cmaps; + + for(int i = 0; i < num_bonds; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + bonds_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = bonds_[i]->GetFuncType(); + ds & func_type; + } + ds & *(bonds_[i]); + } + + for(int i = 0; i < num_angles; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + angles_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = angles_[i]->GetFuncType(); + ds & func_type; + } + ds & *(angles_[i]); + } + + for(int i = 0; i < num_dihedrals; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + dihedrals_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = dihedrals_[i]->GetFuncType(); + ds & func_type; + } + ds & *(dihedrals_[i]); + } + + for(int i = 0; i < num_impropers; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + impropers_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = impropers_[i]->GetFuncType(); + ds & func_type; + } + ds & *(impropers_[i]); + } + + for(int i = 0; i < num_cmaps; ++i){ + int func_type; + if(ds.IsSource()){ + ds & func_type; + cmaps_.push_back(MMInteractionPtr(new MMInteraction(FuncType(func_type)))); + } + else{ + func_type = cmaps_[i]->GetFuncType(); + ds & func_type; + } + ds & *(cmaps_[i]); + } + + int num_replace_atoms = replace_old_atom_name_.size(); + ds & num_replace_atoms; + + if(ds.IsSource()){ + replace_old_atom_name_ = std::vector<String>(num_replace_atoms); + replace_new_atom_name_ = std::vector<String>(num_replace_atoms); + replace_new_atom_type_ = std::vector<String>(num_replace_atoms); + replace_new_charge_ = std::vector<Real>(num_replace_atoms); + } + + for(int i = 0; i < num_replace_atoms; ++i){ + ds & replace_old_atom_name_[i]; + ds & replace_new_atom_name_[i]; + ds & replace_new_atom_type_[i]; + ds & replace_new_charge_[i]; + } + + int num_add_atoms = add_add_number_.size(); + ds & num_add_atoms; + + if(ds.IsSource()){ + add_add_number_ = std::vector<int>(num_add_atoms); + add_methods_ = std::vector<int>(num_add_atoms); + add_atom_names_ = std::vector<std::vector<String> >(num_add_atoms); + add_anchor_atom_names_ = std::vector<std::vector<String> >(num_add_atoms); + add_atom_types_ = std::vector<String>(num_add_atoms); + add_charges_ = std::vector<Real>(num_add_atoms); + } + + for(int i = 0; i < num_add_atoms; ++i){ + ds & add_add_number_[i]; + ds & add_methods_[i]; + ds & add_atom_types_[i]; + ds & add_charges_[i]; + int num_add_atom_names = add_atom_names_[i].size(); + int num_add_anchor_atom_names = add_anchor_atom_names_[i].size(); + ds & num_add_atom_names; + ds & num_add_anchor_atom_names; + if(ds.IsSource()){ + add_atom_names_[i] = std::vector<String>(num_add_atom_names); + add_anchor_atom_names_[i] = std::vector<String>(num_add_anchor_atom_names); + } + for(int j = 0; j < num_add_atom_names; ++j){ + ds & add_atom_names_[i][j]; + } + for(int j = 0; j < num_add_anchor_atom_names; ++j){ + ds & add_anchor_atom_names_[i][j]; + } + } + + int num_delete_atoms = delete_atom_names_.size(); + ds & num_delete_atoms; + if(ds.IsSource()){ + delete_atom_names_ = std::vector<String>(num_delete_atoms); + } + for(int i = 0; i < num_delete_atoms; ++i){ + ds & delete_atom_names_[i]; + } + } + +private: + + void CheckInteractionToAdd(MMInteractionPtr p, const String& interaction_type) const; + + //Atoms, that will be added to the building block + + //Interactions, that will be added to the building block + std::vector<MMInteractionPtr> bonds_; + std::vector<MMInteractionPtr> angles_; + std::vector<MMInteractionPtr> dihedrals_; + std::vector<MMInteractionPtr> impropers_; + std::vector<MMInteractionPtr> cmaps_; + + //paramters we need for the replace statement + std::vector<String> replace_old_atom_name_; + std::vector<String> replace_new_atom_name_; + std::vector<String> replace_new_atom_type_; + std::vector<Real> replace_new_charge_; + + //parameters we need for the add statement => gromacs dependent rules! + std::vector<int> add_add_number_; + std::vector<int> add_methods_; + std::vector<std::vector<String> > add_atom_names_; + std::vector<std::vector<String> > add_anchor_atom_names_; + std::vector<String> add_atom_types_; + std::vector<Real> add_charges_; + + //parameters we need for the delete statement + std::vector<String> delete_atom_names_; +}; + + + + +}}} + +#endif diff --git a/modules/mol/mm/src/gromacs_reader.cc b/modules/mol/mm/src/gromacs_reader.cc new file mode 100644 index 0000000000000000000000000000000000000000..e6fed54ac29ceef9bc77c325183b44d8fb54020f --- /dev/null +++ b/modules/mol/mm/src/gromacs_reader.cc @@ -0,0 +1,2073 @@ +#include <ost/mol/mm/gromacs_reader.hh> + + +namespace ost { namespace mol{ namespace mm { + + +GromacsData::GromacsData(){ + keyword_map_["atoms"] = 0; + keyword_map_["bonds"] = 1; + keyword_map_["angles"] = 2; + keyword_map_["impropers"] = 3; + keyword_map_["dihedrals"] = 4; + keyword_map_["exclusions"] = 5; + keyword_map_["cmap"] = 6; + keyword_map_["replace"] = 7; + keyword_map_["moleculetype"] = 8; + keyword_map_["add"] = 9; + keyword_map_["delete"] = 10; + keyword_map_["bondtypes"] = 11; + keyword_map_["constrainttypes"] = 12; + keyword_map_["angletypes"] = 13; + keyword_map_["dihedraltypes"] = 14; + keyword_map_["atomtypes"] = 15; + keyword_map_["implicit_genborn_params"] = 16; + keyword_map_["pairtypes"] = 17; + keyword_map_["nonbond_params"] = 18; + keyword_map_["defaults"] = 19; + keyword_map_["cmaptypes"] = 20; + keyword_map_["pairs"] = 21; + keyword_map_["settles"] = 22; + + + renaming_to_standard_["ILE"] = std::vector<std::pair<String,String> >(); + renaming_to_standard_["HOH"] = std::vector<std::pair<String,String> >(); + renaming_to_standard_["HO4"] = std::vector<std::pair<String,String> >(); + renaming_to_standard_["HO5"] = std::vector<std::pair<String,String> >(); + renaming_to_standard_["HEME"] = std::vector<std::pair<String,String> >(); + renaming_to_standard_["protein"] = std::vector<std::pair<String,String> >(); + + renaming_to_standard_["ILE"].push_back(std::make_pair("CD1","CD")); + renaming_to_standard_["ILE"].push_back(std::make_pair("HD11","HD1")); + renaming_to_standard_["ILE"].push_back(std::make_pair("HD12","HD2")); + renaming_to_standard_["ILE"].push_back(std::make_pair("HD13","HD3")); + + renaming_to_standard_["HOH"].push_back(std::make_pair("O","OW")); + renaming_to_standard_["HOH"].push_back(std::make_pair("OW1","OW")); + renaming_to_standard_["HO4"].push_back(std::make_pair("O","OW")); + renaming_to_standard_["HO4"].push_back(std::make_pair("OW1","OW")); + renaming_to_standard_["HO5"].push_back(std::make_pair("O","OW")); + renaming_to_standard_["HO5"].push_back(std::make_pair("OW1","OW")); + + renaming_to_standard_["HEME"].push_back(std::make_pair("N_A","NA")); + renaming_to_standard_["HEME"].push_back(std::make_pair("N_B","NB")); + renaming_to_standard_["HEME"].push_back(std::make_pair("N_C","NC")); + renaming_to_standard_["HEME"].push_back(std::make_pair("N_D","ND")); + + renaming_to_standard_["protein"].push_back(std::make_pair("O1","O")); + renaming_to_standard_["protein"].push_back(std::make_pair("O2","OXT")); + renaming_to_standard_["protein"].push_back(std::make_pair("OT1","O")); + renaming_to_standard_["protein"].push_back(std::make_pair("OT2","OXT")); + renaming_to_standard_["protein"].push_back(std::make_pair("OT","OXT")); + renaming_to_standard_["protein"].push_back(std::make_pair("O'","O")); + renaming_to_standard_["protein"].push_back(std::make_pair("O''","OXT")); + renaming_to_standard_["protein"].push_back(std::make_pair("OC1","O")); + renaming_to_standard_["protein"].push_back(std::make_pair("OC2","OXT")); + renaming_to_standard_["protein"].push_back(std::make_pair("HN","H")); + renaming_to_standard_["protein"].push_back(std::make_pair("HT1","H1")); + renaming_to_standard_["protein"].push_back(std::make_pair("HT2","H2")); + renaming_to_standard_["protein"].push_back(std::make_pair("HT3","H3")); +} + +int GromacsData::GetKeywordIndex(const String& keyword){ + String lowercase_keyword = keyword; + boost::algorithm::to_lower(lowercase_keyword); + if(keyword_map_.find(lowercase_keyword) == keyword_map_.end()) return -1; + else return keyword_map_[lowercase_keyword]; +} + +String GromacsData::ConvertToStandard(const String& res_name, const String& atom_name){ + + if(renaming_to_standard_.find(res_name) == renaming_to_standard_.end()) return atom_name; + for(std::vector<std::pair<String,String> >::iterator i = renaming_to_standard_[res_name].begin(); + i != renaming_to_standard_[res_name].end(); ++i){ + if(i->first == atom_name) return i->second; + } + return atom_name; +} + +bool GromacsData::ConversionExists(const String& res_name){ + return renaming_to_standard_.find(res_name) != renaming_to_standard_.end(); +} + +GromacsDataPtr GromacsData::Instance(){ + if(!instance_){ + instance_ = GromacsDataPtr(new GromacsData); + } + return instance_; +} + +GromacsDataPtr GromacsData::instance_ = GromacsDataPtr(); + +CHARMMData::CHARMMData() { + + keyword_map_["atoms"] = 0; + keyword_map_["bonds"] = 1; + keyword_map_["angles"] = 2; + keyword_map_["dihedrals"] = 3; + keyword_map_["improper"] = 4; + keyword_map_["cmap"] = 5; + keyword_map_["nonbonded"] = 6; + keyword_map_["hbond"] = 7; + keyword_map_["end"] = 8; + keyword_map_["mass"] = 9; + keyword_map_["decl"] = 10; + keyword_map_["defa"] = 11; + keyword_map_["auto"] = 12; + keyword_map_["resi"] = 13; + keyword_map_["pres"] = 14; + keyword_map_["atom"] = 15; + keyword_map_["group"] = 16; + keyword_map_["bond"] = 17; + keyword_map_["angle"] = 18; + keyword_map_["dihe"] = 19; + keyword_map_["impr"] = 20; + keyword_map_["donor"] = 21; + keyword_map_["acceptor"] = 22; + keyword_map_["ic"] = 23; + keyword_map_["patching"] = 24; + keyword_map_["print"] = 25; + keyword_map_["double"] = 26; +} + +int CHARMMData::GetKeywordIndex(const String& keyword){ + String lowercase_keyword = keyword; + boost::algorithm::to_lower(lowercase_keyword); + if(keyword_map_.find(lowercase_keyword) == keyword_map_.end()) return -1; + else return keyword_map_[lowercase_keyword]; +} + + +CHARMMDataPtr CHARMMData::Instance(){ + if(!instance_){ + instance_ = CHARMMDataPtr(new CHARMMData); + } + return instance_; +} + +CHARMMDataPtr CHARMMData::instance_ = CHARMMDataPtr(); + + + + + +std::vector<std::vector<String> > MMPreprocessor::Process(const String& filename){ + + std::vector<std::vector<String> > file_content = this->ReadFile(filename); + std::vector<std::vector<String> > temp; + std::vector<std::vector<String> > return_file; + + //we first resolve all include statements + String include_file_name; + for(uint i = 0; i<file_content.size(); ++i){ + if(file_content[i][0] == "#include"){ + if(file_content[i].size() != 2){ + std::stringstream ss; + ss<<"Can only evaluate include statement in combination with a filename."; + ss<<"Also more stuff in the same line blows the thing up..."; + throw ost::io::IOException(ss.str()); + } + String include_filename = file_content[i][1].substr(1,file_content[i][1].size()-2); + temp = this->ReadFile(include_filename); + //directly delete the line with the + //include statement and fill in the full content + file_content.insert(file_content.erase(file_content.begin()+i), temp.begin(), temp.end()); + } + } + + //let's resolve all definitions + std::map<String,std::vector<String> >::iterator definitions_it; + for(uint i=0; i<file_content.size(); ++i){ + //resolve definition + if(file_content[i][0] == "#define"){ + if(file_content[i].size()==2){ + defines_.insert(file_content[i][1]); + file_content.erase(file_content.begin()+i); + if(i == file_content.size()) break; + --i; + continue; + } + definitions_[file_content[i][1]] = std::vector<String>(file_content[i].begin()+2,file_content[i].end()); + file_content.erase(file_content.begin()+i); + if(i == file_content.size()) break; + --i; + continue; + } + //resolve ifdef + if(file_content[i][0] == "#ifdef" || file_content[i][0] == "#ifndef"){ + this->ResolveIFDEF(file_content,i); + --i; + continue; + } + //check whether a word in current line corresponds to a found definition + for(uint j = 0; j<file_content[i].size(); ++j){ + definitions_it = definitions_.find(file_content[i][j]); + if(definitions_it!=definitions_.end()){ + file_content[i].insert(file_content[i].erase(file_content[i].begin()+j),definitions_it->second.begin(),definitions_it->second.end()); + } + } + } + return file_content; +} + +void MMPreprocessor::ResolveIFDEF(std::vector<std::vector<String> >& file_content, int line_counter){ + + String ifdef_statement = file_content[line_counter][1]; + bool logical_outcome; + if(file_content[line_counter][0] == "#ifdef"){ + logical_outcome = defines_.find(ifdef_statement) != defines_.end(); + } + else if(file_content[line_counter][0] == "#ifndef"){ + logical_outcome = defines_.find(ifdef_statement) == defines_.end(); + } + else{ + throw ost::Error("Invalid preprocessor statement observed in ResolveIFDEF function!"); + } + + bool has_else = true; + uint else_position = line_counter+1; + while(true){ + if(else_position >= file_content.size()){ + throw ost::io::IOException("Invalid ifdef statement encountered!"); + } + if(file_content[else_position][0] == "#ifdef" || file_content[else_position][0] == "#ifndef"){ + this->ResolveIFDEF(file_content,else_position); + } + if(file_content[else_position][0] == "#else") break; + if(file_content[else_position][0] == "#endif"){ + has_else = false; + break; + } + ++else_position; + } + + uint endif_position = else_position+1; + while(true && has_else){ + if(endif_position >= file_content.size()){ + throw ost::io::IOException("Invalid ifdef statement encountered!"); + } + if(file_content[endif_position][0] == "#ifdef" || file_content[endif_position][0] == "#ifndef"){ + this->ResolveIFDEF(file_content,endif_position); + } + if(file_content[endif_position][0] == "#endif") break; + ++endif_position; + } + + if(has_else){ + if(logical_outcome){ + //delete part after else + file_content.erase(file_content.begin()+else_position, file_content.begin()+endif_position+1); + file_content.erase(file_content.begin()+line_counter); + } + else{ + //delete part before else + file_content.erase(file_content.begin()+line_counter,file_content.begin()+else_position+1); + file_content.erase(file_content.begin()+line_counter+(endif_position-else_position)-1); + } + } + else{ + if(logical_outcome){//only delete ifdef and endif + file_content.erase(file_content.begin()+else_position); + file_content.erase(file_content.begin()+line_counter); + } + else{//it's not defined => delete whole block + file_content.erase(file_content.begin()+line_counter,file_content.begin()+else_position+1); + } + } +} + +std::vector<std::vector<String> > MMPreprocessor::ReadFile(const String& filename){ + + boost::filesystem::path file_path = basepath_ / filename; + std::ifstream file; + file.open((file_path.string()).c_str()); + + if(!file){ + std::stringstream ss; + ss<<"Could not read file. File '"; + ss<<filename<<"' does not exist!"; + throw ost::io::IOException(ss.str()); + } + + std::vector<String> file_content; + std::vector<std::vector<String> > split_file_content; + String string_line; + ost::StringRef stringref_line; + std::vector<ost::StringRef> data; + std::vector<String> fill_data; + + while(file.good()){ + std::getline(file,string_line); + file_content.push_back(string_line); + } + + //splitting the stuff up. Everything in a line coming after an element starting + //with a colon or exclamation mark, is neglected. (wont neglect anything of: + //ab! c, but will neglect the second item of: ab !c) + for(std::vector<String>::iterator i = file_content.begin(); + i!=file_content.end(); ++i){ + stringref_line = ost::StringRef(i->c_str(),i->length()); + data = stringref_line.split(); + if(data.empty()) continue; + fill_data.clear(); + for(std::vector<ost::StringRef>::iterator j = data.begin(); + j!=data.end(); ++j){ + //if(*(j->begin()) == ';' || *(j->begin()) == '*'){ + if(*(j->begin()) == ';' || *(j->begin()) == '!'){ + break; + } + fill_data.push_back(j->str()); + } + if(fill_data.empty()) continue; + split_file_content.push_back(fill_data); + } + + //handling linebreaks ("\") + for(uint i = 0; i != split_file_content.size(); ++i){ + if(*split_file_content[i].back().rbegin() == '\\'){ + if(i < split_file_content.size() - 1){ + if(split_file_content[i].back() == "\\"){ + split_file_content[i].pop_back(); + } + else{ + split_file_content[i].back() = split_file_content[i].back().substr(0,split_file_content[i].back().size()-1); + } + if(split_file_content[i].empty()){ + throw io::IOException("Observed single linebreak (\\) in one line of input file!"); + } + for(std::vector<String>::iterator j = split_file_content[i+1].begin(); + j != split_file_content[i+1].end(); ++j){ + split_file_content[i].push_back(*j); + } + split_file_content.erase(split_file_content.begin()+i+1); + --i; + } + } + } + + return split_file_content; +} + +GromacsReader::GromacsReader(const String& base_dir): preprocessor_(base_dir), + ff_(new Forcefield) +{ + for(int i = 0; i < 4; ++i){ + ff_bonded_types_.push_back(Invalid); + bonded_types_.push_back(Invalid); + } +} + +void GromacsReader::ReadGromacsForcefield(){ + + //read in the forcefield + if(!boost::filesystem::exists(preprocessor_.GetBasedir() / "forcefield.itp")){ + throw io::IOException("directory must contain forcefield.itp file!"); + } + if(!boost::filesystem::exists(preprocessor_.GetBasedir() / "atomtypes.atp")){ + throw io::IOException("directory must contain atomtypes.atp file!"); + } + std::vector<std::vector<String> > content = preprocessor_.Process("forcefield.itp"); + this->ParseForcefield(content); + content = preprocessor_.Process("atomtypes.atp"); + this->ParseAtomTypes(content); +} + +void GromacsReader::ReadResidueDatabase(const String& basename){ + std::vector<std::vector<String> > data = preprocessor_.Process(basename+".rtp"); + this->ParseRTP(data); + + try{ + data = preprocessor_.Process(basename+".arn"); + this->ParseARN(data); + }catch(ost::io::IOException e) { } + + try{ + data = preprocessor_.Process(basename+".hdb"); + this->ParseHDB(data); + }catch(ost::io::IOException e) { } + + try{ + data = preprocessor_.Process(basename+".n.tdb"); + this->ParseNTDB(data); + }catch(ost::io::IOException e) { } + + try{ + data = preprocessor_.Process(basename+".c.tdb"); + this->ParseCTDB(data); + }catch(ost::io::IOException e) { } + + try{ + data = preprocessor_.Process(basename+".vsd"); + this->ParseVSD(data); + }catch(ost::io::IOException e) { } + + try{ + data = preprocessor_.Process(basename+".r2b"); + this->ParseRtoB(data); + }catch(ost::io::IOException e) { } +} + +void GromacsReader::ReadCHARMMPRM(const String& filename){ + std::vector<std::vector<String> > data = preprocessor_.Process(filename); + this->ParseCHARMMPRM(data); +} + +void GromacsReader::ReadCHARMMRTF(const String& filename){ + std::vector<std::vector<String> > data = preprocessor_.Process(filename); + this->ParseCHARMMRTF(data); +} + +void GromacsReader::ParseForcefield(std::vector<std::vector<String> >& content){ + + int keyword_id = -1; + std::vector<String> current_line; + + for(uint line_counter = 0; line_counter<content.size(); ++line_counter){ + current_line = content[line_counter]; + if(current_line[0] == "["){ + keyword_id = GromacsData::Instance()->GetKeywordIndex(current_line[1]); + if(keyword_id == -1){ + std::stringstream ss; + ss << "Unknown keyword '"<<current_line[1]; + ss << "' in forcefield file."<<std::endl; + throw io::IOException(ss.str()); + } + continue; + } + + switch(keyword_id){ + case 11:{ + MMInteractionPtr bond = this->ParseBond(current_line,true); + ff_->AddBond(bond); + ff_bonded_types_[0] = bond->GetFuncType(); + break; + } + case 12:{ + MMInteractionPtr constraint = this->ParseConstraint(current_line,true); + ff_->AddConstraint(constraint); + break; + } + case 13:{ + MMInteractionPtr angle = this->ParseAngle(current_line,true); + ff_->AddAngle(angle); + ff_bonded_types_[1] = angle->GetFuncType(); + break; + } + case 14:{ + + MMInteractionPtr p = this->ParseDihedral(current_line,true); + FuncType functype = p->GetFuncType(); + + if(functype == PeriodicDihedral){ + ff_->AddDihedral(p); + ff_bonded_types_[2] = functype; + } + else if(functype == PeriodicImproper || functype == HarmonicImproper){ + ff_->AddImproper(p); + ff_bonded_types_[3] = functype; + } + break; + } + case 15:{ + MMInteractionPtr lj = this->ParseLJ(current_line,true); + ff_->AddLJ(lj); + break; + } + case 16:{ + MMInteractionPtr genborn = this->ParseGenborn(current_line,true); + ff_->AddImplicitGenborn(genborn); + break; + } + case 17:{ + MMInteractionPtr lj_pair = this->ParseLJPair(current_line,true); + ff_->AddLJPair(lj_pair); + break; + } + case 18:{ + std::stringstream ss; + ss << "Observerd nonbond_params in forcefield file. Only forcefields with "; + ss << "combining rules for sigma epsilon calculations are supported!"<<std::endl; + throw ost::Error(ss.str()); + break; + } + case 19:{ + bool gen_pairs; + Real fudge_lj, fudge_qq; + if(current_line[2] == "yes") gen_pairs = true; + else if(current_line[2] == "no") gen_pairs = false; + else throw io::IOException("Only \"yes\" and \"no\" are supported for gen_pairs parameter!"); + + fudge_lj = boost::lexical_cast<Real>(current_line[3]); + fudge_qq = boost::lexical_cast<Real>(current_line[4]); + + ff_->SetGenPairs(gen_pairs); + ff_->SetFudgeLJ(fudge_lj); + ff_->SetFudgeQQ(fudge_qq); + break; + } + case 20:{ + MMInteractionPtr cmap = this->ParseCMap(current_line,true); + ff_->AddCMap(cmap); + break; + } + default: break; + } + } +} + +void GromacsReader::ParseAtomTypes(std::vector<std::vector<String> >& content){ + for(std::vector<std::vector<String> >::iterator i = content.begin(); + i!=content.end(); ++i){ + ff_->AddMass((*i)[0],boost::lexical_cast<Real>((*i)[1])); + } +} + +void GromacsReader::ParseRTP(std::vector<std::vector<String> >& content){ + + read_residues_.clear(); + + //we assume, that at the beginning is the keyword 'bondedtypes' + //we neglect anything before that... + uint line_counter = 0; + for(; line_counter<content.size(); ++line_counter){ + if(content[line_counter].size()>1){ + if(content[line_counter][1] == "bondedtypes"){ + ++line_counter; + //we're interested in the next line + if(content[line_counter].size() < 4){ + throw ost::Error("Error in parsing bondedtypes section of RTP file!"); + } + int gromacs_functype; + //first element defines the bonds + gromacs_functype = boost::lexical_cast<int>(content[line_counter][0]); + if(gromacs_functype == 1){ + bonded_types_[0] = HarmonicBond; + } + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for bond in bondedtypes section of rtp file!"; + throw ost::Error(ss.str()); + } + //second element defines angle + gromacs_functype = boost::lexical_cast<int>(content[line_counter][1]); + if(gromacs_functype == 5) bonded_types_[1] = UreyBradleyAngle; + else if(gromacs_functype == 1) bonded_types_[1] = HarmonicAngle; + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for angle in bondedtypes section of rtp file!"; + throw ost::Error(ss.str()); + } + //third element defines the dihedral + gromacs_functype = boost::lexical_cast<int>(content[line_counter][2]); + if(gromacs_functype == 9 || gromacs_functype == 1) bonded_types_[2] = PeriodicDihedral; + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for dihedral in bondedtypes section of rtp file!"; + throw ost::Error(ss.str()); + } + //fourth elemend defines improper dihedral + gromacs_functype = boost::lexical_cast<int>(content[line_counter][3]); + if(gromacs_functype == 4) bonded_types_[3] = PeriodicImproper; + else if(gromacs_functype == 2) bonded_types_[3] = HarmonicImproper; + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for dihedral!"; + throw ost::Error(ss.str()); + } + ++line_counter; + break; + } + } + } + + //data for specific residue will be filled in here and passed + //in the residue_building block Parse function + std::vector<std::vector<String> > residue_data; + String residue_name; + for(; line_counter < content.size(); ++line_counter){ + if(content[line_counter][0] == "["){ + //I there is a keyword (start with [) not defined above, + //we assume, that it is a new residue + if(GromacsData::Instance()->GetKeywordIndex(content[line_counter][1]) == -1){ + //parse the old residue and set new residue name + if(!residue_data.empty()){ + ff_->AddBuildingBlock(residue_name, this->BlockFromRTP(residue_data)); + read_residues_.push_back(residue_name); + } + residue_data.clear(); + residue_name = content[line_counter][1]; + continue; + } + } + residue_data.push_back(content[line_counter]); + } + //we probably missed the last residue + if(!residue_data.empty()){ + ff_->AddBuildingBlock(residue_name, this->BlockFromRTP(residue_data)); + read_residues_.push_back(residue_name); + } + + + //It could be, that certain bondedtypes in the forcefield are not defined yet, + //since all forces are defined in the building blocks... + //We assume, that the whole stuff is consistent across all forcefield and rtp + //files... If not, you'll get errors when setting up your system + for(int i = 0; i < 4; ++i){ + if(ff_bonded_types_[i] == Invalid) ff_bonded_types_[i] = bonded_types_[i]; + } + +} + +void GromacsReader::ParseARN(std::vector<std::vector<String> >& content){ + String res_name, a_one, a_two; + + for(std::vector<std::vector<String> >::iterator i = content.begin(); + i!=content.end(); ++i){ + res_name = (*i)[0]; + a_one = (*i)[1]; + a_two = (*i)[2]; + if(res_name == "*"){ + // * is wildcard... valid for all residues in the previously read rtp file + for(std::vector<String>::iterator j = read_residues_.begin(); + j != read_residues_.end(); ++j){ + ff_->AddAtomRenamingRule(*j,a_one,a_two); + } + } + else{ + ff_->AddAtomRenamingRule(res_name, a_one, a_two); + } + } +} + +void GromacsReader::ParseHDB(std::vector<std::vector<String> >& content){ + + std::vector<std::vector<String> > residue_data; + String residue_name; + for(uint line_counter = 0; line_counter<content.size(); ++line_counter){ + if(content[line_counter].size() == 2){ + if(!residue_data.empty()){ + GromacsHydrogenConstructor* p = new GromacsHydrogenConstructor; + for(std::vector<std::vector<String> >::iterator i = residue_data.begin(); + i != residue_data.end(); ++i){ + this->ParseHydrogenRule(*i,*p); + } + ff_->AddHydrogenConstructor(residue_name,HydrogenConstructorPtr(p)); + } + residue_data.clear(); + residue_name = content[line_counter][0]; + continue; + } + residue_data.push_back(content[line_counter]); + } + //we probably missed the last residue + if(!residue_data.empty()){ + GromacsHydrogenConstructor* p = new GromacsHydrogenConstructor; + for(std::vector<std::vector<String> >::iterator i = residue_data.begin(); + i != residue_data.end(); ++i){ + this->ParseHydrogenRule(*i,*p); + } + ff_->AddHydrogenConstructor(residue_name,HydrogenConstructorPtr(p)); + } +} + +void GromacsReader::ParseHydrogenRule(const std::vector<String>& data, + GromacsHydrogenConstructor& constructor){ + + if(data.size() < 4){ + throw ost::Error("Require at least four items when parsing hydrogen rule!"); + } + + int number = boost::lexical_cast<int>(data[0]); + int method = boost::lexical_cast<int>(data[1]); + String prefix = data[2]; + std::vector<String> anchors; + std::vector<String> hydrogen_names; + + for(uint i=3; i<data.size(); ++i){ + anchors.push_back(data[i]); + } + + switch(number){ + case 1:{ + hydrogen_names.push_back(prefix); + break; + } + case 2:{ + hydrogen_names.push_back(prefix+"1"); + hydrogen_names.push_back(prefix+"2"); + break; + } + case 3:{ + hydrogen_names.push_back(prefix+"1"); + hydrogen_names.push_back(prefix+"2"); + hydrogen_names.push_back(prefix+"3"); + break; + } + default:{ + break; + } + } + + constructor.AddHydrogenRule(number,method,hydrogen_names, anchors); +} + + +void GromacsReader::ParseTerminiReplaceRule(const std::vector<String>& data, + GromacsBlockModifier& modifier){ + + String name; + String new_name; + String new_type; + Real new_charge; + if(data.size() == 5 && data.back() != "0"){ + name = data[0]; + new_name = data[1]; + new_type = data[2]; + new_charge = boost::lexical_cast<Real>(data[4]); + } + else{ + name = data[0]; + new_name = name; + new_type = data[1]; + new_charge = boost::lexical_cast<Real>(data[3]); + } + + modifier.AddReplaceRule(name, new_name, new_type, new_charge); + //we neglect the mass! This will be read from the forcefield itself! +} + +void GromacsReader::ParseTerminiAddRule(const std::vector<String>& data1, + const std::vector<String>& data2, + GromacsBlockModifier& modifier){ + + int number = boost::lexical_cast<int>(data1[0]); + int method = boost::lexical_cast<int>(data1[1]); + String prefix = data1[2]; + + std::vector<String> anchors; + for(uint i = 3; i < data1.size(); ++i){ + anchors.push_back(data1[i]); + } + + String type = data2[0]; + Real charge = boost::lexical_cast<Real>(data2[2]); + //we again neglect the masses... + + std::vector<String> names; + + switch(number){ + case 1:{ + names.push_back(prefix); + break; + } + case 2:{ + names.push_back(prefix+"1"); + names.push_back(prefix+"2"); + break; + } + case 3:{ + names.push_back(prefix+"1"); + names.push_back(prefix+"2"); + names.push_back(prefix+"3"); + break; + } + default:{ + std::stringstream ss; + ss<<"Can only add one, two or three atoms at one position."; + ss<<"The provided force field file seems to tell something different"; + throw ost::Error(ss.str()); + } + } + + modifier.AddAddRule(number, method, names, anchors, type, charge); + +} + + +void GromacsReader::ParseNTDB(std::vector<std::vector<String> >& content){ + + //Besided general termini constructors, there are also residue + //specific constructors => custom constructors + std::vector<String> termini; + std::map<String,std::vector<String> > custom_termini; + + std::vector<std::vector<String> > data; + String name; + + for(uint line_counter = 0; line_counter < content.size(); ++line_counter){ + if(content[line_counter][0] == "["){ + //I there is a keyword (start with [) not defined above, + //we assume, that it is a new residue + if(GromacsData::Instance()->GetKeywordIndex(content[line_counter][1]) == -1){ + //parse the old residue and set new residue name + if(!data.empty()){ + BlockModifierPtr p = this->ParseBlockModifier(data); + ff_->AddBlockModifier(name,p); + size_t minus_pos = name.find("-"); + if(minus_pos != String::npos && minus_pos < (name.size()-1)){ + String a = name.substr(0,minus_pos); + if(custom_termini.find(a) == custom_termini.end()){ + custom_termini[a] = std::vector<String>(); + } + custom_termini[a].push_back(name); + } + else{ + termini.push_back(name); + } + } + data.clear(); + name = content[line_counter][1]; + continue; + } + } + data.push_back(content[line_counter]); + } + + if(!data.empty()){ + BlockModifierPtr p = this->ParseBlockModifier(data); + ff_->AddBlockModifier(name,p); + size_t minus_pos = name.find("-"); + if(minus_pos != String::npos && minus_pos < (name.size()-1)){ + String a = name.substr(0,minus_pos); + if(custom_termini.find(a) == custom_termini.end()){ + custom_termini[a] = std::vector<String>(); + } + custom_termini[a].push_back(name); + } + else{ + termini.push_back(name); + } + } + + for(std::vector<String>::iterator i = read_residues_.begin(); + i != read_residues_.end(); ++i){ + if(custom_termini.find(*i) != custom_termini.end()){ + if(!custom_termini[*i].empty()) ff_->SetStandardNTer(*i,custom_termini[*i][0]); + continue; + } + if(!termini.empty()) ff_->SetStandardNTer(*i,termini[0]); + } +} + +void GromacsReader::ParseCTDB(std::vector<std::vector<String> >& content){ + + //Besided general termini constructors, there are also residue + //specific constructors => custom constructors + std::vector<String> termini; + std::map<String,std::vector<String> > custom_termini; + + std::vector<std::vector<String> > data; + String name; + + for(uint line_counter = 0; line_counter < content.size(); ++line_counter){ + if(content[line_counter][0] == "["){ + //I there is a keyword (start with [) not defined above, + //we assume, that it is a new residue + if(GromacsData::Instance()->GetKeywordIndex(content[line_counter][1]) == -1){ + //parse the old residue and set new residue name + if(!data.empty()){ + BlockModifierPtr p = this->ParseBlockModifier(data); + ff_->AddBlockModifier(name,p); + size_t minus_pos = name.find("-"); + if(minus_pos != String::npos && minus_pos < (name.size()-1)){ + String a = name.substr(0,minus_pos); + if(custom_termini.find(a) == custom_termini.end()){ + custom_termini[a] = std::vector<String>(); + } + custom_termini[a].push_back(name); + } + else{ + termini.push_back(name); + } + } + data.clear(); + name = content[line_counter][1]; + continue; + } + } + data.push_back(content[line_counter]); + } + + if(!data.empty()){ + BlockModifierPtr p = this->ParseBlockModifier(data); + ff_->AddBlockModifier(name,p); + size_t minus_pos = name.find("-"); + if(minus_pos != String::npos && minus_pos < (name.size()-1)){ + String a = name.substr(0,minus_pos); + if(custom_termini.find(a) == custom_termini.end()){ + custom_termini[a] = std::vector<String>(); + } + custom_termini[a].push_back(name); + } + else{ + termini.push_back(name); + } + } + + for(std::vector<String>::iterator i = read_residues_.begin(); + i != read_residues_.end(); ++i){ + if(custom_termini.find(*i) != custom_termini.end()){ + if(!custom_termini[*i].empty()) ff_->SetStandardCTer(*i,custom_termini[*i][0]); + continue; + } + if(!termini.empty()) ff_->SetStandardCTer(*i,termini[0]); + } +} + +void GromacsReader::ParseVSD(std::vector<std::vector<String> >& content){ + +} + +void GromacsReader::ParseRtoB(std::vector<std::vector<String> >& content){ + + //there are two versions of this file, either with two or five + //columns further instructions can be found in the gromacs manual + + String res_name, main, n_ter, c_ter, two_ter; + + for(std::vector<std::vector<String> >::iterator i = content.begin(); + i != content.end(); ++i){ + if((*i).size() == 2){ + res_name = (*i)[0]; + main = (*i)[1]; + n_ter = main; + c_ter = main; + two_ter = main; + ff_->AddResidueRenamingRule(res_name,main,n_ter,c_ter,two_ter); + continue; + } + if((*i).size() == 5){ + res_name = (*i)[0]; + main = (*i)[1]; + n_ter = (*i)[2]; + c_ter = (*i)[3]; + two_ter = (*i)[4]; + ff_->AddResidueRenamingRule(res_name,main,n_ter,c_ter,two_ter); + continue; + } + throw io::IOException("Entries in r2b files must contain 2 or 5 columns"); + } +} + +void GromacsReader::ReadITP(const String& basename){ + std::vector<std::vector<String> > content = preprocessor_.Process(basename + ".itp"); + this->ParseITP(content); +} + +void GromacsReader::ParseITP(std::vector<std::vector<String> >& content){ + + std::vector<std::vector<String> > residue_data; + String residue_name; + for(uint line_counter = 0; line_counter < content.size(); ++line_counter){ + if(content[line_counter][0] == "["){ + if(GromacsData::Instance()->GetKeywordIndex(content[line_counter][1]) == 8){ + //parse the old residue and set new residue name + if(!residue_data.empty()){ + BuildingBlockPtr p = this->BlockFromITP(residue_data); + ff_->AddBuildingBlock(residue_name, p); + } + residue_data.clear(); + residue_name = content[++line_counter][0]; + continue; + } + } + residue_data.push_back(content[line_counter]); + } + //we probably missed the last residue + if(!residue_data.empty()){ + BuildingBlockPtr p = this->BlockFromITP(residue_data); + ff_->AddBuildingBlock(residue_name, p); + } +} + +BuildingBlockPtr GromacsReader::BlockFromRTP(const std::vector<std::vector<String> >& data){ + + if(bonded_types_.size()<4){ + std::stringstream ss; + ss << "There must be at least 4 parameters in the bondedtypes section of"; + ss << ".rtp file"; + throw io::IOException(ss.str()); + } + + if(data[0][1] != "atoms"){ + std::stringstream ss; + ss << "Expect residue definition to start with the atom keyword!"; + throw io::IOException(ss.str()); + } + + int keyword_index = 0; + BuildingBlockPtr p(new BuildingBlock); + + for(uint i=1;i<data.size(); ++i){ + if(data[i].size()>1){ + if(data[i][0]=="["){ + keyword_index = GromacsData::Instance()->GetKeywordIndex(data[i][1]); + continue; + } + } + + switch(keyword_index){ + case 0:{ + p->AddAtom(data[i][0], + data[i][1], + boost::lexical_cast<Real>(data[i][2])); + break; + } + case 1:{ + p->AddBond(this->ParseBond(data[i],false,bonded_types_[0])); + break; + } + case 2:{ + p->AddAngle(this->ParseAngle(data[i],false,bonded_types_[1])); + break; + } + case 3:{ + p->AddImproper(this->ParseDihedral(data[i],false,bonded_types_[3])); + break; + } + case 4:{ + p->AddDihedral(this->ParseDihedral(data[i],false,bonded_types_[2])); + break; + } + case 5:{ + p->AddExclusion(this->ParseExclusion(data[i],false)); + break; + } + case 6:{ + p->AddCMap(this->ParseCMap(data[i],false)); + break; + } + default:{ + std::stringstream ss; + ss << "Encountered invalid keyword while parsing rtp file: " << data[i-1][1]; + throw ost::io::IOException(ss.str()); + } + } + } + return p; +} + +BuildingBlockPtr GromacsReader::BlockFromITP(const std::vector<std::vector<String> >& data){ + + int keyword_index; + + if(data[0][1] != "atoms"){ + std::stringstream ss; + ss << "Expect residue definition to start with the atom keyword!"; + throw io::IOException(ss.str()); + } + + std::map<int,String> index_name_mapper; + keyword_index = 0; + BuildingBlockPtr p(new BuildingBlock); + std::vector<String> current_line; + + for(uint i=1;i<data.size(); ++i){ + if(data[i].size()>1){ + if(data[i][0]=="["){ + keyword_index = GromacsData::Instance()->GetKeywordIndex(data[i][1]); + continue; + } + } + current_line = data[i]; + switch(keyword_index){ + case 0:{ + p->AddAtom(current_line[4], + current_line[1], + boost::lexical_cast<Real>(current_line[6])); + index_name_mapper[boost::lexical_cast<int>(current_line[0])] = current_line[4]; + break; + } + case 1:{ + current_line[0] = index_name_mapper[boost::lexical_cast<int>(current_line[0])]; + current_line[1] = index_name_mapper[boost::lexical_cast<int>(current_line[1])]; + p->AddBond(this->ParseBond(current_line,false)); + break; + } + case 2:{ + current_line[0] = index_name_mapper[boost::lexical_cast<int>(current_line[0])]; + current_line[1] = index_name_mapper[boost::lexical_cast<int>(current_line[1])]; + current_line[2] = index_name_mapper[boost::lexical_cast<int>(current_line[2])]; + p->AddAngle(this->ParseAngle(current_line,false)); + break; + } + case 4:{ + //there must be a function type, otherwise we can't distinguish + //between dihedrals and impropers + current_line[0] = index_name_mapper[boost::lexical_cast<int>(current_line[0])]; + current_line[1] = index_name_mapper[boost::lexical_cast<int>(current_line[1])]; + current_line[2] = index_name_mapper[boost::lexical_cast<int>(current_line[2])]; + current_line[3] = index_name_mapper[boost::lexical_cast<int>(current_line[3])]; + + MMInteractionPtr int_ptr = this->ParseDihedral(current_line,false); + FuncType functype = int_ptr->GetFuncType(); + + if(functype == PeriodicDihedral){ + p->AddDihedral(int_ptr); + } + else if(functype == PeriodicImproper || functype == HarmonicImproper){ + p->AddImproper(int_ptr); + } + break; + } + case 5:{ + //current_line[0] = index_name_mapper[boost::lexical_cast<int>(current_line[0])]; + //current_line[1] = index_name_mapper[boost::lexical_cast<int>(current_line[1])]; + //p->exclusions_.push_back(MMInteraction::ParseExclusion(current_line,false)); + break; + } + case 6:{ + current_line[0] = index_name_mapper[boost::lexical_cast<int>(current_line[0])]; + current_line[1] = index_name_mapper[boost::lexical_cast<int>(current_line[1])]; + current_line[2] = index_name_mapper[boost::lexical_cast<int>(current_line[2])]; + current_line[3] = index_name_mapper[boost::lexical_cast<int>(current_line[3])]; + current_line[4] = index_name_mapper[boost::lexical_cast<int>(current_line[4])]; + p->AddCMap(this->ParseCMap(current_line,false)); + break; + } + case 21:{ + //we extract pairs manually... + break; + } + case 22:{ + std::vector<String> block_atom_names = p->GetAtoms(); + if(block_atom_names.size() < 3){ + throw ost::Error("Molecule with settles keyword must contain at least 3 atoms!"); + } + std::vector<Real> parameters; + std::vector<String> names; + + + MMInteractionPtr p1(new MMInteraction(DistanceConstraint)); + MMInteractionPtr p2(new MMInteraction(DistanceConstraint)); + MMInteractionPtr p3(new MMInteraction(DistanceConstraint)); + + //first constraint dist => O - H + parameters.push_back(boost::lexical_cast<Real>(current_line[2])); + names.push_back(block_atom_names[0]); + names.push_back(block_atom_names[1]); + p1->SetNames(names); + p1->SetParam(parameters); + p->AddConstraint(p1); + + //second constraint dist => O - H + names[1] = block_atom_names[2]; + p2->SetNames(names); + p2->SetParam(parameters); + p->AddConstraint(p2); + + //third constraint dist => H - H + names[0] = block_atom_names[1]; + parameters[0] = boost::lexical_cast<Real>(current_line[3]); + p3->SetNames(names); + p3->SetParam(parameters); + p->AddConstraint(p3); + + break; + } + default:{ + std::stringstream ss; + ss << "Encountered invalid keyword while parsing itp file: " << data[i-1][1]; + throw ost::io::IOException(ss.str()); + } + } + } + return p; +} + + +BlockModifierPtr GromacsReader::ParseBlockModifier(const std::vector<std::vector<String> >& data){ + + + int keyword_index = -1; + + if(data[0].size() > 0){ + keyword_index = GromacsData::Instance()->GetKeywordIndex(data[0][1]); + if(keyword_index == -1){ + throw ost::io::IOException("Expect termini data to start with a valid keyword!"); + } + } + + GromacsBlockModifier* p = new GromacsBlockModifier; + + for(uint i = 1; i < data.size(); ++i){ + if(data[i].size()>1){ + if(data[i][0] == "["){ + keyword_index = GromacsData::Instance()->GetKeywordIndex(data[i][1]); + continue; + } + } + switch(keyword_index){ + case 7:{ + this->ParseTerminiReplaceRule(data[i],*p); + break; + } + case 9:{ + std::vector<String> line1 = data[i]; + std::vector<String> line2 = data[++i]; + this->ParseTerminiAddRule(line1, line2, *p); + break; + } + case 10:{ + p->AddDeleteAtom(data[i][0]); + break; + } + case 1:{ + p->AddBond(this->ParseBond(data[i],false,bonded_types_[0])); + break; + } + case 2:{ + p->AddAngle(this->ParseAngle(data[i],false,bonded_types_[1])); + break; + } + case 4:{ + p->AddDihedral(this->ParseDihedral(data[i],false,bonded_types_[2])); + break; + } + case 3:{ + p->AddImproper(this->ParseDihedral(data[i],false,bonded_types_[3])); + break; + } + case 6:{ + p->AddCMap(this->ParseCMap(data[i],false)); + break; + } + + default:{ + std::stringstream ss; + ss << "Encountered invalid keyword while parsing termini: " << data[i-1][1]; + throw ost::io::IOException(ss.str()); + } + } + } + + return BlockModifierPtr(p); +} + + +MMInteractionPtr GromacsReader::ParseBond(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 2){ + throw ost::io::IOException("Require at least 2 arguments in parsing bond!"); + } + + if(functype == Invalid){ + if(data.size() == 2){ + throw ost::Error("Error in determining bond function type!"); + } + int gromacs_functype; + try{ gromacs_functype = boost::lexical_cast<int>(data[2]); } catch(std::exception& e){ + throw ost::io::IOException("Could not cast function type into int while parsing bond!"); + } + if(gromacs_functype == 1){ + functype = HarmonicBond; + } + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for bond!"; + throw ost::Error(ss.str()); + } + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 3){ + std::vector<Real> parameters; + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast bond parameters into real type!"); + } + return p; +} + +MMInteractionPtr GromacsReader::ParseAngle(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 3){ + throw ost::io::IOException("Require at least 3 arguments in parsing angle!"); + } + + if(functype == Invalid){ + if(data.size() == 3){ + throw ost::Error("Error in determining angle function type!"); + } + int gromacs_functype; + try{ gromacs_functype = boost::lexical_cast<int>(data[3]); } catch(std::exception& e){ + throw ost::io::IOException("Could not cast function type into int while parsing angle!"); + } + if(gromacs_functype == 5) functype = UreyBradleyAngle; + else if(gromacs_functype == 1) functype = HarmonicAngle; + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for angle!"; + throw ost::Error(ss.str()); + } + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + atom_definition.push_back(data[2]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 4){ + std::vector<Real> parameters; + if(functype == UreyBradleyAngle){ + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-4])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-3])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + + } + else{ + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + } + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast angle parameters into real type!"); + } + return p; +} + +MMInteractionPtr GromacsReader::ParseDihedral(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + if(data.size() < 4){ + throw ost::io::IOException("Require at least 4 arguments in parsing dihedral/improper!"); + } + + if(functype == Invalid){ + if(data.size() == 4){ + throw ost::Error("Error in determining angle function type!"); + } + int gromacs_functype; + try{ gromacs_functype = boost::lexical_cast<int>(data[4]); } catch(std::exception& e){ + throw ost::io::IOException("Could not cast function type into int while parsing dihedral!"); + } + if(gromacs_functype == 9 || gromacs_functype == 1) functype = PeriodicDihedral; + else if(gromacs_functype == 4) functype = PeriodicImproper; + else if(gromacs_functype == 2) functype = HarmonicImproper; + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for dihedral!"; + throw ost::Error(ss.str()); + } + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + atom_definition.push_back(data[2]); + atom_definition.push_back(data[3]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 5){ + std::vector<Real> parameters; + if(functype == HarmonicImproper){ + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + } + else{ + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-3])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])); + } + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast dihedral/improper parameters into real type!"); + } + return p; +} + +MMInteractionPtr GromacsReader::ParseCMap(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + if(data.size() < 5){ + throw ost::io::IOException("Require at least 5 arguments in parsing cmap!"); + } + + if(functype == Invalid){ + functype = CMap; //well, there is only this possibility + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + atom_definition.push_back(data[2]); + atom_definition.push_back(data[3]); + atom_definition.push_back(data[4]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + if(data.size() > 6){ + uint a,b; + try{ + a = boost::lexical_cast<uint>(data[6]); + b = boost::lexical_cast<uint>(data[7]); + }catch(std::exception& e){ + throw ost::io::IOException("Failed to parse size of the cmap!"); + } + if(a != b){ + throw ost::io::IOException("Expect cmap to have equal extension into both dimensions!"); + } + + if((8+a*b) > data.size()){ + throw ost::io::IOException("Expected more data to fill cmap!"); + } + try{ + std::vector<Real> parameters; + parameters.push_back(Real(a)); + for(uint i = 0; i < a*a; ++i){ + parameters.push_back(boost::lexical_cast<Real>(data[8+i])); + } + p->SetParam(parameters); + }catch(std::exception& e){ + throw ost::io::IOException("Failed to cast cmap values into real type!"); + } + } + return p; +} + + +MMInteractionPtr GromacsReader::ParseLJ(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 1){ + throw ost::io::IOException("Require at least 1 arguments in parsing LJ!"); + } + + if(functype == Invalid){ + functype = LJ; //well, there is only this possibility + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 2){ + std::vector<Real> parameters; + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast atomtype parameters into real type!"); + } + return p; +} + + +MMInteractionPtr GromacsReader::ParseLJPair(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 2){ + throw ost::io::IOException("Require at least 2 arguments in parsing nonbonded parameters!"); + } + + if(functype == Invalid){ + if(data.size() == 2){ + throw ost::Error("Error in determining LJ Pair function type!"); + } + int gromacs_functype; + try{ gromacs_functype = boost::lexical_cast<int>(data[2]); } catch(std::exception& e){ + throw ost::io::IOException("Could not cast function type into int while parsing lj pair!"); + } + if(gromacs_functype == 1){ + functype = LJPair; + } + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for LJ Pair!"; + throw ost::Error(ss.str()); + } + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 3){ + std::vector<Real> parameters; + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-2])); + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast nonbonded parameters into real type!"); + } + return p; +} + +MMInteractionPtr GromacsReader::ParseConstraint(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 2){ + throw ost::io::IOException("Require at least 2 arguments in parsing nonbonded parameters!"); + } + + if(functype == Invalid){ + if(data.size() == 2){ + throw ost::Error("Error in determining constraint function type!"); + } + int gromacs_functype; + try{ gromacs_functype = boost::lexical_cast<int>(data[2]); } catch(std::exception& e){ + throw ost::io::IOException("Could not cast function type into int while parsing constraint!"); + } + if(gromacs_functype == 1 || gromacs_functype == 2){ + functype = DistanceConstraint; + } + else{ + std::stringstream ss; + ss << "Not supported gromacs function type \""<<gromacs_functype<<"\""; + ss << " for constraint!"; + throw ost::Error(ss.str()); + } + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 3){ + std::vector<Real> parameters; + parameters.push_back(boost::lexical_cast<Real>(data[data.size()-1])); + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast constraint parameters into real type!"); + } + return p; +} + +MMInteractionPtr GromacsReader::ParseGenborn(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + + if(data.size() < 1){ + throw ost::io::IOException("Require at least 1 argument in parsing genborn parameters!"); + } + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + + functype = GBSA; //bit hacky, I know, but there is only one type for gbsa anyway.... + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + try{ + if(data.size() > 1){ + std::vector<Real> parameters; + parameters.push_back(boost::lexical_cast<Real>(data[4])); + parameters.push_back(boost::lexical_cast<Real>(data[5])); + p->SetParam(parameters); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast genborn parameters into real type!"); + } + return p; +} + + +MMInteractionPtr GromacsReader::ParseExclusion(const std::vector<String>& data, + bool type_definition, + FuncType functype){ + + if(data.size() < 2){ + throw ost::io::IOException("Require at least 2 argument in parsing exclusion parameters!"); + } + + functype = Exclusion; //bit hacky, I know, but there is only one type for exclusion anyway.... + + std::vector<String> atom_definition; + atom_definition.push_back(data[0]); + atom_definition.push_back(data[1]); + + MMInteractionPtr p(new MMInteraction(functype)); + + if(type_definition) p->SetTypes(atom_definition); + else p->SetNames(atom_definition); + + return p; +} + +void GromacsReader::ParseCHARMMPRM(std::vector<std::vector<String> >& content){ + + + int keyword_id = -1; + std::vector<String> current_line; + + //will be used to calculate all pairwise 1,4 lj parameters later on + std::vector<String> lj_14_types; + std::vector<Real> lj_14_sigmas; + std::vector<Real> lj_14_epsilons; + std::vector<String> lj_types; + std::vector<Real> lj_sigmas; + std::vector<Real> lj_epsilons; + + for(uint line_counter = 0; line_counter<content.size(); ++line_counter){ + current_line = content[line_counter]; + if(CHARMMData::Instance()->GetKeywordIndex(current_line[0]) != -1){ + keyword_id = CHARMMData::Instance()->GetKeywordIndex(current_line[0]); + continue; + } + + if(keyword_id == 8) break; + + switch(keyword_id){ + case 0:{ //atoms keyword + ff_->AddMass(current_line[2],boost::lexical_cast<Real>(current_line[3])); + break; + } + case 1:{ //bonds + MMInteractionPtr p(new MMInteraction(HarmonicBond)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + types.push_back(current_line[1]); + try{ + parameters.push_back(0.1 * boost::lexical_cast<Real>(current_line[3])); + parameters.push_back(418.4*2 * boost::lexical_cast<Real>(current_line[2])); + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast bond parameters into real type!"); + } + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddBond(p); + break; + } + case 2:{ //angles + MMInteractionPtr p(new MMInteraction(UreyBradleyAngle)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + types.push_back(current_line[1]); + types.push_back(current_line[2]); + try{ + parameters.push_back(boost::lexical_cast<Real>(current_line[4])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(current_line[3])*4.184*2); + if(current_line.size() > 5){ + parameters.push_back(boost::lexical_cast<Real>(current_line[6])*0.1); + parameters.push_back(boost::lexical_cast<Real>(current_line[5])*418.4*2); + } + else{ + parameters.push_back(0.0); + parameters.push_back(0.0); + } + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast angle parameters into real type!"); + } + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddAngle(p); + break; + } + case 3:{ //diherals + MMInteractionPtr p(new MMInteraction(PeriodicDihedral)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + types.push_back(current_line[1]); + types.push_back(current_line[2]); + types.push_back(current_line[3]); + try{ + parameters.push_back(boost::lexical_cast<Real>(current_line[5])); + parameters.push_back(boost::lexical_cast<Real>(current_line[6])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(current_line[4])*4.184); + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast bond parameters into real type!"); + } + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddDihedral(p); + break; + } + case 4:{ //improper + MMInteractionPtr p(new MMInteraction(HarmonicImproper)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + types.push_back(current_line[1]); + types.push_back(current_line[2]); + types.push_back(current_line[3]); + try{ + parameters.push_back(boost::lexical_cast<Real>(current_line[6])/360*2*M_PI); + parameters.push_back(boost::lexical_cast<Real>(current_line[4])*4.184*2); + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast bond parameters into real type!"); + } + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddImproper(p); + break; + } + case 5:{ //cmap + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + types.push_back(current_line[1]); + types.push_back(current_line[2]); + types.push_back(current_line[3]); + types.push_back(current_line[7]); + uint dim = boost::lexical_cast<uint>(current_line[8]); + parameters.push_back(Real(dim)); + + ++line_counter; + + while(true){ + if(line_counter >= content.size()){ + throw ost::io::IOException("Not enough data to fill cmap!"); + } + if(parameters.size() > dim*dim+1){ + std::stringstream ss; + ss << "Expect cmap values to fit exactly into a grid with dim "; + ss << dim << " x " << dim; + throw ost::io::IOException(ss.str()); + } + if(parameters.size() == dim*dim+1){ + MMInteractionPtr p(new MMInteraction(CMap)); + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddCMap(p); + --line_counter; + break; + } + + for(std::vector<String>::iterator i = content[line_counter].begin(); + i != content[line_counter].end(); ++i){ + parameters.push_back(boost::lexical_cast<Real>(*i)*4.184); + } + ++line_counter; + } + + break; + } + case 6:{ //nonbonded + if(current_line[0] == "cutnb") break; + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(current_line[0]); + try{ + parameters.push_back(boost::lexical_cast<Real>(current_line[3])*0.1/(std::pow(2,1.0/6.0))*2); + parameters.push_back(std::abs(boost::lexical_cast<Real>(current_line[2])*4.184)); + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast LJ parameters into real type!"); + } + MMInteractionPtr p(new MMInteraction(LJ)); + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddLJ(p); + + if(current_line.size() >= 7){ + try{ + lj_14_types.push_back(current_line[0]); + lj_14_sigmas.push_back(boost::lexical_cast<Real>(current_line[6])*0.1/(std::pow(2,1.0/6.0))*2); + lj_14_epsilons.push_back(std::abs(boost::lexical_cast<Real>(current_line[5])*4.184)); + }catch(std::exception& e){ + throw ost::io::IOException("Could not cast LJ parameters into real type!"); + } + }else{ + lj_types.push_back(types[0]); + lj_sigmas.push_back(parameters[0]); + lj_epsilons.push_back(parameters[1]); + } + + break; + } + case 7:{ //hbond + //we don't implement any things regarding hbonds in CHARMM + break; + } + } + } + //let's add all possible pairwise 1,4 interactions, where both interaction partners + //have explicitely defined 1,4 interactions + for(uint i = 0; i < lj_14_types.size(); ++i){ + for(uint j = i; j < lj_14_types.size(); ++j){ + MMInteractionPtr p(new MMInteraction(LJPair)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(lj_14_types[i]); + types.push_back(lj_14_types[j]); + parameters.push_back(0.5 * (lj_14_sigmas[i] + lj_14_sigmas[j])); + parameters.push_back(sqrt(lj_14_epsilons[i] * lj_14_epsilons[j])); + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddLJPair(p); + } + } + //let's add all pairwise 1,4 interactions, where only one partner has explicitely defined 1,4 interactions + for(uint i = 0; i < lj_14_types.size(); ++i){ + for(uint j = 0; j < lj_types.size(); ++j){ + MMInteractionPtr p(new MMInteraction(LJPair)); + std::vector<String> types; + std::vector<Real> parameters; + types.push_back(lj_14_types[i]); + types.push_back(lj_types[j]); + parameters.push_back(0.5 * (lj_14_sigmas[i] + lj_sigmas[j])); + parameters.push_back(sqrt(lj_14_epsilons[i] * lj_epsilons[j])); + p->SetTypes(types); + p->SetParam(parameters); + ff_->AddLJPair(p); + } + } + + +} + +void GromacsReader::ParseCHARMMRTF(std::vector<std::vector<String> >& content){ + + bool in_block = false; + + BuildingBlockPtr actual_block; + + String actual_block_name = ""; + + int keyword_id = -1; + std::vector<String> current_line; + bool line_read = false; + + for(uint line_counter = 0; line_counter < content.size(); ++line_counter){ + current_line = content[line_counter]; + std::cerr<<current_line[0]<<std::endl; + if(CHARMMData::Instance()->GetKeywordIndex(current_line[0]) != -1){ + keyword_id = CHARMMData::Instance()->GetKeywordIndex(current_line[0]); + } + if(keyword_id == -1) continue; + + + + if(in_block){ + line_read = false; + switch(keyword_id){ + case 15:{ //atom + actual_block->AddAtom(current_line[1],current_line[2],boost::lexical_cast<Real>(current_line[3])); + line_read=true; + break; + } + case 16:{//group + line_read=true; + break; + } + case 17:{//bond + int num_bonds = (current_line.size()-1) / 2; + for(int i = 0; i < num_bonds; ++i){ + MMInteractionPtr p(new MMInteraction(HarmonicBond)); + std::vector<String> names; + names.push_back(current_line[i*2+1]); + names.push_back(current_line[i*2+2]); + p->SetNames(names); + actual_block->AddBond(p); + } + line_read=true; + break; + } + case 18:{//angle + int num_angles = (current_line.size()-1) / 3; + for(int i = 0; i < num_angles; ++i){ + MMInteractionPtr p(new MMInteraction(UreyBradleyAngle)); + std::vector<String> names; + names.push_back(current_line[i*3+1]); + names.push_back(current_line[i*3+2]); + names.push_back(current_line[i*3+3]); + p->SetNames(names); + actual_block->AddAngle(p); + } + line_read=true; + break; + } + case 19:{//dihedral + int num_dihedrals = (current_line.size()-1) / 4; + for(int i = 0; i < num_dihedrals; ++i){ + MMInteractionPtr p(new MMInteraction(PeriodicDihedral)); + std::vector<String> names; + names.push_back(current_line[i*4+1]); + names.push_back(current_line[i*4+2]); + names.push_back(current_line[i*4+3]); + names.push_back(current_line[i*4+4]); + p->SetNames(names); + actual_block->AddDihedral(p); + } + line_read=true; + break; + } + case 20:{//improper + int num_impropers = (current_line.size()-1) / 4; + for(int i = 0; i < num_impropers; ++i){ + MMInteractionPtr p(new MMInteraction(HarmonicImproper)); + std::vector<String> names; + names.push_back(current_line[i*4+1]); + names.push_back(current_line[i*4+2]); + names.push_back(current_line[i*4+3]); + names.push_back(current_line[i*4+4]); + p->SetNames(names); + actual_block->AddImproper(p); + } + line_read=true; + break; + } + case 5:{//cmap + int num_cmaps = (current_line.size()-1) / 8; + for(int i = 0; i < num_cmaps; ++i){ + MMInteractionPtr p(new MMInteraction(CMap)); + std::vector<String> names; + names.push_back(current_line[i*4+1]); + names.push_back(current_line[i*4+2]); + names.push_back(current_line[i*4+3]); + names.push_back(current_line[i*4+4]); + names.push_back(current_line[i*4+8]); + p->SetNames(names); + actual_block->AddCMap(p); + } + line_read=true; + break; + } + case 21:{ //donor + line_read=true; + break; //I don't think. that this will ever be read... + } + case 22:{//acceptor + line_read=true; + break; //I don't think. that this will ever be read... + } + case 23:{// ic + line_read=true; + break; + } + case 24:{ //patching + line_read=true; + break; + } + case 25:{ //print + line_read=true; + break; + } + case 26:{ //double =>basically a bond + int num_bonds = (current_line.size()-1) / 2; + for(int i = 0; i < num_bonds; ++i){ + MMInteractionPtr p(new MMInteraction(HarmonicBond)); + std::vector<String> names; + names.push_back(current_line[i*2+1]); + names.push_back(current_line[i*2+2]); + p->SetNames(names); + actual_block->AddBond(p); + } + line_read=true; + break; + } + } + } + + if(line_read) continue; + + switch(keyword_id){ + case 9:{ + try {ff_->AddMass(current_line[2],boost::lexical_cast<Real>(current_line[3]));} + catch(std::exception& e){ + throw ost::io::IOException("Could not cast mass into real type!"); + } + break; + } + case 10:{ + break; //we don't read that for now.... + } + case 11:{//we don't allow patches for now + break; + } + case 12:{ + break; //we don't read that for now + } + case 13:{ + //check, whether there is an "open block" + if(in_block){ + ff_->AddBuildingBlock(actual_block_name,actual_block); + std::cerr<<"added building block: "<<actual_block_name<<std::endl; + } + actual_block_name = current_line[1]; + actual_block = BuildingBlockPtr(new BuildingBlock); + in_block = true; + std::cerr<<actual_block_name<<std::endl; + break; + } + case 14:{ + //check, whether there is an "open block" + if(in_block){ + ff_->AddBuildingBlock(actual_block_name,actual_block); + in_block = false; + } + break; + } + + + } + + } + + //add last building block if necessary + if(in_block) ff_->AddBuildingBlock(actual_block_name,actual_block); + +} + +}}} diff --git a/modules/mol/mm/src/gromacs_reader.hh b/modules/mol/mm/src/gromacs_reader.hh new file mode 100644 index 0000000000000000000000000000000000000000..89a2e20a45edbbb2e63c860800a80f704339eefc --- /dev/null +++ b/modules/mol/mm/src/gromacs_reader.hh @@ -0,0 +1,194 @@ +#ifndef OST_GROMACS_READER_HH +#define OST_GROMACS_READER_HH + +#include <fstream> + +#include <boost/filesystem.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/unordered_map.hpp> + +#include <ost/base.hh> +#include <ost/io/io_exception.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class GromacsData; +class CHARMMData; +class GromacsReader; +typedef boost::shared_ptr<GromacsData> GromacsDataPtr; +typedef boost::shared_ptr<GromacsReader> GromacsReaderPtr; +typedef boost::shared_ptr<CHARMMData> CHARMMDataPtr; + +class GromacsData{ +public: + static GromacsDataPtr Instance(); + int GetKeywordIndex(const String& keyword); + String ConvertToStandard(const String& res_name, const String& atom_name); + bool ConversionExists(const String& res_name); + +private: + GromacsData(); + GromacsData(const GromacsData&); + GromacsDataPtr operator=(const GromacsDataPtr&); + static GromacsDataPtr instance_; + boost::unordered_map<String,int> keyword_map_; + boost::unordered_map<String, std::vector<std::pair<String,String> > > renaming_to_standard_; + +}; + +class CHARMMData{ +public: + static CHARMMDataPtr Instance(); + int GetKeywordIndex(const String& keyword); + +private: + CHARMMData(); + CHARMMData(const CHARMMData&); + CHARMMDataPtr operator=(const CHARMMDataPtr&); + static CHARMMDataPtr instance_; + boost::unordered_map<String,int> keyword_map_; +}; + +class MMPreprocessor{ + +public: + + MMPreprocessor(const String& basepath): basepath_(basepath) { } + + std::vector<std::vector<String> > Process(const String& filename); + + void SetDefinition(const String& def) { defines_.insert(def); } + + boost::filesystem::path GetBasedir() { return basepath_; } + +private: + + //function, that can recursively resolve ifdef / ifndef statements + void ResolveIFDEF(std::vector<std::vector<String> >& file_content, int line_counter); + + //simply reads a file, cuts it into pieces and removes comments marked by '*' and ';' + std::vector<std::vector<String> > ReadFile(const String& filename); + + std::map<String,std::vector<String> > definitions_; + std::set<String> defines_; + boost::filesystem::path basepath_; +}; + + +class GromacsReader { +public: + + GromacsReader(const String& base_dir); + + void SetPreprocessorDefinition(const String& def) { preprocessor_.SetDefinition(def); } + + void ReadGromacsForcefield(); + + ForcefieldPtr GetForcefield() { return ff_;} + + void SetForcefield(ForcefieldPtr ff) { ff_ = ff; } + + void ReadResidueDatabase(const String& basename); + + void ReadITP(const String& basename); + + void ReadCHARMMPRM(const String& basename); + + void ReadCHARMMRTF(const String& basename); + +private: + + MMInteractionPtr ParseBond(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseAngle(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseDihedral(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseCMap(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseLJ(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseLJPair(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseConstraint(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseGenborn(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + MMInteractionPtr ParseExclusion(const std::vector<String>& data, + bool type_definition, + FuncType functype = Invalid); + + BuildingBlockPtr BlockFromRTP(const std::vector<std::vector<String> >& data); + + BuildingBlockPtr BlockFromITP(const std::vector<std::vector<String> >& data); + + TerminiConstructorPtr ParseTermini(const std::vector<std::vector<String> >& data); + + BlockModifierPtr ParseBlockModifier(const std::vector<std::vector<String> >& data); + + void ParseHydrogenRule(const std::vector<String>& data, GromacsHydrogenConstructor& constructor); + + void ParseTerminiReplaceRule(const std::vector<String>& data, GromacsBlockModifier& constructor); + + void ParseTerminiAddRule(const std::vector<String>& data1, const std::vector<String>& data2, + GromacsBlockModifier& constructor); + + //Reader functions for the mandatory forcefield files + void ParseForcefield(std::vector<std::vector<String> >& content); + void ParseAtomTypes(std::vector<std::vector<String> >& content); + + //Reader functions for CHARMM stuff + void ParseCHARMMPRM(std::vector<std::vector<String> >& content); + + void ParseCHARMMRTF(std::vector<std::vector<String> >& content); + + //Reader functions for all different residue database files + void ParseRTP(std::vector<std::vector<String> >& content); + void ParseARN(std::vector<std::vector<String> >& content); + void ParseHDB(std::vector<std::vector<String> >& content); + void ParseNTDB(std::vector<std::vector<String> >& content); + void ParseCTDB(std::vector<std::vector<String> >& content); + void ParseVSD(std::vector<std::vector<String> >& content); + void ParseRtoB(std::vector<std::vector<String> >& content); + //Reader function for single molecule itp files + void ParseITP(std::vector<std::vector<String> >& content); + + boost::unordered_map<String, std::vector<std::pair<String,String> > > atom_renaming_ff_specific_; + boost::unordered_map<String, ResidueNamesPtr> res_renaming_ff_specific_; + + std::vector<FuncType> ff_bonded_types_; + + MMPreprocessor preprocessor_; + ForcefieldPtr ff_; + + //following part is ugly... + //data that is read during the residue datababase parsing process gets stored in there + std::vector<FuncType> bonded_types_; + std::vector<String> read_residues_; +}; + + +}}}//ns + +#endif diff --git a/modules/mol/mm/src/index.hh b/modules/mol/mm/src/index.hh new file mode 100644 index 0000000000000000000000000000000000000000..055ad73a23ca22b4f53b02cf78ccefd2aa7421d4 --- /dev/null +++ b/modules/mol/mm/src/index.hh @@ -0,0 +1,173 @@ +#ifndef OST_MM_INDEX_HH +#define OST_MM_INDEX_HH + +/* + Author: Marco Biasini + */ + +#include <algorithm> + +#include <cstring> + +namespace ost { namespace mol{ namespace mm{ + +namespace impl { +template <uint D> +class IndexBase { +public: + enum { Dimension = D }; + IndexBase(const IndexBase& rhs) { + memcpy(data_, rhs.data_, sizeof(uint[D])); + } + IndexBase() { + memset(data_, 0, sizeof(uint[D])); + } + + IndexBase& operator=(const IndexBase& rhs) { + memcpy(data_, rhs.data_, sizeof(uint[D])); + return *this; + } + uint operator[](uint idx) const { + assert(idx < D); + return data_[idx]; + } + uint& operator[](uint idx) { + assert(idx < D); + return data_[idx]; + } + //allows index to be inserted into set + inline bool operator < (const IndexBase<D>& rhs) const{ + return std::lexicographical_compare(data_, data_+D, rhs.data_, rhs.data_+D); + } + + inline bool operator==(const IndexBase<D>& rhs) const{ + return std::equal(data_,data_+D,rhs.data_); + } + + inline bool operator!=(const IndexBase<D>& rhs) const{ + return !(*this == rhs); + } + +private: + uint data_[D]; +}; + +} // namespace impl + +template <uint D> +class Index; + +template <> +class Index<1> : public impl::IndexBase<1> { +public: + Index() : impl::IndexBase<1>() {} + Index(uint a) { + (*this)[0]=a; + } +}; +template <> +class Index<2> : public impl::IndexBase<2> { +public: + Index() : impl::IndexBase<2>() {} + Index(uint a, uint b) { + (*this)[0]=a; + (*this)[1]=b; + } +}; +template <> +class Index<3> : public impl::IndexBase<3> { +public: + Index() : impl::IndexBase<3>() {} + Index(uint a, uint b, uint c) { + (*this)[0]=a; + (*this)[1]=b; + (*this)[2]=c; + } +}; +template <> +class Index<4> : public impl::IndexBase<4> { +public: + Index() : impl::IndexBase<4>() {} + Index(uint a, uint b, uint c, uint d) { + (*this)[0]=a; + (*this)[1]=b; + (*this)[2]=c; + (*this)[3]=d; + } +}; +template <> +class Index<5> : public impl::IndexBase<5> { +public: + Index() : impl::IndexBase<5>() {} + Index(uint a, uint b, uint c, uint d, uint e) { + (*this)[0]=a; + (*this)[1]=b; + (*this)[2]=c; + (*this)[3]=d; + (*this)[4]=e; + } +}; +template <> +class Index<6> : public impl::IndexBase<6> { +public: + Index() : impl::IndexBase<6>() {} + Index(uint a, uint b, uint c, uint d, uint e, uint f) { + (*this)[0]=a; + (*this)[1]=b; + (*this)[2]=c; + (*this)[3]=d; + (*this)[4]=e; + (*this)[5]=f; + } +}; +template <> +class Index<7> : public impl::IndexBase<7> { +public: + Index() : impl::IndexBase<7>() {} + Index(uint a, uint b, uint c, uint d, uint e, uint f, uint g) { + (*this)[0]=a; + (*this)[1]=b; + (*this)[2]=c; + (*this)[3]=d; + (*this)[4]=e; + (*this)[5]=f; + (*this)[6]=g; + } +}; +template<uint D> +class IndexIterator { +public: + typedef Index<D> IndexType; + IndexIterator(const IndexType& s, const IndexType& e) + : start_(s), end_(e), current_(s) { + + } + + IndexIterator<D>& operator++() { + uint current_it=0; + while (++current_[current_it] > end_[current_it]) { + current_it++; + if (current_it < D) { + current_[current_it-1] = start_[current_it-1]; + } else { + break; + } + } + return *this; + } + const IndexType& operator *() const { + return current_; + } + bool AtEnd() { + return current_[D-1] > end_[D-1]; + } +private: + IndexType start_; + IndexType end_; + IndexType current_; + +}; + +}}} + +#endif diff --git a/modules/mol/mm/src/mm_interaction.cc b/modules/mol/mm/src/mm_interaction.cc new file mode 100644 index 0000000000000000000000000000000000000000..093e2d122e43773e786c1afa5b3440e109d65c2d --- /dev/null +++ b/modules/mol/mm/src/mm_interaction.cc @@ -0,0 +1,194 @@ +#include <ost/mol/mm/mm_interaction.hh> + +namespace ost { namespace mol{ namespace mm{ + +MMInteraction::MMInteraction(FuncType func_type): func_type_(func_type), + set_parameters_(false), + has_type_wildcard_(false), + has_name_wildcard_(false){ } + + +void MMInteraction::SetTypes(std::vector<String> types){ + if(!this->CheckSetNamesTypes(types)){ + throw ost::Error("Tried to set invalid number of types to interaction!"); + } + atom_types_ = types; + if(std::find(atom_types_.begin(),atom_types_.end(),"X") != atom_types_.end()){ + has_type_wildcard_ = true; + } + else has_type_wildcard_ = false; +} + +void MMInteraction::SetNames(std::vector<String> names){ + if(!this->CheckSetNamesTypes(names)){ + throw ost::Error("Tried to set invalid number of names to interaction!"); + } + atom_names_ = names; + if(std::find(atom_names_.begin(),atom_names_.end(),"X") != atom_names_.end()){ + has_name_wildcard_ = true; + } + else has_name_wildcard_ = false; +} + +void MMInteraction::SetParam(std::vector<Real>& parameters){ + if(!this->CheckSetParam(parameters)){ + throw ost::Error("Tried to set invalid number of parameters to interaction!"); + } + parameters_ = parameters; + set_parameters_ = true; +} + +ost::mol::AtomHandleList MMInteraction::GetAtoms(const ost::mol::ResidueHandle& res) const{ + + ost::mol::AtomHandleList return_list; + ost::mol::ResidueHandle prev = res.GetPrev(); + ost::mol::ResidueHandle next = res.GetNext(); + String atom_name; + ost::mol::AtomHandle atom; + + for(std::vector<String>::const_iterator i = atom_names_.begin(); + i != atom_names_.end(); ++i){ + atom_name = (*i); + if(atom_name[0] == '+'){ + atom_name = atom_name.substr(1); + if(!next.IsValid()){ + throw ost::Error("Access to nonexistent next residue requested!"); + } + atom = next.FindAtom(atom_name); + if(atom.IsValid()){ + return_list.push_back(atom); + continue; + } + throw ost::Error("Could not find required atom "+*i+"!"); + } + if(atom_name[0] == '-'){ + atom_name = atom_name.substr(1); + if(!prev.IsValid()){ + throw ost::Error("Access to nonexistent previous residue requested!"); + } + atom = prev.FindAtom(atom_name); + if(atom.IsValid()){ + return_list.push_back(atom); + continue; + } + throw ost::Error("Could not find required atom "+*i+"!"); + } + atom = res.FindAtom(atom_name); + if(atom.IsValid()){ + return_list.push_back(atom); + continue; + } + throw ost::Error("Could not find required atom "+*i+"!"); + } + + return return_list; +} + +bool MMInteraction::MatchTypes(const std::vector<String>& atom_types) const { + + if(atom_types_.size() == 0) return false; + if(atom_types.size() != atom_types_.size()) return false; + + bool match = true; + bool reverse_match = true; + + uint i,j; + + for(i = 0, j = atom_types_.size()-1; i < atom_types_.size(); ++i,--j){ + if((atom_types[i] != atom_types_[i]) && (atom_types_[i] != "X")) match = false; + if((atom_types[i] != atom_types_[j]) && (atom_types_[j] != "X")) reverse_match = false; + } + + return match || reverse_match; +} + +bool MMInteraction::MatchNames(const std::vector<String>& atom_names) const { + + if(atom_names_.size() == 0) return false; + if(atom_names.size() != atom_names_.size()) return false; + + bool match = true; + bool r_match = true; + + uint i,j; + + for(i = 0, j = atom_names_.size()-1; i < atom_names_.size(); ++i,--j){ + if((atom_names[i] != atom_names_[i]) && (atom_names_[i] != "X")) match = false; + if((atom_names[i] != atom_names_[j]) && (atom_names_[j] != "X")) r_match = false; + } + + return match || r_match; +} + +bool MMInteraction::ReplaceAtom(const String& name, const String& new_name, const String& new_type){ + + for(uint i = 0; i < atom_names_.size(); ++i){ + if(atom_names_[i] == name){ + atom_names_[i] = new_name; + if(i < atom_types_.size()) atom_types_[i] = new_type; + //it could be, that wildcard stuff has changed + has_type_wildcard_ = std::find(atom_types_.begin(),atom_types_.end(),"X") != atom_types_.end(); + has_name_wildcard_ = std::find(atom_names_.begin(),atom_names_.end(),"X") != atom_names_.end(); + return true; + } + } + return false; +} + +bool MMInteraction::HasName(const String& name) const{ + return std::find(atom_names_.begin(),atom_names_.end(),name) != atom_names_.end(); +} + +bool MMInteraction::HasType(const String& type) const{ + return std::find(atom_types_.begin(),atom_types_.end(),type) != atom_types_.end(); +} + +bool MMInteraction::CheckSetNamesTypes(std::vector<String>& types){ + + switch(func_type_){ + case HarmonicBond: return types.size() == 2; + case HarmonicAngle: return types.size() == 3; + case UreyBradleyAngle: return types.size() == 3; + case PeriodicDihedral: return types.size() == 4; + case PeriodicImproper: return types.size() == 4; + case HarmonicImproper: return types.size() == 4; + case CMap: return types.size() == 5; + case LJ: return types.size() == 1; + case LJPair: return types.size() == 2; + case GBSA: return types.size() == 1; + case DistanceConstraint: return types.size() == 2; + case Exclusion: return types.size() == 2; + case HarmonicPositionRestraint: return types.size() == 1; + case HarmonicDistanceRestraint: return types.size() == 2; + default: return false; + } +} + +bool MMInteraction::CheckSetParam(std::vector<Real>& param){ + + switch(func_type_){ + case HarmonicBond: return param.size() == 2; + case HarmonicAngle: return param.size() == 2; + case UreyBradleyAngle: return param.size() == 4; + case PeriodicDihedral: return param.size() == 3; + case PeriodicImproper: return param.size() == 3; + case HarmonicImproper: return param.size() == 2; + case CMap:{ + int num_param = param.size(); + if(num_param < 1) return false; + int x = param[0]; + return num_param == (x*x + 1); + } + case LJ: return param.size() == 2; + case LJPair: return param.size() == 2; + case GBSA: return param.size() == 2; + case DistanceConstraint: return param.size() == 1; + case Exclusion: return param.empty(); + case HarmonicPositionRestraint: return param.size() == 7; + case HarmonicDistanceRestraint: return param.size() == 2; + default: return false; + } + +} + +}}} //ns \ No newline at end of file diff --git a/modules/mol/mm/src/mm_interaction.hh b/modules/mol/mm/src/mm_interaction.hh new file mode 100644 index 0000000000000000000000000000000000000000..edc8afc21e6ab660b279275267db9ac4fccd2273 --- /dev/null +++ b/modules/mol/mm/src/mm_interaction.hh @@ -0,0 +1,147 @@ +#ifndef OST_MM_INTERACTION_HH +#define OST_MM_INTERACTION_HH + +#include <vector> +#include <fstream> + +#include <boost/shared_ptr.hpp> +#include <boost/filesystem.hpp> + +#include <ost/io/binary_data_source.hh> +#include <ost/io/binary_data_sink.hh> +#include <ost/io/io_exception.hh> +#include <ost/message.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/residue_handle.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class MMInteraction; +typedef boost::shared_ptr<MMInteraction> MMInteractionPtr; + +enum FuncType{ + Invalid, + HarmonicBond, + HarmonicAngle, + UreyBradleyAngle, + PeriodicDihedral, + PeriodicImproper, + HarmonicImproper, + CMap, + LJ, + LJPair, + GBSA, + DistanceConstraint, + Exclusion, + HarmonicPositionRestraint, + HarmonicDistanceRestraint +}; + +class MMInteraction{ + +public: + MMInteraction(FuncType func_type); + + void SetTypes(std::vector<String> types); + + void SetNames(std::vector<String> names); + + void SetParam(std::vector<Real>& parameters); + + std::vector<String> GetTypes() const { return atom_types_; } + + std::vector<String> GetNames() const { return atom_names_; } + + std::vector<Real> GetParam() const { return parameters_; } + + ost::mol::AtomHandleList GetAtoms(const ost::mol::ResidueHandle& res) const; + + FuncType GetFuncType() const { return func_type_; } + + bool ReplaceAtom(const String& name, const String& new_name, const String& new_type); + + bool MatchTypes(const std::vector<String>& atom_types) const; + + bool MatchNames(const std::vector<String>& atom_names) const; + + bool HasName(const String& name) const; + + bool HasType(const String& type) const; + + bool IsParametrized() const { return set_parameters_; } + + bool HasTypeWildcard() const { return has_type_wildcard_; } + + bool HasNameWildcard() const { return has_name_wildcard_; } + + template <typename DS> + void Serialize(DS& ds){ + ds & set_parameters_; + ds & has_type_wildcard_; + ds & has_name_wildcard_; + + if(ds.IsSource()){ + int num_types; + int num_names; + int num_param; + ds & num_types; + ds & num_names; + ds & num_param; + for(int i = 0; i < num_types; ++i){ + String type; + ds & type; + atom_types_.push_back(type); + } + for(int i = 0; i < num_names; ++i){ + String name; + ds & name; + atom_names_.push_back(name); + } + for(int i = 0; i < num_param; ++i){ + Real param; + ds & param; + parameters_.push_back(param); + } + } + else{ + int atom_types_size = atom_types_.size(); + int atom_names_size = atom_names_.size(); + int parameters_size = parameters_.size(); + ds & atom_types_size; + ds & atom_names_size; + ds & parameters_size; + + for(std::vector<String>::iterator i = atom_types_.begin(); + i != atom_types_.end(); ++i){ + ds & *i; + } + for(std::vector<String>::iterator i = atom_names_.begin(); + i != atom_names_.end(); ++i){ + ds & *i; + } + for(std::vector<Real>::iterator i = parameters_.begin(); + i != parameters_.end(); ++i){ + ds & *i; + } + } + } + +private: + + bool CheckSetNamesTypes(std::vector<String>& types); + bool CheckSetParam(std::vector<Real>& param); + + FuncType func_type_; + bool set_parameters_; + bool has_type_wildcard_; + bool has_name_wildcard_; + std::vector<Real> parameters_; + std::vector<String> atom_types_; + std::vector<String> atom_names_; +}; + + +}}} //ns + +#endif diff --git a/modules/mol/mm/src/mm_modeller.cc b/modules/mol/mm/src/mm_modeller.cc new file mode 100644 index 0000000000000000000000000000000000000000..893e1a2702757464e4d1e0e0ce8671b6ce3b5edb --- /dev/null +++ b/modules/mol/mm/src/mm_modeller.cc @@ -0,0 +1,322 @@ +#include <ost/mol/mm/mm_modeller.hh> + + +namespace ost{ namespace mol{ namespace mm{ + +void MMModeller::GenerateDisulfidBonds(ost::mol::EntityHandle& handle){ + + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + ost::mol::XCSEditor ed = handle.EditXCS(); + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(i->GetName() == "CYS" || i->GetName() == "CYX" || i->GetName() == "CYS2" || i->GetName() == "CYM"){ + ost::mol::AtomHandle s = i->FindAtom("SG"); + if(s.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(s.GetPos(),2.5); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if(j->GetName() == "SG" && j->GetResidue() != *i){ + if(!ost::mol::BondExists(s,*j)){ + ed.Connect(s,*j); + } + ed.RenameResidue(*i,"CYS2"); + ed.RenameResidue(j->GetResidue(),"CYS2"); + } + } + } + } + } +} + +void MMModeller::GenerateCYSHEMEBonds(ost::mol::EntityHandle& handle){ + + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + ost::mol::XCSEditor ed = handle.EditXCS(); + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(i->GetName() == "HEM" || i->GetName() == "HEME"){ + ost::mol::AtomHandle fe = i->FindAtom("FE"); + if(fe.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(fe.GetPos(), 3.0); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if( j->GetName() == "SG"){ + if(!ost::mol::BondExists(fe,*j)){ + ed.Connect(fe,*j); + } + ed.RenameResidue(*i,"HEME"); + ed.RenameResidue(j->GetResidue(),"CYS2"); + } + } + } + ost::mol::AtomHandle cab = i->FindAtom("CAB"); + if(cab.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(cab.GetPos(), 0.23); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if(j->GetName() == "SG"){ + if(!BondExists(cab,*j)){ + ed.Connect(cab,*j); + } + ed.RenameResidue(*i,"HEME"); + ed.RenameResidue(j->GetResidue(),"CYS2"); + } + } + } + ost::mol::AtomHandle cac = i->FindAtom("CAC"); + if(cac.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(cac.GetPos(),0.23); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if(j->GetName() == "SG"){ + if(!BondExists(cac,*j)){ + ed.Connect(cac,*j); + } + ed.RenameResidue(*i,"HEME"); + ed.RenameResidue(j->GetResidue(),"CYS2"); + } + } + } + } + } +} + +void MMModeller::GenerateHISHEMEBonds(ost::mol::EntityHandle& handle){ + + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + ost::mol::XCSEditor ed = handle.EditXCS(); + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(i->GetName() == "HEM" || i->GetName() == "HEME"){ + ost::mol::AtomHandle fe = i->FindAtom("FE"); + if(fe.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(fe.GetPos(),2.5); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if(j->GetName() == "NE2" && j->GetResidue().GetName() == "HIS"){ + if(!ost::mol::BondExists(fe,*j)){ + ed.Connect(fe,*j); + } + ed.RenameResidue(*i,"HEME"); + ed.RenameResidue(j->GetResidue(),"HIS1"); + } + } + } + } + } +} + +void MMModeller::GenerateMETHEMEBonds(ost::mol::EntityHandle& handle){ + + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + ost::mol::XCSEditor ed = handle.EditXCS(); + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(i->GetName() == "HEM" || i->GetName() == "HEME"){ + ost::mol::AtomHandle fe = i->FindAtom("FE"); + if(fe.IsValid()){ + ost::mol::AtomHandleList in_reach = handle.FindWithin(fe.GetPos(),2.9); + for(ost::mol::AtomHandleList::iterator j = in_reach.begin(); + j != in_reach.end(); ++j){ + if(j->GetName() == "SD" && j->GetResidue().GetName() == "MET"){ + if(!ost::mol::BondExists(fe,*j)){ + ed.Connect(fe,*j); + } + ed.RenameResidue(*i,"HEME"); + } + } + } + } + } +} + +void MMModeller::LowerPrecision(ost::mol::EntityHandle& handle){ + + ost::mol::AtomHandleList atom_list = handle.GetAtomList(); + ost::mol::XCSEditor ed = handle.EditXCS(ost::mol::BUFFERED_EDIT); + geom::Vec3 pos; + geom::Vec3 truncated_pos; + + for(ost::mol::AtomHandleList::iterator i = atom_list.begin(); + i != atom_list.end(); ++i){ + pos = i->GetPos(); + truncated_pos[0] = Real(round(pos[0]*100))/100; + truncated_pos[1] = Real(round(pos[1]*100))/100; + truncated_pos[2] = Real(round(pos[2]*100))/100; + ed.SetAtomPos(*i,truncated_pos); + } + ed.UpdateICS(); +} + +void MMModeller::AssignPDBNaming(ost::mol::EntityHandle& handle){ + + std::map<String,String> gromacs_to_pdb; + gromacs_to_pdb["ARGN"] = "ARG"; + gromacs_to_pdb["ASPH"] = "ASP"; + gromacs_to_pdb["CYS2"] = "CYS"; + gromacs_to_pdb["GLUH"] = "GLU"; + gromacs_to_pdb["HISD"] = "HIS"; + gromacs_to_pdb["HISE"] = "HIS"; + gromacs_to_pdb["HISH"] = "HIS"; + gromacs_to_pdb["HIS1"] = "HIS"; + gromacs_to_pdb["LYSN"] = "LYS"; + gromacs_to_pdb["HEME"] = "HEM"; + + ost::mol::XCSEditor ed = handle.EditXCS(); + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + String res_name; + ost::mol::AtomHandle atom; + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + res_name = i->GetName(); + if(gromacs_to_pdb.find(res_name) != gromacs_to_pdb.end()){ + ed.RenameResidue(*i,gromacs_to_pdb[res_name]); + } + //this is nasty hardcoded stuff + //in case of ILE gromacs seems to define wrong standard naming + //we have to keep this wrong standard naming to remain consistent + //with the namings in the forcefields. + //to avoid errors in loading a pdb structure with these namings + //we have to hardcode a correct conversion + if(res_name == "ILE"){ + atom = i->FindAtom("CD"); + if(atom.IsValid()){ + ed.RenameAtom(atom,"CD1"); + } + atom = i->FindAtom("HD1"); + if(atom.IsValid()){ + ed.RenameAtom(atom,"HD11"); + } + atom = i->FindAtom("HD2"); + if(atom.IsValid()){ + ed.RenameAtom(atom,"HD12"); + } + atom = i->FindAtom("HD3"); + if(atom.IsValid()){ + ed.RenameAtom(atom,"HD13"); + } + } + } +} + +void MMModeller::AssignGromacsNaming(ost::mol::EntityHandle& handle){ + + ost::mol::XCSEditor ed = handle.EditXCS(); + + //Let's first rename as much as possible to the gromacs standard + std::map<String,String> residue_renaming; + + //a proper solution should be found for that (assign proper protonation) + residue_renaming["HIS"] = "HISE"; + //this is awful.... + + + residue_renaming["HID"] = "HISD"; + residue_renaming["HIE"] = "HISE"; + residue_renaming["HSP"] = "HISH"; + residue_renaming["LSN"] = "LYSN"; + residue_renaming["ASPP"] = "ASPH"; + residue_renaming["GLUP"] = "GLUH"; + residue_renaming["HOH"] = "SOL"; + residue_renaming["TIP3"] = "SOL"; + residue_renaming["HOH"] = "SOL"; + residue_renaming["HEME"] = "HEM"; + //following stuff are required to rename the charmm names that are different, + //as it for example comes from CHARMM GUI + residue_renaming["POT"] = "K"; + residue_renaming["CLA"] = "CL"; + residue_renaming["SOD"] = "NA"; + residue_renaming["CAL"] = "CA"; + residue_renaming["CES"] = "CS"; + residue_renaming["ZN2"] = "ZN"; + + ost::mol::ResidueHandleList res_list = handle.GetResidueList(); + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(residue_renaming.find(i->GetName()) != residue_renaming.end()){ + ed.RenameResidue(*i,residue_renaming[i->GetName()]); + } + } + + //this data is taken from the gromacs xlateat.dat file + std::map<String, std::map<String, String> > renaming_to_standard; + renaming_to_standard["ILE"] = std::map<String,String>(); + renaming_to_standard["HOH"] = std::map<String,String>(); + renaming_to_standard["HO4"] = std::map<String,String>(); + renaming_to_standard["HO5"] = std::map<String,String>(); + renaming_to_standard["HEME"] = std::map<String,String>(); + renaming_to_standard["protein"] = std::map<String,String>(); + + renaming_to_standard["ILE"]["CD1"] = "CD"; + renaming_to_standard["ILE"]["HD11"] = "HD1"; + renaming_to_standard["ILE"]["HD12"] = "HD2"; + renaming_to_standard["ILE"]["HD13"] = "HD3"; + + renaming_to_standard["SOL"]["O"] = "OW"; + renaming_to_standard["SOL"]["OW1"] = "OW"; + renaming_to_standard["SOL"]["OH2"] = "OW"; //specific for CHARMM-GUI + renaming_to_standard["SOL"]["H1"] = "HW1"; //specific for CHARMM-GUI + renaming_to_standard["SOL"]["H2"] = "HW2"; //specific for CHARMM-GUI + + renaming_to_standard["HEM"]["N_A"] = "NA"; + renaming_to_standard["HEM"]["N_B"] = "NB"; + renaming_to_standard["HEM"]["N_C"] = "NC"; + renaming_to_standard["HEM"]["N_D"] = "ND"; + + renaming_to_standard["protein"]["O1"] = "O"; + renaming_to_standard["protein"]["O2"] = "OXT"; + renaming_to_standard["protein"]["OT1"] = "O"; + renaming_to_standard["protein"]["OT2"] = "OXT"; + renaming_to_standard["protein"]["OT"] = "OXT"; + renaming_to_standard["protein"]["O'"] = "O"; + renaming_to_standard["protein"]["O''"] = "OXT"; + renaming_to_standard["protein"]["OC1"] = "O"; + renaming_to_standard["protein"]["OC2"] = "OXT"; + renaming_to_standard["protein"]["HN"] = "H"; + renaming_to_standard["protein"]["HT1"] = "H1"; + renaming_to_standard["protein"]["HT2"] = "H2"; + renaming_to_standard["protein"]["HT3"] = "H3"; + + //again CHARMM specific stuff + renaming_to_standard["K"]["POT"] = "K"; + renaming_to_standard["CL"]["CLA"] = "CL"; + renaming_to_standard["NA"]["SOD"] = "NA"; + renaming_to_standard["CA"]["CAL"] = "CA"; + renaming_to_standard["CS"]["CES"] = "CS"; + + + + //let's apply the explicit residue names definition of aboves weird data structure + ost::mol::AtomHandleList renaming_atom_list; + String res_name; + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + res_name = i->GetName(); + if(renaming_to_standard.find(res_name) == renaming_to_standard.end()) continue; + renaming_atom_list = i->GetAtomList(); + for(ost::mol::AtomHandleList::iterator j = renaming_atom_list.begin(); + j != renaming_atom_list.end(); ++j){ + if(renaming_to_standard[res_name].find(j->GetName()) == renaming_to_standard[res_name].end()) continue; + ed.RenameAtom(*j,renaming_to_standard[res_name][j->GetName()]); + } + } + + //entries with of name protein have to be applied on all peptide residues + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + if(!i->IsPeptideLinking()) continue; + renaming_atom_list = i->GetAtomList(); + for(ost::mol::AtomHandleList::iterator j = renaming_atom_list.begin(); + j != renaming_atom_list.end(); ++j){ + if(renaming_to_standard["protein"].find(j->GetName()) == renaming_to_standard["protein"].end()) continue; + ed.RenameAtom(*j,renaming_to_standard["protein"][j->GetName()]); + } + } +} + +}}} diff --git a/modules/mol/mm/src/mm_modeller.hh b/modules/mol/mm/src/mm_modeller.hh new file mode 100644 index 0000000000000000000000000000000000000000..682f5a885ba37e829e96a35c410923350c7081d1 --- /dev/null +++ b/modules/mol/mm/src/mm_modeller.hh @@ -0,0 +1,61 @@ +#ifndef OST_MMMODELLER_HH +#define OST_MMMODELLER_HH + + +#include <vector> +#include <set> + +#include <ost/platform.hh> +#include <ost/io/mol/pdb_reader.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/geom/vec3.hh> +#include <ost/geom/composite.hh> +#include <ost/geom/transform.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/message.hh> +//#include <ost/mol/mm/gromacs_data.hh> +#include <ost/mol/bounding_box.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/index.hh> +#include <ost/mol/mm/topology.hh> +#include <ost/conop/heuristic.hh> +#include <ost/mol/spatial_organizer.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class MMModeller{ +public: + + static void GenerateDisulfidBonds(ost::mol::EntityHandle& handle); + + static void GenerateCYSHEMEBonds(ost::mol::EntityHandle& handle); + + static void GenerateHISHEMEBonds(ost::mol::EntityHandle& handle); + + static void GenerateMETHEMEBonds(ost::mol::EntityHandle& handle); + + //may sound pretty stupid... + //But this is necessary if we want to compare our energies with + //the energies calculated by gromacs. When ost writes and entity + //down to disk, it uses 3 digits precision. + //If we feed this into gromacs, it also produces a topology + //with three digits precision. The problem is, that gromacs + //uses nm, therefore the precision gets lowered tenfold. + //To take care of that it is necessary to lower our precision... + static void LowerPrecision(ost::mol::EntityHandle& handle); + + static void AssignPDBNaming(ost::mol::EntityHandle& handle); + + static void AssignGromacsNaming(ost::mol::EntityHandle& handle); +}; + + +}}} + +#endif diff --git a/modules/mol/mm/src/mm_observer.cc b/modules/mol/mm/src/mm_observer.cc new file mode 100644 index 0000000000000000000000000000000000000000..ed1f14b7a9396f3765ede452b2d26d7c37bec101 --- /dev/null +++ b/modules/mol/mm/src/mm_observer.cc @@ -0,0 +1,180 @@ +#include <ost/mol/mm/mm_observer.hh> + +namespace ost { namespace mol{ namespace mm{ + +void TrajObserver::Init(boost::shared_ptr<OpenMM::Context> c, + TopologyPtr top){ + + if(registered_){ + throw ost::Error("Can register observer to only one simulation!"); + } + + registered_ = true; + + context_ = c; + ost::mol::EntityHandle ent = top->GetEntity().Copy(); + MMModeller::AssignPDBNaming(ent); + c_group_ = ost::mol::CreateCoordGroup(ent.GetAtomList()); +} + +void TrajObserver::Notify(){ + + geom::Vec3List positions; + StateExtractor::ExtractPositions(context_,positions,true); + c_group_.AddFrame(positions); +} + + +void TrajWriter::Init(boost::shared_ptr<OpenMM::Context> c, + TopologyPtr top){ + + if(registered_){ + throw ost::Error("Can register observer to only one simulation!"); + } + + registered_ = true; + + context_ = c; + ost::io::IOProfile profile("CHARMM",false,false,false,false,false); + ost::io::PDBWriter writer(pdb_filename_, profile); + writer.Write(top->GetEntity().GetAtomList()); + + stream_.open(dcd_filename_.c_str(), std::ios::binary); + + x.resize(top->GetNumAtoms()); + y.resize(top->GetNumAtoms()); + z.resize(top->GetNumAtoms()); + + + // size of first header block in bytes + int32_t magic_number=84; + stream_.write(reinterpret_cast<char*>(&magic_number), 4); + + // magic string + char crd[]={'C', 'O', 'R', 'D'}; + stream_.write(crd, 4); + + // icntrl[0], NSET, number of frames + // we don't know the number of frames yet, will be written + // when the finalize function is called. + int32_t zero=0; + stream_.write(reinterpret_cast<char*>(&zero), 4); + + // icntrl[1], ISTART, starting timestep + stream_.write(reinterpret_cast<char*>(&zero), 4); + + // icntrl[2], NSAVC, timesteps between DCD saves + int32_t one=1; + stream_.write(reinterpret_cast<char*>(&one), 4); + + // icntrl[3] to icntrl[7], unused + for (int i=3; i<=7; ++i) { + stream_.write(reinterpret_cast<char*>(&zero), 4); + } + + // icntrl[8], NAMNF, number of fixed atoms + stream_.write(reinterpret_cast<char*>(&zero), 4); + + // icntrl[9], DELTA, timestep as float for CHARMM format + float delta=1.0; + stream_.write(reinterpret_cast<char*>(&delta), 4); + + // icntrl[10], CHARMM format: ucell per frame + stream_.write(reinterpret_cast<char*>(&one), 4); + + // icntrl[11] to icntrl[18], unused + for (int i=11; i<=18; ++i) { + stream_.write(reinterpret_cast<char*>(&zero), 4); + } + + // icntrl[19], charmm version + int32_t charmm_version=24; + stream_.write(reinterpret_cast<char*>(&charmm_version), 4); + // bracket first header block + stream_.write(reinterpret_cast<char*>(&magic_number), 4); + + // no titles in title block + int32_t four=4; + stream_.write(reinterpret_cast<char*>(&four), 4); + stream_.write(reinterpret_cast<char*>(&zero), 4); + stream_.write(reinterpret_cast<char*>(&four), 4); + + // atom count block + stream_.write(reinterpret_cast<char*>(&four), 4); + int32_t atom_count=top->GetNumAtoms(); + stream_.write(reinterpret_cast<char*>(&atom_count), 4); + stream_.write(reinterpret_cast<char*>(&four), 4); +} + +void TrajWriter::Notify(){ + + if(!registered_){ + throw ost::Error("Trajectory writer is not registered to any simulation!"); + } + + if(!stream_){ + throw ost::Error("Trajectory writer does not contain open filestream. Did you already call the finalize funciton before?"); + } + + geom::Vec3List positions; + StateExtractor::ExtractPositions(context_,positions,true,true); + OpenMM::State openmm_state = context_->getState(0); //create minimal state + //to only extract periodic + //box information + openmm_state.getPeriodicBoxVectors(ucell_a,ucell_b,ucell_c); + + int32_t out_n=positions.size()*4; + + // ucell + int32_t bsize=48; // ucell block size, 6 doubles + //context_->getSystem().getDefaultPeriodicBoxVectors(ucell_a,ucell_b,ucell_c); + + // a,alpha,b,beta,gamma,c (don't ask) + // OpenMM only supports rectangular boxes, since we have to add + // the cosines of the angles, we can directly set the values to 0.0 + + double ucell[]={10 * sqrt(ucell_a.dot(ucell_a)), + 0.0, + 10 * sqrt(ucell_b.dot(ucell_b)), + 0.0, + 0.0, + 10 * sqrt(ucell_c.dot(ucell_c))}; + stream_.write(reinterpret_cast<char*>(&bsize),4); + stream_.write(reinterpret_cast<char*>(ucell),bsize); + stream_.write(reinterpret_cast<char*>(&bsize),4); + + int k=0; + for (geom::Vec3List::iterator i=positions.begin(); + i!=positions.end(); ++i, ++k) { + x[k]=float((*i)[0]); + y[k]=float((*i)[1]); + z[k]=float((*i)[2]); + } + stream_.write(reinterpret_cast<char*>(&out_n), 4); + stream_.write(reinterpret_cast<char*>(&x[0]), out_n); + stream_.write(reinterpret_cast<char*>(&out_n), 4); + stream_.write(reinterpret_cast<char*>(&out_n), 4); + stream_.write(reinterpret_cast<char*>(&y[0]), out_n); + stream_.write(reinterpret_cast<char*>(&out_n), 4); + stream_.write(reinterpret_cast<char*>(&out_n), 4); + stream_.write(reinterpret_cast<char*>(&z[0]), out_n); + stream_.write(reinterpret_cast<char*>(&out_n), 4); + + ++frames_; + + stream_.seekp(8,std::ios_base::beg); + stream_.write(reinterpret_cast<char*>(&frames_),4); + stream_.seekp(0,std::ios_base::end); +} + +void TrajWriter::Finalize(){ + if(!registered_){ + throw ost::Error("Trajectory writer is not registered to any simulation!"); + } + if(!stream_){ + throw ost::Error("Trajectory writer does not contain open filestream. Did you already call the finalize function before?"); + } + stream_.close(); +} + +}}}// ns diff --git a/modules/mol/mm/src/mm_observer.hh b/modules/mol/mm/src/mm_observer.hh new file mode 100644 index 0000000000000000000000000000000000000000..92b52971a4c5b60f3fef5d3e60620e8b9c067588 --- /dev/null +++ b/modules/mol/mm/src/mm_observer.hh @@ -0,0 +1,109 @@ +#ifndef OST_MM_OBSERVER_HH +#define OST_MM_OBSERVER_HH + + +#include <OpenMM.h> + +#include <boost/shared_ptr.hpp> + +#include <ost/io/mol/io_profile.hh> +#include <ost/io/mol/pdb_writer.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/coord_frame.hh> +#include <ost/mol/coord_group.hh> +#include <ost/mol/mm/state_extractor.hh> +#include <ost/mol/mm/topology.hh> +#include <ost/mol/mm/mm_modeller.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class MMObserver; +class TrajObserver; +class TrajWriter; +typedef boost::shared_ptr<MMObserver> MMObserverPtr; +typedef boost::shared_ptr<TrajObserver> TrajObserverPtr; +typedef boost::shared_ptr<TrajWriter> TrajWriterPtr; + +class MMObserver{ +public: + + virtual void Notify() = 0; + + virtual void Init(boost::shared_ptr<OpenMM::Context> c, + TopologyPtr top) = 0; + + virtual int Rythm() = 0; + +}; + + +class TrajObserver : public MMObserver{ + +public: + + TrajObserver(int rythm): rythm_(rythm), registered_(false) { } + + void Init(boost::shared_ptr<OpenMM::Context> c, + TopologyPtr top); + + void Notify(); + + int Rythm() { return rythm_; } + + CoordGroupHandle GetTraj() { return c_group_; } + +private: + + ost::mol::CoordGroupHandle c_group_; + boost::shared_ptr<OpenMM::Context> context_; + int rythm_; + bool registered_; +}; + +class TrajWriter : public MMObserver{ + +//Note, that this code is highly redundant to the code in io/mol/dcd_io.hh!!! + +public: + + TrajWriter(int rythm, const String& pdb_filename, const String& dcd_filename): rythm_(rythm), + pdb_filename_(pdb_filename), + dcd_filename_(dcd_filename), + stream_(), + registered_(false), + frames_(0) { } + + void Init(boost::shared_ptr<OpenMM::Context> c, + TopologyPtr top); + + void Notify(); + + int Rythm() { return rythm_; } + + void Finalize(); + +private: + + TrajWriter(const TrajWriter& writer) { } //output filestream is unique! + + + boost::shared_ptr<OpenMM::Context> context_; + int rythm_; + String pdb_filename_; + String dcd_filename_; + std::ofstream stream_; + bool registered_; + uint32_t frames_; + std::vector<float> x; + std::vector<float> y; + std::vector<float> z; + OpenMM::Vec3 ucell_a; + OpenMM::Vec3 ucell_b; + OpenMM::Vec3 ucell_c; +}; + + +}}}//ns + +#endif diff --git a/modules/mol/mm/src/mm_settings.hh b/modules/mol/mm/src/mm_settings.hh new file mode 100644 index 0000000000000000000000000000000000000000..45fac0b7205cdf17f0895dff1e611f60deb90709 --- /dev/null +++ b/modules/mol/mm/src/mm_settings.hh @@ -0,0 +1,153 @@ +#ifndef OST_MM_SETTINGS_HH +#define OST_MM_SETTINGS_HH + +#include <OpenMM.h> +#include <vector> + +#include <boost/shared_ptr.hpp> +#include <limits> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/mm/forcefield.hh> + + +namespace ost { namespace mol{ namespace mm{ + +struct MMSettings; +class TerminiExceptions; +typedef boost::shared_ptr<MMSettings> MMSettingsPtr; +typedef boost::shared_ptr<TerminiExceptions> TerminiExceptionsPtr; + +enum Platform{ + Reference, + OpenCL, + CUDA, + CPU +}; + + +class TerminiExceptions{ + +public: + + TerminiExceptions(){ } + + void SetException(const ost::mol::ResidueHandle& res, const String& exception_name){ + exceptions_[res.GetQualifiedName()] = exception_name; + } + + bool HasException(const ost::mol::ResidueHandle& res) const{ + return exceptions_.find(res.GetQualifiedName()) != exceptions_.end(); + } + + String GetException(const ost::mol::ResidueHandle& res) const { + if(!this->HasException(res)){ + std::stringstream ss; + ss<<"Tried to get termini exceptions of res "<<res<<" without defined exception!"; + throw ost::Error(ss.str()); + } + std::map<String, String>::const_iterator i = exceptions_.find(res.GetQualifiedName()); + return i->second; + } +private: + std::map<String, String> exceptions_; + +}; + +struct MMSettings{ + + MMSettings(): add_bonds(true), + add_angles(true), + add_dihedrals(true), + add_impropers(true), + add_cmaps(true), + add_exclusions(true), + add_nonbonded(true), + add_gbsa(false), + constrain_hbonds(false), + constrain_hangles(false), + constrain_bonds(false), + rigid_water(false), + strict_interactions(true), + ideal_bond_length_constraints(true), + fix_heavy_atoms(false), + kill_electrostatics(false), + generate_disulfid_bonds(true), + nonbonded_method(OpenMM::NonbondedForce::NoCutoff), + nonbonded_cutoff(10.0), + remove_cmm_motion(true), + cmm_frequency(1), + periodic_box_extents(0,0,0), + init_temperature(0.0), + forcefield(), //note, that we don't create an empty forcefield at this point =>force the user + //to assign a forcefield + termini_exceptions(new TerminiExceptions), + platform(Reference), + add_thermostat(false), + thermostat_temperature(std::numeric_limits<Real>::quiet_NaN()), + thermostat_collision_frequency(std::numeric_limits<Real>::quiet_NaN()), + add_barostat(false), + barostat_temperature(std::numeric_limits<Real>::quiet_NaN()), + barostat_pressure(std::numeric_limits<Real>::quiet_NaN()), + barostat_frequency(25), + integrator(), + solvent_dielectric(78.3), //this is for GBSA + solute_dielectric(1.0), //this is for GBSA + reaction_field_dielectric(78.3), + use_dispersion_correction(true), + openmm_plugin_directory(OpenMM::Platform::getDefaultPluginsDirectory()), + custom_plugin_directory(OpenMM::Platform::getDefaultPluginsDirectory()) + + { } + + // + bool add_bonds; + bool add_angles; + bool add_dihedrals; + bool add_impropers; + bool add_cmaps; + bool add_exclusions; + bool add_nonbonded; + bool add_gbsa; + bool constrain_hbonds; + bool constrain_hangles; + bool constrain_bonds; + bool rigid_water; + bool strict_interactions; + bool ideal_bond_length_constraints; + bool fix_heavy_atoms; + //set all charges to zero + bool kill_electrostatics; + //automatically generate disulfid bonds + bool generate_disulfid_bonds; + //see export_openmm.cc for all possibilities + OpenMM::NonbondedForce::NonbondedMethod nonbonded_method; + Real nonbonded_cutoff; + bool remove_cmm_motion; + int cmm_frequency; + //currently only boxes defined by base vectors are supported + geom::Vec3 periodic_box_extents; + //at the beginning of the simulation, the initial velociities are + //randomly set according to a boltzmann distribution + Real init_temperature; + ForcefieldPtr forcefield; + TerminiExceptionsPtr termini_exceptions; + Platform platform; + bool add_thermostat; + Real thermostat_temperature; + Real thermostat_collision_frequency; + bool add_barostat; + Real barostat_temperature; + Real barostat_pressure; + int barostat_frequency; + boost::shared_ptr<OpenMM::Integrator> integrator; + Real solvent_dielectric; + Real solute_dielectric; + Real reaction_field_dielectric; + bool use_dispersion_correction; + String openmm_plugin_directory; + String custom_plugin_directory; +}; + +}}} //namespace + +#endif \ No newline at end of file diff --git a/modules/mol/mm/src/simulation.cc b/modules/mol/mm/src/simulation.cc new file mode 100644 index 0000000000000000000000000000000000000000..410c9bc41c268ee366ea91e938a61b6539fde092 --- /dev/null +++ b/modules/mol/mm/src/simulation.cc @@ -0,0 +1,591 @@ +#include <ost/mol/mm/simulation.hh> + +namespace ost{ namespace mol{ namespace mm{ + +Simulation::Simulation(const ost::mol::EntityHandle& handle, + const MMSettingsPtr settings): + settings_(settings){ + + //note, that ent_ will be "completed" inside this function! + //(hydrogens and shit) + + TopologyPtr top = TopologyCreator::Create(handle,settings); + this->Init(top); +} + +Simulation::Simulation(const TopologyPtr top, + const MMSettingsPtr settings): + settings_(settings){ + + this->Init(top); +} + +void Simulation::Init(const TopologyPtr top){ + + + top_ = top; + integrator_ = settings_->integrator; + if(!integrator_){ + throw ost::Error("Settings must have a valid integrator attached to set up a simulation!"); + } + system_ = SystemCreator::Create(top_,settings_,system_force_mapper_); + ost::mol::EntityHandle ent = top_->GetEntity(); + original_masses_ = top_->GetMasses(); + + //setting up the context, which combines the system with an integrator + //to proceed in time, but first we have to load the proper platform + + OpenMM::Platform::loadPluginsFromDirectory (settings_->openmm_plugin_directory); + OpenMM::Platform* platform; + + switch(settings_->platform){ + case Reference:{ + platform = &OpenMM::Platform::getPlatformByName("Reference"); + break; + } + case OpenCL:{ + platform = &OpenMM::Platform::getPlatformByName("OpenCL"); + break; + } + case CUDA:{ + platform = &OpenMM::Platform::getPlatformByName("CUDA"); + break; + } + case CPU:{ + platform = &OpenMM::Platform::getPlatformByName("CPU"); + break; + } + } + + context_ = ContextPtr(new OpenMM::Context(*system_,*integrator_,*platform)); + + ost::mol::AtomHandleList atom_list = ent.GetAtomList(); + std::vector<OpenMM::Vec3> positions; + geom::Vec3 ost_vec; + OpenMM::Vec3 open_mm_vec; + for(ost::mol::AtomHandleList::iterator i = atom_list.begin(); + i!=atom_list.end();++i){ + ost_vec = i->GetPos(); + open_mm_vec[0] = ost_vec[0]/10; + open_mm_vec[1] = ost_vec[1]/10; + open_mm_vec[2] = ost_vec[2]/10; + positions.push_back(open_mm_vec); + } + context_->setPositions(positions); + + //make sure the context satisfies the distance constraints + context_->applyConstraints(0.00001); + + if(settings_->init_temperature > 0.0){ + context_->setVelocitiesToTemperature(settings_->init_temperature); + } +} + +ost::mol::EntityHandle Simulation::GetEntityStandardNaming(){ + ost::mol::EntityHandle ent = top_->GetEntity(); + ent = ent.Copy(); + settings_->forcefield->AssignFFSpecificNames(ent,true); + MMModeller::AssignPDBNaming(ent); + return ent; +} + +geom::Vec3List Simulation::GetPositions(bool enforce_periodic_box, bool in_angstrom){ + geom::Vec3List return_vec; + StateExtractor::ExtractPositions(context_,return_vec, enforce_periodic_box, in_angstrom); + return return_vec; +} + +geom::Vec3List Simulation::GetVelocities(){ + geom::Vec3List return_vec; + StateExtractor::ExtractVelocities(context_, return_vec); + return return_vec; +} + +geom::Vec3List Simulation::GetForces(){ + geom::Vec3List return_vec; + StateExtractor::ExtractForces(context_, return_vec); + return return_vec; +} + +void Simulation::SetPositions(geom::Vec3List& positions, bool in_angstrom){ + if(top_->GetNumAtoms() != positions.size()){ + throw ost::Error("Number of positions does not correspond to number of atoms in topology!"); + } + if(in_angstrom) positions /= 10; + std::vector<OpenMM::Vec3> openmm_positions; + OpenMM::Vec3 open_mm_vec; + for(geom::Vec3List::iterator i = positions.begin(); + i != positions.end(); ++i){ + open_mm_vec[0] = (*i)[0]; + open_mm_vec[1] = (*i)[1]; + open_mm_vec[2] = (*i)[2]; + openmm_positions.push_back(open_mm_vec); + } + context_->setPositions(openmm_positions); +} + +void Simulation::SetVelocities(geom::Vec3List& velocities){ + if(top_->GetNumAtoms() != velocities.size()){ + throw ost::Error("Number of velocities does not correspond to number of atoms in topology!"); + } + std::vector<OpenMM::Vec3> openmm_velocities; + OpenMM::Vec3 open_mm_vec; + for(geom::Vec3List::iterator i = velocities.begin(); + i != velocities.end(); ++i){ + open_mm_vec[0] = (*i)[0]; + open_mm_vec[1] = (*i)[1]; + open_mm_vec[2] = (*i)[2]; + openmm_velocities.push_back(open_mm_vec); + } + context_->setVelocities(openmm_velocities); +} + +void Simulation::UpdateTopologyPositions(bool enforce_periodic_box){ + geom::Vec3List positions = this->GetPositions(enforce_periodic_box); + top_->SetEntityPositions(positions); +} + +void Simulation::MinimizeEnergy(const String& type, Real tolerance, int max_iterations){ + if(type == "lbfgs") OpenMM::LocalEnergyMinimizer::minimize(*context_, tolerance, max_iterations); + else if(type == "steep") Steep::Minimize(*context_,tolerance, max_iterations); + else{ + std::stringstream ss; + ss << "Unknown minimization function type \""<< type <<"\" observed"; + throw ost::Error(ss.str()); + } +} + +void Simulation::Steps(int steps){ + + int time_to_next_notification; + + while(steps > 0){ + time_to_next_notification = this->TimeToNextNotification(); + //we can just do the remaining steps and subtract them from + //time_to_notify_ + if(steps < time_to_next_notification){ + integrator_->step(steps); + for(std::vector<int>::iterator i = time_to_notify_.begin(); + i != time_to_notify_.end(); ++i){ + (*i) -= steps; + } + steps = 0; + }else{ + integrator_->step(time_to_next_notification); + for(std::vector<int>::iterator i = time_to_notify_.begin(); + i != time_to_notify_.end(); ++i){ + (*i) -= time_to_next_notification; + } + for(uint i = 0; i < time_to_notify_.size(); ++i){ + if(time_to_notify_[i] == 0){ + observers_[i]->Notify(); + time_to_notify_[i] = observers_[i]->Rythm(); + } + } + steps -= time_to_next_notification; + } + } +} + +Real Simulation::GetEnergy(){ + Real energy; + StateExtractor::ExtractEnergy(context_,energy); + return energy; +} + +Real Simulation::GetKineticEnergy(){ + Real energy; + StateExtractor::ExtractKineticEnergy(context_,energy); + return energy; +} + +Real Simulation::GetPotentialEnergy(){ + Real energy; + StateExtractor::ExtractPotentialEnergy(context_,energy); + return energy; +} + +void Simulation::Register(MMObserverPtr o){ + observers_.push_back(o); + time_to_notify_.push_back(o->Rythm()); + o->Init(context_,top_); +} + +int Simulation::TimeToNextNotification(){ + if(observers_.empty()){ + return std::numeric_limits<int>::max(); + } + int minimal_time = std::numeric_limits<int>::max(); + for(std::vector<int>::iterator i = time_to_notify_.begin(); + i != time_to_notify_.end(); ++i){ + if(*i < minimal_time){ + minimal_time = *i; + } + } + return minimal_time; +} + +void Simulation::ResetHarmonicBond(uint index, Real bond_length, Real force_constant){ + if(system_force_mapper_.find(HarmonicBond) == system_force_mapper_.end()){ + throw ost::Error("There is no harmonic bond force in the simulation!"); + } + uint force_index = system_force_mapper_[HarmonicBond]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::HarmonicBondForce* bond_force_ptr = reinterpret_cast<OpenMM::HarmonicBondForce*>(&force); + if(index >= uint(bond_force_ptr->getNumBonds())){ + throw ost::Error("Provided bond index exceeds number of bonds!"); + } + double dummy_one, dummy_two; + int particle1, particle2; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + bond_force_ptr->getBondParameters(index,particle1,particle2,dummy_one,dummy_two); + bond_force_ptr->setBondParameters(index,particle1,particle2,bond_length,force_constant); + bond_force_ptr->updateParametersInContext(*context_); + top_->SetHarmonicBondParameters(index,bond_length,force_constant); +} + +void Simulation::ResetHarmonicAngle(uint index, Real angle, Real force_constant){ + if(system_force_mapper_.find(HarmonicAngle) == system_force_mapper_.end()){ + throw ost::Error("There is no harmonic angle force in the simulation!"); + } + uint force_index = system_force_mapper_[HarmonicAngle]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::HarmonicAngleForce* angle_force_ptr = reinterpret_cast<OpenMM::HarmonicAngleForce*>(&force); + if(index >= uint(angle_force_ptr->getNumAngles())){ + throw ost::Error("Provided angle index exceeds number of angles!"); + } + double dummy_one, dummy_two; + int particle1, particle2, particle3; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + angle_force_ptr->getAngleParameters(index,particle1,particle2,particle3,dummy_one,dummy_two); + angle_force_ptr->setAngleParameters(index,particle1,particle2,particle3,angle,force_constant); + angle_force_ptr->updateParametersInContext(*context_); + top_->SetHarmonicAngleParameters(index, angle, force_constant); +} + +void Simulation::ResetUreyBradleyAngle(uint index, Real angle, Real angle_force_constant, Real bond_length, Real bond_force_constant){ + if(system_force_mapper_.find(UreyBradleyAngle) == system_force_mapper_.end()){ + throw ost::Error("There is no urey bradley angle force in the simulation!"); + } + uint force_index = system_force_mapper_[UreyBradleyAngle]; + OpenMM::Force& angle_force = system_->getForce(force_index); + OpenMM::Force& bond_force = system_->getForce(force_index+1); + + OpenMM::HarmonicAngleForce* angle_force_ptr = reinterpret_cast<OpenMM::HarmonicAngleForce*>(&angle_force); + OpenMM::HarmonicBondForce* bond_force_ptr = reinterpret_cast<OpenMM::HarmonicBondForce*>(&bond_force); + if(index >= uint(angle_force_ptr->getNumAngles())){ + throw ost::Error("Provided angle index exceeds number of angles!"); + } + double dummy_one, dummy_two; + int particle1, particle2, particle3; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + angle_force_ptr->getAngleParameters(index,particle1,particle2,particle3,dummy_one,dummy_two); + angle_force_ptr->setAngleParameters(index,particle1,particle2,particle3,angle,angle_force_constant); + bond_force_ptr->setBondParameters(index,particle1,particle3,bond_length,bond_force_constant); + angle_force_ptr->updateParametersInContext(*context_); + bond_force_ptr->updateParametersInContext(*context_); + top_->SetUreyBradleyAngleParameters(index,angle,angle_force_constant,bond_length,bond_force_constant); +} + +void Simulation::ResetPeriodicDihedral(uint index, int multiplicity, Real phase, Real force_constant){ + if(system_force_mapper_.find(PeriodicDihedral) == system_force_mapper_.end()){ + throw ost::Error("There is no periodic dihedral force in the simulation!"); + } + uint force_index = system_force_mapper_[PeriodicDihedral]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::PeriodicTorsionForce* dihedral_force_ptr = reinterpret_cast<OpenMM::PeriodicTorsionForce*>(&force); + if(index >= uint(dihedral_force_ptr->getNumTorsions())){ + throw ost::Error("Provided dihedral index exceeds number of dihedrals!"); + } + int dummy_one; + double dummy_two, dummy_three; + int particle1, particle2, particle3, particle4; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + dihedral_force_ptr->getTorsionParameters(index,particle1,particle2,particle3,particle4,dummy_one,dummy_two,dummy_three); + dihedral_force_ptr->setTorsionParameters(index,particle1,particle2,particle3,particle4,multiplicity,phase,force_constant); + dihedral_force_ptr->updateParametersInContext(*context_); + top_->SetPeriodicDihedralParameters(index, multiplicity, phase, force_constant); +} + +void Simulation::ResetPeriodicImproper(uint index, int multiplicity, Real phase, Real force_constant){ + if(system_force_mapper_.find(PeriodicImproper) == system_force_mapper_.end()){ + throw ost::Error("There is no periodic improper force in the simulation!"); + } + uint force_index = system_force_mapper_[PeriodicImproper]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::PeriodicTorsionForce* improper_ptr = reinterpret_cast<OpenMM::PeriodicTorsionForce*>(&force); + if(index >= uint(improper_ptr->getNumTorsions())){ + throw ost::Error("Provided improper index exceeds number of impropers!"); + } + int dummy_one; + double dummy_two, dummy_three; + int particle1, particle2, particle3, particle4; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + improper_ptr->getTorsionParameters(index,particle1,particle2,particle3,particle4,dummy_one,dummy_two,dummy_three); + improper_ptr->setTorsionParameters(index,particle1,particle2,particle3,particle4,multiplicity,phase,force_constant); + improper_ptr->updateParametersInContext(*context_); + top_->SetPeriodicImproperParameters(index, multiplicity, phase, force_constant); +} + +void Simulation::ResetHarmonicImproper(uint index, Real phase, Real force_constant){ + if(system_force_mapper_.find(HarmonicImproper) == system_force_mapper_.end()){ + throw ost::Error("There is no harmonic improper force in the simulation!"); + } + uint force_index = system_force_mapper_[HarmonicImproper]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::CustomTorsionForce* improper_ptr = reinterpret_cast<OpenMM::CustomTorsionForce*>(&force); + if(index >= uint(improper_ptr->getNumTorsions())){ + throw ost::Error("Provided improper index exceeds number of impropers!"); + } + std::vector<double> parameters; + parameters.push_back(0.0); + parameters.push_back(0.0); + int particle1, particle2, particle3, particle4; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + improper_ptr->getTorsionParameters(index,particle1,particle2,particle3,particle4,parameters); + parameters[0] = phase; + parameters[1] = force_constant; + improper_ptr->setTorsionParameters(index,particle1,particle2,particle3,particle4,parameters); + improper_ptr->updateParametersInContext(*context_); + top_->SetHarmonicImproperParameters(index, phase, force_constant); +} + +void Simulation::ResetLJPair(uint index, Real sigma, Real epsilon){ + if(system_force_mapper_.find(LJ) == system_force_mapper_.end()){ + throw ost::Error("There is no nonbonded force in the simulation!"); + } + uint force_index = system_force_mapper_[LJ]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::NonbondedForce* nonbonded_ptr = reinterpret_cast<OpenMM::NonbondedForce*>(&force); + if(index >= uint(nonbonded_ptr->getNumExceptions())){ + throw ost::Error("Provided index exceeds number of defined pairs!"); + } + double charge_prod, dummy_one, dummy_two; + int particle1, particle2; + //we know the parameters, but not the atom indices in the force object, we have to extract it from + //the force itself + nonbonded_ptr->getExceptionParameters(index,particle1,particle2,charge_prod,dummy_one,dummy_two); + nonbonded_ptr->setExceptionParameters(index,particle1,particle2,charge_prod,sigma,epsilon); + nonbonded_ptr->updateParametersInContext(*context_); + top_->SetLJPairParameters(index, sigma, epsilon); +} + +void Simulation::ResetDistanceConstraint(uint index, Real constraint_length){ + if(index >= uint(system_->getNumConstraints())){ + throw ost::Error("Provided index exceeds number of defined constraints!"); + } + double dummy; + int particle1, particle2; + system_->getConstraintParameters(index,particle1,particle2,dummy); + system_->setConstraintParameters(index,particle1,particle2,constraint_length); + context_->reinitialize(); + top_->SetDistanceConstraintParameters(index, constraint_length); +} + +void Simulation::AddPositionConstraint(uint index){ + if(index >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + system_->setParticleMass(index,0.0); + context_->reinitialize(); + top_->AddPositionConstraint(index); +} + +void Simulation::AddPositionConstraints(const std::vector<uint>& index){ + + for(std::vector<uint>::const_iterator i = index.begin(); + i != index.end(); ++i){ + if(*i >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + system_->setParticleMass(*i,0.0); + top_->AddPositionConstraint(*i); + } + context_->reinitialize(); +} + +void Simulation::ResetPositionConstraints(){ + for(uint i = 0; i < original_masses_.size(); ++i){ + system_->setParticleMass(i,original_masses_[i]); + } + top_->ResetPositionConstraints(); + context_->reinitialize(); +} + +void Simulation::ResetHarmonicPositionRestraint(uint index, const geom::Vec3& ref_position, Real k, + Real x_scale, Real y_scale, Real z_scale){ + if(index >= uint(top_->GetNumHarmonicPositionRestraints())){ + throw ost::Error("Provided index exceeds number of defined harmonic position restraints!"); + } + if(system_force_mapper_.find(HarmonicPositionRestraint) == system_force_mapper_.end()){ + throw ost::Error("There is no harmonic position restraint in the simulation!"); + } + uint force_index = system_force_mapper_[HarmonicPositionRestraint]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::CustomExternalForce* restraint_ptr = reinterpret_cast<OpenMM::CustomExternalForce*>(&force); + if(index >= uint(restraint_ptr->getNumParticles())){ + throw ost::Error("Provided index exceeds number of defined harmonic position restraints!"); + } + int particle; + std::vector<double> parameters; + restraint_ptr->getParticleParameters(index,particle,parameters); + parameters[0] = ref_position[0]; + parameters[1] = ref_position[1]; + parameters[2] = ref_position[2]; + parameters[3] = k; + parameters[4] = x_scale; + parameters[5] = y_scale; + parameters[6] = z_scale; + restraint_ptr->setParticleParameters(index,particle,parameters); + restraint_ptr->updateParametersInContext(*context_); + top_->SetHarmonicPositionRestraintParameters(index,ref_position,k,x_scale,y_scale,z_scale); +} + +void Simulation::ResetHarmonicDistanceRestraint(uint index, Real length, Real force_constant){ + if(index >= top_->GetNumHarmonicDistanceRestraints()){ + throw ost::Error("Provided index exceeds number of defined harmonic distance restraints!"); + } + if(system_force_mapper_.find(HarmonicDistanceRestraint) == system_force_mapper_.end()){ + throw ost::Error("There is no harmonic distance restraint in the simulation!"); + } + uint force_index = system_force_mapper_[HarmonicDistanceRestraint]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::HarmonicBondForce* restraint_ptr = reinterpret_cast<OpenMM::HarmonicBondForce*>(&force); + if(index >= uint(restraint_ptr->getNumBonds())){ + throw ost::Error("Provided index exceeds number of defined harmonic distance restraints!"); + } + int particle_one,particle_two; + double dummy_one, dummy_two; + restraint_ptr->getBondParameters(int(index),particle_one,particle_two,dummy_one,dummy_two); + restraint_ptr->setBondParameters(int(index),particle_one,particle_two,length,2*force_constant); + restraint_ptr->updateParametersInContext(*context_); + top_->SetHarmonicDistanceRestraintParameters(index,length,force_constant); +} + +void Simulation::ResetLJ(uint index, Real sigma, Real epsilon){ + if(index >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + if(system_force_mapper_.find(LJ) == system_force_mapper_.end()){ + throw ost::Error("There is no nonbonded force in the simulation!"); + } + uint force_index = system_force_mapper_[LJ]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::NonbondedForce* nonbonded_ptr = reinterpret_cast<OpenMM::NonbondedForce*>(&force); + + double charge, dummy_one, dummy_two; + + nonbonded_ptr->getParticleParameters(index,charge,dummy_one,dummy_two); + nonbonded_ptr->setParticleParameters(index,charge,sigma,epsilon); + nonbonded_ptr->updateParametersInContext(*context_); + top_->SetSigma(index, sigma); + top_->SetEpsilon(index, epsilon); +} + +void Simulation::ResetGBSA(uint index, Real radius, Real scaling){ + if(index >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + if(system_force_mapper_.find(GBSA) == system_force_mapper_.end()){ + throw ost::Error("There is no gbsa force in the simulation!"); + } + uint force_index = system_force_mapper_[GBSA]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::GBSAOBCForce* gbsa_ptr = reinterpret_cast<OpenMM::GBSAOBCForce*>(&force); + + double charge, dummy_one, dummy_two; + + gbsa_ptr->getParticleParameters(index,charge,dummy_one,dummy_two); + gbsa_ptr->setParticleParameters(index,charge,radius,scaling); + gbsa_ptr->updateParametersInContext(*context_); + top_->SetGBSARadius(index, radius); + top_->SetOBCScaling(index, scaling); +} + +void Simulation::ResetCharge(uint index, Real charge){ + if(index >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + if(system_force_mapper_.find(LJ) == system_force_mapper_.end()){ + throw ost::Error("There is no nonbonded force in the simulation!"); + } + uint force_index = system_force_mapper_[LJ]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::NonbondedForce* nonbonded_ptr = reinterpret_cast<OpenMM::NonbondedForce*>(&force); + + double dummy, sigma, epsilon; + + //first update the parameters of the single particle + nonbonded_ptr->getParticleParameters(index,dummy,sigma,epsilon); + nonbonded_ptr->setParticleParameters(index,charge,sigma,epsilon); + + //the charge product has to be updated in the exceptions (1,4 interactions) + std::vector<uint> lj_pair_indices = top_->GetLJPairIndices(index); + Real old_charge = top_->GetCharge(index); + double charge_prod; + Real new_charge_prod; + int particle_one, particle_two; + + for(std::vector<uint>::iterator i = lj_pair_indices.begin(); + i != lj_pair_indices.end(); ++i){ + nonbonded_ptr->getExceptionParameters(*i,particle_one,particle_two,charge_prod,sigma,epsilon); + new_charge_prod = charge_prod/old_charge*charge; // fudge_qq * q1 * q2 + nonbonded_ptr->setExceptionParameters(*i,particle_one,particle_two,new_charge_prod,sigma,epsilon); + } + + nonbonded_ptr->updateParametersInContext(*context_); + top_->SetCharge(index, charge); + + //the charge also affects gbsa force... + if(system_force_mapper_.find(GBSA) != system_force_mapper_.end()){ + force_index = system_force_mapper_[GBSA]; + OpenMM::Force& force = system_->getForce(force_index); + OpenMM::GBSAOBCForce* gbsa_ptr = reinterpret_cast<OpenMM::GBSAOBCForce*>(&force); + + double radius,scaling; + + gbsa_ptr->getParticleParameters(index,dummy,radius,scaling); + gbsa_ptr->setParticleParameters(index,charge,radius,scaling); + gbsa_ptr->updateParametersInContext(*context_); + } +} + +void Simulation::ResetMass(uint index, Real mass){ + if(index >= top_->GetNumAtoms()){ + throw ost::Error("Provided index exceeds number of atoms!"); + } + system_->setParticleMass(index,mass); + context_->reinitialize(); + top_->SetMass(index,mass); +} + +geom::Vec3 Simulation::GetPeriodicBoxExtents(){ + geom::Vec3 vec; + OpenMM::Vec3 ucell_a, ucell_b, ucell_c; + OpenMM::State openmm_state = context_->getState(0); //create minimal state + //to only extract periodic + //box information + openmm_state.getPeriodicBoxVectors(ucell_a,ucell_b,ucell_c); + vec[0] = 10 * sqrt(ucell_a.dot(ucell_a)); + vec[1] = 10 * sqrt(ucell_a.dot(ucell_b)); + vec[2] = 10 * sqrt(ucell_a.dot(ucell_c)); + return vec; +} + +void Simulation::SetPeriodicBoxExtents(geom::Vec3& vec){ + OpenMM::Vec3 ucell_a(vec[0]/10.0,0.0,0.0); + OpenMM::Vec3 ucell_b(0.0,vec[1]/10.0,0.0); + OpenMM::Vec3 ucell_c(0.0,0.0,vec[2]/10.0); + context_->setPeriodicBoxVectors(ucell_a,ucell_b,ucell_c); +} + + + +}}} + diff --git a/modules/mol/mm/src/simulation.hh b/modules/mol/mm/src/simulation.hh new file mode 100644 index 0000000000000000000000000000000000000000..5712b6d5cfab786e65265d9a5a6dfd6b861d1bf3 --- /dev/null +++ b/modules/mol/mm/src/simulation.hh @@ -0,0 +1,138 @@ +#ifndef OST_SIMULATION_HH +#define OST_SIMULATION_HH + +#include <OpenMM.h> + +#include <vector> +#include <map> + +#include <ost/mol/mol.hh> +#include <ost/mol/mm/system_creator.hh> +#include <ost/mol/mm/topology.hh> +#include <ost/mol/mm/topology_creator.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/mm_modeller.hh> +#include <ost/geom/vec3.hh> +#include <ost/mol/mm/mm_observer.hh> +#include <ost/mol/mm/state_extractor.hh> +#include <ost/mol/mm/steep.hh> +#include <ost/mol/mm/mm_interaction.hh> + + +#include <time.h> + +namespace ost { namespace mol{ namespace mm{ + +class Simulation; + +typedef boost::shared_ptr<OpenMM::Integrator> IntegratorPtr; +typedef boost::shared_ptr<OpenMM::VerletIntegrator> VerletIntegratorPtr; +typedef boost::shared_ptr<OpenMM::BrownianIntegrator> BrownianIntegratorPtr; +typedef boost::shared_ptr<OpenMM::LangevinIntegrator> LangevinIntegratorPtr; +typedef boost::shared_ptr<OpenMM::VariableVerletIntegrator> VariableVerletIntegratorPtr; +typedef boost::shared_ptr<OpenMM::VariableLangevinIntegrator> VariableLangevinIntegratorPtr; +typedef boost::shared_ptr<OpenMM::Context> ContextPtr; +typedef boost::shared_ptr<OpenMM::AndersenThermostat> AndersenThermostatPtr; +typedef boost::shared_ptr<OpenMM::MonteCarloBarostat> MonteCarloBarostatPtr; + +typedef boost::shared_ptr<Simulation> SimulationPtr; + +class Simulation { + +public: + + Simulation(const ost::mol::EntityHandle& handle, + const MMSettingsPtr settings); + + Simulation(const ost::mol::mm::TopologyPtr top, + const MMSettingsPtr settings); + + + ost::mol::EntityHandle GetEntity() { return top_->GetEntity(); } + + ost::mol::EntityHandle GetEntityStandardNaming(); + + geom::Vec3List GetPositions(bool enforce_periodic_box = false, bool in_angstrom = true); + + geom::Vec3List GetVelocities(); + + geom::Vec3List GetForces(); + + void SetPositions(geom::Vec3List& positions, bool in_angstrom = true); + + void SetVelocities(geom::Vec3List& velocities); + + void UpdateTopologyPositions(bool enforce_periodic_box = false); + + void MinimizeEnergy(const String& type = "steep", Real tolerance = 1.0, int max_iterations = 1000); + + Real GetEnergy(); + + Real GetPotentialEnergy(); + + Real GetKineticEnergy(); + + TopologyPtr GetTopology() { return top_; } + + void Steps(int steps); + + void Register(MMObserverPtr o); + + void ResetHarmonicBond(uint index, Real bond_length, Real force_constant); + + void ResetHarmonicAngle(uint index, Real angle, Real force_constant); + + void ResetUreyBradleyAngle(uint index, Real angle, Real angle_force_constant, Real bond_length, Real bond_force_constant); + + void ResetPeriodicDihedral(uint index, int multiplicity, Real phase, Real force_constant); + + void ResetPeriodicImproper(uint index, int multiplicity, Real phase, Real force_constant); + + void ResetHarmonicImproper(uint index, Real phase, Real force_constant); + + void ResetLJPair(uint index, Real sigma, Real epsilon); + + void ResetDistanceConstraint(uint index, Real constraint_length); + + void ResetHarmonicPositionRestraint(uint index, const geom::Vec3& ref_position, Real k, + Real x_scale = 1.0, Real y_scale = 1.0, Real z_scale = 1.0); + + void ResetHarmonicDistanceRestraint(uint index, Real length, Real force_constant); + + void ResetLJ(uint index, Real sigma, Real epsilon); + + void ResetGBSA(uint index, Real radius, Real scaling); + + void ResetCharge(uint index, Real charge); + + void ResetMass(uint index, Real mass); + + void AddPositionConstraint(uint index); + + void AddPositionConstraints(const std::vector<uint>& index); + + void ResetPositionConstraints(); + + geom::Vec3 GetPeriodicBoxExtents(); + + void SetPeriodicBoxExtents(geom::Vec3& vec); + +private: + void Init(const ost::mol::mm::TopologyPtr top); + + int TimeToNextNotification(); + + SystemPtr system_; + IntegratorPtr integrator_; + ContextPtr context_; + MMSettingsPtr settings_; + TopologyPtr top_; + std::vector<MMObserverPtr> observers_; + std::vector<int> time_to_notify_; + std::map<FuncType,unsigned int> system_force_mapper_; + std::vector<Real> original_masses_; +}; + +}}} //ns + +#endif diff --git a/modules/mol/mm/src/state_extractor.cc b/modules/mol/mm/src/state_extractor.cc new file mode 100644 index 0000000000000000000000000000000000000000..3bb36f7a7b3b143bba9f446c4e0f70c4acf837ae --- /dev/null +++ b/modules/mol/mm/src/state_extractor.cc @@ -0,0 +1,62 @@ +#include <ost/mol/mm/state_extractor.hh> + + +namespace ost { namespace mol{ namespace mm{ + +void StateExtractor::ExtractPotentialEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy){ + + OpenMM::State s = context->getState(OpenMM::State::Energy); + energy = s.getPotentialEnergy(); +} + +void StateExtractor::ExtractKineticEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy){ + + OpenMM::State s = context->getState(OpenMM::State::Energy); + energy = s.getKineticEnergy(); +} + +void StateExtractor::ExtractEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy){ + + OpenMM::State s = context->getState(OpenMM::State::Energy); + energy = s.getKineticEnergy() + s.getPotentialEnergy(); +} + +void StateExtractor::ExtractPositions(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& positions, bool enforce_periodic_box, bool in_angstrom){ + + positions.clear(); + OpenMM::State s = context->getState(OpenMM::State::Positions, enforce_periodic_box); + std::vector<OpenMM::Vec3> p = s.getPositions(); + for(std::vector<OpenMM::Vec3>::iterator i = p.begin(); i != p.end(); ++i){ + positions.push_back(geom::Vec3((*i)[0],(*i)[1],(*i)[2])); + } + if(in_angstrom) positions*=10.0; +} + +void StateExtractor::ExtractVelocities(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& velocities){ + + velocities.clear(); + OpenMM::State s = context->getState(OpenMM::State::Velocities); + std::vector<OpenMM::Vec3> v = s.getVelocities(); + for(std::vector<OpenMM::Vec3>::iterator i = v.begin(); i != v.end(); ++i){ + velocities.push_back(geom::Vec3((*i)[0],(*i)[1],(*i)[2])); + } +} + +void StateExtractor::ExtractForces(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& forces){ + + forces.clear(); + OpenMM::State s = context->getState(OpenMM::State::Forces); + std::vector<OpenMM::Vec3> f = s.getForces(); + for(std::vector<OpenMM::Vec3>::iterator i = f.begin(); i != f.end(); ++i){ + forces.push_back(geom::Vec3((*i)[0],(*i)[1],(*i)[2])); + } +} + + +}}} //ns diff --git a/modules/mol/mm/src/state_extractor.hh b/modules/mol/mm/src/state_extractor.hh new file mode 100644 index 0000000000000000000000000000000000000000..6b77c554ef53d9b3228e2beb421e044e7e09b288 --- /dev/null +++ b/modules/mol/mm/src/state_extractor.hh @@ -0,0 +1,43 @@ +#ifndef OST_STATE_EXTRACTOR_HH +#define OST_STATE_EXTRACTOR_HH + +#include <vector> + +#include <boost/shared_ptr.hpp> +#include <OpenMM.h> +#include <ost/geom/vec3.hh> + + + +namespace ost { namespace mol{ namespace mm{ + +class StateExtractor{ + +public: + + static void ExtractPotentialEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy); + + static void ExtractKineticEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy); + + static void ExtractEnergy(boost::shared_ptr<OpenMM::Context> context, + Real& energy); + + static void ExtractPositions(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& positions, + bool enforce_periodic_box = false, + bool in_angstrom = true); + + static void ExtractVelocities(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& velocities); + + static void ExtractForces(boost::shared_ptr<OpenMM::Context> context, + geom::Vec3List& forces); + +}; + + +}}} //ns + +#endif diff --git a/modules/mol/mm/src/steep.cc b/modules/mol/mm/src/steep.cc new file mode 100644 index 0000000000000000000000000000000000000000..d201c010ad519dc1e1c7234461c043540d4c530e --- /dev/null +++ b/modules/mol/mm/src/steep.cc @@ -0,0 +1,65 @@ +#include <ost/mol/mm/steep.hh> + +namespace ost{ namespace mol{ namespace mm{ + +void Steep::Minimize(OpenMM::Context& context, double tolerance, uint max_iterations) { + const OpenMM::System& system = context.getSystem(); + if(system.getNumConstraints() > 0){ + throw ost::Error("Cannot handle constraints in steepest descent, use lbgfs instead!"); + } + if( tolerance < 0.0 ){ + throw ost::Error("tolerance value must be greater 0.0!"); //also important to avoid zero division error when calculating normalization factor for forces + } + OpenMM::State state = context.getState(OpenMM::State::Energy | OpenMM::State::Forces | OpenMM::State::Positions); + std::vector<OpenMM::Vec3> positions = state.getPositions(); + std::vector<OpenMM::Vec3> new_positions = positions; + std::vector<OpenMM::Vec3> normalized_forces = state.getForces(); + double energy = state.getPotentialEnergy(); + double h = 0.01; + double new_energy,max_length,factor; + bool normalize_forces = true; + std::vector<uint> non_zero_mass_particles; + for(int i = 0; i < system.getNumParticles(); ++i){ + if(system.getParticleMass(i) != 0){ + non_zero_mass_particles.push_back(i); + } + } + for(uint i = 0; i < max_iterations; ++i){ + if(normalize_forces){ + const std::vector<OpenMM::Vec3>& forces = state.getForces(); + max_length = 0.0; + for(std::vector<uint>::iterator j = non_zero_mass_particles.begin(); + j != non_zero_mass_particles.end(); ++j){ + normalized_forces[*j] = forces[*j]; + max_length = std::max(max_length,forces[*j].dot(forces[*j])); + } + max_length = sqrt(max_length); + if(max_length <= tolerance) break; + factor = 1.0/max_length; + for(std::vector<uint>::iterator j = non_zero_mass_particles.begin(); + j != non_zero_mass_particles.end(); ++j){ + normalized_forces[*j] *= factor; + } + } + for(std::vector<uint>::iterator j = non_zero_mass_particles.begin(); + j != non_zero_mass_particles.end(); ++j){ + new_positions[*j] = positions[*j] + normalized_forces[*j] * h; + } + context.setPositions(new_positions); + //context.computeVirtualSites(); + state = context.getState(OpenMM::State::Forces | OpenMM::State::Energy); + new_energy = state.getPotentialEnergy(); + if(new_energy < energy){ + std::swap(positions,new_positions); + energy = new_energy; + h *= 1.2; + normalize_forces = true; + } + else { + h *= 0.5; + normalize_forces = false; + } + } + context.setPositions(positions); +} +}}}//ns diff --git a/modules/mol/mm/src/steep.hh b/modules/mol/mm/src/steep.hh new file mode 100644 index 0000000000000000000000000000000000000000..cc6ca3af627ed61269cdc2aa4cb552a098315e2a --- /dev/null +++ b/modules/mol/mm/src/steep.hh @@ -0,0 +1,26 @@ +#ifndef OST_STEEP_H_ +#define OST_STEEP_H_ + +#include <OpenMM.h> +#include <ost/base.hh> +#include <cmath> +#include <sstream> +#include <vector> +#include <iostream> +#include <cstdio> +#include <ctime> + +#include <ost/message.hh> + + +namespace ost { namespace mol { namespace mm{ + + +class Steep { +public: + static void Minimize(OpenMM::Context& context, double tolerance = 100, uint maxIterations = 1000); +}; + +}}} + +#endif diff --git a/modules/mol/mm/src/system_creator.cc b/modules/mol/mm/src/system_creator.cc new file mode 100644 index 0000000000000000000000000000000000000000..84b592a39d4b17cf1f1c3d4fe284ae840a60be5d --- /dev/null +++ b/modules/mol/mm/src/system_creator.cc @@ -0,0 +1,341 @@ +#include <ost/mol/mm/system_creator.hh> + +namespace ost{ namespace mol{ namespace mm{ + +SystemPtr SystemCreator::Create(const TopologyPtr top, + const MMSettingsPtr settings, + std::map<FuncType,uint>& mapper){ + + uint mapper_index = 0; + + SystemPtr sys(new OpenMM::System); + + //add particles to the system + std::vector<Real> masses = top->GetMasses(); + + //set masses of position constraints to zero + const std::vector<uint>& position_constraints = top->GetPositionConstraints(); + if(!position_constraints.empty()){ + for(std::vector<uint>::const_iterator i = position_constraints.begin(); + i != position_constraints.end(); ++i){ + masses[*i] = 0.0; + } + } + + for(std::vector<Real>::iterator i = masses.begin(); i != masses.end(); ++i){ + sys->addParticle(*i); + } + + //parameters of all added interactions will temporarily be stored in here + std::vector<Real> parameters; + + const std::vector<std::pair<Index<2>,std::vector<Real> > >& harmonic_bonds = top->GetHarmonicBonds(); + if(!harmonic_bonds.empty()){ + OpenMM::HarmonicBondForce& harmonic_bond_force = *new OpenMM::HarmonicBondForce(); + sys->addForce(&harmonic_bond_force); + mapper[HarmonicBond] = mapper_index++; + for(std::vector<std::pair<Index<2>,std::vector<Real> > >::const_iterator i = harmonic_bonds.begin(); + i != harmonic_bonds.end(); ++i){ + harmonic_bond_force.addBond(i->first[0],i->first[1],i->second[0],i->second[1]); + } + } + + const std::vector<std::pair<Index<3>, std::vector<Real> > >& harmonic_angles = top->GetHarmonicAngles(); + if(!harmonic_angles.empty()){ + OpenMM::HarmonicAngleForce& harmonic_angle_force = *new OpenMM::HarmonicAngleForce(); + sys->addForce(&harmonic_angle_force); + mapper[HarmonicAngle] = mapper_index++; + for(std::vector<std::pair<Index<3>,std::vector<Real> > >::const_iterator i = harmonic_angles.begin(); + i != harmonic_angles.end(); ++i){ + harmonic_angle_force.addAngle(i->first[0],i->first[1],i->first[2], + i->second[0],i->second[1]); + } + } + + const std::vector<std::pair<Index<3>,std::vector<Real> > >& urey_bradley_angles = top->GetUreyBradleyAngles(); + if(!urey_bradley_angles.empty()){ + //urey bradley is a mixture between a harmonic angle and harmonic bond term, + //that gets split up + OpenMM::HarmonicAngleForce& urey_angle_force = *new OpenMM::HarmonicAngleForce(); + OpenMM::HarmonicBondForce& urey_bond_force = *new OpenMM::HarmonicBondForce(); + sys->addForce(&urey_angle_force); + sys->addForce(&urey_bond_force); + mapper[UreyBradleyAngle] = mapper_index++; + ++mapper_index; + for(std::vector<std::pair<Index<3>,std::vector<Real> > >::const_iterator i = urey_bradley_angles.begin(); + i != urey_bradley_angles.end(); ++i){ + urey_angle_force.addAngle(i->first[0],i->first[1],i->first[2], + i->second[0],i->second[1]); + urey_bond_force.addBond(i->first[0],i->first[2],i->second[2],i->second[3]); + } + } + + const std::vector<std::pair<Index<4>,std::vector<Real> > >& periodic_dihedrals = top->GetPeriodicDihedrals(); + if(!periodic_dihedrals.empty()){ + OpenMM::PeriodicTorsionForce& periodic_torsion_force = *new OpenMM::PeriodicTorsionForce(); + sys->addForce(&periodic_torsion_force); + mapper[PeriodicDihedral] = mapper_index++; + for(std::vector<std::pair<Index<4>,std::vector<Real> > >::const_iterator i = periodic_dihedrals.begin(); + i != periodic_dihedrals.end(); ++i){ + periodic_torsion_force.addTorsion(i->first[0],i->first[1],i->first[2],i->first[3], + i->second[0],i->second[1],i->second[2]); + } + } + + const std::vector<std::pair<Index<4>,std::vector<Real> > >& periodic_impropers = top->GetPeriodicImpropers(); + if(!periodic_impropers.empty()){ + OpenMM::PeriodicTorsionForce& periodic_improper_force = *new OpenMM::PeriodicTorsionForce(); + sys->addForce(&periodic_improper_force); + mapper[PeriodicImproper] = mapper_index++; + for(std::vector<std::pair<Index<4>,std::vector<Real> > >::const_iterator i = periodic_impropers.begin(); + i != periodic_impropers.end(); ++i){ + periodic_improper_force.addTorsion(i->first[0],i->first[1],i->first[2],i->first[3], + i->second[0],i->second[1],i->second[2]); + } + } + + const std::vector<std::pair<Index<4>,std::vector<Real> > >& harmonic_impropers = top->GetHarmonicImpropers(); + if(!harmonic_impropers.empty()){ + std::vector<double> custom_parameters; + custom_parameters.push_back(0.0); + custom_parameters.push_back(0.0); + OpenMM::CustomTorsionForce& harmonic_improper_force = *new OpenMM::CustomTorsionForce("0.5*k*(theta-b)^2"); + harmonic_improper_force.addPerTorsionParameter("b"); + harmonic_improper_force.addPerTorsionParameter("k"); + sys->addForce(&harmonic_improper_force); + mapper[HarmonicImproper] = mapper_index++; + for(std::vector<std::pair<Index<4>,std::vector<Real> > >::const_iterator i = harmonic_impropers.begin(); + i != harmonic_impropers.end(); ++i){ + custom_parameters[0] = i->second[0]; + custom_parameters[1] = i->second[1]; + harmonic_improper_force.addTorsion(i->first[0],i->first[1],i->first[2],i->first[3], + custom_parameters); + } + } + + const std::vector<std::pair<Index<5>,std::vector<Real> > >& cmaps = top->GetCMaps(); + if(!cmaps.empty()){ + std::vector<std::vector<Real> > unique_cmap_parameters; + std::vector<Real> current_parameters; + std::vector<int> map_indices; + bool cmap_present; + + for(std::vector<std::pair<Index<5>,std::vector<Real> > >::const_iterator i = cmaps.begin(); + i != cmaps.end(); ++i){ + cmap_present = false; + current_parameters = i->second; + for(uint j = 0; j < unique_cmap_parameters.size(); ++j){ + if(current_parameters == unique_cmap_parameters[j]){ + cmap_present = true; + map_indices.push_back(j); + break; + } + } + if(!cmap_present){ + unique_cmap_parameters.push_back(current_parameters); + map_indices.push_back(unique_cmap_parameters.size()-1); + } + } + + OpenMM::CMAPTorsionForce& cmap_force = *new OpenMM::CMAPTorsionForce(); + sys->addForce(&cmap_force); + mapper[CMap] = mapper_index++; + + for(std::vector<std::vector<Real> >::iterator u_cmap = unique_cmap_parameters.begin(); + u_cmap != unique_cmap_parameters.end(); ++u_cmap){ + uint size = sqrt(u_cmap->size()); + if(size * size != u_cmap->size()){ + throw ost::Error("Expect cmap to be quadratic!"); + } + + //in charmm/gromacs the cmap has the following order regarding angle bins: + //(phi1,psi1),(phi1,psi2)... + //openmm requires following order: + //(phi1,psi1),(phi2,psi1)... + + //in charmm/gromacs the range of the angles in the map is [-180,180],[-pi,pi] + //respectively + //openmm requires the range to be [0,2pi], the map has to be shifted... + + //=>we need basically two "transformation" + + std::vector<double> transformed_map; + for(uint i = 0; i < size; ++i){ + for(uint j = 0; j < size; ++j){ + transformed_map.push_back((*u_cmap)[size*((j+size/2)%size) + ((i+size/2)%size)]); + } + } + cmap_force.addMap(size, transformed_map); + } + + //add the cmaps + int atom1,atom2,atom3,atom4,atom5; + for(uint i = 0; i < cmaps.size(); ++i){ + atom1 = cmaps[i].first[0]; + atom2 = cmaps[i].first[1]; + atom3 = cmaps[i].first[2]; + atom4 = cmaps[i].first[3]; + atom5 = cmaps[i].first[4]; + cmap_force.addTorsion(map_indices[i],atom1,atom2,atom3,atom4,atom2,atom3,atom4,atom5); + } + } + + const std::vector<std::pair<Index<1>,std::vector<Real> > >& harmonic_position_restraints = top->GetHarmonicPositionRestraints(); + if(!harmonic_position_restraints.empty()){ + OpenMM::CustomExternalForce& position_restraint_force = *new OpenMM::CustomExternalForce("k_force*(x_scale*(x-x0)^2+y_scale*(y-y0)^2+z_scale*(z-z0)^2)"); + position_restraint_force.addPerParticleParameter("x0"); + position_restraint_force.addPerParticleParameter("y0"); + position_restraint_force.addPerParticleParameter("z0"); + position_restraint_force.addPerParticleParameter("k_force"); + position_restraint_force.addPerParticleParameter("x_scale"); + position_restraint_force.addPerParticleParameter("y_scale"); + position_restraint_force.addPerParticleParameter("z_scale"); + sys->addForce(&position_restraint_force); + mapper[HarmonicPositionRestraint] = mapper_index++; + for(std::vector<std::pair<Index<1>,std::vector<Real> > >::const_iterator i = harmonic_position_restraints.begin(); + i != harmonic_position_restraints.end(); ++i){ + //stupid cast + std::vector<double> parameters; + for(std::vector<Real>::const_iterator j = i->second.begin(); + j != i->second.end(); ++j){ + parameters.push_back(*j); + } + position_restraint_force.addParticle(i->first[0], parameters); + } + } + + const std::vector<std::pair<Index<2>,std::vector<Real> > > harmonic_distance_restraints = top->GetHarmonicDistanceRestraints(); + if(!harmonic_distance_restraints.empty()){ + OpenMM::HarmonicBondForce& harmonic_distance_restraint_force = *new OpenMM::HarmonicBondForce(); + sys->addForce(&harmonic_distance_restraint_force); + mapper[HarmonicDistanceRestraint] = mapper_index++; + for(std::vector<std::pair<Index<2>,std::vector<Real> > >::const_iterator i = harmonic_distance_restraints.begin(); + i != harmonic_distance_restraints.end(); ++i){ + //note, that the restraint formula is k(b-b0)^2 instead of 1/2*k(b-b0)^2 => multiply by two! + harmonic_distance_restraint_force.addBond(i->first[0],i->first[1],i->second[0],2*i->second[1]); + } + } + + std::vector<Real> sigmas = top->GetSigmas(); + std::vector<Real> epsilons = top->GetEpsilons(); + std::vector<Real> charges = top->GetCharges(); + if(!sigmas.empty() && !epsilons.empty() && !charges.empty()){ + OpenMM::NonbondedForce& nonbonded_force = *new OpenMM::NonbondedForce(); + nonbonded_force.setNonbondedMethod(settings->nonbonded_method); + //we can set the cutoff in any case, since it will have no effect when + //nonbonded method is NoCutoff + nonbonded_force.setCutoffDistance(settings->nonbonded_cutoff/10.0); + nonbonded_force.setReactionFieldDielectric(settings->reaction_field_dielectric); + nonbonded_force.setUseDispersionCorrection(settings->use_dispersion_correction); + sys->addForce(&nonbonded_force); + mapper[LJ] = mapper_index++; + + //we first add all single particles to the force + for(uint i = 0; i < charges.size(); ++i){ + nonbonded_force.addParticle(charges[i], sigmas[i], epsilons[i]); + } + //take care of the 1-4 interactions + const std::vector<std::pair<Index<2>,std::vector<Real> > >& lj_pairs = top->GetLJPairs(); + if(!lj_pairs.empty()){ + Real fudge_lj = top->GetFudgeLJ(); + Real fudge_qq = top->GetFudgeQQ(); + Real charge; + for(std::vector<std::pair<Index<2>,std::vector<Real> > >::const_iterator i = lj_pairs.begin(); + i != lj_pairs.end(); ++i){ + charge = fudge_qq * charges[i->first[0]] * charges[i->first[1]]; + nonbonded_force.addException(i->first[0],i->first[1],charge, + i->second[0],fudge_lj*i->second[1]); + } + } + //take care of the exclusions + const std::vector<Index<2> >& exclusions = top->GetExclusions(); + if(!exclusions.empty()){ + for(std::vector<Index<2> >::const_iterator i = exclusions.begin(); i != exclusions.end(); ++i){ + nonbonded_force.addException((*i)[0],(*i)[1],0.0,1.0,0.0); + } + } + } + std::vector<Real> gbsa_radii = top->GetGBSARadii(); + std::vector<Real> gbsa_scaling = top->GetOBCScalings(); + if(!gbsa_radii.empty() && !gbsa_scaling.empty()){ + std::vector<Real> charges = top->GetCharges(); + if(charges.empty()) + throw ost::Error("GBSA force requires atom charges to be set!"); + OpenMM::GBSAOBCForce& gbsa_force = *new OpenMM::GBSAOBCForce(); + sys->addForce(&gbsa_force); + if(settings->nonbonded_method == OpenMM::NonbondedForce::NoCutoff){ + gbsa_force.setNonbondedMethod(OpenMM::GBSAOBCForce::NoCutoff); + } + else if(settings->nonbonded_method == OpenMM::NonbondedForce::CutoffNonPeriodic){ + gbsa_force.setNonbondedMethod(OpenMM::GBSAOBCForce::CutoffNonPeriodic); + } + else if(settings->nonbonded_method == OpenMM::NonbondedForce::CutoffPeriodic){ + gbsa_force.setNonbondedMethod(OpenMM::GBSAOBCForce::CutoffPeriodic); + } + else{ + throw ost::Error("Can only use Nonbonded methods NoCutoff, CutoffNonPeriodic,CutoffPeriodic when using GBSA"); + } + mapper[GBSA] = mapper_index++; + gbsa_force.setCutoffDistance(settings->nonbonded_cutoff/10); + gbsa_force.setSolventDielectric(settings->solvent_dielectric); + gbsa_force.setSoluteDielectric(settings->solute_dielectric); + //it should be guaranteed from the topology object, that the vectors have the same size + for(uint i = 0; i < gbsa_radii.size(); ++i){ + gbsa_force.addParticle(charges[i], + gbsa_radii[i], + gbsa_scaling[i]); + } + } + //set constraints + std::vector<std::pair<Index<2>,std::vector<Real> > > distance_constraints = top->GetDistanceConstraints(); + if(!distance_constraints.empty()){ + for(std::vector<std::pair<Index<2>,std::vector<Real> > >::iterator i = distance_constraints.begin(); + i != distance_constraints.end(); ++i){ + sys->addConstraint(i->first[0],i->first[1],i->second[0]); + } + } + //set periodic box extents + if(geom::Length(settings->periodic_box_extents) > 0){ + OpenMM::Vec3 x_vec(settings->periodic_box_extents[0]/10,0.0,0.0); + OpenMM::Vec3 y_vec(0.0,settings->periodic_box_extents[1]/10,0.0); + OpenMM::Vec3 z_vec(0.0,0.0,settings->periodic_box_extents[2]/10); + sys->setDefaultPeriodicBoxVectors(x_vec,y_vec,z_vec); + } + else if(settings->add_nonbonded && + !(settings->nonbonded_method == OpenMM::NonbondedForce::NoCutoff || + settings->nonbonded_method == OpenMM::NonbondedForce::CutoffNonPeriodic)){ + throw ost::Error("Chosen nonbonded method requires to define the periodic box extents!"); + } + //set the CMMMotion removing force if required + if(settings->remove_cmm_motion){ + if(settings->cmm_frequency != settings->cmm_frequency){ + throw ost::Error("Cannot set CMM Remover without valid cmm_frequency set!"); + } + sys->addForce(new OpenMM::CMMotionRemover(settings->cmm_frequency)); + } + if(settings->add_thermostat){ + if(settings->thermostat_temperature != settings->thermostat_temperature || + settings->thermostat_collision_frequency != settings->thermostat_collision_frequency){ + throw ost::Error("Cannot set thermostat without defined temperature and collision frequency!"); + } + OpenMM::AndersenThermostat& thermostat = *new OpenMM::AndersenThermostat(settings->thermostat_temperature, + settings->thermostat_collision_frequency); + sys->addForce(&thermostat); + } + if(settings->add_barostat){ + if(geom::Length(settings->periodic_box_extents) == 0){ + throw ost::Error("If you set a barostat, you also have to set nonzero periodic box extents!"); + } + if(settings->barostat_temperature != settings->barostat_temperature || + settings->barostat_pressure != settings->barostat_pressure || + settings->barostat_frequency != settings->barostat_frequency){ + throw ost::Error("Cannot set barostat without defined temperature, pressure, and frequency parameters!"); + } + OpenMM::MonteCarloBarostat& barostat = *new OpenMM::MonteCarloBarostat(settings->barostat_pressure, + settings->barostat_temperature, + settings->barostat_frequency); + sys->addForce(&barostat); + } + return sys; +} +}}} //ns diff --git a/modules/mol/mm/src/system_creator.hh b/modules/mol/mm/src/system_creator.hh new file mode 100644 index 0000000000000000000000000000000000000000..d7fce8408530c205a11f7671fb395fd9fb5f1722 --- /dev/null +++ b/modules/mol/mm/src/system_creator.hh @@ -0,0 +1,42 @@ +#ifndef OST_SYSTEM_CREATOR_HH +#define OST_SYSTEM_CREATOR_HH + +#include <OpenMM.h> + +#include <vector> +#include <map> +#include <set> + +#include <ost/message.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/mm_modeller.hh> +#include <ost/mol/mm/index.hh> +#include <ost/mol/mm/topology.hh> + + +#include <time.h> + + +namespace ost { namespace mol{ namespace mm{ + +typedef boost::shared_ptr<OpenMM::System> SystemPtr; + +class SystemCreator { +public: + static SystemPtr Create(const TopologyPtr top, + const MMSettingsPtr settings, + std::map<FuncType,uint>& mapper); + +}; + + +}}}//ns + +#endif \ No newline at end of file diff --git a/modules/mol/mm/src/topology.cc b/modules/mol/mm/src/topology.cc new file mode 100644 index 0000000000000000000000000000000000000000..e31859803ef132227832f869c1d3c79083dd67f4 --- /dev/null +++ b/modules/mol/mm/src/topology.cc @@ -0,0 +1,1336 @@ +#include <ost/mol/mm/topology.hh> +#include <ost/mol/mm/mm_modeller.hh> + + +namespace ost{ namespace mol{ namespace mm{ + + + +Topology::Topology(const ost::mol::EntityHandle& ent, const std::vector<Real>& masses){ + + num_atoms_ = ent.GetAtomCount(); + if(num_atoms_ != masses.size()){ + throw ost::Error("Number of atoms in entity and number of masses do not match when creating topology!"); + } + ent_ = ent.Copy(); + num_residues_ = ent_.GetResidueCount(); + atom_list_ = ent_.GetAtomList(); + res_list_ = ent_.GetResidueList(); + atom_masses_ = masses; + fudge_lj_ = 1.0; + fudge_qq_ = 1.0; + + for(uint i = 0; i < atom_list_.size(); ++i){ + atom_index_mapper_[atom_list_[i].GetHashCode()] = i; + } + + for(uint i = 0; i < res_list_.size(); ++i){ + residue_index_mapper_[res_list_[i].GetHashCode()] = i; + } + + std::map<String,uint> per_residue_mapper; + ost::mol::AtomHandleList residue_atom_list; + for(uint i = 0; i < num_residues_; ++i){ + per_residue_mapper.clear(); + residue_atom_list = res_list_[i].GetAtomList(); + for(ost::mol::AtomHandleList::iterator j = residue_atom_list.begin(); + j != residue_atom_list.end(); ++j){ + per_residue_mapper[j->GetName()] = atom_index_mapper_[j->GetHashCode()]; + } + atom_name_mapper_.push_back(per_residue_mapper); + } +} + +uint Topology::AddHarmonicBond(uint index_one, + uint index_two, + Real bond_length, + Real force_constant){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_){ + throw ost::Error("Index of bond atom exceeds number of atoms present in topology!"); + } + Index<2> index(index_one,index_two); + std::vector<Real> parameters; + parameters.push_back(bond_length); + parameters.push_back(force_constant); + harmonic_bonds_.push_back(std::make_pair(index,parameters)); + return harmonic_bonds_.size()-1; +} + +uint Topology::AddHarmonicAngle(uint index_one, + uint index_two, + uint index_three, + Real angle, + Real force_constant){ + + if(uint(index_one) >= num_atoms_ || uint(index_two) >= num_atoms_ || + uint(index_three) >= num_atoms_){ + throw ost::Error("Index of angle atom exceeds number of atoms present in topology!"); + } + Index<3> index(index_one,index_two,index_three); + std::vector<Real> parameters; + parameters.push_back(angle); + parameters.push_back(force_constant); + harmonic_angles_.push_back(std::make_pair(index,parameters)); + return harmonic_angles_.size()-1; +} + +uint Topology::AddUreyBradleyAngle(uint index_one, + uint index_two, + uint index_three, + Real angle, + Real angle_force_constant, + Real bond_length, + Real bond_force_constant){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_ || + index_three >= num_atoms_){ + throw ost::Error("Index of angle atom exceeds number of atoms present in topology!"); + } + Index<3> index(index_one,index_two,index_three); + std::vector<Real> parameters; + parameters.push_back(angle); + parameters.push_back(angle_force_constant); + parameters.push_back(bond_length); + parameters.push_back(bond_force_constant); + urey_bradley_angles_.push_back(std::make_pair(index,parameters)); + return urey_bradley_angles_.size()-1; +} + +uint Topology::AddPeriodicDihedral(uint index_one, + uint index_two, + uint index_three, + uint index_four, + int multiplicity, + Real phase, + Real force_constant){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_|| + index_three >= num_atoms_ || index_four >= num_atoms_){ + throw ost::Error("Index of dihedral atom exceeds number of atoms present in topology!"); + } + Index<4> index(index_one,index_two,index_three,index_four); + std::vector<Real> parameters; + parameters.push_back(multiplicity); + parameters.push_back(phase); + parameters.push_back(force_constant); + periodic_dihedrals_.push_back(std::make_pair(index,parameters)); + return periodic_dihedrals_.size()-1; +} + +uint Topology::AddPeriodicImproper(uint index_one, + uint index_two, + uint index_three, + uint index_four, + int multiplicity, + Real phase, + Real force_constant){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_|| + index_three >= num_atoms_ || index_four >= num_atoms_){ + throw ost::Error("Index of improper atom exceeds number of atoms present in topology!"); + } + Index<4> index(index_one,index_two,index_three,index_four); + std::vector<Real> parameters; + parameters.push_back(multiplicity); + parameters.push_back(phase); + parameters.push_back(force_constant); + periodic_impropers_.push_back(std::make_pair(index,parameters)); + return periodic_impropers_.size()-1; +} + +uint Topology::AddHarmonicImproper(uint index_one, + uint index_two, + uint index_three, + uint index_four, + Real angle, + Real force_constant){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_|| + index_three >= num_atoms_ || index_four >= num_atoms_){ + throw ost::Error("Index of improper atom exceeds number of atoms present in topology!"); + } + Index<4> index(index_one,index_two,index_three,index_four); + std::vector<Real> parameters; + parameters.push_back(angle); + parameters.push_back(force_constant); + harmonic_impropers_.push_back(std::make_pair(index,parameters)); + return harmonic_impropers_.size()-1; +} + +uint Topology::AddCMap(uint index_one, + uint index_two, + uint index_three, + uint index_four, + uint index_five, + int dimension, + std::vector<Real> values){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_ || + index_three >= num_atoms_ || index_four >= num_atoms_ || + index_five >= num_atoms_){ + throw ost::Error("Index of cmap atom exceeds number of atoms present in topology!"); + } + if(uint(dimension * dimension) != values.size()){ + throw ost::Error("Dimension of CMap is inconsistent with its values!"); + } + Index<5> index(index_one,index_two,index_three,index_four,index_five); + cmaps_.push_back(std::make_pair(index,values)); + return cmaps_.size()-1; +} + +uint Topology::AddLJPair(uint index_one, + uint index_two, + Real sigma, + Real epsilon){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_){ + throw ost::Error("Index of lj pair atom exceeds number of atoms present in topology!"); + } + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + if(added_lj_pairs_.find(index) != added_lj_pairs_.end() || added_lj_pairs_.find(reverse_index) != added_lj_pairs_.end()){ + throw ost::Error("This particular lj 1,4-interaction is already parametrized!"); + } + added_lj_pairs_.insert(index); + std::vector<Real> parameters; + parameters.push_back(sigma); + parameters.push_back(epsilon); + lj_pairs_.push_back(std::make_pair(index,parameters)); + return lj_pairs_.size()-1; +} + +uint Topology::AddExclusion(uint index_one, + uint index_two){ + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + if(index_one >= num_atoms_ || index_two >= num_atoms_){ + throw ost::Error("Index of exclusion atom exceeds number of atoms present in topology!"); + } + if(added_exclusions_.find(index) != added_exclusions_.end() || added_exclusions_.find(reverse_index) != added_exclusions_.end()){ + throw ost::Error("This particular exclusion has already been set!"); + } + added_exclusions_.insert(index); + exclusions_.push_back(index); + return exclusions_.size()-1; +} + +uint Topology::AddDistanceConstraint(uint index_one, + uint index_two, + Real distance){ + + if(index_one >= num_atoms_ || index_two >= num_atoms_){ + throw ost::Error("Index of distance constraint atom exceeds number of atoms present in topology!"); + } + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + if(added_distance_constraints_.find(index) != added_distance_constraints_.end() || added_distance_constraints_.find(reverse_index) != added_distance_constraints_.end()){ + throw ost::Error("This particular distance constraint is already parametrized!"); + } + added_distance_constraints_.insert(index); + std::vector<Real> parameters; + parameters.push_back(distance); + distance_constraints_.push_back(std::make_pair(index,parameters)); + return distance_constraints_.size()-1; +} + +void Topology::AddPositionConstraint(uint index){ + if(index >= num_atoms_){ + throw ost::Error("Index of position constraint exceeds number of atoms present in topology!"); + } + std::vector<uint>::iterator it = std::find(position_constraints_.begin(),position_constraints_.end(),index); + if(it != position_constraints_.end()) return; //already present + position_constraints_.push_back(index); +} + +uint Topology::AddHarmonicPositionRestraint(uint ind, const geom::Vec3& ref_position, Real k, + Real x_scale, Real y_scale, Real z_scale){ + if(ind >= num_atoms_){ + throw ost::Error("Index of harmonic distance constraint exceeds number of atoms present in topology!"); + } + Index<1> index(ind); + std::vector<Real> parameters; + parameters.push_back(ref_position[0]); + parameters.push_back(ref_position[1]); + parameters.push_back(ref_position[2]); + parameters.push_back(k); + parameters.push_back(x_scale); + parameters.push_back(y_scale); + parameters.push_back(z_scale); + + harmonic_position_restraints_.push_back(std::make_pair(index,parameters)); + return harmonic_position_restraints_.size()-1; +} + +uint Topology::AddHarmonicDistanceRestraint(uint index_one, uint index_two, + Real length, Real force_constant){ + if(index_one >= num_atoms_ || index_two >= num_atoms_){ + throw ost::Error("Index of distance restraint atom exceeds number of atoms present in topology!"); + } + Index<2> index(index_one,index_two); + std::vector<Real> parameters; + parameters.push_back(length); + parameters.push_back(force_constant); + harmonic_distance_restraints_.push_back(std::make_pair(index,parameters)); + return harmonic_distance_restraints_.size()-1; +} + +void Topology::SetSigmas(const std::vector<Real>& sigmas){ + if(sigmas.size() != num_atoms_){ + throw ost::Error("Expect the same number of sigma parameters than atoms!"); + } + sigmas_ = sigmas; +} + +void Topology::SetSigma(uint index, Real sigma){ + if(sigmas_.empty()){ + throw ost::Error("Modification of sigma parameter requires initial assignment of sigma parameters in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + sigmas_[index] = sigma; +} + +void Topology::SetEpsilons(const std::vector<Real>& epsilons){ + if(epsilons.size() != num_atoms_){ + throw ost::Error("Expect the same number of epsilon parameters than atoms!"); + } + epsilons_ = epsilons; +} + +void Topology::SetEpsilon(uint index, Real epsilon){ + if(epsilons_.empty()){ + throw ost::Error("Modification of epsilon parameter requires initial assignment of epsilon parameters in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + epsilons_[index] = epsilon; +} + +void Topology::SetGBSARadii(const std::vector<Real>& gbsa_radii){ + if(gbsa_radii.size() != num_atoms_){ + throw ost::Error("Expect the same number of gbsa parameters than atoms!"); + } + gbsa_radii_ = gbsa_radii; +} + +void Topology::SetGBSARadius(uint index, Real radius){ + if(gbsa_radii_.empty()){ + throw ost::Error("Modification of gbsa radius requires initial assignment of gbsa radii in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + gbsa_radii_[index] = radius; +} + +void Topology::SetOBCScalings(const std::vector<Real>& obc_scaling){ + if(obc_scaling.size() != num_atoms_){ + throw ost::Error("Expect the same number of gbsa parameters than atoms!"); + } + obc_scaling_ = obc_scaling; +} + +void Topology::SetOBCScaling(uint index, Real scaling){ + if(obc_scaling_.empty()){ + throw ost::Error("Modification of obc scaling parameter requires initial assignment of obc scaling parameters in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + obc_scaling_[index] = scaling; +} + +void Topology::SetCharges(const std::vector<Real>& charges){ + if(charges.size() != num_atoms_){ + throw ost::Error("Expect the same number of charges than atoms!"); + } + charges_ = charges; +} + +void Topology::SetCharge(uint index, Real charge){ + if(charges_.empty()){ + throw ost::Error("Modification of charge parameter requires initial assignment of charges in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + charges_[index] = charge; +} + +void Topology::SetMasses(const std::vector<Real>& masses){ + if(masses.size() != num_atoms_){ + throw ost::Error("Expect masses vector to have the same number of elements than atoms in the topologies entity!"); + } + atom_masses_ = masses; +} + +void Topology::SetMass(uint index, Real mass){ + if(atom_masses_.empty()){ + throw ost::Error("Modification of mass parameter requires initial assignment of masses in globo!"); + } + if(index >= num_atoms_){ + throw ost::Error("Given atom index exceeds number off available atoms!"); + } + atom_masses_[index] = mass; + +} + + +void Topology::GetHarmonicBondParameters(uint index, uint& index_one, uint& index_two, + Real& bond_length, Real& force_constant) const{ + if(index >= harmonic_bonds_.size()){ + throw ost::Error("Provided index exceeds number of harmonic bonds present in topology!"); + } + bond_length = harmonic_bonds_[index].second[0]; + force_constant = harmonic_bonds_[index].second[1]; + index_one = harmonic_bonds_[index].first[0]; + index_two = harmonic_bonds_[index].first[1]; +} + +void Topology::GetHarmonicAngleParameters(uint index, uint& index_one, uint& index_two, uint& index_three, + Real& angle, Real& force_constant) const{ + if(index >= harmonic_angles_.size()){ + throw ost::Error("Provided index exceeds number of harmonic angles present in topology!"); + } + angle = harmonic_angles_[index].second[0]; + force_constant = harmonic_angles_[index].second[1]; + index_one = harmonic_angles_[index].first[0]; + index_two = harmonic_angles_[index].first[1]; + index_three = harmonic_angles_[index].first[2]; +} + +void Topology::GetUreyBradleyAngleParameters(uint index, uint& index_one, uint& index_two, uint& index_three, + Real& angle, Real& angle_force_constant, Real& bond_length, Real& bond_force_constant) const{ + if(index >= urey_bradley_angles_.size()){ + throw ost::Error("Provided index exceeds number of urey_bradley angles present in topology!"); + } + angle = urey_bradley_angles_[index].second[0]; + angle_force_constant = urey_bradley_angles_[index].second[1]; + bond_length = urey_bradley_angles_[index].second[2]; + bond_force_constant = urey_bradley_angles_[index].second[3]; + index_one = urey_bradley_angles_[index].first[0]; + index_two = urey_bradley_angles_[index].first[1]; + index_three = urey_bradley_angles_[index].first[2]; +} + +void Topology::GetPeriodicDihedralParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + int& multiplicity, Real& phase, Real& force_constant) const{ + if(index >= periodic_dihedrals_.size()){ + throw ost::Error("Provided index exceeds number of periodic dihedrals present in topology!"); + } + multiplicity = int(periodic_dihedrals_[index].second[0]); + phase = periodic_dihedrals_[index].second[1]; + force_constant = periodic_dihedrals_[index].second[2]; + index_one = periodic_dihedrals_[index].first[0]; + index_two = periodic_dihedrals_[index].first[1]; + index_three = periodic_dihedrals_[index].first[2]; + index_four = periodic_dihedrals_[index].first[3]; +} + +void Topology::GetPeriodicImproperParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + int& multiplicity, Real& phase, Real& force_constant) const{ + if(index >= periodic_impropers_.size()){ + throw ost::Error("Provided index exceeds number of periodic impropers present in topology!"); + } + multiplicity = int(periodic_impropers_[index].second[0]); + phase = periodic_impropers_[index].second[1]; + force_constant = periodic_impropers_[index].second[2]; + index_one = periodic_impropers_[index].first[0]; + index_two = periodic_impropers_[index].first[1]; + index_three = periodic_impropers_[index].first[2]; + index_four = periodic_impropers_[index].first[3]; +} + +void Topology::GetHarmonicImproperParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + Real& angle, Real& force_constant) const{ + if(index >= harmonic_impropers_.size()){ + throw ost::Error("Provided index exceeds number of harmonic impropers present in topology!"); + } + angle = harmonic_impropers_[index].second[0]; + force_constant = harmonic_impropers_[index].second[1]; + index_one = harmonic_impropers_[index].first[0]; + index_two = harmonic_impropers_[index].first[1]; + index_three = harmonic_impropers_[index].first[2]; + index_four = harmonic_impropers_[index].first[3]; +} + +void Topology::GetCMapParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, uint& index_five, + int& dimension, std::vector<Real>& map) const{ + if(index >= cmaps_.size()){ + throw ost::Error("Provided index exceeds number of cmaps present in topology!"); + } + dimension = int(sqrt(cmaps_[index].second.size())); + map = cmaps_[index].second; + index_one = cmaps_[index].first[0]; + index_two = cmaps_[index].first[1]; + index_three = cmaps_[index].first[2]; + index_four = cmaps_[index].first[3]; + index_five = cmaps_[index].first[4]; + +} + +void Topology::GetLJPairParameters(uint index, uint& index_one, uint& index_two, + Real& sigma, Real& epsilon) const{ + if(index >= lj_pairs_.size()){ + throw ost::Error("Provided index exceeds number of lj pairs present in topology!"); + } + sigma = lj_pairs_[index].second[0]; + epsilon = lj_pairs_[index].second[1]; + index_one = lj_pairs_[index].first[0]; + index_two = lj_pairs_[index].first[1]; +} + +void Topology::GetDistanceConstraintParameters(uint index, uint& index_one, uint& index_two, + Real& distance) const{ + if(index >= distance_constraints_.size()){ + throw ost::Error("Provided index exceeds number of distance_constraints present in topology!"); + } + distance = distance_constraints_[index].second[0]; + index_one = distance_constraints_[index].first[0]; + index_two = distance_constraints_[index].first[1]; +} + +void Topology::GetHarmonicPositionRestraintParameters(uint index, uint& atom_index, geom::Vec3& ref_position, + Real& k, Real& x_scale, Real& y_scale, Real& z_scale) const{ + if(index >= harmonic_position_restraints_.size()){ + throw ost::Error("Provided index exceeds numnber of harmonic position constraints present in topology!"); + } + atom_index = harmonic_position_restraints_[index].first[0]; + ref_position[0] = harmonic_position_restraints_[index].second[0]; + ref_position[1] = harmonic_position_restraints_[index].second[1]; + ref_position[2] = harmonic_position_restraints_[index].second[2]; + k = harmonic_position_restraints_[index].second[3]; + x_scale = harmonic_position_restraints_[index].second[4]; + y_scale = harmonic_position_restraints_[index].second[5]; + z_scale = harmonic_position_restraints_[index].second[6]; +} + +void Topology::GetHarmonicDistanceRestraintParameters(uint index, uint& atom_one, uint& atom_two, Real& length, + Real& force_constant) const{ + if(index >= harmonic_distance_restraints_.size()){ + throw ost::Error("Provided index exceeds number of harmonic distance restraints present in topology!"); + } + atom_one = harmonic_distance_restraints_[index].first[0]; + atom_two = harmonic_distance_restraints_[index].first[1]; + length = harmonic_distance_restraints_[index].second[0]; + force_constant = harmonic_distance_restraints_[index].second[1]; +} + + +void Topology::SetHarmonicBondParameters(uint index, const Real& bond_length, const Real& force_constant){ + if(index >= harmonic_bonds_.size()){ + throw ost::Error("Provided index exceeds number of harmonic bonds present in topology!"); + } + harmonic_bonds_[index].second[0] = bond_length; + harmonic_bonds_[index].second[1] = force_constant; +} + +void Topology::SetHarmonicAngleParameters(uint index, const Real& angle, const Real& force_constant){ + if(index >= harmonic_angles_.size()){ + throw ost::Error("Provided index exceeds number of harmonic angles present in topology!"); + } + harmonic_angles_[index].second[0] = angle; + harmonic_angles_[index].second[1] = force_constant; +} + +void Topology::SetUreyBradleyAngleParameters(uint index, const Real& angle, const Real& angle_force_constant, const Real& bond_length, const Real& bond_force_constant){ + if(index >= urey_bradley_angles_.size()){ + throw ost::Error("Provided index exceeds number of urey_bradley angles present in topology!"); + } + urey_bradley_angles_[index].second[0] = angle; + urey_bradley_angles_[index].second[1] = angle_force_constant; + urey_bradley_angles_[index].second[2] = bond_length; + urey_bradley_angles_[index].second[3] = bond_force_constant; +} + +void Topology::SetPeriodicDihedralParameters(uint index, const int& multiplicity, const Real& phase, const Real& force_constant){ + if(index >= periodic_dihedrals_.size()){ + throw ost::Error("Provided index exceeds number of periodic dihedrals present in topology!"); + } + periodic_dihedrals_[index].second[0] = multiplicity; + periodic_dihedrals_[index].second[1] = phase; + periodic_dihedrals_[index].second[2] = force_constant; +} + +void Topology::SetPeriodicImproperParameters(uint index, const int& multiplicity, const Real& phase, const Real& force_constant){ + if(index >= periodic_impropers_.size()){ + throw ost::Error("Provided index exceeds number of periodic impropers present in topology!"); + } + periodic_impropers_[index].second[0] = multiplicity; + periodic_impropers_[index].second[1] = phase; + periodic_impropers_[index].second[2] = force_constant; +} + +void Topology::SetHarmonicImproperParameters(uint index, const Real& angle, const Real& force_constant){ + if(index >= harmonic_impropers_.size()){ + throw ost::Error("Provided index exceeds number of harmonic impropers present in topology!"); + } + harmonic_impropers_[index].second[0] = angle; + harmonic_impropers_[index].second[1] = force_constant; +} + +void Topology::SetCMapParameters(uint index, const int& dimension, const std::vector<Real>& map){ + if(index >= cmaps_.size()){ + throw ost::Error("Provided index exceeds number of cmaps present in topology!"); + } + if(uint(dimension * dimension) != map.size()){ + throw ost::Error("Provided dimension and map are inconsistent!"); + } + cmaps_[index].second = map; +} + +void Topology::SetLJPairParameters(uint index, const Real& sigma, const Real& epsilon){ + if(index >= lj_pairs_.size()){ + throw ost::Error("Provided index exceeds number of lj pairs present in topology!"); + } + lj_pairs_[index].second[0] = sigma; + lj_pairs_[index].second[1] = epsilon; +} + +void Topology::SetDistanceConstraintParameters(uint index, const Real& distance){ + if(index >= distance_constraints_.size()){ + throw ost::Error("Provided index exceeds number of distance_constraints present in topology!"); + } + distance_constraints_[index].second[0] = distance; +} + +void Topology::SetHarmonicPositionRestraintParameters(uint index, const geom::Vec3& ref_position, Real k, + Real x_scale, Real y_scale, Real z_scale){ + if(index >= harmonic_position_restraints_.size()){ + throw ost::Error("Provided index exceeds number of harmonic position restraints present in topology!"); + } + harmonic_position_restraints_[index].second[0] = ref_position[0]; + harmonic_position_restraints_[index].second[1] = ref_position[1]; + harmonic_position_restraints_[index].second[2] = ref_position[2]; + harmonic_position_restraints_[index].second[3] = k; + harmonic_position_restraints_[index].second[4] = x_scale; + harmonic_position_restraints_[index].second[5] = y_scale; + harmonic_position_restraints_[index].second[6] = z_scale; +} + +void Topology::SetHarmonicDistanceRestraintParameters(uint index, Real length, + Real force_constant){ + if(index >= harmonic_distance_restraints_.size()){ + throw ost::Error("Provided index exceeds number of harmonic distance restraints present in topology!"); + } + harmonic_distance_restraints_[index].second[0] = length; + harmonic_distance_restraints_[index].second[1] = force_constant; + +} + +uint Topology::GetAtomIndex(const ost::mol::AtomHandle& at) const{ + std::map<long,uint>::const_iterator i = atom_index_mapper_.find(at.GetHashCode()); + if(i == atom_index_mapper_.end()){ + throw ost::Error("Could not find atom in attached entity!"); + } + return i->second; +} + + +uint Topology::GetResidueIndex(const ost::mol::ResidueHandle& res) const{ + std::map<long,uint>::const_iterator i = residue_index_mapper_.find(res.GetHashCode()); + if(i == residue_index_mapper_.end()){ + throw ost::Error("Could not find residue in attached entity!"); + } + return i->second; +} + +uint Topology::GetAtomIndex(uint residue_index, const String& atom_name) const{ + if(residue_index < 0 || residue_index >= num_residues_){ + throw ost::Error("Residue index out of bounds"); + } + if(atom_name[0] == '+'){ + ost::mol::ResidueHandle actual_res = res_list_[residue_index]; + ost::mol::ResidueHandle next_residue = actual_res.GetNext(); + if(!next_residue){ + throw ost::Error("Could not get next residue!"); + } + String next_atom_name = atom_name.substr(1); + std::map<String,uint>::const_iterator it = atom_name_mapper_[this->GetResidueIndex(next_residue)].find(next_atom_name); + if(it == atom_name_mapper_[this->GetResidueIndex(next_residue)].end()){ + std::stringstream ss; + ss << "Could not find required atom " << next_atom_name; + ss << " from residue " << next_residue.GetQualifiedName(); + } + return it->second; + } + if(atom_name[0] == '-'){ + ost::mol::ResidueHandle actual_res = res_list_[residue_index]; + ost::mol::ResidueHandle prev_residue = actual_res.GetPrev(); + if(!prev_residue){ + throw ost::Error("Could not get prev residue!"); + } + String prev_atom_name = atom_name.substr(1); + std::map<String,uint>::const_iterator it = atom_name_mapper_[this->GetResidueIndex(prev_residue)].find(prev_atom_name); + if(it == atom_name_mapper_[this->GetResidueIndex(prev_residue)].end()){ + std::stringstream ss; + ss << "Could not find required atom " << prev_atom_name; + ss << " from residue " << prev_residue.GetQualifiedName(); + } + return it->second; + } + std::map<String,uint>::const_iterator it = atom_name_mapper_[residue_index].find(atom_name); + if(it == atom_name_mapper_[residue_index].end()){ + std::stringstream ss; + ss << "Could not find required atom " << atom_name; + ss << " from residue " << res_list_[residue_index].GetQualifiedName(); + } + return it->second; +} + +Real Topology::GetMass(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + return atom_masses_[index]; +} + +Real Topology::GetSigma(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + if(sigmas_.empty()) throw ost::Error("No sigmas set!"); + return sigmas_[index]; +} + +Real Topology::GetEpsilon(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + if(epsilons_.empty()) throw ost::Error("No epsilons set!"); + return epsilons_[index]; +} + +Real Topology::GetGBSARadius(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + if(gbsa_radii_.empty()) throw ost::Error("No gbsa radii set!"); + return gbsa_radii_[index]; +} + +Real Topology::GetOBCScaling(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + if(obc_scaling_.empty()) throw ost::Error("No obc scalings set!"); + return obc_scaling_[index]; +} + + +Real Topology::GetCharge(uint index) const{ + if(index >= num_atoms_) throw ost::Error("Provided index exceeds number of atoms present in topology!"); + if(charges_.empty()) throw ost::Error("No charges set!"); + return charges_[index]; +} + + +void Topology::SetEntityPositions(const geom::Vec3List& positions){ + if(positions.size() != num_atoms_){ + throw ost::Error("Expect positions vector to have the same number of elements than atoms in the topologies entity!"); + } + ost::mol::XCSEditor ed = ent_.EditXCS(ost::mol::BUFFERED_EDIT); + for(uint i = 0; i < num_atoms_; ++i){ + ed.SetAtomPos(atom_list_[i],positions[i]); + } + ed.UpdateICS(); +} + +std::vector<uint> Topology::GetHarmonicBondIndices(uint index_one, + uint index_two) const{ + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_bonds_.size(); ++i){ + if(index == harmonic_bonds_[i].first || reverse_index == harmonic_bonds_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicAngleIndices(uint index_one, + uint index_two, + uint index_three) const{ + Index<3> index(index_one,index_two,index_three); + Index<3> reverse_index(index_three,index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_angles_.size(); ++i){ + if(index == harmonic_angles_[i].first || reverse_index == harmonic_angles_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetUreyBradleyAngleIndices(uint index_one, + uint index_two, + uint index_three) const{ + Index<3> index(index_one,index_two,index_three); + Index<3> reverse_index(index_three,index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < urey_bradley_angles_.size(); ++i){ + if(index == urey_bradley_angles_[i].first || reverse_index == urey_bradley_angles_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetPeriodicDihedralIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const{ + Index<4> index(index_one,index_two,index_three,index_four); + Index<4> reverse_index(index_four,index_three,index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < periodic_dihedrals_.size(); ++i){ + if(index == periodic_dihedrals_[i].first || reverse_index == periodic_dihedrals_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetPeriodicImproperIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const{ + Index<4> index(index_one,index_two,index_three,index_four); + Index<4> reverse_index(index_four,index_three,index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < periodic_impropers_.size(); ++i){ + if(index == periodic_impropers_[i].first || reverse_index == periodic_impropers_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicImproperIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const{ + Index<4> index(index_one,index_two,index_three,index_four); + Index<4> reverse_index(index_four,index_three,index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_impropers_.size(); ++i){ + if(index == harmonic_impropers_[i].first || reverse_index == harmonic_impropers_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetCMapIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four, + uint index_five) const{ + //note, that in case of cmaps the order of the atoms matters + Index<5> index(index_one,index_two,index_three,index_four,index_five); + std::vector<uint> return_indices; + for(uint i = 0; i < cmaps_.size(); ++i){ + if(index == cmaps_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +int Topology::GetLJPairIndex(uint index_one, + uint index_two) const{ + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + for(uint i = 0; i < lj_pairs_.size(); ++i){ + if(index == lj_pairs_[i].first || reverse_index == lj_pairs_[i].first){ + return i; + } + } + return -1; +} + +int Topology::GetDistanceConstraintIndex(uint index_one, + uint index_two) const{ + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + for(uint i = 0; i < distance_constraints_.size(); ++i){ + if(index == distance_constraints_[i].first || reverse_index == distance_constraints_[i].first){ + return i; + } + } + return -1; +} + +std::vector<uint> Topology::GetHarmonicPositionRestraintIndices(uint atom_index) const{ + Index<1> index(atom_index); + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_position_restraints_.size(); ++i){ + if(index == harmonic_position_restraints_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicDistanceRestraintIndices(uint index_one, uint index_two) const{ + + Index<2> index(index_one,index_two); + Index<2> reverse_index(index_two,index_one); + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_distance_restraints_.size(); ++i){ + if(index == harmonic_distance_restraints_[i].first || reverse_index == harmonic_distance_restraints_[i].first){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicBondIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_bonds_.size(); ++i){ + if(harmonic_bonds_[i].first[0] == atom_index || harmonic_bonds_[i].first[1] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicAngleIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_angles_.size(); ++i){ + if(harmonic_angles_[i].first[0] == atom_index || harmonic_angles_[i].first[1] == atom_index || + harmonic_angles_[i].first[2] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetUreyBradleyAngleIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < urey_bradley_angles_.size(); ++i){ + if(urey_bradley_angles_[i].first[0] == atom_index || urey_bradley_angles_[i].first[1] == atom_index || + urey_bradley_angles_[i].first[2] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetPeriodicDihedralIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < periodic_dihedrals_.size(); ++i){ + if(periodic_dihedrals_[i].first[0] == atom_index || periodic_dihedrals_[i].first[1] == atom_index || + periodic_dihedrals_[i].first[2] == atom_index || periodic_dihedrals_[i].first[3] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetPeriodicImproperIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < periodic_impropers_.size(); ++i){ + if(periodic_impropers_[i].first[0] == atom_index || periodic_impropers_[i].first[1] == atom_index || + periodic_impropers_[i].first[2] == atom_index || periodic_impropers_[i].first[3] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicImproperIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_impropers_.size(); ++i){ + if(harmonic_impropers_[i].first[0] == atom_index || harmonic_impropers_[i].first[1] == atom_index || + harmonic_impropers_[i].first[2] == atom_index || harmonic_impropers_[i].first[3] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetCMapIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < cmaps_.size(); ++i){ + if(cmaps_[i].first[0] == atom_index || cmaps_[i].first[1] == atom_index || + cmaps_[i].first[2] == atom_index || cmaps_[i].first[3] == atom_index || + cmaps_[i].first[4] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetLJPairIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < lj_pairs_.size(); ++i){ + if(lj_pairs_[i].first[0] == atom_index || lj_pairs_[i].first[1] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetDistanceConstraintIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < distance_constraints_.size(); ++i){ + if(distance_constraints_[i].first[0] == atom_index || distance_constraints_[i].first[1] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +std::vector<uint> Topology::GetHarmonicDistanceRestraintIndices(uint atom_index) const{ + std::vector<uint> return_indices; + for(uint i = 0; i < harmonic_distance_restraints_.size(); ++i){ + if(harmonic_distance_restraints_[i].first[0] == atom_index || harmonic_distance_restraints_[i].first[1] == atom_index){ + return_indices.push_back(i); + } + } + return return_indices; +} + +void Topology::Merge(TopologyPtr p){ + //check whether there is chain from the new entity is already present in the actual entity + ost::mol::EntityHandle source_ent = p->GetEntity(); + ost::mol::ChainHandleList source_chains = source_ent.GetChainList(); + for(ost::mol::ChainHandleList::iterator i = source_chains.begin(); + i != source_chains.end(); ++i){ + if(ent_.FindChain(i->GetName()).IsValid()){ + std::stringstream ss; + ss << "Chain with name \"" << i->GetName() << "\" from source topology"; + ss << "is already present in destination topology!"; + throw ost::Error(ss.str()); + } + } + //check whether the fudge parameters are consistent + if(p->GetFudgeLJ() != fudge_lj_ || p->GetFudgeQQ() != fudge_qq_){ + throw ost::Error("Expect the fudge parameters of source topology to consistent with the fudge parameters from the destination topology!"); + } + + //mapper of hashcode from source atom to index in added_atom list + std::map<long,int> index_mapper; + ost::mol::AtomHandleList added_atoms; + + //let's create an editor to copy over all chains, residues and atoms + //from the source topologies entity + ost::mol::XCSEditor ed = ent_.EditXCS(ost::mol::BUFFERED_EDIT); + for(ost::mol::ChainHandleList::iterator i = source_chains.begin(); + i != source_chains.end(); ++i){ + ost::mol::ResidueHandleList res_list = i->GetResidueList(); + ost::mol::ChainHandle added_chain = ed.InsertChain(i->GetName()); + + for(ost::mol::ResidueHandleList::iterator j = res_list.begin(); + j != res_list.end(); ++j){ + ost::mol::AtomHandleList atom_list = j->GetAtomList(); + ost::mol::ResidueHandle added_residue = ed.AppendResidue(added_chain,*j); + + for(ost::mol::AtomHandleList::iterator k = atom_list.begin(); + k != atom_list.end(); ++k){ + index_mapper[k->GetHashCode()] = added_atoms.size(); + added_atoms.push_back(ed.InsertAtom(added_residue,*k)); + } + } + } + + //let's rebuild the connectivity + ost::mol::BondHandleList bond_list = source_ent.GetBondList(); + for(ost::mol::BondHandleList::iterator i = bond_list.begin(); + i != bond_list.end(); ++i){ + ed.Connect(added_atoms[index_mapper[i->GetFirst().GetHashCode()]], + added_atoms[index_mapper[i->GetSecond().GetHashCode()]]); + } + ed.UpdateICS(); + + //let's update the remaining structural data + atom_list_ = ent_.GetAtomList(); + res_list_ = ent_.GetResidueList(); + num_atoms_ = atom_list_.size(); + num_residues_ = res_list_.size(); + + //let's update the index mappers + for(uint i = 0; i < num_atoms_; ++i){ + if(atom_index_mapper_.find(atom_list_[i].GetHashCode()) == atom_index_mapper_.end()){ + atom_index_mapper_[atom_list_[i].GetHashCode()] = i; + continue; + } + //indices of atoms that have already been there must not be changed + if(atom_index_mapper_[atom_list_[i].GetHashCode()] != i){ + throw ost::Error("Updating indices during merging process went horribly wrong!"); + } + } + + for(uint i = 0; i != num_residues_; ++i){ + if(residue_index_mapper_.find(res_list_[i].GetHashCode()) == residue_index_mapper_.end()){ + residue_index_mapper_[res_list_[i].GetHashCode()] = i; + continue; + } + //indices of residues that have already been there must not be changed + if(residue_index_mapper_[res_list_[i].GetHashCode()] != i){ + throw ost::Error("Updating indices during merging process went horribly wrong!"); + } + } + + atom_name_mapper_.clear(); //let's rebuild from scratch + std::map<String,uint> per_residue_mapper; + ost::mol::AtomHandleList residue_atom_list; + for(uint i = 0; i < num_residues_; ++i){ + per_residue_mapper.clear(); + residue_atom_list = res_list_[i].GetAtomList(); + for(ost::mol::AtomHandleList::iterator j = residue_atom_list.begin(); + j != residue_atom_list.end(); ++j){ + per_residue_mapper[j->GetName()] = atom_index_mapper_[j->GetHashCode()]; + } + atom_name_mapper_.push_back(per_residue_mapper); + } + + //let's first generate an index mapper from source atom indices to the indices in + //the destination entity + ost::mol::AtomHandleList source_atoms = source_ent.GetAtomList(); + std::map<int,int> final_index_mapper; + for(uint i = 0; i < source_atoms.size(); ++i){ + final_index_mapper[i] = atom_index_mapper_[added_atoms[index_mapper[source_atoms[i].GetHashCode()]].GetHashCode()]; + } + + //let's map over masses + std::vector<Real> source_masses = p->GetMasses(); + + for(uint i = 0; i < source_atoms.size(); ++i){ + atom_masses_.push_back(0.0); + } + for(uint i = 0; i < source_atoms.size(); ++i){ + atom_masses_[final_index_mapper[i]] = source_masses[i]; + } + + //let's map over the other per atom parameters if they're defined in the destination topology + if(!charges_.empty()){ + std::vector<Real> source_charges = p->GetCharges(); + if(source_charges.empty()){ + throw ost::Error("Cannot merge topology without charges into a topology with defined charges!"); + } + for(uint i = 0; i < source_charges.size(); ++i){ + charges_.push_back(0.0); + } + for(uint i = 0; i < source_charges.size(); ++i){ + charges_[final_index_mapper[i]] = source_charges[i]; + } + } + + if(!sigmas_.empty()){ + std::vector<Real> source_sigmas = p->GetSigmas(); + if(source_sigmas.empty()){ + throw ost::Error("Cannot merge topology without lj sigmas into a topology with defined sigmas!"); + } + for(uint i = 0; i < source_sigmas.size(); ++i){ + sigmas_.push_back(0.0); + } + for(uint i = 0; i < source_sigmas.size(); ++i){ + sigmas_[final_index_mapper[i]] = source_sigmas[i]; + } + } + + if(!epsilons_.empty()){ + std::vector<Real> source_epsilons= p->GetEpsilons(); + if(source_epsilons.empty()){ + throw ost::Error("Cannot merge topology without lj epsilons into a topology with defined epsilons!"); + } + for(uint i = 0; i < source_epsilons.size(); ++i){ + epsilons_.push_back(0.0); + } + for(uint i = 0; i < source_epsilons.size(); ++i){ + epsilons_[final_index_mapper[i]] = source_epsilons[i]; + } + } + + if(!gbsa_radii_.empty()){ + std::vector<Real> source_radii= p->GetGBSARadii(); + if(source_radii.empty()){ + throw ost::Error("Cannot merge topology without gbsa radii into a topology with defined radii!"); + } + for(uint i = 0; i < source_radii.size(); ++i){ + gbsa_radii_.push_back(0.0); + } + for(uint i = 0; i < source_radii.size(); ++i){ + gbsa_radii_[final_index_mapper[i]] = source_radii[i]; + } + } + + if(!obc_scaling_.empty()){ + std::vector<Real> source_scaling= p->GetOBCScalings(); + if(source_scaling.empty()){ + throw ost::Error("Cannot merge topology without obc scaling into a topology with defined scaling!"); + } + for(uint i = 0; i < source_scaling.size(); ++i){ + obc_scaling_.push_back(0.0); + } + for(uint i = 0; i < source_scaling.size(); ++i){ + obc_scaling_[final_index_mapper[i]] = source_scaling[i]; + } + } + + //finally, all the interactions get mapped over + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& harmonic_bonds = p->GetHarmonicBonds(); + if(!harmonic_bonds.empty()){ + for(std::vector<std::pair<Index<2>, std::vector<Real> > >::const_iterator i = harmonic_bonds.begin(); + i != harmonic_bonds.end(); ++i){ + this->AddHarmonicBond(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + i->second[0],i->second[1]); + } + } + + const std::vector<std::pair<Index<3>, std::vector<Real> > >& harmonic_angles = p->GetHarmonicAngles(); + if(!harmonic_angles.empty()){ + for(std::vector<std::pair<Index<3>, std::vector<Real> > >::const_iterator i = harmonic_angles.begin(); + i != harmonic_angles.end(); ++i){ + this->AddHarmonicAngle(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + i->second[0],i->second[1]); + } + } + + const std::vector<std::pair<Index<3>, std::vector<Real> > >& urey_bradley_angles = p->GetUreyBradleyAngles(); + if(!urey_bradley_angles.empty()){ + for(std::vector<std::pair<Index<3>, std::vector<Real> > >::const_iterator i = urey_bradley_angles.begin(); + i != urey_bradley_angles.end(); ++i){ + this->AddUreyBradleyAngle(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + i->second[0],i->second[1], + i->second[2],i->second[3]); + } + } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& periodic_dihedrals = p->GetPeriodicDihedrals(); + if(!periodic_dihedrals.empty()){ + for(std::vector<std::pair<Index<4>, std::vector<Real> > >::const_iterator i = periodic_dihedrals.begin(); + i != periodic_dihedrals.end(); ++i){ + this->AddPeriodicDihedral(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + final_index_mapper[i->first[3]], + int(i->second[0]),i->second[1],i->second[2]); + } + } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& periodic_impropers = p->GetPeriodicImpropers(); + if(!periodic_impropers.empty()){ + for(std::vector<std::pair<Index<4>, std::vector<Real> > >::const_iterator i = periodic_impropers.begin(); + i != periodic_impropers.end(); ++i){ + this->AddPeriodicImproper(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + final_index_mapper[i->first[3]], + int(i->second[0]),i->second[1],i->second[2]); + } + } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& harmonic_impropers = p->GetHarmonicImpropers(); + if(!harmonic_impropers.empty()){ + for(std::vector<std::pair<Index<4>, std::vector<Real> > >::const_iterator i = harmonic_impropers.begin(); + i != harmonic_impropers.end(); ++i){ + this->AddHarmonicImproper(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + final_index_mapper[i->first[3]], + i->second[0],i->second[1]); + } + } + + const std::vector<std::pair<Index<5>, std::vector<Real> > >& cmaps = p->GetCMaps(); + if(!cmaps.empty()){ + for(std::vector<std::pair<Index<5>, std::vector<Real> > >::const_iterator i = cmaps.begin(); + i != cmaps.end(); ++i){ + uint dimension = sqrt(i->second.size()); + this->AddCMap(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + final_index_mapper[i->first[2]], + final_index_mapper[i->first[3]], + final_index_mapper[i->first[4]], + dimension,i->second); + } + } + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& ljpairs = p->GetLJPairs(); + if(!ljpairs.empty()){ + for(std::vector<std::pair<Index<2>, std::vector<Real> > >::const_iterator i = ljpairs.begin(); + i != ljpairs.end(); ++i){ + this->AddLJPair(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + i->second[0],i->second[1]); + } + } + + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& distance_constraints = p->GetDistanceConstraints(); + if(!distance_constraints.empty()){ + for(std::vector<std::pair<Index<2>, std::vector<Real> > >::const_iterator i = distance_constraints.begin(); + i != distance_constraints.end(); ++i){ + this->AddDistanceConstraint(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + i->second[0]); + } + } + + const std::vector<Index<2> >& exclusions = p->GetExclusions(); + if(!exclusions.empty()){ + for(std::vector<Index<2> >::const_iterator i = exclusions.begin(); + i != exclusions.end(); ++i){ + this->AddExclusion(final_index_mapper[(*i)[0]], + final_index_mapper[(*i)[1]]); + } + } + + const std::vector<std::pair<Index<1>,std::vector<Real> > >& harmonic_position_restraints = p->GetHarmonicPositionRestraints(); + if(!harmonic_position_restraints.empty()){ + for(std::vector<std::pair<Index<1>,std::vector<Real> > >::const_iterator i = harmonic_position_restraints.begin(); + i != harmonic_position_restraints.end(); ++i){ + geom::Vec3 ref_pos(i->second[0],i->second[1],i->second[2]); + this->AddHarmonicPositionRestraint(final_index_mapper[i->first[0]], + ref_pos, + i->second[3], + i->second[4], + i->second[5], + i->second[6]); + } + } + + const std::vector<std::pair<Index<2>,std::vector<Real> > >& harmonic_distance_restraints = p->GetHarmonicDistanceRestraints(); + if(!harmonic_distance_restraints.empty()){ + for(std::vector<std::pair<Index<2>,std::vector<Real> > >::const_iterator i = harmonic_distance_restraints.begin(); + i != harmonic_distance_restraints.end(); ++i){ + this->AddHarmonicDistanceRestraint(final_index_mapper[i->first[0]], + final_index_mapper[i->first[1]], + i->second[0], + i->second[1]); + } + } + + const std::vector<uint>& position_constraints = p->GetPositionConstraints(); + if(!position_constraints.empty()){ + for(std::vector<uint>::const_iterator i = position_constraints.begin(); + i != position_constraints.end(); ++i){ + this->AddPositionConstraint(final_index_mapper[*i]); + } + } + + for(std::set<Index<2> >::iterator i = p->added_lj_pairs_.begin(); + i != p->added_lj_pairs_.end(); ++i){ + added_lj_pairs_.insert(Index<2>(final_index_mapper[(*i)[0]], + final_index_mapper[(*i)[1]])); + } + + for(std::set<Index<2> >::iterator i = p->added_distance_constraints_.begin(); + i != p->added_distance_constraints_.end(); ++i){ + added_distance_constraints_.insert(Index<2>(final_index_mapper[(*i)[0]], + final_index_mapper[(*i)[1]])); + } + + for(std::set<Index<2> >::iterator i = p->added_exclusions_.begin(); + i != p->added_exclusions_.end(); ++i){ + added_exclusions_.insert(Index<2>(final_index_mapper[(*i)[0]], + final_index_mapper[(*i)[1]])); + } + +} + + +}}}//ns diff --git a/modules/mol/mm/src/topology.hh b/modules/mol/mm/src/topology.hh new file mode 100644 index 0000000000000000000000000000000000000000..dbe67e60d48f07cb918d3145e8f7f852da9e3c5d --- /dev/null +++ b/modules/mol/mm/src/topology.hh @@ -0,0 +1,414 @@ +#ifndef OST_MM_TOPOLOGY_HH +#define OST_MM_TOPOLOGY_HH + +#include <vector> +#include <map> +#include <set> + +#include <boost/shared_ptr.hpp> + +#include <ost/message.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/mm/index.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/index.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> + +#include <time.h> + + + +namespace ost { namespace mol{ namespace mm{ + +class Topology; +typedef boost::shared_ptr<Topology> TopologyPtr; + + +class Topology{ + +public: + + Topology(const ost::mol::EntityHandle& ent, const std::vector<Real>& masses); + + uint AddHarmonicBond(uint index_one, + uint index_two, + Real bond_length, + Real force_constant); + + uint AddHarmonicAngle(uint index_one, + uint index_two, + uint index_three, + Real angle, + Real force_constant); + + uint AddUreyBradleyAngle(uint index_one, + uint index_two, + uint index_three, + Real angle, + Real angle_force_constant, + Real bond_length, + Real bond_force_constant); + + uint AddPeriodicDihedral(uint index_one, + uint index_two, + uint index_three, + uint index_four, + int multiplicity, + Real phase, + Real force_constant); + + uint AddPeriodicImproper(uint index_one, + uint index_two, + uint index_three, + uint index_four, + int multiplicity, + Real phase, + Real force_constant); + + uint AddHarmonicImproper(uint index_one, + uint index_two, + uint index_three, + uint index_four, + Real angle, + Real force_constant); + + uint AddCMap(uint index_one, + uint index_two, + uint index_three, + uint index_four, + uint index_five, + int dimension, + std::vector<Real> values); + + uint AddLJPair(uint index_one, + uint index_two, + Real sigma, + Real epsilon); + + + uint AddDistanceConstraint(uint index_one, + uint index_two, + Real distance); + + uint AddExclusion(uint index_one, + uint index_two); + + void AddPositionConstraint(uint index); + + void ResetPositionConstraints() { position_constraints_.clear(); } + + void ResetExclusions() { exclusions_.clear(); } + + uint AddHarmonicPositionRestraint(uint index, const geom::Vec3& ref_position, Real k, + Real x_scale = 1.0, Real y_scale = 1.0, Real z_scale = 1.0); + + uint AddHarmonicDistanceRestraint(uint index_one, uint index_two, + Real length, Real force_constant); + + //Single atom parameters are expected to be set at once... + void SetSigmas(const std::vector<Real>& sigmas); + + void SetSigma(uint index, Real sigma); + + void SetEpsilons(const std::vector<Real>& epsilons); + + void SetEpsilon(uint index, Real epsilon); + + void SetGBSARadii(const std::vector<Real>& gbsa_radii); + + void SetGBSARadius(uint index, Real radius); + + void SetOBCScalings(const std::vector<Real>& obc_scaling); + + void SetOBCScaling(uint index, Real scaling); + + void SetCharges(const std::vector<Real>& charges); + + void SetCharge(uint index, Real charge); + + void SetMasses(const std::vector<Real>& masses); + + void SetMass(uint index, Real mass); + + void SetFudgeQQ(Real fudge) { fudge_qq_ = fudge; } + + void SetFudgeLJ(Real fudge) { fudge_lj_ = fudge;} + + + void GetHarmonicBondParameters(uint index, uint& index_one, uint& index_two, + Real& bond_length, Real& force_constant) const; + + void GetHarmonicAngleParameters(uint index, uint& index_one, uint& index_two, uint& index_three, + Real& angle, Real& force_constant) const; + + void GetUreyBradleyAngleParameters(uint index, uint& index_one, uint& index_two, uint& index_three, + Real& angle, Real& angle_force_constant, Real& bond_length, Real& bond_force_constant) const; + + void GetPeriodicDihedralParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + int& multiplicity, Real& phase, Real& force_constant) const; + + void GetPeriodicImproperParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + int& multiplicity, Real& phase, Real& force_constant) const; + + void GetHarmonicImproperParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, + Real& angle, Real& force_constant) const; + + void GetCMapParameters(uint index, uint& index_one, uint& index_two, uint& index_three, uint& index_four, uint& index_five, + int& dimension, std::vector<Real>& map) const; + + void GetLJPairParameters(uint index, uint& index_one, uint& index_two, + Real& sigma, Real& epsilon) const; + + void GetDistanceConstraintParameters(uint index, uint& index_one, uint& index_two, + Real& distance) const; + + void GetHarmonicPositionRestraintParameters(uint index, uint& atom_index, geom::Vec3& ref_position, + Real& k, Real& x_scale, Real& y_scale, Real& z_scale) const; + + void GetHarmonicDistanceRestraintParameters(uint index, uint& atom_one, uint& atom_two, Real& length, + Real& force_constant) const; + + void SetHarmonicBondParameters(uint index, const Real& bond_length, const Real& force_constant); + + void SetHarmonicAngleParameters(uint index, const Real& angle, const Real& force_constant); + + void SetUreyBradleyAngleParameters(uint index, const Real& angle, const Real& angle_force_constant, const Real& bond_length, const Real& bond_force_constant); + + void SetPeriodicDihedralParameters(uint index, const int& multiplicity, const Real& phase, const Real& force_constant); + + void SetPeriodicImproperParameters(uint index, const int& multiplicity, const Real& phase, const Real& force_constant); + + void SetHarmonicImproperParameters(uint index, const Real& angle, const Real& force_constant); + + void SetCMapParameters(uint index, const int& dimension, const std::vector<Real>& map); + + void SetLJPairParameters(uint index, const Real& sigma, const Real& epsilon); + + void SetDistanceConstraintParameters(uint index, const Real& distance); + + void SetHarmonicPositionRestraintParameters(uint index, const geom::Vec3& ref_position, Real k, + Real x_scale = 1.0, Real y_scale = 1.0, Real z_scale = 1.0); + + void SetHarmonicDistanceRestraintParameters(uint index, Real length, Real force_constant); + + ost::mol::EntityHandle GetEntity() const { return ent_; }; + + uint GetAtomIndex(const ost::mol::AtomHandle& at) const; + + uint GetAtomIndex(uint residue_index, const String& atom_name) const; + + uint GetResidueIndex(const ost::mol::ResidueHandle& res) const; + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& GetHarmonicBonds() const { return harmonic_bonds_; } + + const std::vector<std::pair<Index<3>, std::vector<Real> > >& GetHarmonicAngles() const { return harmonic_angles_; } + + const std::vector<std::pair<Index<3>, std::vector<Real> > >& GetUreyBradleyAngles() const { return urey_bradley_angles_; } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& GetPeriodicDihedrals() const { return periodic_dihedrals_; } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& GetPeriodicImpropers() const { return periodic_impropers_; } + + const std::vector<std::pair<Index<4>, std::vector<Real> > >& GetHarmonicImpropers() const { return harmonic_impropers_; } + + const std::vector<std::pair<Index<5>, std::vector<Real> > >& GetCMaps() const { return cmaps_; } + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& GetLJPairs() const { return lj_pairs_; } + + const std::vector<std::pair<Index<2>, std::vector<Real> > >& GetDistanceConstraints() const { return distance_constraints_; } + + const std::vector<std::pair<Index<1>, std::vector<Real> > >&GetHarmonicPositionRestraints() const { return harmonic_position_restraints_; } + + const std::vector<std::pair<Index<2>, std::vector<Real> > >&GetHarmonicDistanceRestraints() const{ return harmonic_distance_restraints_; } + + const std::vector<Index<2> >& GetExclusions() const { return exclusions_; } + + const std::vector<uint>& GetPositionConstraints() const { return position_constraints_; } + + std::vector<Real> GetSigmas() const { return sigmas_; } + + std::vector<Real> GetEpsilons() const { return epsilons_; } + + std::vector<Real> GetGBSARadii() const { return gbsa_radii_; } + + std::vector<Real> GetOBCScalings() const { return obc_scaling_; } + + std::vector<Real> GetCharges() const { return charges_; } + + Real GetCharge(uint index) const; + + Real GetMass(uint index) const; + + Real GetSigma(uint index) const; + + Real GetEpsilon(uint index) const; + + Real GetGBSARadius(uint index) const; + + Real GetOBCScaling(uint index) const; + + std::vector<Real> GetMasses() const { return atom_masses_; } + + Real GetFudgeQQ() const { return fudge_qq_; } + + Real GetFudgeLJ() const { return fudge_lj_; } + + std::vector<uint> GetHarmonicBondIndices(uint index_one, + uint index_two) const; + + std::vector<uint> GetHarmonicAngleIndices(uint index_one, + uint index_two, + uint index_three) const; + + std::vector<uint> GetUreyBradleyAngleIndices(uint index_one, + uint index_two, + uint index_three) const; + + std::vector<uint> GetPeriodicDihedralIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const; + + std::vector<uint> GetPeriodicImproperIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const; + + std::vector<uint> GetHarmonicImproperIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four) const; + + std::vector<uint> GetCMapIndices(uint index_one, + uint index_two, + uint index_three, + uint index_four, + uint index_five) const; + + int GetLJPairIndex(uint index_one, + uint index_two) const; + + int GetDistanceConstraintIndex(uint index_one, + uint index_two) const; + + + + std::vector<uint> GetHarmonicDistanceRestraintIndices(uint index_one, + uint index_two) const; + + + std::vector<uint> GetHarmonicBondIndices(uint atom_index) const; + + std::vector<uint> GetHarmonicAngleIndices(uint atom_index) const; + + std::vector<uint> GetUreyBradleyAngleIndices(uint atom_index) const; + + std::vector<uint> GetPeriodicDihedralIndices(uint atom_index) const; + + std::vector<uint> GetPeriodicImproperIndices(uint atom_index) const; + + std::vector<uint> GetHarmonicImproperIndices(uint atom_index) const; + + std::vector<uint> GetCMapIndices(uint atom_index) const; + + std::vector<uint> GetLJPairIndices(uint atom_index) const; + + std::vector<uint> GetDistanceConstraintIndices(uint atom_index) const; + + std::vector<uint> GetHarmonicPositionRestraintIndices(uint atom_index) const; + + std::vector<uint> GetHarmonicDistanceRestraintIndices(uint atom_index) const; + + uint GetNumAtoms() { return num_atoms_; } + + uint GetNumResidues() { return num_residues_; } + + uint GetNumHarmonicBonds() { return harmonic_bonds_.size(); } + + uint GetNumHarmonicAngles() { return harmonic_angles_.size(); } + + uint GetNumUreyBradleyAngles() { return urey_bradley_angles_.size(); } + + uint GetNumPeriodicDihedrals() { return periodic_dihedrals_.size(); } + + uint GetNumPeriodicImpropers() { return periodic_impropers_.size(); } + + uint GetNumHarmonicImpropers() { return harmonic_impropers_.size(); } + + uint GetNumCMaps() { return cmaps_.size(); } + + uint GetNumLJPairs() { return lj_pairs_.size(); } + + uint GetNumDistanceConstraints() { return distance_constraints_.size(); } + + uint GetNumPositionConstraints() { return position_constraints_.size(); } + + uint GetNumHarmonicPositionRestraints() { return harmonic_position_restraints_.size(); } + + uint GetNumHarmonicDistanceRestraints() { return harmonic_distance_restraints_.size();} + + uint GetNumExclusions() { return exclusions_.size(); } + + void Merge(TopologyPtr p); + + void SetEntityPositions(const geom::Vec3List& positions); + +private: + + ost::mol::EntityHandle ent_; + ost::mol::AtomHandleList atom_list_; + ost::mol::ResidueHandleList res_list_; + + uint num_atoms_; + uint num_residues_; + + std::map<long,uint> atom_index_mapper_; + std::map<long,uint> residue_index_mapper_; + std::vector<std::map<String,uint> > atom_name_mapper_; + + //fudge parameters for lj 1,4 pairs + Real fudge_qq_; + Real fudge_lj_; + + //single atom parameters + std::vector<Real> atom_masses_; + std::vector<Real> sigmas_; + std::vector<Real> epsilons_; + std::vector<Real> gbsa_radii_; + std::vector<Real> obc_scaling_; + std::vector<Real> charges_; + std::vector<uint> position_constraints_; + + //interactions with multiple atoms involved + std::vector<std::pair<Index<2>,std::vector<Real> > > harmonic_bonds_; + std::vector<std::pair<Index<3>,std::vector<Real> > > harmonic_angles_; + std::vector<std::pair<Index<3>,std::vector<Real> > > urey_bradley_angles_; + std::vector<std::pair<Index<4>,std::vector<Real> > > periodic_dihedrals_; + std::vector<std::pair<Index<4>,std::vector<Real> > > periodic_impropers_; + std::vector<std::pair<Index<4>,std::vector<Real> > > harmonic_impropers_; + std::vector<std::pair<Index<5>,std::vector<Real> > > cmaps_; + std::vector<std::pair<Index<2>,std::vector<Real> > > lj_pairs_; + std::vector<std::pair<Index<2>,std::vector<Real> > > distance_constraints_; + std::vector<Index<2> > exclusions_; + std::vector<std::pair<Index<1>,std::vector<Real> > > harmonic_position_restraints_; + std::vector<std::pair<Index<2>,std::vector<Real> > > harmonic_distance_restraints_; + + //the atoms of the interactions, that should be unique get tracked in here + //note, that this is waste of memory, needs better implementation + std::set<Index<2> > added_lj_pairs_; + std::set<Index<2> > added_distance_constraints_; + std::set<Index<2> > added_exclusions_; + +}; + + +}}} //ns + +#endif diff --git a/modules/mol/mm/src/topology_creator.cc b/modules/mol/mm/src/topology_creator.cc new file mode 100644 index 0000000000000000000000000000000000000000..71401b50b14f3873690f2227214fd32b51ad68d0 --- /dev/null +++ b/modules/mol/mm/src/topology_creator.cc @@ -0,0 +1,937 @@ +#include <ost/mol/mm/topology_creator.hh> +#include <ost/mol/mm/mm_modeller.hh> + +namespace ost{ namespace mol{ namespace mm{ + +TopologyPtr TopologyCreator::Create(const ost::mol::EntityHandle& handle, + const MMSettingsPtr settings){ + + if(settings->constrain_hangles == true && settings->constrain_hbonds == false){ + throw ost::Error("If hangles is true, hbonds must also be true in settings object!"); + } + + //make sure the input gets not modified + ost::mol::EntityHandle ent = handle.Copy(); + ost::mol::ResidueHandleList res_list = ent.GetResidueList(); + ost::mol::XCSEditor ed = ent.EditXCS(ost::mol::BUFFERED_EDIT); + + + //rename all the stuff to the gromacs naming... + MMModeller::AssignGromacsNaming(ent); + + + //even if not reconnected yet, it gets assumed, that + //peptide or nucleotide bonds are correctly set in the input entity + //to allow the identification and tagging of terminal residues + //note, that only nucleotides or aminoacids are allowed to build termini... + //this should be enough for most needs + + ost::mol::ResidueHandle next,prev; + bool n_ter,c_ter; + ost::mol::AtomHandle peptide_n,peptide_c,nucleotide_p,nucleotide_o; + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + + n_ter = false; + c_ter = false; + + peptide_n = i->FindAtom("N"); + nucleotide_p = i->FindAtom("P"); + + if(!peptide_n.IsValid() && !nucleotide_p.IsValid()) continue; + //in this case the residue is neither a peptide nor a nucleotide. + //There won't be a termini anyway... + + prev = i->GetPrev(); + next = i->GetNext(); + + if(!prev.IsValid()){ + n_ter = true; + } + else{ + peptide_c = prev.FindAtom("C"); + nucleotide_o = prev.FindAtom("O3"); + + if(!ost::mol::BondExists(peptide_n,peptide_c) && !ost::mol::BondExists(nucleotide_p,nucleotide_o)){ + n_ter = true; + } + } + + if(!next.IsValid()){ + c_ter = true; + } + else{ + peptide_n = next.FindAtom("N"); + peptide_c = i->FindAtom("C"); + nucleotide_p = next.FindAtom("P"); + nucleotide_o = i->FindAtom("O3"); + + if(!ost::mol::BondExists(peptide_n,peptide_c) && !ost::mol::BondExists(nucleotide_p,nucleotide_o)){ + c_ter = true; + } + } + + if(n_ter) i->SetBoolProp("n_ter",true); + if(c_ter) i->SetBoolProp("c_ter",true); + } + + + ForcefieldPtr ff = settings->forcefield; + if(!ff){ + throw ost::Error("You have to assign a valid forcefield to the settings object when creating a topology!"); + } + //The full parametrization procedure relies on the naming, that is force field specific + + ost::mol::BondHandleList bond_list = ent.GetBondList(); + ed.DeleteBonds(bond_list); + ed.UpdateICS(); + + if(settings->generate_disulfid_bonds){ + MMModeller::GenerateDisulfidBonds(ent); + } + + ff->AssignFFSpecificNames(ent); + + //we first generate the building blocks and directly construct hydrogens/termini and stuff + std::vector<BuildingBlockPtr> building_blocks; + + for(ost::mol::ResidueHandleList::iterator i = res_list.begin(); + i != res_list.end(); ++i){ + BuildingBlockPtr block = ff->GetBuildingBlock(i->GetName()); + HydrogenConstructorPtr hc = ff->GetHydrogenConstructor(i->GetName()); + if(hc){ + hc->ApplyOnBuildingBlock(block); + hc->ApplyOnResidue(*i,ed); + } + //check for n terminus + if(i->HasProp("n_ter")){ + String exception_name = ""; + if(settings->termini_exceptions->HasException(*i)){ + exception_name = settings->termini_exceptions->GetException(*i); + } + BlockModifierPtr bm = ff->GetNTerModifier(i->GetName(), exception_name); + if(bm){ + bm->ApplyOnBuildingBlock(block); + bm->ApplyOnResidue(*i,ed); + block->RemoveInteractionsToPrev(); + } + } + if(i->HasProp("c_ter")){ + String exception_name = ""; + if(settings->termini_exceptions->HasException(*i)){ + exception_name = settings->termini_exceptions->GetException(*i); + } + BlockModifierPtr bm = ff->GetCTerModifier(i->GetName(), exception_name); + if(bm){ + bm->ApplyOnBuildingBlock(block); + bm->ApplyOnResidue(*i,ed); + block->RemoveInteractionsToNext(); + } + } + block->Connect(*i,ed); + building_blocks.push_back(block); + } + + //The editor won't be needed anymore, let's update the internal coordinate system + ed.UpdateICS(); + + + String match_fail_info; + for(unsigned int i = 0; i < building_blocks.size(); ++i){ + if(!building_blocks[i]->Match(res_list[i], false, match_fail_info)){ + std::stringstream ss; + ss << "Residue "<< res_list[i].GetQualifiedName() << " does not match the force field "; + ss << "definition. "<<match_fail_info; + throw ost::Error(ss.str()); + } + } + + std::vector<Real> initial_masses(ent.GetAtomCount()); + + TopologyPtr top = TopologyPtr(new Topology(ent,initial_masses)); + ent = top->GetEntity(); + + //note, that we have to get the residue list again, since there is a new entity handle + //created when initializing the topology + res_list = ent.GetResidueList(); + ost::mol::AtomHandleList atom_list = ent.GetAtomList(); + + //let's extract atom specific informations + //extract information about single atoms + std::vector<std::vector<uint> > bound_to; + std::vector<String> atom_types; + std::vector<Real> atom_charges; + std::vector<String> atom_names; + std::vector<Real> atom_masses; + std::vector<String> atom_elements; + std::vector<String> residue_names_of_atoms; + ost::mol::AtomHandleList bonded_atoms; + std::vector<uint> temp; + //extract masses, types, charges and bondpartners + + ost::mol::ResidueHandle temp_res; + + for(ost::mol::AtomHandleList::iterator i = atom_list.begin(); + i!=atom_list.end();++i){ + temp_res = i->GetResidue(); + residue_names_of_atoms.push_back(temp_res.GetName()); + atom_elements.push_back(i->GetElement()); + atom_types.push_back(building_blocks[top->GetResidueIndex(temp_res)]->GetType(i->GetName())); + atom_charges.push_back(building_blocks[top->GetResidueIndex(temp_res)]->GetCharge(i->GetName())); + //atom_masses.push_back(building_blocks[top->GetResidueIndex(temp_res)]->GetMass(i->GetName())); + //if( atom_masses.back() != atom_masses.back() ){ + // atom_masses.back() = ff->GetMass(atom_types.back()); + //} + atom_masses.push_back(ff->GetMass(atom_types.back())); + bonded_atoms = i->GetBondPartners(); + temp.clear(); + for(ost::mol::AtomHandleList::iterator j = bonded_atoms.begin(); + j!=bonded_atoms.end();++j){ + temp.push_back(top->GetAtomIndex(*j)); + } + bound_to.push_back(temp); + } + + + //let's set the proper masses + top->SetMasses(atom_masses); + + + //we simply set all charges to zero if we want to kill the electrostatics + if(settings->kill_electrostatics){ + for(std::vector<Real>::iterator i = atom_charges.begin(); + i != atom_charges.end(); ++i){ + *i = 0; + } + } + + top->SetCharges(atom_charges); + + //the interaction read from the structure will be stored in here + std::set<Index<2> > bonds; + std::set<Index<3> > angles; + std::set<Index<4> > dihedrals; + std::set<Index<4> > impropers; + std::set<Index<5> > cmaps; + std::set<Index<2> > exclusions; + std::set<Index<2> > pairs_14; + std::set<Index<2> > distance_constraints; + //per atom parameters + std::vector<MMInteractionPtr> ljs; + std::vector<MMInteractionPtr> gbsa; + //extract all bonded interactions directly from the structure itself, + //except the impropers, cmaps and exclusions. Those two get read from the building + //blocks. + //Note, that the bonds build the basis to build angles and the angles + //build the basis to build dihedrals... so we have to extract bonds + //even when only dihedrals have to be added. + //Another special case is when nonbonded terms have to be added. + //They often exclude interactions originating from closely bonded + //atoms. We will use the bonds, angles and dihedrals later on to + //define these closely bonded atoms, so if nonbonded terms have to + //added, we also need to get the bonds, angles and dihedrals. + if(settings->add_bonds || settings->add_angles || + settings->add_dihedrals || settings->add_nonbonded){ + //build all bonds + for(uint i=0 ; i<bound_to.size() ;++i){ + for(uint j = 0; j<bound_to[i].size(); ++j){ + bonds.insert(Index<2>(std::min(i,bound_to[i][j]),std::max(i,bound_to[i][j]))); + } + } + } + if(settings->add_angles || settings->add_dihedrals || + settings->add_nonbonded){ + //build all angles + for(std::set<Index<2> >::iterator i = bonds.begin(); + i!=bonds.end();++i){ + uint atom_1 = (*i)[0]; + uint atom_2 = (*i)[1]; + + for(std::vector<uint>::iterator j = bound_to[atom_1].begin(); + j!=bound_to[atom_1].end(); ++j){ + if((*j) != atom_2){ + angles.insert(Index<3>(std::min((*j),atom_2),atom_1,std::max((*j),atom_2))); + } + } + for(std::vector<uint>::iterator j = bound_to[atom_2].begin(); + j!=bound_to[atom_2].end(); ++j){ + if((*j) != atom_1){ + angles.insert(Index<3>(std::min((*j),atom_1),atom_2,std::max((*j),atom_1))); + } + } + } + } + if(settings->add_dihedrals || settings->add_nonbonded){ + //build all dihedrals + for(std::set<Index<3> >::iterator i = angles.begin(); + i!=angles.end();++i){ + uint atom_1 = (*i)[0]; + uint atom_2 = (*i)[1]; + uint atom_3 = (*i)[2]; + for(std::vector<uint>::iterator j = bound_to[atom_1].begin(); + j!=bound_to[atom_1].end();++j){ + if((*j)!=atom_2){ + if((*j)<atom_3) dihedrals.insert(Index<4>(*j,atom_1,atom_2,atom_3)); + else dihedrals.insert(Index<4>(atom_3,atom_2,atom_1,*j)); + } + } + for(std::vector<uint>::iterator j = bound_to[atom_3].begin(); + j!=bound_to[atom_3].end();++j){ + if((*j)!=atom_2){ + if((*j)<atom_1) dihedrals.insert(Index<4>(*j,atom_3,atom_2,atom_1)); + else dihedrals.insert(Index<4>(atom_1,atom_2,atom_3,*j)); + } + } + } + } + //impropers exclusions and cmaps get read from residuetemplates! + std::vector<MMInteractionPtr> interaction_list; + std::vector<String> interaction_atom_names; + + if(settings->add_impropers){ + for(uint i = 0; i < building_blocks.size(); ++i){ + interaction_list = building_blocks[i]->GetImpropers(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + interaction_atom_names = (*j)->GetNames(); + Index<4> improper_index; + for(uint k = 0; k < 4; ++k){ + improper_index[k] = top->GetAtomIndex(i,interaction_atom_names[k]); + } + impropers.insert(improper_index); + } + } + } + + if(settings->add_cmaps){ + for(uint i = 0; i < building_blocks.size(); ++i){ + interaction_list = building_blocks[i]->GetCMaps(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + interaction_atom_names = (*j)->GetNames(); + Index<5> cmap_index; + for(uint k = 0; k < 5; ++k){ + cmap_index[k] = top->GetAtomIndex(i,interaction_atom_names[k]); + } + cmaps.insert(cmap_index); + } + } + } + + if(settings->add_nonbonded && settings->add_exclusions){ + for(uint i = 0; i < building_blocks.size(); ++i){ + interaction_list = building_blocks[i]->GetExclusions(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i,interaction_atom_names[0]); + uint two = top->GetAtomIndex(i,interaction_atom_names[1]); + exclusions.insert(Index<2>(std::min(one,two),std::max(one,two))); + } + } + } + if(settings->add_nonbonded){ + + //find exclusions and excpetions based on connectivity + //add exclusions using previously extracted bonds => 1,2 interactions + for(std::set<Index<2> >::iterator i = bonds.begin(); + i!=bonds.end(); ++i){ + exclusions.insert(*i); + } + //add exclusions using previously extracted angles => 1,3 interactions + for(std::set<Index<3> >::iterator i = angles.begin(); + i!=angles.end(); ++i){ + exclusions.insert(Index<2>((*i)[0],(*i)[2])); + } + //add exclusions using previously extracted dihedrals => 1,4 interactions + for(std::set<Index<4> >::iterator i = dihedrals.begin(); + i!=dihedrals.end(); ++i){ + pairs_14.insert(Index<2>((*i)[0],(*i)[3])); + } + + //remove all exclusions from the 1,4 interactions + for(std::set<Index<2> >::iterator i = exclusions.begin(); + i != exclusions.end(); ++i){ + pairs_14.erase(*i); + } + } + + //we will need this goddamn variable in a lot of places... + std::vector<Real> parameters; + + + //add constraints from building blocks + //note, that the constraints are in some cases parametrized. + //If there is no constraint distance specified, the actual distance + //between the corresponding atoms is taken. + //if there are several constraints on the same atom pair, + //only the first is added to avoid contradicting constraints + for(uint i = 0; i < building_blocks.size(); ++i){ + interaction_list = building_blocks[i]->GetConstraints(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + Index<2> index(std::min(one,two),std::max(one,two)); + //we don't want contradicting constraints! + if(distance_constraints.find(index) != distance_constraints.end()) continue; + distance_constraints.insert(index); + Real distance; + if((*j)->IsParametrized()){ + parameters = (*j)->GetParam(); + distance = parameters[0]; + } + else distance = geom::Distance(atom_list[one].GetPos(),atom_list[two].GetPos())/10; + top->AddDistanceConstraint(one,two,distance); + } + } + + //add distance constrains given the corresponding settings + if(settings->constrain_bonds || settings->constrain_hbonds || settings->rigid_water){ + for(std::set<Index<2> >::iterator i = bonds.begin(); + i != bonds.end(); ++i){ + if(settings->constrain_bonds){ + if(distance_constraints.find(*i) != distance_constraints.end()) continue; + distance_constraints.insert(*i); + Real distance; + if(settings->ideal_bond_length_constraints){ + MMInteractionPtr bond_ptr = ff->GetBond(atom_types[(*i)[0]],atom_types[(*i)[1]]); + parameters = bond_ptr->GetParam(); + distance = parameters[0]; + } + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[1]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[1],distance); + continue; + } + if(settings->constrain_hbonds){ + //if(atom_elements[(*i)[0]] == "H" || atom_elements[(*i)[1]] == "H"){ + if(atom_masses[(*i)[0]] < 1.1 || atom_masses[(*i)[1]] < 1.1){ + if(distance_constraints.find(*i) != distance_constraints.end()) continue; + distance_constraints.insert(*i); + Real distance; + if(settings->ideal_bond_length_constraints){ + MMInteractionPtr bond_ptr = ff->GetBond(atom_types[(*i)[0]],atom_types[(*i)[1]]); + parameters = bond_ptr->GetParam(); + distance = parameters[0]; + } + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[1]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[1],distance); + continue; + } + } + if(settings->rigid_water){ + if(residue_names_of_atoms[(*i)[0]] == "SOL" || residue_names_of_atoms[(*i)[1]] == "SOL"){ + if(distance_constraints.find(*i) != distance_constraints.end()) continue; + distance_constraints.insert(*i); + Real distance; + if(settings->ideal_bond_length_constraints) distance = 0.09572; //OH bond length in water in CHARMM forcefield... + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[1]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[1],distance); + continue; + } + } + } + } + + //set angle constraints given the corresponding settings + std::set<Index<3> > constrained_angles; + if(settings->rigid_water){ + for(std::set<Index<3> >::iterator i = angles.begin(); + i != angles.end(); ++i){ + if(residue_names_of_atoms[(*i)[0]] == "SOL" || residue_names_of_atoms[(*i)[0]] == "SOL" || + residue_names_of_atoms[(*i)[2]] == "SOL"){ + //even for ideal_bond_length_constraints, we calculate the ideal angle every time... + //could be replaced... + Real distance; + if(settings->ideal_bond_length_constraints) distance = 0.15139; //HH distance taken from CHARMM + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[2]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[2],distance); + constrained_angles.insert(*i); + } + } + } + + if(settings->constrain_hangles){ + for(std::set<Index<3> >::iterator i = angles.begin(); + i != angles.end(); ++i){ + if(atom_masses[(*i)[0]] < 1.1 && atom_masses[(*i)[2]] < 1.1){ + //two hydrogens... + if(constrained_angles.find(*i) != constrained_angles.end()) continue; + Real distance; + if(settings->ideal_bond_length_constraints){ + MMInteractionPtr bond_one = ff->GetBond(atom_types[(*i)[0]],atom_types[(*i)[1]]); + MMInteractionPtr bond_two = ff->GetBond(atom_types[(*i)[1]],atom_types[(*i)[2]]); + MMInteractionPtr angle = ff->GetAngle(atom_types[(*i)[0]],atom_types[(*i)[1]],atom_types[(*i)[2]]); + std::vector<Real> parameters; + Real l1,l2,a; + parameters = bond_one->GetParam(); + l1 = parameters[0]; + parameters = bond_two->GetParam(); + l2 = parameters[0]; + parameters = angle->GetParam(); + a = parameters[0]; + distance = sqrt(l1*l1+l2*l2-2*l1*l2*cos(a)); + } + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[2]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[2],distance); + constrained_angles.insert(*i); + continue; + } + + if(atom_masses[(*i)[1]] > 15.0 && atom_masses[(*i)[1]] < 17.0){ + //central atom is an oxygen + if(atom_masses[(*i)[0]] < 1.1 || atom_masses[(*i)[2]] < 1.1){ + //a hydrogen is attached to the oxygen... + if(constrained_angles.find(*i) != constrained_angles.end()) continue; + Real distance; + if(settings->ideal_bond_length_constraints){ + MMInteractionPtr bond_one = ff->GetBond(atom_types[(*i)[0]],atom_types[(*i)[1]]); + MMInteractionPtr bond_two = ff->GetBond(atom_types[(*i)[1]],atom_types[(*i)[2]]); + MMInteractionPtr angle = ff->GetAngle(atom_types[(*i)[0]],atom_types[(*i)[1]],atom_types[(*i)[2]]); + std::vector<Real> parameters; + Real l1,l2,a; + parameters = bond_one->GetParam(); + l1 = parameters[0]; + parameters = bond_two->GetParam(); + l2 = parameters[0]; + parameters = angle->GetParam(); + a = parameters[0]; + distance = sqrt(l1*l1+l2*l2-2*l1*l2*cos(a)); + } + else distance = geom::Distance(atom_list[(*i)[0]].GetPos(),atom_list[(*i)[2]].GetPos())/10; + top->AddDistanceConstraint((*i)[0],(*i)[2],distance); + constrained_angles.insert(*i); + continue; + } + } + } + } + + //remove all constraints from the bonds and angles + for(std::set<Index<2> >::iterator i = distance_constraints.begin(); + i != distance_constraints.end(); ++i){ + bonds.erase(*i); + } + + for(std::set<Index<3> >::iterator i = constrained_angles.begin(); + i!= constrained_angles.end(); ++i){ + angles.erase(*i); + } + + + //the force definitions from the forcefield can be overwritten by parameters + //defined in the residue building blocks. + //We therefore check which forces have been defined in the building blocks + //and don't search them any more in the forcefield forces. + std::vector<String> types; + if(settings->add_bonds){ + //handle bonds + for(uint i = 0; i < top->GetNumResidues(); ++i){ + interaction_list = building_blocks[i]->GetBonds(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + if((*j)->IsParametrized()){ + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + Index<2> bond_index(std::min(one,two),std::max(one,two)); + bonds.erase(bond_index); + //There are only harmonic bonds supported + parameters = (*j)->GetParam(); + top->AddHarmonicBond(one,two,parameters[0],parameters[1]); + } + } + } + //add pointers of bond definitions, that are not already parametrized + //in the building blocks + for(std::set<Index<2> >::iterator i = bonds.begin(); + i!=bonds.end(); ++i){ + + MMInteractionPtr bond_ptr; + try{ + bond_ptr = ff->GetBond(atom_types[(*i)[0]],atom_types[(*i)[1]]); + } catch(ost::Error& e){ + if(settings->strict_interactions){ + std::stringstream ss; + ss << "Failed to parametrize bond between: " << atom_list[(*i)[0]]; + ss << " and "<<atom_list[(*i)[1]] << ". "; + ss << "To ignore these things, set strict_interactions in the settings"; + ss << " object to False (not recommended)."; + throw ost::Error(ss.str()); + } + continue; // ignore it and continue with next interaction + } + + parameters = bond_ptr->GetParam(); + top->AddHarmonicBond((*i)[0],(*i)[1],parameters[0],parameters[1]); + } + } + + if(settings->add_angles){ + //handle angles + for(uint i = 0; i < top->GetNumResidues(); ++i){ + interaction_list = building_blocks[i]->GetAngles(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + if((*j)->IsParametrized()){ + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + uint three = top->GetAtomIndex(i, interaction_atom_names[2]); + Index<3> angle_index(std::min(one,three),two,std::max(one,three)); + if(angles.find(angle_index) == angles.end()){ + std::stringstream ss; + ss << "Building block for residue " << res_list[i].GetQualifiedName(); + ss << " defines angle, that doesn't exist!"; + throw ost::Error(ss.str()); + } + angles.erase(angle_index); + parameters = (*j)->GetParam(); + switch((*j)->GetFuncType()){ + case HarmonicAngle:{ + top->AddHarmonicAngle(angle_index[0],angle_index[1],angle_index[2], + parameters[0], parameters[1]); + break; + } + case UreyBradleyAngle:{ + top->AddUreyBradleyAngle(angle_index[0],angle_index[1],angle_index[2], + parameters[0], parameters[1], parameters[2], + parameters[3]); + break; + } + default:{ + throw ost::Error("Observed unknown function type for angle interaction!"); + } + } + } + } + } + //add pointers of angle definitions, that are not already parametrized + //in the building blocks + for(std::set<Index<3> >::iterator i = angles.begin(); + i!=angles.end(); ++i){ + + MMInteractionPtr angle_ptr; + try{ + angle_ptr = ff->GetAngle(atom_types[(*i)[0]], + atom_types[(*i)[1]], + atom_types[(*i)[2]]); + } catch(ost::Error& e){ + if(settings->strict_interactions){ + std::stringstream ss; + ss << "Failed to parametrize angle between: " << atom_list[(*i)[0]]; + ss << ", "<<atom_list[(*i)[1]] << " and " << atom_list[(*i)[2]] << "."; + ss << "To ignore these things, set strict_interactions in the settings"; + ss << " object to False (not recommended)."; + throw ost::Error(ss.str()); + } + continue; // ignore it and continue with next interaction + } + + parameters = angle_ptr->GetParam(); + switch(angle_ptr->GetFuncType()){ + case HarmonicAngle:{ + top->AddHarmonicAngle((*i)[0],(*i)[1],(*i)[2], + parameters[0],parameters[1]); + break; + } + case UreyBradleyAngle:{ + top->AddUreyBradleyAngle((*i)[0],(*i)[1],(*i)[2], + parameters[0],parameters[1], + parameters[2],parameters[3]); + break; + } + default:{ + throw ost::Error("Observed invalid function type for angle interaction!"); + } + } + } + } + + if(settings->add_dihedrals){ + //handle dihedrals + for(uint i = 0; i < top->GetNumResidues(); ++i){ + interaction_list = building_blocks[i]->GetDihedrals(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + if((*j)->IsParametrized()){ + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + uint three = top->GetAtomIndex(i, interaction_atom_names[2]); + uint four = top->GetAtomIndex(i, interaction_atom_names[3]); + Index<4> dihedral_index; + if(one<four){ + dihedral_index[0] = one; + dihedral_index[1] = two; + dihedral_index[2] = three; + dihedral_index[3] = four; + } + else{ + dihedral_index[0] = four; + dihedral_index[1] = three; + dihedral_index[2] = two; + dihedral_index[3] = one; + } + if(dihedrals.find(dihedral_index) == dihedrals.end()){ + std::stringstream ss; + ss << "Building block for residue " << res_list[i].GetQualifiedName(); + ss << "defines dihedral, that doesn't exist!"; + throw ost::Error(ss.str()); + } + dihedrals.erase(dihedral_index); + //only periodic dihedrals are supported... + parameters = (*j)->GetParam(); + top->AddPeriodicDihedral(one,two,three,four, + parameters[0],parameters[1],parameters[2]); + } + } + } + + //add pointers of dihedrals definitions, that are not already parametrized + //in the building blocks + for(std::set<Index<4> >::iterator i = dihedrals.begin(); + i!=dihedrals.end(); ++i){ + + std::vector<MMInteractionPtr> dihedral_ptr; + + try{ + dihedral_ptr = ff->GetDihedrals(atom_types[(*i)[0]], + atom_types[(*i)[1]], + atom_types[(*i)[2]], + atom_types[(*i)[3]]); + } catch(ost::Error& e){ + if(settings->strict_interactions){ + std::stringstream ss; + ss << "Failed to parametrize dihedral between: " << atom_list[(*i)[0]]; + ss << ", "<<atom_list[(*i)[1]] << ", " << atom_list[(*i)[2]] << " and "; + ss << atom_list[(*i)[3]] << "."; + ss << "To ignore these things, set strict_interactions in the settings"; + ss << " object to False (not recommended)."; + throw ost::Error(ss.str()); + } + continue; // ignore it and continue with next interaction + } + + for(std::vector<MMInteractionPtr>::iterator j = dihedral_ptr.begin(); + j != dihedral_ptr.end(); ++j){ + parameters = (*j)->GetParam(); + top->AddPeriodicDihedral((*i)[0],(*i)[1],(*i)[2],(*i)[3], + parameters[0],parameters[1],parameters[2]); + } + } + } + + if(settings->add_impropers){ + //handle impropers + for(uint i = 0; i < building_blocks.size(); ++i){ + interaction_list = building_blocks[i]->GetImpropers(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + if((*j)->IsParametrized()){ + //we do not have to care about the ordering, since we extracted the + //impropers from the building block => they will have the same ordering + //anyway (or at least hopefully ;) + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + uint three = top->GetAtomIndex(i, interaction_atom_names[2]); + uint four = top->GetAtomIndex(i, interaction_atom_names[3]); + Index<4> improper_index(one,two,three,four); + impropers.erase(improper_index); + parameters = (*j)->GetParam(); + switch((*j)->GetFuncType()){ + case PeriodicImproper:{ + top->AddPeriodicImproper(one,two,three,four, + parameters[0],parameters[1],parameters[2]); + break; + } + case HarmonicImproper:{ + top->AddHarmonicImproper(one,two,three,four, + parameters[0],parameters[1]); + break; + } + default:{ + throw ost::Error("Observed invalid function type when adding improper interaction!"); + } + } + } + } + } + //add pointers of improper definitions, that are not already parametrized + //in the building blocks + + for(std::set<Index<4> >::iterator i = impropers.begin(); + i!=impropers.end(); ++i){ + + std::vector<MMInteractionPtr> improper_ptr; + + try{ + improper_ptr = ff->GetImpropers(atom_types[(*i)[0]], + atom_types[(*i)[1]], + atom_types[(*i)[2]], + atom_types[(*i)[3]]); + } catch(ost::Error& e){ + if(settings->strict_interactions){ + std::stringstream ss; + ss << "Failed to parametrize improper between: " << atom_list[(*i)[0]]; + ss << ", "<<atom_list[(*i)[1]] << ", " << atom_list[(*i)[2]] << " and "; + ss << atom_list[(*i)[3]] << "."; + ss << "To ignore these things, set strict_interactions in the settings"; + ss << " object to False (not recommended)."; + throw ost::Error(ss.str()); + } + continue; // ignore it and continue with next interaction + } + + for(std::vector<MMInteractionPtr>::iterator j = improper_ptr.begin(); + j != improper_ptr.end(); ++j){ + parameters = (*j)->GetParam(); + switch((*j)->GetFuncType()){ + case PeriodicImproper:{ + top->AddPeriodicImproper((*i)[0],(*i)[1],(*i)[2],(*i)[3], + parameters[0],parameters[1],parameters[2]); + break; + } + case HarmonicImproper:{ + top->AddHarmonicImproper((*i)[0],(*i)[1],(*i)[2],(*i)[3], + parameters[0],parameters[1]); + break; + } + default:{ + throw ost::Error("Observed invalid function type when adding improper interaction!"); + } + } + } + } + } + + if(settings->add_cmaps){ + //handle cmaps + for(uint i = 0; i < top->GetNumResidues(); ++i){ + interaction_list = building_blocks[i]->GetCMaps(); + for(std::vector<MMInteractionPtr>::iterator j = interaction_list.begin(); + j != interaction_list.end(); ++j){ + if((*j)->IsParametrized()){ + //we do not have to care about the ordering, since we extracted the + //cmaps from the building block => they will have the same ordering + //anyway + interaction_atom_names = (*j)->GetNames(); + uint one = top->GetAtomIndex(i, interaction_atom_names[0]); + uint two = top->GetAtomIndex(i, interaction_atom_names[1]); + uint three = top->GetAtomIndex(i, interaction_atom_names[2]); + uint four = top->GetAtomIndex(i, interaction_atom_names[3]); + uint five = top->GetAtomIndex(i, interaction_atom_names[4]); + Index<5> cmap_index(one,two,three,four,five); + cmaps.erase(cmap_index); + parameters = (*j)->GetParam(); + int dimension = int(parameters[0]); + parameters.erase(parameters.begin()); + top->AddCMap(cmap_index[0],cmap_index[1],cmap_index[2],cmap_index[3], + cmap_index[4],dimension,parameters); + } + } + } + + //add pointers of cmap definitions, that are not already parametrized + //in the building blocks + for(std::set<Index<5> >::iterator i = cmaps.begin(); + i!=cmaps.end(); ++i){ + + MMInteractionPtr cmap_ptr; + + try{ + cmap_ptr = ff->GetCMap(atom_types[(*i)[0]], + atom_types[(*i)[1]], + atom_types[(*i)[2]], + atom_types[(*i)[3]], + atom_types[(*i)[4]]); + } catch(ost::Error& e){ + if(settings->strict_interactions){ + std::stringstream ss; + ss << "Failed to parametrize cmap between: " << atom_list[(*i)[0]]; + ss << ", "<<atom_list[(*i)[1]] << ", " << atom_list[(*i)[2]] << ", "; + ss << atom_list[(*i)[3]] << " and " << atom_list[(*i)[4]] << "."; + ss << "To ignore these things, set strict_interactions in the settings"; + ss << " object to False (not recommended)."; + throw ost::Error(ss.str()); + } + continue; // ignore it and continue with next interaction + } + parameters = cmap_ptr->GetParam(); + int dimension = int(parameters[0]); + parameters.erase(parameters.begin()); + top->AddCMap((*i)[0],(*i)[1],(*i)[2],(*i)[3],(*i)[4],dimension,parameters); + } + } + + if(settings->add_nonbonded){ + + MMInteractionPtr lj_interaction; + std::vector<Real> sigmas; + std::vector<Real> epsilons; + + for(std::vector<String>::iterator i = atom_types.begin(); + i != atom_types.end(); ++i){ + lj_interaction = ff->GetLJ(*i); + if(!lj_interaction){ + std::stringstream ss; + ss << "Failed to find LJ parametrization for type \""<<*i<<"\""; + ss << " in given forcefield!"; + throw ost::Error(ss.str()); + } + parameters = lj_interaction->GetParam(); + sigmas.push_back(parameters[0]); + epsilons.push_back(parameters[1]); + } + top->SetSigmas(sigmas); + top->SetEpsilons(epsilons); + //take care of the 1-4 interactions + for(std::set<Index<2> >::iterator i = pairs_14.begin(); + i != pairs_14.end(); ++i){ + //we can be sure, that the parameters are valid, since we found all single + //parameters. The forcefield can therefore build the new parametrization with + //the combination rules... Except: gen_pairs_ is set to no, but then an error + // is thrown anyway + lj_interaction = ff->GetLJ(atom_types[(*i)[0]], + atom_types[(*i)[1]], + true); + parameters = lj_interaction->GetParam(); + top->AddLJPair((*i)[0],(*i)[1],parameters[0],parameters[1]); + } + //take care of the exclusions + for(std::set<Index<2> >::iterator i = exclusions.begin(); + i != exclusions.end(); ++i){ + top->AddExclusion((*i)[0],(*i)[1]); + } + } + if(settings->add_gbsa){ + std::vector<Real> radii; + std::vector<Real> scaling; + for(uint i = 0; i < top->GetNumAtoms(); ++i){ + MMInteractionPtr gbsa_ptr = ff->GetImplicitGenborn(atom_types[i]); + if(!gbsa_ptr){ + std::stringstream ss; + ss << "Structure contains atom of type " << types[i] << " which is not"; + ss << "parametrized in the forcefield!"<<std::endl; + throw ost::Error(ss.str()); + } + parameters = gbsa_ptr->GetParam(); + radii.push_back(parameters[0]); + scaling.push_back(parameters[1]); + } + top->SetGBSARadii(radii); + top->SetOBCScalings(scaling); + } + + top->SetFudgeQQ(ff->GetFudgeQQ()); + top->SetFudgeLJ(ff->GetFudgeLJ()); + + + return top; + +} + +}}}//ns diff --git a/modules/mol/mm/src/topology_creator.hh b/modules/mol/mm/src/topology_creator.hh new file mode 100644 index 0000000000000000000000000000000000000000..1d719a4144b7a3571e8bb2e2764bf4327a2d06e2 --- /dev/null +++ b/modules/mol/mm/src/topology_creator.hh @@ -0,0 +1,40 @@ +#ifndef OST_TOPOLOGY_CREATOR_HH +#define OST_TOPOLOGY_CREATOR_HH + +#include <OpenMM.h> + +#include <vector> +#include <map> +#include <set> +#include <math.h> + +#include <ost/message.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/block_modifiers.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/mm_modeller.hh> +#include <ost/mol/mm/index.hh> +#include <ost/mol/mm/topology.hh> + + +namespace ost { namespace mol{ namespace mm{ + +class TopologyCreator; +typedef boost::shared_ptr<TopologyCreator> TopologyCreatorPtr; + +class TopologyCreator { +public: + static TopologyPtr Create(const ost::mol::EntityHandle& ent, + const MMSettingsPtr settings); + +}; + + +}}}//ns + +#endif \ No newline at end of file diff --git a/modules/mol/mm/tests/1CRN.pdb b/modules/mol/mm/tests/1CRN.pdb new file mode 100644 index 0000000000000000000000000000000000000000..13ca618d438ae60a55a8ce1c532cd23bf545e200 --- /dev/null +++ b/modules/mol/mm/tests/1CRN.pdb @@ -0,0 +1,329 @@ +ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N +ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C +ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C +ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O +ATOM 5 CB THR A 1 18.170 12.703 5.337 1.00 13.02 C +ATOM 6 OG1 THR A 1 19.334 12.829 4.463 1.00 15.06 O +ATOM 7 CG2 THR A 1 18.150 11.546 6.304 1.00 14.23 C +ATOM 8 N THR A 2 15.115 11.555 5.265 1.00 7.81 N +ATOM 9 CA THR A 2 13.856 11.469 6.066 1.00 8.31 C +ATOM 10 C THR A 2 14.164 10.785 7.379 1.00 5.80 C +ATOM 11 O THR A 2 14.993 9.862 7.443 1.00 6.94 O +ATOM 12 CB THR A 2 12.732 10.711 5.261 1.00 10.32 C +ATOM 13 OG1 THR A 2 13.308 9.439 4.926 1.00 12.81 O +ATOM 14 CG2 THR A 2 12.484 11.442 3.895 1.00 11.90 C +ATOM 15 N CYS A 3 13.488 11.241 8.417 1.00 5.24 N +ATOM 16 CA CYS A 3 13.660 10.707 9.787 1.00 5.39 C +ATOM 17 C CYS A 3 12.269 10.431 10.323 1.00 4.45 C +ATOM 18 O CYS A 3 11.393 11.308 10.185 1.00 6.54 O +ATOM 19 CB CYS A 3 14.368 11.748 10.691 1.00 5.99 C +ATOM 20 SG CYS A 3 15.885 12.426 10.016 1.00 7.01 S +ATOM 21 N CYS A 4 12.019 9.272 10.928 1.00 3.90 N +ATOM 22 CA CYS A 4 10.646 8.991 11.408 1.00 4.24 C +ATOM 23 C CYS A 4 10.654 8.793 12.919 1.00 3.72 C +ATOM 24 O CYS A 4 11.659 8.296 13.491 1.00 5.30 O +ATOM 25 CB CYS A 4 10.057 7.752 10.682 1.00 4.41 C +ATOM 26 SG CYS A 4 9.837 8.018 8.904 1.00 4.72 S +ATOM 27 N PRO A 5 9.561 9.108 13.563 1.00 3.96 N +ATOM 28 CA PRO A 5 9.448 9.034 15.012 1.00 4.25 C +ATOM 29 C PRO A 5 9.288 7.670 15.606 1.00 4.96 C +ATOM 30 O PRO A 5 9.490 7.519 16.819 1.00 7.44 O +ATOM 31 CB PRO A 5 8.230 9.957 15.345 1.00 5.11 C +ATOM 32 CG PRO A 5 7.338 9.786 14.114 1.00 5.24 C +ATOM 33 CD PRO A 5 8.366 9.804 12.958 1.00 5.20 C +ATOM 34 N SER A 6 8.875 6.686 14.796 1.00 4.83 N +ATOM 35 CA SER A 6 8.673 5.314 15.279 1.00 4.45 C +ATOM 36 C SER A 6 8.753 4.376 14.083 1.00 4.99 C +ATOM 37 O SER A 6 8.726 4.858 12.923 1.00 4.61 O +ATOM 38 CB SER A 6 7.340 5.121 15.996 1.00 5.05 C +ATOM 39 OG SER A 6 6.274 5.220 15.031 1.00 6.39 O +ATOM 40 N ILE A 7 8.881 3.075 14.358 1.00 4.94 N +ATOM 41 CA ILE A 7 8.912 2.083 13.258 1.00 6.33 C +ATOM 42 C ILE A 7 7.581 2.090 12.506 1.00 5.32 C +ATOM 43 O ILE A 7 7.670 2.031 11.245 1.00 6.85 O +ATOM 44 CB ILE A 7 9.207 0.677 13.924 1.00 8.43 C +ATOM 45 CG1 ILE A 7 10.714 0.702 14.312 1.00 9.78 C +ATOM 46 CG2 ILE A 7 8.811 -0.477 12.969 1.00 11.70 C +ATOM 47 CD1 ILE A 7 11.185 -0.516 15.142 1.00 9.92 C +ATOM 48 N VAL A 8 6.458 2.162 13.159 1.00 5.02 N +ATOM 49 CA VAL A 8 5.145 2.209 12.453 1.00 6.93 C +ATOM 50 C VAL A 8 5.115 3.379 11.461 1.00 5.39 C +ATOM 51 O VAL A 8 4.664 3.268 10.343 1.00 6.30 O +ATOM 52 CB VAL A 8 3.995 2.354 13.478 1.00 9.64 C +ATOM 53 CG1 VAL A 8 2.716 2.891 12.869 1.00 13.85 C +ATOM 54 CG2 VAL A 8 3.758 1.032 14.208 1.00 11.97 C +ATOM 55 N ALA A 9 5.606 4.546 11.941 1.00 3.73 N +ATOM 56 CA ALA A 9 5.598 5.767 11.082 1.00 3.56 C +ATOM 57 C ALA A 9 6.441 5.527 9.850 1.00 4.13 C +ATOM 58 O ALA A 9 6.052 5.933 8.744 1.00 4.36 O +ATOM 59 CB ALA A 9 6.022 6.977 11.891 1.00 4.80 C +ATOM 60 N ARG A 10 7.647 4.909 10.005 1.00 3.73 N +ATOM 61 CA ARG A 10 8.496 4.609 8.837 1.00 3.38 C +ATOM 62 C ARG A 10 7.798 3.609 7.876 1.00 3.47 C +ATOM 63 O ARG A 10 7.878 3.778 6.651 1.00 4.67 O +ATOM 64 CB ARG A 10 9.847 4.020 9.305 1.00 3.95 C +ATOM 65 CG ARG A 10 10.752 3.607 8.149 1.00 4.55 C +ATOM 66 CD ARG A 10 11.226 4.699 7.244 1.00 5.89 C +ATOM 67 NE ARG A 10 12.143 5.571 8.035 1.00 6.20 N +ATOM 68 CZ ARG A 10 12.758 6.609 7.443 1.00 7.52 C +ATOM 69 NH1 ARG A 10 12.539 6.932 6.158 1.00 10.68 N +ATOM 70 NH2 ARG A 10 13.601 7.322 8.202 1.00 9.48 N +ATOM 71 N SER A 11 7.186 2.582 8.445 1.00 5.19 N +ATOM 72 CA SER A 11 6.500 1.584 7.565 1.00 4.60 C +ATOM 73 C SER A 11 5.382 2.313 6.773 1.00 4.84 C +ATOM 74 O SER A 11 5.213 2.016 5.557 1.00 5.84 O +ATOM 75 CB SER A 11 5.908 0.462 8.400 1.00 5.91 C +ATOM 76 OG SER A 11 6.990 -0.272 9.012 1.00 8.38 O +ATOM 77 N ASN A 12 4.648 3.182 7.446 1.00 3.54 N +ATOM 78 CA ASN A 12 3.545 3.935 6.751 1.00 4.57 C +ATOM 79 C ASN A 12 4.107 4.851 5.691 1.00 4.14 C +ATOM 80 O ASN A 12 3.536 5.001 4.617 1.00 5.52 O +ATOM 81 CB ASN A 12 2.663 4.677 7.748 1.00 6.42 C +ATOM 82 CG ASN A 12 1.802 3.735 8.610 1.00 8.25 C +ATOM 83 OD1 ASN A 12 1.567 2.613 8.165 1.00 12.72 O +ATOM 84 ND2 ASN A 12 1.394 4.252 9.767 1.00 9.92 N +ATOM 85 N PHE A 13 5.259 5.498 6.005 1.00 3.43 N +ATOM 86 CA PHE A 13 5.929 6.358 5.055 1.00 3.49 C +ATOM 87 C PHE A 13 6.304 5.578 3.799 1.00 3.40 C +ATOM 88 O PHE A 13 6.136 6.072 2.653 1.00 4.07 O +ATOM 89 CB PHE A 13 7.183 6.994 5.754 1.00 5.48 C +ATOM 90 CG PHE A 13 7.884 8.006 4.883 1.00 5.57 C +ATOM 91 CD1 PHE A 13 8.906 7.586 4.027 1.00 6.99 C +ATOM 92 CD2 PHE A 13 7.532 9.373 4.983 1.00 6.52 C +ATOM 93 CE1 PHE A 13 9.560 8.539 3.194 1.00 8.20 C +ATOM 94 CE2 PHE A 13 8.176 10.281 4.145 1.00 6.34 C +ATOM 95 CZ PHE A 13 9.141 9.845 3.292 1.00 6.84 C +ATOM 96 N ASN A 14 6.900 4.390 3.989 1.00 3.64 N +ATOM 97 CA ASN A 14 7.331 3.607 2.791 1.00 4.31 C +ATOM 98 C ASN A 14 6.116 3.210 1.915 1.00 3.98 C +ATOM 99 O ASN A 14 6.240 3.144 0.684 1.00 6.22 O +ATOM 100 CB ASN A 14 8.145 2.404 3.240 1.00 5.81 C +ATOM 101 CG ASN A 14 9.555 2.856 3.730 1.00 6.82 C +ATOM 102 OD1 ASN A 14 10.013 3.895 3.323 1.00 9.43 O +ATOM 103 ND2 ASN A 14 10.120 1.956 4.539 1.00 8.21 N +ATOM 104 N VAL A 15 4.993 2.927 2.571 1.00 3.76 N +ATOM 105 CA VAL A 15 3.782 2.599 1.742 1.00 3.98 C +ATOM 106 C VAL A 15 3.296 3.871 1.004 1.00 3.80 C +ATOM 107 O VAL A 15 2.947 3.817 -0.189 1.00 4.85 O +ATOM 108 CB VAL A 15 2.698 1.953 2.608 1.00 4.71 C +ATOM 109 CG1 VAL A 15 1.384 1.826 1.806 1.00 6.67 C +ATOM 110 CG2 VAL A 15 3.174 0.533 3.005 1.00 6.26 C +ATOM 111 N CYS A 16 3.321 4.987 1.720 1.00 3.79 N +ATOM 112 CA CYS A 16 2.890 6.285 1.126 1.00 3.54 C +ATOM 113 C CYS A 16 3.687 6.597 -0.111 1.00 3.48 C +ATOM 114 O CYS A 16 3.200 7.147 -1.103 1.00 4.63 O +ATOM 115 CB CYS A 16 3.039 7.369 2.240 1.00 4.58 C +ATOM 116 SG CYS A 16 2.559 9.014 1.649 1.00 5.66 S +ATOM 117 N ARG A 17 4.997 6.227 -0.100 1.00 3.99 N +ATOM 118 CA ARG A 17 5.895 6.489 -1.213 1.00 3.83 C +ATOM 119 C ARG A 17 5.738 5.560 -2.409 1.00 3.79 C +ATOM 120 O ARG A 17 6.228 5.901 -3.507 1.00 5.39 O +ATOM 121 CB ARG A 17 7.370 6.507 -0.731 1.00 4.11 C +ATOM 122 CG ARG A 17 7.717 7.687 0.206 1.00 4.69 C +ATOM 123 CD ARG A 17 7.949 8.947 -0.615 1.00 5.10 C +ATOM 124 NE ARG A 17 9.212 8.856 -1.337 1.00 4.71 N +ATOM 125 CZ ARG A 17 9.537 9.533 -2.431 1.00 5.28 C +ATOM 126 NH1 ARG A 17 8.659 10.350 -3.032 1.00 6.67 N +ATOM 127 NH2 ARG A 17 10.793 9.491 -2.899 1.00 6.41 N +ATOM 128 N LEU A 18 5.051 4.411 -2.204 1.00 4.70 N +ATOM 129 CA LEU A 18 4.933 3.431 -3.326 1.00 5.46 C +ATOM 130 C LEU A 18 4.397 4.014 -4.620 1.00 5.13 C +ATOM 131 O LEU A 18 4.988 3.755 -5.687 1.00 5.55 O +ATOM 132 CB LEU A 18 4.196 2.184 -2.863 1.00 6.47 C +ATOM 133 CG LEU A 18 4.960 1.178 -1.991 1.00 7.43 C +ATOM 134 CD1 LEU A 18 3.907 0.097 -1.634 1.00 8.70 C +ATOM 135 CD2 LEU A 18 6.129 0.606 -2.768 1.00 9.39 C +ATOM 136 N PRO A 19 3.329 4.795 -4.543 1.00 4.28 N +ATOM 137 CA PRO A 19 2.792 5.376 -5.797 1.00 5.38 C +ATOM 138 C PRO A 19 3.573 6.540 -6.322 1.00 6.30 C +ATOM 139 O PRO A 19 3.260 7.045 -7.422 1.00 9.62 O +ATOM 140 CB PRO A 19 1.358 5.766 -5.472 1.00 5.87 C +ATOM 141 CG PRO A 19 1.223 5.694 -3.993 1.00 6.47 C +ATOM 142 CD PRO A 19 2.421 4.941 -3.408 1.00 6.45 C +ATOM 143 N GLY A 20 4.565 7.047 -5.559 1.00 4.94 N +ATOM 144 CA GLY A 20 5.366 8.191 -6.018 1.00 5.39 C +ATOM 145 C GLY A 20 5.007 9.481 -5.280 1.00 5.03 C +ATOM 146 O GLY A 20 5.535 10.510 -5.730 1.00 7.34 O +ATOM 147 N THR A 21 4.181 9.438 -4.262 1.00 4.10 N +ATOM 148 CA THR A 21 3.767 10.609 -3.513 1.00 3.94 C +ATOM 149 C THR A 21 5.017 11.397 -3.042 1.00 3.96 C +ATOM 150 O THR A 21 5.947 10.757 -2.523 1.00 5.82 O +ATOM 151 CB THR A 21 2.992 10.188 -2.225 1.00 4.13 C +ATOM 152 OG1 THR A 21 2.051 9.144 -2.623 1.00 5.45 O +ATOM 153 CG2 THR A 21 2.260 11.349 -1.551 1.00 5.41 C +ATOM 154 N PRO A 22 4.971 12.703 -3.176 1.00 5.04 N +ATOM 155 CA PRO A 22 6.143 13.513 -2.696 1.00 4.69 C +ATOM 156 C PRO A 22 6.400 13.233 -1.225 1.00 4.19 C +ATOM 157 O PRO A 22 5.485 13.061 -0.382 1.00 4.47 O +ATOM 158 CB PRO A 22 5.703 14.969 -2.920 1.00 7.12 C +ATOM 159 CG PRO A 22 4.676 14.893 -3.996 1.00 7.03 C +ATOM 160 CD PRO A 22 3.964 13.567 -3.811 1.00 4.90 C +ATOM 161 N GLU A 23 7.728 13.297 -0.921 1.00 5.16 N +ATOM 162 CA GLU A 23 8.114 13.103 0.500 1.00 5.31 C +ATOM 163 C GLU A 23 7.427 14.073 1.410 1.00 4.11 C +ATOM 164 O GLU A 23 7.036 13.682 2.540 1.00 5.11 O +ATOM 165 CB GLU A 23 9.648 13.285 0.660 1.00 6.16 C +ATOM 166 CG GLU A 23 10.440 12.093 0.063 1.00 7.48 C +ATOM 167 CD GLU A 23 11.941 12.170 0.391 1.00 9.40 C +ATOM 168 OE1 GLU A 23 12.416 13.225 0.681 1.00 10.40 O +ATOM 169 OE2 GLU A 23 12.539 11.070 0.292 1.00 13.32 O +ATOM 170 N ALA A 24 7.212 15.334 0.966 1.00 4.56 N +ATOM 171 CA ALA A 24 6.614 16.317 1.913 1.00 4.49 C +ATOM 172 C ALA A 24 5.212 15.936 2.350 1.00 4.10 C +ATOM 173 O ALA A 24 4.782 16.166 3.495 1.00 5.64 O +ATOM 174 CB ALA A 24 6.605 17.695 1.246 1.00 5.80 C +ATOM 175 N ILE A 25 4.445 15.318 1.405 1.00 4.37 N +ATOM 176 CA ILE A 25 3.074 14.894 1.756 1.00 5.44 C +ATOM 177 C ILE A 25 3.085 13.643 2.645 1.00 4.32 C +ATOM 178 O ILE A 25 2.315 13.523 3.578 1.00 4.72 O +ATOM 179 CB ILE A 25 2.204 14.637 0.462 1.00 6.42 C +ATOM 180 CG1 ILE A 25 1.815 16.048 -0.129 1.00 7.50 C +ATOM 181 CG2 ILE A 25 0.903 13.864 0.811 1.00 7.65 C +ATOM 182 CD1 ILE A 25 0.756 16.761 0.757 1.00 7.80 C +ATOM 183 N CYS A 26 4.032 12.764 2.313 1.00 3.92 N +ATOM 184 CA CYS A 26 4.180 11.549 3.187 1.00 4.37 C +ATOM 185 C CYS A 26 4.632 11.944 4.596 1.00 3.95 C +ATOM 186 O CYS A 26 4.227 11.252 5.547 1.00 4.74 O +ATOM 187 CB CYS A 26 5.038 10.518 2.539 1.00 4.63 C +ATOM 188 SG CYS A 26 4.349 9.794 1.022 1.00 5.61 S +ATOM 189 N ALA A 27 5.408 13.012 4.694 1.00 3.89 N +ATOM 190 CA ALA A 27 5.879 13.502 6.026 1.00 4.43 C +ATOM 191 C ALA A 27 4.696 13.908 6.882 1.00 4.26 C +ATOM 192 O ALA A 27 4.528 13.422 8.025 1.00 5.44 O +ATOM 193 CB ALA A 27 6.880 14.615 5.830 1.00 5.36 C +ATOM 194 N THR A 28 3.827 14.802 6.358 1.00 4.53 N +ATOM 195 CA THR A 28 2.691 15.221 7.194 1.00 5.08 C +ATOM 196 C THR A 28 1.672 14.132 7.434 1.00 4.62 C +ATOM 197 O THR A 28 0.947 14.112 8.468 1.00 7.80 O +ATOM 198 CB THR A 28 1.986 16.520 6.614 1.00 6.03 C +ATOM 199 OG1 THR A 28 1.664 16.221 5.230 1.00 7.19 O +ATOM 200 CG2 THR A 28 2.914 17.739 6.700 1.00 7.34 C +ATOM 201 N TYR A 29 1.621 13.190 6.511 1.00 5.01 N +ATOM 202 CA TYR A 29 0.715 12.045 6.657 1.00 6.60 C +ATOM 203 C TYR A 29 1.125 11.125 7.815 1.00 4.92 C +ATOM 204 O TYR A 29 0.286 10.632 8.545 1.00 7.13 O +ATOM 205 CB TYR A 29 0.755 11.229 5.322 1.00 9.66 C +ATOM 206 CG TYR A 29 -0.203 10.044 5.354 1.00 11.56 C +ATOM 207 CD1 TYR A 29 -1.547 10.337 5.645 1.00 12.85 C +ATOM 208 CD2 TYR A 29 0.193 8.750 5.100 1.00 14.44 C +ATOM 209 CE1 TYR A 29 -2.496 9.329 5.673 1.00 16.61 C +ATOM 210 CE2 TYR A 29 -0.801 7.705 5.156 1.00 17.11 C +ATOM 211 CZ TYR A 29 -2.079 8.031 5.430 1.00 19.99 C +ATOM 212 OH TYR A 29 -3.097 7.057 5.458 1.00 28.98 O +ATOM 213 N THR A 30 2.470 10.984 7.995 1.00 5.31 N +ATOM 214 CA THR A 30 2.986 9.994 8.950 1.00 5.70 C +ATOM 215 C THR A 30 3.609 10.505 10.230 1.00 6.28 C +ATOM 216 O THR A 30 3.766 9.715 11.186 1.00 8.77 O +ATOM 217 CB THR A 30 4.076 9.103 8.225 1.00 6.55 C +ATOM 218 OG1 THR A 30 5.125 10.027 7.824 1.00 6.57 O +ATOM 219 CG2 THR A 30 3.493 8.324 7.035 1.00 7.29 C +ATOM 220 N GLY A 31 3.984 11.764 10.241 1.00 4.99 N +ATOM 221 CA GLY A 31 4.769 12.336 11.360 1.00 5.50 C +ATOM 222 C GLY A 31 6.255 12.243 11.106 1.00 4.19 C +ATOM 223 O GLY A 31 7.037 12.750 11.954 1.00 6.12 O +ATOM 224 N CYS A 32 6.710 11.631 9.992 1.00 4.30 N +ATOM 225 CA CYS A 32 8.140 11.694 9.635 1.00 4.89 C +ATOM 226 C CYS A 32 8.500 13.141 9.206 1.00 5.50 C +ATOM 227 O CYS A 32 7.581 13.949 8.944 1.00 5.82 O +ATOM 228 CB CYS A 32 8.504 10.686 8.530 1.00 4.66 C +ATOM 229 SG CYS A 32 8.048 8.987 8.881 1.00 5.33 S +ATOM 230 N ILE A 33 9.793 13.410 9.173 1.00 6.02 N +ATOM 231 CA ILE A 33 10.280 14.760 8.823 1.00 5.24 C +ATOM 232 C ILE A 33 11.346 14.658 7.743 1.00 5.16 C +ATOM 233 O ILE A 33 11.971 13.583 7.552 1.00 7.19 O +ATOM 234 CB ILE A 33 10.790 15.535 10.085 1.00 5.49 C +ATOM 235 CG1 ILE A 33 12.059 14.803 10.671 1.00 6.85 C +ATOM 236 CG2 ILE A 33 9.684 15.686 11.138 1.00 6.45 C +ATOM 237 CD1 ILE A 33 12.733 15.676 11.781 1.00 8.94 C +ATOM 238 N ILE A 34 11.490 15.773 7.038 1.00 5.52 N +ATOM 239 CA ILE A 34 12.552 15.877 6.036 1.00 6.82 C +ATOM 240 C ILE A 34 13.590 16.917 6.560 1.00 6.92 C +ATOM 241 O ILE A 34 13.168 18.006 6.945 1.00 9.22 O +ATOM 242 CB ILE A 34 11.987 16.360 4.681 1.00 8.11 C +ATOM 243 CG1 ILE A 34 10.914 15.338 4.163 1.00 9.59 C +ATOM 244 CG2 ILE A 34 13.131 16.517 3.629 1.00 9.73 C +ATOM 245 CD1 ILE A 34 10.151 16.024 2.938 1.00 13.41 C +ATOM 246 N ILE A 35 14.856 16.493 6.536 1.00 7.06 N +ATOM 247 CA ILE A 35 15.930 17.454 6.941 1.00 7.52 C +ATOM 248 C ILE A 35 16.913 17.550 5.819 1.00 6.63 C +ATOM 249 O ILE A 35 17.097 16.660 4.970 1.00 7.90 O +ATOM 250 CB ILE A 35 16.622 16.995 8.285 1.00 8.07 C +ATOM 251 CG1 ILE A 35 17.360 15.651 8.067 1.00 9.41 C +ATOM 252 CG2 ILE A 35 15.592 16.974 9.434 1.00 9.46 C +ATOM 253 CD1 ILE A 35 18.298 15.206 9.219 1.00 9.85 C +ATOM 254 N PRO A 36 17.664 18.669 5.806 1.00 8.07 N +ATOM 255 CA PRO A 36 18.635 18.861 4.738 1.00 8.78 C +ATOM 256 C PRO A 36 19.925 18.042 4.949 1.00 8.31 C +ATOM 257 O PRO A 36 20.593 17.742 3.945 1.00 9.09 O +ATOM 258 CB PRO A 36 18.945 20.364 4.783 1.00 9.67 C +ATOM 259 CG PRO A 36 18.238 20.937 5.908 1.00 10.15 C +ATOM 260 CD PRO A 36 17.371 19.900 6.596 1.00 9.53 C +ATOM 261 N GLY A 37 20.172 17.730 6.217 1.00 8.48 N +ATOM 262 CA GLY A 37 21.452 16.969 6.513 1.00 9.20 C +ATOM 263 C GLY A 37 21.143 15.478 6.427 1.00 10.41 C +ATOM 264 O GLY A 37 20.138 15.023 5.878 1.00 12.06 O +ATOM 265 N ALA A 38 22.055 14.701 7.032 1.00 9.24 N +ATOM 266 CA ALA A 38 22.019 13.242 7.020 1.00 9.24 C +ATOM 267 C ALA A 38 21.944 12.628 8.396 1.00 9.60 C +ATOM 268 O ALA A 38 21.869 11.387 8.435 1.00 13.65 O +ATOM 269 CB ALA A 38 23.246 12.697 6.275 1.00 10.43 C +ATOM 270 N THR A 39 21.894 13.435 9.436 1.00 8.70 N +ATOM 271 CA THR A 39 21.936 12.911 10.809 1.00 9.46 C +ATOM 272 C THR A 39 20.615 13.191 11.521 1.00 8.32 C +ATOM 273 O THR A 39 20.357 14.317 11.948 1.00 9.89 O +ATOM 274 CB THR A 39 23.131 13.601 11.593 1.00 10.72 C +ATOM 275 OG1 THR A 39 24.284 13.401 10.709 1.00 11.66 O +ATOM 276 CG2 THR A 39 23.340 12.935 12.962 1.00 11.81 C +ATOM 277 N CYS A 40 19.827 12.110 11.642 1.00 7.64 N +ATOM 278 CA CYS A 40 18.504 12.312 12.298 1.00 8.05 C +ATOM 279 C CYS A 40 18.684 12.451 13.784 1.00 7.63 C +ATOM 280 O CYS A 40 19.533 11.718 14.362 1.00 9.64 O +ATOM 281 CB CYS A 40 17.582 11.117 11.996 1.00 7.80 C +ATOM 282 SG CYS A 40 17.199 10.929 10.237 1.00 7.30 S +ATOM 283 N PRO A 41 17.880 13.266 14.426 1.00 8.00 N +ATOM 284 CA PRO A 41 17.924 13.421 15.877 1.00 8.96 C +ATOM 285 C PRO A 41 17.392 12.206 16.594 1.00 9.06 C +ATOM 286 O PRO A 41 16.652 11.368 16.033 1.00 8.82 O +ATOM 287 CB PRO A 41 17.076 14.658 16.145 1.00 10.39 C +ATOM 288 CG PRO A 41 16.098 14.689 14.997 1.00 10.99 C +ATOM 289 CD PRO A 41 16.859 14.150 13.779 1.00 10.49 C +ATOM 290 N GLY A 42 17.728 12.124 17.884 1.00 7.55 N +ATOM 291 CA GLY A 42 17.334 10.956 18.691 1.00 8.00 C +ATOM 292 C GLY A 42 15.875 10.688 18.871 1.00 7.22 C +ATOM 293 O GLY A 42 15.434 9.550 19.166 1.00 8.41 O +ATOM 294 N ASP A 43 15.036 11.747 18.715 1.00 5.54 N +ATOM 295 CA ASP A 43 13.564 11.573 18.836 1.00 5.85 C +ATOM 296 C ASP A 43 12.936 11.227 17.470 1.00 5.87 C +ATOM 297 O ASP A 43 11.720 11.040 17.428 1.00 7.29 O +ATOM 298 CB ASP A 43 12.933 12.737 19.580 1.00 6.72 C +ATOM 299 CG ASP A 43 13.140 14.094 18.958 1.00 8.59 C +ATOM 300 OD1 ASP A 43 14.109 14.303 18.212 1.00 9.59 O +ATOM 301 OD2 ASP A 43 12.267 14.963 19.265 1.00 11.45 O +ATOM 302 N TYR A 44 13.725 11.174 16.425 1.00 5.22 N +ATOM 303 CA TYR A 44 13.257 10.745 15.081 1.00 5.56 C +ATOM 304 C TYR A 44 14.275 9.687 14.612 1.00 4.61 C +ATOM 305 O TYR A 44 14.930 9.862 13.568 1.00 6.04 O +ATOM 306 CB TYR A 44 13.200 11.914 14.071 1.00 5.41 C +ATOM 307 CG TYR A 44 12.000 12.819 14.399 1.00 5.34 C +ATOM 308 CD1 TYR A 44 12.119 13.853 15.332 1.00 6.59 C +ATOM 309 CD2 TYR A 44 10.775 12.617 13.762 1.00 5.94 C +ATOM 310 CE1 TYR A 44 11.045 14.675 15.610 1.00 5.97 C +ATOM 311 CE2 TYR A 44 9.676 13.433 14.048 1.00 5.17 C +ATOM 312 CZ TYR A 44 9.802 14.456 14.996 1.00 5.96 C +ATOM 313 OH TYR A 44 8.740 15.265 15.269 1.00 8.60 O +ATOM 314 N ALA A 45 14.342 8.640 15.422 1.00 4.76 N +ATOM 315 CA ALA A 45 15.445 7.667 15.246 1.00 5.89 C +ATOM 316 C ALA A 45 15.171 6.533 14.280 1.00 6.67 C +ATOM 317 O ALA A 45 16.093 5.705 14.039 1.00 7.56 O +ATOM 318 CB ALA A 45 15.680 7.099 16.682 1.00 6.82 C +ATOM 319 N ASN A 46 13.966 6.502 13.739 1.00 5.80 N +ATOM 320 CA ASN A 46 13.512 5.395 12.878 1.00 6.15 C +ATOM 321 C ASN A 46 13.311 5.853 11.455 1.00 6.61 C +ATOM 322 O ASN A 46 13.733 6.929 11.026 1.00 7.18 O +ATOM 323 CB ASN A 46 12.266 4.769 13.501 1.00 7.27 C +ATOM 324 CG ASN A 46 12.538 4.304 14.922 1.00 7.98 C +ATOM 325 OD1 ASN A 46 11.982 4.849 15.886 1.00 11.00 O +ATOM 326 ND2 ASN A 46 13.407 3.298 15.015 1.00 10.32 N +ATOM 327 OXT ASN A 46 12.703 4.973 10.746 1.00 7.86 O +TER 328 ASN A 46 +END diff --git a/modules/mol/mm/tests/AMBER03.dat b/modules/mol/mm/tests/AMBER03.dat new file mode 100644 index 0000000000000000000000000000000000000000..69e7d22171f447229ce354d731773876fcba7bd4 Binary files /dev/null and b/modules/mol/mm/tests/AMBER03.dat differ diff --git a/modules/mol/mm/tests/CHARMM27.dat b/modules/mol/mm/tests/CHARMM27.dat new file mode 100644 index 0000000000000000000000000000000000000000..9a9459fb0c9882ff4db05a70560389124a73f2e6 Binary files /dev/null and b/modules/mol/mm/tests/CHARMM27.dat differ diff --git a/modules/mol/mm/tests/CMakeLists.txt b/modules/mol/mm/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..99f2c4575dbc77849567d5d9e08a0497dfc9118d --- /dev/null +++ b/modules/mol/mm/tests/CMakeLists.txt @@ -0,0 +1,12 @@ +set(OST_MOL_MM_UNIT_TESTS + test_interaction.cc + test_block.cc + test_block_modifiers.cc + test_topology.cc + test_forcefield.cc + test_simulation.cc + tests.cc +) + +ost_unittest(MODULE mol_mm SOURCES "${OST_MOL_MM_UNIT_TESTS}") + diff --git a/modules/mol/mm/tests/test.ff b/modules/mol/mm/tests/test.ff new file mode 100644 index 0000000000000000000000000000000000000000..a9dfffe15ebe5915d3daba9c199e01cef5645e0c Binary files /dev/null and b/modules/mol/mm/tests/test.ff differ diff --git a/modules/mol/mm/tests/test_block.cc b/modules/mol/mm/tests/test_block.cc new file mode 100644 index 0000000000000000000000000000000000000000..45732b4131e3d4732ef2cba57169ee8ed294ccb8 --- /dev/null +++ b/modules/mol/mm/tests/test_block.cc @@ -0,0 +1,211 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mol.hh> +#include <ost/mol/builder.hh> +#include <ost/mol/xcs_editor.hh> + + +#include <ost/message.hh> + +using namespace ost::mol::mm; + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_block_basics) +{ + BuildingBlock block = BuildingBlock(); + block.AddAtom("A","a",0.5); + block.AddAtom("B","b",1.0); + MMInteractionPtr bond(new MMInteraction(HarmonicBond)); + std::vector<String> names; + names.push_back("A"); + names.push_back("B"); + bond->SetNames(names); + block.AddBond(bond); + BOOST_CHECK_THROW(block.GetCharge("C"),ost::Error); + BOOST_CHECK_THROW(block.GetType("C"),ost::Error); + BOOST_CHECK(block.GetCharge("A") == 0.5); + BOOST_CHECK(block.GetType("A") == "a"); + block.ReplaceAtom("A","X","x",42.0); + BOOST_CHECK(block.GetType("X") == "x"); + BOOST_CHECK(block.GetCharge("X")==42.0); + BOOST_CHECK(block.GetAtoms().size() == 2); + std::vector<MMInteractionPtr> bonds = block.GetBonds(); + BOOST_CHECK(bonds[0]->HasName("X")); + block.RemoveAtom("X"); + BOOST_CHECK_THROW(block.GetType("X"),ost::Error); + BOOST_CHECK_NO_THROW(block.GetType("B")); + BOOST_CHECK(block.GetAtoms().size()==1); + BOOST_CHECK(block.GetCharges().size()==1); + BOOST_CHECK(block.GetBonds().size()==0); + std::vector<Real> param_one,param_two; + param_one.push_back(1.0); + param_one.push_back(1.0); + param_two.push_back(2.0); + param_two.push_back(2.0); + MMInteractionPtr bond_one(new MMInteraction(HarmonicBond)); + MMInteractionPtr bond_two(new MMInteraction(HarmonicBond)); + bond_one->SetNames(names); + bond_one->SetParam(param_one); + bond_two->SetNames(names); + bond_two->SetParam(param_two); + block.AddBond(bond_one); + BOOST_CHECK(block.GetBonds()[0]->GetParam() == param_one); + block.AddBond(bond_two,true); + BOOST_CHECK(block.GetBonds()[0]->GetParam() == param_two); + block.RemoveAtom("A"); + + names[0] = "-A"; + bond_one->SetNames(names); + names[0] = "A"; + names[1] = "+B"; + bond_two->SetNames(names); + block.AddBond(bond_one); + block.AddBond(bond_two); + BOOST_CHECK(block.GetBonds().size() == 2); + block.RemoveInteractionsToPrev(); + BOOST_CHECK(block.GetBonds().size() == 1); + BOOST_CHECK(block.GetBonds()[0]->HasName("+B")); + block.RemoveInteractionsToNext(); + BOOST_CHECK(block.GetBonds().size() == 0); +} + +BOOST_AUTO_TEST_CASE(test_connect) +{ + ost::mol::EntityHandle e = ost::mol::Builder() + .Chain("A") + .Residue("ONE") + .Atom("A",geom::Vec3(0,0,0)) + .Atom("B",geom::Vec3(1,1,1)) + .Residue("TWO") + .Atom("A",geom::Vec3(2,2,2)) + .Atom("B",geom::Vec3(3,3,3)) + .Residue("THREE") + .Atom("A",geom::Vec3(4,4,4)) + .Atom("B",geom::Vec3(5,5,5)); + + ost::mol::XCSEditor ed = e.EditXCS(); + ed.DeleteBonds(e.GetBondList()); + + BuildingBlock block = BuildingBlock(); + block.AddAtom("A","a",0.0); + block.AddAtom("B","b",0.0); + + MMInteractionPtr bond_one(new MMInteraction(HarmonicBond)); + MMInteractionPtr bond_two(new MMInteraction(HarmonicBond)); + MMInteractionPtr bond_three(new MMInteraction(HarmonicBond)); + std::vector<String> two_string; + two_string.push_back("A"); + two_string.push_back("B"); + bond_one->SetNames(two_string); + two_string[0] = "-B"; + two_string[1] = "A"; + bond_two->SetNames(two_string); + two_string[0] = "B"; + two_string[1] = "+A"; + bond_three->SetNames(two_string); + block.AddBond(bond_one); + block.AddBond(bond_two); + block.AddBond(bond_three); + + ost::mol::ResidueHandleList res_list = e.GetResidueList(); + ost::mol::AtomHandleList atoms_one = res_list[0].GetAtomList(); + ost::mol::AtomHandleList atoms_two = res_list[1].GetAtomList(); + ost::mol::AtomHandleList atoms_three = res_list[2].GetAtomList(); + + block.Connect(res_list[1],ed); + BOOST_CHECK(ost::mol::BondExists(atoms_one[1],atoms_two[0])); + BOOST_CHECK(ost::mol::BondExists(atoms_two[0],atoms_two[1])); + BOOST_CHECK(ost::mol::BondExists(atoms_two[1],atoms_three[0])); + + ed.DeleteBonds(e.GetBondList()); + + BOOST_CHECK_THROW(block.Connect(res_list[0],ed),ost::Error); + BOOST_CHECK_THROW(block.Connect(res_list[2],ed),ost::Error); + + MMInteractionPtr bond_four(new MMInteraction(HarmonicBond)); + two_string[1] = "X"; + bond_four->SetNames(two_string); + block.AddBond(bond_four); + + BOOST_CHECK_THROW(block.Connect(res_list[1],ed),ost::Error); +} + +BOOST_AUTO_TEST_CASE(test_match) +{ + + ost::mol::EntityHandle e = ost::mol::Builder() + .Chain("A") + .Residue("ONE") + .Atom("A",geom::Vec3(0,0,0)) + .Atom("B",geom::Vec3(1,1,1)) + .Residue("TWO") + .Atom("A",geom::Vec3(2,2,2)) + .Atom("B",geom::Vec3(3,3,3)) + .Residue("THREE") + .Atom("A",geom::Vec3(4,4,4)) + .Atom("B",geom::Vec3(5,5,5)) + .Residue("FOUR") + .Atom("A",geom::Vec3(6,6,6)) + .Atom("B",geom::Vec3(7,7,7)); + + ost::mol::ResidueHandleList res_list = e.GetResidueList(); + ost::mol::XCSEditor ed = e.EditXCS(); + + ed.Connect(res_list[0].FindAtom("A"),res_list[0].FindAtom("B")); + ed.Connect(res_list[0].FindAtom("B"),res_list[1].FindAtom("A")); + ed.Connect(res_list[1].FindAtom("A"),res_list[1].FindAtom("B")); + ed.Connect(res_list[1].FindAtom("B"),res_list[2].FindAtom("A")); + ed.Connect(res_list[2].FindAtom("A"),res_list[2].FindAtom("B")); + //ed.Connect(atoms_two[1],atoms_four[1]); + + BuildingBlock block = BuildingBlock(); + String info_string; + BOOST_CHECK(!block.Match(res_list[1],true,info_string)); + + block.AddAtom("A","a",0.0); + block.AddAtom("B","b",0.0); + + BOOST_CHECK(!block.Match(res_list[1],true,info_string)); + + MMInteractionPtr bond_one(new MMInteraction(HarmonicBond)); + MMInteractionPtr bond_two(new MMInteraction(HarmonicBond)); + MMInteractionPtr bond_three(new MMInteraction(HarmonicBond)); + + std::vector<String> names_one; + names_one.push_back("A"); + names_one.push_back("B"); + std::vector<String> names_two; + names_two.push_back("-B"); + names_two.push_back("A"); + std::vector<String> names_three; + names_three.push_back("B"); + names_three.push_back("+A"); + + bond_one->SetNames(names_one); + bond_two->SetNames(names_two); + bond_three->SetNames(names_three); + + block.AddBond(bond_one); + BOOST_CHECK(block.Match(res_list[1],true,info_string)); + + block.AddBond(bond_two); + BOOST_CHECK(block.Match(res_list[1],true,info_string)); + + block.AddBond(bond_three); + BOOST_CHECK(block.Match(res_list[1],true,info_string)); + + //let's remove the central bond and replace it with a constraint + + block.RemoveAtom("A"); + block.AddAtom("A","a",0.0); + MMInteractionPtr constraint(new MMInteraction(DistanceConstraint)); + constraint->SetNames(names_one); + BOOST_CHECK(!block.Match(res_list[1],true,info_string)); + block.AddConstraint(constraint); + BOOST_CHECK(block.Match(res_list[1],true,info_string)); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/mm/tests/test_block_modifiers.cc b/modules/mol/mm/tests/test_block_modifiers.cc new file mode 100644 index 0000000000000000000000000000000000000000..901ae4c6fa8e30a26f632a97475d7da6a50f820b --- /dev/null +++ b/modules/mol/mm/tests/test_block_modifiers.cc @@ -0,0 +1,97 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mol.hh> +#include <ost/mol/builder.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> + + +#include <ost/message.hh> + +using namespace ost::mol::mm; + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_gromacs_block_modifier_basics){ + + GromacsBlockModifier mod; + + //let's create some interactions + MMInteractionPtr harmonic_bond(new MMInteraction(HarmonicBond)); + MMInteractionPtr urey_bradley_angle(new MMInteraction(UreyBradleyAngle)); + MMInteractionPtr harmonic_angle(new MMInteraction(HarmonicAngle)); + MMInteractionPtr periodic_dihedral(new MMInteraction(PeriodicDihedral)); + MMInteractionPtr periodic_improper(new MMInteraction(PeriodicImproper)); + MMInteractionPtr harmonic_improper(new MMInteraction(HarmonicImproper)); + MMInteractionPtr cmap(new MMInteraction(CMap)); + + //check whether error gets thrown, when names of interactions are not set + BOOST_CHECK_THROW(mod.AddBond(harmonic_bond),ost::Error); + BOOST_CHECK_THROW(mod.AddAngle(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(mod.AddDihedral(periodic_dihedral),ost::Error); + BOOST_CHECK_THROW(mod.AddImproper(periodic_improper),ost::Error); + BOOST_CHECK_THROW(mod.AddCMap(cmap),ost::Error); + + std::vector<String> two_string, three_string, four_string, five_string; + + two_string.push_back("one"); + three_string.push_back("one"); + four_string.push_back("one"); + five_string.push_back("one"); + + two_string.push_back("two"); + three_string.push_back("two"); + four_string.push_back("two"); + five_string.push_back("two"); + + three_string.push_back("three"); + four_string.push_back("three"); + five_string.push_back("three"); + + four_string.push_back("four"); + five_string.push_back("four"); + + five_string.push_back("five"); + + harmonic_bond->SetNames(two_string); + harmonic_angle->SetNames(three_string); + urey_bradley_angle->SetNames(three_string); + periodic_dihedral->SetNames(four_string); + periodic_improper->SetNames(four_string); + harmonic_improper->SetNames(four_string); + cmap->SetNames(five_string); + + BOOST_CHECK_NO_THROW(mod.AddBond(harmonic_bond)); + BOOST_CHECK_NO_THROW(mod.AddAngle(harmonic_angle)); + BOOST_CHECK_NO_THROW(mod.AddAngle(urey_bradley_angle)); + BOOST_CHECK_NO_THROW(mod.AddDihedral(periodic_dihedral)); + BOOST_CHECK_NO_THROW(mod.AddImproper(periodic_improper)); + BOOST_CHECK_NO_THROW(mod.AddImproper(harmonic_improper)); + BOOST_CHECK_NO_THROW(mod.AddCMap(cmap)); + + //check whether error get thrown when wrong interactions get added + + BOOST_CHECK_THROW(mod.AddBond(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(mod.AddAngle(harmonic_bond),ost::Error); + BOOST_CHECK_THROW(mod.AddDihedral(harmonic_bond),ost::Error); + BOOST_CHECK_THROW(mod.AddImproper(periodic_dihedral),ost::Error); + BOOST_CHECK_THROW(mod.AddCMap(periodic_improper),ost::Error); + + + + + + + + + + + +} + + + + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/mm/tests/test_forcefield.cc b/modules/mol/mm/tests/test_forcefield.cc new file mode 100644 index 0000000000000000000000000000000000000000..a2fec9865249a2f2ba9a629352516824ad3542e1 --- /dev/null +++ b/modules/mol/mm/tests/test_forcefield.cc @@ -0,0 +1,271 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> +#include <ost/message.hh> +#include <ost/mol/builder.hh> +#include <ost/mol/xcs_editor.hh> + + +using namespace ost::mol::mm; + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_forcefield_basics){ + Forcefield ff; + + //if a building block doesn't exist, it should throw an error + //this is not the case for hydrogen constructors and block modifiers + BOOST_CHECK_THROW(ff.GetBuildingBlock("IDoNotExist"),ost::Error); + + //add some atom types + ff.AddMass("one",1.0); + ff.AddMass("two",2.0); + ff.AddMass("three",3.0); + ff.AddMass("four",4.0); + ff.AddMass("five",5.0); + + BOOST_CHECK_THROW(ff.GetBond("one","two"),ost::Error); + BOOST_CHECK_THROW(ff.GetAngle("one","two","three"),ost::Error); + BOOST_CHECK_THROW(ff.GetDihedrals("one","two","three","four"),ost::Error); + BOOST_CHECK_THROW(ff.GetImpropers("one","two","three","four"),ost::Error); + BOOST_CHECK_THROW(ff.GetCMap("one","two","three","four","five"),ost::Error); + BOOST_CHECK_THROW(ff.GetImplicitGenborn("one"),ost::Error); + BOOST_CHECK_THROW(ff.GetLJ("one"),ost::Error); + BOOST_CHECK_THROW(ff.GetLJ("one","two"),ost::Error); + BOOST_CHECK_THROW(ff.GetConstraint("one","two"),ost::Error); + BOOST_CHECK_THROW(ff.GetMass("i_do_not_exist"),ost::Error); + + //let's add some interactions + std::vector<String> one_string, two_string, three_string, four_string, five_string; + std::vector<Real> one_real, two_real, three_real, four_real, five_real; + + one_string.push_back("one"); + two_string.push_back("one"); + three_string.push_back("one"); + four_string.push_back("one"); + five_string.push_back("one"); + + two_string.push_back("two"); + three_string.push_back("two"); + four_string.push_back("two"); + five_string.push_back("two"); + + three_string.push_back("three"); + four_string.push_back("three"); + five_string.push_back("three"); + + four_string.push_back("four"); + five_string.push_back("four"); + + five_string.push_back("five"); + + + one_real.push_back(1.0); + two_real.push_back(1.0); + three_real.push_back(1.0); + four_real.push_back(1.0); + five_real.push_back(1.0); + + two_real.push_back(2.0); + three_real.push_back(2.0); + four_real.push_back(2.0); + five_real.push_back(2.0); + + three_real.push_back(3.0); + four_real.push_back(3.0); + five_real.push_back(3.0); + + four_real.push_back(4.0); + five_real.push_back(4.0); + + five_real.push_back(5.0); + + + MMInteractionPtr harmonic_bond(new MMInteraction(HarmonicBond)); + MMInteractionPtr urey_bradley_angle(new MMInteraction(UreyBradleyAngle)); + MMInteractionPtr harmonic_angle(new MMInteraction(HarmonicAngle)); + MMInteractionPtr periodic_dihedral(new MMInteraction(PeriodicDihedral)); + MMInteractionPtr periodic_improper(new MMInteraction(PeriodicImproper)); + MMInteractionPtr harmonic_improper(new MMInteraction(HarmonicImproper)); + MMInteractionPtr cmap(new MMInteraction(CMap)); + MMInteractionPtr lj(new MMInteraction(LJ)); + MMInteractionPtr lj_pair(new MMInteraction(LJPair)); + MMInteractionPtr gbsa(new MMInteraction(GBSA)); + MMInteractionPtr distance_constraint(new MMInteraction(DistanceConstraint)); + + + //check whether errors get thrown when incorrectly parametrized interactions are added + BOOST_CHECK_THROW(ff.AddBond(harmonic_bond),ost::Error); + harmonic_bond->SetTypes(two_string); + BOOST_CHECK_THROW(ff.AddBond(harmonic_bond),ost::Error); + harmonic_angle->SetParam(two_real); + BOOST_CHECK_THROW(ff.AddAngle(harmonic_angle),ost::Error); + harmonic_bond->SetParam(two_real); + BOOST_CHECK_NO_THROW(ff.AddBond(harmonic_bond)); + harmonic_angle->SetTypes(three_string); + + //parametrize the rest + urey_bradley_angle->SetTypes(three_string); + urey_bradley_angle->SetParam(four_real); + periodic_dihedral->SetTypes(four_string); + periodic_dihedral->SetParam(three_real); + periodic_improper->SetTypes(four_string); + periodic_improper->SetParam(three_real); + harmonic_improper->SetTypes(four_string); + harmonic_improper->SetParam(two_real); + std::vector<Real> cmap_param = five_real; + cmap_param[0] = 2.0; + cmap->SetTypes(five_string); + cmap->SetParam(cmap_param); + lj->SetTypes(one_string); + lj->SetParam(two_real); + lj_pair->SetTypes(two_string); + lj_pair->SetParam(two_real); + gbsa->SetTypes(one_string); + gbsa->SetParam(two_real); + distance_constraint->SetTypes(two_string); + distance_constraint->SetParam(one_real); + + //check whether errors get thrown when wrong interactions get added + + BOOST_CHECK_THROW(ff.AddBond(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddAngle(harmonic_bond),ost::Error); + BOOST_CHECK_THROW(ff.AddDihedral(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddImproper(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddCMap(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddImplicitGenborn(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddLJ(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddLJPair(harmonic_angle),ost::Error); + BOOST_CHECK_THROW(ff.AddConstraint(harmonic_angle),ost::Error); + + BOOST_CHECK_NO_THROW(ff.AddBond(harmonic_bond)); + BOOST_CHECK_NO_THROW(ff.AddAngle(harmonic_angle)); + BOOST_CHECK_NO_THROW(ff.AddDihedral(periodic_dihedral)); + BOOST_CHECK_NO_THROW(ff.AddImproper(periodic_improper)); + BOOST_CHECK_NO_THROW(ff.AddImproper(harmonic_improper)); + BOOST_CHECK_NO_THROW(ff.AddCMap(cmap)); + BOOST_CHECK_NO_THROW(ff.AddImplicitGenborn(gbsa)); + BOOST_CHECK_NO_THROW(ff.AddLJ(lj)); + BOOST_CHECK_NO_THROW(ff.AddLJPair(lj_pair)); + BOOST_CHECK_NO_THROW(ff.AddConstraint(distance_constraint)); + + + //add a building block + BuildingBlockPtr block(new BuildingBlock); + block->AddAtom("a","one",0.5); + block->AddAtom("b","two",1.0); + ff.AddBuildingBlock("im_so_sexy",block); + + //add block modifier + BlockModifierPtr modifier(new GromacsBlockModifier); + ff.AddBlockModifier("el_modificator",modifier); + + //add hydrogen constructor + HydrogenConstructorPtr hydrogen_constructor(new GromacsHydrogenConstructor); + ff.AddHydrogenConstructor("death_metal",hydrogen_constructor); + + //add some renaming rules + ff.AddResidueRenamingRule("im_so_sexy","even_sexier","sexy_n","sexy_c","sexy_two"); + ff.AddAtomRenamingRule("even_sexier","a","z"); + ff.AddAtomRenamingRule("sexy_two","a","z"); + + //save and load it again, before we check parameters + ff.Save("test.ff"); + ForcefieldPtr loaded_ff = Forcefield::Load("test.ff"); + + + //check the parameters + BOOST_CHECK(loaded_ff->GetBond("one","two")->GetParam() == two_real); + BOOST_CHECK(loaded_ff->GetBond("two","one")->GetParam() == two_real); + + BOOST_CHECK(loaded_ff->GetAngle("one","two","three")->GetParam() == two_real); + BOOST_CHECK(loaded_ff->GetAngle("three","two","one")->GetParam() == two_real); + + BOOST_CHECK(loaded_ff->GetDihedrals("one","two","three","four")[0]->GetParam() == three_real); + BOOST_CHECK(loaded_ff->GetDihedrals("four","three","two","one")[0]->GetParam() == three_real); + + BOOST_CHECK(loaded_ff->GetImpropers("one","two","three","four")[0]->GetParam() == three_real); + BOOST_CHECK(loaded_ff->GetImpropers("four","three","two","one")[0]->GetParam() == three_real); + + BOOST_CHECK(loaded_ff->GetDihedrals("one","two","three","four")[0]->GetParam() == three_real); + BOOST_CHECK(loaded_ff->GetDihedrals("four","three","two","one")[0]->GetParam() == three_real); + + BOOST_CHECK(loaded_ff->GetCMap("one","two","three","four","five")->GetParam() == cmap_param); + //cmaps are directional... + BOOST_CHECK_THROW(loaded_ff->GetCMap("five","four","three","two","one"),ost::Error); + + BOOST_CHECK(loaded_ff->GetImplicitGenborn("one")->GetParam() == two_real); + + BOOST_CHECK(loaded_ff->GetLJ("one","two",true)->GetParam() == two_real); + BOOST_CHECK(loaded_ff->GetLJ("two","one",true)->GetParam() == two_real); + + BOOST_CHECK(loaded_ff->GetLJ("one")->GetParam() == two_real); + + BOOST_CHECK(loaded_ff->GetConstraint("one","two")->GetParam() == one_real); + BOOST_CHECK(loaded_ff->GetConstraint("two","one")->GetParam() == one_real); + + BOOST_CHECK(loaded_ff->GetMass("two") == 2.0); + + BOOST_CHECK(loaded_ff->GetAtomType("im_so_sexy","a") == "one"); + + //check whether the modifiers are still there + BOOST_CHECK(loaded_ff->GetHydrogenConstructor("death_metal")); + BOOST_CHECK(loaded_ff->GetBlockModifier("el_modificator")); + + + //check the renaming stuff + + + ost::mol::EntityHandle new_ent = ost::mol::Builder() + .Chain("A") + .Residue("im_so_sexy") + .Atom("a",geom::Vec3(0,0,0)) + .Atom("b",geom::Vec3(1,1,1)) + .Residue("im_so_sexy") + .Atom("a",geom::Vec3(2,2,2)) + .Atom("b",geom::Vec3(3,3,3)) + .Residue("im_so_sexy") + .Atom("a",geom::Vec3(4,4,4)) + .Atom("b",geom::Vec3(5,5,5)); + + ost::mol::XCSEditor ed = new_ent.EditXCS(); + + + loaded_ff->AssignFFSpecificNames(new_ent); + ost::mol::ResidueHandleList res_list = new_ent.GetResidueList(); + ost::mol::AtomHandleList atom_list = new_ent.GetAtomList(); + + BOOST_CHECK(res_list[0].GetName() == "sexy_n"); + BOOST_CHECK(res_list[1].GetName() == "even_sexier"); + BOOST_CHECK(res_list[2].GetName() == "sexy_c"); + BOOST_CHECK(atom_list[2].GetName() == "z"); + + loaded_ff->AssignFFSpecificNames(new_ent,true); + + BOOST_CHECK(res_list[0].GetName() == "im_so_sexy"); + BOOST_CHECK(res_list[1].GetName() == "im_so_sexy"); + BOOST_CHECK(res_list[2].GetName() == "im_so_sexy"); + BOOST_CHECK(atom_list[2].GetName() == "a"); + + ost::mol::EntityHandle new_ent_two = ost::mol::Builder() + .Chain("A") + .Residue("im_so_sexy") + .Atom("a",geom::Vec3(0,0,0)) + .Atom("b",geom::Vec3(1,1,1)); + + loaded_ff->AssignFFSpecificNames(new_ent_two); + res_list = new_ent_two.GetResidueList(); + atom_list = new_ent_two.GetAtomList(); + BOOST_CHECK(res_list[0].GetName() == "sexy_two"); + BOOST_CHECK(atom_list[0].GetName() == "z"); + loaded_ff->AssignFFSpecificNames(new_ent_two,true); + BOOST_CHECK(res_list[0].GetName() == "im_so_sexy"); + BOOST_CHECK(atom_list[0].GetName() == "a"); + +} + +BOOST_AUTO_TEST_SUITE_END(); \ No newline at end of file diff --git a/modules/mol/mm/tests/test_interaction.cc b/modules/mol/mm/tests/test_interaction.cc new file mode 100644 index 0000000000000000000000000000000000000000..b30080e8c0e924efbe102c3ecd0389bc2489dcc7 --- /dev/null +++ b/modules/mol/mm/tests/test_interaction.cc @@ -0,0 +1,273 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mol.hh> +#include <ost/mol/builder.hh> + +#include <ost/message.hh> + +using namespace ost::mol::mm; + + + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_set_stuff) +{ + MMInteraction harmonic_bond = MMInteraction(HarmonicBond); + MMInteraction harmonic_angle = MMInteraction(HarmonicAngle); + MMInteraction urey_bradley = MMInteraction(UreyBradleyAngle); + MMInteraction periodic_dihedral = MMInteraction(PeriodicDihedral); + MMInteraction periodic_improper = MMInteraction(PeriodicImproper); + MMInteraction harmonic_improper = MMInteraction(HarmonicImproper); + MMInteraction cmap = MMInteraction(CMap); + MMInteraction lj = MMInteraction(LJ); + MMInteraction lj_pair = MMInteraction(LJPair); + MMInteraction gbsa = MMInteraction(GBSA); + MMInteraction distance_constraint = MMInteraction(DistanceConstraint); + MMInteraction exclusion = MMInteraction(Exclusion); + MMInteraction harmonic_distance_restraint = MMInteraction(HarmonicDistanceRestraint); + MMInteraction harmonic_position_restraint = MMInteraction(HarmonicPositionRestraint); + + //std::vector<String> one_string, two_string, three_string, four_string, five_string; + //std::vector<Real> one_real, two_real, three_real, four_real, five_real, zero_real; + + std::vector<Real> one_real(1); + std::vector<Real> two_real(2); + std::vector<Real> three_real(3); + std::vector<Real> four_real(4); + std::vector<Real> five_real(5); + std::vector<Real> seven_real(7); + std::vector<Real> zero_real(0); + + std::vector<String> one_string(1); + std::vector<String> two_string(2); + std::vector<String> three_string(3); + std::vector<String> four_string(4); + std::vector<String> five_string(5); + + + BOOST_CHECK(!harmonic_bond.IsParametrized()); + + BOOST_CHECK_THROW(harmonic_bond.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_angle.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(urey_bradley.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(periodic_dihedral.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(periodic_improper.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_improper.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(cmap.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(lj.SetNames(two_string),ost::Error); + BOOST_CHECK_THROW(lj_pair.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(gbsa.SetNames(two_string),ost::Error); + BOOST_CHECK_THROW(distance_constraint.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(exclusion.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_distance_restraint.SetNames(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_position_restraint.SetNames(two_string),ost::Error); + + + BOOST_CHECK_THROW(harmonic_bond.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_angle.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(urey_bradley.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(periodic_dihedral.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(periodic_improper.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_improper.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(cmap.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(lj.SetTypes(two_string),ost::Error); + BOOST_CHECK_THROW(lj_pair.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(gbsa.SetTypes(two_string),ost::Error); + BOOST_CHECK_THROW(distance_constraint.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(exclusion.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_distance_restraint.SetTypes(one_string),ost::Error); + BOOST_CHECK_THROW(harmonic_position_restraint.SetTypes(two_string),ost::Error); + + BOOST_CHECK_THROW(harmonic_bond.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(harmonic_angle.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(urey_bradley.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(periodic_dihedral.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(periodic_improper.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(harmonic_improper.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(cmap.SetParam(two_real),ost::Error); + BOOST_CHECK_THROW(lj.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(lj_pair.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(gbsa.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(distance_constraint.SetParam(two_real),ost::Error); + BOOST_CHECK_THROW(exclusion.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(harmonic_distance_restraint.SetParam(one_real),ost::Error); + BOOST_CHECK_THROW(harmonic_position_restraint.SetParam(one_real),ost::Error); + + + + BOOST_CHECK_NO_THROW(harmonic_bond.SetNames(two_string)); + BOOST_CHECK_NO_THROW(harmonic_angle.SetNames(three_string)); + BOOST_CHECK_NO_THROW(urey_bradley.SetNames(three_string)); + BOOST_CHECK_NO_THROW(periodic_dihedral.SetNames(four_string)); + BOOST_CHECK_NO_THROW(periodic_improper.SetNames(four_string)); + BOOST_CHECK_NO_THROW(harmonic_improper.SetNames(four_string)); + BOOST_CHECK_NO_THROW(cmap.SetNames(five_string)); + BOOST_CHECK_NO_THROW(lj.SetNames(one_string)); + BOOST_CHECK_NO_THROW(lj_pair.SetNames(two_string)); + BOOST_CHECK_NO_THROW(gbsa.SetNames(one_string)); + BOOST_CHECK_NO_THROW(distance_constraint.SetNames(two_string)); + BOOST_CHECK_NO_THROW(exclusion.SetNames(two_string)); + BOOST_CHECK_NO_THROW(harmonic_distance_restraint.SetNames(two_string)); + BOOST_CHECK_NO_THROW(harmonic_position_restraint.SetNames(one_string)); + + + BOOST_CHECK_NO_THROW(harmonic_bond.SetTypes(two_string)); + BOOST_CHECK_NO_THROW(harmonic_angle.SetTypes(three_string)); + BOOST_CHECK_NO_THROW(urey_bradley.SetTypes(three_string)); + BOOST_CHECK_NO_THROW(periodic_dihedral.SetTypes(four_string)); + BOOST_CHECK_NO_THROW(periodic_improper.SetTypes(four_string)); + BOOST_CHECK_NO_THROW(harmonic_improper.SetTypes(four_string)); + BOOST_CHECK_NO_THROW(cmap.SetTypes(five_string)); + BOOST_CHECK_NO_THROW(lj.SetTypes(one_string)); + BOOST_CHECK_NO_THROW(lj_pair.SetTypes(two_string)); + BOOST_CHECK_NO_THROW(gbsa.SetTypes(one_string)); + BOOST_CHECK_NO_THROW(distance_constraint.SetTypes(two_string)); + BOOST_CHECK_NO_THROW(exclusion.SetTypes(two_string)); + BOOST_CHECK_NO_THROW(harmonic_distance_restraint.SetTypes(two_string)); + BOOST_CHECK_NO_THROW(harmonic_position_restraint.SetTypes(one_string)); + + BOOST_CHECK_NO_THROW(harmonic_bond.SetParam(two_real)); + BOOST_CHECK_NO_THROW(harmonic_angle.SetParam(two_real)); + BOOST_CHECK_NO_THROW(urey_bradley.SetParam(four_real)); + BOOST_CHECK_NO_THROW(periodic_dihedral.SetParam(three_real)); + BOOST_CHECK_NO_THROW(periodic_improper.SetParam(three_real)); + BOOST_CHECK_NO_THROW(harmonic_improper.SetParam(two_real)); + BOOST_CHECK_NO_THROW(lj.SetParam(two_real)); + BOOST_CHECK_NO_THROW(lj_pair.SetParam(two_real)); + BOOST_CHECK_NO_THROW(gbsa.SetParam(two_real)); + BOOST_CHECK_NO_THROW(distance_constraint.SetParam(one_real)); + BOOST_CHECK_NO_THROW(exclusion.SetParam(zero_real)); + BOOST_CHECK_NO_THROW(harmonic_distance_restraint.SetParam(two_real)); + BOOST_CHECK_NO_THROW(harmonic_position_restraint.SetParam(seven_real)); + + std::vector<Real> valid_cmap_parameters; + valid_cmap_parameters.push_back(2.0); + valid_cmap_parameters.push_back(0.0); + valid_cmap_parameters.push_back(0.0); + valid_cmap_parameters.push_back(0.0); + valid_cmap_parameters.push_back(0.0); + + BOOST_CHECK_NO_THROW(cmap.SetParam(valid_cmap_parameters)); + BOOST_CHECK(harmonic_bond.IsParametrized()); + + MMInteraction new_bond = MMInteraction(HarmonicBond); + std::vector<String> with_wildcard, without_wildcard; + with_wildcard.push_back("A"); + without_wildcard.push_back("A"); + with_wildcard.push_back("X"); + without_wildcard.push_back("A"); + + //should be initialized with false + BOOST_CHECK(!new_bond.HasNameWildcard()); + BOOST_CHECK(!new_bond.HasTypeWildcard()); + + new_bond.SetNames(without_wildcard); + new_bond.SetTypes(without_wildcard); + BOOST_CHECK(!new_bond.HasNameWildcard()); + BOOST_CHECK(!new_bond.HasTypeWildcard()); + + new_bond.SetNames(with_wildcard); + new_bond.SetTypes(with_wildcard); + BOOST_CHECK(new_bond.HasNameWildcard()); + BOOST_CHECK(new_bond.HasTypeWildcard()); + + //Check hasname/hastype + BOOST_CHECK(new_bond.HasType("A")); + BOOST_CHECK(!new_bond.HasType("B")); + BOOST_CHECK(new_bond.HasName("A")); + BOOST_CHECK(!new_bond.HasType("B")); + +} + +BOOST_AUTO_TEST_CASE(test_match_stuff) +{ + MMInteraction dihedral = MMInteraction(PeriodicDihedral); + + std::vector<String> with_wildcard, without_wildcard; + with_wildcard.push_back("X"); + with_wildcard.push_back("A"); + with_wildcard.push_back("A"); + with_wildcard.push_back("A"); + without_wildcard.push_back("A"); + without_wildcard.push_back("A"); + without_wildcard.push_back("A"); + without_wildcard.push_back("A"); + + dihedral.SetTypes(with_wildcard); + BOOST_CHECK(dihedral.MatchTypes(with_wildcard)); + BOOST_CHECK(dihedral.MatchTypes(without_wildcard)); + dihedral.SetTypes(without_wildcard); + BOOST_CHECK(dihedral.MatchTypes(without_wildcard)); + BOOST_CHECK(!dihedral.MatchTypes(with_wildcard)); + + dihedral.SetNames(with_wildcard); + BOOST_CHECK(dihedral.MatchNames(with_wildcard)); + BOOST_CHECK(dihedral.MatchNames(without_wildcard)); + dihedral.SetNames(without_wildcard); + BOOST_CHECK(dihedral.MatchNames(without_wildcard)); + BOOST_CHECK(!dihedral.MatchNames(with_wildcard)); + +} + +BOOST_AUTO_TEST_CASE(test_replace_atom){ + MMInteraction bond = MMInteraction(HarmonicBond); + std::vector<String> strings; + strings.push_back("A"); + strings.push_back("B"); + bond.SetNames(strings); + bond.ReplaceAtom("A","X","X"); + std::vector<String> new_names = bond.GetNames(); + BOOST_CHECK(new_names != strings); + bond.SetTypes(strings); + bond.ReplaceAtom("X","A","X"); + std::vector<String> new_types = bond.GetTypes(); + BOOST_CHECK(new_types == new_names); + +} + +BOOST_AUTO_TEST_CASE(test_getatoms){ + ost::mol::EntityHandle e = ost::mol::Builder() + .Chain("A") + .Residue("ONE") + .Atom("A",geom::Vec3(-5,-5,-5)) + .Atom("B",geom::Vec3(-5, 5,-5)) + .Residue("TWO") + .Atom("A",geom::Vec3(1,1,1)) + .Atom("B",geom::Vec3(2,2,2)) + .Residue("THREE") + .Atom("A",geom::Vec3(3,3,3)) + .Atom("B",geom::Vec3(4,4,4)); + + ost::mol::ResidueHandleList res_list = e.GetResidueList(); + ost::mol::AtomHandleList atom_list_one = res_list[0].GetAtomList(); + ost::mol::AtomHandleList atom_list_two = res_list[1].GetAtomList(); + ost::mol::AtomHandleList atom_list_three = res_list[2].GetAtomList(); + + MMInteraction bond = MMInteraction(HarmonicBond); + std::vector<String> strings; + strings.push_back("A"); + strings.push_back("B"); + bond.SetNames(strings); + ost::mol::AtomHandleList bond_atom_list = bond.GetAtoms(res_list[0]); + BOOST_CHECK(atom_list_one[0] == bond_atom_list[0]); + BOOST_CHECK(atom_list_one[1] == bond_atom_list[1]); + strings[1] = "X"; + bond.SetNames(strings); + BOOST_CHECK_THROW(bond.GetAtoms(res_list[0]),ost::Error); + strings[0] = "-A"; + strings[1] = "B"; + bond.SetNames(strings); + BOOST_CHECK_THROW(bond.GetAtoms(res_list[0]),ost::Error); + bond_atom_list = bond.GetAtoms(res_list[1]); + BOOST_CHECK(bond_atom_list[0] == atom_list_one[0]); + BOOST_CHECK(bond_atom_list[1] == atom_list_two[1]); + strings[1]="+B"; + bond.SetNames(strings); + BOOST_CHECK_THROW(bond.GetAtoms(res_list[2]),ost::Error); + bond_atom_list = bond.GetAtoms(res_list[1]); + BOOST_CHECK(bond_atom_list[0] == atom_list_one[0]); + BOOST_CHECK(bond_atom_list[1] == atom_list_three[1]); +} +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/mm/tests/test_simulation.cc b/modules/mol/mm/tests/test_simulation.cc new file mode 100644 index 0000000000000000000000000000000000000000..6d1351972639d9042dc8cf5e0b2c85fa9f600432 --- /dev/null +++ b/modules/mol/mm/tests/test_simulation.cc @@ -0,0 +1,242 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/mol/mm/mm_interaction.hh> +#include <ost/mol/mm/buildingblock.hh> +#include <ost/mol/mm/gromacs_block_modifiers.hh> +#include <ost/message.hh> +#include <ost/mol/builder.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/io/mol/pdb_reader.hh> +#include <ost/mol/mm/simulation.hh> +#include <ost/mol/mm/topology.hh> + + +using namespace ost::mol::mm; + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_simulation_basics){ + + String pdb_name = "1CRN.pdb"; + + ost::io::PDBReader reader(pdb_name, ost::io::IOProfile()); + ost::mol::EntityHandle test_ent = ost::mol::CreateEntity(); + reader.Import(test_ent); + + ost::conop::ProcessorPtr processor(new ost::conop::HeuristicProcessor); + processor->Process(test_ent); + + MMSettingsPtr settings(new MMSettings); + ForcefieldPtr forcefield = Forcefield::Load("CHARMM27.dat"); + settings->forcefield = forcefield; + settings->add_gbsa = true; + + TopologyPtr top = TopologyCreator::Create(test_ent,settings); + //lets add interactions, that are not set when using charmm + top->AddHarmonicAngle(1,2,3,10.0,10.0); + top->AddPeriodicImproper(1,2,3,4,2,10.0,10.0); + top->AddDistanceConstraint(1,2,10.0); + top->AddHarmonicPositionRestraint(1,geom::Vec3(0.0,0.0,0.0),10.0); + top->AddHarmonicDistanceRestraint(1,2,10.0,10.0); + + //try to set up simulation without an integrator + BOOST_CHECK_THROW(Simulation sim(test_ent,settings),ost::Error); + + settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + + Simulation sim(top, settings); + + + //we check, wether the reset functions have the desired effect on the topology + //we cannot really check the effect on the openmm system... + sim.ResetHarmonicBond(42,5.0,6.0); + sim.ResetHarmonicAngle(0,8.0,9.0); + sim.ResetUreyBradleyAngle(42,5.0,6.0,7.0,8.0); + sim.ResetPeriodicDihedral(42,4,5.0,6.0); + sim.ResetPeriodicImproper(0,5,8.0,9.0); + sim.ResetHarmonicImproper(42,5.0,6.0); + sim.ResetLJPair(42,5.0,6.0); + sim.ResetDistanceConstraint(0,10.0); + sim.ResetHarmonicPositionRestraint(0,geom::Vec3(1.0,1.0,1.0),5.0); + sim.ResetHarmonicDistanceRestraint(0,5.0,10.0); + sim.ResetLJ(42,2.0,3.0); + sim.ResetGBSA(42,5.0,6.0); + sim.ResetCharge(42,100.0); + sim.ResetMass(42,200.0); + + uint ui1,ui2,ui3,ui4; + int i1; + Real r1,r2,r3,r4; + geom::Vec3 pos; + + + top->GetHarmonicBondParameters(42,ui1,ui2,r1,r2); + BOOST_CHECK(r1 == 5.0 && r2 == 6.0); + + top->GetHarmonicAngleParameters(0,ui1,ui2,ui3,r1,r2); + BOOST_CHECK(r1 == 8.0 && r2 == 9.0); + + top->GetUreyBradleyAngleParameters(42,ui1,ui2,ui3,r1,r2,r3,r4); + BOOST_CHECK(r1 == 5.0 && r2 == 6.0 && r3 == 7.0 && r4 == 8.0); + + top->GetPeriodicDihedralParameters(42,ui1,ui2,ui3,ui4,i1,r1,r2); + BOOST_CHECK(i1 == 4 && r1 == 5.0 && r2 == 6.0); + + top->GetPeriodicImproperParameters(0,ui1,ui2,ui3,ui4,i1,r1,r2); + BOOST_CHECK(i1 == 5 && r1 == 8.0 && r2 == 9.0); + + top->GetLJPairParameters(42,ui1,ui2,r1,r2); + BOOST_CHECK(r1 == 5.0 && r2 == 6.0); + + top->GetDistanceConstraintParameters(0,ui1,ui2,r1); + BOOST_CHECK(r1 == 10.0); + + top->GetHarmonicPositionRestraintParameters(0, ui1, pos,r1, r2, r3, r3); + BOOST_CHECK(pos == geom::Vec3(1.0,1.0,1.0) && r1 == 5.0); + + top->GetHarmonicDistanceRestraintParameters(0,ui1,ui2, r1, r2); + BOOST_CHECK(r1 == 5.0 && r2 == 10.0); + + r1 = top->GetSigma(42); + r2 = top->GetEpsilon(42); + BOOST_CHECK(r1 == 2.0 && r2 == 3.0); + + r1 = top->GetGBSARadius(42); + r2 = top->GetOBCScaling(42); + BOOST_CHECK(r1 == 5.0 && r2 == 6.0); + + r1 = top->GetCharge(42); + r2 = top->GetMass(42); + BOOST_CHECK(r1 == 100.0 && r2 == 200.0); +} + + +BOOST_AUTO_TEST_CASE(test_simulation_energy_calculations){ + + + String pdb_name = "1CRN.pdb"; + + ost::io::PDBReader reader(pdb_name, ost::io::IOProfile()); + ost::mol::EntityHandle test_ent = ost::mol::CreateEntity(); + reader.Import(test_ent); + + ost::conop::ProcessorPtr processor(new ost::conop::HeuristicProcessor); + processor->Process(test_ent); + + MMSettingsPtr settings(new MMSettings); + ForcefieldPtr forcefield = Forcefield::Load("CHARMM27.dat"); + settings->forcefield = forcefield; + + TopologyPtr top = TopologyCreator::Create(test_ent,settings); + //lets add interactions, that are not set when using charmm + + settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + + Simulation sim(top, settings); + + sim.MinimizeEnergy("steep",1.0,200); + sim.UpdateTopologyPositions(); + + ost::mol::EntityHandle minimized_ent = sim.GetEntity(); + + MMSettingsPtr harmonic_bond_settings(new MMSettings); + harmonic_bond_settings->add_angles = false; + harmonic_bond_settings->add_dihedrals = false; + harmonic_bond_settings->add_impropers = false; + harmonic_bond_settings->add_nonbonded = false; + harmonic_bond_settings->add_cmaps = false; + harmonic_bond_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + harmonic_bond_settings->forcefield = forcefield; + + MMSettingsPtr urey_bradley_angle_settings(new MMSettings); + urey_bradley_angle_settings->add_bonds = false; + urey_bradley_angle_settings->add_dihedrals = false; + urey_bradley_angle_settings->add_impropers = false; + urey_bradley_angle_settings->add_nonbonded = false; + urey_bradley_angle_settings->add_cmaps = false; + urey_bradley_angle_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + urey_bradley_angle_settings->forcefield = forcefield; + + MMSettingsPtr periodic_dihedral_settings(new MMSettings); + periodic_dihedral_settings->add_bonds = false; + periodic_dihedral_settings->add_angles = false; + periodic_dihedral_settings->add_impropers = false; + periodic_dihedral_settings->add_nonbonded = false; + periodic_dihedral_settings->add_cmaps = false; + periodic_dihedral_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + periodic_dihedral_settings->forcefield = forcefield; + + MMSettingsPtr harmonic_improper_settings(new MMSettings); + harmonic_improper_settings->add_bonds = false; + harmonic_improper_settings->add_angles = false; + harmonic_improper_settings->add_dihedrals = false; + harmonic_improper_settings->add_nonbonded = false; + harmonic_improper_settings->add_cmaps = false; + harmonic_improper_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + harmonic_improper_settings->forcefield = forcefield; + + MMSettingsPtr cmap_settings(new MMSettings); + cmap_settings->add_bonds = false; + cmap_settings->add_angles = false; + cmap_settings->add_dihedrals = false; + cmap_settings->add_nonbonded = false; + cmap_settings->add_impropers = false; + cmap_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + cmap_settings->forcefield = forcefield; + + MMSettingsPtr nonbonded_settings(new MMSettings); + nonbonded_settings->add_bonds = false; + nonbonded_settings->add_angles = false; + nonbonded_settings->add_dihedrals = false; + nonbonded_settings->add_cmaps = false; + nonbonded_settings->add_impropers = false; + nonbonded_settings->integrator = IntegratorPtr(new OpenMM::VerletIntegrator(0.002)); + nonbonded_settings->forcefield = forcefield; + + Simulation sim_harmonic_bond(minimized_ent,harmonic_bond_settings); + Simulation sim_urey_bradley_angle(minimized_ent,urey_bradley_angle_settings); + Simulation sim_periodic_dihedral(minimized_ent,periodic_dihedral_settings); + Simulation sim_harmonic_improper(minimized_ent,harmonic_improper_settings); + Simulation sim_cmap(minimized_ent,cmap_settings); + Simulation sim_nonbonded(minimized_ent, nonbonded_settings); + + Real e_harmonic_bond = sim_harmonic_bond.GetPotentialEnergy(); + Real e_urey_bradley_angle = sim_urey_bradley_angle.GetPotentialEnergy(); + Real e_periodic_dihedral = sim_periodic_dihedral.GetPotentialEnergy(); + Real e_harmonic_improper = sim_harmonic_improper.GetPotentialEnergy(); + Real e_cmap = sim_cmap.GetPotentialEnergy(); + Real e_nonbonded = sim_nonbonded.GetPotentialEnergy(); + + + //the energy values have been compared with the results from the + //CHARMM27 forcefield in gromacs + + //differenecs in energy(kJ/mol): + //harmonic_bond: 0.00021344800001 + //urey_bradley_angle: 0.00021319300003 + //periodic_dihedral: 0.00018275799993 + //harmonic_improper: 0.00001410630000 + //cmap: 0.00192255100001 + //nonbonded: 0.00204422999968 + + //You'll most likely get different results when repeating the comparison with gromacs + //this is because of the precision. + //Right now we have full real precision in the positions. + //When you write down the pdb, precision will be lowered to 3 digits. + //Another digit gets lost, when you create a gromacs topology... + //Gromacs writes down the positions using nm instead of A, but + //also has a precision of 3 digits. + + BOOST_CHECK_CLOSE(e_harmonic_bond, 150.238, Real(1e-3)); + BOOST_CHECK_CLOSE(e_urey_bradley_angle, 499.690, Real(1e-3)); + BOOST_CHECK_CLOSE(e_periodic_dihedral, 879.744, Real(1e-3)); + BOOST_CHECK_CLOSE(e_harmonic_improper, 15.7698, Real(1e-3)); + BOOST_CHECK_CLOSE(e_cmap, -303.904, Real(1e-3)); + BOOST_CHECK_CLOSE(e_nonbonded, -3626.539, Real(1e-3)); +} + + + +BOOST_AUTO_TEST_SUITE_END(); \ No newline at end of file diff --git a/modules/mol/mm/tests/test_topology.cc b/modules/mol/mm/tests/test_topology.cc new file mode 100644 index 0000000000000000000000000000000000000000..52744ed6cdb261fac98c91a3fc5b0c1f28b64079 --- /dev/null +++ b/modules/mol/mm/tests/test_topology.cc @@ -0,0 +1,627 @@ +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mm/topology.hh> +#include <ost/mol/mm/topology_creator.hh> +#include <ost/mol/mm/mm_settings.hh> +#include <ost/mol/mm/forcefield.hh> +#include <ost/io/mol/pdb_reader.hh> +#include <ost/conop/heuristic.hh> +#include <ost/message.hh> +#include <ost/mol/builder.hh> +#include <ost/mol/xcs_editor.hh> + + +using namespace ost::mol::mm; + +BOOST_AUTO_TEST_SUITE( mol_mm ); + +BOOST_AUTO_TEST_CASE(test_topology_basics){ + + String pdb_name = "1CRN.pdb"; + + ost::io::PDBReader reader(pdb_name, ost::io::IOProfile()); + ost::mol::EntityHandle test_ent = ost::mol::CreateEntity(); + reader.Import(test_ent); + + ost::conop::ProcessorPtr processor(new ost::conop::HeuristicProcessor); + processor->Process(test_ent); + + //check initialisation without settings + std::vector<Real> zero_real(0); + std::vector<Real> lot_of_reals(test_ent.GetAtomCount()); + + BOOST_CHECK_THROW(Topology(test_ent,zero_real),ost::Error); + + TopologyPtr top(new Topology(test_ent,lot_of_reals)); + + uint ui1(0), ui2(0), ui3(0), ui4(0), ui5(0); + int i1(0), i5(0); + Real r1(0.0), r2(0.0), r3(0.0), r4(0.0); + geom::Vec3 zero_vec(0.0,0.0,0.0); + geom::Vec3 test_vec(0.0,1.0,2.0); + + //check wether errors geth thrown, when atom indices are too big + BOOST_CHECK_THROW(top->AddHarmonicBond(700,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicBond(0,700,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicAngle(700,1,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicAngle(1,700,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicAngle(1,1,700,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddUreyBradleyAngle(700,1,1,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->AddUreyBradleyAngle(1,700,1,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->AddUreyBradleyAngle(1,1,700,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicDihedral(700,1,1,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicDihedral(1,700,1,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicDihedral(1,1,700,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicDihedral(1,1,1,700,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicImproper(700,1,1,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicImproper(1,700,1,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicImproper(1,1,700,1,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddPeriodicImproper(1,1,1,700,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicImproper(700,1,1,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicImproper(1,700,1,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicImproper(1,1,700,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicImproper(1,1,1,700,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(700,1,1,1,1,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(1,700,1,1,1,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(1,1,700,1,1,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(1,1,1,700,1,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(1,1,1,1,700,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->AddCMap(1,1,1,1,1,0,lot_of_reals),ost::Error); //additionally checks error, when dimension and cmap are inconsistent + BOOST_CHECK_THROW(top->AddLJPair(1,700,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddLJPair(700,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddExclusion(1,700),ost::Error); + BOOST_CHECK_THROW(top->AddExclusion(700,1),ost::Error); + BOOST_CHECK_THROW(top->AddDistanceConstraint(1,700,r1),ost::Error); + BOOST_CHECK_THROW(top->AddDistanceConstraint(700,1,r1),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicPositionRestraint(700,zero_vec,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicDistanceRestraint(700,1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->AddHarmonicDistanceRestraint(1,700,r1,r2),ost::Error); + + //check whether errors get thrown when single atom parameters are inconsistent with number of atoms in topology + BOOST_CHECK_THROW(top->SetSigmas(zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetEpsilons(zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetGBSARadii(zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetOBCScalings(zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetMasses(zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetCharges(zero_real),ost::Error); + + //Single atom parameters are not allowed to be modified, without being set initially + BOOST_CHECK_THROW(top->SetSigma(1,r1),ost::Error); + BOOST_CHECK_THROW(top->SetEpsilon(1,r1),ost::Error); + BOOST_CHECK_THROW(top->SetGBSARadius(1,r1),ost::Error); + BOOST_CHECK_THROW(top->SetOBCScaling(1,r1),ost::Error); + BOOST_CHECK_THROW(top->SetCharge(1,r1),ost::Error); + + //Let's set the single atom parameters initially + top->SetSigmas(lot_of_reals); + top->SetEpsilons(lot_of_reals); + top->SetGBSARadii(lot_of_reals); + top->SetOBCScalings(lot_of_reals); + top->SetCharges(lot_of_reals); + + //do the index checks for them + BOOST_CHECK_THROW(top->SetSigma(1000,1.0),ost::Error); + BOOST_CHECK_THROW(top->SetEpsilon(1000,1.0),ost::Error); + BOOST_CHECK_THROW(top->SetGBSARadius(1000,1.0),ost::Error); + BOOST_CHECK_THROW(top->SetOBCScaling(1000,1.0),ost::Error); + BOOST_CHECK_THROW(top->SetMass(1000,1.0),ost::Error); + BOOST_CHECK_THROW(top->SetCharge(1000,1.0),ost::Error); + + //similar stupid checks for SetParameter functions + BOOST_CHECK_THROW(top->SetHarmonicBondParameters(700,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetHarmonicAngleParameters(3000,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetUreyBradleyAngleParameters(3000,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->SetPeriodicDihedralParameters(3000,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetPeriodicImproperParameters(3000,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetHarmonicImproperParameters(3000,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetCMapParameters(3000,0,zero_real),ost::Error); + BOOST_CHECK_THROW(top->SetLJPairParameters(3000,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->SetDistanceConstraintParameters(3000,r1),ost::Error); + BOOST_CHECK_THROW(top->SetHarmonicPositionRestraintParameters(3000,zero_vec,r1),ost::Error); + BOOST_CHECK_THROW(top->SetHarmonicDistanceRestraintParameters(3000,r1,r2),ost::Error); + + BOOST_CHECK_THROW(top->GetHarmonicBondParameters(700,ui1,ui2,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetHarmonicAngleParameters(3000,ui1,ui2,ui3,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetUreyBradleyAngleParameters(3000,ui1,ui2,ui3,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->GetPeriodicDihedralParameters(3000,ui1,ui2,ui3,ui4,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetPeriodicImproperParameters(3000,ui1,ui2,ui3,ui4,i1,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetHarmonicImproperParameters(3000,ui1,ui2,ui3,ui4,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetCMapParameters(3000,ui1,ui2,ui3,ui4,ui5,i1,zero_real),ost::Error); + BOOST_CHECK_THROW(top->GetLJPairParameters(3000,ui1,ui2,r1,r2),ost::Error); + BOOST_CHECK_THROW(top->GetDistanceConstraintParameters(3000,ui1,ui2,r1),ost::Error); + BOOST_CHECK_THROW(top->GetHarmonicPositionRestraintParameters(3000,ui1,zero_vec,r1,r2,r3,r4),ost::Error); + BOOST_CHECK_THROW(top->GetHarmonicDistanceRestraintParameters(3000,ui1,ui2,r1,r2),ost::Error); + + //let's add some interactions to the topology + for(int i = 0; i < 10; ++i){ + top->AddHarmonicBond(0,1,r1,r2); + top->AddHarmonicAngle(0,1,2,r1,r2); + top->AddUreyBradleyAngle(0,1,2,r1,r2,r3,r4); + top->AddPeriodicDihedral(0,1,2,3,i1,r1,r2); + top->AddPeriodicImproper(0,1,2,3,i1,r1,r2); + top->AddHarmonicImproper(0,1,2,3,r1,r2); + top->AddCMap(0,1,2,3,4,i1,zero_real); + top->AddHarmonicPositionRestraint(0,zero_vec,r1,r2,r3,r4); + top->AddHarmonicDistanceRestraint(0,1,r1,r2); + } + + //following interactions are unique for a pair of atoms + top->AddLJPair(0,1,r1,r2); + top->AddDistanceConstraint(0,1,r1); + top->AddExclusion(0,1); + + //errors should be thrown, when previously added interactions are added again + BOOST_CHECK_THROW(top->AddLJPair(0,1,r1,r2), ost::Error); + BOOST_CHECK_THROW(top->AddDistanceConstraint(0,1,r1), ost::Error); + BOOST_CHECK_THROW(top->AddExclusion(0,1), ost::Error); + BOOST_CHECK_THROW(top->AddLJPair(1,0,r1,r2), ost::Error); + BOOST_CHECK_THROW(top->AddDistanceConstraint(1,0,r1), ost::Error); + BOOST_CHECK_THROW(top->AddExclusion(1,0), ost::Error); + + //check set and get parameter stuff, but also the GetIndices functionality + std::vector<uint> ind1,ind2; + top->SetHarmonicBondParameters(0,0.5,15.0); + top->GetHarmonicBondParameters(0,ui1,ui2,r1,r2); + BOOST_CHECK(r1 == 0.5 && r2 == 15.0); + ind1 = top->GetHarmonicBondIndices(0,1); + ind2 = top->GetHarmonicBondIndices(1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetHarmonicBondIndices(0).size() == 10); + BOOST_CHECK(top->GetHarmonicBondIndices(1).size() == 10); + BOOST_CHECK(top->GetHarmonicBondIndices(2).size() == 0); + + + top->SetHarmonicAngleParameters(0,1.0,10.0); + top->GetHarmonicAngleParameters(0,ui1,ui2,ui3,r1,r2); + BOOST_CHECK(r1 == 1.0 && r2 == 10.0); + ind1 = top->GetHarmonicAngleIndices(0,1,2); + ind2 = top->GetHarmonicAngleIndices(2,1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetHarmonicAngleIndices(0).size() == 10); + BOOST_CHECK(top->GetHarmonicAngleIndices(1).size() == 10); + BOOST_CHECK(top->GetHarmonicAngleIndices(2).size() == 10); + BOOST_CHECK(top->GetHarmonicAngleIndices(3).size() == 0); + + top->SetUreyBradleyAngleParameters(0,0.5,0.5,0.5,0.5); + top->GetUreyBradleyAngleParameters(0,ui1,ui2,ui3,r1,r2,r3,r4); + BOOST_CHECK( r1 == 0.5 && r2 == 0.5 && r3 == 0.5 && r3 == 0.5 ); + ind1 = top->GetUreyBradleyAngleIndices(0,1,2); + ind2 = top->GetUreyBradleyAngleIndices(2,1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetUreyBradleyAngleIndices(0).size() == 10); + BOOST_CHECK(top->GetUreyBradleyAngleIndices(1).size() == 10); + BOOST_CHECK(top->GetUreyBradleyAngleIndices(2).size() == 10); + BOOST_CHECK(top->GetUreyBradleyAngleIndices(3).size() == 0); + + + top->SetPeriodicDihedralParameters(0,2,5.0,0.5); + top->GetPeriodicDihedralParameters(0,ui1,ui2,ui3,ui4,i1,r1,r2); + BOOST_CHECK( i5 == 0 && r1 == 5.0 && r2 == 0.5 ); + ind1 = top->GetPeriodicDihedralIndices(0,1,2,3); + ind2 = top->GetPeriodicDihedralIndices(3,2,1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetPeriodicDihedralIndices(0).size() == 10); + BOOST_CHECK(top->GetPeriodicDihedralIndices(1).size() == 10); + BOOST_CHECK(top->GetPeriodicDihedralIndices(2).size() == 10); + BOOST_CHECK(top->GetPeriodicDihedralIndices(3).size() == 10); + BOOST_CHECK(top->GetPeriodicDihedralIndices(4).size() == 0); + + top->SetPeriodicImproperParameters(6,2,2.0,1.0); + top->GetPeriodicImproperParameters(6,ui1,ui2,ui3,ui4,i1,r1,r2); + BOOST_CHECK( i5 == 0 && r1 == 2.0 && r2 == 1.0 ); + ind1 = top->GetPeriodicImproperIndices(0,1,2,3); + ind2 = top->GetPeriodicImproperIndices(3,2,1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetPeriodicImproperIndices(0).size() == 10); + BOOST_CHECK(top->GetPeriodicImproperIndices(1).size() == 10); + BOOST_CHECK(top->GetPeriodicImproperIndices(2).size() == 10); + BOOST_CHECK(top->GetPeriodicImproperIndices(3).size() == 10); + BOOST_CHECK(top->GetPeriodicImproperIndices(4).size() == 0); + + top->SetHarmonicImproperParameters(0,4.0,4.0); + top->GetHarmonicImproperParameters(0,ui1,ui2,ui3,ui4,r1,r2); + BOOST_CHECK(r1 == 4.0 && r2 == 4.0); + ind1 = top->GetHarmonicImproperIndices(0,1,2,3); + ind2 = top->GetHarmonicImproperIndices(3,2,1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetHarmonicImproperIndices(0).size() == 10); + BOOST_CHECK(top->GetHarmonicImproperIndices(1).size() == 10); + BOOST_CHECK(top->GetHarmonicImproperIndices(2).size() == 10); + BOOST_CHECK(top->GetHarmonicImproperIndices(3).size() == 10); + BOOST_CHECK(top->GetHarmonicImproperIndices(4).size() == 0); + + std::vector<Real> one_real(1); + one_real[0] = 42; + top->SetCMapParameters(0,1,one_real); + std::vector<Real> temp_real; + top->GetCMapParameters(0,ui1,ui2,ui3,ui4,ui5,i1,temp_real); + BOOST_CHECK( ui1 == 0 && temp_real.size() == 1 && temp_real[0] == 42); + ind1 = top->GetCMapIndices(0,1,2,3,4); + ind2 = top->GetCMapIndices(4,3,2,1,0); + BOOST_CHECK(ind1.size() == 10); + BOOST_CHECK(ind2.size() == 0); //cmaps are sensitive for the ordering!! + BOOST_CHECK(top->GetCMapIndices(0).size() == 10); + BOOST_CHECK(top->GetCMapIndices(1).size() == 10); + BOOST_CHECK(top->GetCMapIndices(2).size() == 10); + BOOST_CHECK(top->GetCMapIndices(3).size() == 10); + BOOST_CHECK(top->GetCMapIndices(4).size() == 10); + BOOST_CHECK(top->GetCMapIndices(5).size() == 0); + + top->SetLJPairParameters(0,3.5,4.5); + top->GetLJPairParameters(0,ui1,ui2,r1,r2); + BOOST_CHECK( r1 == 3.5 && r2 == 4.5 ); + i1 = top->GetLJPairIndex(0,1); + i5 = top->GetLJPairIndex(1,0); + BOOST_CHECK(i1 == i5 && i1 != -1); + BOOST_CHECK(top->GetLJPairIndices(0).size() == 1); + BOOST_CHECK(top->GetLJPairIndices(1).size() == 1); + BOOST_CHECK(top->GetLJPairIndices(2).size() == 0); + + top->SetDistanceConstraintParameters(0,42.0); + top->GetDistanceConstraintParameters(0,ui1,ui2,r1); + BOOST_CHECK( r1 == 42.0 ); + i1 = top->GetDistanceConstraintIndex(0,1); + i5 = top->GetDistanceConstraintIndex(1,0); + BOOST_CHECK(i1 == i5 && i1 != -1); + + top->SetHarmonicPositionRestraintParameters(0,test_vec,3.0); + top->GetHarmonicPositionRestraintParameters(0,ui1,zero_vec,r1,r2,r3,r4); + BOOST_CHECK(zero_vec == test_vec); + BOOST_CHECK(r1 == 3.0); + BOOST_CHECK(r2 == 1.0); //should be the same for r3 and r4 + //no reverse checking necessary + BOOST_CHECK(top->GetHarmonicPositionRestraintIndices(0).size() == 10); + BOOST_CHECK(top->GetHarmonicPositionRestraintIndices(1).size() == 0); + + top->SetHarmonicDistanceRestraintParameters(0,2.0,2.0); + top->GetHarmonicDistanceRestraintParameters(0,ui1,ui2,r1,r2); + BOOST_CHECK(r1 == 2.0 && r2 == 2.0); + ind1 = top->GetHarmonicDistanceRestraintIndices(0,1); + ind2 = top->GetHarmonicDistanceRestraintIndices(1,0); + BOOST_CHECK(ind1 == ind2 && ind1.size() == 10); + BOOST_CHECK(top->GetHarmonicDistanceRestraintIndices(0).size() == 10); + BOOST_CHECK(top->GetHarmonicDistanceRestraintIndices(1).size() == 10); + BOOST_CHECK(top->GetHarmonicDistanceRestraintIndices(2).size() == 0); + + ost::mol::EntityHandle top_test_ent = top->GetEntity(); + ost::mol::AtomHandleList atom_list = top_test_ent.GetAtomList(); + top->AddPositionConstraint(atom_list[0]); + BOOST_CHECK(top->GetNumPositionConstraints() == 1); + top->ResetPositionConstraints(); + BOOST_CHECK(top->GetNumPositionConstraints() == 0); +} + +BOOST_AUTO_TEST_CASE(test_topology_index_getters){ + + String pdb_name = "1CRN.pdb"; + ost::io::PDBReader reader(pdb_name, ost::io::IOProfile()); + ost::mol::EntityHandle test_ent = ost::mol::CreateEntity(); + reader.Import(test_ent); + ost::conop::ProcessorPtr processor(new ost::conop::HeuristicProcessor); + processor->Process(test_ent); + + //check initialisation without settings + std::vector<Real> fake_masses(test_ent.GetAtomCount()); + TopologyPtr top(new Topology(test_ent,fake_masses)); + test_ent = top->GetEntity(); //we do a copy in the constructor of the topology + + ost::mol::AtomHandleList atom_list = test_ent.GetAtomList(); + ost::mol::ResidueHandleList res_list = test_ent.GetResidueList(); + + for(uint i = 0; i < atom_list.size(); ++i){ + BOOST_CHECK(top->GetAtomIndex(atom_list[i]) == i); + } + for(uint i = 0; i < res_list.size(); ++i){ + BOOST_CHECK(top->GetResidueIndex(res_list[i]) == i); + } + + ost::mol::AtomHandle test_atom_one = res_list[10].FindAtom("CA"); + ost::mol::AtomHandle test_atom_two = res_list[9].FindAtom("CA"); + ost::mol::AtomHandle test_atom_three = res_list[11].FindAtom("CA"); + + uint index_one = top->GetAtomIndex(test_atom_one); + uint index_two = top->GetAtomIndex(test_atom_two); + uint index_three = top->GetAtomIndex(test_atom_three); + + BOOST_CHECK(top->GetAtomIndex(10,"CA") == index_one); + BOOST_CHECK(top->GetAtomIndex(10,"-CA") == index_two); + BOOST_CHECK(top->GetAtomIndex(10,"+CA") == index_three); +} + +BOOST_AUTO_TEST_CASE(test_topology_merge){ + + String pdb_name = "1CRN.pdb"; + ost::io::PDBReader reader(pdb_name, ost::io::IOProfile()); + ost::mol::EntityHandle test_ent = ost::mol::CreateEntity(); + reader.Import(test_ent); + + ForcefieldPtr ff = Forcefield::Load("CHARMM27.dat"); + MMSettingsPtr settings = MMSettingsPtr(new MMSettings); + settings->add_gbsa = true; + settings->forcefield = ff; + + ost::mol::EntityHandle new_ent = ost::mol::Builder() + .Chain("A") + .Residue("ONE") + .Atom("A",geom::Vec3(0,0,0)) + .Atom("B",geom::Vec3(1,1,1)) + .Residue("TWO") + .Atom("A",geom::Vec3(2,2,2)) + .Atom("B",geom::Vec3(3,3,3)) + .Residue("THREE") + .Atom("A",geom::Vec3(4,4,4)) + .Atom("B",geom::Vec3(5,5,5)); + + //check whether error gets thrown when chain with same name is already present + std::vector<Real> real_vec(6); + TopologyPtr merge_top_one(new Topology(new_ent,real_vec)); + merge_top_one->SetCharges(real_vec); + merge_top_one->SetOBCScalings(real_vec); + merge_top_one->SetGBSARadii(real_vec); + merge_top_one->SetSigmas(real_vec); + merge_top_one->SetEpsilons(real_vec); + merge_top_one->SetFudgeQQ(1.0); + merge_top_one->SetFudgeLJ(1.0); + TopologyPtr top_one = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_one->Merge(merge_top_one),ost::Error); + ost::mol::XCSEditor ed = new_ent.EditXCS(); + ed.RenameChain(new_ent.GetChainList()[0],"B"); + TopologyPtr merge_top_one_two(new Topology(new_ent,real_vec)); // I know... + merge_top_one_two->SetCharges(real_vec); + merge_top_one_two->SetOBCScalings(real_vec); + merge_top_one_two->SetGBSARadii(real_vec); + merge_top_one_two->SetSigmas(real_vec); + merge_top_one_two->SetEpsilons(real_vec); + merge_top_one_two->SetFudgeQQ(1.0); + merge_top_one_two->SetFudgeLJ(1.0); + BOOST_CHECK_NO_THROW(top_one->Merge(merge_top_one_two)); + + + //check whether error gets thrown, when fudge parameters are inconsistent + TopologyPtr merge_top_two(new Topology(new_ent,real_vec)); + merge_top_two->SetCharges(real_vec); + merge_top_two->SetOBCScalings(real_vec); + merge_top_two->SetGBSARadii(real_vec); + merge_top_two->SetSigmas(real_vec); + merge_top_two->SetEpsilons(real_vec); + merge_top_two->SetFudgeQQ(42.0); + merge_top_two->SetFudgeLJ(42.0); + TopologyPtr top_two = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_two->Merge(merge_top_two),ost::Error); + merge_top_two->SetFudgeQQ(1.0); + merge_top_two->SetFudgeLJ(1.0); + BOOST_CHECK_NO_THROW(top_two->Merge(merge_top_two)); + + + //check whether error gets thrown when charges are not set + TopologyPtr merge_top_three(new Topology(new_ent,real_vec)); + merge_top_three->SetOBCScalings(real_vec); + merge_top_three->SetGBSARadii(real_vec); + merge_top_three->SetSigmas(real_vec); + merge_top_three->SetEpsilons(real_vec); + merge_top_three->SetFudgeQQ(1.0); + merge_top_three->SetFudgeLJ(1.0); + TopologyPtr top_three = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_three->Merge(merge_top_three),ost::Error); + TopologyPtr top_three_two = TopologyCreator::Create(test_ent,settings); + merge_top_three->SetCharges(real_vec); + BOOST_CHECK_NO_THROW(top_three_two->Merge(merge_top_three)); + + //check whether error gets thrown when obc scaling factors are not set + TopologyPtr merge_top_four(new Topology(new_ent,real_vec)); + merge_top_four->SetCharges(real_vec); + merge_top_four->SetGBSARadii(real_vec); + merge_top_four->SetSigmas(real_vec); + merge_top_four->SetEpsilons(real_vec); + merge_top_four->SetFudgeQQ(1.0); + merge_top_four->SetFudgeLJ(1.0); + TopologyPtr top_four = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_four->Merge(merge_top_four),ost::Error); + TopologyPtr top_four_two = TopologyCreator::Create(test_ent,settings); + merge_top_four->SetOBCScalings(real_vec); + BOOST_CHECK_NO_THROW(top_four_two->Merge(merge_top_four)); + + //check whether error gets thrown when gbsa radii are not set + TopologyPtr merge_top_five(new Topology(new_ent,real_vec)); + merge_top_five->SetCharges(real_vec); + merge_top_five->SetOBCScalings(real_vec); + merge_top_five->SetSigmas(real_vec); + merge_top_five->SetEpsilons(real_vec); + merge_top_five->SetFudgeQQ(1.0); + merge_top_five->SetFudgeLJ(1.0); + TopologyPtr top_five = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_five->Merge(merge_top_five),ost::Error); + TopologyPtr top_five_two = TopologyCreator::Create(test_ent,settings); + merge_top_five->SetGBSARadii(real_vec); + BOOST_CHECK_NO_THROW(top_five_two->Merge(merge_top_five)); + + //check whether error gets thrown when sigmas are not set + TopologyPtr merge_top_six(new Topology(new_ent,real_vec)); + merge_top_six->SetCharges(real_vec); + merge_top_six->SetOBCScalings(real_vec); + merge_top_six->SetGBSARadii(real_vec); + merge_top_six->SetEpsilons(real_vec); + merge_top_six->SetFudgeQQ(1.0); + merge_top_six->SetFudgeLJ(1.0); + TopologyPtr top_six = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_six->Merge(merge_top_six),ost::Error); + TopologyPtr top_six_two = TopologyCreator::Create(test_ent,settings); + merge_top_six->SetSigmas(real_vec); + BOOST_CHECK_NO_THROW(top_six_two->Merge(merge_top_six)); + + //check whether error gets thrown when epsilons are not set + TopologyPtr merge_top_seven(new Topology(new_ent,real_vec)); + merge_top_seven->SetCharges(real_vec); + merge_top_seven->SetOBCScalings(real_vec); + merge_top_seven->SetGBSARadii(real_vec); + merge_top_seven->SetSigmas(real_vec); + merge_top_seven->SetFudgeQQ(1.0); + merge_top_seven->SetFudgeLJ(1.0); + TopologyPtr top_seven = TopologyCreator::Create(test_ent,settings); + BOOST_CHECK_THROW(top_seven->Merge(merge_top_seven),ost::Error); + TopologyPtr top_seven_two = TopologyCreator::Create(test_ent,settings); + merge_top_seven->SetEpsilons(real_vec); + BOOST_CHECK_NO_THROW(top_seven_two->Merge(merge_top_seven)); + + TopologyPtr merge_top_eight(new Topology(new_ent,real_vec)); + merge_top_eight->SetCharges(real_vec); + merge_top_eight->SetOBCScalings(real_vec); + merge_top_eight->SetGBSARadii(real_vec); + merge_top_eight->SetSigmas(real_vec); + merge_top_eight->SetFudgeQQ(1.0); + merge_top_eight->SetFudgeLJ(1.0); + merge_top_eight->SetEpsilons(real_vec); + + //let's add every possible interaction + + merge_top_eight->AddHarmonicBond(0,1,42.0,42000.0); + merge_top_eight->AddHarmonicAngle(0,1,2,24.0,24000.0); + merge_top_eight->AddUreyBradleyAngle(1,2,3,1.0,2.0,3.0,4.0); + merge_top_eight->AddPeriodicDihedral(0,1,2,3,10,2.0,42.0); + merge_top_eight->AddPeriodicImproper(1,2,3,4,3,5.0,10.0); + merge_top_eight->AddHarmonicImproper(0,1,2,3,8.0,12.0); + std::vector<Real> cmap; + cmap.push_back(0.0); + cmap.push_back(1.0); + cmap.push_back(2.0); + cmap.push_back(3.0); + merge_top_eight->AddCMap(0,1,2,3,4,2,cmap); + merge_top_eight->AddLJPair(3,4,1.0,2.0); + merge_top_eight->AddDistanceConstraint(2,3,10.0); + merge_top_eight->AddExclusion(3,4); + merge_top_eight->AddPositionConstraint(2); + geom::Vec3 pos(1.0,2.0,3.0); + merge_top_eight->AddHarmonicPositionRestraint(2,pos,10.0,5.0,6.0,7.0); + merge_top_eight->AddHarmonicDistanceRestraint(1,2,10.0,1000.0); + + TopologyPtr top_eight = TopologyCreator::Create(test_ent,settings);\ + + uint num_harmonic_bonds = top_eight->GetNumHarmonicBonds(); + uint num_harmonic_angles = top_eight->GetNumHarmonicAngles(); + uint num_urey_bradley_angles = top_eight->GetNumUreyBradleyAngles(); + uint num_periodic_dihedrals = top_eight->GetNumPeriodicDihedrals(); + uint num_periodic_impropers = top_eight->GetNumPeriodicImpropers(); + uint num_harmonic_impropers = top_eight->GetNumHarmonicImpropers(); + uint num_cmaps = top_eight->GetNumCMaps(); + uint num_lj_pairs = top_eight->GetNumLJPairs(); + uint num_distance_constraints = top_eight->GetNumDistanceConstraints(); + uint num_exclusions = top_eight->GetNumExclusions(); + uint num_position_constraints = top_eight->GetNumPositionConstraints(); + uint num_harmonic_position_restraints = top_eight->GetNumHarmonicPositionRestraints(); + uint num_harmonic_distance_restraints = top_eight->GetNumHarmonicDistanceRestraints(); + + top_eight->Merge(merge_top_eight); + + BOOST_CHECK(top_eight->GetNumHarmonicBonds() == num_harmonic_bonds+1); + BOOST_CHECK(top_eight->GetNumHarmonicAngles() == num_harmonic_angles+1); + BOOST_CHECK(top_eight->GetNumUreyBradleyAngles() == num_urey_bradley_angles+1); + BOOST_CHECK(top_eight->GetNumPeriodicDihedrals() == num_periodic_dihedrals+1); + BOOST_CHECK(top_eight->GetNumPeriodicImpropers() == num_periodic_impropers+1); + BOOST_CHECK(top_eight->GetNumHarmonicImpropers() == num_harmonic_impropers+1); + BOOST_CHECK(top_eight->GetNumCMaps() == num_cmaps+1); + BOOST_CHECK(top_eight->GetNumLJPairs() == num_lj_pairs+1); + BOOST_CHECK(top_eight->GetNumDistanceConstraints() == num_distance_constraints+1); + BOOST_CHECK(top_eight->GetNumExclusions() == num_exclusions+1); + BOOST_CHECK(top_eight->GetNumPositionConstraints() == num_position_constraints+1); + BOOST_CHECK(top_eight->GetNumHarmonicPositionRestraints() == num_harmonic_position_restraints+1); + BOOST_CHECK(top_eight->GetNumHarmonicDistanceRestraints() == num_harmonic_distance_restraints+1); + + + //check wether the new indices are right... + ost::mol::EntityHandle top_ent = top_eight->GetEntity(); + ost::mol::ChainHandle top_chain = top_ent.FindChain("B"); + ost::mol::ResidueHandleList res_list = top_chain.GetResidueList(); + ost::mol::AtomHandleList atom_list = top_chain.GetAtomList(); + uint res_index_one = top_eight->GetResidueIndex(res_list[0]); + uint res_index_two = top_eight->GetResidueIndex(res_list[1]); + uint res_index_three = top_eight->GetResidueIndex(res_list[2]); + uint atom_index_zero = top_eight->GetAtomIndex(res_index_one,"A"); + uint atom_index_one = top_eight->GetAtomIndex(res_index_one,"B"); + uint atom_index_two = top_eight->GetAtomIndex(res_index_two,"A"); + uint atom_index_three = top_eight->GetAtomIndex(res_index_two,"B"); + uint atom_index_four = top_eight->GetAtomIndex(res_index_three,"A"); + uint atom_index_five = top_eight->GetAtomIndex(res_index_three,"B"); + + BOOST_CHECK(atom_index_zero == top_eight->GetAtomIndex(atom_list[0])); + BOOST_CHECK(atom_index_one == top_eight->GetAtomIndex(atom_list[1])); + BOOST_CHECK(atom_index_two == top_eight->GetAtomIndex(atom_list[2])); + BOOST_CHECK(atom_index_three == top_eight->GetAtomIndex(atom_list[3])); + BOOST_CHECK(atom_index_four == top_eight->GetAtomIndex(atom_list[4])); + BOOST_CHECK(atom_index_five == top_eight->GetAtomIndex(atom_list[5])); + + //check whether the unique interactions are properly mapped + BOOST_CHECK_THROW(top_eight->AddExclusion(atom_index_three,atom_index_four),ost::Error); + BOOST_CHECK_THROW(top_eight->AddDistanceConstraint(atom_index_two,atom_index_three,10.0),ost::Error); + BOOST_CHECK_THROW(top_eight->AddLJPair(atom_index_three,atom_index_four,1.0,2.0),ost::Error); + + //check whether the interactions are properly added (we do not check the correct parametrization at this point) + + std::vector<uint> harmonic_bond_indices = top_eight->GetHarmonicBondIndices(atom_index_zero,atom_index_one); + std::vector<uint> harmonic_angle_indices = top_eight->GetHarmonicAngleIndices(atom_index_zero,atom_index_one,atom_index_two); + std::vector<uint> urey_bradley_angle_indices = top_eight->GetUreyBradleyAngleIndices(atom_index_one,atom_index_two,atom_index_three); + std::vector<uint> periodic_dihedral_indices = top_eight->GetPeriodicDihedralIndices(atom_index_zero,atom_index_one,atom_index_two,atom_index_three); + std::vector<uint> periodic_improper_indices = top_eight->GetPeriodicImproperIndices(atom_index_one,atom_index_two,atom_index_three,atom_index_four); + std::vector<uint> harmonic_improper_indices = top_eight->GetHarmonicImproperIndices(atom_index_zero,atom_index_one,atom_index_two,atom_index_three); + std::vector<uint> cmap_indices = top_eight->GetCMapIndices(atom_index_zero,atom_index_one,atom_index_two,atom_index_three,atom_index_four); + int lj_pair_index = top_eight->GetLJPairIndex(atom_index_three,atom_index_four); + int distance_constraint_index = top_eight->GetDistanceConstraintIndex(atom_index_two,atom_index_three); + std::vector<uint> harmonic_distance_restraint_indices = top_eight->GetHarmonicDistanceRestraintIndices(atom_index_one,atom_index_two); + std::vector<uint> harmonic_position_restraint_indices = top_eight->GetHarmonicPositionRestraintIndices(atom_index_two); + + BOOST_CHECK(harmonic_bond_indices.size() == 1); + BOOST_CHECK(harmonic_angle_indices.size() == 1); + BOOST_CHECK(urey_bradley_angle_indices.size() == 1); + BOOST_CHECK(periodic_dihedral_indices.size() == 1); + BOOST_CHECK(periodic_improper_indices.size() == 1); + BOOST_CHECK(harmonic_improper_indices.size() == 1); + BOOST_CHECK(cmap_indices.size() == 1); + BOOST_CHECK(harmonic_distance_restraint_indices.size() == 1); + BOOST_CHECK(harmonic_position_restraint_indices.size() == 1); + BOOST_CHECK(lj_pair_index != -1); + BOOST_CHECK(distance_constraint_index != -1); + + + //let's finally check the parameters + + uint ui0,ui1,ui2,ui3,ui4; + int i0; + Real r0,r1,r2,r3; + geom::Vec3 v0; + + top_eight->GetHarmonicBondParameters(harmonic_bond_indices[0],ui0,ui1,r0,r1); + BOOST_CHECK(r0 = 42.0 && r1 == 42000.0); + + top_eight->GetHarmonicAngleParameters(harmonic_angle_indices[0],ui0,ui1,ui2,r0,r1); + BOOST_CHECK(r0 == 24.0 && r1 == 24000.0); + + top_eight->GetUreyBradleyAngleParameters(urey_bradley_angle_indices[0],ui0,ui1,ui2,r0,r1,r2,r3); + BOOST_CHECK(r0 == 1.0 && r1 == 2.0 && r2 == 3.0 && r3 == 4.0); + + top_eight->GetPeriodicDihedralParameters(periodic_dihedral_indices[0],ui0,ui1,ui2,ui3,i0,r0,r1); + BOOST_CHECK(i0 == 10 && r0 == 2.0 && r1 == 42.0); + + top_eight->GetPeriodicImproperParameters(periodic_improper_indices[0],ui0,ui1,ui2,ui3,i0,r0,r1); + BOOST_CHECK(i0 == 3 && r0 == 5.0 && r1 == 10.0); + + top_eight->GetHarmonicImproperParameters(harmonic_improper_indices[0],ui0,ui1,ui2,ui3,r0,r1); + BOOST_CHECK(r0 == 8.0 && r1 == 12.0); + + top_eight->GetCMapParameters(cmap_indices[0],ui0,ui1,ui2,ui3,ui4,i0,real_vec); + BOOST_CHECK(real_vec == cmap && i0 == 2); + + top_eight->GetLJPairParameters(lj_pair_index,ui0,ui1,r0,r1); + BOOST_CHECK(r0 == 1.0 && r1 == 2.0); + + top_eight->GetDistanceConstraintParameters(distance_constraint_index,ui0,ui1,r0); + BOOST_CHECK(r0 == 10.0); + + top_eight->GetHarmonicPositionRestraintParameters(harmonic_position_restraint_indices[0],ui0,v0,r0,r1,r2,r3); + BOOST_CHECK(v0 == pos && r0 == 10.0 && r1 == 5.0 && r2 == 6.0 && r3 == 7.0); + + top_eight->GetHarmonicDistanceRestraintParameters(harmonic_distance_restraint_indices[0],ui0,ui1,r0,r1); + BOOST_CHECK(r0 == 10.0 && r1 == 1000.0); + +} + + +BOOST_AUTO_TEST_SUITE_END(); \ No newline at end of file diff --git a/modules/mol/mm/tests/tests.cc b/modules/mol/mm/tests/tests.cc new file mode 100644 index 0000000000000000000000000000000000000000..8fb5bbd47707615b1702765ff363cf8525716942 --- /dev/null +++ b/modules/mol/mm/tests/tests.cc @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE ost_mol_base +#define BOOST_AUTO_TEST_MAIN +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +