diff --git a/.gitignore b/.gitignore index 05c992e3f9ddc3fb38323fbdc356c996822989a0..ae5ec6bffbcb2ec43587ee1e400c83dcc2758019 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ pov_*test.inc *-out.crd *-out.pqr *-out.png +*_out.dcd +*_out.pdb CMakeLists.txt.user OpenStructure.cbp DartConfiguration.tcl diff --git a/CMakeLists.txt b/CMakeLists.txt index 03496411dcccee60289cb1a4b407abc9a6f0040e..059cda055f99b067df0acfb7caf07036780d1af7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,11 @@ if (ENABLE_SPNAV) find_package(SpNav REQUIRED) endif() +if (CMAKE_COMPILER_IS_GNUCXX) + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-strict-aliasing" CACHE STRING "" FORCE) +endif() + + # basic environment include_directories(${Boost_INCLUDE_DIRS} ${FFTW_INCLUDE_PATH} diff --git a/cmake_support/OST.cmake b/cmake_support/OST.cmake index 06457ad71f30651589b40be1b94fe7a710b243e4..70305fbb0142eccdf605611d1e68f702cd0bd756 100644 --- a/cmake_support/OST.cmake +++ b/cmake_support/OST.cmake @@ -166,6 +166,7 @@ macro(module) file(MAKE_DIRECTORY ${LIB_STAGE_PATH}) file(MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) file(MAKE_DIRECTORY ${LIBEXEC_STAGE_PATH}) + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/tests") if (NOT TARGET make_stage_lib_dir) add_custom_target(make_stage_lib_dir COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_STAGE_PATH}) endif() @@ -175,6 +176,9 @@ macro(module) if (NOT TARGET make_libexec_dir) add_custom_target(make_libexec_dir COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBEXEC_STAGE_PATH}) endif() + if (NOT TARGET make_tests_dir) + add_custom_target(make_tests_dir COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/tests") + endif() if (WIN32) set(_ABS_FILE_PATTERN "^[A-Z]:/") else() @@ -204,6 +208,7 @@ macro(module) add_dependencies(${_LIB_NAME} make_stage_lib_dir) add_dependencies(${_LIB_NAME} make_executable_output_dir) add_dependencies(${_LIB_NAME} make_libexec_dir) + add_dependencies(${_LIB_NAME} make_tests_dir) set_target_properties(${_LIB_NAME} PROPERTIES COMPILE_DEFINITIONS OST_MODULE_${_UPPER_LIB_NAME}) set_target_properties(${_LIB_NAME} PROPERTIES @@ -215,7 +220,7 @@ macro(module) RUNTIME_OUTPUT_DIRECTORY ${LIB_STAGE_PATH}) if (APPLE) set_target_properties(${_LIB_NAME} PROPERTIES - LINK_FLAGS "-Wl,-rpath,@@loader_path" + LINK_FLAGS "-Wl,-rpath,@loader_path" INSTALL_NAME_DIR "@rpath") endif() if (WIN32) @@ -303,9 +308,9 @@ macro(executable) message(FATAL_ERROR "invalid use of executable(): a name must be provided") endif() add_executable(${_ARG_NAME} ${_ARG_SOURCES}) - if (APPLE AND NOT _ARG_NO_RPATH AND NOT _ARG_STATIC) + if (APPLE AND NOT _ARG_NO_RPATH AND NOT ENABLE_STATIC) set_target_properties(${_ARG_NAME} PROPERTIES - LINK_FLAGS "-Wl,-rpath,@loader_path/../lib") + LINK_FLAGS "-Wl,-rpath,@loader_path/../lib/") endif() if (_ARG_LINK) target_link_libraries(${_ARG_NAME} ${_ARG_LINK}) @@ -350,7 +355,7 @@ macro(executable_libexec) "${LIBEXEC_STAGE_PATH}") if (APPLE AND NOT _ARG_NO_RPATH AND NOT _ARG_STATIC) set_target_properties(${_ARG_NAME} PROPERTIES - LINK_FLAGS "-Wl,-rpath,@loader_path/../lib") + LINK_FLAGS "-Wl,-rpath,@loader_path/../../lib") endif() if (_ARG_LINK) target_link_libraries(${_ARG_NAME} ${_ARG_LINK}) diff --git a/deployment/linux/README.txt b/deployment/linux/README.txt index 2f1ab3010a1c0854b08e58e45337296f3fe4938a..02beeb3f36f18f170a6b1c4768120552ff2c1c70 100644 --- a/deployment/linux/README.txt +++ b/deployment/linux/README.txt @@ -3,4 +3,5 @@ HOW TO USE THE BUNDLE SCRIPTS: 1. Checkout a copy of the OpenStructure repository. 2. Move to the <OpenStructure folder>/deployment/linux folder and start the create_bundle.py script using python 3. In <OpenStructure> you'll find a tar.gz file. That's the bundle! -4. If the process stops without completing, run the reset_repository.py script or delete the <OpenStructure Folder> and restart from scratch +4. If the process stops without completing, reset the repository with 'git +reset --hard HEAD' from the top level directory diff --git a/deployment/linux/create_bundle_alt.py b/deployment/linux/create_bundle_alt.py deleted file mode 100755 index 6e5cf9bcf26311b4d7e1acd2ee61a18b9fc36a9f..0000000000000000000000000000000000000000 --- a/deployment/linux/create_bundle_alt.py +++ /dev/null @@ -1,183 +0,0 @@ -import os,os.path -import shutil -import sys -import tarfile -import subprocess -import re - -def get_libdir(): - machine=os.uname()[4] - if machine.find('x86_64') !=-1: - return 'lib64' - else: - return 'lib' - -def get_arch(): - machine=os.uname()[4] - if machine.find('x86_64') !=-1: - return '64bit' - else: - return '32bit' - -def clean(standalonedir): - if os.path.exists(standalonedir): - shutil.rmtree(standalonedir) - -def copy_stage(stagedir,standalonedir): - libdir=get_libdir() - copytree_ex(os.path.join(stagedir,'bin'),os.path.join(standalonedir,'bin')) - copytree_ex(os.path.join(stagedir,libdir),os.path.join(standalonedir,libdir)) - if os.path.exists(os.path.join(stagedir,'share')): - copytree_ex(os.path.join(stagedir,'share'),os.path.join(standalonedir,'share')) - -def collect_deps(binaries,exclude_list): - dependencies=set() - for binary in binaries: - collect_deps_recursive_(binary,dependencies,exclude_list) - return dependencies - -def collect_deps_recursive_(binary,collected,exclude_list): - ldd_stdout=subprocess.Popen(['ldd',binary],stdout=subprocess.PIPE).stdout - output=ldd_stdout.readlines() - new_dependencies=set() - for entry in output: - if entry.find("statically linked")!=-1: - continue - sp=entry.split('(0x') - if len(sp)>0: # only continue if line is dependency - sp2=sp[0].split('=>',1)[-1].split() - if sp2: #ensure libname exists (fix for virtual linux-gate) - text=sp2[0] - if not text.split('.')[0].split('/')[-1] in exclude_list and not text in collected: - collect_deps_recursive_(text,collected,exclude_list) - collected.add(text) - - -def copy_deps(binaries,standalonedir,exclude_list): - dependencies=set() - walk_list=os.walk(standalonedir) - binaries_list=[] - for dir_entry in walk_list: - for file_entry in dir_entry[2]: - if file_entry.endswith('.so') or file_entry in binaries: - filepath=os.path.join(dir_entry[0],file_entry) - binaries_list.append(filepath) - dependencies=collect_deps(binaries_list,exclude_list) - for dep in dependencies: - shutil.copy2(dep,os.path.join(standalonedir,get_libdir())) - -def copy_examples(stagedir): - #todo - pass -def copy_qt_plugins(): - #todo - pass - -def process_scripts(scripts,standalonedir): - for script in scripts: - fp=open(os.path.join(standalonedir,'bin',script),'r') - text=fp.read() - fp.close() - text=re.sub('#export PYTHONPATH','export PYTHONPATH',text) - fp=open(os.path.join(standalonedir,'bin',script),'w') - fp.write(text) - fp.close() - -def create_package(name,standalonedir): - try: - import pysvn - try: - client=pysvn.Client() - svn_info=client.info('.') - revstring='-rev'+str(svn_info['revision'.number]) - except pysvn.ClientError: - print 'No svn directory found. Addin no revision number.' - revstring='' - except ImportError: - print 'Pysvn not installed. Adding no revision number.' - revstring='' - tar_name=name+'-linux-'+get_arch()+revstring+'.tgz' - if os.path.exists(tar_name): - os.remove(tar_name) - tar = tarfile.open(tar_name, "w:gz") - tar.add(standalonedir,name+'-linux-'+get_arch()+revstring) - tar.close() - -def ignorer(dirpath,files): - ignores=[] - for f in files: - base=os.path.splitext(f)[0] - if f.endswith('.py'): - if base+'.pyc' in files or base+'.pyo' in files: - ignores.append(f) - elif f.endswith('.pyc'): - if base+'.pyo' in files: - ignores.append(f) - return ignores - -def copy_python_dirs(standalonedir): - dirs=sys.path[1:] - dirs.sort() #get toplevel dir to the beginning - toplevel=dirs[0] - shutil.copytree(toplevel,os.path.join(standalonedir,get_libdir(),'python'),ignore=ignorer) - for d in dirs[1:]: - if not d.startswith(toplevel) and os.path.isdir(d): - toplevel=d - copytree_ex(toplevel,os.path.join(standalonedir,get_libdir(),'python'),ignore=ignorer) - - -def copytree_ex(source,destination, symlinks=False,ignore=None): - if not os.path.exists(destination): - shutil.copytree(source,destination,symlinks,ignore) - elif os.path.isdir(destination): - files=os.listdir(source) - if ignore: - ignores=ignore(source,files) - else: - ignores=[] - for f in files: - srcname=os.path.join(source,f) - dstname=os.path.join(destination,f) - if os.path.isdir(os.path.join(source,f)): - copytree_ex(srcname,dstname,symlinks,ignore=ignorer) - elif f not in ignores: - if symlinks and os.path.islink(srcname): - linkto = os.readlink(srcname) - os.symlink(linkto, dstname) - else: - shutil.copy2(srcname, dstname) - else: - raise IOError("destination is not a directory") - - - -############ main script #################### - -stagedir='../../stage' -ost_stagedir='../../../openstructure/stage' -standalonedir=os.path.join(os.getcwd(),'standalone') -binaries=['gosty'] -exclude_list=['ld-linux','libexpat','libgcc_s','libglib','cmov','libice','libSM','libX','libg','libGL','libfontconfig','libfreetype','libdrm','libxcb','libICE'] -scripts=['dng','ost'] - -#compile_stage() - -clean(standalonedir) -print 'copying stage' -copy_stage(stagedir,standalonedir) -print 'copying ost stage' -copy_stage(ost_stagedir,standalonedir) -print 'copying python' -shutil.copy(sys.executable,os.path.join(stagedir,'bin')) -copy_python_dirs(standalonedir) -print 'copying dependencies' -binaries.append(sys.executable) -copy_deps(binaries,standalonedir,exclude_list) -print 'copying examples' -copy_examples(stagedir) -print 'copying plugins' -copy_qt_plugins() -print 'processing scripts' -process_scripts(scripts,standalonedir) -print 'creating package' -create_package('openstructure','standalone') diff --git a/deployment/linux/create_bundle.py b/deployment/linux/create_bundle_lucid.py similarity index 58% rename from deployment/linux/create_bundle.py rename to deployment/linux/create_bundle_lucid.py index 3f04533f0c4d6c3f84e907a0f73099bdf5988929..21a1dfcbb63c21c624740fff13c34c23b9b8b842 100644 --- a/deployment/linux/create_bundle.py +++ b/deployment/linux/create_bundle_lucid.py @@ -4,31 +4,56 @@ import subprocess import string import sys import datetime +import sip +import PyQt4 -# custom parameters +# parameters that can be modified +qt4_plugins_location='/usr/lib/qt4/plugins' +ssl_crypto_location='/lib/' +chemlib_dictionary_location='/home/bundler/compounds.chemlib' +list_of_excluded_libraries=[ +'ld-linux', +'libexpat', +'libgcc_s', +'libglib', +'cmov', +'libice', +'libSM', +'libX', +'libg', +'libGL.so', +'libfontconfig', +'libfreetype', +'libdrm', +'libxcb', +'libICE', +'libnvidia', +'libc' +] -if len(sys.argv) < 3: - print 'usage: create_bundle.py additional_label system_python_version' +if len(sys.argv) < 2: + print 'usage: create_bundle.py additional_label' sys.exit() -system_python_version='python'+sys.argv[2] -system_python_bin='/usr/bin/'+system_python_version -system_python_libs='/usr/lib/'+system_python_version -second_system_python_libs_flag=True -second_system_python_libs='/usr/lib/pymodules/'+system_python_version -python_bin_in_bundle='python' -qt4_plugins='/usr/lib/qt4/plugins' additional_label=sys.argv[1] -list_of_excluded_libraries=['ld-linux','libexpat','libgcc_s','libglib','cmov','libice','libSM','libX','libg','libGL.so','libfontconfig','libfreetype','libdrm','libxcb','libICE','libnvidia','libc'] + currdir=os.getcwd() if currdir.find('deployment')==-1 or currdir.find('linux')==-1: print '\n' print 'ERROR: Please run this script from the deployment/linux directory' print '\n' sys.exit() + +print "WARNING: If this script does not run to completion, please run 'git reset --hard HEAD' in the main directory (two up from here) before restarting" + +system_python_version=sys.version_info +system_python_executable='python'+str(system_python_version[0])+'.'+str(system_python_version[1]) +system_python_bin='/usr/bin/'+system_python_executable +system_python_libs='/usr/lib/'+system_python_executable +qt4_module_location=os.path.dirname(PyQt4.__file__) +sip_module_location=os.path.dirname(sip.__file__) print '\n' -print 'WARNING: If this script does not run to completion, please run the reset_repository.py script before restarting' print '\n' print 'Detecting architecture and revision' uname_output=subprocess.Popen('uname -a', shell=True, cwd='../../',stdout=subprocess.PIPE).stdout @@ -39,26 +64,16 @@ if uname_line[0].find('x86_64') !=-1: else: libdir='lib' archstring='32bit' -date_pattern='%Y-%b-%d' -build=datetime.date.today() -directory_name='openstructure-linux-'+archstring+'-'+additional_label+'-'+str(build) +directory_name='openstructure-linux-'+archstring+'-'+additional_label print 'Hardcoding package python binary path in openstructure executables' +subprocess.call('rm -f scripts/ost_config.in.pre* scripts/ost_config.in.backup',shell=True,cwd='../../') subprocess.call('mv scripts/ost_config.in scripts/ost_config.in.backup',shell=True,cwd='../../') -subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/'+python_bin_in_bundle+'/g" scripts/ost_config.in.backup > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.preprepre',shell=True,cwd='../../') subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.prepre > scripts/ost_config.in.pre',shell=True,cwd='../../') subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/ost_config.in.pre > scripts/ost_config.in',shell=True,cwd='../../') -#print 'Downloading Chemlib dictionary' -#subprocess.call('wget ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif', shell=True, cwd='../../') -#print 'Compiling Openstructure' -#subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DBoost_COMPILER='+boost_string+'-DENABLE_IMG=OFF -DENABLE_UI=OFF -DENABLE_GFX=OFF', shell=True,cwd='../../') -#subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' s-DENABLE_IMG=OFF -DENABLE_UI=OFF -DENABLE_GFX=OFF', shell=True,cwd='../../') -#subprocess.call('make -j5',shell=True,cwd='../../') -##print 'Converting Chemlib dictionary' -##subprocess.call('stage/bin/chemdict_tool create components.cif compounds.chemlib', shell=True, cwd='../../') -print '\nStaging Chemlib dictionary' print 'Compiling Openstructure' -subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DCOMPOUND_LIB=ChemLib/compounds.chemlib -DENABLE_IMG=ON -DENABLE_UI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') +subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DCOMPOUND_LIB='+chemlib_dictionary_location+' -DENABLE_IMG=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') subprocess.call('make -j2',shell=True,cwd='../../') print 'Removing obsolete packages and package directory' subprocess.call('rm -fr openstructure-linux*',shell=True,cwd='../../') @@ -66,14 +81,12 @@ print 'Creating new package directory' subprocess.call('mkdir '+directory_name,shell=True,cwd='../../') subprocess.call('mkdir '+directory_name+'/bin',shell=True,cwd='../../') print 'Copy python executable into stage for dependency detection' -print system_python_bin subprocess.call('cp '+system_python_bin+ ' stage/bin/python',shell=True,cwd='../../') print 'Copy python libraries into the stage for dependency detection' -subprocess.call('cp -pRL '+system_python_libs+' stage/'+libdir+'/python',shell=True,cwd='../../') -subprocess.call('rm -fr stage/'+libdir+'/python/dist-packages',shell=True,cwd='../../') -if second_system_python_libs_flag==True: - subprocess.call('cp -pRL '+second_system_python_libs+'/sip* stage/'+libdir+'/python/',shell=True,cwd='../../') - subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* stage/'+libdir+'/python/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+system_python_libs+' stage/'+libdir+'/',shell=True,cwd='../../') +subprocess.call('rm -fr stage/'+libdir+'/'+system_python_executable+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+sip_module_location+'/sip* stage/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+qt4_module_location+' stage/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') print 'Creating new dependency list' so_list=[] walk_list=os.walk('../../stage') @@ -106,13 +119,12 @@ for entry in filtered_dep_list: print 'Copy python executable into package directory structure' subprocess.call('cp '+system_python_bin+ ' '+directory_name+'/bin/python',shell=True,cwd='../../') print 'Copy python libraries into package directory structure' -subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir+'/python',shell=True,cwd='../../') -subprocess.call('rm -fr '+directory_name+'/'+libdir+'/python/dist-packages',shell=True,cwd='../../') -if second_system_python_libs_flag==True: - subprocess.call('cp -pRL '+second_system_python_libs+'/sip* '+directory_name+'/'+libdir+'/python/',shell=True,cwd='../../') - subprocess.call('cp -pRL '+second_system_python_libs+'/PyQt* '+directory_name+'/'+libdir+'/python/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('rm -fr '+directory_name+'/'+libdir+'/'+system_python_executable+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+sip_module_location+'/sip* '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+qt4_module_location+' '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') print 'Copy Qt 4 plugins into package directory structure' -subprocess.call('cp -pRL '+qt4_plugins+' '+directory_name+'/bin/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+qt4_plugins_location+' '+directory_name+'/bin/',shell=True,cwd='../../') print 'Copying supplementary material into package directory structure' subprocess.call('cp -pRL stage/share/openstructure '+directory_name+'/share/',shell=True,cwd='../../') print 'Copying examples into package directory structure' @@ -122,19 +134,19 @@ subprocess.call('cp deployment/README.html '+directory_name,shell=True,cwd='../. print 'Creating executables at the top level of the package directory structure' subprocess.call('ln -sf bin/dng ./dng',shell=True,cwd='../../'+directory_name) subprocess.call('ln -sf bin/ost ./ost',shell=True,cwd='../../'+directory_name) +subprocess.call('ln -sf bin/lddt ./lddt',shell=True,cwd='../../'+directory_name) print 'Copying additional libraries in the package directory structure' -subprocess.call('cp /usr/lib/libssl.so.0.9.8 '+directory_name+'/'+libdir,shell=True,cwd='../../') -subprocess.call('cp /usr/lib/libcrypto.so.0.9.8 '+directory_name+'/'+libdir,shell=True,cwd='../../') -print 'Removing headers from package directory structure' -subprocess.call('rm -fr '+directory_name+'/include',shell=True,cwd='../../') +subprocess.call('cp '+ssl_crypto_location+'/libssl.so* '+directory_name+'/'+libdir,shell=True,cwd='../../') +subprocess.call('cp '+ssl_crypto_location+'/libcrypto.so* '+directory_name+'/'+libdir,shell=True,cwd='../../') +print 'Copying python headers in the package directory structure' +subprocess.call('mkdir -p '+directory_name+'/local/include/',shell=True,cwd='../../') +subprocess.call('cp -r /usr/include/'+system_python_executable+' '+directory_name+'/local/include/',shell=True,cwd='../../') print 'Stripping pyc files from bundle' subprocess.call('rm -rf $(find . -name *.pyc)',shell=True,cwd='../../') print 'removing dokk and harmony examples from bundle' subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/dokk',shell=True,cwd='../../') subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/harmony',shell=True,cwd='../../') -print 'De-hardcoding package python binary path from openstructure executables' -subprocess.call('rm scripts/ost_config.in',shell=True,cwd='../../') -subprocess.call('rm scripts/ost_config.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost_config.in.backup scripts/ost_config.in',shell=True,cwd='../../') +print 'Compressing the bundle' subprocess.call('tar cfz '+directory_name+'.tgz '+directory_name,shell=True,cwd='../../') +print "Done. Please run 'git reset --hard HEAD' in the top directory before restarting." diff --git a/deployment/linux/create_bundle_precise.py b/deployment/linux/create_bundle_precise.py new file mode 100644 index 0000000000000000000000000000000000000000..b59409ffffc7d099c31f7d8437eae8a72e49e50a --- /dev/null +++ b/deployment/linux/create_bundle_precise.py @@ -0,0 +1,152 @@ +import os +import shutil +import subprocess +import string +import sys +import datetime +import sip +import PyQt4 + + +# parameters that can be modified +qt4_plugins_location='/usr/lib/i386-linux-gnu/qt4/plugins' +ssl_crypto_location='/lib/i386-linux-gnu/' +chemlib_dictionary_location='/home/bundler/compounds.chemlib' +list_of_excluded_libraries=[ +'ld-linux', +'libexpat', +'libgcc_s', +'libglib', +'cmov', +'libice', +'libSM', +'libX', +'libg', +'libGL.so', +'libfontconfig', +'libfreetype', +'libdrm', +'libxcb', +'libICE', +'libnvidia', +'libc' +] + +if len(sys.argv) < 2: + print 'usage: create_bundle.py additional_label' + sys.exit() + +additional_label=sys.argv[1] + +currdir=os.getcwd() +if currdir.find('deployment')==-1 or currdir.find('linux')==-1: + print '\n' + print 'ERROR: Please run this script from the deployment/linux directory' + print '\n' + sys.exit() + +print "WARNING: If this script does not run to completion, please run 'git reset --hard HEAD' in the main directory (two up from here) before restarting" + +system_python_version=sys.version_info +system_python_executable='python'+str(system_python_version[0])+'.'+str(system_python_version[1]) +system_python_bin='/usr/bin/'+system_python_executable +system_python_libs='/usr/lib/'+system_python_executable +qt4_module_location=os.path.dirname(PyQt4.__file__) +sip_module_location=os.path.dirname(sip.__file__) +print '\n' +print '\n' +print 'Detecting architecture and revision' +uname_output=subprocess.Popen('uname -a', shell=True, cwd='../../',stdout=subprocess.PIPE).stdout +uname_line=uname_output.readlines() +if uname_line[0].find('x86_64') !=-1: + libdir='lib64' + archstring='64bit' +else: + libdir='lib' + archstring='32bit' +directory_name='openstructure-linux-'+archstring+'-'+additional_label +print 'Hardcoding package python binary path in openstructure executables' +subprocess.call('rm -f scripts/ost_config.in.pre* scripts/ost_config.in.backup',shell=True,cwd='../../') +subprocess.call('mv scripts/ost_config.in scripts/ost_config.in.backup',shell=True,cwd='../../') +subprocess.call('sed "s/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.prepre > scripts/ost_config.in.pre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export QT_PLUGIN_PATH/ export QT_PLUGIN_PATH/g" scripts/ost_config.in.pre > scripts/ost_config.in',shell=True,cwd='../../') +print 'Compiling Openstructure' +subprocess.call('cmake ./ -DCMAKE_BUILD_TYPE=Release -DPREFIX='+directory_name+' -DCOMPOUND_LIB='+chemlib_dictionary_location+' -DENABLE_IMG=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') +subprocess.call('make -j2',shell=True,cwd='../../') +print 'Removing obsolete packages and package directory' +subprocess.call('rm -fr openstructure-linux*',shell=True,cwd='../../') +print 'Creating new package directory' +subprocess.call('mkdir '+directory_name,shell=True,cwd='../../') +subprocess.call('mkdir '+directory_name+'/bin',shell=True,cwd='../../') +print 'Copy python executable into stage for dependency detection' +subprocess.call('cp '+system_python_bin+ ' stage/bin/python',shell=True,cwd='../../') +print 'Copy python libraries into the stage for dependency detection' +subprocess.call('cp -pRL '+system_python_libs+' stage/'+libdir+'/',shell=True,cwd='../../') +subprocess.call('rm -fr stage/'+libdir+'/'+system_python_executable+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+sip_module_location+'/sip* stage/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+qt4_module_location+' stage/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +print 'Creating new dependency list' +so_list=[] +walk_list=os.walk('../../stage') +for dir_entry in walk_list: + for file_entry in dir_entry[2]: + if file_entry.find('.so')==len(file_entry)-3 or file_entry=='gosty': + filepath=os.path.join(dir_entry[0],file_entry) + so_list.append(filepath) +dep_list=[] +for so_entry in so_list: + dep=subprocess.Popen('perl ./ldd-rec.pl '+so_entry,shell=True,stdout=subprocess.PIPE,cwd='./').stdout + dep_so_entry=dep.readlines() + for dep_entry in dep_so_entry: + dep_list.append(dep_entry[:-1]) +sorted_dep_list=sorted(list(set(dep_list))) +print 'Filtering system libraries from depenedency list' +filtered_dep_list=[] +for entry in sorted_dep_list: + exclude=False + for exclusion in list_of_excluded_libraries: + if entry.find(exclusion)!=-1: + exclude=True + if exclude==False: + filtered_dep_list.append(entry) +print 'Installing OpenStructure into package directory structure' +subprocess.call('make install',shell=True,cwd='../../') +print 'Copy libraries in the package directory structure' +for entry in filtered_dep_list: + subprocess.call('cp '+entry+' '+directory_name+'/'+libdir,shell=True,cwd='../../') +print 'Copy python executable into package directory structure' +subprocess.call('cp '+system_python_bin+ ' '+directory_name+'/bin/python',shell=True,cwd='../../') +print 'Copy python libraries into package directory structure' +subprocess.call('cp -pRL '+system_python_libs+' '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('rm -fr '+directory_name+'/'+libdir+'/'+system_python_executable+'/dist-packages',shell=True,cwd='../../') +subprocess.call('cp -pRL '+sip_module_location+'/sip* '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +subprocess.call('cp -pRL '+qt4_module_location+' '+directory_name+'/'+libdir+'/'+system_python_executable+'/',shell=True,cwd='../../') +print 'Copy Qt 4 plugins into package directory structure' +subprocess.call('cp -pRL '+qt4_plugins_location+' '+directory_name+'/bin/',shell=True,cwd='../../') +print 'Copying supplementary material into package directory structure' +subprocess.call('cp -pRL stage/share/openstructure '+directory_name+'/share/',shell=True,cwd='../../') +print 'Copying examples into package directory structure' +subprocess.call('cp -pRL examples '+directory_name+'/share/openstructure/',shell=True,cwd='../../') +print 'Copying ReadMe file into package directory structure' +subprocess.call('cp deployment/README.html '+directory_name,shell=True,cwd='../../') +print 'Creating executables at the top level of the package directory structure' +subprocess.call('ln -sf bin/dng ./dng',shell=True,cwd='../../'+directory_name) +subprocess.call('ln -sf bin/ost ./ost',shell=True,cwd='../../'+directory_name) +subprocess.call('ln -sf bin/lddt ./lddt',shell=True,cwd='../../'+directory_name) +print 'Copying additional libraries in the package directory structure' +subprocess.call('cp '+ssl_crypto_location+'/libssl.so* '+directory_name+'/'+libdir,shell=True,cwd='../../') +subprocess.call('cp '+ssl_crypto_location+'/libcrypto.so* '+directory_name+'/'+libdir,shell=True,cwd='../../') +print 'Copying python headers in the package directory structure' +subprocess.call('mkdir -p '+directory_name+'/local/include/',shell=True,cwd='../../') +subprocess.call('cp -r /usr/include/'+system_python_executable+' '+directory_name+'/local/include/',shell=True,cwd='../../') +print 'Stripping pyc files from bundle' +subprocess.call('rm -rf $(find . -name *.pyc)',shell=True,cwd='../../') +print 'removing dokk and harmony examples from bundle' +subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/dokk',shell=True,cwd='../../') +subprocess.call('rm -rf '+directory_name+'/share/openstructure/examples/code_fragments/harmony',shell=True,cwd='../../') +print 'Compressing the bundle' +subprocess.call('tar cfz '+directory_name+'.tgz '+directory_name,shell=True,cwd='../../') +print "Done. Please run 'git reset --hard HEAD' in the top directory before restarting." + diff --git a/deployment/linux/debian/README b/deployment/linux/debian/README deleted file mode 100644 index c3a5a886f2754202845d533c5399e6eeb416ae86..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/README +++ /dev/null @@ -1,8 +0,0 @@ -1. Checkout OpenStructure into a directory called strictly:'openstructure-<version>' (currently is 1.1d - 1.1 develop) -2. Remove all the .git* files and directories from the source -3. Create a compressed file with the source directory called strictly 'openstructure_<version>.orig.tar.gz' - (At the same level as the source directory) -4. Copy the 'debian' directory into the top level of the source directory -5. Go into the top level of the source directory -6. Build package with 'debuilder -uc -us' -7. You can find the built package at the same level as the source directory and the source zipped file diff --git a/deployment/linux/debian/debian/README.source b/deployment/linux/debian/debian/README.source deleted file mode 100644 index c6c09893537f7e95bd2a01b7fe343ed65798ecf3..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/README.source +++ /dev/null @@ -1,18 +0,0 @@ -===============OPENSTRUCTURE molecular modelling framework =============== - - -OpenStructure is the next generation molecular modelling tailored at anybody - using 3D Structures or electron density maps. - -Please refer to www.openstructure.org for more information or try out - directly one of the binary packages available for download. - -Thank you for you interest and enjoy the straightforward way of handling -protein structure data! - -Please do not hesitate to contact us for feedback or troubleshooting: - -ost-users@maillist.unibas.ch - - -=============== The OpenStructure Team =================================== diff --git a/deployment/linux/debian/debian/changelog b/deployment/linux/debian/debian/changelog deleted file mode 100644 index 9ecfb662316dd8c2d6a8e6ddcc17e4cf3573e526..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -openstructure (1.1d-0ubuntu1) natty; urgency=low - - * Initial release - - -- Valerio Mariani <valerio.mariani@unibas.ch> Wed, 13 Jul 2011 15:41:35 +0200 diff --git a/deployment/linux/debian/debian/chemdict_tool.1 b/deployment/linux/debian/debian/chemdict_tool.1 deleted file mode 100644 index 7cbb4e805d2f7e52bf0ae16701d208cc5946fff1..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/chemdict_tool.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. -.TH CHEMDICT_TOOL: "1" "July 2011" "User Commands" -.SH NAME -chemdict_tool \- compound libary creation tool for OpenStructure -.SH SYNOPSIS -chemdict_tool action <compound\-dict> <db> (pdb|charmm|amber|opls) -.SH OPTIONS -Supported actions are: -.TP -create -\- creates a new db -.TP -update -\- update existing db -.SS "supported actions are:" -.TP -create -\- creates a new db -.TP -update -\- update existing db -.SH "SEE ALSO" -The full documentation for -.B usage: -is maintained as a Texinfo manual. If the -.B info -and -.B usage: -programs are properly installed at your site, the command -.IP -.B info usage: -.PP -should give you access to the complete manual. diff --git a/deployment/linux/debian/debian/compat b/deployment/linux/debian/debian/compat deleted file mode 100644 index 7f8f011eb73d6043d2e6db9d2c101195ae2801f2..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/deployment/linux/debian/debian/control b/deployment/linux/debian/debian/control deleted file mode 100644 index 43a9f02fdda663dcf358819cf3bb92381c501311..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/control +++ /dev/null @@ -1,23 +0,0 @@ -Source: openstructure -Section: science -Priority: extra -Maintainer: Valerio Mariani <valerio.mariani@unibas.ch> -Build-Depends: debhelper (>= 7.0.50~),cmake,desktop-file-utils,libboost-all-dev,libeigen2-dev,qt4-dev-tools,libqt4-dev,libqt4-opengl-dev,python-qt4-dev,pyqt4-dev-tools,libfftw3-dev,libpng12-dev,libtiff4-dev,python-dev -Standards-Version: 3.9.1 -Homepage: http://www.openstructure.org - -Package: openstructure -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, python-sip, python-qt4 -Description: Open-source computational structural biology framework - The Openstructure project aims to provide an open-source, modular, flexible, - molecular modelling and visualization environment. It is targeted at - interested method developers in the field of structural bioinformatics. - -Package: openstructure-dev -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, openstructure -Description: Open-source computational structural biology framework - The Openstructure project aims to provide an open-source, modular, flexible, - molecular modelling and visualization environment. It is targeted at - interested method developers in the field of structural bioinformatics. diff --git a/deployment/linux/debian/debian/copyright b/deployment/linux/debian/debian/copyright deleted file mode 100644 index b93d7503fb504646b3023bcc25817335d2579868..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/copyright +++ /dev/null @@ -1,40 +0,0 @@ -Format: http://dep.debian.net/deps/dep5 -Upstream-Name: openstructure -Source: http://www.openstructure.org - -Files: * -Copyright: 2008-2011 Torsten Schwede <torsten.schwede@unibas.ch> -License: LGPL-3.0 - -Files: debian/* -Copyright: 2011 Valerio Mariani <valerio.mariani@unibas.ch> -License: LGPL-3.0 - -License: LGPL-3.0 - This package 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 of the License, or (at your option) any later version. - . - This package 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 General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - . - On Debian systems, the complete text of the GNU Lesser General - Public License can be found in "/usr/share/common-licenses/LGPL-3". - -Files: modules/db/src/sqlite3.h, modules/db/src/sqlite.c -Copyright: 2011 Valerio Mariani <valerio.mariani@unibas.ch> -License: None - 2001 September 15 - . - The author disclaims copyright to this source code. In place of - a legal notice, here is a blessing: - . - May you do good and not evil. - May you find forgiveness for yourself and forgive others. - May you share freely, never taking more than you give. diff --git a/deployment/linux/debian/debian/dng.1 b/deployment/linux/debian/debian/dng.1 deleted file mode 100644 index dbc68330d425affad81420e25645719ac07c8b24..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/dng.1 +++ /dev/null @@ -1,39 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. -.TH DNG "1" "July 2011" "User Commands" -.SH NAME -dng \- GUI for OpenStructure -.SH SYNOPSIS -.B dng -[\fIoptions\fR] [\fIfiles to load\fR] -.SH OPTIONS -.TP -\fB\-h\fR, \fB\-\-help\fR -show this help message and exit -.TP -\fB\-v\fR VLEVEL, \fB\-\-verbosity_level\fR=\fIVLEVEL\fR -sets the verbosity level [default: 2] -.TP -\fB\-s\fR SCRIPT, \fB\-\-script\fR=\fISCRIPT\fR -executes a script (syntax: \fB\-s\fR SCRIPT [options] [args]) -Anything that follows this option is passed to the -script -.TP -\fB\-p\fR PDB_IDS, \fB\-\-pdb_id\fR=\fIPDB_IDS\fR -PDB file ID. The file will be retrieved from PDB -.TP -\fB\-b\fR BUILDER, \fB\-\-builder\fR=\fIBUILDER\fR -Type of builder used by the progam (either RULE_BASED -or HEURISTIC) [default: HEURISTIC] -.TP -\fB\-c\fR COMPLIB, \fB\-\-compound_library\fR=\fICOMPLIB\fR -Compound library for the RULE_BASED builder (only used -if \fB\-\-builder\fR option is set to RULE_BASED, otherwise -ignored [default: compounds.chemlib] -.TP -\fB\-q\fR QUERY, \fB\-\-query\fR=\fIQUERY\fR -Selection query to be highlighted automatically upon -loading (only used together with \fB\-p\fR option or when a -PDB file is loaded, otherwise ignored [default: None] -.TP -\fB\-S\fR, \fB\-\-stereo\fR -try to get a quad\-buffer stereo visual diff --git a/deployment/linux/debian/debian/openstructure.desktop b/deployment/linux/debian/debian/openstructure.desktop deleted file mode 100644 index b5ae761af421073b92e3ce58fa0c5100417a3ae8..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/openstructure.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=OpenStructure -GenericName=Open-Source Computational Structural Biology Framework -Exec=dng -Icon=openstructure -Terminal=false -Type=Application -Categories=Education;Science; diff --git a/deployment/linux/debian/debian/openstructure.manpages b/deployment/linux/debian/debian/openstructure.manpages deleted file mode 100644 index e73d09dbbec1bf1adaed4065f926ecbe8e872771..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/openstructure.manpages +++ /dev/null @@ -1,3 +0,0 @@ -debian/ost.1 -debian/dng.1 -debian/chemdict_tool.1 diff --git a/deployment/linux/debian/debian/ost.1 b/deployment/linux/debian/debian/ost.1 deleted file mode 100644 index afd5f75dcb8eadc27a09ecacb147138c3451ac7a..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/ost.1 +++ /dev/null @@ -1,18 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. -.TH OST "1" "July 2011" "User Commands" -.SH NAME -ost: \- command-line console for OpenStructure -.SH SYNOPSIS -.B ost -[\fIost options\fR] [\fIscript to execute\fR] [\fIscript parameters\fR] -.SH OPTIONS -.TP -\fB\-i\fR, \fB\-\-interactive\fR -start interpreter interactively (must be first -parameter, ignored otherwise) -.TP -\fB\-h\fR, \fB\-\-help\fR -show this help message and exit -.TP -\fB\-v\fR VLEVEL, \fB\-\-verbosity_level\fR=\fIVLEVEL\fR -sets the verbosity level [default: 2] diff --git a/deployment/linux/debian/debian/postinst b/deployment/linux/debian/debian/postinst deleted file mode 100644 index a448189622f2efd26b94eb33f2759706a6d7bdbd..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/postinst +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -# postinst script for openstructure -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * <postinst> `configure' <most-recently-configured-version> -# * <old-postinst> `abort-upgrade' <new version> -# * <conflictor's-postinst> `abort-remove' `in-favour' <package> -# <new-version> -# * <postinst> `abort-remove' -# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' -# <failed-install-package> <version> `removing' -# <conflicting-package> <version> -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - configure) - ldconfig - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff --git a/deployment/linux/debian/debian/rules b/deployment/linux/debian/debian/rules deleted file mode 100755 index 7b9d18ba98b725099155c5f3d87a78f20e2cba5c..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/rules +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -%: - dh $@ --buildsystem cmake -override_dh_auto_configure: - cmake ./ -DPREFIX=debian/openstructure/usr -DOPTIMIZE=ON -DCOMPOUND_LIB=compounds.chemlib -override_dh_auto_build: - make -j6 -override_dh_auto_install: - make install - rm debian/openstructure/usr/bin/ldt - mkdir -p debian/openstructure-dev/usr - mv debian/openstructure/usr/include debian/openstructure-dev/usr/ - mkdir -p debian/openstructure/usr/share/pixmaps/ - cp modules/gui/share/images/logo-small.png debian/openstructure/usr/share/pixmaps/openstructure.png - mkdir -p debian/openstructure/usr/share/applications/ - cp debian/openstructure.desktop debian/openstructure/usr/share/applications/ - desktop-file-validate debian/openstructure/usr/share/applications/openstructure.desktop diff --git a/deployment/linux/debian/debian/source/format b/deployment/linux/debian/debian/source/format deleted file mode 100644 index c3d9f2407417795889250717d7b519eadd8373e6..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/source/format +++ /dev/null @@ -1,2 +0,0 @@ -3.0 (quilt) - diff --git a/deployment/linux/debian/debian/source/include-binaries b/deployment/linux/debian/debian/source/include-binaries deleted file mode 100644 index e2a64033aea5f1dda66b509afe7ee03c8d40095e..0000000000000000000000000000000000000000 --- a/deployment/linux/debian/debian/source/include-binaries +++ /dev/null @@ -1 +0,0 @@ -compounds.chemlib diff --git a/deployment/linux/fedora/openstructure.desktop b/deployment/linux/fedora/openstructure.desktop deleted file mode 100644 index 5da5cfab6fa466c91de1e5be5cf5073448ad72dd..0000000000000000000000000000000000000000 --- a/deployment/linux/fedora/openstructure.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=OpenStructure -GenericName=Open-Source Computational Structural Biology Framework -Exec=dng -Icon=openstructure -Terminal=false -Type=Application -Categories=Science; diff --git a/deployment/linux/fedora/openstructure.spec b/deployment/linux/fedora/openstructure.spec deleted file mode 100644 index 3d27b5deac2b8e299e1ab1406900a722347866be..0000000000000000000000000000000000000000 --- a/deployment/linux/fedora/openstructure.spec +++ /dev/null @@ -1,82 +0,0 @@ -Name: openstructure -Version: 1.1 -Release: 0.1d%{?dist} -Summary: Open-source computational structural biology framework - - -# The entire source code is LGPLv3 except the following files: -# modules/db/src/sqlite3.h, modules/db/src/sqlite.c -# which have no license -License: LGPLv3 and unlicensed -URL: www.openstructure.org -# The source for this package was pulled from upstream's git. Use the -# following commands to generate the tarball: -# git clone https://dng.biozentrum.unibas.ch/git/ost.git openstructure-1.1d -# cp /import/bc2/home/schwede/GROUP/OpenStructure/compounds.chemlib \ -# openstructure-1.1d/ -# tar -cJvf openstructure-1.1d.tar.xz openstructure-1.1d -Source0: %{name}-%{version}d.tar.xz -Source1: %{name}.desktop - -BuildRequires: boost-devel,fftw-devel,eigen2-devel,libtiff-devel,libpng-devel,sip-devel,PyQt4-devel,cmake,desktop-file-utils -Requires: sip,PyQt4 - -%description -The Openstructure project aims to provide an open-source, modular, flexible, -molecular modelling and visualization environment. It is targeted at -interested method developers in the field of structural bioinformatics. - -%prep -%setup -n openstructure-1.1d - -%build -%cmake . -DPREFIX=%{buildroot}/usr -DOPTIMIZE=ON -DCOMPOUND_LIB=compounds.chemlib -make %{?_smp_mflags} - -%install -rm -rf %{buildroot} -make install -mkdir -p %{buildroot}/%{_defaultdocdir}/%{name}-%{version} -mkdir -p %{buildroot}/%{_datadir}/pixmaps -cp LICENSE.txt %{buildroot}/%{_defaultdocdir}/%{name}-%{version}/ -cp ReadMe.txt %{buildroot}/%{_defaultdocdir}/%{name}-%{version}/ -cp modules/gui/share/images/logo-small.png %{buildroot}/%{_datadir}/pixmaps/openstructure.png -rm %{buildroot}/%{_bindir}/ldt -desktop-file-install --dir=%{buildroot}/%{_datadir}/applications %{SOURCE1} - -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root,-) -%{_bindir}/* -%{_libdir}/libost* -%{_libdir}/openstructure -%{_datadir}/openstructure -%{_datadir}/applications/* -%{_datadir}/pixmaps/* - -%doc -%{_defaultdocdir}/%{name}-%{version}/LICENSE.txt -%{_defaultdocdir}/%{name}-%{version}/ReadMe.txt - -%changelog -* Wed Jul 20 2011 Valerio Mariani <valerio.mariani@unibas.ch> 1.1-1d -- Initial release - - - - -%package devel -Summary: Open-source computational structural biology framework -Requires: openstructure - -%description devel -The Openstructure project aims to provide an open-source, modular, flexible, -molecular modelling and visualization environment. It is targeted at -interested method developers in the field of structural bioinformatics. - -%files devel -%{_includedir}/* - diff --git a/deployment/linux/reset_repository.py b/deployment/linux/reset_repository.py deleted file mode 100644 index 6ac0809e34a767ff7ff16febd6d392b95e31861f..0000000000000000000000000000000000000000 --- a/deployment/linux/reset_repository.py +++ /dev/null @@ -1,13 +0,0 @@ -import subprocess -import os - -currdir=os.getcwd() -if currdir.find('deployment')==-1 or currdir.find('linux')==-1: - print '\n' - print 'ERROR: Please run this script from the deployment/linux directory' - print '\n' - sys.exit() - -subprocess.call('rm -fr scripts/ost_config.in.pre*',shell=True,cwd='../../') -subprocess.call('mv scripts/ost_config.in.backup scripts/ost_config.in',shell=True,cwd='../../') - diff --git a/deployment/macos/deploy.py b/deployment/macos/deploy.py index dea9207ab211bf8b210ff1cf0b62748140a04def..de10ec84cfcce14a8a158f15338b7366caad9a05 100644 --- a/deployment/macos/deploy.py +++ b/deployment/macos/deploy.py @@ -10,18 +10,25 @@ p.add_option('--no_rpath', action='store_true', default=False) p.add_option('--macports_workaround', action='store_true', default=False) p.add_option('--dmg', action='store_true', default=False) +p.add_option('--no-gui', action='store_true', default=False) opts, args=p.parse_args() deps.make_standalone('../../stage', 'standalone', True, opts.no_rpath, - macports_workaround=opts.macports_workaround) + macports_workaround=opts.macports_workaround, + no_gui=opts.no_gui) if os.path.exists('DNG.app'): shutil.rmtree('DNG.app') +if opts.no_gui: + out_dir='ost-%s' % ost.VERSION + if os.path.exists(out_dir): + shutil.rmtree(out_dir) + shutil.move('standalone', out_dir) + sys.exit(0) bundle.create_bundle('DNG', opts.bundle) if opts.bundle: shutil.copytree('../../examples', 'DNG.app/Contents/examples') os.system('rm `find DNG.app/Contents/examples/ -name "*.pyc"` 2> /dev/null') - os.system('rm -rf DNG.app/Contents/examples/demos/harmony') - os.system('rm -rf DNG.app/Contents/examples/demos/dokk') + os.system('rm -rf DNG.app/Contents/examples/code_fragments/') if opts.dmg: - os.system('rm -rf openstructure.dmg') - os.system('hdiutil create -srcFolder DNG.app openstructure.dmg') \ No newline at end of file + os.system('rm -rf openstructure-%s.dmg' % ost.VERSION) + os.system('hdiutil create -srcFolder DNG.app openstructure-%s.dmg' % ost.VERSION) diff --git a/deployment/macos/deps.py b/deployment/macos/deps.py index 627d73ef764773d2bc904f2fdc422a7737bf208b..65474472153ea460b9e91860b58af7bf7277dbb4 100644 --- a/deployment/macos/deps.py +++ b/deployment/macos/deps.py @@ -26,8 +26,8 @@ def _deps_for_lib(lib, pool, recursive=True): pool.add(d) return -def collect_deps(stage_dir, components, binaries, site_packages, - site_packages_dir): +def collect_deps(stage_dir, components, binaries, libexec_binaries, + site_packages, site_packages_dir): """ Collect the dependencies for the given components and returns a list of frameworks/libraries that the component depends on. @@ -49,6 +49,14 @@ def collect_deps(stage_dir, components, binaries, site_packages, continue if bin_name not in pool: _deps_for_lib(bin_name, pool) + for bin in libexec_binaries: + bin_name=os.path.abspath(os.path.join(stage_dir, 'libexec/openstructure', + bin)) + if not os.path.exists(bin_name): + print 'WARNING:', bin_name, 'does not exist' + continue + if bin_name not in pool: + _deps_for_lib(bin_name, pool) for site_package in site_packages: full_path=get_python_module_path(site_package) print full_path @@ -60,39 +68,45 @@ def collect_deps(stage_dir, components, binaries, site_packages, _deps_for_lib(so_file, pool) return pool -BINARIES=['gosty', 'chemdict_tool'] -COMPONENTS=['mol', 'geom', 'conop', 'gfx', 'gui', 'seq_alg', 'seq', - 'img', 'img_alg', 'info', 'io', 'db', 'base'] -SCRIPTS=['dng', 'ost'] +LIBEXEC_SCRIPTS=['ost_config'] +LIBEXEC_BINARIES=[] +GUI_LIBEXEC_BINARIES=['gosty'] +BINARIES=['ldt', 'chemdict_tool', 'tmalign', 'tmscore'] +GUI_BINARIES=[] +GUI_COMPONENTS=['gfx', 'gui', 'info'] +COMPONENTS=['mol', 'geom', 'conop', 'seq_alg', 'seq', + 'img', 'img_alg', 'io', 'db', 'base'] +GUI_SCRIPTS=['dng'] +SCRIPTS=['ost'] CHANGE_ID_RPATH='install_name_tool -id @rpath/%s %s' -CHANGE_ID='install_name_tool -id @executable_path/%s %s' +CHANGE_ID='install_name_tool -id @rpath/%s %s' CHANGE_LOAD_CMD_RPATH='install_name_tool -change %s @rpath/%s %s' CHANGE_LOAD_CMD='install_name_tool -change %s @executable_path/%s %s' ADD_RPATH='install_name_tool -add_rpath %s %s 2> /dev/null' -SITE_PACKAGES=['sip.so', 'sipconfig.py', 'sipdistutils.py', 'PyQt4'] +SITE_PACKAGES=[] +GUI_SITE_PACKAGES=['sip.so', 'sipconfig.py', 'sipdistutils.py', 'PyQt4'] REMOVE_HEADERS='rm -rf `find %s/lib -type d -name Headers`' REMOVE_CURRENT='rm -rf `find %s/lib -type d -name Current`' # collect libs of non-standard libraries/frameworks we depend on -def copy_binaries(stage_dir, outdir, binary_names, scripts, use_rpath, +def copy_binaries(stage_dir, outdir, binary_names, scripts, bin_dir, append_bin=True): - exe_path=os.path.abspath(os.path.join(outdir, 'bin')) + exe_path=os.path.abspath(os.path.join(outdir, bin_dir)) for binary_name in binary_names: if append_bin: - bin_name=os.path.join(stage_dir, 'bin', binary_name) + bin_name=os.path.join(stage_dir, bin_dir, binary_name) else: bin_name=os.path.join(stage_dir, binary_name) if not os.path.exists(bin_name): print 'WARNING:', binary_name, 'does not exist' continue - dst_name=os.path.join(outdir, 'bin', os.path.basename(bin_name)) + dst_name=os.path.join(outdir, bin_dir, os.path.basename(bin_name)) shutil.copy(bin_name, dst_name) - update_load_commands(dst_name, True, use_rpath, exe_path) - os.system(ADD_RPATH % ('../lib', dst_name)) + update_load_commands(dst_name, True, exe_path) for script in scripts: - shutil.copy(os.path.join(stage_dir, 'bin', script), - os.path.join(outdir,'bin', script)) + shutil.copy(os.path.join(stage_dir, bin_dir, script), + os.path.join(outdir,bin_dir, script)) def split_framework_components(abs_path): """ @@ -108,46 +122,31 @@ def split_framework_components(abs_path): trail=os.path.join(*parts[i+1:]) return lead, trail -def change_id(id, lib, use_rpath): +def change_id(id, lib): os.chmod(lib, 0666) - if use_rpath: - os.system(CHANGE_ID_RPATH % (id,lib)) - else: - os.system(CHANGE_ID % (id,lib)) + os.system(CHANGE_ID_RPATH % (id,lib)) os.chmod(lib, 0444) -def update_load_commands(lib, exe, use_rpath, exe_path): +def update_load_commands(lib, exe, exe_path): direct_deps=set() _deps_for_lib(lib, direct_deps, recursive=False) os.chmod(lib, 0666) for direct_dep in direct_deps: if direct_dep.endswith('.dylib'): - if use_rpath: - new_name=os.path.basename(direct_dep) - os.system(CHANGE_LOAD_CMD_RPATH % (direct_dep, new_name, lib)) - else: - new_name=os.path.join('../lib', os.path.basename(direct_dep)) - os.system(CHANGE_LOAD_CMD % (direct_dep, new_name, lib)) + new_name=os.path.basename(direct_dep) + os.system(CHANGE_LOAD_CMD_RPATH % (direct_dep, new_name, lib)) else: assert direct_dep.find('.framework/')>=0 - if use_rpath: - framework_path, rel_path=split_framework_components(direct_dep) - framework_name=os.path.basename(framework_path) - new_name=os.path.join(framework_name, rel_path) - os.system(CHANGE_LOAD_CMD_RPATH % (direct_dep, new_name, lib)) - else: - framework_path, rel_path=split_framework_components(direct_dep) - framework_name=os.path.basename(framework_path) - new_name=os.path.join('../lib', framework_name, rel_path) - os.system(CHANGE_LOAD_CMD % (direct_dep, new_name, lib)) - if use_rpath: - os.system(ADD_RPATH % ('.', lib)) + framework_path, rel_path=split_framework_components(direct_dep) + framework_name=os.path.basename(framework_path) + new_name=os.path.join(framework_name, rel_path) + os.system(CHANGE_LOAD_CMD_RPATH % (direct_dep, new_name, lib)) if exe: os.chmod(lib, 0555) else: os.chmod(lib, 0444) -def copy_deps(dependencies, outdir, use_rpath): +def copy_deps(dependencies, outdir): exe_path=os.path.join(outdir, 'bin') for dep in dependencies: if dep.endswith('.dylib'): @@ -155,29 +154,21 @@ def copy_deps(dependencies, outdir, use_rpath): if not os.path.exists(dep): continue shutil.copy(dep, dst_name) - if use_rpath: - change_id(os.path.basename(dep), dst_name, use_rpath) - else: - change_id('../lib/%s' % os.path.basename(dep), dst_name, use_rpath) - update_load_commands(dst_name, False, use_rpath, exe_path) + change_id(os.path.basename(dep), dst_name) + update_load_commands(dst_name, False, exe_path) else: assert dep.find('.framework/')>=0 framework_path, rel_path=split_framework_components(dep) framework_name=os.path.basename(framework_path) dst_name=os.path.join(outdir, 'lib', framework_name) shutil.copytree(framework_path, dst_name) - if use_rpath: - change_id(os.path.join(dst_name, rel_path), - os.path.join(dst_name, rel_path), use_rpath) - else: - change_id(os.path.join('../lib', framework_name, rel_path), - os.path.join(dst_name, rel_path), use_rpath) + change_id(os.path.join(dst_name, rel_path), + os.path.join(dst_name, rel_path)) os.unlink(os.path.join(dst_name, os.path.splitext(framework_name)[0])) update_load_commands(os.path.join(dst_name, rel_path), False, - use_rpath, exe_path) + exe_path) -def update_pymod_shared_objects(args, path, files): - lib_path, use_rpath=args +def update_pymod_shared_objects(lib_path, path, files): exe_path=os.path.abspath(os.path.join(lib_path, '../bin')) for f in files: if not os.path.exists(os.path.join(path, f)): @@ -187,7 +178,7 @@ def update_pymod_shared_objects(args, path, files): path_to_lib_path=os.path.relpath(lib_path, path) abs_name=os.path.join(path, f) os.system(ADD_RPATH % (path_to_lib_path, abs_name)) - update_load_commands(abs_name, False, use_rpath, exe_path) + update_load_commands(abs_name, False, exe_path) elif ext in ('.pyc', '.pyo'): os.unlink(os.path.join(path, f)) @@ -217,43 +208,46 @@ def get_python_home(): """ return os.path.dirname(sys.modules['os'].__file__) -def check_install_name_tool_capabilities(): - """ - Find out whether install_name_tool supports the add_rpath option. - """ - inst_name_tool=subprocess.Popen('install_name_tool', shell=True, - stderr=subprocess.PIPE) - output=inst_name_tool.communicate()[1] - return output.find('-add_rpath')!=-1 - def make_standalone(stage_dir, outdir, no_includes, force_no_rpath=False, - macports_workaround=False): - site_packages=get_site_package_dir() - # figure out if install_name_tool supports the -add_rpath option. - use_rpath=True - if not check_install_name_tool_capabilities(): - print "install_name_tool doesn't support the -add_rpath option." - print "I will fallback to the more arcane @executable_path" - use_rpath=False - elif force_no_rpath: - print "I will use the arcane @executable_path" - use_rpath=False + macports_workaround=False, no_gui=False): + site_packages_dir=get_site_package_dir() if os.path.exists(outdir): shutil.rmtree(outdir) os.system('mkdir -p "%s"' % outdir) os.system('mkdir -p "%s/lib"' % outdir) os.system('mkdir -p "%s/bin"' % outdir) + os.system('mkdir -p "%s/libexec/openstructure"' % outdir) print 'copying shared datafiles' shutil.copytree(os.path.join(stage_dir, 'share'), os.path.join(outdir, 'share')) + scripts=SCRIPTS + binaries=BINARIES + components=COMPONENTS + libexec_scripts=LIBEXEC_SCRIPTS + site_packages=SITE_PACKAGES + libexec_binaries=LIBEXEC_BINARIES + if not no_gui: + scripts+=GUI_SCRIPTS + binaries+=GUI_BINARIES + components+=GUI_COMPONENTS + libexec_binaries+=GUI_LIBEXEC_BINARIES + site_packages+=GUI_SITE_PACKAGES print 'collecting dependencies' - deps=collect_deps(stage_dir, COMPONENTS, BINARIES, SITE_PACKAGES, - site_packages) + deps=collect_deps(stage_dir, components, binaries, libexec_binaries, + site_packages, site_packages_dir) + # when running in non-gui mode, we are most likely missing the boost + # python library. Let's add it to the list of dependencies by + # inspecting "_ost_base.so". + _deps_for_lib(os.path.join(stage_dir, 'lib/openstructure/ost/_ost_base.so'), + deps, recursive=False) print 'copying dependencies' - copy_deps(deps, outdir, use_rpath) + copy_deps(deps, outdir) + print 'copying libexec binaries' + copy_binaries(stage_dir, outdir, libexec_binaries, libexec_scripts, + 'libexec/openstructure') print 'copying binaries' - copy_binaries(stage_dir, outdir, BINARIES, SCRIPTS, use_rpath) + copy_binaries(stage_dir, outdir, binaries, scripts, 'bin') print 'copying pymod' shutil.copytree(os.path.join(stage_dir, 'lib/openstructure'), os.path.join(outdir, 'lib/openstructure')) @@ -275,7 +269,7 @@ def make_standalone(stage_dir, outdir, no_includes, force_no_rpath=False, if os.path.exists(os.path.join(modules_dst, 'site-packages')): shutil.rmtree(os.path.join(modules_dst, 'site-packages')) copy_binaries(os.path.join(python_home, '../..'), outdir, - ['python'], [], use_rpath) + ['python'], [], 'bin') python_bin=os.path.abspath(os.path.join(python_home, '../../bin/python')) else: # For MacPorts it's even more involved. Python is not executed directly @@ -285,11 +279,11 @@ def make_standalone(stage_dir, outdir, no_includes, force_no_rpath=False, path_to_app='../../Resources/Python.app/Contents/MacOS/' exe_path=os.path.join(python_home, path_to_app) copy_binaries(exe_path, outdir, ['python'], [], - use_rpath, append_bin=False) + append_bin=False) python_bin=os.path.join('/opt/local/bin/python') else: copy_binaries(os.path.join(python_home, '../..'), outdir, - ['python'], [], use_rpath) + ['python'], []) python_bin=os.path.abspath(os.path.join(python_home, '../../bin/python')) # remove all versions but the one we are using version_string=sys.version[0:3] @@ -302,15 +296,12 @@ def make_standalone(stage_dir, outdir, no_includes, force_no_rpath=False, if os.path.basename(directory)!=version_string: shutil.rmtree(directory) # replace the python executable - ost_script=os.path.join(outdir, 'bin', 'ost') + ost_script=os.path.join(outdir, 'libexec', 'openstructure', 'ost_config') os.chmod(ost_script, 0666) script=''.join(open(ost_script, 'r').readlines()) script=script.replace(python_bin, '$BIN_DIR/python') open(ost_script, 'w').write(script) os.chmod(ost_script, 0555) - elif use_rpath==False: - print 'BIG FAT WARNING: Creating bundle with @executable_path and default' - print 'Python might not work. Test carefully before deploying.' if no_includes: os.system(REMOVE_HEADERS % outdir) @@ -325,4 +316,4 @@ def make_standalone(stage_dir, outdir, no_includes, force_no_rpath=False, print 'updating link commands of python shared objects' os.path.walk(os.path.join(outdir, 'lib'), update_pymod_shared_objects, - (os.path.join(outdir, 'lib'), use_rpath)) + os.path.join(outdir, 'lib')) diff --git a/doc/make.py b/doc/make.py index e849931f35272bd03e82fcc208afa9a8c9ec63f7..71f2dc1bc3cf004cd56fe7f3229434438122a5ab 100644 --- a/doc/make.py +++ b/doc/make.py @@ -11,6 +11,12 @@ if len(sys.argv)==2: else: root_dir='.' +def _CheckCall(cmd, shell): + r = subprocess.call(cmd, shell=True) + if r != 0: + sys.stderr.write("Command '%s' returned non-zero exit status %d\n"%(cmd, r)) + sys.exit(-1) + def _OutputPath(inpath, outdir): parts=inpath.split(os.path.sep) filtered_parts=[outdir] @@ -88,23 +94,24 @@ if opts.quiet: for sub_dir in ('modules',): os.path.walk(sub_dir, _CollectRstDocs, 'doc/source') -sphinx_bin=settings.Locate(['sphinx-build', 'sphinx-build-2.6']) +sphinx_bin=settings.Locate(['sphinx-build', 'sphinx-build-2.6','sphinx-build-2.7']) if opts.html: cmd='%s %s -b html -c %s %s %s' % (sphinx_bin, opt_str, 'doc/conf', 'doc/source', 'doc/build/html') print cmd - subprocess.check_call(cmd, shell=True) + _CheckCall(cmd, shell=True) + if opts.doctest: cmd='%s %s -b doctest -c %s %s %s' % (sphinx_bin, opt_str, 'doc/conf', 'doc/source', 'doc/build/doctest') - subprocess.check_call(cmd, shell=True) + _CheckCall(cmd, shell=True) if opts.build_json: cmd='%s %s -b json -c %s %s %s' % (sphinx_bin, opt_str, 'doc/conf', 'doc/source', 'doc/build/json') - subprocess.check_call(cmd, shell=True) + _CheckCall(cmd, shell=True) if opts.linkcheck: cmd='%s %s -b linkcheck -c %s %s %s' % (sphinx_bin, opt_str, 'doc/conf', 'doc/source', 'doc/build/check') - subprocess.check_call(cmd, shell=True) + _CheckCall(cmd, shell=True) diff --git a/doxygen/Doxyfile b/doxygen/Doxyfile index 9a12a6fd10e192dba8e333bd3ff0f0ede284ca5c..064ced94d988ffc3424b71c1da9572582860fa4c 100644 --- a/doxygen/Doxyfile +++ b/doxygen/Doxyfile @@ -252,4 +252,4 @@ DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- -SEARCHENGINE = NO +SEARCHENGINE = YES diff --git a/examples/code_fragments/entity/gfx_symmetry.py b/examples/code_fragments/entity/gfx_symmetry.py index a0d795ece75923058688a6a3ebabc2c9a3f8012e..c45e4d7507ff44bcba936da559a3e894ec10f98a 100644 --- a/examples/code_fragments/entity/gfx_symmetry.py +++ b/examples/code_fragments/entity/gfx_symmetry.py @@ -6,9 +6,9 @@ if len(sys.argv)>1: filename=sys.argv[1] ent=io.LoadEntity(filename) -edi=ent.RequestXCSEditor() +edi=ent.EditXCS() m=geom.Mat4() -m.PasteTranslation(-ent.GetGeometricStart()) +m.PasteTranslation(-ent.bounds.min) edi.ApplyTransform(m) edi.UpdateICS() frag=gfx.Entity('frag', ent) diff --git a/examples/code_fragments/entity/superpose.py b/examples/code_fragments/entity/superpose.py index 78dfb87e2440a4d109937e4d9e1e36ff6e3ad4e0..02ea214bc1c83fa02489b33e2ab7e363536e7500 100644 --- a/examples/code_fragments/entity/superpose.py +++ b/examples/code_fragments/entity/superpose.py @@ -20,7 +20,7 @@ g=gfx.Entity("second", ev_b) scene.Add(g) h=gfx.Entity("first",ev_a) scene.Add(h) -h.SetColor(gfx.Color(0x0000ff), '') -g.SetColor(gfx.Color(0xff0000), '') +h.SetColor(gfx.RED) +g.SetColor(gfx.BLUE) scene.CenterOn(g) diff --git a/examples/code_fragments/misc/roll_helix.py b/examples/code_fragments/misc/roll_helix.py index 482a89c2205027121ecb3199172d63cf3f0475a7..cd8eb9d4170b0d4572176ae86a58f61c5951d832 100644 --- a/examples/code_fragments/misc/roll_helix.py +++ b/examples/code_fragments/misc/roll_helix.py @@ -3,7 +3,7 @@ import math e=io.LoadEntity('../entity/sdh.pdb') c=e.FindChain('A') -edi=e.RequestICSEditor(mol.EditMode.BUFFERED_EDIT) +edi=e.EditXCS(mol.EditMode.BUFFERED_EDIT) for r in c.GetResidueList(): phi=r.GetPhiTorsion() psi=r.GetPsiTorsion() diff --git a/examples/code_fragments/misc/strip_sidechains.py b/examples/code_fragments/misc/strip_sidechains.py index 4359ba1f7a830e34f7b90b591e7895c2efa2eb86..e86e345e2f0de1719dbbceeeb312c5ffdf0d7585 100644 --- a/examples/code_fragments/misc/strip_sidechains.py +++ b/examples/code_fragments/misc/strip_sidechains.py @@ -9,7 +9,7 @@ def StripSidechain(edi, residue): edi.DeleteAtom(atom) def StripSidechains(entity): - edi=entity.RequestXCSEditor(mol.EditMode.BUFFERED_EDIT) + edi=entity.EditXCS(mol.EditMode.BUFFERED_EDIT) for c in e.GetChainList(): residues=c.GetResidueList() for residue in residues: diff --git a/examples/code_fragments/seq/sh2.aln b/examples/code_fragments/seq/sh2.aln new file mode 100644 index 0000000000000000000000000000000000000000..98002530eb12d258e805b3bf64a1902fc05d9008 --- /dev/null +++ b/examples/code_fragments/seq/sh2.aln @@ -0,0 +1,209 @@ +CLUSTAL 2.0.12 multiple sequence alignment + + +SH2 -------------------------KP-HPWFFGKIPRAKAEEMLSKQR- 23 +UniRef90_UPI0000EB201F KAELNGKDGFIPKN-------YIEMKP-HPWFFGKIPRAKAEEMLSKQR- 45 +UniRef90_P62993 KAELNGKDGFIPKN-------YIEMKP-HPWFFGKIPRAKAEEMLSKQR- 78 +UniRef90_P87379 KAELNGKDGFIPKN-------YIEMKA-HPWFFGKIPRAKAEEMLGKQR- 78 +UniRef90_UPI00016E653C KAELRGKDGFIPKN-------YIEMKA-HPWFYGKIPRAKAEEILNKQR- 78 +UniRef90_UPI00016E653B KAELRGKDGFIPKN-------YIEMKA-HPWFYGKIPRAKAEEILNKQR- 78 +UniRef90_Q4T656 DQALS-FASLLPVS-------FSAC---CRWFYGKIPRAKAEEILNKQR- 75 +UniRef90_UPI0001555716 KAELNGKDGFIPKN-------YIEMKP-HLWFFGKIPRAYAEEMLGKQL- 388 +UniRef90_UPI000180AF26 KAEQDGKEGLVPMN-------YIQMKP-CEWFARNMTRANAELRL-KNA- 52 +UniRef90_UPI000180AF37 KAEQDGKEGLVPMN-------YIEIKE-CEWFARNMTRANAELRL-KNT- 77 +UniRef90_A8XPY6 KAELDGTEGFIPSN-------YIRMGD-CSWYLGKITRNDAEVLLKKSNV 79 +UniRef90_P29355 KAELDGNEGFIPSN-------YIRMTE-CNWYLGKITRNDAEVLLKKPTV 79 +UniRef90_UPI000186E6C5 RAELDSKEGLIPSN-------YIEMKN-HDWYYGRITRADAEKLLMNK-- 77 +UniRef90_Q08012 RAELDGKEGLIPSN-------YIEMKN-HDWYYGRITRADAEKLLSNK-- 77 +UniRef90_B7P0R2 RAELDSKEGLIPSN-------YIEMKK-HDWYYGRITRADAEKLLSNK-- 77 +UniRef90_D3PIQ8 RAESGGKEGLIPSN-------YIDMKP-HDWYYSRMTRATAEKLLSNK-- 77 +UniRef90_C4WWT7 RAEFEGKEGLIPSN-------YIEMKN-HDWYYGKITRADAEKLLDQQ-- 77 +UniRef90_UPI0000586DB6 -------------------------------------RDGAEELLKND-- 40 +UniRef90_UPI0001CBA623 KAELDGREGFIPKN-------YITMRP-HDWFHGKISRAKAEELLQLQP- 78 +UniRef90_UPI0001CBA624 NAELDGREGLIPKN-------YIEMKP-HEWFHGKISREKAEELLQLQS- 77 +UniRef90_UPI000192619C KAEQNGKEGFVPKN-------YIQMKP-HSWYYGKIRRSEAEQLLLQEP- 52 +UniRef90_UPI0000521DDC RAEIDGRMGLVPKN-------YIELKA-HDWYHGKISRVKAEQSLNKPHY 79 +UniRef90_C1LZF7 LAEQEGRTGLIPCN-------YITMRP-HPWYIRHCSRMEAEERLQEIDQ 79 +UniRef90_UPI0000E478D2 LAHQGAKQGLVPEN-------YLKIEKSHPWYVGKISRKVAEEYLMSMP- 80 +UniRef90_UPI0000E49A1C ----------MGPK-------HTYPEIAMAWFFPTITRKNAELLLMQE-- 31 +UniRef90_A8E5T1 KAELFGREGYIPKN-------YIKVKP-HPWYAGRISRQVAEEILLKRNF 79 +UniRef90_C1C3T6 KAELKGQEGYIPKN-------YIKVKP-HPWYAGRISRQVAEEILLKKRF 79 +UniRef90_Q13588 KAELRGVEGFIPKN-------YIRVKP-HPWYSGRISRQLAEEILMKRNH 79 +UniRef90_UPI0001C606E3 KAELRGAEGFVPKN-------YIHIKP-HPWYSGRISRQLAEEILMKRNQ 79 +UniRef90_Q9CX99 KAELRGAEGFVPKN-------YIRVKP-HPWYSGRISRQLAEETLMKRNH 79 +UniRef90_UPI0000DA3575 GVGLKPIEGMRPTNRTXRIPADIVPSP-HRWYSGRISRQLAEETLMKRNH 86 +UniRef90_UPI0000D9440A KAELRGAEGFIPKN-------YIQVKP-HPWFAGRISRQFAEEILLRRNH 79 +UniRef90_UPI000155C0E1 RTSLLGGESFFYKN-------IQKLSP-SPWYAGRISRQLAEEVLLKRNH 79 +UniRef90_UPI0000E80FCB KAELYGCEGFVPKN-------YIKVKP-HPWYAGRISRHVAEELLLKRRY 79 +UniRef90_UPI00016E4BE7 TAELHNRKGFVPKN-------YINLRP-HAWFAGRISRSVAESRLRQRE- 78 +UniRef90_Q503S8 TAEFVNRKGYVPKN-------YISLRP-HAWFAGRISRHVAENRLHQRD- 78 +UniRef90_Q4V9Q1 TAELLGRRGYVPKN-------YINVRP-HTWFVGGISRQAAENRLRPLE- 78 +UniRef90_UPI00017B202F TAEIQGKRGYIPQN-------YISLLP-YPWFVGRVSRLEAEKRLRWQD- 78 +UniRef90_UPI0000E25B42 KAELGSQEGYVPKN-------FIDIQF-PEWFHEGLSRHQAENLLMGKE- 149 +UniRef90_O75791 KAELGSQEGYVPKN-------FIDIQF-PKWFHEGLSRHQAENLLMGKE- 76 +UniRef90_B7Z8F8 RHKLNP---FSSK----------------RWFHEGLSRHQAENLLMGKE- 50 +UniRef90_UPI00005BC6B6 KAELGSQEGYVPKN-------FIEIEF-PEWFHEGLSRHQAESLLMGKE- 76 +UniRef90_O89100 KAELGSQEGYVPKN-------FIDIEF-PEWFHEGLSRHQAENLLMGKD- 76 +UniRef90_UPI0000EDE7DF KAELKSHEGYVPKN-------FIDIHI-PGWFHEGISRHEAESLLMGKE- 76 +UniRef90_UPI0000F2E19C KAELGSQEGYVPKN-------FIDIQF-PSWFHEDISRHDAESLLMGKD- 241 +UniRef90_UPI0000E7F8B9 KAELRSQEGYVPKN-------FIDFHV-PPWFDEKISRHEAESILMNKG- 76 +UniRef90_UPI0000ECD2B7 KAELRSQEGYVPKN-------FIDFHV-PPWFDEKISRHEAESILMNKG- 76 +UniRef90_UPI000194E163 KAELRSHEGYVPKN-------FIDFHV-PHWFDEKISRHEAENLLMSKG- 91 +UniRef90_B5X487 KAELHGQEGFVPQN-------YIERQT-PSWFKETASRSSAEELLMSRE- 76 +UniRef90_Q567F1 KAELHGHEGYVPKN-------YVDRQI-PSWFKESASRGSAEETLMSRE- 76 + + +SH2 -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 58 +UniRef90_UPI0000EB201F -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 80 +UniRef90_P62993 -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 113 +UniRef90_P87379 -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 113 +UniRef90_UPI00016E653C -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 113 +UniRef90_UPI00016E653B -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 113 +UniRef90_Q4T656 -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 110 +UniRef90_UPI0001555716 -------NYGSFFILXXXXP--PGDALTGARSTPRFGNDVQHFKVLR--D 427 +UniRef90_UPI000180AF26 -------LDESFLVRESEST--PGDFSL----SVKTNSGVQHFKVLR--D 87 +UniRef90_UPI000180AF37 -------LDGSFLVRESEST--PGEFSV----SVKTNSGVQHFKVLR--D 112 +UniRef90_A8XPY6 -------RDGHFLVRQCESS--PGEFSI----SVRFQDSVQHFKVLR--D 114 +UniRef90_P29355 -------RDGHFLVRQCESS--PGEFSI----SVRFQDSVQHFKVLR--D 114 +UniRef90_UPI000186E6C5 -------HEGAFLIRVSESS--PGDFSL----SVKCSDGVQHFKVLR--D 112 +UniRef90_Q08012 -------HEGAFLIRISESS--PGDFSL----SVKCPDGVQHFKVLR--D 112 +UniRef90_B7P0R2 -------HEGAFLIRVSESS--PGDFSL----SVRCGDGVQHFKVLR--D 112 +UniRef90_D3PIQ8 -------HEGAFVIRVSESS--PGDFSL----SVKCGDGVQHFKVLR--D 112 +UniRef90_C4WWT7 -------PEGCFLVRISESS--PGDFSL----SVKCGDGVQHFKVLR--D 112 +UniRef90_UPI0000586DB6 -------GDGAFLIRESEGT--PGDYSL----SVKFVDGVQHFKVLR--D 75 +UniRef90_UPI0001CBA623 -------HDGAFLIRESESA--PGDFSL----SVKFKDEVQHFKVLR--D 113 +UniRef90_UPI0001CBA624 -------YDGAFLIRESEST--PGDFSL----SVKFKDGVQNFKILR--D 112 +UniRef90_UPI000192619C -------HDGAYLIRDSEST--AGDFSL----SVKFNNQVQHFKVLR--D 87 +UniRef90_UPI0000521DDC -------PDGAFLIRESESS--PGDFSL----SVKYGSAVQHFKVLR--D 114 +UniRef90_C1LZF7 ETAQHLQPDGAFILRQSEAD--GKGFSL----SVKQGCEVLHFKVLQ--D 121 +UniRef90_UPI0000E478D2 -------SDGAFMIRDSESNPDSGNFSL----SVKFRDQVQHFKILT--D 117 +UniRef90_UPI0000E49A1C -------RNGAFLVRRSESS--EGLYSL----SVKYNESVQHFRILQ--D 66 +UniRef90_A8E5T1 --------VGAFLIRDSESS--PGDFSI----SVNYGHHVQHFKVLRDTE 115 +UniRef90_C1C3T6 --------LGAFLIRDSESS--PGEFSI----SVNYGHHVQHFKVLR--E 113 +UniRef90_Q13588 --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113 +UniRef90_UPI0001C606E3 --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113 +UniRef90_Q9CX99 --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113 +UniRef90_UPI0000DA3575 --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 120 +UniRef90_UPI0000D9440A --------LGAFLIRESESS--PGEFSV----SVNYGNQVQHFKVLR--E 113 +UniRef90_UPI000155C0E1 --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113 +UniRef90_UPI0000E80FCB --------VGAFLIRESESA--PGEFSI----SVNYGQHVQHFKVLR--E 113 +UniRef90_UPI00016E4BE7 --------CGAFLVRESESA--PGEFSM----SVSYGDHVQHFKVLQD-- 112 +UniRef90_Q503S8 --------CGSFLVRESESA--PGEFSM----SVSYGDHVQHFKVLKD-- 112 +UniRef90_Q4V9Q1 --------CGAFLIRESEST--PGEFSV----SVSYGDHVQHFKVLKD-- 112 +UniRef90_UPI00017B202F --------PGVFLVRESESA--PGEFSV----SVSYGNRVEHFRVLE--- 111 +UniRef90_UPI0000E25B42 --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 183 +UniRef90_O75791 --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_B7Z8F8 --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 84 +UniRef90_UPI00005BC6B6 --------LGCFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_O89100 --------IGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_UPI0000EDE7DF --------VGSFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_UPI0000F2E19C --------VGSFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 275 +UniRef90_UPI0000E7F8B9 --------VGSFIVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_UPI0000ECD2B7 --------VGSFIVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 110 +UniRef90_UPI000194E163 --------VGCFVVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 125 +UniRef90_B5X487 --------VGGFLIRGSQSS--PGEFSI----SVRHEFDVQHFKVMK--D 110 +UniRef90_Q567F1 --------VGAFLIRGSQSS--PGDFSI----SVRHDYDVQHFKVMK--D 110 + * :*::: + +SH2 GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 93 +UniRef90_UPI0000EB201F GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 115 +UniRef90_P62993 GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 148 +UniRef90_P87379 GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 148 +UniRef90_UPI00016E653C GAGKYFLWVVKFNSLNELVEYHRTTSVSR---------------NQQIFL 148 +UniRef90_UPI00016E653B GAGKYFLWVVKFNSLNELVEYHRTTSVSR---------------NQQIFL 148 +UniRef90_Q4T656 GAGKYFLWVVKFTSLNELVEYHRTTSVSR---------------NQQIFL 145 +UniRef90_UPI0001555716 GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 462 +UniRef90_UPI000180AF26 GAGKYFIWLVKFKSLNQLVDYHRTSSVSR---------------SEQILL 122 +UniRef90_UPI000180AF37 GAGKYFIWVVKFSSLNELVVYHRVMTVSG---------------SERIFL 147 +UniRef90_A8XPY6 QNGKYYLWAVKFNSLNELVAYHRTASVSR---------------THTILL 149 +UniRef90_P29355 QNGKYYLWAVKFNSLNELVAYHRTASVSR---------------THTILL 149 +UniRef90_UPI000186E6C5 AQGKFFLWVVKFSSLNELVEYHRTSSVSR---------------SQHVKL 147 +UniRef90_Q08012 AQSKFFLWVVKFNSLNELVEYHRTASVSR---------------SQDVKL 147 +UniRef90_B7P0R2 TLGKFFLWVVKFASLNELVEYHRSASVSR---------------SQDIKL 147 +UniRef90_D3PIQ8 GQGKFFLWVVKFNSLNELVEYHHSASVSR---------------SQDIKL 147 +UniRef90_C4WWT7 AQAKFFLWVVKFDSLNELVDYHRESSVSR---------------SQDVRL 147 +UniRef90_UPI0000586DB6 GAGKYFLWVVKFNSLNQLVEYHRTSSVSR---------------SQTIYL 110 +UniRef90_UPI0001CBA623 GAGKYFLWVVKFNSLNELVEYHRSSSVSR---------------TQTIYL 148 +UniRef90_UPI0001CBA624 GAGKYFLWVVKFNSLNQLVDYHRTSSVSR---------------SEQIFL 147 +UniRef90_UPI000192619C GAGKYFLWVVKFNSLNQLVEYHRAASVSR---------------SQTIYL 122 +UniRef90_UPI0000521DDC GAGKYFLWVVKFSSLNELIKYHREQSISR---------------TQQIML 149 +UniRef90_C1LZF7 EAGKYFFWLSKFDSINQLIDHHRKTSISR---------------NRLLTL 156 +UniRef90_UPI0000E478D2 LAGKYFLWVVKFTSINDLVDYHKDNSVSRTQEIVLNEPCVPIEDANQRPQ 167 +UniRef90_UPI0000E49A1C TAGKFHLWIVKFPSLDALVDYYRTTSVTR---------------ENQVST 101 +UniRef90_A8E5T1 SNGKYYLWEAKFNSLNELVDYYRRHSIAK---------------FHEVFL 150 +UniRef90_C1C3T6 KSGTYFLWETKFGSLNELVEFYRSSSIAK---------------THPVLL 148 +UniRef90_Q13588 ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KRQIFL 148 +UniRef90_UPI0001C606E3 ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KRQIFL 148 +UniRef90_Q9CX99 ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------RRQIFL 148 +UniRef90_UPI0000DA3575 ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------RRQIFL 155 +UniRef90_UPI0000D9440A NMGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KKQIFL 148 +UniRef90_UPI000155C0E1 RIGKYYLWEEKFNSLNELVDFYRTTTIAK---------------KKQIFL 148 +UniRef90_UPI0000E80FCB RNGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KQQIFL 148 +UniRef90_UPI00016E4BE7 RGGQYYVWDELFPSLNELVEFYHCNSIAR---------------ERTVLL 147 +UniRef90_Q503S8 REGYYFVWEEIFPSLNQLVDFYKTNSIAK---------------ERTVFL 147 +UniRef90_Q4V9Q1 GLGQYFIWDEVFSSLNQLVDFYRINSIAK---------------ERTVFL 147 +UniRef90_UPI00017B202F GGGQYCIWEESFCSLNRLVDFYRTHSIAM---------------DKVVCL 146 +UniRef90_UPI0000E25B42 NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 218 +UniRef90_O75791 NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 145 +UniRef90_B7Z8F8 NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 119 +UniRef90_UPI00005BC6B6 NKGNYFLWTEKFPSLNKLVDYYRKNSISK---------------QKQIFL 145 +UniRef90_O89100 TKGNYFLWTEKFPSLNKLVDYYRTTSISK---------------QKQVFL 145 +UniRef90_UPI0000EDE7DF AKGHYFLWTEKFQSLNRLVEFYKTSSISR---------------QKQIFL 145 +UniRef90_UPI0000F2E19C AKGHYFLWTEKFQSLNQLVNFYRTSSISK---------------QKQIYL 310 +UniRef90_UPI0000E7F8B9 SKGNYYLWTEKFYSLNKLVDYYRTSTISR---------------QKQILL 145 +UniRef90_UPI0000ECD2B7 SKGNYYLWTEKFYSLNKLVDYYRTSTISR---------------QKQILL 145 +UniRef90_UPI000194E163 SKGSYYLWTEKFHSLNKLVDYYKTSSISR---------------QKQIFL 160 +UniRef90_B5X487 SKGHYFLWSEKFTSLNKLVDFYKNTSISK---------------QRDIYL 145 +UniRef90_Q567F1 KSGHYYLWTEKFTSLNKLVDFYKTTSISK---------------QKEIFL 145 + . : .* * *:: *: .:: ::: . + +SH2 RDIEQVP------------------------------------------- 100 +UniRef90_UPI0000EB201F RDIEQVPQQNSIFSLCQR----TSLTLCSIVSLEASEEENPVVREWSPHS 161 +UniRef90_P62993 RDIEQVP------------------------------------------- 155 +UniRef90_P87379 RDIEQVPQVHGGDRATS--------------------------------- 165 +UniRef90_UPI00016E653C REIEQ--------------------------------------------- 153 +UniRef90_UPI00016E653B REIEQVTQVNVGTHYIN--------------------------------- 165 +UniRef90_Q4T656 RDIEQVTQV----------------------------------------- 154 +UniRef90_UPI0001555716 RDIEQMPQQKSPVCDRLS----FLFCAVNCRACSDGVFHG---------- 498 +UniRef90_UPI000180AF26 RHPIIS-------------------------------------------- 128 +UniRef90_UPI000180AF37 LHPIS--------------------------------------------- 152 +UniRef90_A8XPY6 ADMNV--------------------------------------------- 154 +UniRef90_P29355 SDMNV--------------------------------------------- 154 +UniRef90_UPI000186E6C5 RDMVP--------------------------------------------- 152 +UniRef90_Q08012 RDMIP--------------------------------------------- 152 +UniRef90_B7P0R2 RDMHP--------------------------------------------- 152 +UniRef90_D3PIQ8 KEIIC--------------------------------------------- 152 +UniRef90_C4WWT7 RDMPAATQNG---------------------------------------- 157 +UniRef90_UPI0000586DB6 KDRKS--------------------------------------------- 115 +UniRef90_UPI0001CBA623 LKMHV--------------------------------------------- 153 +UniRef90_UPI0001CBA624 KDKQ---------------------------------------------- 151 +UniRef90_UPI000192619C KDMTN--------------------------------------------- 127 +UniRef90_UPI0000521DDC VDLPV--------------------------------------------- 154 +UniRef90_C1LZF7 VDLVPSKRFPTN-------------------------------------- 168 +UniRef90_UPI0000E478D2 PAMQQSR------------------------------------------- 174 +UniRef90_UPI0000E49A1C QSVEQWS------------------------------------------- 108 +UniRef90_A8E5T1 CDEEQ--------------------------------------------- 155 +UniRef90_C1C3T6 RDEEE--------------------------------------------- 153 +UniRef90_Q13588 RDEEP--------------------------------------------- 153 +UniRef90_UPI0001C606E3 RDEEP--------------------------------------------- 153 +UniRef90_Q9CX99 CDEQP--------------------------------------------- 153 +UniRef90_UPI0000DA3575 CDEQP--------------------------------------------- 160 +UniRef90_UPI0000D9440A RDEEP--------------------------------------------- 153 +UniRef90_UPI000155C0E1 RDEEQ--------------------------------------------- 153 +UniRef90_UPI0000E80FCB RDDEQ--------------------------------------------- 153 +UniRef90_UPI00016E4BE7 RDPEQ--------------------------------------------- 152 +UniRef90_Q503S8 RDLDH--------------------------------------------- 152 +UniRef90_Q4V9Q1 RDPEG--------------------------------------------- 152 +UniRef90_UPI00017B202F RDPPS--------------------------------------------- 151 +UniRef90_UPI0000E25B42 RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 265 +UniRef90_O75791 RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 192 +UniRef90_B7Z8F8 RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 166 +UniRef90_UPI00005BC6B6 RDRTREEQGQRGNSLDR---RSQGGHPLSGAVGEEIRPSMNRKPSDHP-L 191 +UniRef90_O89100 RDGTQ-DQGHRGNSLDR---RSQGGPHPSGTVGEEIRPSVNRKLSDHLPL 191 +UniRef90_UPI0000EDE7DF RDGTREDQERRGGSLDR---RAQEGLGLGGACGEEIRVPMNRKMSDLHPP 192 +UniRef90_UPI0000F2E19C RDGGREEQDRWGGSLER---RLQEGLHISGGVGEETRPSTNRKQSDHPPA 357 +UniRef90_UPI0000E7F8B9 RDDSREEKERRGGSLER---MSRDGLHVGGAAAEAHS-SMSKRYVDHP-- 189 +UniRef90_UPI0000ECD2B7 RDDSREEKERRGGSLER---MSRDGLHVGGAAAEAHS-SMSKRYVDHPVP 191 +UniRef90_UPI000194E163 RDNSQEEKERHGGSLER---IGREGFHMGGAAGEDHS-SISKRYVEYPIP 206 +UniRef90_B5X487 RDGSRDDQSPSTPQPLKRGSLPEERS-----YGAPTAATSHRRASDLP-- 188 +UniRef90_Q567F1 RDGSGDE--PRAPPPIK--SQPEVRPPPGGGYGSPQTSSQNRSTTDPT-- 189 diff --git a/examples/code_fragments/trj/test_trj.py b/examples/code_fragments/trj/test_trj.py index 0c3ed1f310eacb6e6e2a2dcc03af26a3aa077258..a1625996c109ed4272a2d8439219b9e7d583db61 100644 --- a/examples/code_fragments/trj/test_trj.py +++ b/examples/code_fragments/trj/test_trj.py @@ -16,9 +16,8 @@ class Anim(QtCore.QTimer): go.UpdatePositions() -# old-style CHARMM format, requires flag bit 0 set -cg = io.LoadCHARMMTraj("mpor_trj.crd","mpor_trj_short.trj",1) -eh=cg.GetEntity() +eh = io.LoadCRD("mpor_trj.crd") +cg = io.LoadCHARMMTraj(eh,"mpor_trj_short.trj") go=gfx.Entity("test",eh.CreateFullView()) scene.Add(go) diff --git a/examples/dssp_sa.py b/examples/dssp_sa.py deleted file mode 100644 index 23369a99e7d18b74c2623150773687823666827a..0000000000000000000000000000000000000000 --- a/examples/dssp_sa.py +++ /dev/null @@ -1,7 +0,0 @@ -from ost.bindings import dssp -ent=io.LoadMMCIF('1ake.cif') -dssp.AssignDSSP(ent, extract_burial_status=True) -for chain in ent.chains: - if chain.is_polypeptide: - for res in chain.residues: - print res.GetFloatProp('relative_solvent_accessibility') diff --git a/modules/base/pymod/export_logger.cc b/modules/base/pymod/export_logger.cc index 91eccbdec2922ab4b5c1167ef48c3ef6d1d8e301..446d041166e3695c7a63578ff223ef966e78f2fb 100644 --- a/modules/base/pymod/export_logger.cc +++ b/modules/base/pymod/export_logger.cc @@ -18,6 +18,10 @@ //------------------------------------------------------------------------------ #include <boost/python.hpp> #include <boost/python/raw_function.hpp> +#if BOOST_VERSION<103400 +#include <boost/python/detail/api_placeholder.hpp> +#endif + using namespace boost::python; #include <ost/log.hh> @@ -178,7 +182,7 @@ void export_Logger() // the "ost" command-line interpreter. If we don't remove all the sinks from // the sink stack, we will get "Fatal Python error: PyEval_SaveThread: // NULL tstate" upon exiting ost. I don't completely understand why, though. - scope().attr("__dict__")["atexit"]=import("atexit"); + scope().attr("__dict__")["atexit"]=handle<>(PyImport_ImportModule("atexit")); def("_reset_sinks", &reset_sinks); object r=scope().attr("_reset_sinks"); diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py index 4bd1a9999738a8814554997a7e7ceb6d4e7c6cfe..48ac52d6467c670b73de3e2f88bb989298caba90 100644 --- a/modules/base/pymod/table.py +++ b/modules/base/pymod/table.py @@ -258,12 +258,30 @@ class Table(object): return type_list def SetName(self, name): + ''' + Set name of the table + :param name: name + :type name: :class:`str` + ''' self.name = name def GetName(self): + ''' + Get name of table + ''' return self.name def _Coerce(self, value, ty): + ''' + Try to convert values (e.g. from :class:`str` type) to the specified type + + :param value: the value + :type value: any type + + :param ty: name of type to convert it to (i.e. *int*, *float*, *string*, + *bool*) + :type ty: :class:`str` + ''' if value=='NA' or value==None: return None if ty=='int': @@ -320,11 +338,23 @@ class Table(object): def ToString(self, float_format='%.3f', int_format='%d', rows=None): ''' Convert the table into a string representation. + The output format can be modified for int and float type columns by specifying a formatting string for the parameters 'float_format' and 'int_format'. + The option 'rows' specify the range of rows to be printed. The parameter - must be a iterable containing two elements, e.g. [start_row, end_row]. + must be a type that supports indexing (e.g. a :class:`list`) containing the + start and end row *index*, e.g. [start_row_idx, end_row_idx]. + + :param float_format: formatting string for float columns + :type float_format: :class:`str` + + :param int_format: formatting string for int columns + :type int_format: :class:`str` + + :param rows: iterable containing start and end row *index* + :type rows: iterable containing :class:`ints <int>` ''' widths=[len(cn) for cn in self.col_names] sel_rows=self.rows @@ -365,7 +395,26 @@ class Table(object): def __str__(self): return self.ToString() - def _AddRowsFromDict(self, d, overwrite=False): + def _AddRowsFromDict(self, d, overwrite=None): + ''' + Add one or more rows from a :class:`dictionary <dict>`. + + If *overwrite* is not None and set to an existing column name, the specified + column in the table is searched for the first occurrence of a value matching + the value of the column with the same name in the dictionary. If a matching + value is found, the row is overwritten with the dictionary. If no matching + row is found, a new row is appended to the table. + + :param d: dictionary containing the data + :type d: :class:`dict` + + :param overwrite: column name to overwrite existing row if value in + column *overwrite* matches + :type overwrite: :class:`str` + + :raises: :class:`ValueError` if multiple rows are added but the number of + data items is different for different columns. + ''' # get column indices idxs = [self.GetColIndex(k) for k in d.keys()] @@ -373,13 +422,13 @@ class Table(object): old_len = None for k,v in d.iteritems(): if IsScalar(v): - d[k] = [v] - else: - if not old_len: - old_len = len(v) - elif old_len!=len(v): - raise ValueError("Cannot add rows: length of data must be equal " + \ - "for all columns in %s"%str(d)) + v = [v] + d[k] = v + if not old_len: + old_len = len(v) + elif old_len!=len(v): + raise ValueError("Cannot add rows: length of data must be equal " + \ + "for all columns in %s"%str(d)) # convert column based dict to row based dict and create row and add data for i,data in enumerate(zip(*d.values())): @@ -409,18 +458,78 @@ class Table(object): """ Add a row to the table. - *row* may either be a dictionary or a list-like object. - In the case of a dictionary the keys in the dictionary must match the column - names. Columns not found in the dict will be initialized to None. - Alternatively, if data is a list-like object, the row is initialized from - the values in data. The number of items in data must match the number of - columns in the table. A :class:`ValuerError` is raised otherwise. The values - are added in the order specified in the list, thus, the order of the data - must match the columns. - - If *overwrite* is set and not None (must be set to an existing column name), - an existing row is overwritten if the value of column *overwrite* matches. - If no matching row is found, a new row is appended to the table. + *data* may either be a dictionary or a list-like object: + + - If *data* is a dictionary the keys in the dictionary must match the + column names. Columns not found in the dict will be initialized to None. + If the dict contains list-like objects, multiple rows will be added, if + the number of items in all list-like objects is the same, otherwise a + :class:`ValueError` is raised. + + - If *data* is a list-like object, the row is initialized from the values + in *data*. The number of items in *data* must match the number of + columns in the table. A :class:`ValuerError` is raised otherwise. The + values are added in the order specified in the list, thus, the order of + the data must match the columns. + + If *overwrite* is not None and set to an existing column name, the specified + column in the table is searched for the first occurrence of a value matching + the value of the column with the same name in the dictionary. If a matching + value is found, the row is overwritten with the dictionary. If no matching + row is found, a new row is appended to the table. + + :param data: data to add + :type data: :class:`dict` or *list-like* object + + :param overwrite: column name to overwrite existing row if value in + column *overwrite* matches + :type overwrite: :class:`str` + + :raises: :class:`ValueError` if *list-like* object is used and number of + items does *not* match number of columns in table. + + :raises: :class:`ValueError` if *dict* is used and multiple rows are added + but the number of data items is different for different columns. + + **Example:** add multiple data rows to a subset of columns using a dictionary + + .. code-block:: python + + # create table with three float columns + tab = Table(['x','y','z'], 'fff') + + # add rows from dict + data = {'x': [1.2, 1.6], 'z': [1.6, 5.3]} + tab.AddRow(data) + print tab + + ''' + will produce the table + + ==== ==== ==== + x y z + ==== ==== ==== + 1.20 NA 1.60 + 1.60 NA 5.30 + ==== ==== ==== + ''' + + # overwrite the row with x=1.2 and add row with x=1.9 + data = {'x': [1.2, 1.9], 'z': [7.9, 3.5]} + tab.AddRow(data, overwrite='x') + print tab + + ''' + will produce the table + + ==== ==== ==== + x y z + ==== ==== ==== + 1.20 NA 7.90 + 1.60 NA 5.30 + 1.90 NA 3.50 + ==== ==== ==== + ''' """ if type(data)==dict: self._AddRowsFromDict(data, overwrite) @@ -448,6 +557,9 @@ class Table(object): def RemoveCol(self, col): """ Remove column with the given name from the table + + :param col: name of column to remove + :type col: :class:`str` """ idx = self.GetColIndex(col) del self.col_names[idx] @@ -459,26 +571,81 @@ class Table(object): """ Add a column to the right of the table. + :param col_name: name of new column + :type col_name: :class:`str` + + :param col_type: type of new column (long versions: *int*, *float*, *bool*, + *string* or short versions: *i*, *f*, *b*, *s*) + :type col_type: :class:`str` + + :param data: data to add to new column. + :type data: scalar or iterable + + **Example:** + .. code-block:: python tab=Table(['x'], 'f', x=range(5)) tab.AddCol('even', 'bool', itertools.cycle([True, False])) print tab - will produce the table - - ==== ==== - x even - ==== ==== - 0 True - 1 False - 2 True - 3 False - 4 True - ==== ==== + ''' + will produce the table + + ==== ==== + x even + ==== ==== + 0 True + 1 False + 2 True + 3 False + 4 True + ==== ==== + ''' + + If data is a constant instead of an iterable object, it's value + will be written into each row: + + .. code-block:: python + + tab=Table(['x'], 'f', x=range(5)) + tab.AddCol('num', 'i', 1) + print tab + + ''' + will produce the table + + ==== ==== + x num + ==== ==== + 0 1 + 1 1 + 2 1 + 3 1 + 4 1 + ==== ==== + ''' + + .. warning:: + + :meth:`AddCol` only adds data to existing rows and does *not* + add new rows. Use :meth:`AddRow` to do this. Therefore, the following code + snippet does not add any data items: + + .. code-block:: python + + tab=Table() + tab.AddCol('even', 'int', [1,2,3,4,5]) + print tab - if data is a constant instead of an iterable object, it's value - will be written into each row + ''' + will produce the empty table + + ==== + even + ==== + ''' + """ col_type = self._ParseColTypes(col_type, exp_num=1)[0] self.col_names.append(col_name) @@ -490,8 +657,6 @@ class Table(object): for row, d in zip(self.rows, data): row.append(d) - - def Filter(self, *args, **kwargs): """ Returns a filtered table only containing rows matching all the predicates @@ -601,13 +766,38 @@ class Table(object): return cPickle.load(stream) @staticmethod - def Load(stream_or_filename, format='ost', sep=','): + def _GuessFormat(filename): + try: + filename = filename.name + except AttributeError, e: + pass + if filename.endswith('.csv'): + return 'csv' + elif filename.endswith('.pickle'): + return 'pickle' + else: + return 'ost' + + + @staticmethod + def Load(stream_or_filename, format='auto', sep=','): """ Load table from stream or file with given name. - By default, the file format is *ost* (see below) and is *not* automatically - determined (e.g. from file extension). Thus, it *format* must be specified - for reading other file formats. + By default, the file format is set to *auto*, which tries to guess the file + format from the file extension. The following file extensions are + recognized: + + ============ ====================== + extension recognized format + ============ ====================== + .csv comma separated values + .pickle pickled byte stream + <all others> ost-specific format + ============ ====================== + + Thus, *format* must be specified for reading file with different filename + extensions. The following file formats are understood: @@ -643,6 +833,9 @@ class Table(object): :returns: A new :class:`Table` instance """ format=format.lower() + if format=='auto': + format = Table._GuessFormat(stream_or_filename) + if format=='ost': return Table._LoadOST(stream_or_filename) if format=='csv': @@ -653,7 +846,13 @@ class Table(object): def Sort(self, by, order='+'): """ - Performs an in-place sort of the table, based on column. + Performs an in-place sort of the table, based on column *by*. + + :param by: column name by which to sort + :type by: :class:`str` + + :param order: ascending (``-``) or descending (``+``) order + :type order: :class:`str` (i.e. *+*, *-*) """ sign=-1 if order=='-': @@ -666,6 +865,12 @@ class Table(object): def GetUnique(self, col, ignore_nan=True): """ Extract a list of all unique values from one column + + :param col: column name + :type col: :class:`str` + + :param ignore_nan: ignore all *None* values + :type ignore_nan: :class:`bool` """ idx = self.GetColIndex(col) seen = {} @@ -704,7 +909,102 @@ class Table(object): num_z_levels=10, diag_line=False, labels=None, max_num_labels=None, title=None, clear=True, save=False, **kwargs): """ - Plot x against y using matplot lib + Function to plot values from your table in 1, 2 or 3 dimensions using + `Matplotlib <http://matplotlib.sourceforge.net>`__ + + :param x: column name for first dimension + :type x: :class:`str` + + :param y: column name for second dimension + :type y: :class:`str` + + :param z: column name for third dimension + :type z: :class:`str` + + :param style: symbol style (e.g. *.*, *-*, *x*, *o*, *+*, *\**). For a + complete list check (`matplotlib docu <http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.plot>`__). + :type style: :class:`str` + + :param x_title: title for first dimension, if not specified it is + automatically derived from column name + :type x_title: :class:`str` + + :param y_title: title for second dimension, if not specified it is + automatically derived from column name + :type y_title: :class:`str` + + :param z_title: title for third dimension, if not specified it is + automatically derived from column name + :type z_title: :class:`str` + + :param x_range: start and end value for first dimension (e.g. [start_x, end_x]) + :type x_range: :class:`list` of length two + + :param y_range: start and end value for second dimension (e.g. [start_y, end_y]) + :type y_range: :class:`list` of length two + + :param z_range: start and end value for third dimension (e.g. [start_z, end_z]) + :type z_range: :class:`list` of length two + + :param color: color for data (e.g. *b*, *g*, *r*). For a complete list check + (`matplotlib docu <http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.plot>`__). + :type color: :class:`str` + + :param plot_if: callable which returnes *True* if row should be plotted. Is + invoked like ``plot_if(self, row)`` + :type plot_if: callable + + :param legend: legend label for data series + :type legend: :class:`str` + + :param num_z_levels: number of levels for third dimension + :type num_z_levels: :class:`int` + + :param diag_line: draw diagonal line + :type diag_line: :class:`bool` + + :param labels: column name containing labels to put on x-axis for one + dimensional plot + :type labels: :class:`str` + + :param max_num_labels: limit maximum number of labels + :type max_num_labels: :class:`int` + + :param title: plot title, if not specified it is automatically derived from + plotted column names + :type title: :class:`str` + + :param clear: clear old data from plot + :type clear: :class:`bool` + + :param save: filename for saving plot + :type save: :class:`str` + + :param \*\*kwargs: additional arguments passed to matplotlib + + :returns: the ``matplotlib.pyplot`` module + + **Examples:** simple plotting functions + + .. code-block:: python + + tab=Table(['a','b','c','d'],'iffi', a=range(5,0,-1), + b=[x/2.0 for x in range(1,6)], + c=[math.cos(x) for x in range(0,5)], + d=range(3,8)) + + # one dimensional plot of column 'd' vs. index + plt=tab.Plot('d') + plt.show() + + # two dimensional plot of 'a' vs. 'c' + plt=tab.Plot('a', y='c', style='o-') + plt.show() + + # three dimensional plot of 'a' vs. 'c' with values 'b' + plt=tab.Plot('a', y='c', z='b') + # manually save plot to file + plt.savefig("plot.png") """ try: import matplotlib.pyplot as plt @@ -714,7 +1014,7 @@ class Table(object): xs = [] ys = [] zs = [] - + if clear: plt.figure(figsize=[8, 6]) @@ -738,6 +1038,14 @@ class Table(object): nice_z = MakeTitle(z) else: nice_z = None + + if x_range and (IsScalar(x_range) or len(x_range)!=2): + raise ValueError('parameter x_range must contain exactly two elements') + if y_range and (IsScalar(y_range) or len(y_range)!=2): + raise ValueError('parameter y_range must contain exactly two elements') + if z_range and (IsScalar(z_range) or len(z_range)!=2): + raise ValueError('parameter z_range must contain exactly two elements') + if color: kwargs['color']=color if legend: @@ -846,7 +1154,56 @@ class Table(object): y_title=None, title=None, clear=True, save=False): """ Create a histogram of the data in col for the range *x_range*, split into - *num_bins* bins and plot it using matplot lib. + *num_bins* bins and plot it using Matplotlib. + + :param col: column name with data + :type col: :class:`str` + + :param x_range: start and end value for first dimension (e.g. [start_x, end_x]) + :type x_range: :class:`list` of length two + + :param num_bins: number of bins in range + :type num_bins: :class:`int` + + :param normed: normalize histogram + :type normed: :class:`bool` + + :param histtype: type of histogram (i.e. *bar*, *barstacked*, *step*, + *stepfilled*). See (`matplotlib docu <http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.hist>`__). + :type histtype: :class:`str` + + :param align: style of histogram (*left*, *mid*, *right*). See + (`matplotlib docu <http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.hist>`__). + :type align: :class:`str` + + :param x_title: title for first dimension, if not specified it is + automatically derived from column name + :type x_title: :class:`str` + + :param y_title: title for second dimension, if not specified it is + automatically derived from column name + :type y_title: :class:`str` + + :param title: plot title, if not specified it is automatically derived from + plotted column names + :type title: :class:`str` + + :param clear: clear old data from plot + :type clear: :class:`bool` + + :param save: filename for saving plot + :type save: :class:`str` + + **Examples:** simple plotting functions + + .. code-block:: python + + tab=Table(['a'],'f', a=[math.cos(x*0.01) for x in range(100)]) + + # one dimensional plot of column 'd' vs. index + plt=tab.PlotHistogram('a') + plt.show() + """ try: import matplotlib.pyplot as plt @@ -915,6 +1272,9 @@ class Table(object): Returns the row containing the cell with the maximal value in col. If several rows have the highest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Max(col) return self.rows[idx] @@ -923,6 +1283,9 @@ class Table(object): """ Returns the maximum value in col. If several rows have the highest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Max(col) return val @@ -932,6 +1295,9 @@ class Table(object): Returns the row index of the cell with the maximal value in col. If several rows have the highest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Max(col) return idx @@ -958,6 +1324,9 @@ class Table(object): """ Returns the minimal value in col. If several rows have the lowest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Min(col) return val @@ -967,6 +1336,9 @@ class Table(object): Returns the row containing the cell with the minimal value in col. If several rows have the lowest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Min(col) return self.rows[idx] @@ -976,6 +1348,9 @@ class Table(object): Returns the row index of the cell with the minimal value in col. If several rows have the lowest value, only the first one is returned. None values are ignored. + + :param col: column name + :type col: :class:`str` """ val, idx = self._Min(col) return idx @@ -985,6 +1360,11 @@ class Table(object): Returns the sum of the given column. Cells with None are ignored. Returns 0.0, if the column doesn't contain any elements. Col must be of numeric column type ('float', 'int') or boolean column type. + + :param col: column name + :type col: :class:`str` + + :raises: :class:`TypeError` if column type is ``string`` """ idx = self.GetColIndex(col) col_type = self.col_types[idx] @@ -1004,6 +1384,11 @@ class Table(object): If column type is *bool*, the function returns the ratio of number of 'Trues' by total number of elements. + + :param col: column name + :type col: :class:`str` + + :raises: :class:`TypeError` if column type is ``string`` """ idx = self.GetColIndex(col) col_type = self.col_types[idx] @@ -1021,13 +1406,21 @@ class Table(object): def RowMean(self, mean_col_name, cols): """ - Adds a new column of type 'float' with a specified name (mean_col), + Adds a new column of type 'float' with a specified name (*mean_col_name*), containing the mean of all specified columns for each row. Cols are specified by their names and must be of numeric column - type ('float', 'int') or boolean column type.. Cells with None are ignored. + type ('float', 'int') or boolean column type. Cells with None are ignored. Adds None if the row doesn't contain any values. + :param mean_col_name: name of new column containing mean values + :type mean_col_name: :class:`str` + + :param cols: name or list of names of columns to include in computation of + mean + :type cols: :class:`str` or :class:`list` of strings + + :raises: :class:`TypeError` if column type of columns in *col* is ``string`` == Example == @@ -1045,7 +1438,7 @@ class Table(object): .. code-block::python - tab.RowMean('mean', 'x', 'u') + tab.RowMean('mean', ['x', 'u']) ==== ==== ==== ===== @@ -1089,6 +1482,11 @@ class Table(object): Returns the median of the given column. Cells with None are ignored. Returns None, if the column doesn't contain any elements. Col must be of numeric column type ('float', 'int') or boolean column type. + + :param col: column name + :type col: :class:`str` + + :raises: :class:`TypeError` if column type is ``string`` """ idx = self.GetColIndex(col) col_type = self.col_types[idx] @@ -1110,6 +1508,11 @@ class Table(object): Returns the standard deviation of the given column. Cells with None are ignored. Returns None, if the column doesn't contain any elements. Col must be of numeric column type ('float', 'int') or boolean column type. + + :param col: column name + :type col: :class:`str` + + :raises: :class:`TypeError` if column type is ``string`` """ idx = self.GetColIndex(col) col_type = self.col_types[idx] @@ -1128,6 +1531,12 @@ class Table(object): def Count(self, col, ignore_nan=True): """ Count the number of cells in column that are not equal to None. + + :param col: column name + :type col: :class:`str` + + :param ignore_nan: ignore all *None* values + :type ignore_nan: :class:`bool` """ count=0 idx=self.GetColIndex(col) @@ -1141,10 +1550,16 @@ class Table(object): def Correl(self, col1, col2): """ - Calculate the Pearson correlation coefficient between col1 and col2, only - taking rows into account where both of the values are not equal to None. If - there are not enough data points to calculate a correlation coefficient, - None is returned. + Calculate the Pearson correlation coefficient between *col1* and *col2*, only + taking rows into account where both of the values are not equal to *None*. + If there are not enough data points to calculate a correlation coefficient, + *None* is returned. + + :param col1: column name for first column + :type col1: :class:`str` + + :param col2: column name for second column + :type col2: :class:`str` """ if IsStringLike(col1) and IsStringLike(col2): col1 = self.GetColIndex(col1) @@ -1166,7 +1581,13 @@ class Table(object): there are not enough data points to calculate a correlation coefficient, None is returned. - The function depends on the following module: *scipy.stats.mstats* + :warning: The function depends on the following module: *scipy.stats.mstats* + + :param col1: column name for first column + :type col1: :class:`str` + + :param col2: column name for second column + :type col2: :class:`str` """ try: import scipy.stats.mstats @@ -1194,8 +1615,22 @@ class Table(object): def Save(self, stream_or_filename, format='ost', sep=','): """ - Save the table to stream or filename. For supported file formats, see - :meth:`Load` + Save the table to stream or filename. The following three file formats + are supported (for more information on file formats, see :meth:`Load`): + + ============= ======================================= + ost ost-specific format (human readable) + csv comma separated values (human readable) + pickle pickled byte stream (binary) + ============= ======================================= + + :param stream_or_filename: filename or stream for writing output + :type stream_or_filename: :class:`str` or :class:`file` + + :param format: output format (i.e. *ost*, *csv*, *pickle*) + :type format: :class:`str` + + :raises: :class:`ValueError` if format is unknown """ format=format.lower() if format=='ost': @@ -1245,8 +1680,12 @@ class Table(object): ''' Returns a numpy matrix containing the selected columns from the table as columns in the matrix. - Only columns of type int or float are supported. NA values in the table - will be converted to None values. + Only columns of type *int* or *float* are supported. *NA* values in the + table will be converted to *None* values. + + :param \*args: column names to include in numpy matrix + + :warning: The function depends on *numpy* ''' try: import numpy as np @@ -1352,11 +1791,14 @@ class Table(object): style='-', title=None, x_title=None, y_title=None, clear=True, save=None): ''' - Plot an enrichment curve using matplotlib. + Plot an enrichment curve using matplotlib of column *score_col* classified + according to *class_col*. - For more information about parameters, see :meth:`ComputeEnrichment` - ''' + For more information about parameters of the enrichment, see + :meth:`ComputeEnrichment`, and for plotting see :meth:`Plot`. + :warning: The function depends on *matplotlib* + ''' try: import matplotlib.pyplot as plt @@ -1392,24 +1834,23 @@ class Table(object): def ComputeEnrichment(self, score_col, class_col, score_dir='-', class_dir='-', class_cutoff=2.0): ''' - Computes the enrichment of one column (e.g. score) over all data points. + Computes the enrichment of column *score_col* classified according to + *class_col*. For this it is necessary, that the datapoints are classified into positive and negative points. This can be done in two ways: - - by using one 'bool' column which contains True for positives and False - for negatives - - by specifying an additional column, a cutoff value and the columns - direction. This will generate the classification on the fly + - by using one 'bool' type column (*class_col*) which contains *True* for + positives and *False* for negatives - * if class_dir=='-': values in the classification column that are - less than or equal to class_cutoff will be counted - as positives - * if class_dir=='+': values in the classification column that are - larger than or equal to class_cutoff will be counted - as positives - - During the calculation, the table will be sorted according to score_dir, + - by specifying a classification column (*class_col*), a cutoff value + (*class_cutoff*) and the classification columns direction (*class_dir*). + This will generate the classification on the fly + + * if ``class_dir=='-'``: values in the classification column that are less than or equal to class_cutoff will be counted as positives + * if ``class_dir=='+'``: values in the classification column that are larger than or equal to class_cutoff will be counted as positives + + During the calculation, the table will be sorted according to *score_dir*, where a '-' values means smallest values first and therefore, the smaller the value, the better. @@ -1456,7 +1897,10 @@ class Table(object): Computes the area under the curve of the enrichment using the trapezoidal rule. - For more information about parameters, see :meth:`ComputeEnrichment` + For more information about parameters of the enrichment, see + :meth:`ComputeEnrichment`. + + :warning: The function depends on *numpy* ''' try: import numpy as np @@ -1472,8 +1916,8 @@ class Table(object): def ComputeROC(self, score_col, class_col, score_dir='-', class_dir='-', class_cutoff=2.0): ''' - Computes the receiver operating characteristics of one column (e.g. score) - over all data points. + Computes the receiver operating characteristics (ROC) of column *score_col* + classified according to *class_col*. For this it is necessary, that the datapoints are classified into positive and negative points. This can be done in two ways: @@ -1484,12 +1928,8 @@ class Table(object): and the classification columns direction (*class_dir*). This will generate the classification on the fly - - if *class_dir* =='-': values in the classification column that are - less than or equal to *class_cutoff* will be counted - as positives - - if *class_dir* =='+': values in the classification column that are - larger than or equal to *class_cutoff* will be - counted as positives + - if ``class_dir=='-'``: values in the classification column that are less than or equal to *class_cutoff* will be counted as positives + - if ``class_dir=='+'``: values in the classification column that are larger than or equal to *class_cutoff* will be counted as positives During the calculation, the table will be sorted according to *score_dir*, where a '-' values means smallest values first and therefore, the smaller @@ -1561,7 +2001,10 @@ class Table(object): Computes the area under the curve of the receiver operating characteristics using the trapezoidal rule. - For more information about parameters, see :meth:`ComputeROC` + For more information about parameters of the ROC, see + :meth:`ComputeROC`. + + :warning: The function depends on *numpy* ''' try: import numpy as np @@ -1583,7 +2026,10 @@ class Table(object): ''' Plot an ROC curve using matplotlib. - For more information about parameters, see :meth:`ComputeROC` + For more information about parameters of the ROC, see + :meth:`ComputeROC`, and for plotting see :meth:`Plot`. + + :warning: The function depends on *matplotlib* ''' try: @@ -1640,14 +2086,8 @@ class Table(object): - by using 'float' or 'int' columns and specifying a cutoff value and the columns direction. This will generate the classification on the fly - * if *class_dir*/*score_dir*=='-': values in the classification column - that are less than or equal to - *class_cutoff*/*score_cutoff* will be - counted as positives - * if *class_dir*/*score_dir*=='+': values in the classification column - that are larger than or equal to - *class_cutoff*/*score_cutoff* will be - counted as positives + * if ``class_dir``/``score_dir=='-'``: values in the classification column that are less than or equal to *class_cutoff*/*score_cutoff* will be counted as positives + * if ``class_dir``/``score_dir=='+'``: values in the classification column that are larger than or equal to *class_cutoff*/*score_cutoff* will be counted as positives The two possibilities can be used together, i.e. 'bool' type for one column and 'float'/'int' type and cutoff/direction for the other column. @@ -1754,9 +2194,11 @@ class Table(object): If the type of any column in *tab* is not the same as in the current table a *TypeError* is raised. - If *overwrite* is set and not None (must be set to an existing column name), - an existing row is overwritten if the value of column *overwrite* matches. - If no matching row is found, a new row is appended to the table. + If *overwrite* is not None and set to an existing column name, the specified + column in the table is searched for the first occurrence of a value matching + the value of the column with the same name in the dictionary. If a matching + value is found, the row is overwritten with the dictionary. If no matching + row is found, a new row is appended to the table. """ # add column to current table if it doesn't exist for name,typ in zip(tab.col_names, tab.col_types): diff --git a/modules/base/pymod/wrap_base.cc b/modules/base/pymod/wrap_base.cc index 40ad33717f79c38e58c21624b87736f387016f3c..e1a74154acc8cd264166c732533c63f9adcd9556 100644 --- a/modules/base/pymod/wrap_base.cc +++ b/modules/base/pymod/wrap_base.cc @@ -102,7 +102,7 @@ BOOST_PYTHON_MODULE(_ost_base) ; class_<std::vector<String> >("StringList", init<>()) - .def(vector_indexing_suite<std::vector<String> >()) + .def(vector_indexing_suite<std::vector<String>, true>()) ; typedef std::vector<int> IntList; diff --git a/modules/base/src/export_helper/pair_to_tuple_conv.hh b/modules/base/src/export_helper/pair_to_tuple_conv.hh index 90eccdb49c49c16629b69b822b9ec1cac0d0cbbb..e187b0a92e5854541b94c717f917269ee2e36c09 100644 --- a/modules/base/src/export_helper/pair_to_tuple_conv.hh +++ b/modules/base/src/export_helper/pair_to_tuple_conv.hh @@ -34,4 +34,5 @@ struct PairToTupleConverter { return boost::python::incref(t.ptr()); } }; -} \ No newline at end of file +} + diff --git a/modules/base/src/message.cc b/modules/base/src/message.cc index eff6b1c68374bb95caa6418f2c8d378cfd668a3f..6fc3e6e31dce299cf20b937a8b02cf19f1031c9d 100644 --- a/modules/base/src/message.cc +++ b/modules/base/src/message.cc @@ -40,4 +40,5 @@ const char* Error::what() const throw() return mesg_.c_str(); } -} \ No newline at end of file +} + diff --git a/modules/base/src/platform.cc b/modules/base/src/platform.cc index 492a6a4a5810acf8b6bd8a8034ca142b08f82d86..52e75870f0caf9da34d3980983c0a83253557e86 100644 --- a/modules/base/src/platform.cc +++ b/modules/base/src/platform.cc @@ -16,7 +16,7 @@ // 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/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <ost/platform.hh> using boost::filesystem::path; namespace ost { diff --git a/modules/base/src/stdint.h b/modules/base/src/stdint.h index 59d067302fcfe1f5ec82cd7534f89c18167dd895..666e23080351623987e4993a085372cab10d9d06 100644 --- a/modules/base/src/stdint.h +++ b/modules/base/src/stdint.h @@ -245,3 +245,4 @@ typedef uint64_t uintmax_t; #endif // _MSC_STDINT_H_ ] + diff --git a/modules/base/src/stdint.hh b/modules/base/src/stdint.hh index be11eb9e18b3e3d4d6ba796d8c38c8de223cd4b9..282a564d9c618918f46a2b8d93f63c8bf5d8299e 100644 --- a/modules/base/src/stdint.hh +++ b/modules/base/src/stdint.hh @@ -2,4 +2,5 @@ #include <ost/stdint_msc.hh> #else #include <stdint.h> -#endif \ No newline at end of file +#endif + diff --git a/modules/base/src/stdint_msc.hh b/modules/base/src/stdint_msc.hh index 59d067302fcfe1f5ec82cd7534f89c18167dd895..666e23080351623987e4993a085372cab10d9d06 100644 --- a/modules/base/src/stdint_msc.hh +++ b/modules/base/src/stdint_msc.hh @@ -245,3 +245,4 @@ typedef uint64_t uintmax_t; #endif // _MSC_STDINT_H_ ] + diff --git a/modules/base/tests/test_generic_property.cc b/modules/base/tests/test_generic_property.cc index 48fa0d63addd1ff12f5e446a1f0a2e8586a7fcbd..83f4aef79ad30a04542f7f63b8442aac299189de 100644 --- a/modules/base/tests/test_generic_property.cc +++ b/modules/base/tests/test_generic_property.cc @@ -16,15 +16,17 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ -#include <ost/mol/mol.hh> #define BOOST_TEST_DYN_LINK + #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mol.hh> using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( base ) +BOOST_AUTO_TEST_SUITE( base ); BOOST_AUTO_TEST_CASE( test_generic_property ) { @@ -62,4 +64,4 @@ BOOST_AUTO_TEST_CASE( test_generic_property ) BOOST_CHECK(atomv.GetBoolProp("d")==true); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/base/tests/test_pod_vector.cc b/modules/base/tests/test_pod_vector.cc index f5dd2003f2eda686e031119204159725b2380a28..0e7225cedd522e89e527b0ea643932b80ae37beb 100644 --- a/modules/base/tests/test_pod_vector.cc +++ b/modules/base/tests/test_pod_vector.cc @@ -22,6 +22,7 @@ #include <ost/pod_vector.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; @@ -31,7 +32,7 @@ struct Payload { int x; }; -BOOST_AUTO_TEST_SUITE(base) +BOOST_AUTO_TEST_SUITE(base); BOOST_AUTO_TEST_CASE(pod_vector_trivia) { @@ -59,4 +60,4 @@ BOOST_AUTO_TEST_CASE(pod_vector_push_pop) BOOST_CHECK_EQUAL(vec.capacity(), size_t(4)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/base/tests/test_string_ref.cc b/modules/base/tests/test_string_ref.cc index 05ea7701ec963d2d89f0c6098c9272e2cd59d3f2..8d69f0ce80ff297a7dd27149fdffad9548982cbe 100644 --- a/modules/base/tests/test_string_ref.cc +++ b/modules/base/tests/test_string_ref.cc @@ -20,13 +20,15 @@ /* Author: Marco Biasini */ -#include <ost/string_ref.hh> + #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> - +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <ost/string_ref.hh> using namespace ost; -BOOST_AUTO_TEST_SUITE( base ) +BOOST_AUTO_TEST_SUITE( base ); BOOST_AUTO_TEST_CASE( test_string_ref) { @@ -135,4 +137,4 @@ BOOST_AUTO_TEST_CASE( test_string_ref) BOOST_CHECK(r3.first==false); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/base/tests/test_table.py b/modules/base/tests/test_table.py index 7b6b3be222600a86e534eb12c1b3d02cfe1da654..20d17681f258bb7092bdc9ad49d89fea11b430dd 100644 --- a/modules/base/tests/test_table.py +++ b/modules/base/tests/test_table.py @@ -6,6 +6,7 @@ Author: Tobias Schmidt import os import unittest +import glob from ost.table import * import ost @@ -41,6 +42,10 @@ except ImportError: class TestTable(unittest.TestCase): + def tearDown(self): + for filename in glob.glob('*_out.*'): + os.remove(filename) + def setUp(self): ost.PushVerbosityLevel(3) @@ -501,6 +506,35 @@ class TestTable(unittest.TestCase): 'first': ['x','foo','bar'], 'third': [3.141, 3.141, 3.141]}) + def testAddMultiRowFromDict(self): + tab = Table(['x','y','z'], 'fff') + data = {'x': [1.2, 1.5], 'z': [1.6, 2.4]} + tab.AddRow(data) + self.CompareDataFromDict(tab, {'x': [1.2, 1.5], + 'y': [None, None], + 'z': [1.6, 2.4]}) + + data = {'y': [5.1, 3.4, 1.5]} + tab.AddRow(data) + self.CompareDataFromDict(tab, {'x': [1.2, 1.5, None, None, None], + 'y': [None, None, 5.1, 3.4, 1.5], + 'z': [1.6, 2.4, None, None, None]}) + + # must raise since length of data is not the same + data = {'x': [1.2, 1.5], 'y': 1.2, 'z': [1.6, 2.4]} + self.assertRaises(ValueError, tab.AddRow, data) + + # must raise since length of data is not the same + data = {'x': [1.2, 1.5], 'y': [1.2], 'z': [1.6, 2.4]} + self.assertRaises(ValueError, tab.AddRow, data) + + # overwrite certain rows + data = {'x': [1.2, 1.9], 'z': [7.9, 3.5]} + tab.AddRow(data, overwrite='x') + self.CompareDataFromDict(tab, {'x': [1.2, 1.5, None, None, None, 1.9], + 'y': [None, None, 5.1, 3.4, 1.5, None], + 'z': [7.9, 2.4, None, None, None, 3.5]}) + def testAddRowFromDictWithOverwrite(self): ''' add rows from dictionary with overwrite (i.e. overwrite third row with additional data) @@ -720,6 +754,53 @@ class TestTable(unittest.TestCase): tab.Sort('third', '+') self.CompareDataFromDict(tab, {'first': [None,'foo','x'], 'second': [9,None,3], 'third': [3.3,2.2,None]}) + def testGuessFormat(self): + self.assertEqual(Table._GuessFormat('table_test.csv'), 'csv') + self.assertEqual(Table._GuessFormat('table_test.pickle'), 'pickle') + self.assertEqual(Table._GuessFormat('table_test.tab'), 'ost') + self.assertEqual(Table._GuessFormat('table_test.ost'), 'ost') + self.assertEqual(Table._GuessFormat('table_test.xyz'), 'ost') + + def testSaveLoadTableAutoFormat(self): + tab = self.CreateTestTable() + self.CompareDataFromDict(tab, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + + # write to disc + tab.Save("saveloadtable_filename_out.csv", format='csv') + tab.Save("saveloadtable_filename_out.tab", format='ost') + tab.Save("saveloadtable_filename_out.pickle", format='pickle') + + # read from disc: csv + in_stream_csv = open("saveloadtable_filename_out.csv", 'r') + tab_loaded_stream_csv = Table.Load(in_stream_csv) + in_stream_csv.close() + tab_loaded_fname_csv = Table.Load('saveloadtable_filename_out.csv') + + # check content: csv + self.CompareDataFromDict(tab_loaded_stream_csv, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + self.CompareDataFromDict(tab_loaded_fname_csv, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + + # read from disc: pickle + in_stream_pickle = open("saveloadtable_filename_out.pickle", 'rb') + tab_loaded_stream_pickle = Table.Load(in_stream_pickle) + in_stream_pickle.close() + tab_loaded_fname_pickle = Table.Load('saveloadtable_filename_out.pickle') + + # check content: pickle + self.CompareDataFromDict(tab_loaded_stream_pickle, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + self.CompareDataFromDict(tab_loaded_fname_pickle, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + + # read from disc: ost + in_stream_ost = open("saveloadtable_filename_out.tab", 'rb') + tab_loaded_stream_ost = Table.Load(in_stream_ost) + in_stream_ost.close() + tab_loaded_fname_ost = Table.Load('saveloadtable_filename_out.tab') + + # check content: ost + self.CompareDataFromDict(tab_loaded_stream_ost, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + self.CompareDataFromDict(tab_loaded_fname_ost, {'first': ['x','foo',None], 'second': [3,None,9], 'third': [None,2.2,3.3]}) + + def testLoadTableOSTUnknownType(self): self.assertRaises(ValueError, Table.Load, os.path.join('testfiles','ost-table-unknown-type.tab')) @@ -1048,6 +1129,14 @@ class TestTable(unittest.TestCase): score_dir='+', class_col='rmsd', class_cutoff=2.0, class_dir='y') + def testPlot(self): + if not HAS_MPL or not HAS_NUMPY: + return + tab = self.CreateTestTable() + self.assertRaises(ValueError, tab.Plot, 'second', x_range=1) + self.assertRaises(ValueError, tab.Plot, x='second', y='third', y_range=[1,2,3]) + self.assertRaises(ValueError, tab.Plot, x='second', y='third', z_range='st') + def testPlotEnrichment(self): if not HAS_MPL or not HAS_PIL: return @@ -1147,6 +1236,8 @@ class TestTable(unittest.TestCase): self.assertEquals(auc, None) def testCalcROCFromFile(self): + if not HAS_NUMPY: + return tab = Table.Load(os.path.join('testfiles','roc_table.dat')) auc = tab.ComputeROCAUC(score_col='prediction', class_col='reference', class_cutoff=0.4) self.assertEquals(auc, 1.0) @@ -1195,6 +1286,8 @@ class TestTable(unittest.TestCase): self.assertAlmostEquals(mcc, 0.882089673321) def testTableAsNumpyMatrix(self): + if not HAS_NUMPY: + return ''' checks numpy matrix diff --git a/modules/base/tests/tests.cc b/modules/base/tests/tests.cc index 2d38b16a54f1835134efdc927bf1c59b30a106b6..9d9646b9f8ead978584f0a48da4af3c58a671fad 100644 --- a/modules/base/tests/tests.cc +++ b/modules/base/tests/tests.cc @@ -18,5 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_base +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/bindings/pymod/clustalw.py b/modules/bindings/pymod/clustalw.py index 0204cd8ccc9a51962ccbef257676341c43b4cd7c..084fe8d3337acd235fcd6fe9453ac56af63292aa 100644 --- a/modules/bindings/pymod/clustalw.py +++ b/modules/bindings/pymod/clustalw.py @@ -44,6 +44,30 @@ def ClustalW(seq1, seq2=None, clustalw=None, keep_files=False, nopgap=False, :type clustalw_option_string: :class:`str` :param keep_files: do not delete temporary files :type keep_files: :class:`bool` + + Note: ClustalW will convert lowercase to uppercase, and change all '.' to '-'. + OST will convert and '?' to 'X' before aligning sequences with Clustalw. + + ClustalW will accept only IUB/IUPAC amino acid and nucleic acid codes: + + ======= ======================= ======= ============================ + Residue Name Residue Name + ======= ======================= ======= ============================ + A alanine P proline + B aspartate or asparagine Q glutamine + C cystine R arginine + D aspartate S serine + E glutamate T threonine + F phenylalanine U selenocysteine + G glycine V valine + H histidine W tryptophan + I isoleucine Y tyrosine + K lysine Z glutamate or glutamine + L leucine X any + M methionine \* translation stop + N asparagine \- gap of indeterminate length + ======= ======================= ======= ============================ + ''' clustalw_path=settings.Locate(('clustalw', 'clustalw2'), explicit_file_name=clustalw) @@ -67,6 +91,16 @@ def ClustalW(seq1, seq2=None, clustalw=None, keep_files=False, nopgap=False, else: LogError("WARNING: Specify either two SequenceHandles or one SequenceList") return + + new_list = seq.CreateSequenceList() + for s in seq_list: + ss = s.Copy() + for i,c in enumerate(ss): + if c=='?': + ss[i]='X' + new_list.AddSequence(ss) + + seq_list = new_list temp_dir=utils.TempDirWithFiles((seq_list,)) out=os.path.join(temp_dir.dirname, 'out.fasta') diff --git a/modules/bindings/src/CMakeLists.txt b/modules/bindings/src/CMakeLists.txt index 3c178c5f3b7d0158a90e8e1f14d1b21242ec18e4..7dd88cfe58b24ccc734a14eb65b022c3ad718b60 100644 --- a/modules/bindings/src/CMakeLists.txt +++ b/modules/bindings/src/CMakeLists.txt @@ -1,5 +1,5 @@ if (COMPILE_TMTOOLS) enable_language(Fortran) - executable(NAME tmalign SOURCES tmalign.f NO_RPATH) - executable(NAME tmscore SOURCES tmscore.f NO_RPATH) + executable(NAME tmalign SOURCES tmalign.f) + executable(NAME tmscore SOURCES tmscore.f) endif() \ No newline at end of file diff --git a/modules/conop/doc/aminoacid.rst b/modules/conop/doc/aminoacid.rst index 2dd39c057b33a3ea04c83c82052e9e552b99eab2..9751631723150af30d849154f03f253ee4ba2c26 100644 --- a/modules/conop/doc/aminoacid.rst +++ b/modules/conop/doc/aminoacid.rst @@ -67,4 +67,62 @@ Converter functions .. method:: Empty() Whether the set is empty, i.e. doesn't contain any amino acids. - + + +Mapping functions +-------------------------------------------------------------------------------- + +The following functions help to convert one residue into another by reusing as +much as possible from the present atoms. They are mainly meant to map from +standard amino acid to other standard amino acids or from modified amino acids +to standard amino acids. + +.. function:: CopyResidue(src_res, dst_res, editor) + + Copies the atoms of ``src_res`` to ``dst_res`` using the residue names + as guide to decide which of the atoms should be copied. If ``src_res`` and + ``dst_res`` have the same name, or ``src_res`` is a modified version of + ``dst_res`` (i.e. have the same single letter code), CopyConserved will be + called, otherwise CopyNonConserved will be called. + + :param src_res: The source residue + :type src_res: :class:`~mol.ResidueHandle` + :param dst_res: The destination residue + :type dst_res: :class:`~mol.ResidueHandle` + + :returns: true if the residue could be copied, false if not. + +.. function:: CopyConserved(src_res, dst_res, editor) + + Copies the atoms of ``src_res`` to ``dst_res`` assuming that the parent + amino acid of ``src_res`` (or ``src_res`` itself) are identical to ``dst_res``. + + If ``src_res`` and ``dst_res`` are identical, all heavy atoms are copied + to ``dst_res``. If ``src_res`` is a modified version of ``dst_res`` and the + modification is a pure addition (e.g. the phosphate group of phosphoserine), + the modification is stripped off and all other heavy atoms are copied to + ``dst_res``. If the modification is not a pure addition, only the backbone + heavy atoms are copied to ``dst_res``. + + Additionally, the selenium atom of ``MSE`` is converted to sulphur. + + :param src_res: The source residue + :type src_res: :class:`~mol.ResidueHandle` + :param dst_res: The destination residue + :type dst_res: :class:`~mol.ResidueHandle` + + :returns: a tuple of bools stating whether the residue could be copied and + whether the Cbeta atom was inserted into the ``dst_res``. + +.. function:: CopyNonConserved(src_res, dst_res, editor) + + Copies the heavy backbone atoms and Cbeta (except for ``GLY``) of ``src_res`` + to ``dst_res``. + + :param src_res: The source residue + :type src_res: :class:`~mol.ResidueHandle` + :param dst_res: The destination residue + :type dst_res: :class:`~mol.ResidueHandle` + + :returns: a tuple of bools stating whether the residue could be copied and + whether the Cbeta atom was inserted into the ``dst_res``. diff --git a/modules/conop/doc/connectivity.rst b/modules/conop/doc/connectivity.rst index 9b56d65662df21b3350d7ce7cdb080bb984263a8..98270b1aff31b7fa6d0f15f526e4dde56e8ef735 100644 --- a/modules/conop/doc/connectivity.rst +++ b/modules/conop/doc/connectivity.rst @@ -258,3 +258,15 @@ The RuleBasedBuilder class :rtype: list of :class:`~ost.mol.AtomHandle` instances +Changing the default builder +--------------------------------------------------------------------------------- + +The default builder can be specified with :func:`SetDefaultBuilder`. Before being +able to set a builder, it needs to be registered with :func:`RegisterBuilder`. +By default, there is always a builder called "HEURISTIC" registered. If, for some +reason your are currently using the :class:`RuleBasedBuilder` and you would like +to switch to that builder, call + +.. code-block:: python + + conop.SetDefaultBuilder("HEURISTIC") diff --git a/modules/conop/pymod/__init__.py b/modules/conop/pymod/__init__.py index a534ea808bf883c616c7eb7165af5b71155fdc5b..a24f5d2ec21b9333c7548cce372739a3c1753e6d 100644 --- a/modules/conop/pymod/__init__.py +++ b/modules/conop/pymod/__init__.py @@ -64,7 +64,12 @@ def RegisterBuilder(builder, name): def SetDefaultBuilder(builder_name): ''' - Set the builder with the given name as the default. + Set the builder with the given name as the default. You will have to register + a builder with :func:`RegisterBuilder` before you will be able to set it as + the default. + + :raises: :exc:`RuntimeError` when trying to set a builder as the default that + has not been registered yet. ''' conop_inst=Conopology.Instance() conop_inst.SetDefaultBuilder(builder_name) diff --git a/modules/conop/src/compound.cc b/modules/conop/src/compound.cc index 4e4500969e004b25be00fcdb667549a0f7b5ea3b..dc6ff57c85239de34ab48c18025a9c2215a21670 100644 --- a/modules/conop/src/compound.cc +++ b/modules/conop/src/compound.cc @@ -23,11 +23,18 @@ namespace ost { namespace conop { int Compound::GetAtomSpecIndex(const String& name) const { AtomSpecList::const_iterator i=atom_specs_.begin(); + // BZDNG-261: first search all primary atom names before falling back to + // alternative names. There are some files where alternative atom names are + // used as primary names for other atoms for (; i!=atom_specs_.end(); ++i) { - if ((*i).name==name || (*i).alt_name==name) + if ((*i).name==name) + return std::distance(atom_specs_.begin(), i); + } + for (; i!=atom_specs_.end(); ++i) { + if ((*i).alt_name==name) return std::distance(atom_specs_.begin(), i); } - return -1; + return -1; } String Date::ToString() const { diff --git a/modules/conop/src/conop.cc b/modules/conop/src/conop.cc index 138d62c7c988e11c6393cca79d6b222fd9c9c239..f72956f1a2f732a5734ddd1a8d20bec46e5cc91f 100644 --- a/modules/conop/src/conop.cc +++ b/modules/conop/src/conop.cc @@ -161,7 +161,8 @@ void Conopology::SetDefaultBuilder(const String& default_name) { if (builder) builder_map_["DEFAULT"]=builder; else - assert(0 && "what is this?"); + throw std::runtime_error("trying to set unknown builder '"+ + default_name+"' as the default"); } BuilderP Conopology::GetBuilder(const String& name) diff --git a/modules/conop/src/nonstandard.cc b/modules/conop/src/nonstandard.cc index 5effd8d9014ca886d63bb50f5457cc487fa782f0..b8f09f283e7676be010b2a1b0720b60001536354 100644 --- a/modules/conop/src/nonstandard.cc +++ b/modules/conop/src/nonstandard.cc @@ -35,50 +35,6 @@ using namespace ost::conop; namespace ost { namespace conop { -namespace { - -bool CheckBackboneAtoms(ResidueHandle res) -{ - String atom_names[]={"N", "CA", "C", "O"}; - std::vector<String> missing; - for (int i =0; i<4; ++i) { - if (!res.FindAtom(atom_names[i])) { - missing.push_back(atom_names[i]); - } - } - if (!missing.empty()) { - std::stringstream ss; - ss << "residue " << res.GetQualifiedName() << " is missing atoms "; - for (std::vector<String>::const_iterator - i=missing.begin(), e=missing.end(); i!=e; ++i) { - if (i!=missing.begin()) { - ss << ", "; - } - ss << *i; - } - LOG_WARNING(ss.str()); - return false; - } - return true; -} - -bool CheckCalphaAtom(ResidueHandle res) -{ - String atom_names[]={"N", "CA", "C", "O"}; - std::vector<String> missing; - for (int i =0; i<4; ++i) { - if (!res.FindAtom(atom_names[i])) { - missing.push_back(atom_names[i]); - } - } - if (!res.FindAtom("CA")) { - LOG_WARNING("residue " << res.GetQualifiedName() << " is missing CA atom"); - return false; - } - return true; -} - -} bool CopyResidue(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi) { diff --git a/modules/conop/src/nonstandard.hh b/modules/conop/src/nonstandard.hh index f8ad1cfa33d07b8d4c51db0b9019de340a882163..50a214715b518e6f5c2893e8fbf9c968b5296b37 100644 --- a/modules/conop/src/nonstandard.hh +++ b/modules/conop/src/nonstandard.hh @@ -37,8 +37,8 @@ namespace ost { namespace conop { bool DLLEXPORT_OST_CONOP CopyResidue(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi); /// \brief copies all atom of src_res to dst_res /// \param has_cbeta will be set to true if the src_res has a cbeta and the @@ -46,9 +46,9 @@ bool DLLEXPORT_OST_CONOP CopyResidue(ost::mol::ResidueHandle src_res, bool DLLEXPORT_OST_CONOP CopyIdentical(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi, - bool& has_cbeta); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi, + bool& has_cbeta); /// \brief copies atoms of src_res to dst_res /// @@ -60,9 +60,9 @@ bool DLLEXPORT_OST_CONOP CopyIdentical(ost::mol::ResidueHandle src_res, bool DLLEXPORT_OST_CONOP CopyConserved(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi, - bool& has_cbeta); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi, + bool& has_cbeta); /// \brief construct dst_res in case src_res and dst_res are not conserved. /// @@ -71,24 +71,24 @@ bool DLLEXPORT_OST_CONOP CopyConserved(ost::mol::ResidueHandle src_res, bool DLLEXPORT_OST_CONOP CopyNonConserved(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi, - bool& has_cbeta); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi, + bool& has_cbeta); /// \brief construct dst_res from src_res when src_res is an MSE bool DLLEXPORT_OST_CONOP CopyMSE(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi, - bool& has_cbeta); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi, + bool& has_cbeta); /// \brief construct a dst_res with only atoms matching the standard aminoacid /// from src_res when src_res is an is modified bool DLLEXPORT_OST_CONOP CopyModified(ost::mol::ResidueHandle src_res, - ost::mol::ResidueHandle dst_res, - ost::mol::XCSEditor& edi, - bool& has_cbeta); + ost::mol::ResidueHandle dst_res, + ost::mol::XCSEditor& edi, + bool& has_cbeta); diff --git a/modules/conop/src/rule_based_builder.cc b/modules/conop/src/rule_based_builder.cc index 33d33c667faebb47593eebe53f28285c448b1956..529fbcbc65f29be69c4b6391b346e45d9f382e3a 100644 --- a/modules/conop/src/rule_based_builder.cc +++ b/modules/conop/src/rule_based_builder.cc @@ -238,18 +238,20 @@ void RuleBasedBuilder::ConnectAtomsOfResidue(mol::ResidueHandle rh) mol::AtomHandle a1=this->LocateAtom(atoms, bond.atom_one); mol::AtomHandle a2=this->LocateAtom(atoms, bond.atom_two); if (a1.IsValid() && a2.IsValid()) { - if (this->GetBondFeasibilityCheck()==false) { - if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || a2.GetElement()=="D")) { + if (this->GetBondFeasibilityCheck()==false) { + if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || + a2.GetElement()=="D")) { continue; } e.Connect(a1, a2, bond.order); - } else { - if (IsBondFeasible(a1, a2)) { - if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || a2.GetElement()=="D")) { + } else { + if (IsBondFeasible(a1, a2)) { + if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || + a2.GetElement()=="D")) { continue; - } + } e.Connect(a1, a2, bond.order); - } + } } } } diff --git a/modules/conop/tests/test_builder.cc b/modules/conop/tests/test_builder.cc index b557b76f30fb44e72131650960d8314bcb7d6519..0d5d6537145ea27dc63cbe2960afe7f9e6b293a2 100644 --- a/modules/conop/tests/test_builder.cc +++ b/modules/conop/tests/test_builder.cc @@ -21,6 +21,7 @@ #include <ost/conop/heuristic_builder.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> // using boost::unit_test_framework::test_suite; @@ -28,7 +29,7 @@ using namespace ost; using namespace ost::conop; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( conop ) +BOOST_AUTO_TEST_SUITE( conop ); BOOST_AUTO_TEST_CASE(test_guess_chem_class) { @@ -72,4 +73,4 @@ BOOST_AUTO_TEST_CASE( test_builder ) BOOST_CHECK_EQUAL(Builder::GuessAtomElement("11", false), ""); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/conop/tests/test_heuristic_builder.cc b/modules/conop/tests/test_heuristic_builder.cc index 0e3a811ae922d0d8375fe98ab96163765f5766f4..bca1b67ee9e4e5ed9b9a9784031ba6fd57918370 100644 --- a/modules/conop/tests/test_heuristic_builder.cc +++ b/modules/conop/tests/test_heuristic_builder.cc @@ -22,6 +22,7 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/log.hh> using boost::unit_test_framework::test_suite; @@ -155,7 +156,7 @@ void verify_connectivity(const ResidueHandle& res) } } -BOOST_AUTO_TEST_SUITE( conop ) +BOOST_AUTO_TEST_SUITE( conop ); BOOST_AUTO_TEST_CASE(name_based_connect) @@ -218,4 +219,4 @@ BOOST_AUTO_TEST_CASE(test_assign_torsions){ BOOST_CHECK(a2.GetPsiTorsion().IsValid()); } -BOOST_AUTO_TEST_SUITE_END( ) \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END( ); diff --git a/modules/conop/tests/test_rule_based_builder.cc b/modules/conop/tests/test_rule_based_builder.cc index 50e34860a606912aa978fc3429dc1b1f87c2656a..bc89d94a5a297f1e3c690d8ddcc05a0a643e5dda 100644 --- a/modules/conop/tests/test_rule_based_builder.cc +++ b/modules/conop/tests/test_rule_based_builder.cc @@ -20,9 +20,10 @@ #include <ost/mol/mol.hh> #include <ost/platform.hh> #include <ost/conop/rule_based_builder.hh> - +#include <ost/conop/conop.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/log.hh> using boost::unit_test_framework::test_suite; @@ -148,6 +149,139 @@ ResidueHandle make_defective_uracil2(ChainHandle chain) return res; } +ResidueHandle make_1zk(ChainHandle chain) +{ + XCSEditor edi=chain.GetEntity().EditXCS(); + ResidueHandle r=edi.AppendResidue(chain, "1ZK"); + edi.InsertAtom(r, "C", geom::Vec3(3.946, 3.520, 10.861),"C"); + edi.InsertAtom(r, "C1", geom::Vec3(6.308, 3.824, 8.036),"C"); + edi.InsertAtom(r, "CA", geom::Vec3(4.856, 4.282, 9.931),"C"); + edi.InsertAtom(r, "C2", geom::Vec3(6.770, 5.099, 8.019),"C"); + edi.InsertAtom(r, "C3", geom::Vec3(7.805, 5.484, 7.142),"C"); + edi.InsertAtom(r, "C4", geom::Vec3(8.363, 4.590, 6.284),"C"); + edi.InsertAtom(r, "C5", geom::Vec3(8.469, 2.345, 5.318),"C"); + edi.InsertAtom(r, "C6", geom::Vec3(7.986, 1.072, 5.322),"C"); + edi.InsertAtom(r, "C4A", geom::Vec3(7.885, 3.277, 6.208),"C"); + edi.InsertAtom(r, "C7", geom::Vec3(6.949, 0.682, 6.190),"C"); + edi.InsertAtom(r, "C8", geom::Vec3(6.398, 1.548, 7.074),"C"); + edi.InsertAtom(r, "C9", geom::Vec3(4.018, 0.269, 12.183),"C"); + edi.InsertAtom(r, "C1A", geom::Vec3(6.824, 2.882, 7.117),"C"); + edi.InsertAtom(r, "O", geom::Vec3(3.224, 4.213, 11.565),"O"); + edi.InsertAtom(r, "O1", geom::Vec3(5.331, 3.476, 8.904),"O"); + edi.InsertAtom(r, "O3", geom::Vec3(5.748, -4.044, 14.612),"O"); + edi.InsertAtom(r, "N", geom::Vec3(3.855, 2.201, 10.790),"N"); + edi.InsertAtom(r, "N1", geom::Vec3(4.814, 0.719, 13.173),"N"); + edi.InsertAtom(r, "CA1", geom::Vec3(3.077, 1.346, 11.644),"C"); + edi.InsertAtom(r, "O2", geom::Vec3(4.203, -0.810, 11.651),"O"); + edi.InsertAtom(r, "O4", geom::Vec3(7.311, -5.667, 18.880),"O"); + edi.InsertAtom(r, "CB", geom::Vec3(1.856, 0.712, 11.049),"C"); + edi.InsertAtom(r, "CG", geom::Vec3(1.015, 1.845, 10.511),"C"); + edi.InsertAtom(r, "ND1", geom::Vec3(1.467, 2.439, 9.321),"N"); + edi.InsertAtom(r, "N2", geom::Vec3(6.478, -3.958, 16.751),"N"); + edi.InsertAtom(r, "CD2", geom::Vec3(-0.105, 2.479, 10.887),"C"); + edi.InsertAtom(r, "CE1", geom::Vec3(0.638, 3.428, 9.002),"C"); + edi.InsertAtom(r, "NE2", geom::Vec3(-0.372, 3.461, 9.881),"N"); + edi.InsertAtom(r, "N3", geom::Vec3(6.871, -7.136, 17.332),"N"); + edi.InsertAtom(r, "CA2", geom::Vec3(5.881, -0.001, 13.808),"C"); + edi.InsertAtom(r, "CB1", geom::Vec3(7.140, 0.860, 13.743),"C"); + edi.InsertAtom(r, "CG1", geom::Vec3(7.503, 1.324, 12.299),"C"); + edi.InsertAtom(r, "C21", geom::Vec3(5.126, -8.557, 18.179),"C"); + edi.InsertAtom(r, "CD1", geom::Vec3(8.185, 0.142, 11.507),"C"); + edi.InsertAtom(r, "CD21", geom::Vec3(8.420, 2.537, 12.325),"C"); + edi.InsertAtom(r, "CE11", geom::Vec3(8.381, 0.689, 10.066),"C"); + edi.InsertAtom(r, "CE2", geom::Vec3(8.907, 2.979, 10.922),"C"); + edi.InsertAtom(r, "CZ", geom::Vec3(9.409, 1.807, 10.075),"C"); + edi.InsertAtom(r, "CH", geom::Vec3(5.592, -0.511, 15.204),"C"); + edi.InsertAtom(r, "OH", geom::Vec3(5.225, 0.377, 16.238),"O"); + edi.InsertAtom(r, "CB11", geom::Vec3(4.426, -1.543, 15.170),"C"); + edi.InsertAtom(r, "CA'", geom::Vec3(4.451, -2.730, 16.152),"C"); + edi.InsertAtom(r, "CB'", geom::Vec3(3.124, -3.441, 16.281),"C"); + edi.InsertAtom(r, "CG11", geom::Vec3(2.553, -3.986, 14.933),"C"); + edi.InsertAtom(r, "C31", geom::Vec3(4.413, -7.811, 19.117),"C"); + edi.InsertAtom(r, "CG2", geom::Vec3(3.204, -4.586, 17.345),"C"); + edi.InsertAtom(r, "OB1", geom::Vec3(3.249, -0.875, 15.134),"O"); + edi.InsertAtom(r, "CC", geom::Vec3(5.603, -3.655, 15.782),"C"); + edi.InsertAtom(r, "CA3", geom::Vec3(7.592, -4.867, 16.603),"C"); + edi.InsertAtom(r, "CD", geom::Vec3(7.274, -5.947, 17.691),"C"); + edi.InsertAtom(r, "CB2", geom::Vec3(8.986, -4.351, 16.803),"C"); + edi.InsertAtom(r, "CG12", geom::Vec3(9.488, -3.108, 16.016),"C"); + edi.InsertAtom(r, "CG21", geom::Vec3(10.000, -5.461, 16.472),"C"); + edi.InsertAtom(r, "CD11", geom::Vec3(9.099, -3.257, 14.571),"C"); + edi.InsertAtom(r, "CM", geom::Vec3(6.587, -8.286, 18.106),"C"); + edi.InsertAtom(r, "C41", geom::Vec3(3.045, -7.980, 19.287),"C"); + edi.InsertAtom(r, "C51", geom::Vec3(2.423, -8.911, 18.456),"C"); + edi.InsertAtom(r, "C61", geom::Vec3(3.164, -9.631, 17.518),"C"); + edi.InsertAtom(r, "N11", geom::Vec3(4.497, -9.459, 17.386),"N"); + return r; +} + +void verify_1zk_connectivity(const ResidueHandle& r1) +{ + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("CA"))); + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("O"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA"), r1.FindAtom("O1"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C2"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("O1"))); + BOOST_CHECK(BondExists(r1.FindAtom("C2"), r1.FindAtom("C3"))); + BOOST_CHECK(BondExists(r1.FindAtom("C3"), r1.FindAtom("C4"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4"), r1.FindAtom("C4A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C5"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C5"), r1.FindAtom("C6"))); + BOOST_CHECK(BondExists(r1.FindAtom("C6"), r1.FindAtom("C7"))); + BOOST_CHECK(BondExists(r1.FindAtom("C7"), r1.FindAtom("C8"))); + BOOST_CHECK(BondExists(r1.FindAtom("C8"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("N"), r1.FindAtom("CA1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("C9"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("CB"))); + BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("O2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB"), r1.FindAtom("CG"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("ND1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("CD2"))); + BOOST_CHECK(BondExists(r1.FindAtom("ND1"), r1.FindAtom("CE1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD2"), r1.FindAtom("NE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE1"), r1.FindAtom("NE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("N1"), r1.FindAtom("CA2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CB1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CH"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB1"), r1.FindAtom("CG1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD21"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD1"), r1.FindAtom("CE11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD21"), r1.FindAtom("CE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE11"), r1.FindAtom("CZ"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE2"), r1.FindAtom("CZ"))); + BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("OH"))); + BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("CB11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("CA'"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("OB1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CB'"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CC"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("O3"))); + BOOST_CHECK(BondExists(r1.FindAtom("N2"), r1.FindAtom("CA3"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CD"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CB2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("O4"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG12"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG21"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG12"), r1.FindAtom("CD11"))); + BOOST_CHECK(BondExists(r1.FindAtom("N3"), r1.FindAtom("CM"))); + BOOST_CHECK(BondExists(r1.FindAtom("CM"), r1.FindAtom("C21"))); + BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("C31"))); + BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("N11"))); + BOOST_CHECK(BondExists(r1.FindAtom("C31"), r1.FindAtom("C41"))); + BOOST_CHECK(BondExists(r1.FindAtom("C41"), r1.FindAtom("C51"))); + BOOST_CHECK(BondExists(r1.FindAtom("C51"), r1.FindAtom("C61"))); + BOOST_CHECK(BondExists(r1.FindAtom("C61"), r1.FindAtom("N11"))); + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("N"))); + BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("N1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("N2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("N3"))); +} + void verify_nucleotide_connectivity(const ResidueHandle& res) { BOOST_CHECK(BondExists(res.FindAtom("P"), @@ -231,7 +365,7 @@ void verify_nucleotide_nolink(const ResidueHandle& p3, const ResidueHandle& p5) p5.FindAtom("P"))); } -BOOST_AUTO_TEST_SUITE( conop ) +BOOST_AUTO_TEST_SUITE( conop ); BOOST_AUTO_TEST_CASE(nucleotide_based_connect) @@ -296,4 +430,27 @@ BOOST_AUTO_TEST_CASE(nucleotide_based_connect) } -BOOST_AUTO_TEST_SUITE_END( ) +BOOST_AUTO_TEST_CASE(rule_based_connect_1zk) +{ + SetPrefixPath(getenv("OST_ROOT")); + String lib_path=GetSharedDataPath()+"/compounds.chemlib"; + CompoundLibPtr compound_lib=CompoundLib::Load(lib_path); + if (!compound_lib) { + std::cout << "WARNING: skipping NUCLEOTIDE_BASED connect unit test. " + << "Rule-based builder is required" << std::endl; + return; + } + + boost::shared_ptr<RuleBasedBuilder> drb_builder(new RuleBasedBuilder(compound_lib)); + Conopology::Instance().RegisterBuilder(drb_builder, "RBB"); + Conopology::Instance().SetDefaultBuilder("RBB"); + drb_builder->SetBondFeasibilityCheck(false); + EntityHandle e=CreateEntity(); + ChainHandle c=e.EditXCS().InsertChain("A"); + ResidueHandle r1=make_1zk(c); + Conopology::Instance().ConnectAll(drb_builder, e); + Conopology::Instance().SetDefaultBuilder("HEURISTIC"); + verify_1zk_connectivity(r1); +} + +BOOST_AUTO_TEST_SUITE_END( ); diff --git a/modules/conop/tests/tests.cc b/modules/conop/tests/tests.cc index aa255bcd2314b7829ade4c01c1ed0b2052da75fd..7a6d17c40b6332d2185913263122eb86e91d3df6 100644 --- a/modules/conop/tests/tests.cc +++ b/modules/conop/tests/tests.cc @@ -18,4 +18,6 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_conop -#include <boost/test/unit_test.hpp> \ No newline at end of file +#define BOOST_AUTO_TEST_MAIN +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/doc/intro-01.rst b/modules/doc/intro-01.rst index 8534e9b55889b1b555191fbb9d33c98e506382c1..f7d791d6fadcb1f12717e542bd3307230b28bc13 100644 --- a/modules/doc/intro-01.rst +++ b/modules/doc/intro-01.rst @@ -16,6 +16,15 @@ stored in a PDB file is an *entity* and we decided to follow this convention in OpenStructure. You will hear this word all the time, but you can replace the word entity with molecule (or most of the time even protein) in your head. +Loading a PDB file leaves you with an :class:`~ost.mol.EntityHandle`. This is +the central class holding together :class:`chains <ost.mol.ChainHandle>`, +:class:`residues <ost.mol.ResidueHandle>` and +:class:`atoms <ost.mol.AtomHandle>` in a straight-forward hierarchy. This +hierarchy will always be intact: there are no atoms without a residue they +belong to and no residues without chains which have to belong to an entity. +Beside the molecule itself, there are a lot of additional attributes stored in +the entity, like the +:attr:`centre of mass <ost.mol.EntityHandle.center_of_mass>`. To load a PDB file, simply type @@ -73,13 +82,6 @@ what bonds we have in there: for bond in fragment.bonds: print bond -From these short code examples we already see how the entity is structured: On -one hand we have a hierarchy of chains, residues and atoms. On the other hand, -we have bonds that form a network overlayed on the hierarchy. An important -feature of entities is that we can always assume that the hierarchy is intact. -You will never find an atom without residues, no residue can exist without a -parent chain and chains belong always to an entity. - Let There Be Shiny Graphics -------------------------------------------------------------------------------- @@ -104,24 +106,24 @@ Introduction to Views -------------------------------------------------------------------------------- Often during processing and visualisation of data, only parts of a protein -structure are of interest. This realisation has had a major impact on the design -of OpenStructure and is tied very deeply into the core of the framework. +structure are of interest. This realisation has had a major impact on the +design of OpenStructure and is tied very deeply into the core of the framework. Subparts of structure are modelled as so-called :class:`EntityViews -<ost.mol.EntityView>`. You can think of them as a selection of chains, residues, -atoms and bonds of an entity. A views has almost the same interface as the -underlying entity, making it very easy to mix entity views with handles in -Python due to the dynamic nature of the language. An algorithm that is written -for entities will almost always (with some care) also work for +<ost.mol.EntityView>`. You can think of them as a selection of chains, +residues, atoms and bonds of an entity stored in a variable. A view has almost +the same interface as the underlying entity, making it very easy to mix entity +views with handles in Python due to the dynamic nature of the language. An +algorithm that is written for entities will almost always (with some care) also +work for :class:`EntityHandles <ost.mol.EntityHandle>`. This is referred to as `duck-typing <http://en.wikipedia.org/wiki/Duck_typing>`_ (I don' t care if it -is a duck as long as it looks like a duck), a concept used all over the place in Python. - -The view consists of one chain, one residue and two atoms. Again the same rule -applies: No atom can be part of the view without it's residue. In this example, -no bonds are included, since there is at most one atom per bond in the original structure. +is a duck as long as it looks like a duck), a concept used all over the place +in Python. For views, the same rule as for +:class:`entities <ost.mol.EntityHandle>` applies: No atom can be part of the +view without it's residue... To familiarize yourself with the concept of views, we will use the fragment in -the 3D window. +the 3D window of the last example. We will use several ways to select parts of our fragment: * By using a dedicated query language @@ -223,3 +225,5 @@ select the backbone atoms and then save it: That's it for the mol module. Continue with :doc:`part two<intro-02>` of the tutorial. + +.. LocalWords: attr diff --git a/modules/doc/intro-02.rst b/modules/doc/intro-02.rst index 2d22a985ff76e1810b65d8f58cab27b902fd68ba..e4c93d62e3c8ad121c8b37beef2d8be3d04afc2f 100644 --- a/modules/doc/intro-02.rst +++ b/modules/doc/intro-02.rst @@ -11,11 +11,11 @@ OpenStructure features a :mod:`~ost.img` module that is dedicated to the manipulation of images/density maps. The images or density maps can either be one-, two- or three-dimensional. The most common formats used in X-ray and electron crystallography and atomic force microscope are supported in addition -to several general purpose image formats. See `supported file formats -<http://www.openstructure.org/docs/io/formats>`_ for details. -The :mod:`~ost.img` module was originally developed as part of the -Image Processing Library & Toolbox IPLT. More documentation and examples can -also be found on the `IPLT website <http://www.iplt.org>`_. +to several general purpose image formats. See +:doc:`supported file formats <io/formats>` for details. The :mod:`~ost.img` +module was originally developed as part of the Image Processing Library & +Toolbox IPLT. More documentation and examples can also be found on the +`IPLT website <http://www.iplt.org>`_. To load a density map, type diff --git a/modules/doc/intro.rst b/modules/doc/intro.rst index 9d2d3bacbe6bd5a081c277829e3703b0bc2f0fb0..9da3856631e82265e0dc301a0cea9eb71801d191 100644 --- a/modules/doc/intro.rst +++ b/modules/doc/intro.rst @@ -31,13 +31,13 @@ walk-through of the basic functionality you will be using in your everyday work, Getting ready to rumble -------------------------------------------------------------------------------- -The files we will be using in the tutorial are available in the examples folder -that comes with OpenStructure. Depending on your platform, the examples are -located at a different location: +The files we will be using in the tutorial are available in the examples +directory that comes with OpenStructure. Depending on your platform, the +examples are located at a different location: - * on *MacOS X* the files are located inside the application bundle. The file - browser will automatically point to the examples. - * on *Linux* and *Windows* PREFIX/share/openstructure/examples, where PREFIX is + * on *MacOS X* the files are located inside the application bundle (DNG.app). + The file browser will automatically point to the examples. + * on *Linux* PREFIX/share/openstructure/examples, where PREFIX is the path to the directory containing OpenStructure. Starting DNG @@ -47,7 +47,6 @@ The graphical user interface of OpenStructure is called DNG (Dino/DeepView Next Generation). To start it, * on *MacOS X* double click DNG.app - * on *Windows* double click dng.bat inside the PREFIX/bin directory * on *Linux* fire up a terminal change into the OpenStructure installation directory and type 'bin/dng'. If you have the binary directory in the PATH, typing dng is sufficient. diff --git a/modules/doc/table.rst b/modules/doc/table.rst index 08beaad21d3e558db80ae2e3acee0fb425587b4d..19d9c3c278a08f908fe7c8d712d4881ac4774aab 100644 --- a/modules/doc/table.rst +++ b/modules/doc/table.rst @@ -4,23 +4,98 @@ .. module:: ost.table :synopsis: Working with tabular data -This module defines the table class that provides convenient functionality to work with tabular data. It features functions to calculate statistical moments, e.g. mean, standard deviations as well as functionality to plot the data using matplotlib. +This module defines the table class that provides convenient functionality to +work with tabular data. It features functions to calculate statistical moments, +e.g. mean, standard deviations as well as functionality to plot the data using +matplotlib. Basic Usage -------------------------------------------------------------------------------- +Populate table with data: + .. code-block:: python from ost.table import * + # create table with two columns, x and y both of float type tab=Table(['x', 'y'], 'ff') for x in range(1000): tab.AddRow([x, x**2]) + # create a plot plt=tab.Plot('x', 'y') + # save resulting plot to png file plt.savefig('x-vs-y.png') +Iterating over table items: + +.. code-block:: python + + # load table from file + tab=Table.Load(...) + + # get column index for col 'foo' + idx=tab.GetColIndex('foo') + + # iterate over all rows + for row in tab.rows: + # print complete row + print row + + # print value for column 'foo' + print row[idx] + + # iterate over all rows of selected columns + for foo, bar in tab.Zip('foo','bar'): + print foo, bar + + +Functions You Might be Interested In +-------------------------------------------------------------------------------- +============================================= ============================================ +**Adding/Removing/Reordering data** +:meth:`~ost.table.Table.AddRow` add a row to the table +:meth:`~ost.table.Table.AddCol` add a column to the table +:meth:`~ost.table.Table.RemoveCol` remove a column from the table +:meth:`~ost.table.Table.Extend` append a table to the end of another table +:meth:`~ost.table.Merge` merge two tables together +:meth:`~ost.table.Table.Sort` sort table by column +:meth:`~ost.table.Table.Filter` filter table by values +:meth:`~ost.table.Table.Zip` extract multiple columns at once + +**Input/Output** +:meth:`~ost.table.Table.Save` save a table to a file +:meth:`~ost.table.Table.Load` load a table from a file +:meth:`~ost.table.Table.ToString` convert a table to a string for printing + +**Simple Math** +:meth:`~ost.table.Table.Min` compute the minimum of a column +:meth:`~ost.table.Table.Max` compute the maximum of a column +:meth:`~ost.table.Table.Sum` compute the sum of a column +:meth:`~ost.table.Table.Mean` compute the mean of a column +:meth:`~ost.table.Table.RowMean` compute the mean for each row +:meth:`~ost.table.Table.Median` compute the median of a column +:meth:`~ost.table.Table.StdDev` compute the standard deviation of a column +:meth:`~ost.table.Table.Count` compute the number of items in a column + +**More Sophisticated Math** +:meth:`~ost.table.Table.Correl` compute Pearson's correlation coefficient +:meth:`~ost.table.Table.SpearmanCorrel` compute Spearman's rank correlation coefficient +:meth:`~ost.table.Table.ComputeMCC` compute Matthew's correlation coefficient +:meth:`~ost.table.Table.ComputeROC` compute receiver operating characteristics (ROC) +:meth:`~ost.table.Table.ComputeEnrichment` compute enrichment +:meth:`~ost.table.Table.GetOptimalPrefactors` compute optimal coefficients for linear combination of columns + +**Plot** +:meth:`~ost.table.Table.Plot` Plot data in 1, 2 or 3 dimensions +:meth:`~ost.table.Table.PlotHistogram` Plot data as histogram +:meth:`~ost.table.Table.PlotROC` Plot receiver operating characteristics (ROC) +:meth:`~ost.table.Table.PlotEnrichment` Plot enrichment + + +============================================= ============================================ The Table class -------------------------------------------------------------------------------- diff --git a/modules/doc/users.rst b/modules/doc/users.rst new file mode 100644 index 0000000000000000000000000000000000000000..a24b4aad076970cf8a64abc9316f88479ce6459e --- /dev/null +++ b/modules/doc/users.rst @@ -0,0 +1,20 @@ +Reporting a Problem +============================================================================== + + +When you run into a problem in OST or have question regarding it's usage, there +are a few things you can do to make the life of people helping you easier. If +you follow these simple steps, you will make sure, people understand what you are +after and will get a response more quickly. + + * Provide a short explanation of what you tried to accomplish, the result you + were expecting and what you got instead. A good example would be: **I tried + to read the attached PDB file. The file looks clean to me, but OST fails with + the following error: "invalid coordinate on line 4."** + * If possible, attach a small script that reproduces the problem. + * Include the relevant error message in your report + * Include the version of OpenStructure you are using + * Specify your operating system + * If you compiled OpenStructure manually, also include the version for Qt, + Eigen, Python and Boost. + diff --git a/modules/geom/src/composite3.hh b/modules/geom/src/composite3.hh index ae5f56ba61771f6ff41cb9de2a9fb2b2f3106744..e780f8deb4d126042ae60e5ed41ee51d97f902d6 100644 --- a/modules/geom/src/composite3.hh +++ b/modules/geom/src/composite3.hh @@ -21,7 +21,7 @@ #include <iostream> #include <vector> -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include "vec3.hh" #include "mat3.hh" diff --git a/modules/geom/src/vec3.cc b/modules/geom/src/vec3.cc index 6e657081fb7ed1496d85514b29f390aa52d6028e..8909ce8b8648879741c01965ef13961614223e6b 100644 --- a/modules/geom/src/vec3.cc +++ b/modules/geom/src/vec3.cc @@ -28,7 +28,13 @@ namespace geom { + +#if OST_DOUBLE_PRECISION +typedef Eigen::Matrix3d EMat3; +#else typedef Eigen::Matrix3f EMat3; +#endif + Mat3 Vec3List::GetInertia() const { @@ -101,16 +107,17 @@ Line3 Vec3List::FitCylinder(const Vec3& initial_direction, const Vec3& center) c radius/=Real(n_res); res_sum=0.0; for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { - res_sum+=pow(Distance(axis,(*i))-radius,2.); + Real r=Distance(axis,(*i))-radius; + res_sum+=r*r; } unsigned long k=0; err=2.0*prec; - while (err>prec and k<n_step) { + while (err>prec && k<n_step) { res_sum_old=res_sum; axis_old=axis; radius=0.0; if (k>50) { - delta=delta_0*pow((50./k),2.0); + delta=delta_0*50.0*50.0/(k*k); } for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { radius+=Distance(axis,(*i)); @@ -127,7 +134,8 @@ Line3 Vec3List::FitCylinder(const Vec3& initial_direction, const Vec3& center) c } radius/=Real(n_res); for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { - res_sum+=pow(Distance(axis,(*i))-radius,2.); + Real r=Distance(axis,(*i))-radius; + res_sum+=r*r; } gradient[j]=(res_sum-res_sum_old)/delta; } @@ -143,7 +151,8 @@ Line3 Vec3List::FitCylinder(const Vec3& initial_direction, const Vec3& center) c radius/=Real(n_res); res_sum=0.0; for (Vec3List::const_iterator i=this->begin(),e=this->end(); i!=e; ++i) { - res_sum+=pow(Distance(axis,(*i))-radius,2.); + Real r=Distance(axis,(*i))-radius; + res_sum+=r*r; } err=fabs((res_sum-res_sum_old)/float(n_res)); k++; diff --git a/modules/geom/src/vec_mat_predicates.hh b/modules/geom/src/vec_mat_predicates.hh index 5827c60cc81b1266288794ff284fa9519cac3645..e294efdbfc23a0938d72c35e98653231e9f0a3b7 100644 --- a/modules/geom/src/vec_mat_predicates.hh +++ b/modules/geom/src/vec_mat_predicates.hh @@ -18,8 +18,9 @@ //------------------------------------------------------------------------------ #ifndef OST_GEOM_VEC_MAT_PREDICATES_HH #define OST_GEOM_VEC_MAT_PREDICATES_HH - +#include <boost/version.hpp> #include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> #include <ost/geom/geom.hh> @@ -38,7 +39,11 @@ boost::test_tools::predicate_result vec_is_close(const V& v1, const V& v2, std::string labels[]={"x","y","z","w"}; bool flag=true; boost::test_tools::predicate_result res( false ); - boost::test_tools::close_at_tolerance<Real> close_test(::boost::test_tools::percent_tolerance(tolerance)); +#if BOOST_VERSION<103400 + boost::test_tools::close_at_tolerance<Real> close_test(tolerance); +#else + boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance)); +#endif for(unsigned int i=0;i<dim;++i){ if(v1[i]==0.0){ if(!boost::test_tools::check_is_small(v2[i],tolerance)){ @@ -92,7 +97,11 @@ boost::test_tools::predicate_result mat_is_close(const M& m1, const M& m2, { bool flag=true; boost::test_tools::predicate_result res( false ); - boost::test_tools::close_at_tolerance<Real> close_test(::boost::test_tools::percent_tolerance(tolerance)); +#if BOOST_VERSION<103400 + boost::test_tools::close_at_tolerance<Real> close_test(tolerance); +#else + boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance)); +#endif for(unsigned int i=0;i<dim;++i){ for(unsigned int j=0;j<dim;++j){ if(m1(i,j)==0.0){ diff --git a/modules/geom/tests/test_composite2.cc b/modules/geom/tests/test_composite2.cc index eccafec8a5e543f0e2c6709e25b9c9d3b06b27a6..5e437a730a79a0c9ccaa0f6066210f70c22c6d94 100644 --- a/modules/geom/tests/test_composite2.cc +++ b/modules/geom/tests/test_composite2.cc @@ -24,10 +24,11 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace geom; -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(line_init2) @@ -54,4 +55,4 @@ BOOST_AUTO_TEST_CASE(is_on_line2) BOOST_CHECK(!IsOnLine(line, geom::Vec2(3,2.1))); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_composite3.cc b/modules/geom/tests/test_composite3.cc index f5cd5cf6bfbe0f411490361103e9bf0e13b5c0b9..83cbb5d19cb3dafd2b0379fcee1cb8cdad269949 100644 --- a/modules/geom/tests/test_composite3.cc +++ b/modules/geom/tests/test_composite3.cc @@ -25,8 +25,10 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_composite3) { @@ -200,8 +202,14 @@ BOOST_AUTO_TEST_CASE(rotation3) Rotation3 r(Vec3(0,1,0), 30.0*M_PI/180.0); Vec3 vrot=r.Apply(v); BOOST_CHECK_CLOSE(Real(cos(30.0*M_PI/180.0)), Real(vrot[0]), Real(1e-5)); - BOOST_CHECK_SMALL(vrot[1],float(1e-5)); + BOOST_CHECK_SMALL(vrot[1],Real(1e-5)); BOOST_CHECK_CLOSE(Real(-sin(30.0*M_PI/180.0)), Real(vrot[2]), Real(1e-5)); + + Rotation3 r2(Vec3(0,1,0), 30.0*M_PI/180.0,Vec3(2,0,0)); + Vec3 vrot2=r2.Apply(v); + BOOST_CHECK_CLOSE(Real(2.0)-Real(cos(30.0*M_PI/180.0)), Real(vrot2[0]), Real(1e-5)); + BOOST_CHECK_SMALL(vrot2[1],Real(1e-5)); + BOOST_CHECK_CLOSE(Real(sin(30.0*M_PI/180.0)), Real(vrot2[2]), Real(1e-5)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_mat2.cc b/modules/geom/tests/test_mat2.cc index af119e96500ababed360545a73178b4c2c263bbe..c7da1125e3edef8c78e4f1304f535199be6618cd 100644 --- a/modules/geom/tests/test_mat2.cc +++ b/modules/geom/tests/test_mat2.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_mat2) @@ -61,4 +62,4 @@ BOOST_AUTO_TEST_CASE(access_mat2) BOOST_CHECK_THROW( m(2,2), std::out_of_range); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_mat3.cc b/modules/geom/tests/test_mat3.cc index 742ba05ed1b270d47bf50f12e0501fe4e5ff9b1c..8a8b40e53c7749832c8143379950a6ee66cc9670 100644 --- a/modules/geom/tests/test_mat3.cc +++ b/modules/geom/tests/test_mat3.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_mat3) { @@ -89,4 +90,4 @@ BOOST_AUTO_TEST_CASE(mult_mat3) BOOST_CHECK(Equal(m1*m5,m3*m4)); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_mat4.cc b/modules/geom/tests/test_mat4.cc index 343a68ffe6a3850b997dafc46d69839cfe6daeea..36ea668c19a2ffa7483a98bc1a2c697afc57bc8e 100644 --- a/modules/geom/tests/test_mat4.cc +++ b/modules/geom/tests/test_mat4.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_mat4) { @@ -101,4 +102,4 @@ BOOST_AUTO_TEST_CASE(access_mat4) BOOST_CHECK_THROW( m(0,4), std::out_of_range); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_op2.cc b/modules/geom/tests/test_op2.cc index 62774a650dc0067efac60c5be2869d1fb33d3f45..2815b3e65d3e99d74ea6ee780c240bd552ab1d25 100644 --- a/modules/geom/tests/test_op2.cc +++ b/modules/geom/tests/test_op2.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(vecmat_mult2) { @@ -47,4 +48,4 @@ BOOST_AUTO_TEST_CASE(vecmat_mult2) BOOST_CHECK(Equal(v3*m2,v2*m3)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_op3.cc b/modules/geom/tests/test_op3.cc index a2e30db8bd92aadeaa90818d6834ef86b45ec589..de7e74843e536b2b635d111752e1142c6cd7dcb2 100644 --- a/modules/geom/tests/test_op3.cc +++ b/modules/geom/tests/test_op3.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(vecmat_mult3) { @@ -62,4 +63,4 @@ BOOST_AUTO_TEST_CASE(vec3list_op) BOOST_CHECK(MinDistance(l1,l2)==5.0); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_op4.cc b/modules/geom/tests/test_op4.cc index 19eaaaa12ed879b8fefe7dde95df3b49ee395d49..df5995eca4b06298cd400111b6a4b46b952d9ee0 100644 --- a/modules/geom/tests/test_op4.cc +++ b/modules/geom/tests/test_op4.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(vecmat_mult4) { @@ -43,4 +44,4 @@ BOOST_AUTO_TEST_CASE(vecmat_mult4) BOOST_CHECK(match(CompDivide(v2,v1),2.0,3.0,3.0,2.0)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_quat.cc b/modules/geom/tests/test_quat.cc index ccaf9ab2dd4aa7d4730cfd511dcdd7d0ad9fe811..cfd36460be4d09487e15000f2579cfdb78ed8697 100644 --- a/modules/geom/tests/test_quat.cc +++ b/modules/geom/tests/test_quat.cc @@ -24,8 +24,10 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_quat) { @@ -49,10 +51,10 @@ BOOST_AUTO_TEST_CASE(quat_rotate) Quat q(30.0*M_PI/180.0,Vec3(0,1,0)); Vec3 vrot=q.Rotate(v); BOOST_CHECK_CLOSE(Real(cos(30.0*M_PI/180.0)), Real(vrot[0]), Real(1e-5)); - BOOST_CHECK_SMALL(vrot[1],float(1e-5)); + BOOST_CHECK_SMALL(vrot[1],Real(1e-5)); BOOST_CHECK_CLOSE(Real(-sin(30.0*M_PI/180.0)), Real(vrot[2]), Real(1e-5)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_vec2.cc b/modules/geom/tests/test_vec2.cc index 77ec6f0b57293e67ab2980bb5846969454c04a8e..87cc3aba086dbd08cd72409859175713cbf81616 100644 --- a/modules/geom/tests/test_vec2.cc +++ b/modules/geom/tests/test_vec2.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_vec2) { @@ -107,4 +108,4 @@ BOOST_AUTO_TEST_CASE(operators_vec2) BOOST_CHECK(match(v2,0.3,0.55)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_vec3.cc b/modules/geom/tests/test_vec3.cc index a02bc8c5bdc8fa585668e05d43b1996e5bf682c7..9e3e4d9485c379293b59bf454d0befce87181737 100644 --- a/modules/geom/tests/test_vec3.cc +++ b/modules/geom/tests/test_vec3.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_vec3) { @@ -124,4 +125,4 @@ BOOST_AUTO_TEST_CASE(operators_vec3) BOOST_CHECK(match(v2,0.01,-0.02,0.01)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/test_vec4.cc b/modules/geom/tests/test_vec4.cc index c0f0163d369512c10fe45ee77e6439976b0fcee7..25276e4f33e55055ce3a75383e724bbb8f4ab8ee 100644 --- a/modules/geom/tests/test_vec4.cc +++ b/modules/geom/tests/test_vec4.cc @@ -24,8 +24,9 @@ using namespace geom; #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> -BOOST_AUTO_TEST_SUITE( geom ) +BOOST_AUTO_TEST_SUITE( geom ); BOOST_AUTO_TEST_CASE(init_vec4) { @@ -109,4 +110,4 @@ BOOST_AUTO_TEST_CASE(operators_vec4) BOOST_CHECK(match(v2,-0.2,0.3,0.55,0.8)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/tests/tests.cc b/modules/geom/tests/tests.cc index fbce7b185d7ce437b2832e5468bba0226a4da83b..87ec85ccf0cf850e2307d22223343055c59eb17f 100644 --- a/modules/geom/tests/tests.cc +++ b/modules/geom/tests/tests.cc @@ -18,5 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE geom +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc index 6202bd1cc4d353d61b673c78d68b402ecbc7b137..d8ee109298405de304b4b7e178671b1f4388141f 100644 --- a/modules/gfx/pymod/export_entity.cc +++ b/modules/gfx/pymod/export_entity.cc @@ -360,6 +360,8 @@ void export_Entity() .def("IsRenderModeEnabled", &Entity::IsRenderModeEnabled) .def("SetVisible", set_vis1, (arg("view"), arg("flag")=true)) .def("SetVisible", set_vis2, (arg("sel"), arg("flag")=true)) + .def("ColorBy", color_by_10) // this line must be before color_by_01 because + // of boost python overload resolution .def("ColorBy", color_by_01) .def("ColorBy", color_by_02) .def("ColorBy", color_by_03) @@ -369,7 +371,6 @@ void export_Entity() .def("ColorBy", color_by_07) .def("ColorBy", color_by_08) .def("ColorBy", color_by_09) - .def("ColorBy", color_by_10) .def("DetailColorBy", detail_color_by_02) COLOR_BY_DEF() .def("RadiusBy", radius_by_01) diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc index 7920cd4eb8fdad036d4bed302dbbf9e845afadd0..3aec22fe5eaee632938be7b74ba4bc97342db774 100644 --- a/modules/gfx/src/entity.cc +++ b/modules/gfx/src/entity.cc @@ -940,7 +940,7 @@ void Entity::ColorBy(const String& prop, const Color& c1, const Color& c2, mol::Prop::Level level) { - std::pair<float,float> minmax = this->GetView().GetMinMax(prop); + std::pair<float,float> minmax = this->GetView().GetMinMax(prop, level); this->ColorBy(prop,c1,c2,minmax.first, minmax.second,level); } diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 5a2055b732cb953bd29030bee115bb6bbbe99335..708d8688cbf43435ed995ce0d1963c9a31d07768 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -1380,7 +1380,7 @@ void Scene::SetStereoMode(unsigned int m) if(win_ && win_->HasStereo()) { stereo_mode_=1; } else { - LOG_INFO("Scene: No visual present for quad-buffered stereo"); + LOG_WARNING("Scene: No visual present for quad-buffered stereo (run dng with --stereo)"); stereo_mode_=0; } } else if(m==2) { diff --git a/modules/gui/pymod/init_spacenav.py b/modules/gui/pymod/init_spacenav.py index df8bf383b3efa580d385196d57a6a515a38fe2a5..5346b4ca5b8d21d947aa12fa5ef9323faef80fde 100644 --- a/modules/gui/pymod/init_spacenav.py +++ b/modules/gui/pymod/init_spacenav.py @@ -11,17 +11,18 @@ class SpacenavControl(QtCore.QObject): self.trans = True self.rot = True + self.speed = 480.0 def Changed(self, tx,ty,tz,rx,ry,rz): transf = gfx.Scene().GetTransform() if(self.trans): - transf.ApplyXAxisTranslation(tx/480.0) - transf.ApplyYAxisTranslation(ty/480.0) - transf.ApplyZAxisTranslation(-tz/480.0) + transf.ApplyXAxisTranslation(tx/self.speed) + transf.ApplyYAxisTranslation(ty/self.speed) + transf.ApplyZAxisTranslation(-tz/self.speed) if(self.rot): - transf.ApplyXAxisRotation(rx/480.0) - transf.ApplyYAxisRotation(ry/480.0) - transf.ApplyZAxisRotation(rz/480.0) + transf.ApplyXAxisRotation(rx/self.speed) + transf.ApplyYAxisRotation(ry/self.speed) + transf.ApplyZAxisRotation(rz/self.speed) gfx.Scene().SetTransform(transf) gfx.Scene().RequestRedraw() @@ -32,6 +33,16 @@ class SpacenavControl(QtCore.QObject): elif button == 1: self.rot = not self.rot print "Rotation Enabled:",self.rot + elif button == 12: + if self.speed > 20: + self.speed *= 0.8 + print "Speed Increased:",self.speed + elif button == 13: + self.speed /= 0.8 + print "Speed Reduced:",self.speed + else: + print "other:",button + def _InitSpaceNav(app): try: @@ -40,4 +51,4 @@ def _InitSpaceNav(app): parent = app.gl_win.qobject SpacenavControl(spnav,parent) except AttributeError: - pass \ No newline at end of file + pass diff --git a/modules/gui/pymod/scene/color_options_widget.py b/modules/gui/pymod/scene/color_options_widget.py index 13e33f7c68c52e17e858d5e8d0aa356a8433c08c..1d8e95cf6ec5ff9402daec6b917dcc5ea2d06742 100644 --- a/modules/gui/pymod/scene/color_options_widget.py +++ b/modules/gui/pymod/scene/color_options_widget.py @@ -146,7 +146,10 @@ class ByElementWidget(QtGui.QWidget): def ChangeViewColor(self, entity, view): if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView): - beco=gfx.ByElementColorOp(mol.QueryViewWrapper(view)) + if self.parent_.GetCarbonsOnly(): + beco=gfx.ByElementColorOp(mol.QueryViewWrapper(mol.Query("ele=C"), view)) + else: + beco=gfx.ByElementColorOp(mol.QueryViewWrapper(view)) entity.Apply(beco) def GetText(self): @@ -185,7 +188,10 @@ class ByChainWidget(QtGui.QWidget): def ChangeViewColor(self, entity, view): if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView): - bco=gfx.ByChainColorOp(mol.QueryViewWrapper(view)) + if self.parent_.GetCarbonsOnly(): + bco=gfx.ByChainColorOp(mol.QueryViewWrapper(mol.Query("ele=C"),view)) + else: + bco=gfx.ByChainColorOp(mol.QueryViewWrapper(view)) entity.Apply(bco) def GetText(self): @@ -234,7 +240,10 @@ class ByEntityWidget(QtGui.QWidget): def ChangeViewColor(self, entity, view): if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView): - bco=gfx.ByChainColorOp(mol.QueryViewWrapper(view)) + if self.parent_.GetCarbonsOnly(): + bco=gfx.ByChainColorOp(mol.QueryViewWrapper(mol.Query("ele=C"),view)) + else: + bco=gfx.ByChainColorOp(mol.QueryViewWrapper(view)) entity.Apply(bco) def GetText(self): diff --git a/modules/gui/pymod/scene/gradient_editor_widget.py b/modules/gui/pymod/scene/gradient_editor_widget.py index 34c11a24ac0d70b2a2026308365ad8f351a64005..ee61e2721ab80a2f5c80692f91d8be861356fb81 100644 --- a/modules/gui/pymod/scene/gradient_editor_widget.py +++ b/modules/gui/pymod/scene/gradient_editor_widget.py @@ -90,7 +90,10 @@ class GradientEditor(QtGui.QWidget): def ChangeViewColor(self, entity, view): if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView): - glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED) + if self.parent_.GetCarbonsOnly(): + glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(mol.Query("ele=C"),view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED) + else: + glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED) entity.Apply(glco) #Gradient Preview diff --git a/modules/gui/pymod/scene/uniform_color_widget.py b/modules/gui/pymod/scene/uniform_color_widget.py index db8e5346f3276fac962da07868670c88149e2f88..66461dcff9c391e926e47d77eaa1458fb1f1ce63 100644 --- a/modules/gui/pymod/scene/uniform_color_widget.py +++ b/modules/gui/pymod/scene/uniform_color_widget.py @@ -97,7 +97,10 @@ class UniformColorWidget(QtGui.QWidget): def ChangeViewColor(self, entity, view): if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView): gfx_color = self.color_select_widget_.GetGfxColor() - ufco=gfx.UniformColorOp(mol.QueryViewWrapper(view),gfx_color) + if self.parent_.GetCarbonsOnly(): + ufco=gfx.UniformColorOp(mol.QueryViewWrapper(mol.Query("ele=C"), view),gfx_color) + else: + ufco=gfx.UniformColorOp(mol.QueryViewWrapper(view),gfx_color) entity.Apply(ufco) def resizeEvent(self, event): diff --git a/modules/gui/src/scene_menu.cc b/modules/gui/src/scene_menu.cc index 67f85b90de1ccf0b1197693c0e9fc369f3be3cbd..ef02a2aee2807a00034228fc451a2763d73bdde1 100644 --- a/modules/gui/src/scene_menu.cc +++ b/modules/gui/src/scene_menu.cc @@ -60,12 +60,12 @@ SceneMenu::SceneMenu() { void SceneMenu::SelectBackbone() { - this->Select("peptide=true and aname=CA,C,N,O"); + this->Select("peptide=true and aname=CA,C,N,O,H,HA,OXT,HXT,HA2,HA3"); } void SceneMenu::SelectSidechains() { - this->Select("peptide=true and aname!=CA,C,N,O"); + this->Select("peptide=true and aname!=CA,C,N,O,H,HA,OXT,HXT,HA2,HA3"); } void SceneMenu::SelectLigands() diff --git a/modules/gui/src/scene_win/entity_node.cc b/modules/gui/src/scene_win/entity_node.cc index 4f49dcc96e676a8df67f73179c266f2e029649bd..02dc97c54f8396bc2e986b208c727a4a52144b43 100644 --- a/modules/gui/src/scene_win/entity_node.cc +++ b/modules/gui/src/scene_win/entity_node.cc @@ -59,9 +59,9 @@ EntityNode::EntityNode(gfx::EntityP& entity, SceneNode* parent): SceneNode* quick_selection = new LabelNode("Quick Selection",this); model->AddNode(this, quick_selection); - SceneNode* node = new EntityPartNode("Backbone", entity, mol::QueryViewWrapper(mol::Query("aname=CA,C,N,O and peptide=true"),entity->GetView()), quick_selection); + SceneNode* node = new EntityPartNode("Backbone", entity, mol::QueryViewWrapper(mol::Query("aname=CA,C,N,O,H,HA,OXT,HXT,HA2,HA3 and peptide=true"),entity->GetView()), quick_selection); model->AddNode(quick_selection, node); - node = new EntityPartNode("Sidechains", entity, mol::QueryViewWrapper(mol::Query("aname!=CA,C,N,O and peptide=true"),mol::QueryFlag::EXCLUSIVE_BONDS,entity->GetView()), quick_selection); + node = new EntityPartNode("Sidechains", entity, mol::QueryViewWrapper(mol::Query("aname!=CA,C,N,O,H,HA,OXT,HXT,HA2,HA3 and peptide=true"),mol::QueryFlag::EXCLUSIVE_BONDS,entity->GetView()), quick_selection); model->AddNode(quick_selection, node); node = new EntityPartNode("Ligands", entity, mol::QueryViewWrapper(mol::Query("ishetatm=1 and rname!=HOH,WAT"),entity->GetView()), quick_selection); model->AddNode(quick_selection, node); diff --git a/modules/img/alg/tests/test_fft.cc b/modules/img/alg/tests/test_fft.cc index dd742e41ec869feadc9b8747874fef73013b28f6..3e3702690117843ed71fc633b0ddbfeb69e0d418 100644 --- a/modules/img/alg/tests/test_fft.cc +++ b/modules/img/alg/tests/test_fft.cc @@ -88,7 +88,7 @@ void Test_C2C_1D_calc(int N) Point peak(N/step,0); Complex peak_value = out_state->Value(peak); Complex calc_peak_value = Complex(sum,0.0); - std::cout << std::abs(peak_value-calc_peak_value); + //std::cout << std::abs(peak_value-calc_peak_value); BOOST_REQUIRE(std::abs(peak_value-calc_peak_value)<1e-06); } catch (alg::FFTException& e) { diff --git a/modules/index.rst b/modules/index.rst index 89bb6d3614d7c91c7fb9050a1fc9f9ab73deecc3..cb92f375dcdc0b20527f1bc26fec308465c4cc62 100644 --- a/modules/index.rst +++ b/modules/index.rst @@ -7,6 +7,7 @@ OpenStructure documentation install intro + users base/generic base/base geom/geom @@ -57,6 +58,7 @@ Density Maps and Images **Overview**: :doc:`images intro <intro-02>` | :doc:`img module <img/base/img>` | :doc:`img.alg module <img/alg/alg>` +**Input/Output**: :ref:`loading and saving density maps <img-io>` @@ -93,8 +95,9 @@ Varia **Datasets:** :doc:`tabular data <table>` -**File Formats:** :doc:`supported file formats <io/formats>` +**Supported File Formats:** :doc:`structure formats<io/structure_formats>` | :doc:`sequence formats <io/sequence_formats>` | :doc:`image formats <io/image_formats>` +**Users** :doc:`Reporting a problem <users>` Extending OpenStructure -------------------------------------------------------------------------------- @@ -102,7 +105,3 @@ Extending OpenStructure **Howto:** :doc:`write new modules <newmodule>` | :doc:`integrate third-party tools <external>` | :doc:`logging <base/logging>` | :doc:`instructions for developers <contributing>` - - - - diff --git a/modules/io/doc/formats.rst b/modules/io/doc/formats.rst deleted file mode 100644 index fc6fee4cb8e12e0b2ed01731d0a213be18270b76..0000000000000000000000000000000000000000 --- a/modules/io/doc/formats.rst +++ /dev/null @@ -1,186 +0,0 @@ -Supported File Formats -================================================================================ - -Structure File Formats --------------------------------------------------------------------------------- - -The following file formats are supported by :func:`~ost.io.LoadEntity`. - - - -CRD - CARD format file used by CHARMM -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This trajectory file format is used by the CHARMM program suite (Molecular Modelling). - -*Recognized File Extensions* - crd - -PDB - Brookhaven PDB File -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Fine grained control over PDB file import is available via the -:func:`~ost.io.LoadPDB` function. The PDB importer supports loading gzipped PDB -files, which are auto-detected by the .gz file extension. - -*Recognized File Extensions* - ent, pdb, ent.gz, pdb.gz - -*Format Name* - pdb - -PQR -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - pqr - -*Format Name* - pqr - -SDF - Structured Data File -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - sdf - -Sequence File Formats --------------------------------------------------------------------------------- - -FASTA -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - fasta, fna, fas, fa, fsa - -*Format Name* - fasta - -ClustalW -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - aln - -*Format Name* - clustal - -Promod -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - ali - -*Format Name* - promod - - -Image File Formats --------------------------------------------------------------------------------- - -DAT -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - dat, img - -*Format Name* - Simple binary format for square images - -DF3 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - df3 - -*Format Name* - PovRay Density file format - -DM3 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - dm3 - -*Format Name* - Format used by Gatan Inc.'s Digital Micrograph software - -DX -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - dx - -*Format Name* - Format used by the OpenDX software package - -IPL -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - ipl - -*Format Name* - Ditabis Micron Image Plate Scanner Format - -JPK -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - jpk - -*Format Name* - Format used by JPK Instruments AG's software (Customized Tiff format) - -MRC -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - map, ccp4, mrc - -*Format Name* - Format used by the MRC software package - -NanoScope -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - mod - -*Format Name* - Format used by software from Veeco - -PNG -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - png - -*Format Name* - Portable Network Graphic image format - -Situs -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - situs, sit - -*Format Name* - Format used by the Situs software package - -SPI -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - spi - -*Format Name* - Format used by the Spider software package - -TIFF -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -*Recognized File Extensions* - tif, tiff - -*Format Name* - Tagged Image File Format - diff --git a/modules/io/doc/image_formats.rst b/modules/io/doc/image_formats.rst new file mode 100644 index 0000000000000000000000000000000000000000..0764bb5735ae81c9c8d95a32ca499b33d8773862 --- /dev/null +++ b/modules/io/doc/image_formats.rst @@ -0,0 +1,258 @@ +Supported Image File Formats +================================================================================ + +CCP4 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by the ccp4 software package + +* Recognized file extensions: *ccp4, map* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.CCP4(normalize_on_save=false, endianess_on_save=OST_LOCAL_ENDIAN) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + :param endianess_on_save: Byte order for saving. + :type endianess_on_save: ost.io.Endianess + + +DAT +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Simple binary format for square images + +* Recognized file extensions: *dat, img* +* Recognized based on content: *no* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.DAT(normalize_on_save=false, format=OST_DEFAULT_FORMAT, signed=false, endianess=OST_LOCAL_ENDIAN) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + :param format: Data format for loading and saving. + :type format: ost.io.Format + :param signed: Determines wether data is interpreted as signed or unsigned values during loading and saving. + :type signed: bool + :param endianess: Byte order for loading and saving. + :type endianess: ost.io.Endianess + +DF3 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +PovRay Density file format + +* Recognized file extensions: *df3* +* Recognized based on content: *no* +* File import: *no* +* File export: *yes* + +.. class:: ost.io.DF3(normalize_on_save=false) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + + +DM3 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by Gatan Inc.'s Digital Micrograph software + +* Recognized file extensions: *dm3* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *no* + +.. class:: ost.io.DM3( ) + +DX +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by the OpenDX software package + +* Recognized file extensions: *dx* +* Recognized based on content: *no* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.DX(normalize_on_save=false) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + + +IPL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Ditabis Micron Image Plate Scanner Format + +* Recognized file extensions: *ipl* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.IPL(normalize_on_save=false, format=OST_DEFAULT_FORMAT) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + :param format: Data format for loading and saving. + :type format: ost.io.Format + +JPK +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by JPK Instruments AG's software (Customized Tiff format) + +* Recognized file extensions: *jpk* +* Recognized based on content: *no (jpk files without file extension are recognized as tif)* +* File import: *yes* +* File export: *yes* + + + +.. class:: ost.io.JPK(normalize_on_save=indeterminate, format=OST_DEFAULT_FORMAT, signed=false, phasecolor=false, subimage=-1) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: tribool + :param format: Data format for loading and saving. + :type format: ost.io.Format + :param signed: Determines wether data is interpreted as signed or unsigned values during loading and saving. + :type signed: bool + :param phasecolor: Determines wether the phases of complex values are encoded as color information. + :type phasecolor: bool + :param subimage: Determines which subimage is read from a multi-image jpk (-1 = default image). + :type subimage: int + +MRC +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by the MRC software package + +* Recognized file extensions: *mrc* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.MRC(normalize_on_save=false, subformat=MRC_NEW_FORMAT, endianess_on_save=OST_LOCAL_ENDIAN) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + :param subformat: Determines wether old style or new style mrc files should be saved. + :type subformat: ost.io.Subformat + :param endianess_on_save: Byte order for saving. + :type endianess_on_save: ost.io.Endianess + +.. py:class:: ost.io.Subformat + + .. py:attribute:: MRC_AUTO_FORMAT + .. py:attribute:: MRC_OLD_FORMAT + .. py:attribute:: MRC_NEW_FORMAT + +Nanoscope +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by software from Veeco + +* Recognized file extensions: *mod* +* Recognized based on content: *no* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.Nanoscope(subimage=-1) + + :param subimage: Determines which subimage is read from a multi-image nanoscope file (-1 = default image). + :type subimage: int + + +PNG +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Portable Network Graphic image format + +* Recognized file extensions: *png* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.PNG(normalize_on_save=false) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + +Situs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by the Situs software package + +* Recognized file extensions: *situs, sit* +* Recognized based on content: *no* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.Situs(normalize_on_save=false) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + +Spider +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Format used by the Spider software package + +* Recognized file extensions: *spi* +* Recognized based on content: *no* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.Spider(normalize_on_save=false, endianess_on_save=OST_LOCAL_ENDIAN) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: bool + :param endianess_on_save: Byte order for saving. + :type endianess_on_save: ost.io.Endianess + +TIF +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Tagged Image File Format + +* Recognized file extensions: *tif, tiff* +* Recognized based on content: *yes* +* File import: *yes* +* File export: *yes* + +.. class:: ost.io.TIF(normalize_on_save=indeterminate, format=OST_DEFAULT_FORMAT, signed=false, phasecolor=false, subimage=-1) + + :param normalize_on_save: Determines wether to renormalize image upon saving. + :type normalize_on_save: tribool + :param format: Data format for loading and saving. + :type format: ost.io.Format + :param signed: Determines wether data is interpreted as signed or unsigned values during loading and saving. + :type signed: bool + :param phasecolor: Determines wether the phases of complex values are encoded as color information. + :type phasecolor: bool + :param subimage: Determines which subimage is read from a multi-image tif (-1 = default image). + :type subimage: int + +Common parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: ost.io.Endianess + + .. py:attribute:: OST_BIG_ENDIAN + .. py:attribute:: OST_LITTLE_ENDIAN + .. py:attribute:: OST_VAX_DATA + .. py:attribute:: OST_LOCAL_ENDIAN + +.. py:class:: ost.io.Format + + .. py:attribute:: OST_BIT8_FORMAT + .. py:attribute:: OST_BIT16_FORMAT + .. py:attribute:: OST_BIT32_FORMAT + .. py:attribute:: OST_FLOAT_FORMAT + .. py:attribute:: OST_DOUBLE_FORMAT + .. py:attribute:: OST_DEFAULT_FORMAT + diff --git a/modules/io/doc/io.rst b/modules/io/doc/io.rst index 41759d1987ef149bd53ed942fc21814b22ba43c0..1f97001cf35f461b18527ee99c446580e0d57b20 100644 --- a/modules/io/doc/io.rst +++ b/modules/io/doc/io.rst @@ -4,7 +4,9 @@ .. toctree:: :hidden: - formats + structure_formats + sequence_formats + image_formats mmcif profile @@ -49,7 +51,7 @@ on the file extension. # SDF file explicitly ent=io.LoadEntity('file', 'sdf') - For a list of file formats supported by :func:`LoadEntity`, see :doc:`formats`. + For a list of file formats supported by :func:`LoadEntity`, see :doc:`structure_formats`. :raises: :exc:`~ost.io.IOUnknownFormatException` if the format string supplied is not recognized or the file format can not be detected based on the @@ -145,7 +147,7 @@ Loading sequence or alignment files aln=io.LoadAlignment('algnm.aln',format="clustal") For a list of file formats supported by :func:`LoadSequence` see - :doc:`formats`. + :doc:`sequence_formats`. :raises: :exc:`~ost.io.IOUnknownFormatException` if the format string supplied is not recognized or the file format can not be detected based on the @@ -158,13 +160,13 @@ Loading sequence or alignment files For a desription of how to use :func:`LoadSequenceList` please refer to :func:`LoadSequence`. For a list of file formats supported by - :func:`LoadSequenceList` see :doc:`formats`. + :func:`LoadSequenceList` see :doc:`sequence_formats`. .. function:: LoadAlignment(filename, format='auto') For a desription of how to use :func:`LoadAlignment` please refer to :func:`LoadSequence`. For a list of file formats supported by - :func:`LoadAlignment` see :doc:`formats`. + :func:`LoadAlignment` see :doc:`sequence_formats`. Saving Sequence Data ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +187,7 @@ Saving Sequence Data io.SaveAlignment(aln,'algnm.aln',format="clustal") For a list of file formats supported by :func:`SaveSequence` see - :doc:`formats`. + :doc:`sequence_formats`. :raises: :exc:`~ost.io.IOUnknownFormatException` if the format string supplied is not recognized or the file format can not be detected based on the @@ -198,7 +200,7 @@ Saving Sequence Data For a desription of how to use :func:`SaveSequenceList` please refer to :func:`SaveSequence`. For a list of file formats supported by - :func:`SaveSequenceList` see :doc:`formats`. + :func:`SaveSequenceList` see :doc:`sequence_formats`. .. function:: SaveAlignment(aln, filename, format='auto') @@ -206,7 +208,79 @@ Saving Sequence Data :func:`SaveSequence`. For a list of file formats supported by :func:`SaveAlignment` see - :doc:`formats`. + :doc:`sequence_formats`. + + +.. _img-io: + +Density Maps +-------------------------------------------------------------------------------- + +Loading Density Maps +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. function:: LoadImage(filename) +.. function:: LoadImage(filename, format) + + Load density map from disk. If no format is given, the function guesses the + filetype based on the extension of the file. If the extension is unknown or not present the + filetype will be guessed based on the content of the file if possible. + + :param filename: The filename + :type filename: string + :param format: The file format + + :raises: :exc:`~ost.io.IOUnknownFormatException` if the format supplied + is not recognized or the file format can not be detected based on the + file extension and content + + :exc:`~ost.io.IOException` if the import fails due to an erroneous or + inexistent file + + .. code-block:: python + + # recognizes mrc file by file extension + ent=io.LoadImage('file.mrc') + + # It is always possible to explicitely set the image format + # DAT file explicitly + ent=io.LoadImage('file', Dat()) + + For a list of file formats supported by :func:`LoadImage`, see :doc:`image_formats`. + + + + +Saving Density Maps +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. function:: SaveImage(image,filename) +.. function:: SaveImage(image,filename, format) + + + Save density map to disk. If no format is set, the function guesses the + filetype based on the file extension. + + :param image: The density map to be saved + :type image: :class:`~ost.img.IMageHandle` + :param filename: The filename + :type filename: string + :param format: The file format + + :raises: :exc:`~ost.io.IOUnknownFormatException` if the file format can not be detected based on the + file extension + + For a list of file formats supported by :func:`SaveImage`, see :doc:`image_formats`. + + .. code-block:: python + + # load density map + image=io.LoadImage('density_map.ccp4') + # save density map + io.SaveImage(image, 'new_map.map', CCP4()) + + + .. testsetup:: io diff --git a/modules/io/doc/profile.rst b/modules/io/doc/profile.rst index 8df9254e5aaf1ba3554b1e4fc8c9d39b442ed764..a0a43565e6631ca9c2adc28449930a9ffbe3656c 100644 --- a/modules/io/doc/profile.rst +++ b/modules/io/doc/profile.rst @@ -45,7 +45,7 @@ STRICT IOProfile(dialect='PDB', strict_hydrogens=False, quack_mode=False, fault_tolerant=False, join_spread_atom_records=False, - no_hetatms=False) + no_hetatms=False, bond_feasibility_check=True) SLOPPY: @@ -55,7 +55,7 @@ SLOPPY: IOProfile(dialect='PDB', strict_hydrogens=False, quack_mode=True, fault_tolerant=True, join_spread_atom_records=False, - no_hetatms=False) + no_hetatms=False, bond_feasibility_check=True) CHARMM: @@ -66,13 +66,13 @@ CHARMM: IOProfile(dialect='CHARMM', strict_hydrogens=False, quack_mode=True, fault_tolerant=True, join_spread_atom_records=True, - no_hetatms=False) + no_hetatms=False, bond_feasibility_check=True) The IOProfile Class -------------------------------------------------------------------------------- -.. class:: IOProfile(quack_mode=False, dialect='PDB', strict_hydrogens=False, fault_tolerant=False) +.. class:: IOProfile(dialect='PDB', strict_hydrogens=False, quack_mode=False, join_spread_atom_records=False, no_hetatms=False, calpha_only=False, fault_tolerant=False, bond_feasibility_check=True) Aggregates flags that control the import of molecular structures. @@ -123,3 +123,18 @@ The IOProfile Class If set to true, atom records belonging to the same residue are joined, even if they do not appear sequentially in the PDB file. + + .. attribute:: calpha_only + + When set to true, forces the importers to only load atoms named CA. This is + most useful in combination with protein-only PDB files to speed up subsequent + processing and importing. + + .. attribute:: bond_feasibility_check + + When set to true, adds an additional distance feasibility to figure out if + two atoms should be connected. Atoms are only connected if they are within a + certain distance range. Set this to false to completely disable distance + checks for intra-residual bonds. Peptide bonds as well as bonds between + nucleotides involving more than one residue still make use of the distance + check to figure out of if the two residues should be connected. diff --git a/modules/io/doc/sequence_formats.rst b/modules/io/doc/sequence_formats.rst new file mode 100644 index 0000000000000000000000000000000000000000..63f01ffc9189be292ec376a7e124a6faa7fb5cfc --- /dev/null +++ b/modules/io/doc/sequence_formats.rst @@ -0,0 +1,31 @@ +Supported Sequence File Formats +================================================================================ + +FASTA +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + fasta, fna, fas, fa, fsa + +*Format Name* + fasta + +ClustalW +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + aln + +*Format Name* + clustal + +Promod +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + ali + +*Format Name* + promod + + diff --git a/modules/io/doc/structure_formats.rst b/modules/io/doc/structure_formats.rst new file mode 100644 index 0000000000000000000000000000000000000000..46ceadba36c66f78f922865b8382818282baa786 --- /dev/null +++ b/modules/io/doc/structure_formats.rst @@ -0,0 +1,54 @@ +Supported Structure File Formats +================================================================================ + +The following file formats are supported by :func:`~ost.io.LoadEntity`. + + + +CRD - CARD format file used by CHARMM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This trajectory file format is used by the CHARMM program suite (Molecular Modelling). + +*Recognized File Extensions* + crd + +PDB - Brookhaven PDB File +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Fine grained control over PDB file import is available via the +:func:`~ost.io.LoadPDB` function. The PDB importer supports loading gzipped PDB +files, which are auto-detected by the .gz file extension. + +*Recognized File Extensions* + ent, pdb, ent.gz, pdb.gz + +*Format Name* + pdb + +mmCIF - macromolecular Crystallographic Information File +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Fine grained control over mmCIFile import is available via the +:func:`~ost.io.LoadMMCIF` function. Most notably, this gives you access to the +:class:`MMCifInfo` class. The mmCIF importer supports loading gzipped files, +which are auto-detected by the .gz file extension. + +*Recognized File Extensions* + cif, cif.gz + +*Format Name* + mmcif + +PQR +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + pqr + +*Format Name* + pqr + +SDF - Structured Data File +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + sdf + diff --git a/modules/io/pymod/export_map_io.cc b/modules/io/pymod/export_map_io.cc index afe494d1997b4d1720fe49592b35c36e51976980..4d49dad7f6f2e08de62a1fa39a65146d8cecd7bd 100644 --- a/modules/io/pymod/export_map_io.cc +++ b/modules/io/pymod/export_map_io.cc @@ -17,6 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ #include <boost/python.hpp> +#include <ost/io/img/map_io_df3_handler.hh> #include <ost/io/img/map_io_dx_handler.hh> #include <ost/io/img/map_io_spi_handler.hh> #include <ost/io/img/map_io_mrc_handler.hh> @@ -92,6 +93,11 @@ void export_map_io() .def("GetMaximum", &ImageFormatBase::GetMaximum) .def("GetMinimum", &ImageFormatBase::GetMinimum) ; + + class_<DF3, bases<ImageFormatBase> >("DF3", init<bool>(arg("normalize_on_save") = false)) + .def("SetNormalizeOnSave", &DF3::SetNormalizeOnSave) + .def("GetNormalizeOnSave", &DF3::GetNormalizeOnSave) + ; class_<DX, bases<ImageFormatBase> >("DX", init<bool>(arg("normalize_on_save") = false)) .def("SetNormalizeOnSave", &DX::SetNormalizeOnSave) @@ -107,7 +113,7 @@ void export_map_io() ; class_<MRC, bases<ImageFormatBase> >("MRC", init<bool,Subformat,Endianess> - ((arg("normalize_on_save") = false,arg("subformat")=MRC_NEW_FORMAT,arg("endianess_on_save")=OST_LOCAL_ENDIAN))) + ((arg("normalize_on_save") = false,arg("subformat")=MRC_AUTO_FORMAT,arg("endianess_on_save")=OST_LOCAL_ENDIAN))) .def("SetNormalizeOnSave", &MRC::SetNormalizeOnSave) .def("GetNormalizeOnSave", &MRC::GetNormalizeOnSave) .def("SetSubformat", &MRC::SetSubformat) @@ -116,6 +122,10 @@ void export_map_io() .def("GetEndianessOnSave", &MRC::GetEndianessOnSave) ; + class_<CCP4, bases<MRC> >("CCP4", init<bool,Endianess> + ((arg("normalize_on_save") = false,arg("endianess_on_save")=OST_LOCAL_ENDIAN))) + ; + class_<DM3, bases<ImageFormatBase> >("DM3", init<>()) ; diff --git a/modules/io/src/img/map_io_dm3_handler.hh b/modules/io/src/img/map_io_dm3_handler.hh index 89d5f87c1ca78f98b794dff63b45f508c236238f..97191f67ef9456c3c3d5e804ec9a8011454daea2 100644 --- a/modules/io/src/img/map_io_dm3_handler.hh +++ b/modules/io/src/img/map_io_dm3_handler.hh @@ -50,7 +50,7 @@ class DLLEXPORT_OST_IO MapIODm3Handler: public MapIOHandler static bool MatchType(const ImageFormatBase& type); static bool MatchSuffix(const String& loc); static bool ProvidesImport() { return true; } - static bool ProvidesExport() { return true; } + static bool ProvidesExport() { return false; } static String GetFormatName() { return String("Dm3"); } static String GetFormatDescription() {return String("Format used by Gatan Inc.'s Digital Micrograph software");} diff --git a/modules/io/src/img/map_io_ipl_handler.cc b/modules/io/src/img/map_io_ipl_handler.cc index dd1fb2981a1f8c95f407331086508253a425f450..a61715908fba718173e7af9b347e7ca7a5f3eaa7 100644 --- a/modules/io/src/img/map_io_ipl_handler.cc +++ b/modules/io/src/img/map_io_ipl_handler.cc @@ -193,9 +193,8 @@ std::ostream& operator<< (std::ostream& out, const IPLHeader& h ) out << "COMMENT = Created by OpenStructure \r\n"; out << " \r\n"; uint fillsize=h.header_length-out.tellp()+start_pos; - char empty[fillsize]; - std::fill_n(empty,fillsize,0); - out.write(empty,fillsize); + std::vector<char> empty(fillsize,'\0'); + out.write(&empty[0],fillsize); return out; } @@ -256,9 +255,8 @@ std::istream& operator>> (std::istream& in, IPLHeader& h) } }while(in.peek()!=0); uint fillsize=h.header_length-in.tellg()+start_pos; - char empty[h.header_length]; - std::fill_n(empty,fillsize,0); - in.read(empty,fillsize); + std::vector<char> empty(fillsize,'\0'); + in.read(&empty[0],fillsize); return in; } diff --git a/modules/io/src/mol/dcd_io.cc b/modules/io/src/mol/dcd_io.cc index 5acc5bf4b79dcb0eca650ebe306f6d944cc78b68..7ec81f5ed190a9f68aed306199e56cc5cd4d9cf5 100644 --- a/modules/io/src/mol/dcd_io.cc +++ b/modules/io/src/mol/dcd_io.cc @@ -56,7 +56,7 @@ struct DCDHeader { char hdrr[4]; int icntrl[20]; int ntitle; - char title[1024]; + std::string title; int num, istep, freq,nstep; int t_atom_count,f_atom_count, atom_count; }; @@ -78,18 +78,25 @@ bool read_dcd_header(std::istream& istream, DCDHeader& header, bool& swap_flag, ucell_flag=false; if(gap_flag) istream.read(dummy,sizeof(dummy)); istream.read(header.hdrr,sizeof(char)*4); + if(header.hdrr[0]!='C' || header.hdrr[1]!='O' || header.hdrr[2]!='R' || header.hdrr[3]!='D') { + throw IOException("LoadCHARMMTraj: missing CORD magic in header"); + } istream.read(reinterpret_cast<char*>(header.icntrl),sizeof(int)*20); - if(header.icntrl[1]<0 || header.icntrl[1]>1e8) { + if(header.icntrl[1]<0 || header.icntrl[1]>1e6) { // nonsense atom count, try swapping swap_int(header.icntrl,20); - if(header.icntrl[1]<0 || header.icntrl[1]>1e8) { - throw(IOException("LoadCHARMMTraj: nonsense atom count in header")); + if(header.icntrl[1]<0 || header.icntrl[1]>1e6) { + std::ostringstream msg; + msg << "LoadCHARMMTraj: nonsense atom count (" << header.icntrl[1] << ") in header"; + throw IOException(msg.str()); } else { LOG_VERBOSE("LoadCHARMMTraj: byte-swapping"); swap_flag=true; } } + LOG_VERBOSE("LoadCHARMMTraj: found " << header.icntrl[1] << " atoms"); + if(header.icntrl[19]!=0) { // CHARMM format ucell_flag=(header.icntrl[10]!=0); if(ucell_flag) { @@ -112,8 +119,12 @@ bool read_dcd_header(std::istream& istream, DCDHeader& header, bool& swap_flag, if(swap_flag) swap_int(&header.ntitle,1); if(gap_flag) istream.read(dummy,sizeof(dummy)); - istream.read(header.title,sizeof(char)*header.ntitle); - header.title[header.ntitle]='\0'; + std::vector<char> title(header.ntitle+1); + + istream.read(&title[0],sizeof(char)*header.ntitle); + header.title=std::string(&title[0],header.ntitle); + LOG_VERBOSE("LoadCHARMMTraj: title string [" << header.title << "]") + if(gap_flag) istream.read(dummy,sizeof(dummy)); istream.read(reinterpret_cast<char*>(&header.t_atom_count),sizeof(int)); if(swap_flag) swap_int(&header.t_atom_count,1); @@ -359,11 +370,11 @@ mol::CoordGroupHandle LoadCHARMMTraj(const mol::EntityHandle& ent, mol::AtomHandleList alist(ent.GetAtomList()); std::sort(alist.begin(),alist.end(),less_index); if (lazy_load) { - LOG_INFO("Importing CHARMM trajectory with lazy_load=true"); - DCDCoordSource* source=new DCDCoordSource(alist, trj_fn, stride); - return mol::CoordGroupHandle(DCDCoordSourcePtr(source)); + LOG_VERBOSE("LoadCHARMMTraj: importing with lazy_load=true"); + DCDCoordSourcePtr source(new DCDCoordSource(alist, trj_fn, stride)); + return mol::CoordGroupHandle(source); } - LOG_INFO("Importing CHARMM trajectory with lazy_load=false"); + LOG_VERBOSE("LoadCHARMMTraj: importing with lazy_load=false"); return load_dcd(alist, trj_fn, stride); } diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc index 58fdcb910d7346f8564be8dcc68fa3e64d34b8a2..0f08c72e08ab95460e5552770706bd3c54d3a002 100644 --- a/modules/io/src/mol/entity_io_crd_handler.cc +++ b/modules/io/src/mol/entity_io_crd_handler.cc @@ -244,12 +244,12 @@ CRDWriter::CRDWriter(std::ostream& ostream, bool ext) : {} CRDWriter::CRDWriter(const boost::filesystem::path& filename, bool ext) : -#if BOOST_FILESYSTEM_VERSION==3 - outfile_(filename.string().c_str()), outstream_(outfile_), +#if BOOST_FILESYSTEM_VERSION==3 || BOOST_VERSION<103400 + outfile_(filename.string().c_str()), #else - outfile_(filename.file_string().c_str()), outstream_(outfile_), + outfile_(filename.file_string().c_str()), #endif - ext_(ext), atom_count_(0), res_count_(0) + outstream_(outfile_), ext_(ext), atom_count_(0), res_count_(0) {} CRDWriter::CRDWriter(const String& filename, bool ext) : diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc index be91fb54b5530413a1ccc3d51e51f8481c87b229..b4b097c1b8c8bdffcf29a3ccfac8ee9173a4abf0 100644 --- a/modules/io/src/mol/pdb_reader.cc +++ b/modules/io/src/mol/pdb_reader.cc @@ -355,17 +355,17 @@ void PDBReader::Import(mol::EntityHandle& ent, } } break; - case 'C': - case 'c': - if (curr_line.size()<20) { - LOG_TRACE("skipping entry"); - continue; - } - if (IEquals(curr_line.substr(0, 6), StringRef("COMPND", 6))) { - LOG_TRACE("processing COMPND entry"); - this->ParseCompndEntry(curr_line, line_num_); - } - break; + case 'C': + case 'c': + if (curr_line.size()<20) { + LOG_TRACE("skipping entry"); + continue; + } + if (IEquals(curr_line.substr(0, 6), StringRef("COMPND", 6))) { + LOG_TRACE("processing COMPND entry"); + this->ParseCompndEntry(curr_line, line_num_); + } + break; case 'E': case 'e': if (curr_line.size()<3) { diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index fdae17a5110b741790e5c4c4c791b78cb67edbe6..3be9390b7d7a3763345364004cbe39853de4579c 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -347,7 +347,7 @@ PDBWriter::PDBWriter(std::ostream& stream, const IOProfile& profile): PDBWriter::PDBWriter(const boost::filesystem::path& filename, const IOProfile& profile): -#if BOOST_FILESYSTEM_VERSION==3 +#if BOOST_FILESYSTEM_VERSION==3 || BOOST_VERSION<103400 outfile_(filename.string().c_str()), outstream_(outfile_), #else outfile_(filename.file_string().c_str()), outstream_(outfile_), diff --git a/modules/io/src/mol/sdf_writer.cc b/modules/io/src/mol/sdf_writer.cc index f38f953f68c31dca8c6378958734589607a68ad1..973224e48aff879b099aacd5fbd0f85002071b1b 100644 --- a/modules/io/src/mol/sdf_writer.cc +++ b/modules/io/src/mol/sdf_writer.cc @@ -140,7 +140,7 @@ SDFWriter::SDFWriter(const String& filename) } SDFWriter::SDFWriter(const boost::filesystem::path& filename): -#if BOOST_FILESYSTEM_VERSION==3 +#if BOOST_FILESYSTEM_VERSION==3 || BOOST_VERSION<103400 outfile_(filename.string().c_str()), #else outfile_(filename.file_string().c_str()), diff --git a/modules/io/tests/test_clustal.cc b/modules/io/tests/test_clustal.cc index 682dc60bb47edde6388ce5dfbaa9772cb11d6e09..0f8b4d63bd56e0aa4f51acba6dcb18c64b273bd6 100644 --- a/modules/io/tests/test_clustal.cc +++ b/modules/io/tests/test_clustal.cc @@ -25,6 +25,7 @@ #include <ost/io/seq/load.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::io; @@ -32,7 +33,7 @@ const static String MOUSE="MFQAFPGDYDSGSRCSSSPSAESQYLSSVDSFGSPPTAAASQECAGLGEMPGS const static String HUMAN="MFQAFPGDYDSGSRCSSSPSAESQYLSSVDSFGSPPTAAASQECAGLGEMPGSFVPTVTAITTSQDLQWLVQPTLISSMAQSQGQPLASQPPVVDPYDMPGTSYSTPGMSGYSSGGASGS"; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(clustal) @@ -49,4 +50,4 @@ BOOST_AUTO_TEST_CASE(clustal) BOOST_CHECK_EQUAL(aln.GetSequence(1).GetString(), HUMAN); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_io_crd.cc b/modules/io/tests/test_io_crd.cc index 82126d10f1fb9d9298e68a035340396df58dd57e..5fa943c87bd1cc942c0cf5b9dc1053ce15099a42 100644 --- a/modules/io/tests/test_io_crd.cc +++ b/modules/io/tests/test_io_crd.cc @@ -22,12 +22,13 @@ #include <ost/io/save_entity.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::io; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(test_io_crd_import_handler) { @@ -154,4 +155,4 @@ BOOST_AUTO_TEST_CASE(test_io_crd_default_format) } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_io_dcd.cc b/modules/io/tests/test_io_dcd.cc index 5bfd0161f354155527dff2d79e7b24a02fb9ca8e..b326d381b68d15f4bf61c80df65ddc06f5446f11 100644 --- a/modules/io/tests/test_io_dcd.cc +++ b/modules/io/tests/test_io_dcd.cc @@ -26,6 +26,7 @@ #include <ost/mol/coord_group.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::io; @@ -36,7 +37,7 @@ namespace { boost::uniform_01<boost::mt19937> UniformRandom(RandomGenerator); } -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(test_io_dcd_charmm_frames) { @@ -85,4 +86,4 @@ BOOST_AUTO_TEST_CASE(test_io_dcd_charmm_frames) } } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc index 47f858f8eb26f61b3e7e775c201fbbfd2d73f160..b0e54cdc37dacf167da076cc78b813c2ee7b4fab 100644 --- a/modules/io/tests/test_io_pdb.cc +++ b/modules/io/tests/test_io_pdb.cc @@ -17,6 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ #include <ost/test_utils/compare_files.hh> +#include <ost/geom/vec_mat_predicates.hh> #include <ost/platform.hh> #include <ost/dyn_cast.hh> @@ -32,12 +33,14 @@ #include <ost/io/io_exception.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> using boost::unit_test_framework::test_suite; using namespace ost; using namespace ost::io; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(test_pdb_import_handler) { @@ -1007,8 +1010,7 @@ BOOST_AUTO_TEST_CASE(test_pqr_read_atom) BOOST_CHECK_EQUAL(a1.GetResidue().GetName(), "MET"); BOOST_CHECK_EQUAL(a1.GetResidue().GetChain().GetName(), " "); - - BOOST_CHECK_EQUAL(a1.GetPos(), geom::Vec3(21.6, 35.3, 56.7)); + BOOST_CHECK(vec3_is_close(a1.GetPos(), geom::Vec3(21.6, 35.3, 56.7),Real(0.1))); BOOST_CHECK_EQUAL(a1.GetElement(), ""); BOOST_CHECK_EQUAL(a1.IsHetAtom(), false); BOOST_CHECK_CLOSE(a1.GetCharge(), Real(-0.3755), Real(1e-4)); @@ -1020,7 +1022,7 @@ BOOST_AUTO_TEST_CASE(test_pqr_read_atom) BOOST_CHECK_EQUAL(a2.GetResidue().GetName(), "ARG"); BOOST_CHECK_EQUAL(a2.GetResidue().GetChain().GetName(), " "); - BOOST_CHECK_EQUAL(a2.GetPos(), geom::Vec3(23.9, 28.7, 56.5)); + BOOST_CHECK(vec3_is_close(a2.GetPos(), geom::Vec3(23.9, 28.7, 56.5),Real(0.1))); BOOST_CHECK_EQUAL(a2.GetElement(), ""); BOOST_CHECK_EQUAL(a2.IsHetAtom(), false); BOOST_CHECK_CLOSE(a2.GetCharge(), Real(0.2507), Real(1e-4)); @@ -1059,4 +1061,4 @@ BOOST_AUTO_TEST_CASE(test_pqr_write_atom) BOOST_CHECK_EQUAL(fwriter.IsPQR(), true); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_io_sdf.cc b/modules/io/tests/test_io_sdf.cc index bd62e05280eff093f51133ad7f26a9fa8cdc602a..dcf7df6daf7afb4d5ea08bd6a19b1236f9128d91 100644 --- a/modules/io/tests/test_io_sdf.cc +++ b/modules/io/tests/test_io_sdf.cc @@ -23,6 +23,8 @@ #include <ost/io/io_exception.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/test/auto_unit_test.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> using boost::unit_test_framework::test_suite; @@ -30,7 +32,7 @@ using boost::unit_test_framework::test_suite; using namespace ost; using namespace ost::io; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(test_sdf_import_handler) { @@ -252,4 +254,4 @@ BOOST_AUTO_TEST_CASE(empty_dataheader_error_sdf) } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_iomanager.cc b/modules/io/tests/test_iomanager.cc index 47a7e628ec0cabacfb20334413bca4073ed53949..fc4cc0366b2a640aafbd8f569951886b78adef9f 100644 --- a/modules/io/tests/test_iomanager.cc +++ b/modules/io/tests/test_iomanager.cc @@ -19,13 +19,14 @@ #include <ost/io/io_manager.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using boost::unit_test_framework::test_suite; using namespace ost; using namespace ost::io; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(io_manager) @@ -36,4 +37,4 @@ BOOST_AUTO_TEST_CASE(io_manager) BOOST_CHECK(iom.FindEntityImportHandler("model.ent")); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_mmcif_info.cc b/modules/io/tests/test_mmcif_info.cc index 23a28205ea74f2e15eb9cd793e16113d137da425..3d26747976b618212b05d0416012ecc2b78f5fc5 100644 --- a/modules/io/tests/test_mmcif_info.cc +++ b/modules/io/tests/test_mmcif_info.cc @@ -22,7 +22,8 @@ #define BOOST_AUTO_TEST_DYN_LINK #include <boost/test/unit_test.hpp> - +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> using namespace ost; using namespace ost::io; @@ -170,7 +171,11 @@ BOOST_AUTO_TEST_CASE(mmcif_info_structdetails) BOOST_CHECK(sd.GetTitle() == "More than a structure"); BOOST_CHECK(sd.GetCASPFlag() == 'Y'); BOOST_CHECK(sd.GetDescriptor() == "ADENYLATE KINASE"); + #if OST_DOUBLE_PRECISION + BOOST_CHECK_CLOSE(sd.GetMass(), 1.0, 0.001); + #else BOOST_CHECK_CLOSE(sd.GetMass(), 1.0f, 0.001f); + #endif BOOST_CHECK(sd.GetMassMethod() == "Good Guess"); BOOST_CHECK(sd.GetModelDetails() == "Even more guessing"); BOOST_CHECK(sd.GetModelTypeDetails() == "MINIMIZED AVERAGE"); @@ -192,8 +197,12 @@ BOOST_AUTO_TEST_CASE(mmcif_info) info.SetResolution(1.9f); BOOST_CHECK(info.GetMethod() == StringRef("Cooking.", 8)); + #if OST_DOUBLE_PRECISION + BOOST_CHECK_CLOSE(info.GetResolution(), 1.9, 0.001); + #else BOOST_CHECK_CLOSE(info.GetResolution(), 1.9f, 0.001f); - + #endif + BOOST_MESSAGE(" done."); } diff --git a/modules/io/tests/test_mmcif_reader.cc b/modules/io/tests/test_mmcif_reader.cc index fff6bbb2e6d6d2596f69f6a223aeeb957f84a50d..953ac31323ea774278d94aead1d66c078df70cc8 100644 --- a/modules/io/tests/test_mmcif_reader.cc +++ b/modules/io/tests/test_mmcif_reader.cc @@ -26,6 +26,8 @@ #define BOOST_AUTO_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> using namespace ost; @@ -397,6 +399,14 @@ BOOST_AUTO_TEST_CASE(mmcif_entity_tests) BOOST_AUTO_TEST_CASE(mmcif_entity_poly_tests) { + SetPrefixPath(getenv("OST_ROOT")); + String lib_path=GetSharedDataPath()+"/compounds.chemlib"; + conop::CompoundLibPtr compound_lib=conop::CompoundLib::Load(lib_path); + if (!compound_lib) { + std::cout << "WARNING: skipping SEQRES import unit test. " + << "Rule-based builder is required" << std::endl; + return; + } conop::Conopology::Instance().SetDefaultBuilder("RBB"); BOOST_MESSAGE(" Running mmcif_entity_poly_tests..."); mol::ChainHandle ch; @@ -601,7 +611,7 @@ BOOST_AUTO_TEST_CASE(mmcif_citation_author_tests) std::ifstream s("testfiles/mmcif/atom_site.mmcif"); IOProfile profile; MMCifReader mmcif_p(s, eh, profile); - BOOST_CHECK_NO_THROW(mmcif_p.Parse()); + BOOST_REQUIRE_NO_THROW(mmcif_p.Parse()); std::vector<String> authors = mmcif_p.GetInfo().GetCitations().back().GetAuthorList(); @@ -657,8 +667,12 @@ BOOST_AUTO_TEST_CASE(mmcif_refine_tests) std::ifstream s("testfiles/mmcif/atom_site.mmcif"); IOProfile profile; MMCifReader mmcif_p(s, eh, profile); - BOOST_CHECK_NO_THROW(mmcif_p.Parse()); + BOOST_REQUIRE_NO_THROW(mmcif_p.Parse()); + #if OST_DOUBLE_PRECISION + BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetResolution(), 2.0, 0.001); + #else BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetResolution(), 2.0f, 0.001f); + #endif } BOOST_MESSAGE(" done."); BOOST_MESSAGE(" capturing fishy data lines..."); @@ -1206,7 +1220,7 @@ BOOST_AUTO_TEST_CASE(mmcif_testreader) mmcif_p.SetRestrictChains("A O C"); BOOST_MESSAGE(" testing Parse()..."); - BOOST_CHECK_NO_THROW(mmcif_p.Parse()); + BOOST_REQUIRE_NO_THROW(mmcif_p.Parse()); BOOST_REQUIRE_EQUAL(eh.GetChainCount(), 3); BOOST_REQUIRE_EQUAL(eh.GetResidueCount(), 14); @@ -1253,7 +1267,11 @@ BOOST_AUTO_TEST_CASE(mmcif_testreader) BOOST_CHECK(sd.GetTitle() == "A Title"); BOOST_CHECK(sd.GetCASPFlag() == 'Y'); BOOST_CHECK(sd.GetDescriptor() == "ADENYLATE KINASE"); + #if OST_DOUBLE_PRECISION + BOOST_CHECK_CLOSE(sd.GetMass(), 1.0, 0.001); + #else BOOST_CHECK_CLOSE(sd.GetMass(), 1.0f, 0.001f); + #endif BOOST_CHECK(sd.GetMassMethod() == "Good Guess"); BOOST_CHECK(sd.GetModelDetails() == "Even better guessing"); BOOST_CHECK(sd.GetModelTypeDetails() == "Guess"); diff --git a/modules/io/tests/test_pir.cc b/modules/io/tests/test_pir.cc index 00482c0647ae31e254aa2c487c394379f3ee32c1..946d113bab6f8781be733582e45bfe15f65dc7f7 100644 --- a/modules/io/tests/test_pir.cc +++ b/modules/io/tests/test_pir.cc @@ -23,6 +23,7 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/seq/invalid_sequence.hh> #include <ost/io/seq/pir_io_handler.hh> #include <ost/io/seq/load.hh> @@ -33,7 +34,7 @@ using namespace ost; using namespace ost::io; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(pir_filetypes) @@ -70,4 +71,4 @@ BOOST_AUTO_TEST_CASE(pir_no_star) seq::InvalidSequence); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_star_parser.cc b/modules/io/tests/test_star_parser.cc index d9a100dfa40ec1a32168cdefe13734e8d6a35194..5561dd89203f14d29c45c0ba3655c1fb15919aed 100644 --- a/modules/io/tests/test_star_parser.cc +++ b/modules/io/tests/test_star_parser.cc @@ -27,6 +27,8 @@ #define BOOST_AUTO_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> using namespace ost; @@ -131,7 +133,7 @@ public: const std::vector<StringRef>& columns) { BOOST_CHECK_EQUAL(columns[0][0], cur_char_); - BOOST_CHECK_EQUAL(columns[0].size(), 1); + BOOST_CHECK_EQUAL(columns[0].size(), static_cast<size_t>(1)); ++cur_char_; BOOST_CHECK_EQUAL(columns[1][0], cur_char_); BOOST_CHECK_EQUAL(columns[1].size(), 1); diff --git a/modules/io/tests/tests.cc b/modules/io/tests/tests.cc index faa6774fc478a3bf696a7105461792447f9fff7a..85c0f12e22ce3afe219d727fcd687ee35d33a7a6 100644 --- a/modules/io/tests/tests.cc +++ b/modules/io/tests/tests.cc @@ -18,4 +18,6 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_io +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/mol/alg/doc/molalg.rst b/modules/mol/alg/doc/molalg.rst index 020ef98b6395f2ec74629e6fd4f3c8c9e4a88dc0..29f3750b70d3d1aedd50bfc4f23790d2ed3c8cc1 100644 --- a/modules/mol/alg/doc/molalg.rst +++ b/modules/mol/alg/doc/molalg.rst @@ -4,105 +4,364 @@ .. module:: ost.mol.alg :synopsis: Algorithms operating on molecular structures -.. function:: LocalDistTest(model, reference, tolerance, radius, local_ldt_property_string="") +.. function:: LocalDistDiffTest(model, reference, tolerance, radius, local_ldt_property_string="") - This function calculates the agreement of local contacts between the model and - the reference structure. The overlap is a number between zero and one, where - one indicates complete agreement, zero indicates no agreement at all. This - score is similar to the GDT, but does not require any superposition of the - model and the reference. + This function calculates the agreement of local contacts between a model and + a reference structure (Local Distance Difference Tests). The overlap is a number + between zero and one, where one indicates complete agreement, zero indicates no + agreement at all. This score is similar to the GDT, but does not require any + superposition between the model and the reference. - The distance of atom pairs in the reference structure that are closer than a - certain distance (radius) to each other is compared to the distance found in + The distance of atom pairs in the reference structure, when shorter than a + certain predefined distance (inclusion radius), is compared with the same distance in the model. If the difference between these two distances is smaller than a - threshold value (tolerance), the model and the reference agree. Missing atoms - in the model are treated disagreement and thus lower the score. + threshold value (tolerance), the distance is considered conserverd in the model. Missing atoms + in the model lead to non-conserved distances and thus lower the score. - For residue with symmetric sidechains (GLU, ASP, ARG, VAL, PHE, TYR), the - naming of the atoms is ambigous. For these residues, the overlap of both - possible solutions to the fixed atoms, that is, everything that is not - ambigous is calculated. The solution that gives higher overlap is then used to - calculate the actual overlap score. - - If a string is passed as last parameter, the function computes the overlap score for - each residue and saves it as a float property in the ResidueHandle, with the passed string - as property name + The function only processes standard residues in the first chains of the model and of the reference + For residues with symmetric sidechains (GLU, ASP, ARG, VAL, PHE, TYR), the + naming of the atoms is ambigous. For these residues, the function computes the Local Distance Difference + Test score that each naming convention would generate when considering all non-ambigous surrounding atoms. + The solution that gives higher score is then picked to compute the final Local Difference + Distance Score for the whole model. + + If a string is passed as last parameter to the function, the function computes the Local Difference Distance + Test score for each residue and saves it as a float property in the ResidueHandle, with the passed string + as property name. Additionally, the actual residue-based counts of the total checked distances and of + the distances conserved in the model are stored as integer properties in the ResidueHandle. The property + names are respectively <passed string>_total and <passed string>_conserved. + + :param model: the model structure + :type model: :class:`~ost.mol.EntityView` + :param reference: the reference structure + :type reference: :class:`~ost.mol.EntityView` + :param tolerance: the tolerance threshold used to determine distance conservation + :param radius: the inclusion radius in Angstroms + :param local_ldt_property_string: the base name for the ResidueHandle properties that store the local scores + + :returns: the Local Distance Difference Test score -.. function:: SuperposeFrames(frames, sel, from=0, to=-1, ref=-1) - - This function superposes the frames of the given coord group and returns them - as a new coord group. - - :param frames: The source coord group. - :type frames: :class:`~ost.mol.CoordGroupHandle` - :param sel: An entity view containing the selection of atoms to be used for - superposition. If set to an invalid view, all atoms in the coord group are - used. - :type sel: :class:`ost.mol.EntityView` - :param from: index of the first frame - :param to: index of the last frame plus one. If set to -1, the value is set to - the number of frames in the coord group - :param ref: The index of the reference frame to use for superposition. If set - to -1, the each frame is superposed to the previous frame. - - :returns: A newly created coord group containing the superposed frames. - +.. function:: LocalDistDiffTest(model, distance_list, tolerance_list, sequence_separation=0, local_ldt_property_string="") -.. function:: SuperposeFrames(frames, sel, ref_view, from=0, to=-1) - - Same as SuperposeFrames above, but the superposition is done on a reference - view and not on another frame of the trajectory. + This function counts the conserved local contacts between the model and the reference structure + (these are the values needed to compute the Local Distance Difference Test score, see description of + the previous function). It shares the same properties as the previous function, with some differences: + the thresholds can be more than one (the return counts are then the average over all thresholds), and + the input is not the reference structure, but already a list of distances to be checked for conservation + + A sequence separation parameter can be passed to the function. If this happens, only distances between residues + whose separation is higher than the provided parameter are considered when computing the score + + If a string is passed as the last parameter, residue-based counts and the value of the residue-based Local + Distance Difference Test score are saved in each ResidueHandle as int and float properties, as detailed in + the description of the previous function. + + :param model: the model structure + :type model: :class:`~ost.mol.EntityView` + :param distance_list: the list of distances to check for conservation + :type distance_list: :class:`~ost.mol.alg.GlobalRDMap` + :param tolerance_list: a list of thresholds used to determine distance conservation + :param sequence_separation: sequence separation parameter used when computing the score + :param local_ldt_property_string: the base name for the ResidueHandle properties that store the local scores + + :returns: a tuple containing the counts of the conserved distances in the model and of all the checked + distances + +.. function:: LocalDistDiffTest(alignment, tolerance, radius, ref_index=0, mdl_index=1); + + Calculates the Local Distance Difference Test score (see previous functions) starting from an + alignment between a reference structure and a model. The AlignmentHandle parameter used to provide the + alignment to the function needs to have the two structures attached to it. By default the first structure in the + alignment is considered to be the reference structure, and the second structure is taken as the model. This + can however be changed by passing the indexes of the two structures in the AlignmentHandle as parameters to the + function. + + BEWARE: This function uses the old implementation of the Local Distance Difference Test algorithm and + will give slightly different results from the new one. + + :param alignment: an alignment containing the sequences of the reference and of the model structures, with the structures themselves + attached + :type alignment: :class:`~ost.seq.AlignmentHandle` + :param tolerance: a list of thresholds used to determine distance conservation + :param radius: the inclusion radius in Angstroms (to determine which distances are checked for conservation) + :param ref_index: index of the reference structure in the alignment + :param mdl_index: index of the model in the alignment + + :returns: the Local Distance Difference Test score + +.. function:: LDTHA(model, distance_list, sequence_separation=0); + + This function calculates the Local Distance Difference Test - High Accuracy score (see previous functions). + The High Accuracy name comes from the fact that the tolerance levels used by this function are the same + as the thresholds used by GDT-HA (0.5, 1, 2, and 4 Angstrom). + + A sequence separation parameter can be passed to the function. If this happens, only distances between residues + whose separation is higher than the provided parameter are considered when computing the score + + :param model: the model structure + :type model: :class:`~ost.mol.EntityView` + :param distance_list: the list of distances to check for conservation + :type distance_list: :class:`~ost.mol.alg.GlobalRDMap` + :param sequence_separation: sequence separation parameter used when computing the score + + :returns: the Local Distance Difference Test score + +.. function:: CreateDistanceList(reference, radius); +.. function:: CreateDistanceListFromMultipleReferences(reference_list, tolerance_list, sequence_separation, radius); + + Both these functions create lists of distances to be checked during a Local Distance Difference Test + (see description of the functions above). + + Both functions process only standard residues present in the first chain of the reference structures. + + The only difference between the two functions is that one takes a single reference structure and the other + a list of reference structures. The structures in the list have to be properly prepared before being passed + to the function. Corresponding residues in the structures must have the same residue number, the same chain name, + etc. Gaps are allowed and automatically dealt with: if information about a distance is present in at least one of + the structures, it will be considered. + + If a distance between two atoms is shorter than the inclusion radius in all structures in which the two atoms are + present, it is included in the list. However, if the distance is longer than the inclusion radius in at least + one of the structures, it is not considered to be a local interaction and is excluded from the list. + + The multiple-reference function takes care of residues with ambigous symmetric sidechains. To decide which naming + convention to use, the function computes a Local Distance Difference Test score for each reference against the + first reference structure in the list, using only non ambigously-named atoms. It picks then the naming convention + that gives the highest score, guaranteeing that all references are processed with the correct atom names. + + The cutoff list that will later be used to compute the Local Distance Difference Test score and the sequence + separation parameter must be passed to the multi-reference function. These parameters do not influence the output + distance list, which always includes all distances within the provided radius (to make it consistent with the + single-reference corresponding function). However, the parameters are used when dealing with the naming convention + of residues with ambiguous nomenclature. + + :param reference: a reference structure from which distances are derived + :type reference: :class:`~ost.mol.EntityView` + :param reference_list: a list of of reference structures from which distances are derived + :type reference_list: list of :class:`~ost.mol.EntityView` + :param tolerance_list: a list of thresholds used to determine distance conservation when computing the LDDT score + :param sequence_separation: sequence separation parameter used when computing the LDDT score + :param radius: inclusion radius (in Angstroms) used to determine the distances included in the list - :param frames: The source coord group. - :type frames: :class:`~ost.mol.CoordGroupHandle` - :param sel: An entity view containing the selection of atoms of the frames to be used for - superposition. - :type sel: :class:`ost.mol.EntityView` - :param ref_view: The reference view on which the frames will be superposed. The number - of atoms in this reference view should be equal to the number of atoms in sel. - :type ref_view: :class:`ost.mol.EntityView` - :param from: index of the first frame - :param to: index of the last frame plus one. If set to -1, the value is set to - the number of frames in the coord group + :returns: class `~ost.mol.alg.GlobalRDMap` - :returns: A newly created coord group containing the superposed frames. +.. class:: UniqueAtomIdentifier -.. autofunction:: ParseAtomNames + Object containing enough information to uniquely identify an atom in a structure -.. autofunction:: MatchResidueByNum + .. method:: UniqueAtomIdentifier(chain,residue_number,residue_name,atom_name) + + Creates an UniqueAtomIdentifier object starting from relevant atom information -.. autofunction:: MatchResidueByIdx + :param chain: a string containing the name of the chain to which the atom belongs + :param residue_number: the number of the residue to which the atom belongs + :type residue_number: :class:`~ost.mol.ResNum` + :param residue_name: a string containing the name of the residue to which the atom belongs + :param atom_name: a string containing the name of the atom -.. autofunction:: MatchResidueByLocalAln + .. method:: GetChainName() -.. autofunction:: MatchResidueByGlobalAln + Returns the name of the chain to which the atom belongs, as a String -.. autofunction:: Superpose + .. method:: GetResNum() + + Returns the number of the residue the atom belongs to, as a :class:`~ost.mol.ResNum` object + + .. method:: GetResidueName() + + Returns the name of the residue to which the atom belongs, as a String + + .. method:: GetAtomName() + + Returns the name of the atom, as a String + +.. class:: ResidueRDMap + + Dictionary-like object containing the a list of distances that originate from the a single residue residue, to + check during a run of the Local Distance Difference Test algorithm + +.. class:: GlobalRDMap + + Dictionary-like object containing all the :class:`~ost.mol.alg.ResidueRDMap` objects related to residues + of a single structure + +.. function: PrintResidueRDMap(residue_distance_list) + Prints to standard output all the distances contained in a :class:`~ost.mol.ResidueRDMap` object + +.. function: PrintGlobalRDMap(global_distance_list) + + Prints to standard output all the distances contained in each of the :class:`~ost.mol.ResidueRDMap` objects that + make up a :class:`~ost.mol.GlobalRDMap` object + + +.. _steric-clashes: Steric Clashes -------------------------------------------------------------------------------- -The following function detects steric clashes in atomic structures. Two atoms are clashing if their euclidian distance is smaller than a threshold value. The threshold values are calculated from high-resolution X-ray structures for each possible element pair. The value is chosen such that 99.99% of observed distances between 0 and 5 Angstroem are above the threshold. +The following function detects steric clashes in atomic structures. Two atoms are clashing if their euclidian distance is smaller than a threshold value (minus a tolerance offset). +.. function:: FilterClashes(entity, clashing_distances, always_remove_bb=False) -.. function:: FilterClashes(ent, tolerance=0.0) + This function filters out residues with non-bonded clashing atoms. If the clashing atom + is a backbone atom, the complete residue is removed from the structure, if the atom is part of + the sidechain, only the sidechain atoms are removed. This behavior is changed + by the always_remove_bb flag: when the flag is set to True the whole residue is removed even if + a clash is just detected in the side-chain. + + Two atoms are defined as clashing if their distance is shorter than the reference distance minus a tolerance + threshold. The information about the clashing distances and the tolerance thresholds for all possible pairs of + atoms is passed to the function as a parameter - This function filters out residues with clashing atoms. If the clashing atom - is a backbone atom, the complete residue is removed, if the atom is part of - the sidechain, only the sidechain atoms are removed. + Hydrogen and deuterium atoms are ignored by this function. - Hydrogen and deuterium atoms are ignored. + :param entity: The input entity + :type entity: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle` + :param clashing_distances: information about the clashing distances + :type clashing_distances: :class:`~ost.mol.alg.ClashingDistances` + :param always_remove_bb: if set to True, the whole residue is removed even if the clash happens in the side-chain + + :returns: The filtered :class:`~ost.mol.EntityView` + +.. function:: CheckStereoChemistry(entity,bond_stats,angle_stats,bond_tolerance,angle_tolerance,always_remove_bb=False) + + This function filters out residues with severe stereo-chemical violations. If the violation + involves a backbone atom, the complete residue is removed from the structure, if it involves an atom that is + part of the sidechain, only the sidechain is removed. This behavior is changed + by the always_remove_bb flag: when the flag is set to True the whole residue is removed even if + a violation is just detected in the side-chain - :param ent: The input entity - :type ent: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle` - :param tolerance: The tolerance in (Angstroem) is substracted from the - thresholds calculated from high resolution X-ray structures to make the - function less pedantic. Negative values are also allowed and make the - function more stringent. + A violation is defined as a bond length that lies outside of the range: [mean_length-std_dev*bond_tolerance <-> meanlength+std_dev*bond_tolerance] or an angle width lying outside of the range [mean_width-std_dev*angle_tolerance <-> mean_width+std_dev*angle_tolerance ]. The information about the mean lengths and widths and the corresponding standard deviations is passed to the function using two parameters. + + Hydrogen and deuterium atoms are ignored by this function. + + :param entity: The input entity + :type entity: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle` + :param bond_stats: statistics about bond lengths + :type bond_stats: :class:`~ost.mol.alg.StereoChemicalParams` + :param angle_stats: statistics about angle widths + :type angle_stats: :class:`~ost.mol.alg.StereoChemicalParams` + :param bond_tolerance: tolerance for bond lengths (in standard deviations) + :param angle_tolerance: tolerance for angle widths (in standard deviations)£ + :param always_remove_bb: if set to True, the whole residue is removed even if a violation in just detected in the side-chain :returns: The filtered :class:`~ost.mol.EntityView` +.. class:: ClashingDistances + + Object containing information about clashing distances between non-bonded atoms + + .. method:: ClashingDistances() + + Creates an empty distance list + + .. method:: SetClashingDistance(ele1,ele2, clash_distance, tolerance) + + Adds or replaces an entry in the list + + :param ele1: string containing the first element's name + :param ele2: string containing the second element's name + :param clash_distance: minimum clashing distance (in Angstroms) + :param tolerance: tolerance threshold (in Angstroms) + + .. method GetClashingDistance() + + Recovers a reference distance and a tolerance threshold from the list + + :param ele1: string containing the first element's name + :param ele2: string containing the second element's name + + :returns: a tuple containing the minimum clashing distance and the tolerance threshold + + .. method:: GetMaxAdjustedDistance() + + Returns the longest clashing distance in the list, after adjustment with tolerance threshold + + .. method:: IsEmpty() + + Returns True if the list is empty (i.e. in an invalid, useless state) + + .. method:: PrintAllDistances() + + Prints all distances in the list to standard output + + +.. class:: StereoChemicalParams + + Object containing stereo-chemical information about bonds and angles. For each item (bond or angle + in a specific residue), stores the mean and standard deviation + + .. method:: StereoChemicalParams() + + Creates an empty parameter list + + .. method:: SetParam(item, residue, mean, standard_dev) + + Adds or replaces an entry in the list + + :param item: string defining a bond (format: X-Y) or an angle (format:X-Y-Z), where X,Y an Z are atom names + :param residue: string containing the residue type the information pertains to + :param mean: mean bond length or angle width + :param standard_dev: standard deviation of the bond length or of the angle width + + .. method GetParam(item,residue) + + Recovers an entry from the list, + + :param item: string defining a bond (format: X-Y) or an angle (format:X-Y-Z), where X,Y an Z are atom names + :param residue: string containing the residue type the item information pertains to + + :returns: a tuple containing the mean length or width and the standard deviation + + .. method ContainsParam(item,residue) + + Checks if a specific entry is present in the list + + :param item: string defining a bond (format: X-Y) or an angle (format:X-Y-Z), where X,Y an Z are atom names + :param residue: string containing the residue type the information pertains to + + :returns: True if the list contains an entry corresponding to the correct item and residue, False if it does not + + .. method:: IsEmpty() + + Returns True if the list is empty (i.e. in an invalid, useless state) + + .. method:: PrintAllParameters() + + Prints all distances in the list to standard output + +.. function:: FillClashingDistances(file_content) +.. function:: FillBondStereoChemicalParams(file_content) +.. function:: FillAngleStereoChemicalParams(file_content) + + These three functions fill a list of reference clashing distances, a list of stereo-chemical parameters for + bonds and a list of stereo-chemical parameters for angles, respectively, starting from a the content of + parameter file. The content of the file is passed to the function as a list of strings, each containing + a line from the parameter file + + :returns: :class:`~ost.mol.alg.ClashingDistances` and :class:`~ost.mol.alg.StereoChemicalParams` respectively + +.. function:: FillClashingDistancesFromFile(filename) +.. function:: FillBondStereoChemicalParamsFromFile(filename) +.. function:: FillAngleStereoChemicalParamsFromFile(filename) + + These three functions fill a list of reference clashing distances, a list of stereo-chemical parameters for + bonds and a list of stereo-chemical parameters for angles, respectively, starting from a file. The filename + passed to the function can be a full path. + + :returns: :class:`~ost.mol.alg.ClashingDistances` and :class:`~ost.mol.alg.StereoChemicalParams` respectively + +.. function:: DefaultClashingDistances() +.. function:: DefaultBondStereoChemicalParams() +.. function:: DefaultAngleStereoChemicalParams() + + These three functions fill a list of reference clashing distances, a list of stereo-chemical parameters for + bonds and a list of stereo-chemical parameters for angles, respectively, using the default parameter file + distributed with OpenStructure. + + :returns: :class:`~ost.mol.alg.ClashingDistances` and :class:`~ost.mol.alg.StereoChemicalParams` respectively + .. _traj-analysis: @@ -230,8 +489,6 @@ used to skip frames in the analysis. :param stride: Size of the increment of the frame's index between two consecutive frames analyzed. - - .. function:: AnalyzeMinDistance(traj, view1, view2, stride=1) This function extracts the minimal distance between two sets of atoms @@ -278,3 +535,53 @@ used to skip frames in the analysis. :param stride: Size of the increment of the frame's index between two consecutive frames analyzed. +.. function:: SuperposeFrames(frames, sel, from=0, to=-1, ref=-1) + + This function superposes the frames of the given coord group and returns them + as a new coord group. + + :param frames: The source coord group. + :type frames: :class:`~ost.mol.CoordGroupHandle` + :param sel: An entity view containing the selection of atoms to be used for + superposition. If set to an invalid view, all atoms in the coord group are + used. + :type sel: :class:`ost.mol.EntityView` + :param from: index of the first frame + :param to: index of the last frame plus one. If set to -1, the value is set to + the number of frames in the coord group + :param ref: The index of the reference frame to use for superposition. If set + to -1, the each frame is superposed to the previous frame. + + :returns: A newly created coord group containing the superposed frames. + +.. function:: SuperposeFrames(frames, sel, ref_view, from=0, to=-1) + + Same as SuperposeFrames above, but the superposition is done on a reference + view and not on another frame of the trajectory. + + :param frames: The source coord group. + :type frames: :class:`~ost.mol.CoordGroupHandle` + :param sel: An entity view containing the selection of atoms of the frames to be used for + superposition. + :type sel: :class:`ost.mol.EntityView` + :param ref_view: The reference view on which the frames will be superposed. The number + of atoms in this reference view should be equal to the number of atoms in sel. + :type ref_view: :class:`ost.mol.EntityView` + :param from: index of the first frame + :param to: index of the last frame plus one. If set to -1, the value is set to + the number of frames in the coord group + + :returns: A newly created coord group containing the superposed frames. + +.. autofunction:: ParseAtomNames + +.. autofunction:: MatchResidueByNum + +.. autofunction:: MatchResidueByIdx + +.. autofunction:: MatchResidueByLocalAln + +.. autofunction:: MatchResidueByGlobalAln + +.. autofunction:: Superpose + diff --git a/modules/mol/alg/pymod/__init__.py b/modules/mol/alg/pymod/__init__.py index 3d7901d005e4328a1c730c1fd2e5a493360cce16..126d0196f2d6ff25148a6724df5dd63a1e764d6a 100644 --- a/modules/mol/alg/pymod/__init__.py +++ b/modules/mol/alg/pymod/__init__.py @@ -1,5 +1,55 @@ +import os.path from _ost_mol_alg import * from ost.mol.alg.superpose import * import ost.mol.alg.trajectory_analysis import ost.mol.alg.structure_analysis import ost.mol.alg.helix_kinks + +# Fills a list of reference clashing distances from a file (requires a path to the file) +def FillClashingDistancesFromFile(filename,default_clashing_distance,default_tolerance): + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillClashingDistances(lines,default_clashing_distance,default_tolerance) + +# Fills a list of bond stereo-chemical statistics from a file (requires a path to the file) +def FillBondStereoChemicalParamsFromFile(filename): + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillBondStereoChemicalParams("Bond",lines) + +# Fills a list of angle stereo-chemical statistics from a file (requires a path to the file) +def FillAngleStereoChemicalParamsFromFile(filename): + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillAngleStereoChemicalParams("Angle",lines) + +# Returns the default list of reference clashing distances (from the default OpenStructure parameter file) +def DefaultClashingDistances(): + shared_path=ost.GetSharedDataPath() + filename=os.path.join(shared_path,'stereo_chemical_props.txt') + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillClashingDistances(lines,1.5,0.0) + +# Returns the default list of bond stereo-chemical statistics (from the default OpenStructure parameter file) +def DefaultBondStereoChemicalParams(): + shared_path=ost.GetSharedDataPath() + filename=os.path.join(shared_path,'stereo_chemical_props.txt') + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillStereoChemicalParams("Bond",lines) + +# Returns the default list of angle stereo-chemical statistics (from the default OpenStructure parameter file) +def DefaultAngleStereoChemicalParams(): + shared_path=ost.GetSharedDataPath() + filename=os.path.join(shared_path,'stereo_chemical_props.txt') + fh=open(filename,'r') + lines=fh.readlines() + fh.close() + return FillStereoChemicalParams("Angle",lines) + diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc index c7c3e1c3b3b62e46de87b21ff5a118da5808cbcb..8949279dbc7f603174818f9166cc7bb7118d2748 100644 --- a/modules/mol/alg/pymod/wrap_mol_alg.cc +++ b/modules/mol/alg/pymod/wrap_mol_alg.cc @@ -18,9 +18,9 @@ //------------------------------------------------------------------------------ #include <boost/python.hpp> -#include <boost/python/suite/indexing/vector_indexing_suite.hpp> +#include <boost/python/suite/indexing/map_indexing_suite.hpp> #include <ost/config.hh> -#include <ost/mol/alg/local_dist_test.hh> +#include <ost/mol/alg/local_dist_diff_test.hh> #include <ost/mol/alg/superpose_frames.hh> #include <ost/mol/alg/filter_clashes.hh> using namespace boost::python; @@ -36,8 +36,9 @@ void export_entity_to_density(); namespace { -Real (*ldt_a)(const mol::EntityView&, const mol::alg::GlobalDistanceList& glob_dist_list, Real, const String&)=&mol::alg::LocalDistTest; -Real (*ldt_b)(const seq::AlignmentHandle&,Real, Real, int, int)=&mol::alg::LocalDistTest; +std::pair<long int,long int> (*lddt_a)(const mol::EntityView&, const mol::alg::GlobalRDMap& , std::vector<Real>, int, const String&)=&mol::alg::LocalDistDiffTest; +Real (*lddt_c)(const mol::EntityView&, const mol::EntityView& , Real, Real, const String&)=&mol::alg::LocalDistDiffTest; +Real (*lddt_b)(const seq::AlignmentHandle&,Real, Real, int, int)=&mol::alg::LocalDistDiffTest; mol::EntityView (*fc_a)(const mol::EntityView&, const mol::alg::ClashingDistances&,bool)=&mol::alg::FilterClashes; mol::EntityView (*fc_b)(const mol::EntityHandle&, const mol::alg::ClashingDistances&, bool)=&mol::alg::FilterClashes; mol::EntityView (*csc_a)(const mol::EntityView&, const mol::alg::StereoChemicalParams&, const mol::alg::StereoChemicalParams&, Real, Real, bool)=&mol::alg::CheckStereoChemistry; @@ -66,11 +67,28 @@ ost::mol::alg::ClashingDistances fill_clashing_distances_wrapper (const list& st stereo_chemical_props_file_vector[i] = boost::python::extract<char const*>(stereo_chemical_props_file[i]); } - return ost::mol::alg::FillClashingDistances(stereo_chemical_props_file_vector,min_default_distance,min_distance_tolerance); + return ost::mol::alg::FillClashingDistances(stereo_chemical_props_file_vector); } +ost::mol::alg::GlobalRDMap create_distance_list_from_multiple_references(const list& ref_list, const list& cutoff_list, int sequence_separation, Real max_dist) +{ + int ref_list_length = boost::python::extract<int>(ref_list.attr("__len__")()); + std::vector<ost::mol::EntityView> ref_list_vector(ref_list_length); + + for (int i=0; i<ref_list_length; i++) { + ref_list_vector[i] = boost::python::extract<ost::mol::EntityView>(ref_list[i]); + } + + int cutoff_list_length = boost::python::extract<int>(cutoff_list.attr("__len__")()); + std::vector<Real> cutoff_list_vector(cutoff_list_length); + + for (int i=0; i<cutoff_list_length; i++) { + cutoff_list_vector[i] = boost::python::extract<Real>(cutoff_list[i]); + } + return ost::mol::alg::CreateDistanceListFromMultipleReferences(ref_list_vector, cutoff_list_vector, sequence_separation, max_dist); } +} BOOST_PYTHON_MODULE(_ost_mol_alg) @@ -82,14 +100,16 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) export_entity_to_density(); #endif - def("LocalDistTest", ldt_a, (arg("local_ldt_property_string")="")); - def("LocalDistTest", ldt_b, (arg("ref_index")=0, arg("mdl_index")=1)); + def("LocalDistDiffTest", lddt_a, (arg("sequence_separation")=0,arg("local_lddt_property_string")="")); + def("LocalDistDiffTest", lddt_c, (arg("local_lddt_property_string")="")); + def("LocalDistDiffTest", lddt_b, (arg("ref_index")=0, arg("mdl_index")=1)); def("FilterClashes", fc_a, (arg("ent"), arg("clashing_distances"), arg("always_remove_bb")=false)); def("FilterClashes", fc_b, (arg("ent"), arg("clashing_distances"), arg("always_remove_bb")=false)); def("CheckStereoChemistry", csc_a, (arg("ent"), arg("bonds"), arg("angles"), arg("bond_tolerance"), arg("angle_tolerance"), arg("always_remove_bb")=false)); def("CheckStereoChemistry", csc_b, (arg("ent"), arg("bonds"), arg("angles"), arg("bond_tolerance"), arg("angle_tolerance"), arg("always_remove_bb")=false)); - def("LDTHA",&mol::alg::LDTHA); + def("LDDTHA",&mol::alg::LDDTHA); def("CreateDistanceList",&mol::alg::CreateDistanceList); + def("CreateDistanceListFromMultipleReferences",&create_distance_list_from_multiple_references); def("SuperposeFrames", superpose_frames1, (arg("source"), arg("sel")=ost::mol::EntityView(), arg("begin")=0, @@ -98,7 +118,7 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) (arg("source"), arg("sel"), arg("ref_view"),arg("begin")=0, arg("end")=-1)); - class_<mol::alg::ClashingDistances> ("ClashingDistances" ,init<Real,Real>()) + class_<mol::alg::ClashingDistances> ("ClashingDistances",init<>()) .def("SetClashingDistance",&mol::alg::ClashingDistances::SetClashingDistance) .def("GetClashingDistance",&mol::alg::ClashingDistances::GetClashingDistance) .def("GetMaxAdjustedDistance",&mol::alg::ClashingDistances::GetMaxAdjustedDistance) @@ -125,23 +145,18 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) ; - class_<mol::alg::ReferenceDistance> ("ReferenceDistance", init <const mol::alg::UniqueAtomIdentifier&,const mol::alg::UniqueAtomIdentifier&, Real, Real>()) - .def("GetFirstAtom",&mol::alg::ReferenceDistance::GetFirstAtom) - .def("GetSecondAtom",&mol::alg::ReferenceDistance::GetSecondAtom) - .def("GetMinDistance",&mol::alg::ReferenceDistance::GetMinDistance) - .def("GetMaxDistance",&mol::alg::ReferenceDistance::GetMaxDistance) - ; - - class_<std::vector<mol::alg::ReferenceDistance> >("ResidueDistanceList") - .def(vector_indexing_suite<std::vector<mol::alg::ReferenceDistance > >()) + class_<mol::alg::ResidueRDMap>("ResidueRDMap") + .def(map_indexing_suite<mol::alg::ResidueRDMap>()) ; - class_<std::vector<mol::alg::ResidueDistanceList> >("GlobalDistanceList") - .def(vector_indexing_suite<std::vector<mol::alg::ResidueDistanceList > >()) + class_<mol::alg::GlobalRDMap>("GlobalRDMap") + .def(map_indexing_suite<mol::alg::GlobalRDMap>()) ; def("FillClashingDistances",&fill_clashing_distances_wrapper); def("FillStereoChemicalParams",&fill_stereochemical_params_wrapper); def("IsStandardResidue",&mol::alg::IsStandardResidue); + def("PrintGlobalRDMap",&mol::alg::PrintGlobalRDMap); + def("PrintResidueRDMap",&mol::alg::PrintResidueRDMap); } diff --git a/modules/mol/alg/src/CMakeLists.txt b/modules/mol/alg/src/CMakeLists.txt index 050d4822712f8789bfac97938e18c327334f7d92..146717ace4972b697c0ce160206b67749c029f2e 100644 --- a/modules/mol/alg/src/CMakeLists.txt +++ b/modules/mol/alg/src/CMakeLists.txt @@ -2,7 +2,7 @@ set(OST_MOL_ALG_HEADERS svd_superpose.hh module_config.hh sec_structure_segments.hh - local_dist_test.hh + local_dist_diff_test.hh superpose_frames.hh filter_clashes.hh construct_cbeta.hh @@ -15,7 +15,7 @@ set(OST_MOL_ALG_SOURCES svd_superpose.cc clash_score.cc sec_structure_segments.cc - local_dist_test.cc + local_dist_diff_test.cc superpose_frames.cc filter_clashes.cc construct_cbeta.cc @@ -39,7 +39,7 @@ if (ENABLE_IMG) set(MOL_ALG_DEPS ${MOL_ALG_DEPS} ost_img ost_img_alg) endif() -executable(NAME ldt SOURCES ldt.cc +executable(NAME lddt SOURCES lddt.cc DEPENDS_ON ost_mol ost_mol_alg ost_io STATIC) module(NAME mol_alg SOURCES ${OST_MOL_ALG_SOURCES} diff --git a/modules/mol/alg/src/filter_clashes.cc b/modules/mol/alg/src/filter_clashes.cc index 1b163d17616c676e0933b7ebc7bad4c6e56dea91..27ffb844853f7d68821d3356ec6895ef4389b4f1 100644 --- a/modules/mol/alg/src/filter_clashes.cc +++ b/modules/mol/alg/src/filter_clashes.cc @@ -27,6 +27,7 @@ namespace { +// helper function String bond_string(const ost::mol::AtomView& atom1, const ost::mol::AtomHandle& atom2) { String atom1_str = atom1.GetName(); String atom2_str = atom2.GetName(); @@ -43,6 +44,22 @@ String bond_string(const ost::mol::AtomView& atom1, const ost::mol::AtomHandle& return stkey.str(); } +// helper function +String bond_string_elems(String& ele1, String ele2) { + String string1,string2; + if (ele1 < ele2) { + string1 = ele1; + string2 = ele2; + } else { + string1 = ele2; + string2 = ele1; + } + std::stringstream stkey; + stkey << string1 << "-" << string2; + return stkey.str(); +} + +// helper function String angle_string(const ost::mol::AtomHandle& atom1, const ost::mol::AtomView& atom, const ost::mol::AtomHandle& atom2 ) { String atom1_str = atom1.GetName(); String atom2_str = atom2.GetName(); @@ -62,7 +79,6 @@ String angle_string(const ost::mol::AtomHandle& atom1, const ost::mol::AtomView& } - namespace ost { namespace mol { namespace alg { void ClashingDistances::SetClashingDistance(const String& ele1,const String& ele2, Real min_distance, Real tolerance) @@ -84,7 +100,9 @@ std::pair<Real,Real> ClashingDistances::GetClashingDistance(const String& ele1,c String key=stkey.str(); std::map <String,std::pair<float,float> >::const_iterator find_ci= min_distance_.find(key); if (find_ci == min_distance_.end()) { - return std::make_pair<Real,Real> (default_min_distance_,default_min_distance_tolerance_); + std::stringstream serr; + serr << "Entry for distance " << stkey << " not found in the parameter table"; + throw Error(serr.str()); } return find_ci->second; } @@ -239,9 +257,9 @@ StereoChemicalParams FillStereoChemicalParams(const String& header, std::vector< return table; }; -ClashingDistances FillClashingDistances(std::vector<String>& stereo_chemical_props_file, Real min_default_distance, Real min_distance_tolerance) +ClashingDistances FillClashingDistances(std::vector<String>& stereo_chemical_props_file) { - ClashingDistances table(min_default_distance,min_distance_tolerance); + ClashingDistances table; bool found=false; std::vector<String>::const_iterator line_iter=stereo_chemical_props_file.begin(); while (line_iter!=stereo_chemical_props_file.end()) { @@ -257,7 +275,7 @@ ClashingDistances FillClashingDistances(std::vector<String>& stereo_chemical_pro std::vector<StringRef> second_line_str_vec = second_line_string_ref.split(); if (second_line_str_vec.size()!=3) { std::cout << "The number of elements in one of the lines is wrong" << std::endl; - return ClashingDistances(min_default_distance,min_distance_tolerance); + return ClashingDistances(); } String item = second_line_str_vec[0].str(); @@ -268,19 +286,19 @@ ClashingDistances FillClashingDistances(std::vector<String>& stereo_chemical_pro value=static_cast<Real>(parse_value.second); } else { std::cout << "One of the distance values is not a number" << std::endl; - return ClashingDistances(min_default_distance,min_distance_tolerance); + return ClashingDistances(); }; if (parse_stddev.first==true) { stddev=static_cast<Real>(parse_stddev.second); } else { std::cout << "One of the tolerance values is not a number" << std::endl; - return ClashingDistances(min_default_distance,min_distance_tolerance); + return ClashingDistances(); } StringRef itemsr(item.data(),item.length()); std::vector<StringRef> eles = itemsr.split('-'); if (itemsr.size() != 3) { std::cout << "One of the strings describing the interacting atoms has the wrong format" << std::endl; - return ClashingDistances(min_default_distance,min_distance_tolerance); + return ClashingDistances(); } String ele1=eles[0].str(); String ele2=eles[1].str(); @@ -298,7 +316,7 @@ ClashingDistances FillClashingDistances(std::vector<String>& stereo_chemical_pro } if (found==false) { std::cout << "Could not find the relevant section in the stereo-chemical parameter file" << std::endl; - return ClashingDistances(min_default_distance,min_distance_tolerance); + return ClashingDistances(); } return table; } @@ -312,6 +330,9 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam int bad_bond_count = 0; int angle_count = 1; int bad_angle_count = 0; + std::map<String,Real> bond_length_sum; + std::map<String,Real> bond_zscore_sum; + std::map<String,int> bond_counter_sum; LOG_INFO("Checking stereo-chemistry") EntityView filtered=ent.CreateEmptyView(); ResidueViewList residues=ent.GetResidueList(); @@ -365,8 +386,19 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam } else { LOG_VERBOSE("BOND:" << " " << res.GetChain() << " " << res.GetName() << " " << res.GetNumber() << " " << bond_str << " " << min_length << " " << max_length << " " << blength << " " << zscore << " " << "PASS") } - bond_count++; - running_sum_zscore_bonds+=zscore; + bond_count++; + running_sum_zscore_bonds+=zscore; + String bond_elems=bond_string_elems(ele1,ele2); + std::map<String,Real>::const_iterator find_be = bond_length_sum.find(bond_elems); + if (find_be==bond_length_sum.end()) { + bond_length_sum[bond_elems]=blength; + bond_zscore_sum[bond_elems]=zscore; + bond_counter_sum[bond_elems]=1; + } else { + bond_length_sum[bond_elems]+=blength; + bond_zscore_sum[bond_elems]+=zscore; + bond_counter_sum[bond_elems]+=1; + } } } @@ -448,6 +480,17 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam Real avg_zscore_angles = running_sum_zscore_angles/static_cast<float>(angle_count); LOG_SCRIPT("Average Z-Score for bond lengths: " << avg_zscore_bonds); LOG_SCRIPT("Bonds outside of tolerance range: " << bad_bond_count << " out of " << bond_count); + LOG_SCRIPT("Bond\tAvg Length\tAvg zscore\tNum Bonds") + + for (std::map<String,Real>::const_iterator bls_it=bond_length_sum.begin();bls_it!=bond_length_sum.end();++bls_it) { + String key = (*bls_it).first; + int counter=bond_counter_sum[key]; + Real sum_bond_length=(*bls_it).second; + Real sum_bond_zscore=bond_zscore_sum[key]; + Real avg_length=sum_bond_length/static_cast<Real>(counter); + Real avg_zscore=sum_bond_zscore/static_cast<Real>(counter); + LOG_SCRIPT(key << "\t" << avg_length << "\t" << avg_zscore << "\t" << counter); + } LOG_SCRIPT("Average Z-Score angle widths: " << avg_zscore_angles); LOG_SCRIPT("Angles outside of tolerance range: " << bad_angle_count << " out of " << angle_count); return filtered; @@ -464,6 +507,7 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis { int distance_count = 0; int bad_distance_count = 0; + Real average_offset_sum = 0.0; LOG_INFO("Filtering non-bonded clashes") EntityView filtered=ent.CreateEmptyView(); ResidueViewList residues=ent.GetResidueList(); @@ -488,9 +532,6 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis for (AtomViewList::iterator k=within.begin(), e3=within.end(); k!=e3; ++k) { AtomView atom2=*k; - - - if (atom2==atom) { continue; } @@ -507,8 +548,6 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis continue; } - - Real d=geom::Length2(atom.GetPos()-atom2.GetPos()); std::pair <Real,Real> distance_tolerance=min_distances.GetClashingDistance(ele1, ele2); Real distance=distance_tolerance.first; @@ -518,6 +557,7 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis if (d<threshold*threshold) { LOG_INFO(atom.GetResidue().GetChain() << " " << atom.GetResidue().GetName() << " " << atom.GetResidue().GetNumber() << " " << atom.GetName() << " " << atom2.GetResidue().GetChain() << " " << atom2.GetResidue().GetName() << " " << atom2.GetResidue().GetNumber() << " " << atom2.GetName() << " " << threshold << " " << sqrt(d) << " " << sqrt(d)-threshold << " " << "FAIL") bad_distance_count++; + average_offset_sum+=sqrt(d)-threshold; remove_sc=true; if (always_remove_bb==true) { remove_bb=true; @@ -551,7 +591,12 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis } filtered.AddResidue(res, ViewAddFlag::INCLUDE_ATOMS); } - LOG_SCRIPT(bad_distance_count << " out of " << distance_count << " non-bonded short-range distances checked shorter than tolerance distance"); + Real average_offset = 0; + if (bad_distance_count!=0) { + average_offset = average_offset_sum / static_cast<Real>(bad_distance_count); + } + LOG_SCRIPT(bad_distance_count << " non-bonded short-range distances shorter than tolerance distance"); + LOG_SCRIPT("Distances shorter than tolerance are on average shorter by: " << average_offset); return filtered; } diff --git a/modules/mol/alg/src/filter_clashes.hh b/modules/mol/alg/src/filter_clashes.hh index 5d64fc23060cdf879c434ccf52c950444b2087d0..64ae81040ed83f0cf00bf5f8beff92979f25b67e 100644 --- a/modules/mol/alg/src/filter_clashes.hh +++ b/modules/mol/alg/src/filter_clashes.hh @@ -24,17 +24,29 @@ namespace ost { namespace mol { namespace alg { +/// \brief List of reference atom-atom distances to detect clashes between non-bonded atoms class ClashingDistances { public: - ClashingDistances(Real default_dist, Real tolerance): default_min_distance_(default_dist), default_min_distance_tolerance_(tolerance), valid_flag_(true) {} + /// \brief Default constructor (creates an empty list) + ClashingDistances(): valid_flag_(true) {} + + /// \brief Adds or replaces an entry + /// + /// Requires an atom-atom distance and a tolerance threshold void SetClashingDistance(const String& ele1,const String& ele2, Real min_distance, Real tolerance); + + /// \brief Recovers a reference distance and a tolerance threshold (respectively) from the list std::pair<Real,Real> GetClashingDistance(const String& ele1,const String& ele2) const; + + /// \brief Recovers the longest distance in the list, corrected by tolerance Real GetMaxAdjustedDistance() const; + + /// \brief Returns true if the list is empty (i.e. in an invalid, useless state) bool IsEmpty() const; - //DEBUG + /// \brief Prints all distances in the list to standard output void PrintAllDistances() const; private: @@ -45,17 +57,33 @@ private: bool valid_flag_; }; - + +/// \brief List of stereo chemical parameters (Bonds and angles) +/// +/// For each item (bond or angle in a specific residue), stores the mean and standard deviation class StereoChemicalParams { public: + /// \brief Adds or replaces an entry void SetParam(const String& param, const String& residue, Real value, Real st_dev); + + /// \brief Recovers mean and standard deviation (respectively) of a stereo⁻chemical item (bond or angle) from the list + /// + /// Item format: Bond: X-Y, Angle:X-Y-Z std::pair<Real,Real> GetParam(const String& element,const String& residue) const; + + /// \brief Checks if the list contains an entry for a specific stereo-chemical item (a bond or atom in a specific residue) + /// + /// Item format: Bond: X-Y, Angle:X-Y-Z bool ContainsParam(const String& param,const String& residue) const; + + /// \brief Returns true if the list is empty (i.e. in an invalid, useless state) + /// + /// Item format: Bond: X-Y, Angle:X-Y-Z bool IsEmpty() const; - //DEBUG + /// \brief Prints all distances in the list to standard output void PrintAllParameters() const; private: @@ -64,15 +92,44 @@ private: }; -ClashingDistances DLLEXPORT_OST_MOL_ALG FillClashingDistances(std::vector<String>& stereo_chemical_props_file, Real min_default_distance, Real min_distance_tolerance); +/// \brief Fills a list of reference clashing distances from the content of a parameter file +/// +/// Requires a list of strings holding the contents of a parameter file, one line per string +ClashingDistances DLLEXPORT_OST_MOL_ALG FillClashingDistances(std::vector<String>& stereo_chemical_props_file); + +/// \brief Fills a list of stereo-chemical statistics from the content of a parameter file +/// +/// Requires a list of strings holding the contents of a parameter file, one line per string +/// The header can be 'Bonds' to read bond statistics or 'Angles' to read angle statistics StereoChemicalParams DLLEXPORT_OST_MOL_ALG FillStereoChemicalParams(const String& header, std::vector<String>& stereo_chemical_props_file); - + +/// \brief Filters a structure based on detected clashes between non bonded atoms. Entity version +/// +/// If a clash between two atoms (distance shorter than reference clashing distance - tolerance threshold) +/// is detected in a residue's side-chain, all atoms in the side chain are removed from the structure +/// If a clash is detected in the backbone, all atoms in the residue are removed. This behavior is changed +/// by the always_remove_bb flag: when the flag is set to true all atoms in the residue are removed even if +/// a clash is just detected in the side-chain EntityView DLLEXPORT_OST_MOL_ALG FilterClashes(const EntityView& ent, const ClashingDistances& min_distances, bool always_remove_bb=false); +/// \brief Filters a structure based on detected clashes between non bonded atoms. Handle version +/// +/// If a clash between two atoms (distance shorter than reference clashing distance - tolerance threshold) +/// is detected in a residue's side-chain, all atoms in the side chain are removed from the structure +/// If a clash is detected in the backbone, all atoms in the residue are removed. This behavior is changed +/// by the always_remove_bb flag: when the flag is set to true all atoms in the residue are removed even if +/// a clash is just detected in the side-chain EntityView DLLEXPORT_OST_MOL_ALG FilterClashes(const EntityHandle& ent, const ClashingDistances& min_distances, bool always_remove_bb=false); +/// \brief Filters a structure based on detected stereo-chemical violations. Entity version +/// +/// If a stereo-chemical violation (i.e., a bond or an angle with a value outside the range defined by +/// the mean value, the standard deviation and the tolerance parameter) is detected in a residue's side-chain, +/// all atoms in the side chain are removed from the structure. If a violation is detected in the backbone, all +/// atoms in the residue are removed. This behavior is changed by the always_remove_bb flag: when the flag is +/// set to true all atoms in the residue are removed even if a violation is just detected in the side-chain EntityView DLLEXPORT_OST_MOL_ALG CheckStereoChemistry(const EntityView& ent, const StereoChemicalParams& bond_table, const StereoChemicalParams& angle_table, @@ -80,6 +137,13 @@ EntityView DLLEXPORT_OST_MOL_ALG CheckStereoChemistry(const EntityView& ent, Real angle_tolerance, bool always_remove_bb=false); +/// \brief Filters a structure based on detected stereo-chemical violations. Handle version +/// +/// If a stereo-chemical violation (i.e., a bond or an angle with a value outside the range defined by +/// the mean value, the standard deviation and the tolerance parameter) is detected in a residue's side-chain, +/// all atoms in the side chain are removed from the structure. If a violation is detected in the backbone, all +/// atoms in the residue are removed. This behavior is changed by the always_remove_bb flag: when the flag is +/// set to true all atoms in the residue are removed even if a violation is just detected in the side-chain EntityView DLLEXPORT_OST_MOL_ALG CheckStereoChemistry(const EntityHandle& ent, const StereoChemicalParams& bond_table, const StereoChemicalParams& angle_table, diff --git a/modules/mol/alg/src/ldt.cc b/modules/mol/alg/src/lddt.cc similarity index 66% rename from modules/mol/alg/src/ldt.cc rename to modules/mol/alg/src/lddt.cc index 48dfc9a6ca3e08762a8356be905867bd3c868678..f619bd52f651824e191c3404e7091b9290149055 100644 --- a/modules/mol/alg/src/ldt.cc +++ b/modules/mol/alg/src/lddt.cc @@ -16,17 +16,19 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ +#include <iomanip> #if defined (_MSC_VER) #define BOOST_ALL_DYN_LINK 1 #endif #include <boost/program_options.hpp> #include <boost/filesystem/fstream.hpp> #include <boost/filesystem/convenience.hpp> -#include <ost/mol/alg/local_dist_test.hh> +#include <ost/mol/alg/local_dist_diff_test.hh> #include <ost/mol/alg/filter_clashes.hh> #include <ost/io/mol/pdb_reader.hh> #include <ost/io/io_exception.hh> #include <ost/conop/conop.hh> +#include <ost/string_ref.hh> #include <ost/conop/amino_acids.hh> #include <ost/mol/iterator.hh> #include <ost/platform.hh> @@ -41,6 +43,7 @@ using namespace ost::mol; using namespace ost::mol::alg; namespace po=boost::program_options; +// loads a file EntityHandle load(const String& file, const IOProfile& profile) { try { @@ -50,6 +53,9 @@ EntityHandle load(const String& file, const IOProfile& profile) reader.Import(ent); conop::Conopology& conop_inst=conop::Conopology::Instance(); conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + if (ent.GetChainList().size()!=1) { + std::cout << "WARNING: File " << file << "has more than one chain" << std::endl; + } return ent; } std::cerr << "ERROR: '" << file << "' does not contain any ATOM records. " @@ -61,9 +67,10 @@ EntityHandle load(const String& file, const IOProfile& profile) } } +// prints usage output void usage() { - std::cerr << "usage: ldt [options] <mod1> [mod1 [mod2]] <ref>" << std::endl; + std::cerr << "usage: lddt [options] <mod1> [mod1 [mod2]] <re1>[,ref2,ref3]" << std::endl; std::cerr << " -s selection performed on ref" << std::endl; std::cerr << " -c use Calphas only" << std::endl; std::cerr << " -f perform structural checks and filter input data" << std::endl; @@ -74,10 +81,12 @@ void usage() std::cerr << " -a <value> tolerance in stddevs for angles" << std::endl; std::cerr << " -m <value> clashing distance for unknwon atom types" << std::endl; std::cerr << " -r <value> distance inclusion radius" << std::endl; + std::cerr << " -i <value> sequence separation" << std::endl; std::cerr << " -e print version" << std::endl; } -std::pair<int,int> compute_coverage (const EntityView& v,const GlobalDistanceList& glob_dist_list) +// computes coverage +std::pair<int,int> compute_coverage (const EntityView& v,const GlobalRDMap& glob_dist_list) { int second=0; int first=0; @@ -85,15 +94,12 @@ std::pair<int,int> compute_coverage (const EntityView& v,const GlobalDistanceLis return std::make_pair<int,int>(0,1); } ChainView vchain=v.GetChainList()[0]; - for (std::vector<ResidueDistanceList>::const_iterator i=glob_dist_list.begin();i!=glob_dist_list.end();++i) + for (GlobalRDMap::const_iterator i=glob_dist_list.begin();i!=glob_dist_list.end();++i) { - ResNum rnum = (*i)[0].GetFirstAtom().GetResNum(); - String rname = (*i)[0].GetFirstAtom().GetResidueName(); - if (IsStandardResidue(rname)) { - second++; - if (vchain.FindResidue(rnum)) { - first++; - } + ResNum rnum = (*i).first; + second++; + if (vchain.FindResidue(rnum)) { + first++; } } return std::make_pair<int,int>(first,second); @@ -101,16 +107,18 @@ std::pair<int,int> compute_coverage (const EntityView& v,const GlobalDistanceLis int main (int argc, char **argv) { - String version = "Beta - 2012-01-17"; - Real min_default_distance = 1.5; - Real min_distance_tolerance = 0.0; + // sets some default values for parameters + String version = "1.2"; Real bond_tolerance = 8.0; Real angle_tolerance = 8.0; - Real radius=15.0; - + Real radius=15.0; + int sequence_separation = 0; + + // creates the required loading profile IOProfile profile; profile.bond_feasibility_check=false; - // parse options + + // parses options String sel; bool structural_checks=false; po::options_description desc("Options"); @@ -124,17 +132,23 @@ int main (int argc, char **argv) ("verbosity,v", po::value<int>(), "verbosity level") ("bond_tolerance,b", po::value<Real>(), "tolerance in stddev for bonds") ("angle_tolerance,a", po::value<Real>(), "tolerance in stddev for angles") - ("default_clash,m", po::value<Real>(), "clashing distance for unknown atom types") ("inclusion_radius,r", po::value<Real>(), "distance inclusion radius") + ("sequence_separation,i", po::value<int>(), "sequence separation") ("files", po::value< std::vector<String> >(), "input file(s)") - ("reference",po::value<String>(),"reference(s)") + ("reference",po::value<String>(),"reference(s)") ; po::positional_options_description p; p.add("files", -1); po::variables_map vm; - po::store(po::command_line_parser(argc, argv). + try { + po::store(po::command_line_parser(argc, argv). options(desc).positional(p).run(), - vm); + vm); + } catch (std::exception& e) { + std::cout << e.what() << std::endl; + usage(); + exit(-1); + } po::notify(vm); if (vm.count("version")) { std::cout << "Version: " << version << std::endl; @@ -158,8 +172,8 @@ int main (int argc, char **argv) } String parameter_filename; if (vm.count("parameter-file")) { - parameter_filename=vm["parameter-file"].as<String>(); - } else if (structural_checks==true) { + parameter_filename=vm["parameter-file"].as<String>(); + } else if (structural_checks==true) { std::cout << "Please specify a stereo-chemical parameter file" << std::endl; exit(-1); } @@ -187,20 +201,57 @@ int main (int argc, char **argv) if (vm.count("angle_tolerance")) { angle_tolerance=vm["angle_tolerance"].as<Real>(); } - if (vm.count("default_clash")) { - min_default_distance=vm["default_clash"].as<Real>(); - } if (vm.count("inclusion_radius")) { radius=vm["inclusion_radius"].as<Real>(); } - String ref_file=files.back(); - EntityHandle ref=load(ref_file, profile); - if (!ref) { - exit(-1); + if (vm.count("sequence_separation")) { + sequence_separation=vm["sequence_separation"].as<int>(); } + + std::vector<Real> cutoffs; + cutoffs.push_back(0.5); + cutoffs.push_back(1.0); + cutoffs.push_back(2.0); + cutoffs.push_back(4.0); + + // loads the reference file and creates the list of distances to check in lddt + // if the reference file is a comma-separated list of files, switches to multi- + // reference mode + GlobalRDMap glob_dist_list; + String ref_file=files.back(); + ost::StringRef ref_file_sr(ref_file.c_str(),ref_file.length()); + std::vector<StringRef> ref_file_split_sr=ref_file_sr.split(','); + if (ref_file_split_sr.size()==1) { + std::cout << "Multi-reference mode: Off" << std::endl; + String ref_filename = ref_file_split_sr[0].str(); + EntityHandle ref=load(ref_filename, profile); + if (!ref) { + exit(-1); + } + glob_dist_list = CreateDistanceList(ref.CreateFullView(),radius); + } else { + std::cout << "Multi-reference mode: On" << std::endl; + std::vector<EntityView> ref_list; + for (std::vector<StringRef>::const_iterator ref_file_split_sr_it = ref_file_split_sr.begin(); + ref_file_split_sr_it != ref_file_split_sr.end();++ref_file_split_sr_it) { + String ref_filename = ref_file_split_sr_it->str(); + EntityHandle ref=load(ref_filename, profile); + if (!ref) { + exit(-1); + } + if (ref_list.size()>0) { + if (ref_list[0].GetChainList()[0].GetName()!=ref.GetChainList()[0].GetName()) { + std::cout << "ERROR: First chains in the reference structures have different names" << std::endl; + exit(-1); + } + } + ref_list.push_back(ref.CreateFullView()); + } + glob_dist_list = CreateDistanceListFromMultipleReferences (ref_list,cutoffs,sequence_separation,radius); + } files.pop_back(); - EntityView ref_view=ref.Select(sel); - GlobalDistanceList glob_dist_list = CreateDistanceList(ref_view,radius); + + // prints out parameters used in the lddt calculation std::cout << "Verbosity level: " << verbosity_level << std::endl; if (structural_checks) { std::cout << "Stereo-chemical and steric clash checks: On " << std::endl; @@ -208,17 +259,19 @@ int main (int argc, char **argv) std::cout << "Stereo-chemical and steric clash checks: Off " << std::endl; } std::cout << "Inclusion Radius: " << radius << std::endl; + std::cout << "Sequence separation: " << sequence_separation << std::endl; if (structural_checks) { std::cout << "Parameter filename: " << parameter_filename << std::endl; std::cout << "Tolerance in stddevs for bonds: " << bond_tolerance << std::endl; std::cout << "Tolerance in stddevs for angles: " << angle_tolerance << std::endl; - std::cout << "Clashing distance for unknown atom types: " << min_default_distance << std::endl; LOG_INFO("Log entries format:"); LOG_INFO("BOND INFO FORMAT: Chain Residue ResNum Bond Min Max Observed Z-score Status"); LOG_INFO("ANGLE INFO FORMAT: Chain Residue ResNum Angle Min Max Observed Z-score Status"); LOG_INFO("CLASH INFO FORMAT: Chain1 Residue1 ResNum1 Atom1 Chain2 Residue2 ResNum2 Atom2 Observed Difference Status"); } - LOG_INFO("LDT INFO FORMAT: Chain1 Residue1 ResNum1 Atom1 Chain2 Residue2 ResNum2 Atom2 ModelDist TargetDist Difference Tolerance Status"); + LOG_INFO("LDDT INFO FORMAT: Chain1 Residue1 ResNum1 Atom1 Chain2 Residue2 ResNum2 Atom2 ModelDist TargetDist Difference Tolerance Status"); + + // cycles through the models to evaluate for (size_t i=0; i<files.size(); ++i) { EntityHandle model=load(files[i], profile); if (!model) { @@ -229,32 +282,18 @@ int main (int argc, char **argv) } EntityView v=model.CreateFullView(); - - // The code in this following block is only used to make CASP9 models load correctly and normally commented out - EntityView model2=model.Select("aname!=CEN,NV,OT1,OT,CAY,CY,OXT,1OCT,NT,OT2,2OCT,OVL1,OC1,O1,OC2,O2,OVU1"); - EntityView v1=model2.Select("not (rname==GLY and aname==CB)"); boost::filesystem::path pathstring(files[i]); - - #if BOOST_FILESYSTEM_VERSION==3 - String filestring=pathstring.filename().string(); + #if BOOST_FILESYSTEM_VERSION==3 || BOOST_VERSION<103400 + String filestring=pathstring.string(); #else String filestring=pathstring.file_string(); #endif - - if (filestring.substr(5,5)=="TS257" || filestring.substr(5,5)=="TS458" ) { - for (AtomHandleIter ait=v1.GetHandle().AtomsBegin();ait!=v1.GetHandle().AtomsEnd();++ait){ - AtomHandle aitv = *ait; - String atomname=aitv.GetName(); - String firstletter=atomname.substr(0,1); - aitv.SetElement(firstletter); - } - } - v=v1; std::cout << "File: " << files[i] << std::endl; std::pair<int,int> cov = compute_coverage(v,glob_dist_list); std::cout << "Coverage: " << (float(cov.first)/float(cov.second)) << " (" << cov.first << " out of " << cov.second << " residues)" << std::endl; if (structural_checks) { + // reads in parameter files boost::filesystem::path loc(parameter_filename); boost::filesystem::ifstream infile(loc); if (!infile) { @@ -279,12 +318,13 @@ int main (int argc, char **argv) exit(-1); } - ClashingDistances nonbonded_table = FillClashingDistances(stereo_chemical_props,min_default_distance,min_distance_tolerance); + ClashingDistances nonbonded_table = FillClashingDistances(stereo_chemical_props); if (nonbonded_table.IsEmpty()) { std::cout << "Error reading the Clashing section of the stereo-chemical parameter file." << std::endl; exit(-1); - } + } + // performs structural checks and filters the structure v=alg::CheckStereoChemistry(v,bond_table,angle_table,bond_tolerance,angle_tolerance); cov = compute_coverage(v,glob_dist_list); std::cout << "Coverage after stereo-chemical checks: " << (float(cov.first)/float(cov.second)) << " (" << cov.first << " out of " << cov.second << " residues)" << std::endl; @@ -293,24 +333,33 @@ int main (int argc, char **argv) std::cout << "Coverage after clashing checks: " << (float(cov.first)/float(cov.second)) << " (" << cov.first << " out of " << cov.second << " residues)" << std::endl; } if (cov.first==0) { - std::cout << "Global LDT score: 0.0" << std::endl; + std::cout << "Global LDDT score: 0.0" << std::endl; return 0; } - Real ldt=LDTHA(v, glob_dist_list); - std::cout << "Global LDT score: " << ldt << std::endl; - std::cout << "Local LDT Score:" << std::endl; - std::cout << "Chain\tResName\tResNum\tScore" << std::endl; - String labels[]={"localldt0.5","localldt1","localldt2","ldtlocal4"}; + // computes the lddt score + String label="localldt"; + std::pair<int,int> total_ov=alg::LocalDistDiffTest(v, glob_dist_list, cutoffs, sequence_separation, label); + Real lddt = static_cast<Real>(total_ov.first)/(static_cast<Real>(total_ov.second) ? static_cast<Real>(total_ov.second) : 1); + std::cout << "Global LDDT score: " << std::setprecision(4) << lddt << std::endl; + std::cout << "(" << std::fixed << total_ov.first << " conserved distances out of " << total_ov.second + << " checked, over " << cutoffs.size() << " thresholds)" << std::endl; + + // prints the residue-by-residue statistics + std::cout << "Local LDDT Score:" << std::endl; + std::cout << "Chain\tResName\tResNum\tScore\t(Conserved/Total, over " << cutoffs.size() << " thresholds)" << std::endl; for (ResidueViewIter rit=v.ResiduesBegin();rit!=v.ResiduesEnd();++rit){ ResidueView ritv = *rit; - Real ldt_local_sum = 0; - if (ritv.HasProp("localldt0.5")) { - for (int n=0; n<4; ++n) { - ldt_local_sum+=ritv.GetFloatProp(labels[n]); - } - ldt_local_sum/=4.0; - std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << ldt_local_sum << std::endl; + Real lddt_local = 0; + int conserved_dist = 0; + int total_dist = 0; + if (ritv.HasProp(label)) { + lddt_local=ritv.GetFloatProp(label); + conserved_dist=ritv.GetIntProp(label+"_conserved"); + total_dist=ritv.GetIntProp(label+"_total"); + } + if (lddt_local!=0) { + std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << std::setprecision(4) << lddt_local << "\t" << "("<< conserved_dist << "/" << total_dist << ")" <<std::endl; } } std::cout << std::endl; diff --git a/modules/mol/alg/src/local_dist_diff_test.cc b/modules/mol/alg/src/local_dist_diff_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..74c6278e2075882cf2a35d32b97d75b742ebb678 --- /dev/null +++ b/modules/mol/alg/src/local_dist_diff_test.cc @@ -0,0 +1,618 @@ +#include <ost/log.hh> +#include <ost/mol/mol.hh> +#include "local_dist_diff_test.hh" +#include <boost/concept_check.hpp> + +namespace ost { namespace mol { namespace alg { + +namespace { + +// helper function +String swapped_name(const String& name) +{ + if (name=="OE1") return "OE2"; + if (name=="OE2") return "OE1"; + + if (name=="OD1") return "OD2"; + if (name=="OD2") return "OD1"; + + if (name=="CG1") return "CG2"; + if (name=="CG2") return "CG1"; + + if (name=="CE1") return "CE2"; + if (name=="CE2") return "CE1"; + + if (name=="CD1") return "CD2"; + if (name=="CD2") return "CD1"; + + if (name=="NH1") return "NH2"; + if (name=="NH2") return "NH1"; + + return name; +} + +// helper function +bool swappable(const String& rname, const String& aname) +{ + if (rname=="GLU") { + return (aname=="OE1" || aname=="OE2"); + } + if (rname=="ASP") { + return (aname=="OD1" || aname=="OD2"); + } + if (rname=="VAL") { + + return (aname=="CG1" || aname=="CG2"); + } + if (rname=="TYR" || rname=="PHE") { + return (aname=="CD1" || aname=="CD2" || aname=="CE1" || aname=="CE2"); + } + if (rname=="LEU") { + return (aname=="CD1" || aname=="CD2"); + } + if (rname=="ARG") { + return (aname=="NH1" || aname=="NH2"); + } + return false; +} + +// helper function +bool within_tolerance(Real mdl_dist, const std::pair<Real,Real>& values, Real tol) +{ + + return (values.first-tol)<=mdl_dist && (values.second+tol)>=mdl_dist; +} + +// helper function +std::pair<long int, long int> calc_overlap1(const ResidueRDMap& res_distance_list, const ResNum& rnum, + ChainView mdl_chain, int sequence_separation, + std::vector<Real>& tol_list, bool only_fixed, + bool swap,std::vector<std::pair<long int, long int> >& overlap_list, bool log ) +{ + std::pair<long int, long int> overlap(0, 0); + ResidueView mdl_res=mdl_chain.FindResidue(rnum); + for (ResidueRDMap::const_iterator ai=res_distance_list.begin(); ai!=res_distance_list.end(); ++ai) { + const UAtomIdentifiers& uais = ai->first; + const std::pair <Real,Real>& values = ai->second; + const UniqueAtomIdentifier& first_atom=uais.first; + const UniqueAtomIdentifier& second_atom=uais.second; + String name=swap ? swapped_name(first_atom.GetAtomName()) : first_atom.GetAtomName(); + AtomView av1=mdl_res ? mdl_res.FindAtom(name) : AtomView(); + + if (only_fixed) { + if (std::abs(first_atom.GetResNum().GetNum()-second_atom.GetResNum().GetNum())<=sequence_separation) { + continue; + } + if (swappable(second_atom.GetResidueName(), second_atom.GetAtomName())) { + continue; + } + } + if (!only_fixed) { + if (first_atom.GetResNum().GetNum()<=(second_atom.GetResNum().GetNum()+sequence_separation)) { + continue; + } + } + ResidueView rv2=mdl_chain.FindResidue(second_atom.GetResNum()); + overlap.second+=tol_list.size(); + int rindex2=0; + int rindex1=mdl_res ? mdl_res.GetIndex() : -1; + if (!only_fixed && rindex1!=-1) + overlap_list[rindex1].second+=tol_list.size(); + if (!rv2) { + continue; + } + rindex2=rv2.GetIndex(); + if (!only_fixed) + overlap_list[rindex2].second+=tol_list.size(); + AtomView av2=rv2.FindAtom(second_atom.GetAtomName()); + if (!(av1 && av2)) { + continue; + } + Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); + std::vector<Real>::const_reverse_iterator rend_it=tol_list.rend(); + for (std::vector<Real>::const_reverse_iterator tol_list_it=tol_list.rbegin();tol_list_it!=rend_it;++tol_list_it) { + Real tol = * tol_list_it; + if (within_tolerance(mdl_dist,values,tol)) { + if (log) { + LOG_VERBOSE("lddt:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() + << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " + << mdl_dist << " " << values.first << " " << values.second << " " << tol << " " << "PASS") + } + overlap.first+=1; + if (!only_fixed) { + overlap_list[rindex1].first+=1; + overlap_list[rindex2].first+=1; + } + } else { + if (log) { + LOG_VERBOSE("lddt:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() + << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " + << mdl_dist << " " << values.first << " " << values.second << " " << tol << " " << "FAIL"); + } + break; + } + } + } + return overlap; +} + +// helper function used by the alignment-based Local Distance Difference Test +std::pair<Real, Real> calc_overlap2(const seq::ConstSequenceHandle& ref_seq, + const seq::ConstSequenceHandle& mdl_seq, + int pos, Real tol, Real max_dist, + bool only_fixed, bool swap) +{ + std::pair<Real, Real> overlap(0.0, 0.0); + EntityView ref=ref_seq.GetAttachedView(); + ResidueView ref_res=ref_seq.GetResidue(pos); + if (!ref_res.IsValid()) { + return std::pair<Real,Real>(0.0, 0.0); + } + AtomViewList ref_atoms=ref_res.GetAtomList(); + ResidueView mdl_res=mdl_seq.GetResidue(pos); + AtomViewList within; + if (max_dist<0) { + within=ref.GetAtomList(); + } + for (AtomViewList::iterator ai=ref_atoms.begin(), + ae=ref_atoms.end(); ai!=ae; ++ai) { + if (ai->GetElement()=="H") { continue; } + String name=swap ? swapped_name(ai->GetName()) : ai->GetName(); + AtomView av1=mdl_res ? mdl_res.FindAtom(name) : AtomView(); + if (max_dist>=0){ + within=ref.FindWithin(ai->GetPos(), max_dist); + } + for (AtomViewList::iterator aj=within.begin(), + ae2=within.end(); aj!=ae2; ++aj) { + if (aj->GetElement()=="H" || + aj->GetResidue().GetChain()!=ai->GetResidue().GetChain()) { + continue; + } + if (only_fixed) { + if (aj->GetResidue().GetNumber()==ref_res.GetNumber()) { + continue; + } + if (swappable(aj->GetResidue().GetName(), aj->GetName())) { + continue; + } + overlap.second+=1.0; + // map from residue index to position in alignment + try { + int aln_pos=ref_seq.GetPos(aj->GetResidue().GetIndex()); + ResidueView r2=mdl_seq.GetResidue(aln_pos); + if (!r2.IsValid()) { + continue; + } + AtomView av2=r2.FindAtom(aj->GetName()); + if (!(av1 && av2)) { + continue; + } + Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); + Real ref_dist=geom::Length(ai->GetPos()-aj->GetPos()); + if (std::abs(mdl_dist-ref_dist)<tol) { + overlap.first+=1; + } + } catch(...) { } + continue; + } else { + if (aj->GetResidue().GetNumber()>ref_res.GetNumber()) { + overlap.second+=1.0; + + try { + int aln_pos=ref_seq.GetPos(aj->GetResidue().GetIndex()); + ResidueView r2=mdl_seq.GetResidue(aln_pos); + if (!r2.IsValid()) { + continue; + } + AtomView av2=r2.FindAtom(aj->GetName()); + if (!(av1 && av2)) { + continue; + } + Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); + Real ref_dist=geom::Length(ai->GetPos()-aj->GetPos()); + if (std::abs(mdl_dist-ref_dist)<tol) { + overlap.first+=1; + } + } catch (...) { } + } + } + } + } + return overlap; +} + +// for each residue with multiple possible nomenclature conventions, checks which choice (switched or not) +// of atom nomenclature gives the highest lddt score then changes the naming convention of the input +// entity view accordingly +void check_and_swap(const GlobalRDMap& glob_dist_list, const EntityView& mdl, std::vector<Real> cutoff_list, int sequence_separation, std::vector<std::pair<long int, long int> > overlap_list) +{ + ChainView mdl_chain=mdl.GetChainList()[0]; + XCSEditor edi=mdl.GetHandle().EditXCS(BUFFERED_EDIT); + for (GlobalRDMap::const_iterator i=glob_dist_list.begin(); i!=glob_dist_list.end(); ++i) { + ResNum rnum = i->first; + if (i->second.size()==0) { + continue; + } + ResidueView mdl_res=mdl_chain.FindResidue(rnum); + if (!mdl_res) { + continue; + } + String rname = mdl_res.GetName(); + if (!(rname=="GLU" || rname=="ASP" || rname=="VAL" || rname=="TYR" || + rname=="PHE" || rname=="LEU" || rname=="ARG")) { + continue; + } + std::pair<long int, long int> ov1=calc_overlap1(i->second, rnum,mdl_chain, sequence_separation, + cutoff_list, true, + false, overlap_list,false); + + std::pair<long int, long int> ov2=calc_overlap1(i->second, rnum, mdl_chain, sequence_separation, + cutoff_list, true, + true, overlap_list,false); + + if (static_cast<Real>(ov1.first)/ov1.second< + static_cast<Real>(ov2.first)/ov2.second) { + AtomViewList atoms=mdl_res.GetAtomList(); + for (AtomViewList::iterator j=atoms.begin(), e2=atoms.end(); j!=e2; ++j) { + if (swappable(rname, j->GetName())) { + edi.RenameAtom(j->GetHandle(), swapped_name(j->GetName())); + } + } + } + } +} + +// helper function to update existence map entries for multiple reference input structures +void update_existence_map (ExistenceMap& ex_map, const EntityView& ev, int ref_counter) +{ + AtomViewList ev_atom=ev.GetAtomList(); + for (AtomViewList::iterator ev_atom_it=ev_atom.begin(); ev_atom_it!=ev_atom.end();++ev_atom_it) { + UniqueAtomIdentifier uai (ev_atom_it->GetResidue().GetChain().GetName(),ev_atom_it->GetResidue().GetNumber(),ev_atom_it->GetResidue().GetName(),ev_atom_it->GetName()); + ex_map[uai] |=1 << ref_counter; + } +} + +// helper function for super-fast lookup of atom existence in multiple reference input structures +int in_existence_map(const ExistenceMap& ex_map, const UniqueAtomIdentifier& uai) +{ + ExistenceMap::const_iterator find_uai_ci = ex_map.find(uai); + return find_uai_ci!=ex_map.end() ? find_uai_ci->second : 0; +} + +// merges distance lists from multiple reference structures. The login is described in the code +void merge_distance_lists(GlobalRDMap& ref_dist_map, const GlobalRDMap& new_dist_map, ExistenceMap& ex_map, const EntityView& ref,int ref_counter) +{ + // iterate over the residues in the ref_dist_map + for (GlobalRDMap::iterator ref_dist_map_it=ref_dist_map.begin();ref_dist_map_it!=ref_dist_map.end();++ref_dist_map_it) { + ResNum ref_resnum = ref_dist_map_it->first; + GlobalRDMap::const_iterator find_new_res_ci = new_dist_map.find(ref_resnum); + //if the residue is found in new_dist_map, + if (find_new_res_ci != new_dist_map.end()) { + //iterate over the the reference distances in the ResidueDistanceMap + //It's on purpose that we don't increase the loop variable inside + //the for statement! This is required to make iteration work when erasing + //an element from the map while iterating over it. + for (ResidueRDMap::iterator + ref_res_map_it = ref_dist_map_it->second.begin(); + ref_res_map_it!=ref_dist_map_it->second.end();) { + const UAtomIdentifiers& ref_rd = ref_res_map_it->first; + bool erased=false; + std::pair<Real,Real>& ref_minmax = ref_res_map_it->second; + ResidueRDMap::const_iterator find_new_rd_ci = find_new_res_ci->second.find(ref_rd); + // if you find the distance in the residue new, udate min and max + if (find_new_rd_ci != find_new_res_ci->second.end()) { + if (find_new_rd_ci->second.first < ref_minmax.first) { + ref_minmax.first=find_new_rd_ci->second.first; + } else if (find_new_rd_ci->second.second > ref_minmax.second) { + ref_minmax.second=find_new_rd_ci->second.second; + } + } else { + // if you don't find it in the residue new, check that it is not missing because it is too long + UniqueAtomIdentifier first_atom_to_find = ref_rd.first; + UniqueAtomIdentifier second_atom_to_find = ref_rd.second; + // if both atoms are there, remove the distance from the ref_dist_map, + if ((ref.FindAtom(first_atom_to_find.GetChainName(),first_atom_to_find.GetResNum(),first_atom_to_find.GetAtomName()).IsValid() && + ref.FindAtom(second_atom_to_find.GetChainName(),second_atom_to_find.GetResNum(),second_atom_to_find.GetAtomName()).IsValid()) ) { + erased=true; + ref_dist_map_it->second.erase(ref_res_map_it++); + } + } + if (!erased) { + ++ref_res_map_it; + } + } + // now iterate over the the new reference distances in residue new + for (ResidueRDMap::const_iterator new_res_map_it = find_new_res_ci->second.begin(); new_res_map_it!=find_new_res_ci->second.end();++new_res_map_it) { + UAtomIdentifiers new_rd = new_res_map_it->first; + std::pair<Real,Real> new_minmax = new_res_map_it->second; + ResidueRDMap::const_iterator find_ref_rd_ci = ref_dist_map_it->second.find(new_rd); + // if the distance is found in the residue ref, + // it has been taken care of before. If not + if (find_ref_rd_ci==ref_dist_map_it->second.end()) { + UniqueAtomIdentifier first_atom_to_find = new_rd.first; + UniqueAtomIdentifier second_atom_to_find = new_rd.second; + // check that there isn't a structure already processed where both atoms are in + // if there is none, add the distance to the residue ref map + if (!(in_existence_map(ex_map,first_atom_to_find) & in_existence_map(ex_map,second_atom_to_find))) { + ref_dist_map_it->second[new_rd]= new_minmax; + } + } + } + } + // if the residue was not found in the new list, it means that it is + // absent in the new structure, no new information + } + // now iterate over the residues in the new_list + for (GlobalRDMap::const_iterator new_dist_map_it=new_dist_map.begin();new_dist_map_it!=new_dist_map.end();++new_dist_map_it) { + ResNum new_resnum = new_dist_map_it->first; + GlobalRDMap::const_iterator find_ref_res_ci = ref_dist_map.find(new_resnum); + // if the residue is found in new_dist_map, it has been taken care before, + // if not, add it to the res_dist_map: + if (find_ref_res_ci == ref_dist_map.end()) { + ref_dist_map[new_resnum] = new_dist_map_it->second; + } + } +} + +} + +// helper function +bool IsStandardResidue(String rn) +{ + String upper_rn=rn; + std::transform(rn.begin(),rn.end(),rn.begin(),toupper); + if (upper_rn == "ALA" || + upper_rn == "ARG" || + upper_rn == "ASN" || + upper_rn == "ASP" || + upper_rn == "GLN" || + upper_rn == "GLU" || + upper_rn == "LYS" || + upper_rn == "SER" || + upper_rn == "CYS" || + upper_rn == "TYR" || + upper_rn == "TRP" || + upper_rn == "THR" || + upper_rn == "VAL" || + upper_rn == "ILE" || + upper_rn == "MET" || + upper_rn == "LEU" || + upper_rn == "GLY" || + upper_rn == "PRO" || + upper_rn == "HIS" || + upper_rn == "PHE") { + return true; + } + return false; +} + + +GlobalRDMap CreateDistanceList(const EntityView& ref,Real max_dist) +{ + GlobalRDMap dist_list; + ResidueViewList ref_residues=ref.GetChainList()[0].GetResidueList(); + for (ResidueViewList::iterator i=ref_residues.begin(), e=ref_residues.end(); i!=e; ++i) { + if (IsStandardResidue(i->GetName())) { + ResidueRDMap res_dist_list; + ResNum rnum = i->GetNumber(); + AtomViewList ref_atoms=i->GetAtomList(); + AtomViewList within; + if (max_dist<0){ + within=ref.GetAtomList(); + } + for (AtomViewList::iterator ai=ref_atoms.begin(), ae=ref_atoms.end(); ai!=ae; ++ai) { + UniqueAtomIdentifier first_atom(ai->GetResidue().GetChain().GetName(),ai->GetResidue().GetNumber(),ai->GetResidue().GetName(),ai->GetName()); + if (ai->GetElement()=="H") { continue; } + if (max_dist>=0){ + within=ref.FindWithin(ai->GetPos(), max_dist); + } + for (AtomViewList::iterator aj=within.begin(), ae2=within.end(); aj!=ae2; ++aj) { + UniqueAtomIdentifier second_atom(aj->GetResidue().GetChain().GetName(),aj->GetResidue().GetNumber(),aj->GetResidue().GetName(),aj->GetName()); + if (aj->GetElement()=="H" || + aj->GetResidue().GetChain()!=ai->GetResidue().GetChain()) { + continue; + } + Real dist=geom::Length(ai->GetPos()-aj->GetPos()); + UAtomIdentifiers atoms = std::make_pair<UniqueAtomIdentifier,UniqueAtomIdentifier>(first_atom,second_atom); + std::pair<Real,Real> values = std::make_pair<Real,Real>(dist,dist); + res_dist_list[atoms]=values; + } + } + dist_list[rnum]=res_dist_list; + } + } + return dist_list; +} + +GlobalRDMap CreateDistanceListFromMultipleReferences(const std::vector<EntityView>& ref_list, std::vector<Real>& cutoff_list, int sequence_separation, Real max_dist) +{ + int ref_counter=0; + ExistenceMap ex_map; + GlobalRDMap glob_dist_list = CreateDistanceList(ref_list[0],max_dist); + update_existence_map (ex_map,ref_list[0],ref_counter); + ref_counter++; + for (std::vector<EntityView>::const_iterator ref_list_it=ref_list.begin()+1;ref_list_it!=ref_list.end();++ref_list_it) { + EntityView ref = *ref_list_it; + std::vector<std::pair<long int, long int> > overlap_list(ref.GetResidueCount(), std::pair<long int, long int>(0, 0)); + check_and_swap(glob_dist_list,ref,cutoff_list,sequence_separation,overlap_list); + GlobalRDMap new_dist_list=CreateDistanceList(ref,max_dist); + merge_distance_lists(glob_dist_list,new_dist_list,ex_map,ref,ref_counter); + update_existence_map (ex_map,ref,ref_counter); + ref_counter++; + } + return glob_dist_list; +} + +void PrintResidueRDMap(const ResidueRDMap& res_dist_list) +{ + for (ResidueRDMap::const_iterator res_dist_list_it = res_dist_list.begin();res_dist_list_it!=res_dist_list.end();++res_dist_list_it) { + UAtomIdentifiers uais = res_dist_list_it->first; + std::pair<Real,Real> minmax = res_dist_list_it->second; + std::cout << uais.first.GetChainName() << " " << uais.first.GetResNum() << " " << uais.first.GetResidueName() << " " << uais.first.GetAtomName() << " " << + uais.second.GetChainName() << " " << uais.second.GetResNum() << " " << uais.second.GetResidueName() << " " << uais.second.GetAtomName() << " " << + minmax.first << " " << minmax.second << std::endl; + } +} + + +void PrintGlobalRDMap(const GlobalRDMap& glob_dist_list){ + for (GlobalRDMap::const_iterator glob_dist_list_it = glob_dist_list.begin();glob_dist_list_it!=glob_dist_list.end();++glob_dist_list_it) { + if (glob_dist_list_it->second.size()!=0) { + PrintResidueRDMap(glob_dist_list_it->second); + } + } +} + + + +std::pair<long int,long int> LocalDistDiffTest(const EntityView& mdl, const GlobalRDMap& glob_dist_list, + std::vector<Real> cutoff_list, int sequence_separation, const String& local_lddt_property_string) +{ + if (!mdl.GetResidueCount()) { + LOG_WARNING("model structures doesn't contain any residues"); + return std::make_pair<long int,long int>(0,0); + } + if (glob_dist_list.size()==0) { + LOG_WARNING("global reference list is empty"); + return std::make_pair<long int,long int>(0,0); + } + std::vector<std::pair<long int, long int> > overlap_list(mdl.GetResidueCount(), std::pair<long int, long int>(0, 0)); + check_and_swap(glob_dist_list,mdl,cutoff_list,sequence_separation,overlap_list); + ChainView mdl_chain=mdl.GetChainList()[0]; + overlap_list.clear(); + std::pair<long int, long int> total_ov(0, 0); + for (GlobalRDMap::const_iterator i=glob_dist_list.begin(), e=glob_dist_list.end(); i!=e; ++i) { + ResNum rn = i->first; + if (i->second.size()!=0) { + std::pair<long int, long int> ov1=calc_overlap1(i->second, rn, mdl_chain, sequence_separation, cutoff_list, + false, false, overlap_list,true); + total_ov.first+=ov1.first; + total_ov.second+=ov1.second; + } + + } + for (GlobalRDMap::const_iterator i=glob_dist_list.begin(), + e=glob_dist_list.end();i!=e; ++i) { + ResNum rn = i->first; + if(local_lddt_property_string!="") { + ResidueView mdlr=mdl_chain.FindResidue(rn); + if (mdlr.IsValid()) { + int mdl_res_index =mdlr.GetIndex(); + Real local_lddt=static_cast<Real>(overlap_list[mdl_res_index].first)/(static_cast<Real>(overlap_list[mdl_res_index].second) ? static_cast<Real>(overlap_list[mdl_res_index].second) : 1); + mdlr.SetFloatProp(local_lddt_property_string, local_lddt); + mdlr.SetIntProp(local_lddt_property_string+"_conserved", overlap_list[mdl_res_index].first); + mdlr.SetIntProp(local_lddt_property_string+"_total", overlap_list[mdl_res_index].second); + } + } + } + overlap_list.clear(); + return std::make_pair<long int,long int>(total_ov.first,total_ov.second); +} + +Real LocalDistDiffTest(const EntityView& mdl, const EntityView& target, Real cutoff, Real max_dist, const String& local_lddt_property_string) +{ + std::vector<Real> cutoffs; + cutoffs.push_back(cutoff); + GlobalRDMap glob_dist_list = CreateDistanceList(target,max_dist); + int sequence_separation = 0; + std::pair<long int,long int> total_ov = LocalDistDiffTest(mdl, glob_dist_list, cutoffs, sequence_separation, local_lddt_property_string); + return static_cast<Real>(total_ov.first)/(static_cast<Real>(total_ov.second) ? static_cast<Real>(total_ov.second) : 1); +} + + +Real LocalDistDiffTest(const ost::seq::AlignmentHandle& aln, + Real cutoff, Real max_dist, int ref_index, int mdl_index) +{ + seq::ConstSequenceHandle ref_seq=aln.GetSequence(ref_index); + seq::ConstSequenceHandle mdl_seq=aln.GetSequence(mdl_index); + if (!ref_seq.HasAttachedView()) { + LOG_ERROR("reference sequence doesn't have a view attached."); + return 0.0; + } + if (!mdl_seq.HasAttachedView()) { + LOG_ERROR("model sequence doesn't have a view attached"); + return 0.0; + } + XCSEditor edi=ref_seq.GetAttachedView().GetHandle().EditXCS(BUFFERED_EDIT); + for (int i=0; i<aln.GetLength(); ++i) { + ResidueView mdl_res=mdl_seq.GetResidue(i); + if (!mdl_res) { + continue; + } + String rname=mdl_res.GetName(); + if (!(rname=="GLU" || rname=="ASP" || rname=="VAL" || rname=="TYR" || + rname=="PHE" || rname=="LYS" || rname=="ARG")) { + continue; + } + std::pair<Real, Real> ov1=calc_overlap2(ref_seq, mdl_seq, i, + cutoff, max_dist, true, + false); + std::pair<Real, Real> ov2=calc_overlap2(ref_seq, mdl_seq, i, + cutoff, max_dist, true, + true); + if (ov1.first/ov1.second<ov2.first/ov2.second) { + AtomViewList atoms=mdl_res.GetAtomList(); + for (AtomViewList::iterator j=atoms.begin(), + e2=atoms.end(); j!=e2; ++j) { + if (swappable(rname, j->GetName())) { + edi.RenameAtom(j->GetHandle(), swapped_name(j->GetName())); + } + } + } + } + std::pair<Real, Real> total_ov(0.0, 0.0); + for (int i=0; i<aln.GetLength(); ++i) { + std::pair<Real, Real> ov1=calc_overlap2(ref_seq, mdl_seq, i, cutoff, + max_dist, false, false); + total_ov.first+=ov1.first; + total_ov.second+=ov1.second; + } + return total_ov.first/(total_ov.second ? total_ov.second : 1); +} + +Real LDDTHA(EntityView& v, const GlobalRDMap& global_dist_list, int sequence_separation) +{ + std::vector<Real> cutoffs; + cutoffs.push_back(0.5); + cutoffs.push_back(1.0); + cutoffs.push_back(2.0); + cutoffs.push_back(4.0); + String label="locallddt"; + std::pair<long int,long int> total_ov=alg::LocalDistDiffTest(v, global_dist_list, cutoffs, sequence_separation, label); + return static_cast<Real>(total_ov.first)/(static_cast<Real>(total_ov.second) ? static_cast<Real>(total_ov.second) : 1); +} + +// debugging code +/* +Real OldStyleLDDTHA(EntityView& v, const GlobalRDMap& global_dist_list) +{ + Real lddt =0; + std::vector<Real> cutoffs05; + cutoffs05.push_back(0.5); + std::pair<Real,Real> lddt05o=alg::LocalDistDiffTest(v, global_dist_list, cutoffs05, "locallddt0.5"); + std::vector<Real> cutoffs1; + cutoffs1.push_back(1.0); + std::pair<Real,Real> lddt1o=alg::LocalDistDiffTest(v, global_dist_list, cutoffs1, "locallddt1"); + std::vector<Real> cutoffs2; + cutoffs2.push_back(2.0); + std::pair<Real,Real> lddt2o=alg::LocalDistDiffTest(v, global_dist_list, cutoffs2, "locallddt2"); + std::vector<Real> cutoffs4; + cutoffs4.push_back(4.0); + std::pair<Real,Real> lddt4o=alg::LocalDistDiffTest(v, global_dist_list, cutoffs4, "locallddt4"); + Real lddt05 = lddt05o.first/(lddt05o.second ? lddt05o.second : 1); + Real lddt1 = lddt1o.first/(lddt1o.second ? lddt1o.second : 1); + Real lddt2 = lddt2o.first/(lddt2o.second ? lddt2o.second : 1); + Real lddt4 = lddt4o.first/(lddt4o.second ? lddt4o.second : 1); + lddt = (lddt05+lddt1+lddt2+lddt4)/4.0; + for (ResidueViewIter rit=v.ResiduesBegin();rit!=v.ResiduesEnd();++rit){ + ResidueView ritv = *rit; + if (ritv.HasProp("locallddt0.5")) { + Real lddt_local = (ritv.GetFloatProp("locallddt0.5")+ritv.GetFloatProp("locallddt1")+ritv.GetFloatProp("locallddt2")+ritv.GetFloatProp("locallddt4"))/4.0; + ritv.SetFloatProp("locallddt",lddt_local); + } + } + return lddt; +} +*/ + +}}} diff --git a/modules/mol/alg/src/local_dist_diff_test.hh b/modules/mol/alg/src/local_dist_diff_test.hh new file mode 100644 index 0000000000000000000000000000000000000000..ed6e10badd68fc0ba760350f1d7c1551428f2d79 --- /dev/null +++ b/modules/mol/alg/src/local_dist_diff_test.hh @@ -0,0 +1,212 @@ +//------------------------------------------------------------------------------ +// 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 +//------------------------------------------------------------------------------ +#ifndef OST_MOL_ALG_LOCAL_DIST_TEST_HH +#define OST_MOL_ALG_LOCAL_DIST_TEST_HH + +#include <ost/mol/entity_view.hh> +#include <ost/mol/alg/module_config.hh> +#include <ost/seq/alignment_handle.hh> + +namespace ost { namespace mol { namespace alg { + +/// \brief Contains the infomation needed to uniquely identify an atom in a structure +/// +/// Used by the the Local Distance Difference Test classes and functions +class UniqueAtomIdentifier +{ + +public: + /// \brief Constructor with all the relevant information + UniqueAtomIdentifier(const String& chain,const ResNum& residue,const String& residue_name, const String& atom): chain_(chain),residue_(residue),residue_name_(residue_name),atom_(atom) {} + + // to make the compiler happy (boost python map suite) + UniqueAtomIdentifier(): chain_(""),residue_(ResNum(1)),residue_name_(""),atom_("") {} + + /// \brief Returns the name of the chain to which the atom belongs, as a String + String GetChainName() const { return chain_; } + + /// \brief Returns the ResNum of the residue to which the atom belongs + ResNum GetResNum() const { return residue_; } + + /// \brief Returns the name of the residue to which the atom belongs, as a String + String GetResidueName() const { return residue_name_; } + + /// \brief Returns the name of the atom, as a String + String GetAtomName() const { return atom_; } + + // required because UniqueAtomIdentifier is used as a key for a std::map + bool operator==(const UniqueAtomIdentifier& rhs) const { + return chain_==rhs.chain_ && residue_==rhs.residue_ && atom_==rhs.atom_; + } + + // required because UniqueAtomIdentifier is used as a key for a std::map + bool operator<(const UniqueAtomIdentifier& rhs) const { + int cc=chain_.compare(rhs.chain_); + if (cc) { + return cc<0; + } + if (residue_<rhs.residue_) { + return true; + } else if (residue_>rhs.residue_) { + return false; + } + return atom_.compare(rhs.atom_)<0; + } +private: + + String chain_; + ResNum residue_; + String residue_name_; + String atom_; +}; + +// typedef used to make the code cleaner +typedef std::pair<UniqueAtomIdentifier,UniqueAtomIdentifier> UAtomIdentifiers; + +/// \brief Residue distance list. +/// +/// Container for all the interatomic distances that are checked in a Local Distance Difference Test +/// and are originating from a single specific residue +typedef std::map<std::pair<UniqueAtomIdentifier,UniqueAtomIdentifier>,std::pair<Real,Real> > ResidueRDMap; + +/// \brief Global distance list. +/// +/// Container for all the residue-based interatomic distance lists that are checked in a Local Distance Difference Test +/// and belong to the same structure +typedef std::map<ost::mol::ResNum,ResidueRDMap> GlobalRDMap; + +// used by the multi-reference distance-list generator function +typedef std::map<UniqueAtomIdentifier,int> ExistenceMap; + +/// \brief Calculates number of distances conserved in a model, given a list of distances to check and a model +/// +/// Calculates the two values needed to determine the Local Distance Difference Test for a given model, i.e. +/// the number of conserved distances in the model and the number of total distances in the reference structure. +/// The function requires a list of distances to check, a model on which the distances are checked, and a +/// list of tolerance thresholds that are used to determine if the distances are conserved. +/// +/// The function only processes standard residues in the first chains of the model and of the reference +/// For residues with symmetric sidechains (GLU, ASP, ARG, VAL, PHE, TYR), the +/// naming of the atoms is ambigous. For these residues, the function computes the Local Distance Difference +/// Test score that each naming convention would generate when considering all non-ambigous surrounding atoms. +/// The solution that gives higher score is then picked to compute the final Local Difference +/// Distance Score for the whole model. +/// +/// A sequence separation parameter can be passed to the function. If this happens, only distances between residues +/// whose separation is higher than the provided parameter are considered when computing the score. +/// +/// If a string is provided as an argument to the function, residue-per-residue statistics are stored as +/// residue properties. Specifically, the local residue-based lddt score is stored in a float property named +/// as the provided string, while the residue-based number of conserved and total distances are saved in two +/// int properties named <string>_conserved and <string>_total. +std::pair<long int,long int> DLLEXPORT_OST_MOL_ALG LocalDistDiffTest(const EntityView& mdl, + const GlobalRDMap& dist_list, + std::vector<Real> cutoff_list, + int sequence_separation = 0, + const String& local_ldt_property_string=""); + +/// \brief Calculates the Local Distance Difference Score for a given model with respect to a given target +/// +/// Calculates the Local Distance Difference Test score for a given model with respect to a given reference structure. Requires +/// a model, a reference structure, a list of thresholds that are used to determine if distances are conserved, and an inclusion +/// radius value used to determine which distances are checked. +/// +/// The function only processes standard residues in the first chains of the model and of the reference +/// For residues with symmetric sidechains (GLU, ASP, ARG, VAL, PHE, TYR), the +/// naming of the atoms is ambigous. For these residues, the function computes the Local Distance Difference +/// Test score that each naming convention would generate when considering all non-ambigous surrounding atoms. +/// The solution that gives higher score is then picked to compute the final Local Difference +/// Distance Score for the whole model. +/// +/// If a string is provided as an argument to the function, residue-per-residue statistics are stored as +/// residue properties. Specifically, the local residue-based lddt score is stored in a float property named +/// as the provided string, while the residue-based number of conserved and total distances are saved in two +/// int properties named <string>_conserved and <string>_total. +Real DLLEXPORT_OST_MOL_ALG LocalDistDiffTest(const EntityView& mdl, + const EntityView& target, + Real cutoff, + Real max_dist, + const String& local_ldt_property_string=""); +/// \brief Calculates the Local Distance Difference Test score for a given model starting from an alignment between a reference structure and the model. +/// +/// Calculates the Local Distance Difference Test score given an alignment between a model and a taget structure. +/// Requires a threshold on which to calculate the score and an inclusion radius to determine the interatiomic +/// distances to check. Obviously, the strucvtures of the model and the reference must be attached to the alignment. +/// By default the first structure in the alignment is considered the reference and the second is considered the +/// model, but this can be changed by passing to the function the indexes of the two structures in the ref_index +/// and mdl_index parameters. +/// BEWARE: This algorithm uses the old version of the Local Distance Difference Test +/// (multiple cycles, single threshold, etc. ) and will give a slightly different result than the other functions +Real DLLEXPORT_OST_MOL_ALG LocalDistDiffTest(const ost::seq::AlignmentHandle& aln, + Real cutoff, Real max_dist, + int ref_index=0, int mdl_index=1); + +/// \brief Computes the Local Distance Difference High-Accuracy Test given a list of distances to check +/// +/// Computes the Local Distance Difference High-Accuracy Test (with threshold 0.5,1,2 and 4 Angstrom) +/// Requires a list of distances to check and a model for which the score is computed +/// +/// A sequence separation parameter can be passed to the function. If this happens, only distances between residues +/// whose separation is higher than the provided parameter are considered when computing the score. +Real DLLEXPORT_OST_MOL_ALG LDDTHA(EntityView& v, const GlobalRDMap& global_dist_list, int sequence_separation=0); + +/// \brief Creates a list of distances to check during a Local Difference Distance Test +/// +/// Requires a reference structure and an inclusion radius (max_dist) +GlobalRDMap CreateDistanceList(const EntityView& ref,Real max_dist); + +/// \brief Creates a list of distances to check during a Local Difference Distance Test starting from multiple reference structures +/// +/// Requires a list of reference structure and an inclusion radius (max_dist). +/// +/// The structures in the list have to be properly prepared before being passed +/// to the function. Corresponding residues in the structures must have the same residue number, the same chain name, +/// etc. Gaps are allowed and automatically dealt with: if information about a distance is present in at least one of +/// the structures, it will be considered. +/// +/// +/// If a distance between two atoms is shorter than the inclusion radius in all structures in which the two atoms are +/// present, it is included in the list. However, if the distance is longer than the inclusion radius in at least one +/// of the structures, it is not be considered a local interaction and is exluded from the list +/// +/// The function takes care of residues with ambigous symmetric sidechains. To decide which naming convention to use, the functions +/// computes a local distance score of each reference structure with the first reference structure in the list, using only non ambigously-named atoms. +/// It picks then the naming convention that gives the highest score, guaranteeing that all references are processed with the correct atom names. +/// +/// The cutoff list that will later be used to compute the Local Distance Difference Test score and the sequence separation parameter +/// must be passed to the function. These parameters do not influence the output distance list, which always includes all distances +/// within the provided max_dist (to make it consistent with the single-reference corresponding function). However, the parameters are used when +/// dealing with the naming convention of residues with ambiguous nomenclature. +GlobalRDMap CreateDistanceListFromMultipleReferences(const std::vector<EntityView>& ref_list,std::vector<Real>& cutoff_list, int sequence_separation, Real max_dist); + +/// \brief Prints all distances in a global distance list to standard output +void PrintGlobalRDMap(const GlobalRDMap& glob_dist_list); + +/// \brief Prints all distances in a residue distance list to standard output +void PrintResidueRDMap(const ResidueRDMap& res_dist_list); + +// required by some helper function. Cannot reuse similar functions in other modules without creating +// circular dependencies +bool IsStandardResidue(String rn); + +}}} + +#endif + + diff --git a/modules/mol/alg/src/local_dist_test.cc b/modules/mol/alg/src/local_dist_test.cc deleted file mode 100644 index 430dd31bebb4e5c5bea26461df9b253e8bc0d608..0000000000000000000000000000000000000000 --- a/modules/mol/alg/src/local_dist_test.cc +++ /dev/null @@ -1,492 +0,0 @@ -#include <ost/log.hh> -#include <ost/mol/mol.hh> -#include "local_dist_test.hh" -#include <boost/concept_check.hpp> - -namespace ost { namespace mol { namespace alg { - -namespace { - -String swapped_name(const String& name) -{ - if (name=="OE1") return "OE2"; - if (name=="OE2") return "OE1"; - - if (name=="OD1") return "OD2"; - if (name=="OD2") return "OD1"; - - if (name=="CG1") return "CG2"; - if (name=="CG2") return "CG1"; - - if (name=="CE1") return "CE2"; - if (name=="CE2") return "CE1"; - - if (name=="CD1") return "CD2"; - if (name=="CD2") return "CD1"; - - if (name=="NH1") return "NH2"; - if (name=="NH2") return "NH1"; - - return name; -} - -bool swappable(const String& rname, const String& aname) -{ - if (rname=="GLU") { - return (aname=="OE1" || aname=="OE2"); - } - if (rname=="ASP") { - return (aname=="OD1" || aname=="OD2"); - } - if (rname=="VAL") { - - return (aname=="CG1" || aname=="CG2"); - } - if (rname=="TYR" || rname=="PHE") { - return (aname=="CD1" || aname=="CD2" || aname=="CE1" || aname=="CE2"); - } - if (rname=="ARG") { - return (aname=="NH1" || aname=="NH2"); - } - return false; -} - -std::pair<bool,Real> within_tolerance(Real mdl_dist, const ReferenceDistance& ref_dist, Real tol) -{ - Real min = ref_dist.GetMaxDistance(); - Real max = ref_dist.GetMaxDistance(); - bool within_tol = false; - Real difference = 0; - if (mdl_dist>=min && mdl_dist <=max) { - within_tol=true; - } else if (mdl_dist < min && std::abs(min-mdl_dist) < tol) { - within_tol = true; - } else if (mdl_dist > max && std::abs(mdl_dist-max) < tol) { - within_tol = true; - } - if (within_tol == false) { - if (mdl_dist > max) { - difference = mdl_dist-(max+tol); - } else { - difference = mdl_dist-(min-tol); - } - } - return std::make_pair<bool,Real>(within_tol,difference); -} - - -std::pair<Real, Real> calc_overlap1(const ResidueDistanceList& res_distance_list, - ChainView mdl_chain, - Real tol, bool only_fixed, - bool swap,std::vector<std::pair<Real, Real> >& overlap_list, bool log ) -{ - std::pair<Real, Real> overlap(0.0, 0.0); - - ResidueView mdl_res=mdl_chain.FindResidue(res_distance_list[0].GetFirstAtom().GetResNum()); - for (ResidueDistanceList::const_iterator ai=res_distance_list.begin(), - ae=res_distance_list.end(); ai!=ae; ++ai) { - UniqueAtomIdentifier first_atom=ai->GetFirstAtom(); - UniqueAtomIdentifier second_atom=ai->GetSecondAtom(); - String name=swap ? swapped_name(first_atom.GetAtomName()) : first_atom.GetAtomName(); - AtomView av1=mdl_res ? mdl_res.FindAtom(name) : AtomView(); - - if (only_fixed) { - if (swappable(second_atom.GetResidueName(), second_atom.GetAtomName())) { - continue; - } - AtomView av2=mdl_chain.FindAtom(second_atom.GetResNum(),second_atom.GetAtomName()); - overlap.second+=1.0; - if (!(av1 && av2)) { - continue; - } - Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); - ReferenceDistance ref_dist=*ai; - if (within_tolerance(mdl_dist,ref_dist,tol).first) { - if (log) { - LOG_VERBOSE("LDT:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() - << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " - << mdl_dist << " " << ref_dist.GetMinDistance() << " " << ref_dist.GetMaxDistance() << " " << tol << " " << "PASS") - } - overlap.first+=1; - } else { - if (log) { - LOG_VERBOSE("LDT:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() - << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " - << mdl_dist << " " << ref_dist.GetMinDistance() << " " << mdl_dist-ref_dist.GetMinDistance() << " " << tol << " " << "FAIL") - } - } - continue; - } - AtomView av2=mdl_chain.FindAtom(second_atom.GetResNum(), second_atom.GetAtomName()); - overlap.second+=1.0; - if (av1) { - overlap_list[av1.GetResidue().GetIndex()].second+=1.0; - } - if (av2) { - overlap_list[av2.GetResidue().GetIndex()].second+=1.0; - } - if (!(av1 && av2)) { - continue; - } - - Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); - ReferenceDistance ref_dist=*ai; - if (within_tolerance(mdl_dist,ref_dist,tol).first) { - LOG_INFO("LDT:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() - << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " - << mdl_dist << " " << ref_dist.GetMinDistance() << " " << mdl_dist-ref_dist.GetMinDistance() << " " << tol << " " << "PASS") - overlap.first+=1; - overlap_list[av1.GetResidue().GetIndex()].first+=1.0; - overlap_list[av2.GetResidue().GetIndex()].first+=1.0; - } else { - LOG_VERBOSE("LDT:" << " " << av1.GetResidue().GetChain() << " " << av1.GetResidue().GetName() << " " << av1.GetResidue().GetNumber() << " " << av1.GetName() - << " " << av2.GetResidue().GetChain() << " " << av2.GetResidue().GetName() << " " << av2.GetResidue().GetNumber() << " " << av2.GetName() << " " - << mdl_dist << " " << ref_dist.GetMinDistance() << " " << mdl_dist-ref_dist.GetMinDistance() << " " << tol << " " << "FAIL") - } - } - return overlap; -} - - -std::pair<Real, Real> calc_overlap2(const seq::ConstSequenceHandle& ref_seq, - const seq::ConstSequenceHandle& mdl_seq, - int pos, Real tol, Real max_dist, - bool only_fixed, bool swap) -{ - std::pair<Real, Real> overlap(0.0, 0.0); - EntityView ref=ref_seq.GetAttachedView(); - ResidueView ref_res=ref_seq.GetResidue(pos); - if (!ref_res.IsValid()) { - return std::pair<Real,Real>(0.0, 0.0); - } - AtomViewList ref_atoms=ref_res.GetAtomList(); - ResidueView mdl_res=mdl_seq.GetResidue(pos); - AtomViewList within; - if (max_dist<0) { - within=ref.GetAtomList(); - } - for (AtomViewList::iterator ai=ref_atoms.begin(), - ae=ref_atoms.end(); ai!=ae; ++ai) { - if (ai->GetElement()=="H") { continue; } - String name=swap ? swapped_name(ai->GetName()) : ai->GetName(); - AtomView av1=mdl_res ? mdl_res.FindAtom(name) : AtomView(); - if (max_dist>=0){ - within=ref.FindWithin(ai->GetPos(), max_dist); - } - for (AtomViewList::iterator aj=within.begin(), - ae2=within.end(); aj!=ae2; ++aj) { - if (aj->GetElement()=="H" || - aj->GetResidue().GetChain()!=ai->GetResidue().GetChain()) { - continue; - } - if (only_fixed) { - if (aj->GetResidue().GetNumber()==ref_res.GetNumber()) { - continue; - } - if (swappable(aj->GetResidue().GetName(), aj->GetName())) { - continue; - } - overlap.second+=1.0; - // map from residue index to position in alignment - try { - int aln_pos=ref_seq.GetPos(aj->GetResidue().GetIndex()); - ResidueView r2=mdl_seq.GetResidue(aln_pos); - if (!r2.IsValid()) { - continue; - } - AtomView av2=r2.FindAtom(aj->GetName()); - if (!(av1 && av2)) { - continue; - } - Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); - Real ref_dist=geom::Length(ai->GetPos()-aj->GetPos()); - if (std::abs(mdl_dist-ref_dist)<tol) { - overlap.first+=1; - } - } catch(...) { } - continue; - } else { - if (aj->GetResidue().GetNumber()>ref_res.GetNumber()) { - overlap.second+=1.0; - - try { - int aln_pos=ref_seq.GetPos(aj->GetResidue().GetIndex()); - ResidueView r2=mdl_seq.GetResidue(aln_pos); - if (!r2.IsValid()) { - continue; - } - AtomView av2=r2.FindAtom(aj->GetName()); - if (!(av1 && av2)) { - continue; - } - Real mdl_dist=geom::Length(av1.GetPos()-av2.GetPos()); - Real ref_dist=geom::Length(ai->GetPos()-aj->GetPos()); - if (std::abs(mdl_dist-ref_dist)<tol) { - overlap.first+=1; - } - } catch (...) { } - } - } - } - } - return overlap; -} - -} - -bool IsStandardResidue(String rn) -{ - String upper_rn=rn; - std::transform(rn.begin(),rn.end(),rn.begin(),toupper); - if (upper_rn == "ALA" || - upper_rn == "ARG" || - upper_rn == "ASN" || - upper_rn == "ASP" || - upper_rn == "GLN" || - upper_rn == "GLU" || - upper_rn == "LYS" || - upper_rn == "SER" || - upper_rn == "CYS" || - upper_rn == "TYR" || - upper_rn == "TRP" || - upper_rn == "THR" || - upper_rn == "VAL" || - upper_rn == "ILE" || - upper_rn == "MET" || - upper_rn == "LEU" || - upper_rn == "GLY" || - upper_rn == "PRO" || - upper_rn == "HIS" || - upper_rn == "PHE") { - return true; - } - return false; -} - -bool UniqueAtomIdentifier::operator==(const UniqueAtomIdentifier& rhs) const -{ - if (chain_ == rhs.GetChainName() && - residue_ == rhs.GetResNum() && - residue_name_ == rhs.GetResidueName() && - atom_ == rhs.GetAtomName() ) { - return true; - } - return false; -} - -bool ReferenceDistance::IsValid() const -{ - if (mind_ == -1.0 and maxd_ == -1.0) { - return false; - } - return true; -} - -void ReferenceDistance::Print() const -{ - if (this->IsValid() == true) { - std::cout << first_atom_.GetChainName() << " " << first_atom_.GetResNum() << " " << first_atom_.GetResidueName() << " " << first_atom_.GetAtomName() << " " << - second_atom_.GetChainName() << " " << second_atom_.GetResNum() << " " << second_atom_.GetResidueName() << " " << second_atom_.GetAtomName() << " " << - mind_ << " " << maxd_ << std::endl; - } else { - std::cout << first_atom_.GetChainName() << " " << first_atom_.GetResNum() << " " << first_atom_.GetResidueName() << " Placeholder" << std::endl; - } -} - -bool ReferenceDistance::operator==(const ReferenceDistance& rhs) const -{ - if (first_atom_ == rhs.GetFirstAtom() && - second_atom_ == rhs.GetSecondAtom() && - mind_ == rhs.GetMinDistance() && - maxd_ == rhs.GetMaxDistance() ) { - return true; - } - return false; -} - - - - -GlobalDistanceList CreateDistanceList(const EntityView& ref,Real max_dist) -{ - GlobalDistanceList dist_list; - ResidueViewList ref_residues=ref.GetChainList()[0].GetResidueList(); - for (ResidueViewList::iterator i=ref_residues.begin(), e=ref_residues.end(); i!=e; ++i) { - ResidueView rview = (*i); - if (IsStandardResidue(rview.GetName())) { - ResidueDistanceList res_dist_list; - AtomViewList ref_atoms=(*i).GetAtomList(); - AtomViewList within; - if (max_dist<0){ - dist_list.push_back(res_dist_list); - within=ref.GetAtomList(); - } - for (AtomViewList::iterator ai=ref_atoms.begin(), ae=ref_atoms.end(); ai!=ae; ++ai) { - UniqueAtomIdentifier first_atom(ai->GetResidue().GetChain().GetName(),ai->GetResidue().GetNumber(),ai->GetResidue().GetName(),ai->GetName()); - if (ai->GetElement()=="H") { continue; } - if (max_dist>=0){ - within=ref.FindWithin(ai->GetPos(), max_dist); - } - for (AtomViewList::iterator aj=within.begin(), ae2=within.end(); aj!=ae2; ++aj) { - UniqueAtomIdentifier second_atom(aj->GetResidue().GetChain().GetName(),aj->GetResidue().GetNumber(),aj->GetResidue().GetName(),aj->GetName()); - if (aj->GetElement()=="H" || - aj->GetResidue().GetChain()!=ai->GetResidue().GetChain()) { - continue; - } - if (aj->GetResidue().GetNumber()>i->GetNumber()) { - Real dist=geom::Length(ai->GetPos()-aj->GetPos()); - ReferenceDistance ref_dist(first_atom,second_atom,dist,dist); - res_dist_list.push_back(ref_dist); - } - } - } - if (res_dist_list.size()==0) { - UniqueAtomIdentifier current_residue_fake_atom(rview.GetChain().GetName(),rview.GetNumber(),rview.GetName(),"CA"); - ReferenceDistance fake_ref_distance(current_residue_fake_atom,current_residue_fake_atom,-1.0,-1.0); - res_dist_list.push_back(fake_ref_distance); - } - dist_list.push_back(res_dist_list); - } - } - return dist_list; -} - - -Real LocalDistTest(const EntityView& mdl, const GlobalDistanceList& glob_dist_list, - Real cutoff, const String& local_ldt_property_string) -{ - if (!mdl.GetResidueCount()) { - LOG_WARNING("model structures doesn't contain any residues"); - return 0.0; - } - if (glob_dist_list.size()==0) { - LOG_WARNING("global reference list is empty"); - return 0.0; - } - std::vector<std::pair<Real, Real> > overlap_list(mdl.GetResidueCount(), std::pair<Real, Real>(0.0, 0.0)); - ChainView mdl_chain=mdl.GetChainList()[0]; - // Residues with symmetric side-chains require special treatment as there are - // two possible ways to name the atoms. We calculate the overlap with the - // fixed atoms and take the solution that gives bigger scores. - XCSEditor edi=mdl.GetHandle().EditXCS(BUFFERED_EDIT); - for (GlobalDistanceList::const_iterator i=glob_dist_list.begin(), e=glob_dist_list.end(); i!=e; ++i) { - ResidueDistanceList rdl = *i; - if (!rdl[0].IsValid()) { - continue; - } - - ResNum rnum = rdl[0].GetFirstAtom().GetResNum() ; - String rname=rdl[0].GetFirstAtom().GetResidueName(); - ResidueView mdl_res=mdl_chain.FindResidue(rnum); - if (!mdl_res) { - continue; - } - if (!(rname=="GLU" || rname=="ASP" || rname=="VAL" || rname=="TYR" || rname=="PHE" || rname=="LYS" || rname=="ARG")) { - continue; - } - std::pair<Real, Real> ov1=calc_overlap1(*i, mdl_chain, - cutoff, true, - false, overlap_list,false); - - std::pair<Real, Real> ov2=calc_overlap1(*i, mdl_chain, - cutoff, true, - true, overlap_list,false); - if (ov1.first/ov1.second<ov2.first/ov2.second) { - AtomViewList atoms=mdl_res.GetAtomList(); - for (AtomViewList::iterator j=atoms.begin(), e2=atoms.end(); j!=e2; ++j) { - if (swappable(rname, j->GetName())) { - edi.RenameAtom(j->GetHandle(), swapped_name(j->GetName())); - } - } - } - } - overlap_list.clear(); - std::pair<Real, Real> total_ov(0.0, 0.0); - for (GlobalDistanceList::const_iterator i=glob_dist_list.begin(), e=glob_dist_list.end(); i!=e; ++i) { - ResidueDistanceList rdl = *i; - if (rdl[0].IsValid()) { - std::pair<Real, Real> ov1=calc_overlap1(*i, mdl_chain, cutoff, - false, false, overlap_list,true); - total_ov.first+=ov1.first; - total_ov.second+=ov1.second; - } - if(local_ldt_property_string!="") { - ResNum rn = rdl[0].GetFirstAtom().GetResNum(); - ResidueView mdlr=mdl_chain.FindResidue(rn); - if (mdlr.IsValid()) { - int mdl_res_index =mdlr.GetIndex(); - Real local_ldt=overlap_list[mdl_res_index].first/(overlap_list[mdl_res_index].second ? overlap_list[mdl_res_index].second : 1); - ResidueView res_to_wr = mdl_chain.FindResidue((*i)[0].GetFirstAtom().GetResNum()); - res_to_wr.SetFloatProp(local_ldt_property_string, local_ldt); - } - } - } - overlap_list.clear(); - return total_ov.first/(total_ov.second ? total_ov.second : 1); -} - -Real LocalDistTest(const ost::seq::AlignmentHandle& aln, - Real cutoff, Real max_dist, int ref_index, int mdl_index) -{ - seq::ConstSequenceHandle ref_seq=aln.GetSequence(ref_index); - seq::ConstSequenceHandle mdl_seq=aln.GetSequence(mdl_index); - if (!ref_seq.HasAttachedView()) { - LOG_ERROR("reference sequence doesn't have a view attached."); - return 0.0; - } - if (!mdl_seq.HasAttachedView()) { - LOG_ERROR("model sequence doesn't have a view attached"); - return 0.0; - } - XCSEditor edi=ref_seq.GetAttachedView().GetHandle().EditXCS(BUFFERED_EDIT); - for (int i=0; i<aln.GetLength(); ++i) { - ResidueView mdl_res=mdl_seq.GetResidue(i); - if (!mdl_res) { - continue; - } - String rname=mdl_res.GetName(); - if (!(rname=="GLU" || rname=="ASP" || rname=="VAL" || rname=="TYR" || - rname=="PHE" || rname=="LYS" || rname=="ARG")) { - continue; - } - std::pair<Real, Real> ov1=calc_overlap2(ref_seq, mdl_seq, i, - cutoff, max_dist, true, - false); - std::pair<Real, Real> ov2=calc_overlap2(ref_seq, mdl_seq, i, - cutoff, max_dist, true, - true); - if (ov1.first/ov1.second<ov2.first/ov2.second) { - AtomViewList atoms=mdl_res.GetAtomList(); - for (AtomViewList::iterator j=atoms.begin(), - e2=atoms.end(); j!=e2; ++j) { - if (swappable(rname, j->GetName())) { - edi.RenameAtom(j->GetHandle(), swapped_name(j->GetName())); - } - } - } - } - std::pair<Real, Real> total_ov(0.0, 0.0); - for (int i=0; i<aln.GetLength(); ++i) { - std::pair<Real, Real> ov1=calc_overlap2(ref_seq, mdl_seq, i, cutoff, - max_dist, false, false); - total_ov.first+=ov1.first; - total_ov.second+=ov1.second; - } - return total_ov.first/(total_ov.second ? total_ov.second : 1); - return 0.0; -} - -Real LDTHA(EntityView& v, const GlobalDistanceList& global_dist_list) -{ - - Real cutoffs[]={0.5,1,2,4}; - String labels[]={"localldt0.5","localldt1","localldt2","ldtlocal4"}; - Real ldt=0.0; - for (int n=0; n<4; ++n) { - ldt+=alg::LocalDistTest(v, global_dist_list, cutoffs[n], labels[n]); - } - ldt/=4.0; - return ldt; -} - -}}} diff --git a/modules/mol/alg/src/local_dist_test.hh b/modules/mol/alg/src/local_dist_test.hh deleted file mode 100644 index 74e0f4f29ca00b54340a683a036904d3eb66e596..0000000000000000000000000000000000000000 --- a/modules/mol/alg/src/local_dist_test.hh +++ /dev/null @@ -1,96 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 -//------------------------------------------------------------------------------ -#ifndef OST_MOL_ALG_LOCAL_DIST_TEST_HH -#define OST_MOL_ALG_LOCAL_DIST_TEST_HH - -#include <ost/mol/entity_view.hh> -#include <ost/mol/alg/module_config.hh> -#include <ost/seq/alignment_handle.hh> - -namespace ost { namespace mol { namespace alg { - - -class UniqueAtomIdentifier -{ - -public: - UniqueAtomIdentifier(const String& chain,const ResNum& residue,const String& residue_name, const String& atom): chain_(chain),residue_(residue),residue_name_(residue_name),atom_(atom) {} - - String GetChainName() const { return chain_; } - ResNum GetResNum() const { return residue_; } - String GetResidueName() const { return residue_name_; } - String GetAtomName() const { return atom_; } - bool operator==(const UniqueAtomIdentifier& rhs) const; - -private: - - String chain_; - ResNum residue_; - String residue_name_; - String atom_; -}; - -class ReferenceDistance -{ - -public: - - ReferenceDistance(const UniqueAtomIdentifier& first_atom, const UniqueAtomIdentifier& second_atom, Real mind, Real maxd): - first_atom_(first_atom),second_atom_(second_atom),mind_(mind),maxd_(maxd) {} - UniqueAtomIdentifier GetFirstAtom() const {return first_atom_;} - UniqueAtomIdentifier GetSecondAtom() const {return second_atom_;} - Real GetMinDistance() const {return mind_ ;} - Real GetMaxDistance() const {return maxd_ ;} - bool IsValid() const; - void Print() const; - bool operator==(const ReferenceDistance& rhs) const; - -private: - - UniqueAtomIdentifier first_atom_; - UniqueAtomIdentifier second_atom_; - Real mind_; - Real maxd_; -}; - -typedef std::vector<ReferenceDistance> ResidueDistanceList; -typedef std::vector<ResidueDistanceList> GlobalDistanceList; - -Real DLLEXPORT_OST_MOL_ALG LocalDistTest(const EntityView& mdl, - const GlobalDistanceList& dist_list, - Real cutoff, - const String& local_ldt_property_string=""); - -Real DLLEXPORT_OST_MOL_ALG LocalDistTest(const ost::seq::AlignmentHandle& aln, - Real cutoff, Real max_dist, - int ref_index=0, int mdl_index=1); - - -Real DLLEXPORT_OST_MOL_ALG LDTHA(EntityView& v, const GlobalDistanceList& global_dist_list); - -GlobalDistanceList CreateDistanceList(const EntityView& ref,Real max_dist); -bool IsStandardResidue(String rn); - - - -}}} - -#endif - - diff --git a/modules/mol/alg/src/new_stereo_chemical_props.txt b/modules/mol/alg/src/new_stereo_chemical_props.txt deleted file mode 100644 index 25262efd7689fc76f4d6ea1a7c75e342e840ea1d..0000000000000000000000000000000000000000 --- a/modules/mol/alg/src/new_stereo_chemical_props.txt +++ /dev/null @@ -1,345 +0,0 @@ -Bond Residue Mean StdDev -CA-CB ALA 1.520 0.021 -N-CA ALA 1.459 0.020 -CA-C ALA 1.525 0.026 -C-O ALA 1.229 0.019 -CA-CB ARG 1.535 0.022 -CB-CG ARG 1.521 0.027 -CG-CD ARG 1.515 0.025 -CD-NE ARG 1.460 0.017 -NE-CZ ARG 1.326 0.013 -CZ-NH1 ARG 1.326 0.013 -CZ-NH2 ARG 1.326 0.013 -N-CA ARG 1.459 0.020 -CA-C ARG 1.525 0.026 -C-O ARG 1.229 0.019 -CA-CB ASN 1.527 0.026 -CB-CG ASN 1.506 0.023 -CG-OD1 ASN 1.235 0.022 -CG-ND2 ASN 1.324 0.025 -N-CA ASN 1.459 0.020 -CA-C ASN 1.525 0.026 -C-O ASN 1.229 0.019 -CA-CB ASP 1.535 0.022 -CB-CG ASP 1.513 0.021 -CG-OD1 ASP 1.249 0.023 -CG-OD2 ASP 1.249 0.023 -N-CA ASP 1.459 0.020 -CA-C ASP 1.525 0.026 -C-O ASP 1.229 0.019 -CA-CB CYS 1.526 0.013 -CB-SG CYS 1.812 0.016 -N-CA CYS 1.459 0.020 -CA-C CYS 1.525 0.026 -C-O CYS 1.229 0.019 -CA-CB GLU 1.535 0.022 -CB-CG GLU 1.517 0.019 -CG-CD GLU 1.515 0.015 -CD-OE1 GLU 1.252 0.011 -CD-OE2 GLU 1.252 0.011 -N-CA GLU 1.459 0.020 -CA-C GLU 1.525 0.026 -C-O GLU 1.229 0.019 -CA-CB GLN 1.535 0.022 -CB-CG GLN 1.521 0.027 -CG-CD GLN 1.506 0.023 -CD-OE1 GLN 1.235 0.022 -CD-NE2 GLN 1.324 0.025 -N-CA GLN 1.459 0.020 -CA-C GLN 1.525 0.026 -C-O GLN 1.229 0.019 -N-CA GLY 1.456 0.015 -CA-C GLY 1.514 0.016 -C-O GLY 1.232 0.016 -CA-CB HIS 1.535 0.022 -CB-CG HIS 1.492 0.016 -CG-ND1 HIS 1.369 0.015 -CG-CD2 HIS 1.353 0.017 -ND1-CE1 HIS 1.343 0.025 -CD2-NE2 HIS 1.415 0.021 -CE1-NE2 HIS 1.322 0.023 -N-CA HIS 1.459 0.020 -CA-C HIS 1.525 0.026 -C-O HIS 1.229 0.019 -CA-CB ILE 1.544 0.023 -CB-CG1 ILE 1.536 0.028 -CB-CG2 ILE 1.524 0.031 -CG1-CD1 ILE 1.500 0.069 -N-CA ILE 1.459 0.020 -CA-C ILE 1.525 0.026 -C-O ILE 1.229 0.019 -CA-CB LEU 1.533 0.023 -CB-CG LEU 1.521 0.029 -CG-CD1 LEU 1.514 0.037 -CG-CD2 LEU 1.514 0.037 -N-CA LEU 1.459 0.020 -CA-C LEU 1.525 0.026 -C-O LEU 1.229 0.019 -CA-CB LYS 1.535 0.022 -CB-CG LYS 1.521 0.027 -CG-CD LYS 1.520 0.034 -CD-CE LYS 1.508 0.025 -CE-NZ LYS 1.486 0.025 -N-CA LYS 1.459 0.020 -CA-C LYS 1.525 0.026 -C-O LYS 1.229 0.019 -CA-CB MET 1.535 0.022 -CB-CG MET 1.509 0.032 -CG-SD MET 1.807 0.026 -SD-CE MET 1.774 0.056 -N-CA MET 1.459 0.020 -CA-C MET 1.525 0.026 -C-O MET 1.229 0.019 -CA-CB PHE 1.535 0.022 -CB-CG PHE 1.509 0.017 -CG-CD1 PHE 1.383 0.015 -CG-CD2 PHE 1.383 0.015 -CD1-CE1 PHE 1.388 0.020 -CD2-CE2 PHE 1.388 0.020 -CE1-CZ PHE 1.369 0.019 -CE2-CZ PHE 1.369 0.019 -N-CA PHE 1.459 0.020 -CA-C PHE 1.525 0.026 -C-O PHE 1.229 0.019 -CA-CB PRO 1.531 0.020 -CB-CG PRO 1.495 0.050 -CG-CD PRO 1.502 0.033 -CD-N PRO 1.474 0.014 -N-CA PRO 1.468 0.017 -CA-C PRO 1.524 0.020 -C-O PRO 1.228 0.020 -CA-CB SER 1.525 0.015 -CB-OG SER 1.418 0.013 -N-CA SER 1.459 0.020 -CA-C SER 1.525 0.026 -C-O SER 1.229 0.019 -CA-CB THR 1.529 0.026 -CB-OG1 THR 1.428 0.020 -CB-CG2 THR 1.519 0.033 -N-CA THR 1.459 0.020 -CA-C THR 1.525 0.026 -C-O THR 1.229 0.019 -CA-CB TRP 1.535 0.022 -CB-CG TRP 1.498 0.018 -CG-CD1 TRP 1.363 0.014 -CG-CD2 TRP 1.432 0.017 -CD1-NE1 TRP 1.375 0.017 -NE1-CE2 TRP 1.371 0.013 -CD2-CE2 TRP 1.409 0.012 -CD2-CE3 TRP 1.399 0.015 -CE2-CZ2 TRP 1.393 0.017 -CE3-CZ3 TRP 1.380 0.017 -CZ2-CH2 TRP 1.369 0.019 -CZ3-CH2 TRP 1.396 0.016 -N-CA TRP 1.459 0.020 -CA-C TRP 1.525 0.026 -C-O TRP 1.229 0.019 -CA-CB TYR 1.535 0.022 -CB-CG TYR 1.512 0.015 -CG-CD1 TYR 1.387 0.013 -CG-CD2 TYR 1.387 0.013 -CD1-CE1 TYR 1.389 0.015 -CD2-CE2 TYR 1.389 0.015 -CE1-CZ TYR 1.381 0.013 -CE2-CZ TYR 1.381 0.013 -CZ-OH TYR 1.374 0.017 -N-CA TYR 1.459 0.020 -CA-C TYR 1.525 0.026 -C-O TYR 1.229 0.019 -CA-CB VAL 1.543 0.021 -CB-CG1 VAL 1.524 0.021 -CB-CG2 VAL 1.524 0.021 -N-CA VAL 1.459 0.020 -CA-C VAL 1.525 0.026 -C-O VAL 1.229 0.019 -- - -Angle Residue Mean StdDev -N-CA-CB ALA 110.1 1.4 -CB-CA-C ALA 110.1 1.5 -N-CA-C ALA 111.0 2.7 -CA-C-O ALA 120.1 2.1 -N-CA-CB ARG 110.6 1.8 -CB-CA-C ARG 110.4 2.0 -CA-CB-CG ARG 113.4 2.2 -CB-CG-CD ARG 111.6 2.6 -CG-CD-NE ARG 111.8 2.1 -CD-NE-CZ ARG 123.6 1.4 -NE-CZ-NH1 ARG 120.3 0.5 -NE-CZ-NH2 ARG 120.3 0.5 -NH1-CZ-NH2 ARG 119.4 1.1 -N-CA-C ARG 111.0 2.7 -CA-C-O ARG 120.1 2.1 -N-CA-CB ASN 110.6 1.8 -CB-CA-C ASN 110.4 2.0 -CA-CB-CG ASN 113.4 2.2 -CB-CG-ND2 ASN 116.7 2.4 -CB-CG-OD1 ASN 121.6 2.0 -ND2-CG-OD1 ASN 121.9 2.3 -N-CA-C ASN 111.0 2.7 -CA-C-O ASN 120.1 2.1 -N-CA-CB ASP 110.6 1.8 -CB-CA-C ASP 110.4 2.0 -CA-CB-CG ASP 113.4 2.2 -CB-CG-OD1 ASP 118.3 0.9 -CB-CG-OD2 ASP 118.3 0.9 -OD1-CG-OD2 ASP 123.3 1.9 -N-CA-C ASP 111.0 2.7 -CA-C-O ASP 120.1 2.1 -N-CA-CB CYS 110.8 1.5 -CB-CA-C CYS 111.5 1.2 -CA-CB-SG CYS 114.2 1.1 -N-CA-C CYS 111.0 2.7 -CA-C-O CYS 120.1 2.1 -N-CA-CB GLU 110.6 1.8 -CB-CA-C GLU 110.4 2.0 -CA-CB-CG GLU 113.4 2.2 -CB-CG-CD GLU 114.2 2.7 -CG-CD-OE1 GLU 118.3 2.0 -CG-CD-OE2 GLU 118.3 2.0 -OE1-CD-OE2 GLU 123.3 1.2 -N-CA-C GLU 111.0 2.7 -CA-C-O GLU 120.1 2.1 -N-CA-CB GLN 110.6 1.8 -CB-CA-C GLN 110.4 2.0 -CA-CB-CG GLN 113.4 2.2 -CB-CG-CD GLN 111.6 2.6 -CG-CD-OE1 GLN 121.6 2.0 -CG-CD-NE2 GLN 116.7 2.4 -OE1-CD-NE2 GLN 121.9 2.3 -N-CA-C GLN 111.0 2.7 -CA-C-O GLN 120.1 2.1 -N-CA-C GLY 113.1 2.5 -CA-C-O GLY 120.6 1.8 -N-CA-CB HIS 110.6 1.8 -CB-CA-C HIS 110.4 2.0 -CA-CB-CG HIS 113.6 1.7 -CB-CG-ND1 HIS 123.2 2.5 -CB-CG-CD2 HIS 130.8 3.1 -CG-ND1-CE1 HIS 108.2 1.4 -ND1-CE1-NE2 HIS 109.9 2.2 -CE1-NE2-CD2 HIS 106.6 2.5 -NE2-CD2-CG HIS 109.2 1.9 -CD2-CG-ND1 HIS 106.0 1.4 -N-CA-C HIS 111.0 2.7 -CA-C-O HIS 120.1 2.1 -N-CA-CB ILE 110.8 2.3 -CB-CA-C ILE 111.6 2.0 -CA-CB-CG1 ILE 111.0 1.9 -CB-CG1-CD1 ILE 113.9 2.8 -CA-CB-CG2 ILE 110.9 2.0 -CG1-CB-CG2 ILE 111.4 2.2 -N-CA-C ILE 111.0 2.7 -CA-C-O ILE 120.1 2.1 -N-CA-CB LEU 110.4 2.0 -CB-CA-C LEU 110.2 1.9 -CA-CB-CG LEU 115.3 2.3 -CB-CG-CD1 LEU 111.0 1.7 -CB-CG-CD2 LEU 111.0 1.7 -CD1-CG-CD2 LEU 110.5 3.0 -N-CA-C LEU 111.0 2.7 -CA-C-O LEU 120.1 2.1 -N-CA-CB LYS 110.6 1.8 -CB-CA-C LYS 110.4 2.0 -CA-CB-CG LYS 113.4 2.2 -CB-CG-CD LYS 111.6 2.6 -CG-CD-CE LYS 111.9 3.0 -CD-CE-NZ LYS 111.7 2.3 -N-CA-C LYS 111.0 2.7 -CA-C-O LYS 120.1 2.1 -N-CA-CB MET 110.6 1.8 -CB-CA-C MET 110.4 2.0 -CA-CB-CG MET 113.3 1.7 -CB-CG-SD MET 112.4 3.0 -CG-SD-CE MET 100.2 1.6 -N-CA-C MET 111.0 2.7 -CA-C-O MET 120.1 2.1 -N-CA-CB PHE 110.6 1.8 -CB-CA-C PHE 110.4 2.0 -CA-CB-CG PHE 113.9 2.4 -CB-CG-CD1 PHE 120.8 0.7 -CB-CG-CD2 PHE 120.8 0.7 -CD1-CG-CD2 PHE 118.3 1.3 -CG-CD1-CE1 PHE 120.8 1.1 -CG-CD2-CE2 PHE 120.8 1.1 -CD1-CE1-CZ PHE 120.1 1.2 -CD2-CE2-CZ PHE 120.1 1.2 -CE1-CZ-CE2 PHE 120.0 1.8 -N-CA-C PHE 111.0 2.7 -CA-C-O PHE 120.1 2.1 -N-CA-CB PRO 103.3 1.2 -CB-CA-C PRO 111.7 2.1 -CA-CB-CG PRO 104.8 1.9 -CB-CG-CD PRO 106.5 3.9 -CG-CD-N PRO 103.2 1.5 -CA-N-CD PRO 111.7 1.4 -N-CA-C PRO 112.1 2.6 -CA-C-O PRO 120.2 2.4 -N-CA-CB SER 110.5 1.5 -CB-CA-C SER 110.1 1.9 -CA-CB-OG SER 111.2 2.7 -N-CA-C SER 111.0 2.7 -CA-C-O SER 120.1 2.1 -N-CA-CB THR 110.3 1.9 -CB-CA-C THR 111.6 2.7 -CA-CB-OG1 THR 109.0 2.1 -CA-CB-CG2 THR 112.4 1.4 -OG1-CB-CG2 THR 110.0 2.3 -N-CA-C THR 111.0 2.7 -CA-C-O THR 120.1 2.1 -N-CA-CB TRP 110.6 1.8 -CB-CA-C TRP 110.4 2.0 -CA-CB-CG TRP 113.7 1.9 -CB-CG-CD1 TRP 127.0 1.3 -CB-CG-CD2 TRP 126.6 1.3 -CD1-CG-CD2 TRP 106.3 0.8 -CG-CD1-NE1 TRP 110.1 1.0 -CD1-NE1-CE2 TRP 109.0 0.9 -NE1-CE2-CD2 TRP 107.3 1.0 -CE2-CD2-CG TRP 107.3 0.8 -CG-CD2-CE3 TRP 133.9 0.9 -NE1-CE2-CZ2 TRP 130.4 1.1 -CE3-CD2-CE2 TRP 118.7 1.2 -CD2-CE2-CZ2 TRP 122.3 1.2 -CE2-CZ2-CH2 TRP 117.4 1.0 -CZ2-CH2-CZ3 TRP 121.6 1.2 -CH2-CZ3-CE3 TRP 121.2 1.1 -CZ3-CE3-CD2 TRP 118.8 1.3 -N-CA-C TRP 111.0 2.7 -CA-C-O TRP 120.1 2.1 -N-CA-CB TYR 110.6 1.8 -CB-CA-C TYR 110.4 2.0 -CA-CB-CG TYR 113.4 1.9 -CB-CG-CD1 TYR 121.0 0.6 -CB-CG-CD2 TYR 121.0 0.6 -CD1-CG-CD2 TYR 117.9 1.1 -CG-CD1-CE1 TYR 121.3 0.8 -CG-CD2-CE2 TYR 121.3 0.8 -CD1-CE1-CZ TYR 119.8 0.9 -CD2-CE2-CZ TYR 119.8 0.9 -CE1-CZ-CE2 TYR 119.8 1.6 -CE1-CZ-OH TYR 120.1 2.7 -CE2-CZ-OH TYR 120.1 2.7 -N-CA-C TYR 111.0 2.7 -CA-C-O TYR 120.1 2.1 -N-CA-CB VAL 111.5 2.2 -CB-CA-C VAL 111.4 1.9 -CA-CB-CG1 VAL 110.9 1.5 -CA-CB-CG2 VAL 110.9 1.5 -CG1-CB-CG2 VAL 110.9 1.6 -N-CA-C VAL 111.0 2.7 -CA-C-O VAL 120.1 2.1 -- - -Non-bonded distance Minimum Dist Tolerance -C-C 3.4 1.5 -C-N 3.25 1.5 -C-S 3.5 1.5 -C-O 3.22 1.5 -N-N 3.1 1.5 -N-S 3.35 1.5 -N-O 3.07 1.5 -O-S 3.32 1.5 -O-O 3.04 1.5 -S-S 2.03 1.0 -- diff --git a/modules/mol/alg/src/stereo_chemical_props.txt b/modules/mol/alg/src/stereo_chemical_props.txt index f17af3cf31baf8789c648fb1d5f1eff1d882a46d..25262efd7689fc76f4d6ea1a7c75e342e840ea1d 100644 --- a/modules/mol/alg/src/stereo_chemical_props.txt +++ b/modules/mol/alg/src/stereo_chemical_props.txt @@ -1,367 +1,345 @@ -# This file contains stereochemical parameters used to evaluate the quality of models. -# Bond distances and Angles come from Engh,Huber (1991). Non bonded distances come from - Bond Residue Mean StdDev -N-CA ALA 1.458 0.019 -CA-C ALA 1.525 0.021 -C-O ALA 1.231 0.02 -CA-CB ALA 1.521 0.033 -N-CA CYS 1.458 0.019 -CA-C CYS 1.525 0.021 -C-O CYS 1.231 0.02 -CA-CB CYS 1.53 0.02 -CB-SG CYS 1.808 0.033 -N-CA ASP 1.458 0.019 -CA-C ASP 1.525 0.021 -C-O ASP 1.231 0.02 -CA-CB ASP 1.53 0.02 -CB-CG ASP 1.516 0.025 -CG-OD1 ASP 1.249 0.019 -CG-OD2 ASP 1.249 0.019 -N-CA GLU 1.458 0.019 -CA-C GLU 1.525 0.021 -C-O GLU 1.231 0.02 -CA-CB GLU 1.53 0.02 -CB-CG GLU 1.52 0.03 -CG-CD GLU 1.516 0.025 -CD-OE1 GLU 1.249 0.019 -CD-OE2 GLU 1.249 0.019 -N-CA PHE 1.458 0.019 -CA-C PHE 1.525 0.021 -C-O PHE 1.231 0.02 -CA-CB PHE 1.53 0.02 -CB-CG PHE 1.502 0.023 -CG-CD1 PHE 1.384 0.021 -CG-CD2 PHE 1.384 0.021 -CD1-CE1 PHE 1.382 0.03 -CD2-CE2 PHE 1.382 0.03 -CE1-CZ PHE 1.382 0.03 -CE2-CZ PHE 1.382 0.03 -N-CA GLY 1.451 0.016 -CA-C GLY 1.516 0.018 -C-O GLY 1.231 0.02 -N-CA HIS 1.458 0.019 -CA-C HIS 1.525 0.021 -C-O HIS 1.231 0.02 -CA-CB HIS 1.53 0.02 -CB-CG HIS 1.497 0.014 -CG-ND1 HIS 1.378 0.011 -CG-CD2 HIS 1.354 0.011 -ND1-CE1 HIS 1.321 0.01 -CD2-NE2 HIS 1.374 0.011 -CE1-NE2 HIS 1.321 0.01 -N-CA ILE 1.458 0.019 -CA-C ILE 1.525 0.021 -C-O ILE 1.231 0.02 -CA-CB ILE 1.54 0.027 -CB-CG1 ILE 1.53 0.02 -CB-CG2 ILE 1.521 0.033 -CG1-CD1 ILE 1.513 0.039 -N-CA LYS 1.458 0.019 -CA-C LYS 1.525 0.021 -C-O LYS 1.231 0.02 -CA-CB LYS 1.53 0.02 -CB-CG LYS 1.52 0.03 -CG-CD LYS 1.52 0.03 -CD-CE LYS 1.52 0.03 -CE-NZ LYS 1.489 0.03 -N-CA LEU 1.458 0.019 -CA-C LEU 1.525 0.021 -C-O LEU 1.231 0.02 -CA-CB LEU 1.53 0.02 -CB-CG LEU 1.53 0.02 -CG-CD1 LEU 1.521 0.033 -CG-CD2 LEU 1.521 0.033 -N-CA MET 1.458 0.019 -CA-C MET 1.525 0.021 -C-O MET 1.231 0.02 -CA-CB MET 1.53 0.02 -CB-CG MET 1.52 0.03 -CG-SD MET 1.803 0.034 -SD-CE MET 1.791 0.059 -N-CA ASN 1.458 0.019 -CA-C ASN 1.525 0.021 -C-O ASN 1.231 0.02 -CA-CB ASN 1.53 0.02 -CB-CG ASN 1.516 0.025 -CG-OD1 ASN 1.231 0.02 -CG-ND2 ASN 1.328 0.021 -N-CA PRO 1.466 0.015 -CA-C PRO 1.525 0.021 -C-O PRO 1.231 0.02 -CA-CB PRO 1.53 0.02 -CB-CG PRO 1.492 0.05 -CG-CD PRO 1.503 0.034 -CD-N PRO 1.473 0.014 -N-CA GLN 1.458 0.019 -CA-C GLN 1.525 0.021 -C-O GLN 1.231 0.02 -CA-CB GLN 1.53 0.02 -CB-CG GLN 1.52 0.03 -CG-CD GLN 1.516 0.025 -CD-OE1 GLN 1.231 0.02 -CD-NE2 GLN 1.328 0.021 -N-CA ARG 1.458 0.019 -CA-C ARG 1.525 0.021 -C-O ARG 1.231 0.02 -CA-CB ARG 1.53 0.02 -CB-CG ARG 1.52 0.03 -CG-CD ARG 1.52 0.03 -CD-NE ARG 1.46 0.018 -NE-CZ ARG 1.329 0.014 -CZ-NH1 ARG 1.326 0.018 -CZ-NH2 ARG 1.326 0.018 -N-CA SER 1.458 0.019 -CA-C SER 1.525 0.021 -C-O SER 1.231 0.02 -CA-CB SER 1.53 0.02 -CB-OG SER 1.417 0.02 -N-CA THR 1.458 0.019 -CA-C THR 1.525 0.021 -C-O THR 1.231 0.02 -CA-CB THR 1.54 0.027 -CB-OG1 THR 1.433 0.016 -CB-CG2 THR 1.521 0.033 -N-CA VAL 1.458 0.019 -CA-C VAL 1.525 0.021 -C-O VAL 1.231 0.02 -CA-CB VAL 1.54 0.027 -CB-CG1 VAL 1.521 0.033 -CB-CG2 VAL 1.521 0.033 -N-CA TRP 1.458 0.019 -CA-C TRP 1.525 0.021 -C-O TRP 1.231 0.02 -CA-CB TRP 1.53 0.02 -CB-CG TRP 1.498 0.031 -CG-CD1 TRP 1.365 0.025 -CG-CD2 TRP 1.433 0.018 -CD1-NE1 TRP 1.374 0.021 -NE1-CE2 TRP 1.37 0.011 -CD2-CE2 TRP 1.409 0.017 -CD2-CE3 TRP 1.398 0.016 -CE2-CZ2 TRP 1.394 0.021 -CE3-CZ3 TRP 1.382 0.03 -CZ2-CH2 TRP 1.368 0.019 -CZ3-CH2 TRP 1.4 0.025 -N-CA TYR 1.458 0.019 -CA-C TYR 1.525 0.021 -C-O TYR 1.231 0.02 -CA-CB TYR 1.53 0.02 -CB-CG TYR 1.512 0.022 -CG-CD1 TYR 1.389 0.021 -CG-CD2 TYR 1.389 0.021 -CD1-CE1 TYR 1.382 0.03 -CD2-CE2 TYR 1.382 0.03 -CE1-CZ TYR 1.378 0.024 -CE2-CZ TYR 1.378 0.024 -CZ-OH TYR 1.376 0.021 +CA-CB ALA 1.520 0.021 +N-CA ALA 1.459 0.020 +CA-C ALA 1.525 0.026 +C-O ALA 1.229 0.019 +CA-CB ARG 1.535 0.022 +CB-CG ARG 1.521 0.027 +CG-CD ARG 1.515 0.025 +CD-NE ARG 1.460 0.017 +NE-CZ ARG 1.326 0.013 +CZ-NH1 ARG 1.326 0.013 +CZ-NH2 ARG 1.326 0.013 +N-CA ARG 1.459 0.020 +CA-C ARG 1.525 0.026 +C-O ARG 1.229 0.019 +CA-CB ASN 1.527 0.026 +CB-CG ASN 1.506 0.023 +CG-OD1 ASN 1.235 0.022 +CG-ND2 ASN 1.324 0.025 +N-CA ASN 1.459 0.020 +CA-C ASN 1.525 0.026 +C-O ASN 1.229 0.019 +CA-CB ASP 1.535 0.022 +CB-CG ASP 1.513 0.021 +CG-OD1 ASP 1.249 0.023 +CG-OD2 ASP 1.249 0.023 +N-CA ASP 1.459 0.020 +CA-C ASP 1.525 0.026 +C-O ASP 1.229 0.019 +CA-CB CYS 1.526 0.013 +CB-SG CYS 1.812 0.016 +N-CA CYS 1.459 0.020 +CA-C CYS 1.525 0.026 +C-O CYS 1.229 0.019 +CA-CB GLU 1.535 0.022 +CB-CG GLU 1.517 0.019 +CG-CD GLU 1.515 0.015 +CD-OE1 GLU 1.252 0.011 +CD-OE2 GLU 1.252 0.011 +N-CA GLU 1.459 0.020 +CA-C GLU 1.525 0.026 +C-O GLU 1.229 0.019 +CA-CB GLN 1.535 0.022 +CB-CG GLN 1.521 0.027 +CG-CD GLN 1.506 0.023 +CD-OE1 GLN 1.235 0.022 +CD-NE2 GLN 1.324 0.025 +N-CA GLN 1.459 0.020 +CA-C GLN 1.525 0.026 +C-O GLN 1.229 0.019 +N-CA GLY 1.456 0.015 +CA-C GLY 1.514 0.016 +C-O GLY 1.232 0.016 +CA-CB HIS 1.535 0.022 +CB-CG HIS 1.492 0.016 +CG-ND1 HIS 1.369 0.015 +CG-CD2 HIS 1.353 0.017 +ND1-CE1 HIS 1.343 0.025 +CD2-NE2 HIS 1.415 0.021 +CE1-NE2 HIS 1.322 0.023 +N-CA HIS 1.459 0.020 +CA-C HIS 1.525 0.026 +C-O HIS 1.229 0.019 +CA-CB ILE 1.544 0.023 +CB-CG1 ILE 1.536 0.028 +CB-CG2 ILE 1.524 0.031 +CG1-CD1 ILE 1.500 0.069 +N-CA ILE 1.459 0.020 +CA-C ILE 1.525 0.026 +C-O ILE 1.229 0.019 +CA-CB LEU 1.533 0.023 +CB-CG LEU 1.521 0.029 +CG-CD1 LEU 1.514 0.037 +CG-CD2 LEU 1.514 0.037 +N-CA LEU 1.459 0.020 +CA-C LEU 1.525 0.026 +C-O LEU 1.229 0.019 +CA-CB LYS 1.535 0.022 +CB-CG LYS 1.521 0.027 +CG-CD LYS 1.520 0.034 +CD-CE LYS 1.508 0.025 +CE-NZ LYS 1.486 0.025 +N-CA LYS 1.459 0.020 +CA-C LYS 1.525 0.026 +C-O LYS 1.229 0.019 +CA-CB MET 1.535 0.022 +CB-CG MET 1.509 0.032 +CG-SD MET 1.807 0.026 +SD-CE MET 1.774 0.056 +N-CA MET 1.459 0.020 +CA-C MET 1.525 0.026 +C-O MET 1.229 0.019 +CA-CB PHE 1.535 0.022 +CB-CG PHE 1.509 0.017 +CG-CD1 PHE 1.383 0.015 +CG-CD2 PHE 1.383 0.015 +CD1-CE1 PHE 1.388 0.020 +CD2-CE2 PHE 1.388 0.020 +CE1-CZ PHE 1.369 0.019 +CE2-CZ PHE 1.369 0.019 +N-CA PHE 1.459 0.020 +CA-C PHE 1.525 0.026 +C-O PHE 1.229 0.019 +CA-CB PRO 1.531 0.020 +CB-CG PRO 1.495 0.050 +CG-CD PRO 1.502 0.033 +CD-N PRO 1.474 0.014 +N-CA PRO 1.468 0.017 +CA-C PRO 1.524 0.020 +C-O PRO 1.228 0.020 +CA-CB SER 1.525 0.015 +CB-OG SER 1.418 0.013 +N-CA SER 1.459 0.020 +CA-C SER 1.525 0.026 +C-O SER 1.229 0.019 +CA-CB THR 1.529 0.026 +CB-OG1 THR 1.428 0.020 +CB-CG2 THR 1.519 0.033 +N-CA THR 1.459 0.020 +CA-C THR 1.525 0.026 +C-O THR 1.229 0.019 +CA-CB TRP 1.535 0.022 +CB-CG TRP 1.498 0.018 +CG-CD1 TRP 1.363 0.014 +CG-CD2 TRP 1.432 0.017 +CD1-NE1 TRP 1.375 0.017 +NE1-CE2 TRP 1.371 0.013 +CD2-CE2 TRP 1.409 0.012 +CD2-CE3 TRP 1.399 0.015 +CE2-CZ2 TRP 1.393 0.017 +CE3-CZ3 TRP 1.380 0.017 +CZ2-CH2 TRP 1.369 0.019 +CZ3-CH2 TRP 1.396 0.016 +N-CA TRP 1.459 0.020 +CA-C TRP 1.525 0.026 +C-O TRP 1.229 0.019 +CA-CB TYR 1.535 0.022 +CB-CG TYR 1.512 0.015 +CG-CD1 TYR 1.387 0.013 +CG-CD2 TYR 1.387 0.013 +CD1-CE1 TYR 1.389 0.015 +CD2-CE2 TYR 1.389 0.015 +CE1-CZ TYR 1.381 0.013 +CE2-CZ TYR 1.381 0.013 +CZ-OH TYR 1.374 0.017 +N-CA TYR 1.459 0.020 +CA-C TYR 1.525 0.026 +C-O TYR 1.229 0.019 +CA-CB VAL 1.543 0.021 +CB-CG1 VAL 1.524 0.021 +CB-CG2 VAL 1.524 0.021 +N-CA VAL 1.459 0.020 +CA-C VAL 1.525 0.026 +C-O VAL 1.229 0.019 - Angle Residue Mean StdDev -N-CA-C ALA 111.2 2.8 -CA-C-O ALA 120.8 1.7 -N-CA-CB ALA 110.4 1.5 -C-CA-CB ALA 110.5 1.5 -N-CA-C CYS 111.2 2.8 -CA-C-O CYS 120.8 1.7 -N-CA-CB CYS 110.5 1.7 -C-CA-CB CYS 110.1 1.9 -N-CA-C ASP 111.2 2.8 -CA-C-O ASP 120.8 1.7 -N-CA-CB ASP 110.5 1.7 -C-CA-CB ASP 110.1 1.9 -CA-CB-CG ASP 112.6 1.0 -CB-CG-OD2 ASP 118.4 2.3 -CB-CG-OD1 ASP 118.4 2.3 -OD2-CG-OD1 ASP 122.9 2.4 -N-CA-C GLU 111.2 2.8 -CA-C-O GLU 120.8 1.7 -N-CA-CB GLU 110.5 1.7 -C-CA-CB GLU 110.1 1.9 -CA-CB-CG GLU 114.1 2.0 -CB-CG-CD GLU 112.6 1.7 -CG-CD-OE2 GLU 118.4 2.3 -CG-CD-OE1 GLU 118.4 2.3 -OE2-CD-OE1 GLU 122.9 2.4 -N-CA-C PHE 111.2 2.8 -CA-C-O PHE 120.8 1.7 -N-CA-CB PHE 110.5 1.7 -C-CA-CB PHE 110.1 1.9 -CA-CB-CG PHE 113.8 1.0 -CB-CG-CD1 PHE 120.7 1.7 -CB-CG-CD2 PHE 120.7 1.7 -CG-CD1-CE1 PHE 120.7 1.7 -CG-CD2-CE2 PHE 120.7 1.7 -CD1-CE1-CZ PHE 120.0 1.8 -CD2-CE2-CZ PHE 120.0 1.8 +N-CA-CB ALA 110.1 1.4 +CB-CA-C ALA 110.1 1.5 +N-CA-C ALA 111.0 2.7 +CA-C-O ALA 120.1 2.1 +N-CA-CB ARG 110.6 1.8 +CB-CA-C ARG 110.4 2.0 +CA-CB-CG ARG 113.4 2.2 +CB-CG-CD ARG 111.6 2.6 +CG-CD-NE ARG 111.8 2.1 +CD-NE-CZ ARG 123.6 1.4 +NE-CZ-NH1 ARG 120.3 0.5 +NE-CZ-NH2 ARG 120.3 0.5 +NH1-CZ-NH2 ARG 119.4 1.1 +N-CA-C ARG 111.0 2.7 +CA-C-O ARG 120.1 2.1 +N-CA-CB ASN 110.6 1.8 +CB-CA-C ASN 110.4 2.0 +CA-CB-CG ASN 113.4 2.2 +CB-CG-ND2 ASN 116.7 2.4 +CB-CG-OD1 ASN 121.6 2.0 +ND2-CG-OD1 ASN 121.9 2.3 +N-CA-C ASN 111.0 2.7 +CA-C-O ASN 120.1 2.1 +N-CA-CB ASP 110.6 1.8 +CB-CA-C ASP 110.4 2.0 +CA-CB-CG ASP 113.4 2.2 +CB-CG-OD1 ASP 118.3 0.9 +CB-CG-OD2 ASP 118.3 0.9 +OD1-CG-OD2 ASP 123.3 1.9 +N-CA-C ASP 111.0 2.7 +CA-C-O ASP 120.1 2.1 +N-CA-CB CYS 110.8 1.5 +CB-CA-C CYS 111.5 1.2 +CA-CB-SG CYS 114.2 1.1 +N-CA-C CYS 111.0 2.7 +CA-C-O CYS 120.1 2.1 +N-CA-CB GLU 110.6 1.8 +CB-CA-C GLU 110.4 2.0 +CA-CB-CG GLU 113.4 2.2 +CB-CG-CD GLU 114.2 2.7 +CG-CD-OE1 GLU 118.3 2.0 +CG-CD-OE2 GLU 118.3 2.0 +OE1-CD-OE2 GLU 123.3 1.2 +N-CA-C GLU 111.0 2.7 +CA-C-O GLU 120.1 2.1 +N-CA-CB GLN 110.6 1.8 +CB-CA-C GLN 110.4 2.0 +CA-CB-CG GLN 113.4 2.2 +CB-CG-CD GLN 111.6 2.6 +CG-CD-OE1 GLN 121.6 2.0 +CG-CD-NE2 GLN 116.7 2.4 +OE1-CD-NE2 GLN 121.9 2.3 +N-CA-C GLN 111.0 2.7 +CA-C-O GLN 120.1 2.1 +N-CA-C GLY 113.1 2.5 +CA-C-O GLY 120.6 1.8 +N-CA-CB HIS 110.6 1.8 +CB-CA-C HIS 110.4 2.0 +CA-CB-CG HIS 113.6 1.7 +CB-CG-ND1 HIS 123.2 2.5 +CB-CG-CD2 HIS 130.8 3.1 +CG-ND1-CE1 HIS 108.2 1.4 +ND1-CE1-NE2 HIS 109.9 2.2 +CE1-NE2-CD2 HIS 106.6 2.5 +NE2-CD2-CG HIS 109.2 1.9 +CD2-CG-ND1 HIS 106.0 1.4 +N-CA-C HIS 111.0 2.7 +CA-C-O HIS 120.1 2.1 +N-CA-CB ILE 110.8 2.3 +CB-CA-C ILE 111.6 2.0 +CA-CB-CG1 ILE 111.0 1.9 +CB-CG1-CD1 ILE 113.9 2.8 +CA-CB-CG2 ILE 110.9 2.0 +CG1-CB-CG2 ILE 111.4 2.2 +N-CA-C ILE 111.0 2.7 +CA-C-O ILE 120.1 2.1 +N-CA-CB LEU 110.4 2.0 +CB-CA-C LEU 110.2 1.9 +CA-CB-CG LEU 115.3 2.3 +CB-CG-CD1 LEU 111.0 1.7 +CB-CG-CD2 LEU 111.0 1.7 +CD1-CG-CD2 LEU 110.5 3.0 +N-CA-C LEU 111.0 2.7 +CA-C-O LEU 120.1 2.1 +N-CA-CB LYS 110.6 1.8 +CB-CA-C LYS 110.4 2.0 +CA-CB-CG LYS 113.4 2.2 +CB-CG-CD LYS 111.6 2.6 +CG-CD-CE LYS 111.9 3.0 +CD-CE-NZ LYS 111.7 2.3 +N-CA-C LYS 111.0 2.7 +CA-C-O LYS 120.1 2.1 +N-CA-CB MET 110.6 1.8 +CB-CA-C MET 110.4 2.0 +CA-CB-CG MET 113.3 1.7 +CB-CG-SD MET 112.4 3.0 +CG-SD-CE MET 100.2 1.6 +N-CA-C MET 111.0 2.7 +CA-C-O MET 120.1 2.1 +N-CA-CB PHE 110.6 1.8 +CB-CA-C PHE 110.4 2.0 +CA-CB-CG PHE 113.9 2.4 +CB-CG-CD1 PHE 120.8 0.7 +CB-CG-CD2 PHE 120.8 0.7 +CD1-CG-CD2 PHE 118.3 1.3 +CG-CD1-CE1 PHE 120.8 1.1 +CG-CD2-CE2 PHE 120.8 1.1 +CD1-CE1-CZ PHE 120.1 1.2 +CD2-CE2-CZ PHE 120.1 1.2 CE1-CZ-CE2 PHE 120.0 1.8 -CD1-CG-CD2 PHE 118.6 1.5 -N-CA-C GLY 112.5 2.9 -CA-C-O GLY 120.8 2.1 -N-CA-C HIS 111.2 2.8 -CA-C-O HIS 120.8 1.7 -N-CA-CB HIS 110.5 1.7 -C-CA-CB HIS 110.1 1.9 -CA-CB-CG HIS 113.8 1.0 -CB-CG-ND1 HIS 122.7 1.5 -CG-ND1-CE1 HIS 109.3 1.7 -ND1-CE1-NE2 HIS 108.4 1.0 -CE1-NE2-CD2 HIS 109.0 1.0 -NE2-CD2-CG HIS 107.2 1.0 -CD2-CG-ND1 HIS 106.1 1.0 -CB-CG-CD2 HIS 131.2 1.3 -N-CA-C ILE 111.2 2.8 -CA-C-O ILE 120.8 1.7 -N-CA-CB ILE 111.5 1.7 -C-CA-CB ILE 109.1 2.2 -CA-CB-CG2 ILE 110.5 1.7 -CA-CB-CG1 ILE 110.4 1.7 -CG2-CB-CG1 ILE 110.7 3.0 -CB-CG1-CD1 ILE 113.8 2.1 -N-CA-C LYS 111.2 2.8 -CA-C-O LYS 120.8 1.7 -N-CA-CB LYS 110.5 1.7 -C-CA-CB LYS 110.1 1.9 -CA-CB-CG LYS 114.1 2.0 -CB-CG-CD LYS 111.3 2.3 -CG-CD-CE LYS 111.3 2.3 -CD-CE-NZ LYS 111.9 3.2 -N-CA-C LEU 111.2 2.8 -CA-C-O LEU 120.8 1.7 -N-CA-CB LEU 110.5 1.7 -C-CA-CB LEU 110.1 1.9 -CA-CB-CG LEU 116.3 3.5 -CB-CG-CD1 LEU 110.7 3.0 -CB-CG-CD2 LEU 110.7 3.0 -CD1-CG-CD2 LEU 110.8 2.2 -N-CA-C MET 111.2 2.8 -CA-C-O MET 120.8 1.7 -N-CA-CB MET 110.5 1.7 -C-CA-CB MET 110.1 1.9 -CA-CB-CG MET 114.1 2.0 -CB-CG-SD MET 112.7 3.0 -CG-SD-CE MET 100.9 2.2 -N-CA-C ASN 111.2 2.8 -CA-C-O ASN 120.8 1.7 -N-CA-CB ASN 110.5 1.7 -C-CA-CB ASN 110.1 1.9 -CA-CB-CG ASN 112.6 1.0 -CB-CG-ND2 ASN 116.4 1.5 -CB-CG-OD1 ASN 120.8 2.0 -ND2-CG-OD1 ASN 122.6 1.0 -N-CA-C PRO 111.8 2.5 -CA-C-O PRO 120.8 1.7 -N-CA-CB PRO 103.0 1.1 -C-CA-CB PRO 110.1 1.9 -CA-CB-CG PRO 104.5 1.9 -CB-CG-CD PRO 106.1 3.2 +N-CA-C PHE 111.0 2.7 +CA-C-O PHE 120.1 2.1 +N-CA-CB PRO 103.3 1.2 +CB-CA-C PRO 111.7 2.1 +CA-CB-CG PRO 104.8 1.9 +CB-CG-CD PRO 106.5 3.9 CG-CD-N PRO 103.2 1.5 -CD-N-CA PRO 112.0 1.4 -N-CA-C GLN 111.2 2.8 -CA-C-O GLN 120.8 1.7 -N-CA-CB GLN 110.5 1.7 -C-CA-CB GLN 110.1 1.9 -CA-CB-CG GLN 114.1 2.0 -CB-CG-CD GLN 112.6 1.7 -CG-CD-NE2 GLN 116.4 1.5 -CG-CD-OE1 GLN 120.8 2.0 -NE2-CD-OE1 GLN 122.6 1.0 -N-CA-C ARG 111.2 2.8 -CA-C-O ARG 120.8 1.7 -N-CA-CB ARG 110.5 1.7 -C-CA-CB ARG 110.1 1.9 -CA-CB-CG ARG 114.1 2.0 -CB-CG-CD ARG 111.3 2.3 -CG-CD-NE ARG 112.0 2.2 -CD-NE-CZ ARG 124.2 1.5 -NE-CZ-NH1 ARG 120.0 1.9 -NE-CZ-NH2 ARG 120.0 1.9 -NH1-CZ-NH2 ARG 119.7 1.8 -N-CA-C SER 111.2 2.8 -CA-C-O SER 120.8 1.7 -N-CA-CB SER 110.5 1.7 -C-CA-CB SER 110.1 1.9 -CA-CB-OG SER 111.1 2.0 -N-CA-C THR 111.2 2.8 -CA-C-O THR 120.8 1.7 -N-CA-CB THR 111.5 1.7 -C-CA-CB THR 109.1 2.2 -CA-CB-CG2 THR 110.5 1.7 -CA-CB-OG1 THR 109.6 1.5 -CG2-CB-OG1 THR 109.3 2.0 -N-CA-C VAL 111.2 2.8 -CA-C-O VAL 120.8 1.7 -N-CA-CB VAL 111.5 1.7 -C-CA-CB VAL 109.1 2.2 -CA-CB-CG1 VAL 110.5 1.7 -CA-CB-CG2 VAL 110.5 1.7 -CG1-CB-CG2 VAL 110.8 2.2 -N-CA-C TRP 111.2 2.8 -CA-C-O TRP 120.8 1.7 -N-CA-CB TRP 110.5 1.7 -C-CA-CB TRP 110.1 1.9 -CA-CB-CG TRP 113.6 1.9 -CB-CG-CD1 TRP 126.9 1.5 -CB-CG-CD2 TRP 126.8 1.4 -CD1-CG-CD2 TRP 106.3 1.6 -CG-CD1-NE1 TRP 110.2 1.3 -CD1-NE1-CE2 TRP 108.9 1.8 -NE1-CE2-CZ2 TRP 130.1 1.5 -NE1-CE2-CD2 TRP 107.4 1.3 -CZ2-CE2-CD2 TRP 122.4 1.0 -CE2-CZ2-CH2 TRP 117.5 1.3 -CZ2-CH2-CZ3 TRP 121.5 1.3 -CH2-CZ3-CE3 TRP 121.1 1.3 -CZ3-CE3-CD2 TRP 118.6 1.3 -CE3-CD2-CG TRP 133.9 1.0 -CE3-CD2-CE2 TRP 118.8 1.0 -CG-CD2-CE2 TRP 107.2 1.2 -N-CA-C TYR 111.2 2.8 -CA-C-O TYR 120.8 1.7 -N-CA-CB TYR 110.5 1.7 -C-CA-CB TYR 110.1 1.9 -CA-CB-CG TYR 113.9 1.8 -CB-CG-CD1 TYR 120.8 1.5 -CB-CG-CD2 TYR 120.8 1.5 -CG-CD1-CE1 TYR 121.2 1.5 -CG-CD2-CE2 TYR 121.2 1.5 -CD1-CE1-CZ TYR 119.6 1.8 -CD2-CE2-CZ TYR 119.6 1.8 -CE1-CZ-CE2 TYR 120.3 2.0 -CD1-CG-CD2 TYR 118.1 1.5 -CE1-CZ-OH TYR 119.9 3.0 -CE2-CZ-OH TYR 119.9 3.0 +CA-N-CD PRO 111.7 1.4 +N-CA-C PRO 112.1 2.6 +CA-C-O PRO 120.2 2.4 +N-CA-CB SER 110.5 1.5 +CB-CA-C SER 110.1 1.9 +CA-CB-OG SER 111.2 2.7 +N-CA-C SER 111.0 2.7 +CA-C-O SER 120.1 2.1 +N-CA-CB THR 110.3 1.9 +CB-CA-C THR 111.6 2.7 +CA-CB-OG1 THR 109.0 2.1 +CA-CB-CG2 THR 112.4 1.4 +OG1-CB-CG2 THR 110.0 2.3 +N-CA-C THR 111.0 2.7 +CA-C-O THR 120.1 2.1 +N-CA-CB TRP 110.6 1.8 +CB-CA-C TRP 110.4 2.0 +CA-CB-CG TRP 113.7 1.9 +CB-CG-CD1 TRP 127.0 1.3 +CB-CG-CD2 TRP 126.6 1.3 +CD1-CG-CD2 TRP 106.3 0.8 +CG-CD1-NE1 TRP 110.1 1.0 +CD1-NE1-CE2 TRP 109.0 0.9 +NE1-CE2-CD2 TRP 107.3 1.0 +CE2-CD2-CG TRP 107.3 0.8 +CG-CD2-CE3 TRP 133.9 0.9 +NE1-CE2-CZ2 TRP 130.4 1.1 +CE3-CD2-CE2 TRP 118.7 1.2 +CD2-CE2-CZ2 TRP 122.3 1.2 +CE2-CZ2-CH2 TRP 117.4 1.0 +CZ2-CH2-CZ3 TRP 121.6 1.2 +CH2-CZ3-CE3 TRP 121.2 1.1 +CZ3-CE3-CD2 TRP 118.8 1.3 +N-CA-C TRP 111.0 2.7 +CA-C-O TRP 120.1 2.1 +N-CA-CB TYR 110.6 1.8 +CB-CA-C TYR 110.4 2.0 +CA-CB-CG TYR 113.4 1.9 +CB-CG-CD1 TYR 121.0 0.6 +CB-CG-CD2 TYR 121.0 0.6 +CD1-CG-CD2 TYR 117.9 1.1 +CG-CD1-CE1 TYR 121.3 0.8 +CG-CD2-CE2 TYR 121.3 0.8 +CD1-CE1-CZ TYR 119.8 0.9 +CD2-CE2-CZ TYR 119.8 0.9 +CE1-CZ-CE2 TYR 119.8 1.6 +CE1-CZ-OH TYR 120.1 2.7 +CE2-CZ-OH TYR 120.1 2.7 +N-CA-C TYR 111.0 2.7 +CA-C-O TYR 120.1 2.1 +N-CA-CB VAL 111.5 2.2 +CB-CA-C VAL 111.4 1.9 +CA-CB-CG1 VAL 110.9 1.5 +CA-CB-CG2 VAL 110.9 1.5 +CG1-CB-CG2 VAL 110.9 1.6 +N-CA-C VAL 111.0 2.7 +CA-C-O VAL 120.1 2.1 - -Non-bonded distance Minimum Dist Tolerance -C-C 2.10 0.5 -C-N 2.10 0.5 -C-S 2.45 0.5 -C-O 2.25 0.5 -N-N 2.05 0.5 -N-S 2.55 0.5 -N-O 2.10 0.5 -O-S 2.45 0.5 -O-O 2.05 0.5 -S-S 1.80 0.5 +Non-bonded distance Minimum Dist Tolerance +C-C 3.4 1.5 +C-N 3.25 1.5 +C-S 3.5 1.5 +C-O 3.22 1.5 +N-N 3.1 1.5 +N-S 3.35 1.5 +N-O 3.07 1.5 +O-S 3.32 1.5 +O-O 3.04 1.5 +S-S 2.03 1.0 - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/mol/alg/src/trajectory_analysis.cc b/modules/mol/alg/src/trajectory_analysis.cc index 4a2671c01b981c8eed22fc8ebe9c9a86a66664e7..5adf3c6eb1bc584522abcfec8725ebe2651fe213 100644 --- a/modules/mol/alg/src/trajectory_analysis.cc +++ b/modules/mol/alg/src/trajectory_analysis.cc @@ -396,7 +396,7 @@ std::vector<Real> AnalyzeAromaticRingInteraction(const CoordGroupHandle& traj, c rmsf+=geom::Dot(v,v); } } - return pow(rmsf/float(n_atoms*n_frames),0.5); + return sqrt(rmsf/float(n_atoms*n_frames)); } }}} //ns diff --git a/modules/mol/alg/tests/test_superposition.cc b/modules/mol/alg/tests/test_superposition.cc index a0d4d230914fe6842c50b670af67ad82044ed70b..83bc902b383800cd348f646d146a41e807de368b 100644 --- a/modules/mol/alg/tests/test_superposition.cc +++ b/modules/mol/alg/tests/test_superposition.cc @@ -23,6 +23,7 @@ #include <ost/mol/alg/svd_superpose.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> using namespace ost; @@ -77,7 +78,7 @@ struct Fixture { }; -BOOST_AUTO_TEST_SUITE( mol_alg ) +BOOST_AUTO_TEST_SUITE( mol_alg ); BOOST_AUTO_TEST_CASE(superposition_svd) { @@ -101,4 +102,4 @@ BOOST_AUTO_TEST_CASE(superposition_svd) BOOST_CHECK(abs(res.rmsd)<0.0001); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/alg/tests/tests.cc b/modules/mol/alg/tests/tests.cc index 4308786c168fa90c76c2b7e0417e86407509efe8..fb9a32714d45fb72999e591145120f97a809923d 100644 --- a/modules/mol/alg/tests/tests.cc +++ b/modules/mol/alg/tests/tests.cc @@ -22,4 +22,6 @@ */ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_mol_alg +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/mol/base/doc/entity.rst b/modules/mol/base/doc/entity.rst index 94b8a1b3b14bbb62f03c68a043cf270b1e827e9f..847dcefb73a1b275277c69eb14e94aa4928a8103 100644 --- a/modules/mol/base/doc/entity.rst +++ b/modules/mol/base/doc/entity.rst @@ -181,7 +181,7 @@ The Handle Classes # select calpha atoms of peptides calphas=ent.Select('aname=CA and peptide=true') - # select atoms in a box of size 10, centered at the origin + # select atoms in a box of size 10, centred at the origin in_box=ent.Select('x=-5:5 and y=-5:5 and z=-5:5') :param query: The query to be executed. See :class:`Query` for details. @@ -256,7 +256,7 @@ The Handle Classes .. method:: FindWithin(pos, radius) - Find all atoms in sphere of given radius centered at *pos*. To turn the + Find all atoms in sphere of given radius centred at *pos*. To turn the returned list of atoms into an :class:`EntityView`, use :func:`CreateViewFromAtomList`. @@ -856,44 +856,59 @@ The View Classes Returns a copy of this entity. Provided for `duck-typing <http://en.wikipedia.org/wiki/Duck_typing>` purposes. - :rtype: EntityView - + :rtype: :class:`EntityView` + .. method:: AddChain(chain_handle[, view_add_flags]) Add chain to view. By default, only the chain is added to the view, but not - its residues and atoms. This behavior can be changed by passing in an - appropriate set of `view_add_flags` - - :param chain_handle: - :type chain_handle: ChainHandle - :param view_add_flags: An ORed together combination of `view_add_flags`. - :type view_add_flags: int - :rtype: class:`ChainView` + its residues and atoms. This behaviour can be changed by passing in an + appropriate set of `view_add_flags`. + + The following example just adds a chain without residues and atoms: + + .. code-block:: python + + pdb = ost.io.LoadPDB(<PDB file name>) + v = pdb.CreateEmptyView() + v.AddChain(pdb.chains[0]) + + To **copy** a whole chain, go like: + + .. code-block:: python + + pdb = ost.io.LoadPDB(<PDB file name>) + v = pdb.CreateEmptyView() + v.AddChain(pdb.chains[0], ost.mol.INCLUDE_ALL) + + :param chain_handle: The chain handle to be added. + :type chain_handle: :class:`ChainHandle` + :param view_add_flags: An ORed together combination of :ref:`viewaddflags`. + :type view_add_flags: :class:`int` + :rtype: :class:`ChainView` .. method:: AddResidue(residue_handle[, view_add_flags]) - Add residue to view. If the residue's chain is not already part of the view, - it will be added. By default, only the residue is added, but not its atoms. - This behaviour can be modified by passing in an appropriate combination of - `view_add_flags`. - - :param residue_handle: - :type residue_handle: ResidueHandle - :param view_add_flags: - :type view_add_flags: int - :rtype: class:`ResidueView` + Add residue to view. If the residue's chain is not already part of the + view, it will be added. By default, only the residue is added, but not its + atoms. This behaviour can be modified by passing in an appropriate + combination of :ref:`viewaddflags`. + + :param residue_handle: The residue handle to be added + :type residue_handle: :class:`ResidueHandle` + :param view_add_flags: An ORed together combination of :ref:`viewaddflags` + :type view_add_flags: :class:`int` + :rtype: :class:`ResidueView` .. method:: AddAtom(atom_handle[, view_add_flags]) Add the atom to view. The chain and residue of the atom are added to the view if they haven't already been added. - :param atom_handle: The atom handle - :type atom_handle: AtomHandle - :param view_add_flags: An ORed together combination of ViewAddFlags - :type view_add_flags: int - :rtype: class:`AtomView` + :type atom_handle: :class:`AtomHandle` + :param view_add_flags: An ORed together combination of :ref:`viewaddflags` + :type view_add_flags: :class:`int` + :rtype: :class:`AtomView` .. method:: AddBond(bond_handle) @@ -1210,24 +1225,25 @@ The View Classes Add atom to the view. If the residue of the atom is not already part of the view, it will be added. If the atom does not belong to chain, the result is - undefined. + undefined. Foo :param atom_handle: The atom to be added :type atom_handle: :class:`AtomHandle` - :param view_add_flags: An ORed together combination of ViewAddFlags - :type view_add_flags: int + :param view_add_flags: An ORed together combination of :ref:`viewaddflags` + :type view_add_flags: :class:`int` :rtype: :class:`AtomView` .. method:: AddResidue(residue_handle[, view_add_flags]) Add residue to the view. If the atom does not belong to chain, the result is - undefined. By default, only the residue, but no atoms are added to the view. - To change the behavior, pass in a suitable combination of `view_add_flags`. + undefined. By default, only the residue, but no atoms are added to the + view. To change the behavior, pass in a suitable combination of + :ref:`viewaddflags`. - :param residue_handle: + :param residue_handle: The residue handle to be added. :type residue_handle: :class:`ResidueHandle` - :param view_add_flags: - :type view_add_flags: int + :param view_add_flags: An ORed together combination of :ref:`viewaddflags` + :type view_add_flags: :class:`int` :rtype: :class:`ResidueView` .. method:: FindAtom(res_num, atom_name) @@ -1462,11 +1478,12 @@ The View Classes .. method:: AddAtom(atom_handle[, flags]) - Add atom to the view. - :param atom_handle: + Add atom to the view. + + :param atom_handle: Atom handle to be added :type atom_handle: :class:`AtomHandle` - :param flags: An ORed together combination of ViewAddFlags. - :type flags: int + :param flags: An ORed together combination of :ref:`viewaddflags` + :type flags: :class:`int` :rtype: :class:`AtomView` .. method:: GetCenterOfAtoms() @@ -1618,3 +1635,23 @@ ChainType functions :returns: :class:`str` +.. _viewaddflags: + +ViewAddFlags +-------------------------------------------------------------------------------- + +Those are the flags controlling behaviour of routines adding handles to views. + +* ``INCLUDE_ATOMS`` - Include all atoms when adding a residue handle to a view + +* ``INCLUDE_RESIDUES`` - Include all residues when adding a chain to a view + +* ``INCLUDE_CHAINS`` - Include all chains when creating a new entity view + +* ``INCLUDE_ALL`` = ``INCLUDE_ATOMS`` | ``INCLUDE_RESIDUES`` | + ``INCLUDE_CHAINS`` - Convenience flags to include all substructures + +* ``CHECK_DUPLICATES`` - If set, it will be checked that no duplicates are + created when adding a new handle + + diff --git a/modules/mol/base/pymod/export_entity.cc b/modules/mol/base/pymod/export_entity.cc index 6fda49c793342259e0d3ab5078716d3dda8c0a5e..adf2c83b7621420f1000aafa96439f90d34a203f 100644 --- a/modules/mol/base/pymod/export_entity.cc +++ b/modules/mol/base/pymod/export_entity.cc @@ -63,15 +63,15 @@ ICSEditor depr_request_ics_editor(EntityHandle e, EditMode m) return e.EditICS(m); } + +#if OST_NUMPY_SUPPORT_ENABLED + bool less_index(const mol::AtomHandle& a1, const mol::AtomHandle& a2) { return a1.GetIndex()<a2.GetIndex(); } - - PyObject* get_pos2(EntityHandle& entity, bool id_sorted) { -#if OST_NUMPY_SUPPORT_ENABLED npy_intp dims[]={entity.GetAtomCount(),3}; PyObject* na = PyArray_SimpleNew(2,dims,NPY_FLOAT); npy_float* nad = reinterpret_cast<npy_float*>(PyArray_DATA(na)); @@ -93,10 +93,6 @@ PyObject* get_pos2(EntityHandle& entity, bool id_sorted) } } return na; -#else - throw std::runtime_error("GetPositions disabled, since numpy support is not compiled in"); - return 0; -#endif } PyObject* get_pos1(EntityHandle& entity) @@ -104,6 +100,9 @@ PyObject* get_pos1(EntityHandle& entity) return get_pos2(entity,true); } + + +#endif } // ns void export_Entity() @@ -208,3 +207,4 @@ void export_Entity() .def(vector_indexing_suite<EntityHandleList>()) ; } + diff --git a/modules/mol/base/pymod/export_entity_view.cc b/modules/mol/base/pymod/export_entity_view.cc index 9d724a57982f024103e2949ad56b7eda5e57eea4..4ce29c03b4be50ba28d895fa957b25a626fbe690 100644 --- a/modules/mol/base/pymod/export_entity_view.cc +++ b/modules/mol/base/pymod/export_entity_view.cc @@ -18,6 +18,9 @@ //------------------------------------------------------------------------------ #include <boost/python.hpp> #include <boost/python/suite/indexing/vector_indexing_suite.hpp> +#if BOOST_VERSION<103400 +#include <boost/python/detail/api_placeholder.hpp> +#endif using namespace boost::python; #include <ost/export_helper/pair_to_tuple_conv.hh> diff --git a/modules/mol/base/src/coord_frame.cc b/modules/mol/base/src/coord_frame.cc index 1c30611b3b82a75ffd6660c6980183a0a94e5663..97803e242b4f057c9e02a166fd303334c0f6af72 100644 --- a/modules/mol/base/src/coord_frame.cc +++ b/modules/mol/base/src/coord_frame.cc @@ -39,13 +39,12 @@ namespace ost { namespace mol { */ Real Eval2AngleDist(Real phi, Real phi0, Real psi, Real psi0, Real delta) { - Real d1,d2,d; - d1=abs(phi-phi0); - d2=abs(psi-psi0); - if (d1>M_PI) d1=abs(d1-2.*M_PI); - if (d2>M_PI) d1=abs(d2-2.*M_PI); - d=(pow(d1,2.)+pow(d2,2.))/pow(delta,2.); - return 1./(1+d); + Real d1=std::abs(phi-phi0); + Real d2=std::abs(psi-psi0); + if (d1>M_PI) d1=std::abs(d1-2.*M_PI); + if (d2>M_PI) d1=std::abs(d2-2.*M_PI); + Real d=(d1*d1+d2*d2)/(delta*delta); + return 1.0/(1.0+d); } } @@ -138,7 +137,7 @@ namespace ost { namespace mol { val=geom::Length2(av_ref-av_sele); rmsd+=val; } - return pow(rmsd/indices_sele.size(),0.5); + return sqrt(rmsd/indices_sele.size()); } Real CoordFrame::GetRMSD(const EntityView& reference_view,const EntityView& sele_view) const @@ -303,8 +302,10 @@ namespace ost { namespace mol { psi=geom::DihedralAngle(n,ca,c,n_next); score.push_back(Eval2AngleDist(phi,phi_0,psi,psi_0,delta)); } - score2[0]=pow(score[0]*score[1],3./2.); - score2[n_atoms-3]=pow(score[n_atoms-3]*score[n_atoms-4],3./2.); + score2[0]=sqrt(score[0]*score[1]*score[0]*score[1]*score[0]*score[1]); + score2[n_atoms-3]=sqrt(score[n_atoms-3]*score[n_atoms-4]* + score[n_atoms-3]*score[n_atoms-4]* + score[n_atoms-3]*score[n_atoms-4]); for (unsigned long i=1; i!=n_atoms-3; ++i) { score2[i]=score[i-1]*score[i]*score[i+1]; } diff --git a/modules/mol/base/src/residue_prop.hh b/modules/mol/base/src/residue_prop.hh index e86eef5f11b16ba4eed55153e0cb38901faedd1e..4a411cca6e27250fdd23d4b538ffea6064b8d106 100644 --- a/modules/mol/base/src/residue_prop.hh +++ b/modules/mol/base/src/residue_prop.hh @@ -34,6 +34,12 @@ class DLLEXPORT ResNum: private boost::unit_steppable<ResNum> > > > > { public: + + // needed to wrap certain map classes + ResNum(): + num_(1),alt_('\0') + {} + ResNum(int n): num_(n), alt_('\0') { } diff --git a/modules/mol/base/src/transform.cc b/modules/mol/base/src/transform.cc index d035bf2b9a0b9887f172f492fe7ed185ead7ac1f..9202ed0b3971110a1f6298f70a9c1f30f46ea6f6 100644 --- a/modules/mol/base/src/transform.cc +++ b/modules/mol/base/src/transform.cc @@ -49,6 +49,7 @@ void Transform::SetMatrix(const Mat4& m) { tm_=m; ttm_ = Transpose(tm_); + update_components(); } Mat4 Transform::GetTransposedMatrix() const @@ -213,6 +214,15 @@ void Transform::update_tm() ttm_ = Transpose(tm_); } +void Transform::update_components() +{ + rot_ = tm_.ExtractRotation(); + cen_ = tm_.ExtractTranslation(); + trans_[0] = tm_(3,0); + trans_[1] = tm_(3,1); + trans_[2] = tm_(3,2); +} + #if(OST_INFO_ENABLED) Transform TransformFromInfo(const info::InfoGroup& group) { diff --git a/modules/mol/base/src/transform.hh b/modules/mol/base/src/transform.hh index 726b578a73f82ee27ab77c0303df8e31a41cc39d..20ef4820efca693a968d29ce420f46823b8454fe 100644 --- a/modules/mol/base/src/transform.hh +++ b/modules/mol/base/src/transform.hh @@ -83,6 +83,7 @@ private: geom::Mat4 ttm_; void update_tm(); + void update_components(); }; diff --git a/modules/mol/base/tests/CMakeLists.txt b/modules/mol/base/tests/CMakeLists.txt index 5085b0b10b257fab18361001a1cb7a55b796769d..c29dc6adfe3d5ec1bbe2e85a5a587940b35848c2 100644 --- a/modules/mol/base/tests/CMakeLists.txt +++ b/modules/mol/base/tests/CMakeLists.txt @@ -10,6 +10,7 @@ set(OST_MOL_BASE_UNIT_TESTS test_query.cc test_surface.cc test_residue.cc + test_transform.cc test_view.cc test_view_op.cc tests.cc diff --git a/modules/mol/base/tests/test_atom_groups.cc b/modules/mol/base/tests/test_atom_groups.cc index 01377b5f5ee7458bf8d360e6b463643eecec4ace..fd55845fe2fb550df4545842f0ac92bdf53f3b1c 100644 --- a/modules/mol/base/tests/test_atom_groups.cc +++ b/modules/mol/base/tests/test_atom_groups.cc @@ -23,15 +23,16 @@ #include <ost/message.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include "dummy_ent.hh" using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE(mol_base) +BOOST_AUTO_TEST_SUITE(mol_base); -BOOST_AUTO_TEST_CASE(switch_pos) +BOOST_AUTO_TEST_CASE(switch_pos) { test::DummyEnt ent; geom::Vec3 y=geom::Vec3(0.0, 1.0, 0.0); @@ -85,4 +86,4 @@ BOOST_AUTO_TEST_CASE(atom_group_triv) BOOST_CHECK_EQUAL(names[0], "B"); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_chain.cc b/modules/mol/base/tests/test_chain.cc index 3b7bbd85b15bee45ec61832548dfc97541893257..e6587c2992be6486d31bb173625db9e9dbc670ac 100644 --- a/modules/mol/base/tests/test_chain.cc +++ b/modules/mol/base/tests/test_chain.cc @@ -24,6 +24,7 @@ #include <ost/integrity_error.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::mol; @@ -72,7 +73,7 @@ void test_res_pos() { find_and_check_res(ch1, ResNum(13)); } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(test_comparison) { @@ -334,4 +335,4 @@ BOOST_AUTO_TEST_CASE(chain_description) BOOST_CHECK(ch1.GetDescription() == description); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_conn.cc b/modules/mol/base/tests/test_conn.cc index e908f8f89ef59e30edd382d25f82b053ac23dbda..e9c5bcfe10b2fd7196fbcd0c1f4ed5a178587bb0 100644 --- a/modules/mol/base/tests/test_conn.cc +++ b/modules/mol/base/tests/test_conn.cc @@ -22,11 +22,12 @@ #include <ost/mol/mol.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(connect) { @@ -56,4 +57,4 @@ BOOST_AUTO_TEST_CASE(connect) BOOST_CHECK(n.GetBondCount()==1); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_coord_group.cc b/modules/mol/base/tests/test_coord_group.cc index 1fc365ad0382a256ee781c0cf69f0c93afc8a4fa..7e3d385982636a346a6b88ea6b143b410352d64d 100644 --- a/modules/mol/base/tests/test_coord_group.cc +++ b/modules/mol/base/tests/test_coord_group.cc @@ -21,6 +21,7 @@ */ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> #include <ost/mol/coord_group.hh> @@ -28,7 +29,7 @@ using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( io ) +BOOST_AUTO_TEST_SUITE( io ); BOOST_AUTO_TEST_CASE(coord_group) { @@ -81,4 +82,4 @@ BOOST_AUTO_TEST_CASE(coord_group) BOOST_CHECK(ad.GetPos()==geom::Vec3(9,10,11)); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_delete.cc b/modules/mol/base/tests/test_delete.cc index ccbce7045a54980a158f07ffe5afb3babc631671..20799d4ddff3c07b9cf5cd2d72dd55f828d340a0 100644 --- a/modules/mol/base/tests/test_delete.cc +++ b/modules/mol/base/tests/test_delete.cc @@ -23,6 +23,7 @@ #include <ost/log.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/message.hh> #include <ost/geom/geom.hh> @@ -66,7 +67,7 @@ struct Fixture { TorsionHandle t; }; -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(atom_delete) { @@ -77,4 +78,4 @@ BOOST_AUTO_TEST_CASE(atom_delete) BOOST_CHECK_NO_THROW(f.e.Apply(ev)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_entity.cc b/modules/mol/base/tests/test_entity.cc index 944dd6809d1eab014a0dc34d1a4d90fddbb4da46..46a4de626f41d8a37c57c8b0292ab2e7605dca2b 100644 --- a/modules/mol/base/tests/test_entity.cc +++ b/modules/mol/base/tests/test_entity.cc @@ -23,18 +23,20 @@ #include <ost/geom/vec_mat_predicates.hh> #include <ost/mol/chem_class.hh> #include <ost/mol/mol.hh> +#include <ost/mol/property_id.hh> #include <cmath> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #define CHECK_TRANSFORMED_ATOM_POSITION(ATOM,TARGET) \ - BOOST_CHECK(vec3_is_close(ATOM.GetPos(), TARGET)) + BOOST_CHECK(vec3_is_close(ATOM.GetPos(), TARGET,Real(0.1))) #define CHECK_ORIGINAL_ATOM_POSITION(ATOM,TARGET) \ - BOOST_CHECK(vec3_is_close(ATOM.GetOriginalPos(), TARGET)) + BOOST_CHECK(vec3_is_close(ATOM.GetOriginalPos(), TARGET,Real(0.1))) #define CHECK_ALTERNATE_ATOM_POSITION(ATOM,TARGET,GROUP) \ - BOOST_CHECK(vec3_is_close(ATOM.GetAltPos(GROUP), TARGET)) + BOOST_CHECK(vec3_is_close(ATOM.GetAltPos(GROUP), TARGET,Real(0.1))) using namespace ost; using namespace ost::mol; @@ -72,7 +74,7 @@ EntityHandle make_test_entity() return eh; } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(throw_invalid_ent_handle) @@ -412,4 +414,19 @@ BOOST_AUTO_TEST_CASE(rename_atom) BOOST_CHECK_EQUAL(atom.GetName(), "B"); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_CASE(minmax) +{ + EntityHandle eh=make_test_entity(); + EntityView ev = eh.CreateFullView(); + mol::AtomViewList avl = ev.GetAtomList(); + mol::AtomViewList::iterator i; + int n=0.0; + for (i=avl.begin(); i!=avl.end(); ++i, ++n) { + i->SetFloatProp("test", n); + } + std::pair<float,float> minmax = ev.GetMinMax("test", Prop::ATOM); + BOOST_CHECK_EQUAL(minmax.first, 0.0); + BOOST_CHECK_EQUAL(minmax.second, 7.0); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_ics.cc b/modules/mol/base/tests/test_ics.cc index 4f84f6a78bf0882302f9d5edce87ed13656b6064..c2285ee1b0464ce64e7372e041b760317b0a04fb 100644 --- a/modules/mol/base/tests/test_ics.cc +++ b/modules/mol/base/tests/test_ics.cc @@ -23,6 +23,8 @@ #include <ost/log.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/message.hh> #include <ost/geom/geom.hh> @@ -101,7 +103,7 @@ bool test_angle(Real a, Real e) { return std::abs(fmod(float(a-e), float(M_PI/2)))<EPSILON; } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(ics_update_icsbondlength) { @@ -115,11 +117,11 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_unbuffered) Real eps = 0.0001; TorsionStructure s; ICSEditor e = s.e.EditICS(mol::UNBUFFERED_EDIT); - BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps)); + BOOST_CHECK_CLOSE(std::abs(s.t1.GetAngle()), Real(M_PI), Real(eps)); BOOST_CHECK_SMALL(s.t2.GetAngle(), eps); e.SetTorsionAngle(s.t1,0); BOOST_CHECK_SMALL(s.t1.GetAngle(), eps); - BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI), Real(eps)); + BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), Real(M_PI), Real(eps)); e.SetTorsionAngle(s.t2,M_PI/4); BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps)); BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI+M_PI/4), Real(eps)); @@ -136,11 +138,11 @@ BOOST_AUTO_TEST_CASE(ics_settorsion_buffered) Real eps = 0.0001; TorsionStructure s; ICSEditor e = s.e.EditICS(mol::BUFFERED_EDIT); - BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(M_PI), Real(eps)); + BOOST_CHECK_CLOSE(std::abs(s.t1.GetAngle()), Real(M_PI), Real(eps)); BOOST_CHECK_SMALL(s.t2.GetAngle(), eps); e.SetTorsionAngle(s.t1,0); BOOST_CHECK_SMALL(s.t1.GetAngle(), eps); - BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI), Real(eps)); + BOOST_CHECK_CLOSE(std::abs(s.t2.GetAngle()), Real(M_PI), Real(eps)); e.SetTorsionAngle(s.t2,M_PI/4); BOOST_CHECK_CLOSE(s.t2.GetAngle(), Real(M_PI/4), Real(eps)); BOOST_CHECK_CLOSE(s.t1.GetAngle(), Real(-M_PI+M_PI/4), Real(eps)); @@ -290,4 +292,4 @@ BOOST_AUTO_TEST_CASE(ics_get_angle) << " found"); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_iterators.cc b/modules/mol/base/tests/test_iterators.cc index 46c33e4d5b2bbe665ea1b71aec244f8f8b6891fb..829b15c96c218bb6630b013f9be1584edd48bc6c 100644 --- a/modules/mol/base/tests/test_iterators.cc +++ b/modules/mol/base/tests/test_iterators.cc @@ -23,6 +23,7 @@ #include <ost/message.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <iostream> using namespace ost; @@ -135,7 +136,7 @@ void test_atom_handle_iterator_b(HANDLE rr) { BOOST_CHECK(a1==a2); } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(chain_handle_iterator) { @@ -254,4 +255,4 @@ BOOST_AUTO_TEST_CASE(test_atom_handle_iterator) test_atom_handle_iterator_c<EntityView, AtomViewIter>(v); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_query.cc b/modules/mol/base/tests/test_query.cc index 815e597f7bf0e68b7d94ba0396b901988daa1d02..52fece59d284408ef8e5e7cdc2adda6d1f48f836 100644 --- a/modules/mol/base/tests/test_query.cc +++ b/modules/mol/base/tests/test_query.cc @@ -21,6 +21,7 @@ */ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/query.hh> #include <ost/mol/mol.hh> #include <ost/mol/entity_view.hh> @@ -101,7 +102,7 @@ void ensure_counts_v(EntityView src, const String& qs, " for query String " << qs); } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(test_query_parse_properties) { @@ -296,4 +297,4 @@ BOOST_AUTO_TEST_CASE(test_glob) ensure_counts(e, "rname=LEU and aname=?D?", 1, 1, 2); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_residue.cc b/modules/mol/base/tests/test_residue.cc index 6cc900c621c840e4814b8a106f8fe6b7901f6ad6..7dca39081915d4e7f49a29765a98920e4926ae00 100644 --- a/modules/mol/base/tests/test_residue.cc +++ b/modules/mol/base/tests/test_residue.cc @@ -24,12 +24,13 @@ #include <ost/message.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(test_in_sequence) { @@ -124,4 +125,4 @@ BOOST_AUTO_TEST_CASE(rename_res) BOOST_CHECK_EQUAL(rA2B.GetName(), "B"); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_surface.cc b/modules/mol/base/tests/test_surface.cc index 2a077d867ad48060987b049a3561b76e726aa2f0..18ab12a8887993bad36afcc5fabe0df2a447f6b9 100644 --- a/modules/mol/base/tests/test_surface.cc +++ b/modules/mol/base/tests/test_surface.cc @@ -21,11 +21,12 @@ #include <cmath> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> using namespace ost; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(test_throw_invalid_surface) @@ -37,4 +38,4 @@ BOOST_AUTO_TEST_CASE(test_throw_invalid_surface) BOOST_CHECK_NO_THROW(CheckHandleValidity(surf)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_transform.cc b/modules/mol/base/tests/test_transform.cc new file mode 100644 index 0000000000000000000000000000000000000000..5c950acc5a170448290be09dde71d76fad5e8e66 --- /dev/null +++ b/modules/mol/base/tests/test_transform.cc @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// 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 +//------------------------------------------------------------------------------ +/* + Authors: Tobias Schmidt + */ + #define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/mol.hh> +#include <ost/mol/transform.hh> +#include <ost/geom/geom.hh> + +using namespace ost; +using namespace ost::mol; + +BOOST_AUTO_TEST_SUITE( mol_base ); + +BOOST_AUTO_TEST_CASE(test_transform) +{ + Transform tf; + + BOOST_CHECK_EQUAL(tf.GetMatrix(), geom::Mat4()); + BOOST_CHECK_EQUAL(tf.GetRot(), geom::Mat3()); + BOOST_CHECK_EQUAL(tf.GetTrans(), geom::Vec3()); + BOOST_CHECK_EQUAL(tf.GetCenter(), geom::Vec3()); + + geom::Mat4 mat = geom::Mat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); + tf.SetMatrix(mat); + BOOST_CHECK_EQUAL(tf.GetMatrix(), mat); + BOOST_CHECK_EQUAL(tf.GetRot(), geom::Mat3(1,2,3,5,6,7,9,10,11)); + BOOST_CHECK_EQUAL(tf.GetCenter(), geom::Vec3(4,8,12)); + BOOST_CHECK_EQUAL(tf.GetTrans(), geom::Vec3(13,14,15)); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_view.cc b/modules/mol/base/tests/test_view.cc index cfe3a395c5cbaae2e2390c95609874afcdf55233..9a72c9d16dcf879f2fa4fe2bb569e4156aa847c9 100644 --- a/modules/mol/base/tests/test_view.cc +++ b/modules/mol/base/tests/test_view.cc @@ -21,6 +21,7 @@ */ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> @@ -50,7 +51,7 @@ struct FixtureView { AtomHandle ad; }; -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(gen_full_view) { @@ -90,4 +91,4 @@ BOOST_AUTO_TEST_CASE(gen_full_view) BOOST_CHECK_EQUAL(av1.GetHashCode(), av3.GetHashCode()); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/test_view_op.cc b/modules/mol/base/tests/test_view_op.cc index 61fff1ff0955baac7eaa11e775d42e19f35179c5..abe84f3baa65d356bcc2989245084c605f21f672 100644 --- a/modules/mol/base/tests/test_view_op.cc +++ b/modules/mol/base/tests/test_view_op.cc @@ -21,6 +21,7 @@ */ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> #include <ost/mol/view_op.hh> @@ -62,7 +63,7 @@ bool find_bond(AtomHandle a, AtomHandle b, const BondHandleList& bonds) return std::find(bonds.begin(), bonds.end(), a.FindBondToAtom(b))!=bonds.end(); } -BOOST_AUTO_TEST_SUITE( mol_base ) +BOOST_AUTO_TEST_SUITE( mol_base ); BOOST_AUTO_TEST_CASE(test_difference) { @@ -397,5 +398,4 @@ BOOST_AUTO_TEST_CASE(ent_from_view_atom_props) BOOST_CHECK_EQUAL(atom2.GetRadius(), Real(500.0)); } -BOOST_AUTO_TEST_SUITE_END() - +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/mol/base/tests/tests.cc b/modules/mol/base/tests/tests.cc index 87994767bc96550f154133301645b1fc1727672a..8fb5bbd47707615b1702765ff363cf8525716942 100644 --- a/modules/mol/base/tests/tests.cc +++ b/modules/mol/base/tests/tests.cc @@ -18,5 +18,7 @@ //------------------------------------------------------------------------------ #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> diff --git a/modules/seq/alg/tests/test_aligntoseqres.py b/modules/seq/alg/tests/test_aligntoseqres.py index 0f4b8ceaa9bdbdf61bec7a390127b6ebc6687f89..6c390008e69d81d2613337a863503769b6da1872 100644 --- a/modules/seq/alg/tests/test_aligntoseqres.py +++ b/modules/seq/alg/tests/test_aligntoseqres.py @@ -68,5 +68,9 @@ class TestAlignToSeqRes(unittest.TestCase): self.assertEqual(seq.alg.ValidateSEQRESAlignment(seqres_aln, chain), False) if __name__ == "__main__": - from ost import testutils - testutils.RunTests() + builder=conop.GetBuilder() + if not hasattr(builder, 'compound_lib'): + print 'default builder does not use compound library. ignoring unit tests' + else: + from ost import testutils + testutils.RunTests() diff --git a/modules/seq/alg/tests/test_merge_pairwise_alignments.cc b/modules/seq/alg/tests/test_merge_pairwise_alignments.cc index 25f9b836bd361560531922e2215bd3001cc909f0..5c23b1f65873aefba0cb99c9dbf1a6ca2cc89708 100644 --- a/modules/seq/alg/tests/test_merge_pairwise_alignments.cc +++ b/modules/seq/alg/tests/test_merge_pairwise_alignments.cc @@ -22,6 +22,7 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/seq/alg/merge_pairwise_alignments.hh> #include <ost/integrity_error.hh> @@ -30,7 +31,7 @@ using namespace ost; using namespace ost::seq; -BOOST_AUTO_TEST_SUITE(ost_seq_alg) +BOOST_AUTO_TEST_SUITE(ost_seq_alg); BOOST_AUTO_TEST_CASE(merge_pairwise_alignments_one) { @@ -192,4 +193,4 @@ BOOST_AUTO_TEST_CASE(merge_pairwise_alignments_six) } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/alg/tests/test_sequence_identity.cc b/modules/seq/alg/tests/test_sequence_identity.cc index 0b275d99bfb12dfe8a5087522a35e2b2b7244f76..7173ff8c2920ce4665fbe379a8e35c204bca79b2 100644 --- a/modules/seq/alg/tests/test_sequence_identity.cc +++ b/modules/seq/alg/tests/test_sequence_identity.cc @@ -22,7 +22,8 @@ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> - +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> #include <ost/seq/alg/sequence_identity.hh> @@ -30,7 +31,7 @@ using namespace ost; using namespace ost::seq; -BOOST_AUTO_TEST_SUITE(ost_seq_alg) +BOOST_AUTO_TEST_SUITE(ost_seq_alg); BOOST_AUTO_TEST_CASE(seqid_one) { @@ -129,4 +130,4 @@ BOOST_AUTO_TEST_CASE(seqid_empty) } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/alg/tests/tests.cc b/modules/seq/alg/tests/tests.cc index 1a5815a6a29d48ddab94798837eb62cee081f936..6203808c24decbbfc2ebe5aee2ce74cdf78ad659 100644 --- a/modules/seq/alg/tests/tests.cc +++ b/modules/seq/alg/tests/tests.cc @@ -18,5 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_seq_alg +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/modules/seq/base/doc/seq.rst b/modules/seq/base/doc/seq.rst index e84cfe6747c627a07f7c756eb26397ce95e1598d..99f4c6b737c015ccfec384d030ce203e45b156ac 100644 --- a/modules/seq/base/doc/seq.rst +++ b/modules/seq/base/doc/seq.rst @@ -65,14 +65,16 @@ The SequenceHandle .. function:: CreateSequence(name, sequence) Create a new :class:`SequenceHandle` with the given name and sequence. - + :param name: name of the sequence :type name: str :param sequence: String of characters representing the sequence. Only - alphanumerical characters and '-' are allowed. + 'word' characters (no digits), '?', '-' and '.' are allowed. In an + upcoming release, '?' and '.' will also be forbidden so its best to + translate those to 'X' or '-'. :type sequence: str :raises InvalidSequence: When the sequence string contains forbidden - characters, that is anything that is not alphanumeric or a hyphen. + characters. In the future, '?' and '.' will also raise this exception. .. class:: SequenceHandle diff --git a/modules/seq/base/src/alignment_handle.cc b/modules/seq/base/src/alignment_handle.cc index 47a4fd0dd371747b35761519f15c696751fa3a4a..c91fa3bbc93168a82b2870d31ed4f9c3f115d537 100644 --- a/modules/seq/base/src/alignment_handle.cc +++ b/modules/seq/base/src/alignment_handle.cc @@ -66,10 +66,14 @@ int AlignmentHandle::GetResidueIndex(int seq_index, int pos) const void AlignmentHandle::AddSequence(const ConstSequenceHandle& sequence) { this->CheckValidity(); - if (!sequence.IsValid() || (impl_->GetCount()>0 && - impl_->GetSequence(0)->GetLength()!=sequence.GetLength())) { + if (!sequence.IsValid()) { throw InvalidSequence(); } + if (impl_->GetCount()>0 && + impl_->GetSequence(0)->GetLength()!=sequence.GetLength()) { + throw std::runtime_error("sequence doesn't have the same length as the " + "alignment"); + } return impl_->AddSequence(sequence.Impl()); } @@ -137,7 +141,7 @@ AlignmentHandle AlignmentFromSequenceList(const SequenceList& seq_list) if (seq_list.IsValid() && seq_list.SequencesHaveEqualLength()) { return AlignmentHandle(seq_list.Impl()); } - throw InvalidAlignment(); + throw std::runtime_error("sequences have different lengths"); } ConstSequenceList AlignmentHandle::GetSequences() const diff --git a/modules/seq/base/tests/test_aligned_column.cc b/modules/seq/base/tests/test_aligned_column.cc index 17e1ec6f0d2a23c01ce010026038a864228538ee..d934cefb0d930ed167367d583ced4e9dcf6f4b3c 100644 --- a/modules/seq/base/tests/test_aligned_column.cc +++ b/modules/seq/base/tests/test_aligned_column.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> @@ -59,7 +60,7 @@ struct Fixture { ResidueHandle res3; }; -BOOST_AUTO_TEST_SUITE( aligned_column ) +BOOST_AUTO_TEST_SUITE( aligned_column ); BOOST_AUTO_TEST_CASE(aligned_column_triv) { @@ -130,4 +131,4 @@ BOOST_AUTO_TEST_CASE(aligned_get_residue_index) BOOST_CHECK_THROW(ac.GetResidueIndex(-1),std::out_of_range); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/base/tests/test_aligned_region.cc b/modules/seq/base/tests/test_aligned_region.cc index cc408f41c51bcdb22e6548e48e2f2b369be5109e..118c8d09fd843b94c4cec8551d50ac968892e961 100644 --- a/modules/seq/base/tests/test_aligned_region.cc +++ b/modules/seq/base/tests/test_aligned_region.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> @@ -38,7 +39,7 @@ using namespace ost::seq; using namespace ost::mol; -BOOST_AUTO_TEST_SUITE( aligned_region ) +BOOST_AUTO_TEST_SUITE( aligned_region ); BOOST_AUTO_TEST_CASE(aligned_region_triv) { @@ -183,4 +184,4 @@ BOOST_AUTO_TEST_CASE(aligned_region_shift) BOOST_CHECK_THROW(ar.ShiftRight(1),IntegrityError); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/base/tests/test_alignment.cc b/modules/seq/base/tests/test_alignment.cc index d4d1aca4eb92a25fc2dd9d0a4770710422dc4a3c..6b438e304e06367e76e2667643af4ece2aad6e06 100644 --- a/modules/seq/base/tests/test_alignment.cc +++ b/modules/seq/base/tests/test_alignment.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/invalid_handle.hh> #include <ost/mol/mol.hh> @@ -54,7 +55,7 @@ struct Fixture { ResidueHandle res3; }; -BOOST_AUTO_TEST_SUITE( alignment ) +BOOST_AUTO_TEST_SUITE( alignment ); BOOST_AUTO_TEST_CASE(alignment_triv) { @@ -63,11 +64,12 @@ BOOST_AUTO_TEST_CASE(alignment_triv) a = CreateAlignment(); BOOST_CHECK_NO_THROW(a.AddSequence(CreateSequence("S1","-asdf-"))); BOOST_CHECK_THROW(a.AddSequence(SequenceHandle()),InvalidSequence); - BOOST_CHECK_THROW(a.AddSequence(CreateSequence("S2","-asdf-f")),InvalidSequence); + BOOST_CHECK_THROW(a.AddSequence(CreateSequence("S2","-asdf-f")), + std::runtime_error); SequenceList list = CreateSequenceList(); list.AddSequence(CreateSequence("S1", "-asdf-")); list.AddSequence(CreateSequence("S2", "fasdfas")); - BOOST_CHECK_THROW(AlignmentFromSequenceList(list),InvalidAlignment); + BOOST_CHECK_THROW(AlignmentFromSequenceList(list), std::runtime_error); list = CreateSequenceList(); list.AddSequence(CreateSequence("S1", "-asdf-")); list.AddSequence(CreateSequence("S2", "fasdfa")); @@ -229,4 +231,4 @@ BOOST_AUTO_TEST_CASE(alignment_aligned_region) BOOST_CHECK_NO_THROW(ar = a.MakeRegion(3,3,0)); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/base/tests/test_sequence.cc b/modules/seq/base/tests/test_sequence.cc index 3c418443503c2d94552e2571f85c9037d2821df7..462747784933dcc25dd36689c3a0d0df5a5f2de2 100644 --- a/modules/seq/base/tests/test_sequence.cc +++ b/modules/seq/base/tests/test_sequence.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> #include <ost/mol/mol.hh> @@ -50,7 +51,7 @@ struct Fixture { ResidueHandle res3; }; -BOOST_AUTO_TEST_SUITE( seq ) +BOOST_AUTO_TEST_SUITE( seq ); BOOST_AUTO_TEST_CASE(seq_triv) { @@ -246,4 +247,4 @@ BOOST_AUTO_TEST_CASE(seq_attach_view) BOOST_CHECK_EQUAL(s.GetResidue(0),ResidueHandle()); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/seq/base/tests/tests.cc b/modules/seq/base/tests/tests.cc index 4d3b8b161269ae40f50241b4d1643f03117d9ddd..8d2205011a3c18953a65922d8a8e851ef6f6fd52 100644 --- a/modules/seq/base/tests/tests.cc +++ b/modules/seq/base/tests/tests.cc @@ -18,4 +18,6 @@ //------------------------------------------------------------------------------ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE ost_seq_base +#define BOOST_AUTO_TEST_MAIN #include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> diff --git a/scripts/ost.in b/scripts/ost.in index 2891d37c28597c2fbdee3dbb05b1bd7bf20aca5c..90c74f045e5ceff238b207c3043046d96546c57f 100755 --- a/scripts/ost.in +++ b/scripts/ost.in @@ -34,5 +34,3 @@ source $BIN_DIR/../@LIBEXEC_PATH@/ost_config $pyexec $interactive "$DNG_ROOT/@LIBDIR@/openstructure/init_cl.py" $opts RC=$? exit $RC - -