diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8891b9639dcdac2c2c38132c8028cd0836951e91..70fff8b1708376fa63fce83575973a6f86c0de3c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,16 @@ +Changes In Release 1.3.2 +-------------------------------------------------------------------------------- + + * Fixed atom ordering in the GetFrameFromEntity() function in the + structure_analysis.py module. + * Fix atom indices generated by CoordGroup::Filter() + * small tweaks to lDDT output + * small tweaks to molck + * Repaired bio unit parsing from mmCIF file/ PDBizing bio units, before + chains with different transformations were ignored + * use new remote loader written in Python to work around crash on Mountain + Lion + Changes In Release 1.3.1 -------------------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index f4ce4d675a556308f5b1031c3f4446050d9a15eb..93d9c7d5884931ad3c4ae72135a7a39f551ac5dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR) project(OpenStructure CXX C) set (OST_VERSION_MAJOR 1) set (OST_VERSION_MINOR 3) -set (OST_VERSION_PATCH 1) +set (OST_VERSION_PATCH 2) set (OST_VERSION_STRING ${OST_VERSION_MAJOR}.${OST_VERSION_MINOR}.${OST_VERSION_PATCH} ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake_support) include(OST) diff --git a/deployment/linux/create_bundle_centos5.py b/deployment/linux/create_bundle_centos5.py index dd141cba74437a0c150775e275459c83a14abb7e..36aa8a6877c2a702fcc6919ff4eab102c88465f8 100644 --- a/deployment/linux/create_bundle_centos5.py +++ b/deployment/linux/create_bundle_centos5.py @@ -12,7 +12,7 @@ import PyQt4 qt4_plugins_location='/usr/lib/qt47/plugins' qt4_qmake_location='/usr/lib/qt47/bin/qmake' ssl_crypto_location='/lib/' -chemlib_dictionary_location='/home/bundler/ost/ChemLib/1.2.2/compounds.chemlib' +chemlib_dictionary_location='/home/bundler/compounds.chemlib' list_of_excluded_libraries=[ 'ld-linux', 'libexpat', @@ -75,9 +75,10 @@ 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/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.prepreprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.prepreprepre > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#unset PYTHONPATH/ unset 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 -DQT_QMAKE_EXECUTABLE='+qt4_qmake_location+' -DPREFIX='+directory_name+' -DCOMPOUND_LIB='+chemlib_dictionary_location+' -DENABLE_IMG=ON -DUSE_RPATH=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') @@ -128,7 +129,7 @@ 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+'/'+system_python_executable+'/',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='../../') diff --git a/deployment/linux/create_bundle_centos6.py b/deployment/linux/create_bundle_centos6.py index 48fc8596dfc9b1ec88be7470721f153ffd824ebd..cfb2669676fbcad27513e86a35dff63d7b7ef34e 100644 --- a/deployment/linux/create_bundle_centos6.py +++ b/deployment/linux/create_bundle_centos6.py @@ -12,7 +12,7 @@ import PyQt4 qt4_plugins_location='/usr/lib/qt4/plugins' qt4_qmake_location='/usr/lib/qt4/bin/qmake' ssl_crypto_location='/usr/lib/' -chemlib_dictionary_location='/home/bundler/ost/ChemLib/1.2.2/compounds.chemlib' +chemlib_dictionary_location='/home/bundler/compounds.chemlib' list_of_excluded_libraries=[ 'ld-linux', 'libexpat', @@ -75,9 +75,10 @@ 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/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.prepreprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.prepreprepre > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#unset PYTHONPATH/ unset 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 -DQT_QMAKE_EXECUTABLE='+qt4_qmake_location+' -DPREFIX='+directory_name+' -DCOMPOUND_LIB='+chemlib_dictionary_location+' -DENABLE_IMG=ON -DUSE_RPATH=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') @@ -128,7 +129,7 @@ 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+'/'+system_python_executable+'/',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='../../') diff --git a/deployment/linux/create_bundle_lucid.py b/deployment/linux/create_bundle_lucid.py index aec419bd5d17043c6a273044ad14e20abacec3f7..17e6b1a443b829b9ff967224402dbaf794c59692 100644 --- a/deployment/linux/create_bundle_lucid.py +++ b/deployment/linux/create_bundle_lucid.py @@ -68,9 +68,10 @@ 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/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.prepreprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.prepreprepre > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#unset PYTHONPATH/ unset 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 -DUSE_RPATH=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') @@ -121,7 +122,7 @@ 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+'/'+system_python_executable+'/',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='../../') diff --git a/deployment/linux/create_bundle_precise.py b/deployment/linux/create_bundle_precise.py index 9ffeff82463112f79e857ecc8f7bf202deef91da..1bde046d6b089a9bdd9b4fa3d4aaee43d8a7328a 100644 --- a/deployment/linux/create_bundle_precise.py +++ b/deployment/linux/create_bundle_precise.py @@ -68,9 +68,10 @@ 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/@PYTHON_BINARY@/\$DNG_ROOT\/bin\/python/g" scripts/ost_config.in.backup > scripts/ost_config.in.prepreprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONHOME/ export PYTHONHOME/g" scripts/ost_config.in.prepreprepre > scripts/ost_config.in.preprepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#export PYTHONPATH/ export PYTHONPATH/g" scripts/ost_config.in.preprepre > scripts/ost_config.in.prepre',shell=True,cwd='../../') +subprocess.call('sed "s/\#unset PYTHONPATH/ unset 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+' -DUSE_RPATH=ON -DENABLE_IMG=ON -DENABLE_GUI=ON -DENABLE_GFX=ON -DOPTIMIZE=ON',shell=True,cwd='../../') @@ -121,7 +122,7 @@ 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+'/'+system_python_executable+'/',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='../../') diff --git a/modules/gfx/pymod/gradients.xml b/modules/gfx/pymod/gradients.xml index bd79d60947eefc96fcf343f930990cca004d4b9d..999345e3032a89940a0ca3e69c0a22b906f1267d 100644 --- a/modules/gfx/pymod/gradients.xml +++ b/modules/gfx/pymod/gradients.xml @@ -75,5 +75,18 @@ 0.0 0.901960784314 0.0 0.392156862745 1 1.0 0.352941176471 0.176470588235 0.529411764706 1 </Gradient> +<Gradient Name="RED_TO_GREEN">5 +0.00 0.886275 0.0745098 0.0509804 1 +0.25 1 0.505882 0 1 +0.50 0.988235 1 0 1 +0.75 0.67451 1 0 1 +1.00 0.176471 1 0 1 +</Gradient> +<Gradient Name="BLUE_TO_GREEN">3 +0.00 0.0313726 0.286275 0.501961 1 +0.50 0.567727 0.988205 1 1 +1.00 0.176471 1 0 1 +</Gradient> + </Gradients> </EMDataInfo> diff --git a/modules/gui/pymod/CMakeLists.txt b/modules/gui/pymod/CMakeLists.txt index 4ac7f7cfe75a5fe6a0e843a4389e64e02e8228ed..d4515a2f31ebe7541eb05c4981d3aa8f02b016a6 100644 --- a/modules/gui/pymod/CMakeLists.txt +++ b/modules/gui/pymod/CMakeLists.txt @@ -6,7 +6,6 @@ set(OST_GUI_PYMOD_SOURCES export_tool.cc export_py_shell.cc export_gosty.cc - export_remote_site_loader.cc export_scene_win.cc export_sequence_viewer.cc export_perspective.cc @@ -37,6 +36,7 @@ init_inspector.py inspector_widget.py map_level_widget.py preset.py +remote.py preset_editor_list_model.py preset_editor_widget.py preset_info_handler.py @@ -54,11 +54,6 @@ trace_widget.py tube_widget.py uniform_color_widget.py visibility_op.py -file_loader.py -loader_info_handler.py -loader_list_model.py -loader_manager_widget.py -immutable_loader_info_handler.py line_trace_widget.py wireframe_widget.py query_editor.py diff --git a/modules/gui/pymod/dng/init.py b/modules/gui/pymod/dng/init.py index d46af73d8e1a93678a576698e06bdd69b552b84c..b8a68e539c9e2fca127ca82c797409564c049b2d 100644 --- a/modules/gui/pymod/dng/init.py +++ b/modules/gui/pymod/dng/init.py @@ -22,6 +22,8 @@ from ost.gui.init_context_menu import _InitContextMenu from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse from ost.gui.dng import superpositiondialog +from ost.gui.scene.remote import RemoteLoader + import ost.gui.dng.menu from PyQt4.QtGui import * def _my_exit(code): @@ -55,7 +57,6 @@ def _InitPanels(app): panels = app.perspective.panels panels.AddWidgetToPool('ost.gui.FileBrowser', -1) panels.AddWidgetToPool('ost.gui.PythonShell', 1) - panels.AddWidgetToPool('ost.gui.RemoteLoader', -1) panels.AddWidgetToPool('ost.gui.SceneWin', 1) panels.AddWidgetToPool('ost.gui.SequenceViewer', 1) panels.AddWidgetToPool('ost.gui.MessageWidget', 1) @@ -63,8 +64,6 @@ def _InitPanels(app): panels.AddWidget(gui.PanelPosition.LEFT_PANEL, app.scene_win) panels.AddWidgetByName(gui.PanelPosition.LEFT_PANEL, 'ost.gui.FileBrowser', False) - panels.AddWidgetByName(gui.PanelPosition.LEFT_PANEL, - 'ost.gui.RemoteLoader', False) panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.seq_viewer) panels.AddWidget(gui.PanelPosition.BOTTOM_PANEL, app.py_shell) panels.AddWidget(gui.PanelPosition.RIGHT_PANEL, app.message_widget) diff --git a/modules/gui/pymod/dng/menu.py b/modules/gui/pymod/dng/menu.py index 75d2ae2ba34ba30328cf57a6fef4656bcf4fbba0..800c3f80525048c26a14c3454dd8d8f3950a9313 100644 --- a/modules/gui/pymod/dng/menu.py +++ b/modules/gui/pymod/dng/menu.py @@ -2,7 +2,6 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * from ost import * from ost import gui -from ost.gui.scene.loader_manager_widget import LoaderManagerWidget from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse from ost.gui.dng import superpositiondialog @@ -204,7 +203,6 @@ class WindowMenu(QMenu): def __init__(self, parent=None): QMenu.__init__(self, parent) self.setTitle('Window') - self.loader_manager=LoaderManagerWidget() gosty=gui.GostyApp.Instance() QObject.connect(self, SIGNAL('aboutToShow()'), self._AboutToShow) inspector_visible=gosty.GetWidget('InspectorDialog').isVisible() diff --git a/modules/gui/pymod/export_file_loader.cc b/modules/gui/pymod/export_file_loader.cc index ab978f09a21c6b42224bbdec59371b55ca713dd7..b39d6dadd8383cbe9b42c31d085528ace7dc6aca 100644 --- a/modules/gui/pymod/export_file_loader.cc +++ b/modules/gui/pymod/export_file_loader.cc @@ -24,7 +24,6 @@ using namespace boost::python; #include <QString> #include <ost/gui/file_loader.hh> -#include <ost/gui/loader_manager.hh> using namespace ost; using namespace ost::gui; @@ -41,48 +40,13 @@ void load_object_b(const QString& file_name, const QString& selection) FileLoader::LoadObject(file_name, selection); } -void load_from_site_a(const QString& id) -{ - FileLoader::LoadFrom(id); -} - -void load_from_site_b(const QString& id, const QString& site) -{ - FileLoader::LoadFrom(id,site); -} - -void load_from_site_c(const QString& id, const QString& site, const QString& selection) -{ - FileLoader::LoadFrom(id,site,selection); -} - -void add_remote_site_loader(LoaderManager* loader_manager, const QString& site, RemoteSiteLoader* site_loader){ - loader_manager->AddRemoteSiteLoader(site,site_loader); -} - } void export_FileLoader() { - class_<LoaderManager, LoaderManagerPtr, boost::noncopyable>("LoaderManager", no_init) - .def("GetSiteLoaderIdents", &LoaderManager::GetSiteLoaderIdents) - .def("AddRemoteSiteLoader", &add_remote_site_loader) - .def("RemoveRemoteSiteLoader", &LoaderManager::RemoveRemoteSiteLoader) - .def("SetDefaultRemoteSiteIdent", &LoaderManager::SetDefaultRemoteSiteIdent) - .def("GetDefaultRemoteSiteIdent", &LoaderManager::GetDefaultRemoteSiteIdent) - ; - class_<FileLoader, boost::noncopyable>("FileLoader", no_init) .def("LoadObject", &load_object_a) .def("LoadObject", &load_object_b) .staticmethod("LoadObject") - .def("LoadFrom", &load_from_site_a) - .def("LoadFrom", &load_from_site_b) - .def("LoadFrom", &load_from_site_c) - .staticmethod("LoadFrom") - .def("GetSiteLoaderIdents", &FileLoader::GetSiteLoaderIdents) - .staticmethod("GetSiteLoaderIdents") - .def("GetLoaderManager", &FileLoader::GetLoaderManager) - .staticmethod("GetLoaderManager") ; } diff --git a/modules/gui/pymod/export_remote_site_loader.cc b/modules/gui/pymod/export_remote_site_loader.cc deleted file mode 100644 index 80ad570496f295d32cd7ed4cf1aa8ee668731dd9..0000000000000000000000000000000000000000 --- a/modules/gui/pymod/export_remote_site_loader.cc +++ /dev/null @@ -1,76 +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 -//------------------------------------------------------------------------------ - -#include <boost/python.hpp> -#include <string> - - -#include <ost/gui/remote_site_loader.hh> -#include <boost/python/register_ptr_to_python.hpp> -#include <boost/python/suite/indexing/vector_indexing_suite.hpp> - -#include "sip_handler.hh" - -using namespace ost; -using namespace ost::gui; -using namespace boost::python; - -struct WrappedRemoteSiteLoader : public RemoteSiteLoader -{ - WrappedRemoteSiteLoader(PyObject *p): - RemoteSiteLoader(), self(p) - { } - - virtual void LoadById(const QString& id, const QString& selection=QString()){ - return call_method<void, std::string>(self, "LoadById", id.toStdString(), selection.toStdString()); - } - - virtual QString GetRemoteSiteName(){ - return call_method<QString>(self, "GetRemoteSiteName"); - } - - virtual bool IsImg() const{ - return call_method<bool>(self, "IsImg"); - } - - virtual QNetworkReply* ById(const QString& id, const QString& selection=QString()){ - object obj = call_method<object, std::string, std::string>(self, "ById", id.toStdString(), selection.toStdString()); - QNetworkReply* network_reply= get_cpp_qobject<QNetworkReply>(obj); - if(network_reply){ - return network_reply; - } - return NULL; - } - - private: - PyObject* self; -}; - -void export_RemoteSiteLoader() -{ - class_<RemoteSiteLoader, WrappedRemoteSiteLoader, boost::noncopyable>("RemoteSiteLoader") - .def("LoadById",&WrappedRemoteSiteLoader::LoadById) - .def("GetRemoteSiteName", &WrappedRemoteSiteLoader::GetRemoteSiteName) - .def("IsImg", &WrappedRemoteSiteLoader::IsImg) - ; - -} - - - diff --git a/modules/gui/pymod/init_menubar.py b/modules/gui/pymod/init_menubar.py index cc8dd3b618b34679ea766ff6648a6ea06bb1f9d6..761e483bb3493284a4078904dd24113a5011ddc2 100644 --- a/modules/gui/pymod/init_menubar.py +++ b/modules/gui/pymod/init_menubar.py @@ -25,8 +25,6 @@ import ost from PyQt4 import QtCore, QtGui from ost.gui import FileLoader -from ost.gui.scene.file_loader import GenericLoader -from ost.gui.scene.loader_manager_widget import LoaderManagerWidget from ost.gui.init_splash import _InitSplash from ost.gui.dng import termuse class InitMenuBar(QtCore.QObject): @@ -74,15 +72,6 @@ class InitMenuBar(QtCore.QObject): self.connect(reset, QtCore.SIGNAL('triggered()'), self.ResetView) window.addAction(reset) - #Options - #Add file loader to menu - loader_manager = QtGui.QAction('File &Loader', self) - loader_manager.setStatusTip('Loader Manager') - self.connect(loader_manager, QtCore.SIGNAL('triggered()'), self.LoaderManager) - options.addAction(loader_manager) - - self.loader_manager = LoaderManagerWidget() - def Exit(self): reply = QtGui.QMessageBox() reply.addButton(QtGui.QMessageBox.Yes) @@ -93,9 +82,6 @@ class InitMenuBar(QtCore.QObject): if(QtCore.QFileInfo(filename).isFile()): FileLoader.LoadObject(str(filename)) - def LoaderManager(self): - self.loader_manager.exec_() - def OpenDocs(self): QtGui.QDesktopServices.openUrl(QtCore.QUrl("http://www.openstructure.org/docs/")) diff --git a/modules/gui/pymod/scene/file_loader.py b/modules/gui/pymod/scene/file_loader.py index ba7efb375eb525f1bfd0fa58ebd1eab9665b3750..a0acf4140669bee32e6c4e34c6ec44ea2c1888a5 100644 --- a/modules/gui/pymod/scene/file_loader.py +++ b/modules/gui/pymod/scene/file_loader.py @@ -26,7 +26,7 @@ import re from PyQt4 import QtCore, QtGui, QtNetwork from ost.gui import FileLoader - +""" class BaseRemoteLoader(gui.RemoteSiteLoader): def __init__(self): gui.RemoteSiteLoader.__init__(self) @@ -195,3 +195,4 @@ class GenericLoader(BaseRemoteLoader): default = bool(int(group.GetAttribute(GenericLoader.DEFAULT_ATTRIBUTE_NAME))) return GenericLoader(name, url, up_case, file_type, tmp_url, img, default) +""" diff --git a/modules/gui/pymod/scene/loader_info_handler.py b/modules/gui/pymod/scene/loader_info_handler.py deleted file mode 100644 index 079620eccab9957c669d66c3996e9d1442be30b6..0000000000000000000000000000000000000000 --- a/modules/gui/pymod/scene/loader_info_handler.py +++ /dev/null @@ -1,60 +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 -#------------------------------------------------------------------------------ -# -*- coding: utf-8 -*- - -from ost import gui -from ost import gfx -from ost import info -from PyQt4 import QtCore, QtGui -from immutable_loader_info_handler import ImmutableLoaderInfoHandler - -#Generic Loader Info Handler -class LoaderInfoHandler(ImmutableLoaderInfoHandler): - - def __init__(self, file_name): - ImmutableLoaderInfoHandler.__init__(self, file_name) - - def StoreLoader(self,name, loader): - group = self.loaders_.CreateGroup(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - group.SetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME, str(name)) - loader.ToInfo(group) - self.handle_.Export(self.file_name_) - - def RemoveLoader(self, name): - group_list = self.loaders_.GetGroups(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - group_to_del = None - for group in group_list: - if group.HasAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME): - groupname = group.GetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME) - if name == groupname: - group_to_del = group - break - - if group_to_del != None: - self.loaders_.Remove(group_to_del) - self.handle_.Export(self.file_name_) - - def RenameLoader(self, old, new): - group_list = self.loaders_.GetGroups(ImmutableLoaderInfoHandler.LOADER_GROUP_NAME) - for group in group_list: - if group.HasAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME): - groupname = group.GetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME) - if old == groupname: - group.SetAttribute(ImmutableLoaderInfoHandler.NAME_ATTRIBUTE_NAME, new) - self.handle_.Export(self.file_name_) \ No newline at end of file diff --git a/modules/gui/pymod/scene/loader_list_model.py b/modules/gui/pymod/scene/loader_list_model.py deleted file mode 100644 index c033df0388f7f6f36e1290c371318d4b4c91a6a4..0000000000000000000000000000000000000000 --- a/modules/gui/pymod/scene/loader_list_model.py +++ /dev/null @@ -1,156 +0,0 @@ -from ost import gui -from ost import gfx -import os -import ost -from PyQt4 import QtCore, QtGui -from immutable_loader_info_handler import ImmutableLoaderInfoHandler -from loader_info_handler import LoaderInfoHandler -from ost.gui import LoaderManager - -class LoaderListModel(QtCore.QAbstractListModel): - - IMMUTABLE_LOADERS_PATH = os.path.join(ost.GetSharedDataPath(),"scene", - "loaders.xml") - MUTABLE_LOADERS_PATH = "user_loaders.xml" - - def __init__(self, parent=None, *args): - QtCore.QAbstractListModel.__init__(self, parent, *args) - - self.data_ = list() - - #Info Handler - self.immutable_infoh_ = ImmutableLoaderInfoHandler(LoaderListModel.IMMUTABLE_LOADERS_PATH) - self.infoh_ = LoaderInfoHandler(LoaderListModel.MUTABLE_LOADERS_PATH) - self.LoadLoaderFromInfo() - - self.loader_manager_ = gui.FileLoader.GetLoaderManager() - - def AddItem(self, name, loader, row, editable, save): - if self.NameIsValid(name): - self.insertRow(row, QtCore.QModelIndex()) - self.data_[row] = [name, loader, editable] - model_index = self.createIndex(row,0) - index = self.index(row) - end_index = self.createIndex(self.rowCount(),0) - if save: - self.AddLoaderToInfo(name, loader) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, end_index) - gui.FileLoader.GetLoaderManager().AddRemoteSiteLoader(name, loader) - if(loader.IsDefault()): - gui.FileLoader.GetLoaderManager().SetDefaultRemoteSiteIdent(name) - return True - return False - - def IsEditable(self, row): - return self.data_[row][2] - - def RemoveItem(self, row): - if self.IsEditable(row): - name = self.data_[row][0] - self.removeRow(row, QtCore.QModelIndex()) - model_index = self.createIndex(row,0) - self.infoh_.RemoveLoader(name) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, model_index) - self.loader_manager_.RemoveRemoteSiteLoader(name) - return True - return False - - def AddLoaderToInfo(self, name, loader): - self.infoh_.StoreLoader(name, loader) - - def RemoveLoaderFromInfo(self, name): - self.infoh_.RemoveLoader(name) - - def SetItem(self, model_index, loader): - row = model_index.row() - name = self.data_[row][0] - self.data_[row][1] = loader - model_index = self.createIndex(row,0) - index = self.index(row) - end_index = self.createIndex(self.rowCount(),0) - self.RemoveLoaderFromInfo(self.data_[row][0]) - self.AddLoaderToInfo(self.data_[row][0], loader) - self.emit(QtCore.SIGNAL("dataChanged"),model_index, end_index) - self.loader_manager_.RemoveRemoteSiteLoader(name) - self.loader_manager_.AddRemoteSiteLoader(name, loader) - return True - - def LoadLoaderFromInfo(self): - if self.immutable_infoh_: - loaders = self.immutable_infoh_.GetLoaders() - for k, v in loaders.iteritems(): - self.AddItem(k, v, self.GetLastRow(), False, False) - - loaders = self.infoh_.GetLoaders() - for k, v in loaders.iteritems(): - self.AddItem(k, v, self.GetLastRow(), True, False) - - def GetLoader(self, model_index): - if model_index.isValid(): - return self.data_[model_index.row()][1] - - def GetLastRow(self): - return self.rowCount() - - #Helper - def NameIsValid(self, string): - if len(string)==0: - return False - for values in self.data_: - if string == values[0]: - return False - return True - - #Overwritten Methods - def rowCount(self, parent=QtCore.QModelIndex()): - return len(self.data_) - - def data(self, index, role): - if index.isValid() and index.row()< self.rowCount(): - data = self.data_[index.row()] - if role == QtCore.Qt.DisplayRole: - return QtCore.QVariant(data[0]) - return QtCore.QVariant() - - def setData(self, index, value, role): - if index.isValid(): - row = index.row() - if not self.data_[row]: - self.data_[row] = list() - if role == QtCore.Qt.EditRole and self.NameIsValid(value.toString()): - old_name = str(self.data_[row][0]) - new_name = value.toString() - self.data_[row][0] = new_name - self.infoh_.RenameLoader(old_name,str(new_name)) - self.emit(QtCore.SIGNAL("dataChanged"),index, index) - self.loader_manager_.RemoveRemoteSiteLoader(old_name) - self.loader_manager_.AddRemoteSiteLoader(str(new_name), self.data_[row][1]) - return True - elif role == QtCore.Qt.DisplayRole: - self.data_[row][0] = value.toString() - return False - - def flags(self, index): - if index.isValid(): - flags = QtCore.QAbstractItemModel.flags(self,index) - if self.IsEditable(index.row()): - return flags | QtCore.Qt.ItemIsEditable - else: - return flags - return QtCore.Qt.ItemIsEnabled - - def insertRow(self, position, index): - self.beginInsertRows(index, position, position) - self.data_.insert(position,list()) - self.endInsertRows() - return True - - def removeRow(self, position, index): - self.beginRemoveRows(index, position, position) - del self.data_[position] - self.endRemoveRows() - return True - - - - diff --git a/modules/gui/pymod/scene/loader_manager_widget.py b/modules/gui/pymod/scene/loader_manager_widget.py deleted file mode 100644 index d1fd7795d0d30f517c783d87498878766811488e..0000000000000000000000000000000000000000 --- a/modules/gui/pymod/scene/loader_manager_widget.py +++ /dev/null @@ -1,199 +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 -#------------------------------------------------------------------------------ -# -*- coding: utf-8 -*- - -import os -import ost -from ost import gui -from ost import gfx -from datetime import datetime -from PyQt4 import QtCore, QtGui - -from loader_list_model import LoaderListModel -from file_loader import GenericLoader - -#Gradient Preset Widget -class LoaderManagerWidget(QtGui.QDialog): - ICONS_DIR = os.path.join(ost.GetSharedDataPath(), "gui", "icons/") - def __init__(self, parent=None): - QtGui.QDialog.__init__(self, parent) - - #Title - self.text_ = "Loader Manager" - - #Create Ui elements - self.list_view_ = QtGui.QListView() - - #Create Model - self.list_model_ = LoaderListModel(self) - self.list_view_.setModel(self.list_model_) - self.list_view_.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - - loader_label = QtGui.QLabel(self.text_) - font = loader_label.font() - font.setBold(True) - - self.add_action = QtGui.QAction("+",self) - self.add_action.setIcon(QtGui.QIcon(LoaderManagerWidget.ICONS_DIR+"add_icon.png")) - - QtCore.QObject.connect(self.add_action, QtCore.SIGNAL("triggered()"), self.Add) - - self.add_button_ = QtGui.QToolButton(self) - self.add_button_.setIconSize(QtCore.QSize(20,20)) - self.add_button_.setDefaultAction(self.add_action) - - grid = QtGui.QGridLayout() - grid.setContentsMargins(0,5,0,0) - grid.addWidget(loader_label, 0, 0, 1, 1) - qhbox = QtGui.QHBoxLayout() - grid.addWidget(self.list_view_,1,0,3,3) - grid.addWidget(self.add_button_,4,0,1,1) - self.setLayout(grid) - - self.list_view_.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - QtCore.QObject.connect(self.list_view_, QtCore.SIGNAL("customContextMenuRequested(const QPoint)"), self.contextMenuEvent) - self.CreateContextMenu() - - QtCore.QObject.connect(self.list_view_, QtCore.SIGNAL("doubleClicked(const QModelIndex)"), self.Edit) - - def CreateContextMenu(self): - self.contextMenu_ = QtGui.QMenu("Context menu", self) - self.remove_ = QtGui.QAction("Remove", self.list_view_) - self.rename_ = QtGui.QAction("Rename", self.list_view_) - self.edit_ = QtGui.QAction("Edit", self.list_view_) - self.contextMenu_.addAction(self.remove_) - self.contextMenu_.addAction(self.rename_) - self.contextMenu_.addAction(self.edit_) - #Connect Signals with Slots - QtCore.QObject.connect(self.remove_, QtCore.SIGNAL("triggered()"), self.Remove) - QtCore.QObject.connect(self.rename_, QtCore.SIGNAL("triggered()"), self.Rename) - QtCore.QObject.connect(self.edit_, QtCore.SIGNAL("triggered()"), self.Edit) - - def contextMenuEvent(self, pos): - #ContextMenu - index = self.list_view_.indexAt(pos) - if index.isValid(): - if self.list_model_.IsEditable(index.row()): - self.contextMenu_.popup(QtGui.QCursor.pos()) - - def Add(self): - row = self.list_model_.GetLastRow() - edit_widget = LoaderEditWidget() - - if edit_widget.exec_() and self.list_model_.AddItem(datetime.now().isoformat(' '), edit_widget.GetLoader(), row, True, True): - index = self.list_model_.index(row) - self.list_view_.setCurrentIndex(index) - self.Rename() - - def Edit(self): - current_index = self.list_view_.currentIndex() - loader = self.list_model_.GetLoader(current_index) - edit_widget = LoaderEditWidget() - edit_widget.SetLoader(loader) - if edit_widget.exec_(): - self.list_model_.SetItem(current_index, edit_widget.GetLoader()) - - - def Remove(self): - if(self.list_view_.currentIndex().isValid()): - ret = QtGui.QMessageBox.warning(self, "Delete File Loader", - "Delete File Loader?", - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) - if ret == QtGui.QMessageBox.Yes: - self.list_model_.RemoveItem(self.list_view_.currentIndex().row()) - - def Rename(self): - if(self.list_view_.currentIndex().isValid()): - self.list_view_.edit(self.list_view_.currentIndex()) - - def GetText(self): - return self.text_ - - - - -class LoaderEditWidget(QtGui.QDialog): - def __init__(self, parent=None): - QtGui.QDialog.__init__(self, parent) - name_ext_label = QtGui.QLabel("Name Extension") - self.name_ext_edit_ = QtGui.QLineEdit() - - url_label = QtGui.QLabel("Url") - self.url_edit_ = QtGui.QLineEdit() - self.add_id_button_ = QtGui.QToolButton(self) - self.add_id_button_.setDefaultAction(QtGui.QAction("ID",self)) - - file_ext_label = QtGui.QLabel("File Type") - self.file_ext_auto_ = QtGui.QCheckBox("Auto") - self.file_ext_edit_ = QtGui.QLineEdit() - - self.hbox_ = QtGui.QHBoxLayout() - self.ok_button_ = QtGui.QPushButton("OK") - self.cancel_button_ = QtGui.QPushButton("Cancel") - self.hbox_.addWidget(self.ok_button_) - self.hbox_.addStretch() - self.hbox_.addWidget(self.cancel_button_) - - grid = QtGui.QGridLayout() - grid.setContentsMargins(0,5,0,0) - grid.addWidget(name_ext_label, 0, 0, 1, 1) - grid.addWidget(self.name_ext_edit_, 0, 1, 1, 4) - grid.addWidget(url_label, 1, 0, 1, 1) - grid.addWidget(self.url_edit_, 1, 1, 1, 3) - grid.addWidget(self.add_id_button_, 1, 4, 1, 1) - grid.addWidget(file_ext_label, 2, 0, 1, 1) - grid.addWidget(self.file_ext_auto_, 2, 1, 1, 1) - grid.addWidget(self.file_ext_edit_, 2, 2, 1, 3) - grid.addLayout(self.hbox_,3,0,1,2) - grid.setRowStretch(2, 1) - self.setLayout(grid) - - QtCore.QObject.connect(self.add_id_button_, QtCore.SIGNAL("clicked()"), self.AppendId) - QtCore.QObject.connect(self.file_ext_auto_, QtCore.SIGNAL("stateChanged(int)"), self.CbStateChanged) - QtCore.QObject.connect(self.ok_button_, QtCore.SIGNAL("clicked()"), self.Ok) - QtCore.QObject.connect(self.cancel_button_, QtCore.SIGNAL("clicked()"), self.Cancel) - - def GetLoader(self): - name_ext = str(self.name_ext_edit_.text()) - url = str(self.url_edit_.text()) - file_ext = None - if not self.file_ext_auto_.isChecked(): - file_ext = str(self.file_ext_edit_.text()) - - return GenericLoader(name_ext, url, False, file_ext) - - def SetLoader(self, loader): - self.name_ext_edit_.setText(loader.name_) - self.url_edit_.setText(loader.url_) - if loader.file_type_ is not None: - self.file_ext_edit_.setText(loader.file_type_) - self.file_ext_auto_.setChecked(False) - else: - self.file_ext_auto_.setChecked(True) - def AppendId(self): - self.url_edit_.setText(self.url_edit_.text()+"${ID}") - - def CbStateChanged(self, state): - self.file_ext_edit_.setEnabled(not self.file_ext_auto_.isChecked()) - - def Ok(self): - self.accept() - - def Cancel(self): - self.reject() diff --git a/modules/gui/pymod/scene/remote.py b/modules/gui/pymod/scene/remote.py new file mode 100644 index 0000000000000000000000000000000000000000..46a7553b41a1c6b12ae43f6f6d99aead520ea0bd --- /dev/null +++ b/modules/gui/pymod/scene/remote.py @@ -0,0 +1,78 @@ +from PyQt4.QtCore import * +from PyQt4.QtGui import * +import threading +from ost import LogError +from ost import gui, gfx +from ost.io.remote import RemoteLoad, REMOTE_REPOSITORIES +import re + +class RemoteLoader(QWidget): + def __init__(self): + QWidget.__init__(self) + self._line = QLineEdit(self) + self._load = QToolButton(self) + self._load.setAttribute(Qt.WA_MacSmallSize) + QObject.connect(self._line, SIGNAL('returnPressed()'), + self._DoLoad) + QObject.connect(self._load, SIGNAL('clicked()'), + self._DoLoad) + hbox = QHBoxLayout(self) + hbox.addWidget(self._line,1) + hbox.addWidget(self._load,0) + self.setLayout(hbox) + hbox.setMargin(3) + hbox.setSpacing(3) + self._menu = self._RemoteMenu() + self._load.setMenu(self._menu) + self._current_repo = 'pdb' + self._UpdateLoadButton(self._current_repo) + self.setFixedHeight(self._load.height()) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) + + def _RemoteMenu(self): + menu = QMenu() + action_group = QActionGroup(menu) + for k,v in REMOTE_REPOSITORIES.iteritems(): + action = menu.addAction(v.name) + action.setCheckable(True) + if k == 'pdb': + action.setChecked(True) + action.setData(QVariant(k)) + action_group.addAction(action) + QObject.connect(menu, SIGNAL('triggered(QAction*)'), + self._ToggleRepo) + return menu + def _UpdateLoadButton(self, current): + name = REMOTE_REPOSITORIES[current].name + self._load.setText('load from %s ' % name) + + def _ToggleRepo(self, action): + self._current_repo = str(action.data().toString()) + self._UpdateLoadButton(self._current_repo) + + + def _DoLoad(self): + split_ids = [] + for p in str(self._line.text()).split(','): + for k in p.split(): + if len(k.strip()): + split_ids.append(k.strip()) + self._line.setText('') + for split_id in split_ids: + try: + ent = RemoteLoad(split_id, from_repo=self._current_repo) + except Exception, e: + LogError(str(e)) + continue + g = gfx.Entity(split_id, ent) + try: + gfx.Scene().Add(g) + except Exception, e: + LogError(str(e)) + +remote_loader=RemoteLoader() +remote_loader_for_panel=gui.Widget(remote_loader) +remote_loader_for_panel.qobject.setSizePolicy(QSizePolicy.Expanding, + QSizePolicy.Fixed) +panels=gui.GostyApp.Instance().perspective.panels +panels.AddWidgetToPool("Remote Loader",remote_loader_for_panel) diff --git a/modules/gui/pymod/wrap_gui.cc b/modules/gui/pymod/wrap_gui.cc index 81b6ff7889a3c5d91d2c42cf558fdd1a0a1f7cbd..a4474a6f861e427982f701581f852c2ea14c63bf 100644 --- a/modules/gui/pymod/wrap_gui.cc +++ b/modules/gui/pymod/wrap_gui.cc @@ -38,7 +38,6 @@ void export_SipHandler(); void export_SceneSelection(); void export_MainArea(); void export_MenuBar(); -void export_RemoteSiteLoader(); void export_FileLoader(); void export_FileViewer(); void export_Widget(); @@ -118,7 +117,6 @@ BOOST_PYTHON_MODULE(_ost_gui) export_SceneWin(); export_SceneSelection(); export_SequenceViewer(); - export_RemoteSiteLoader(); export_FileLoader(); export_FileViewer(); export_Widget(); diff --git a/modules/gui/src/CMakeLists.txt b/modules/gui/src/CMakeLists.txt index b4d9ee6e433268164006b2c8806b1ebaf905e168..83819bc0b7d7c3e151ebe797d90c4b1e08a87998 100644 --- a/modules/gui/src/CMakeLists.txt +++ b/modules/gui/src/CMakeLists.txt @@ -166,7 +166,6 @@ set(OST_GUI_HEADERS file_browser.hh file_type_dialog.hh file_viewer.hh -remote_loader.hh gl_canvas.hh gl_win.hh scene_menu.hh @@ -176,7 +175,6 @@ module_config.hh main.hh main_area.hh perspective.hh -remote_site_loader.hh scene_selection.hh main_window.hh dock_widget.hh @@ -188,7 +186,6 @@ widget_pool.hh widget_registry.hh widget_state_saver.hh file_loader.hh -loader_manager.hh ) set(OST_GUI_SOURCES @@ -198,7 +195,6 @@ widget_registry.cc file_browser.cc file_type_dialog.cc file_viewer.cc -remote_loader.cc main.cc gl_canvas.cc dock_widget.cc @@ -208,7 +204,6 @@ scene_menu.cc widget.cc admin.cc widget_pool.cc -remote_site_loader.cc messages/message_widget.cc messages/message_box_widget.cc messages/log_reader.cc @@ -237,7 +232,6 @@ widget_state_saver.cc scene_selection.cc widget_geom_handler.cc file_loader.cc -loader_manager.cc panels/button_bar.cc panels/drop_box.cc panels/panel_bar.cc @@ -305,7 +299,6 @@ set(HEADERS_TO_BE_MOCCED file_browser.hh file_type_dialog.hh file_viewer.hh -remote_loader.hh gl_canvas.hh gl_win.hh scene_menu.hh diff --git a/modules/gui/src/file_loader.cc b/modules/gui/src/file_loader.cc index d31c2f0b891ddd592ce55033ee0cbb298d2f7d8a..bc69ba7b852e035afa0c9417b46f2c4217d39f03 100644 --- a/modules/gui/src/file_loader.cc +++ b/modules/gui/src/file_loader.cc @@ -59,7 +59,6 @@ #include <QMenuBar> namespace ost { namespace gui { -LoaderManagerPtr FileLoader::loader_manager_ = LoaderManagerPtr(); #if OST_IMG_ENABLED QList<img::ImageHandle> FileLoader::loaded_images_; @@ -161,36 +160,6 @@ gfx::GfxObjP FileLoader::NoHandlerFound(const QString& filename) return gfx::GfxObjP(); } -void FileLoader::LoadFrom(const QString& id, const QString& site, const QString& selection) -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - RemoteSiteLoader* remote_site = loader_manager_->GetRemoteSiteLoader(site); - if(remote_site){ - remote_site->LoadById(id,selection); - } - else{ - remote_site = loader_manager_->GetCurrentSiteLoader(); - if(remote_site){ - remote_site->LoadById(id,selection); - } - } -} - -LoaderManagerPtr FileLoader::GetLoaderManager() -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - return loader_manager_; -} - -std::vector<String> FileLoader::GetSiteLoaderIdents() -{ - if(!loader_manager_) - loader_manager_ = LoaderManagerPtr(new LoaderManager()); - return loader_manager_->GetSiteLoaderIdents(); -} - void FileLoader::HandleError(const Error& e, ErrorType type, const QString& filename, gfx::GfxObjP obj) { if(type==GFX_ADD || type==GFX_MULTIPLE_ADD){ diff --git a/modules/gui/src/file_loader.hh b/modules/gui/src/file_loader.hh index 32a4ba18e9b685ce8086d47edef10cc1c22e4e04..23419b613eb851fb9aeeec56ce8c9efe91701050 100644 --- a/modules/gui/src/file_loader.hh +++ b/modules/gui/src/file_loader.hh @@ -24,8 +24,6 @@ #include <ost/gfx/gfx_object.hh> #include <ost/gui/module_config.hh> -#include <ost/gui/remote_site_loader.hh> -#include <ost/gui/loader_manager.hh> #include <ost/io/io_exception.hh> #include <ost/io/entity_io_handler.hh> @@ -64,7 +62,6 @@ private: static gfx::GfxObjP NoHandlerFound(const QString& filename); virtual ~FileLoader(); - static LoaderManagerPtr loader_manager_; #if OST_IMG_ENABLED static QList<img::ImageHandle> loaded_images_; @@ -72,9 +69,7 @@ private: public: static void LoadObject(const QString& filename, const QString& selection=QString()); - static void LoadFrom(const QString& id, const QString& site=QString(), const QString& selection=QString()); static std::vector<String> GetSiteLoaderIdents(); - static LoaderManagerPtr GetLoaderManager(); }; } } diff --git a/modules/gui/src/loader_manager.cc b/modules/gui/src/loader_manager.cc deleted file mode 100644 index bfe2853dc926669bdf33ddbee80bb360925c46f0..0000000000000000000000000000000000000000 --- a/modules/gui/src/loader_manager.cc +++ /dev/null @@ -1,112 +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 -//------------------------------------------------------------------------------ -#include <ost/gui/gosty_app.hh> -#include "loader_manager.hh" - -#include <ost/gui/perspective.hh> -#include <QDir> -#include <QAction> -#include <QMenu> -#include <QFileInfo> -#include <QMessageBox> -#include <QMenuBar> - - -namespace ost { namespace gui { - -LoaderManager::LoaderManager(): - site_loaders_(), - site_actions_(new QActionGroup(GostyApp::Instance()->GetPerspective()->GetMenuBar())), - default_site_() - -{ - site_actions_->setExclusive(true); -} - -void LoaderManager::AddRemoteSiteLoader(const QString& ident, RemoteSiteLoader* site_loader) -{ - site_loaders_.insert(ident,site_loader); - - QAction* action = new QAction(ident,site_actions_); - action->setCheckable(true); - site_actions_->addAction(action); - if(site_actions_->checkedAction()==NULL){ - action->setChecked(true); - } -} - -void LoaderManager::RemoveRemoteSiteLoader(const QString& ident) -{ - site_loaders_.remove(ident); - - QList<QAction*> actions = site_actions_->actions(); - QAction* action = NULL; - for (int i=0; i<actions.size(); i++){ - if(actions[i]->text()==ident){ - action = actions[i]; - break; - } - } - if(action){ - site_actions_->removeAction(action); - } -} - - -RemoteSiteLoader* LoaderManager::GetRemoteSiteLoader(const QString& ident) -{ - if(site_loaders_.contains(ident)){ - return site_loaders_[ident]; - } - return NULL; -} - -RemoteSiteLoader* LoaderManager::GetCurrentSiteLoader() -{ - if(site_actions_->checkedAction()!=NULL) - return site_loaders_[site_actions_->checkedAction()->text()]; - return NULL; -} - -std::vector<String> LoaderManager::GetSiteLoaderIdents() -{ - QList<QString> keys = site_loaders_.keys(); - std::vector<String> sites; - for(int i=0;i<keys.size();i++){ - sites.push_back(keys.at(i).toStdString()); - } - return sites; -} - -RemoteSiteLoader* LoaderManager::GetDefaultRemoteSiteLoader() -{ - return GetRemoteSiteLoader(GetDefaultRemoteSiteIdent()); -} - -QString LoaderManager::GetDefaultRemoteSiteIdent(){ - return default_site_; -} - -void LoaderManager::SetDefaultRemoteSiteIdent(const QString& ident){ - default_site_ = ident; -} - -LoaderManager::~LoaderManager(){} - -} } diff --git a/modules/gui/src/loader_manager.hh b/modules/gui/src/loader_manager.hh deleted file mode 100644 index f969b289c45282d13e5f8541f31f0f96e66157e2..0000000000000000000000000000000000000000 --- a/modules/gui/src/loader_manager.hh +++ /dev/null @@ -1,59 +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_GUI_LOADER_MANAGER_HH -#define OST_GUI_LOADER_MANAGER_HH -#include <vector> - -#include <boost/shared_ptr.hpp> - -#include <QString> -#include <QMap> - -#include <ost/gui/remote_site_loader.hh> - -namespace ost { namespace gui { - -class DLLEXPORT_OST_GUI LoaderManager { - -public: - LoaderManager(); - virtual ~LoaderManager(); - std::vector<String> GetSiteLoaderIdents(); - void AddRemoteSiteLoader(const QString& ident, RemoteSiteLoader* site_loader); - void RemoveRemoteSiteLoader(const QString& ident); - RemoteSiteLoader* GetRemoteSiteLoader(const QString& ident); - RemoteSiteLoader* GetCurrentSiteLoader(); - RemoteSiteLoader* GetDefaultRemoteSiteLoader(); - QString GetDefaultRemoteSiteIdent(); - void SetDefaultRemoteSiteIdent(const QString& ident); - QMenu* GetSiteMenu(); - -private: - QMap<QString,RemoteSiteLoader*> site_loaders_; - QActionGroup* site_actions_; - QString default_site_; - - -}; - -typedef boost::shared_ptr<LoaderManager> LoaderManagerPtr; - -} } - -#endif /* OST_GUI_LOADER_MANAGER_HH */ diff --git a/modules/gui/src/remote_loader.cc b/modules/gui/src/remote_loader.cc deleted file mode 100644 index a75a0b4a12dbbfe02f0c8af5b766ec3cb2cd7545..0000000000000000000000000000000000000000 --- a/modules/gui/src/remote_loader.cc +++ /dev/null @@ -1,208 +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 -//------------------------------------------------------------------------------ -#include <vector> - -#include <ost/platform.hh> - -#include <ost/gui/file_loader.hh> -#include <ost/gui/loader_manager.hh> - -#include "widget_registry.hh" -#include "remote_loader.hh" - -#include <QString> -#include <QSettings> -#include <QNetworkReply> -#include <QHBoxLayout> -#include <QDir> -namespace ost { namespace gui { - -RemoteLoader::RemoteLoader(QWidget* parent): - Widget(NULL, parent) -{ - img_support_=OST_IMG_ENABLED; - line_edit_ = new QLineEdit(this); - button_ = new QToolButton(this); - button_->setAttribute(Qt::WA_MacSmallSize); - progress_bar_ = new QProgressBar(this); - progress_bar_->setAttribute(Qt::WA_MacSmallSize); - progress_bar_->setVisible(false); - progress_bar_->setRange(0,0); - - QHBoxLayout* l=new QHBoxLayout(this); - l->addWidget(line_edit_); - l->addWidget(button_); - l->addWidget(progress_bar_); - l->setMargin(3); - l->setSpacing(2); - - connect(button_, SIGNAL(clicked()), this, - SLOT(Clicked())); - - QDir icon_path(GetSharedDataPath().c_str()); - icon_path.cd("gui"); - icon_path.cd("icons"); - site_loader_menu_ = new QMenu(this); - site_actions_ = new QActionGroup(site_loader_menu_); - - site_loader_menu_ = new QMenu(this); - site_actions_ = new QActionGroup(site_loader_menu_); - - QAction* select_url_action = new QAction(this); - select_url_action->setText("URL"); - select_url_action->setToolTip("Select remote URL"); - select_url_action->setIcon(QIcon(icon_path.absolutePath()+QDir::separator()+ - QString("site_icon.png"))); - action_list_.append(select_url_action); - connect(select_url_action, SIGNAL(triggered(bool)), this, SLOT(UrlClick())); - this->BuildMenu(); - this->RenameButton(); - this->setFixedHeight(button_->height()); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); -} - -void RemoteLoader::UrlClick() -{ - this->BuildMenu(); - site_loader_menu_->exec(QCursor::pos()); -} - -void RemoteLoader::BuildMenu(String active_loader) -{ - if(!active_loader.empty()){ - selected_site_loader_ = active_loader; - } - else if(site_actions_->checkedAction()!=NULL){ - selected_site_loader_=site_actions_->checkedAction()->text().toStdString(); - } - site_loader_menu_->clear(); - QList<QAction*> actions = site_actions_->actions(); - for(int i=0;i<actions.size();i++){ - site_actions_->removeAction(actions[i]); - } - std::vector<String> site_loaders = FileLoader::GetSiteLoaderIdents(); - for(unsigned int i=0; i<site_loaders.size(); i++){ - QString loader_ident(site_loaders[i].c_str()); - RemoteSiteLoader* loader = FileLoader::GetLoaderManager()->GetRemoteSiteLoader(loader_ident); - if(loader && ((loader->IsImg() && img_support_) || !loader->IsImg())){ - QAction* action = new QAction(loader_ident,site_loader_menu_); - connect(action, SIGNAL(triggered()), this, SLOT(RenameButton())); - action->setCheckable(true); - site_actions_->addAction(action); - if((site_actions_->checkedAction()==NULL && loader_ident == FileLoader::GetLoaderManager()->GetDefaultRemoteSiteIdent()) ||selected_site_loader_==loader_ident.toStdString() ){ - action->setChecked(true); - } - site_loader_menu_->addAction(action); - } - } -} - -ActionList RemoteLoader::GetActions() -{ - return action_list_; -} - -bool RemoteLoader::Save(const QString& prefix) -{ - this->BuildMenu(); - QSettings settings; - settings.beginGroup(prefix); - settings.setValue("loader", site_actions_->checkedAction()->text()); - settings.endGroup(); - return true; -} - -bool RemoteLoader::Restore(const QString& prefix) -{ - QSettings settings; - settings.beginGroup(prefix); - if (settings.contains("loader")) { - this->BuildMenu(settings.value("loader").toString().toStdString()); - } - else{ - this->BuildMenu(); - } - this->RenameButton(); - return true; -} - -void RemoteLoader::Clicked() -{ - this->BuildMenu(); - if(!line_edit_->text().isEmpty() && site_actions_->checkedAction()){ - RemoteSiteLoader* loader = FileLoader::GetLoaderManager()->GetRemoteSiteLoader(site_actions_->checkedAction()->text()); - - QString text = line_edit_->text().simplified(); - QString id = text; - QString selection = ""; - int pos = text.indexOf('['); - if(pos >= 0){ - id = text.left(pos); - selection = text.right(text.size()-(pos+1)); - pos = selection.lastIndexOf(']'); - if(pos>=0){ - selection = selection.left(pos); - } - } - QNetworkReply* network_reply = loader->ById(id,selection); - if(network_reply){ - progress_bar_->reset(); - connect(network_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(UpdateProgress(qint64,qint64))); - connect(network_reply, SIGNAL(finished()), this, SLOT(DownloadFinished())); - this->ShowProgressBar(true); - } - line_edit_->setText(""); - line_edit_->setFocus(); - } -} - -void RemoteLoader::keyPressEvent(QKeyEvent* event){ - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - this->Clicked(); - } -} - -void RemoteLoader::ShowProgressBar(bool visibility){ - button_->setVisible(!visibility); - line_edit_->setVisible(!visibility); - progress_bar_->setVisible(visibility); -} - -void RemoteLoader::UpdateProgress(qint64 read, qint64 total){ - progress_bar_->setMaximum(total); - progress_bar_->setValue(read); - -} - -void RemoteLoader::DownloadFinished(){ - this->ShowProgressBar(false); -} - - -void RemoteLoader::RenameButton(){ - if(site_actions_->checkedAction()){ - QString text = "Load (" + site_actions_->checkedAction()->text() + ")"; - button_->setText(text); - } -} - -OST_REGISTER_WIDGET_WITH_DEFAULT_FACTORY(ost::gui, RemoteLoader, "Remote Loader"); - -}} - diff --git a/modules/img/alg/src/discrete_shrink.cc b/modules/img/alg/src/discrete_shrink.cc index d24979b3f5b632d6376342bbb8db0b84e128a004..ba01ae54635d9c4bab555b1772f38f5c43b1129b 100644 --- a/modules/img/alg/src/discrete_shrink.cc +++ b/modules/img/alg/src/discrete_shrink.cc @@ -49,6 +49,7 @@ void do_shrink(const ImageStateImpl<T,D>& isi, T& dest, const Extent& inner_ext) T sum(0); Real count=0.0; for(ExtentIterator bit(inner_ext);!bit.AtEnd();++bit) { + LOG_VERBOSE("inner extent point:" << Point(bit)<<","<<isi.GetExtent().Contains(Point(bit))); sum+=isi.Value(bit); count+=1.0; } @@ -61,18 +62,27 @@ void do_shrink(const ImageStateImpl<T,D>& isi, T& dest, const Extent& inner_ext) template <typename T, class D> ImageStateBasePtr DiscreteShrinkFnc::VisitState(const ImageStateImpl<T,D>& isi) const { - Size size(isi.GetExtent().GetSize()); - Point start(isi.GetExtent().GetStart()); + Size size(isi.GetLogicalExtent().GetSize()); + Point start(isi.GetLogicalExtent().GetStart()); Size newsize; div_t dt; - dt = div(static_cast<int>(size[0]),bs_[0]); newsize[0] = dt.quot + ((dt.rem>0) ? 1 : 0); - dt = div(static_cast<int>(size[1]),bs_[1]); newsize[1] = dt.quot + ((dt.rem>0) ? 1 : 0); - dt = div(static_cast<int>(size[2]),bs_[2]); newsize[2] = dt.quot + ((dt.rem>0) ? 1 : 0); - + dt = div(static_cast<int>(size[0]),bs_[0]); + newsize[0] = dt.quot + ((dt.rem>0) ? 1 : 0); + dt = div(static_cast<int>(size[1]),bs_[1]); + newsize[1] = dt.quot + ((dt.rem>0) ? 1 : 0); + dt = div(static_cast<int>(size[2]),bs_[2]); + newsize[2] = dt.quot + ((dt.rem>0) ? 1 : 0); Extent new_ext(newsize); + Point newstart; - LOG_DEBUG("extent of shrunken image" << isi.GetExtent() << " " << new_ext); + dt = div(start[0],bs_[0]); newstart[0] = dt.quot; + dt = div(start[1],bs_[1]); newstart[1] = dt.quot; + dt = div(start[2],bs_[2]); newstart[2] = dt.quot; + + new_ext.Shift(newstart); + + LOG_DEBUG("extent of shrunken image" << isi.GetExtent() << " " << new_ext<< new_ext.GetEnd()); geom::Vec3 ao = isi.GetAbsoluteOrigin(); @@ -80,26 +90,18 @@ ImageStateBasePtr DiscreteShrinkFnc::VisitState(const ImageStateImpl<T,D>& isi) new_ps.SetExtent(new_ext); typename ImageStateImpl<T,D>::SharedPtrType ni(new ImageStateImpl<T,D>(new_ext,new_ps)); + ni->SetAbsoluteOrigin(ao); + ni->GetSampling().SetPixelSampling(CompMultiply(ni->GetSampling().GetPixelSampling(),Vec3(bs_[0],bs_[1],bs_[2]))); - for(ExtentIterator it(new_ext); !it.AtEnd(); ++it) { + for(ExtentIterator it(ni->GetExtent(),ni->GetDomain()); !it.AtEnd(); ++it) { Point t(it[0]*bs_[0], it[1]*bs_[1], it[2]*bs_[2]); - - Extent inner_ext = Overlap(Extent(t+start,bs_),isi.GetExtent()); - + Extent inner_ext = Overlap(Extent(t,bs_),isi.GetExtent()); do_shrink(isi,ni->Value(it),inner_ext); } - Point newstart; - - dt = div(start[0],bs_[0]); newstart[0] = dt.quot; - dt = div(start[1],bs_[1]); newstart[1] = dt.quot; - dt = div(start[2],bs_[2]); newstart[2] = dt.quot; - ni->SetAbsoluteOrigin(ao); - ni->SetSpatialOrigin(newstart); - ni->GetSampling().SetPixelSampling(CompMultiply(ni->GetSampling().GetPixelSampling(),Vec3(bs_[0],bs_[1],bs_[2]))); return ni; } diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index a887323546f8b9687ec9c6e0bde909903261d2d7..df9a948bd44cb5b17c9e3174d97c6cc64fb83e01 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -130,7 +130,14 @@ of the annotation available. .. method:: AddBioUnit(biounit) - Add a bio unit to the bio unit list of an info object. + Add a bio unit to the bio unit list of an info object. If the + :attr:`id <MMCifInfoBioUnit.id>` of ``biounit`` already exists in the set + of assemblies, both will be merged. This means that + :attr:`chain <MMCifInfoBioUnit.chains>` and + :attr:`operations <MMCifInfoBioUnit.operations>` lists will be concatenated + and the interval lists + (:attr:`operationsintervalls <MMCifInfoBioUnit.operationsintervalls>`, + :attr:`chainintervalls <MMCifInfoBioUnit.chainintervalls>`) will be updated. :param biounit: Bio unit to be added. :type biounit: :class:`MMCifInfoBioUnit` @@ -499,7 +506,17 @@ of the annotation available. Chains involved in this bio unit. If not provided, resembles an empty list. Also available as :meth:`GetChainList`. May also be modified by - :meth:`AddChain`. + :meth:`AddChain` or :meth:`SetChainList`. + + .. attribute:: chainintervalls + + List of intervals on the chain list. Needed if there a several sets of + chains and transformations to create the bio unit. Comes as a list of + tuples. First component is the start, second is the right border of the + interval. + + Also available as :meth:`GetChainIntervalList`. Is automatically modified by + :meth:`AddChain`, :meth:`SetChainList` and :meth:`MMCifInfo.AddBioUnit`. .. attribute:: operations @@ -509,6 +526,16 @@ of the annotation available. Also available as :meth:`GetOperations`. May be modified by :meth:`AddOperations` + .. attribute:: operationsintervalls + + List of intervals on the operations list. Needed if there a several sets of + chains and transformations to create the bio unit. Comes as a list of + tuples. First component is the start, second is the right border of the + interval. + + Also available as :meth:`GetOperationsIntervalList`. Is automatically + modified by :meth:`AddOperations` and :meth:`MMCifInfo.AddBioUnit`. + .. method:: GetID() See :attr:`id` @@ -529,9 +556,22 @@ of the annotation available. See :attr:`chains` + .. method:: SetChainList(chains) + + See :attr:`chains`, also resets :attr:`chainintervalls` to contain only one + interval enclosing the whole chain list. + + :param chains: List of chain names. + :type chains: :class:`~ost.StringList` + .. method:: AddChain(chain name) - See :attr:`chains` + See :attr:`chains`, also extends the right border of the last entry in + :attr:`chainintervalls`. + + .. method:: GetChainIntervalList() + + See :attr:`chainintervalls` .. method:: GetOperations() @@ -539,7 +579,12 @@ of the annotation available. .. method:: AddOperations(list of operations) - See :attr:`operations` + See :attr:`operations`, also extends the right border of the last entry in + :attr:`operationsintervalls`. + + .. method:: GetOperationsIntervalList() + + See :attr:`operationsintervalls` .. function:: PDBize(asu, seqres=None, min_polymer_size=10, transformation=False) @@ -567,7 +612,7 @@ of the annotation available. :param asu: Asymmetric unit to work on. Should be created from a mmCIF file. - :type asu: :class:`~ost.mol.EntityHandle>` + :type asu: :class:`~ost.mol.EntityHandle` :param seqres: If set to a valid sequence list, the length of the seqres records will be used to determine if a certain chain has the minimally required length. @@ -948,3 +993,8 @@ of the annotation available. .. LocalWords: auth GetMMCifPDBChainTr AddPDBCMMCifhainTr GetPDBMMCifChainTr .. LocalWords: GetRevisions AddRevision SetRevisionsDateOriginal GetSize .. LocalWords: GetNum num GetStatus GetLastDate GetFirstRelease storable +.. LocalWords: SetChainList MMCifInfoTransOp ChainTypes MMCifInfoStructRef +.. LocalWords: MMCifInfoRevisions bool difs MMCifInfoStructRefSeqDif rnum +.. LocalWords: SetDateOriginal GetDateOriginal yyyy operationsintervalls +.. LocalWords: chainintervalls GetChainIntervalList +.. LocalWords: GetOperationsIntervalList diff --git a/modules/io/pymod/CMakeLists.txt b/modules/io/pymod/CMakeLists.txt index 007569fff38887504ed15d21231b2b5d4464b346..6763a0189c4d779f8d2777576ba576d886201af4 100644 --- a/modules/io/pymod/CMakeLists.txt +++ b/modules/io/pymod/CMakeLists.txt @@ -10,7 +10,7 @@ endif() set(OST_IO_PYMOD_MODULES __init__.py - hhsearch.py + remote.py repository.py ) diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index e9e597d726f5d921fb6938f12a13a221610b16b8..7cf8437f7c60b8efb080ae5790e79e70542bf30e 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -58,30 +58,6 @@ def _override(val1, val2): else: return val1 -def __GetModelFromPDB(model_id, output_dir, file_pattern='pdb%s.ent.gz'): - file_name = file_pattern % model_id - file_path = os.path.join(output_dir,file_name) - try: - server="ftp.wwpdb.org" - ftp=ftplib.FTP(server,"anonymous","user@") - ftp.cwd("pub/pdb/data/structures/all/pdb") - ftp_retrfile=open(file_path,"wb") - ftp.retrbinary("RETR "+file_name,ftp_retrfile.write) - ftp_retrfile.close() - except: - conn=httplib.HTTPConnection('www.pdb.org') - conn.request('GET', '/pdb/files/%s.pdb.gz' % model_id ) - response=conn.getresponse() - if response.status==200: - data=response.read() - f=open(os.path.join(output_dir, file_pattern % model_id), 'w+') - f.write(data) - f.close() - else: - conn.close() - return False - return os.path.getsize(file_path) > 0 - def LoadPDB(filename, restrict_chains="", no_hetatms=None, fault_tolerant=None, load_multi=False, quack_mode=None, join_spread_atom_records=None, calpha_only=None, @@ -154,12 +130,11 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, prof.join_spread_atom_records=_override(prof.join_spread_atom_records, join_spread_atom_records) + tmp_file = None # avoid getting out of scope if remote: - output_dir = tempfile.gettempdir() - if __GetModelFromPDB(filename, output_dir): - filename = os.path.join(output_dir, 'pdb%s.ent.gz' % filename) - else: - raise IOError('Can not load PDB %s from www.pdb.org'%filename) + from ost.io.remote import RemoteGet + tmp_file =RemoteGet(filename) + filename = tmp_file.name conop_inst=conop.Conopology.Instance() builder=conop_inst.GetBuilder("DEFAULT") @@ -380,105 +355,110 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10, return atom_pos_wrong chain_names='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz' + cur_chain_name = 0 + water_chain = mol.ChainHandle() + ligand_chain = mol.ChainHandle() + a_pos_wrong = False + pdb_bu = mol.CreateEntity() + edi = pdb_bu.EditXCS(mol.BUFFERED_EDIT) + chains = biounit.GetChainList() + c_intvls = biounit.GetChainIntervalList() + o_intvls = biounit.GetOperationsIntervalList() # create list of operations # for cartesian products, operations are stored in a list, multiplied with # the next list of operations and re-stored... until all lists of operations # are multiplied in an all-against-all manner. operations = biounit.GetOperations() - trans_matrices = list() - if len(operations) > 0: - for op in operations[0]: - rot = geom.Mat4() - rot.PasteRotation(op.rotation) - trans = geom.Mat4() - trans.PasteTranslation(op.translation) - tr = geom.Mat4() - tr = trans * rot - trans_matrices.append(tr) - for op_n in range(1, len(operations)): - tmp_ops = list() - for o in operations[op_n]: + for i in range(0,len(c_intvls)): + trans_matrices = list() + l_operations = operations[o_intvls[i][0]:o_intvls[i][1]] + if len(l_operations) > 0: + for op in l_operations[0]: rot = geom.Mat4() - rot.PasteRotation(o.rotation) + rot.PasteRotation(op.rotation) trans = geom.Mat4() - trans.PasteTranslation(o.translation) + trans.PasteTranslation(op.translation) tr = geom.Mat4() tr = trans * rot - for t_o in trans_matrices: - tp = t_o * tr - tmp_ops.append(tp) - trans_matrices = tmp_ops - # select chains into a view as basis for each transformation - assu = asu.Select('cname=' + ','.join(biounit.GetChainList())) - # use each transformation on the view, store as entity and transform, PDBize - # the result while adding everything to one large entity - pdb_bu = mol.CreateEntity() - edi = pdb_bu.EditXCS(mol.BUFFERED_EDIT) - cur_chain_name = 0 - water_chain = mol.ChainHandle() - ligand_chain = mol.ChainHandle() - a_pos_wrong = False - for tr in trans_matrices: - # do a PDBize, add each new entity to the end product - for chain in assu.chains: - residue_count = len(chain.residues) - if seqres: - seqres_chain = seqres.FindSequence(chain.name) - if seqres_chain.IsValid(): - residue_count = len(seqres_chain) - if chain.is_polymer and residue_count >= min_polymer_size: - if len(chain_names) == cur_chain_name: - raise RuntimeError('Running out of chain names') - new_chain = edi.InsertChain(chain_names[cur_chain_name]) - cur_chain_name += 1 - edi.SetChainDescription(new_chain, chain.description) - edi.SetChainType(new_chain, chain.type) - new_chain.SetStringProp('original_name', chain.name) - if chain.HasProp("pdb_auth_chain_name"): - new_chain.SetStringProp("pdb_auth_chain_name", - chain.GetStringProp("pdb_auth_chain_name")) - for res in chain.residues: - new_res = edi.AppendResidue(new_chain, res.name, res.number) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b - elif chain.type == mol.CHAINTYPE_WATER: - if not water_chain.IsValid(): - # water gets '-' as name - water_chain = edi.InsertChain('-') - edi.SetChainDescription(water_chain, chain.description) - edi.SetChainType(water_chain, chain.type) - for res in chain.residues: - new_res = edi.AppendResidue(water_chain, res.name) - new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) - new_res.SetStringProp('description', chain.description) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b - else: - if not ligand_chain.IsValid(): - # all ligands, put in one chain, are named '_' - ligand_chain = edi.InsertChain('_') - last_rnum = 0 - else: - last_rnum = ligand_chain.residues[-1].number.num - residues=chain.residues - ins_code='\0' - if len(residues)>1: - ins_code='A' - for res in chain.residues: - new_res = edi.AppendResidue(ligand_chain, res.name, - mol.ResNum(last_rnum+1, ins_code)) - new_res.SetStringProp('description', chain.description) - new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) - new_res.SetStringProp("original_name", chain.name) + trans_matrices.append(tr) + for op_n in range(1, len(l_operations)): + tmp_ops = list() + for o in l_operations[op_n]: + rot = geom.Mat4() + rot.PasteRotation(o.rotation) + trans = geom.Mat4() + trans.PasteTranslation(o.translation) + tr = geom.Mat4() + tr = trans * rot + for t_o in trans_matrices: + tp = t_o * tr + tmp_ops.append(tp) + trans_matrices = tmp_ops + # select chains into a view as basis for each transformation + assu = asu.Select('cname='+','.join(chains[c_intvls[i][0]:c_intvls[i][1]])) + # use each transformation on the view, store as entity and transform, PDBize + # the result while adding everything to one large entity + for tr in trans_matrices: + # do a PDBize, add each new entity to the end product + for chain in assu.chains: + residue_count = len(chain.residues) + if seqres: + seqres_chain = seqres.FindSequence(chain.name) + if seqres_chain.IsValid(): + residue_count = len(seqres_chain) + if chain.is_polymer and residue_count >= min_polymer_size: + if len(chain_names) == cur_chain_name: + raise RuntimeError('Running out of chain names') + new_chain = edi.InsertChain(chain_names[cur_chain_name]) + cur_chain_name += 1 + edi.SetChainDescription(new_chain, chain.description) + edi.SetChainType(new_chain, chain.type) + new_chain.SetStringProp('original_name', chain.name) if chain.HasProp("pdb_auth_chain_name"): - new_res.SetStringProp("pdb_auth_chain_name", - chain.GetStringProp("pdb_auth_chain_name")) - ins_code = chr(ord(ins_code)+1) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b + new_chain.SetStringProp("pdb_auth_chain_name", + chain.GetStringProp("pdb_auth_chain_name")) + for res in chain.residues: + new_res = edi.AppendResidue(new_chain, res.name, res.number) + a_b = _CopyAtoms(res, new_res, edi, tr) + if not a_pos_wrong: + a_pos_wrong = a_b + elif chain.type == mol.CHAINTYPE_WATER: + if not water_chain.IsValid(): + # water gets '-' as name + water_chain = edi.InsertChain('-') + edi.SetChainDescription(water_chain, chain.description) + edi.SetChainType(water_chain, chain.type) + for res in chain.residues: + new_res = edi.AppendResidue(water_chain, res.name) + new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) + new_res.SetStringProp('description', chain.description) + a_b = _CopyAtoms(res, new_res, edi, tr) + if not a_pos_wrong: + a_pos_wrong = a_b + else: + if not ligand_chain.IsValid(): + # all ligands, put in one chain, are named '_' + ligand_chain = edi.InsertChain('_') + last_rnum = 0 + else: + last_rnum = ligand_chain.residues[-1].number.num + residues=chain.residues + ins_code='\0' + if len(residues)>1: + ins_code='A' + for res in chain.residues: + new_res = edi.AppendResidue(ligand_chain, res.name, + mol.ResNum(last_rnum+1, ins_code)) + new_res.SetStringProp('description', chain.description) + new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) + new_res.SetStringProp("original_name", chain.name) + if chain.HasProp("pdb_auth_chain_name"): + new_res.SetStringProp("pdb_auth_chain_name", + chain.GetStringProp("pdb_auth_chain_name")) + ins_code = chr(ord(ins_code)+1) + a_b = _CopyAtoms(res, new_res, edi, tr) + if not a_pos_wrong: + a_pos_wrong = a_b move_to_origin = None if a_pos_wrong: start = pdb_bu.bounds.min diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc index 78cd7e124f08460009e4f5b98432080e8422ae95..9a21bdb1af003bdaa33406e7f7e98754f8a606ea 100644 --- a/modules/io/pymod/export_mmcif_io.cc +++ b/modules/io/pymod/export_mmcif_io.cc @@ -21,6 +21,7 @@ #include <boost/python/suite/indexing/vector_indexing_suite.hpp> using namespace boost::python; +#include <ost/export_helper/pair_to_tuple_conv.hh> #include <ost/io/mol/io_profile.hh> #include <ost/io/mol/mmcif_reader.hh> #include <ost/io/mol/mmcif_info.hh> @@ -172,23 +173,44 @@ void export_mmcif_io() .add_property("seq_rnum", &MMCifInfoStructRefSeqDif::GetSeqRNum) .add_property("db_rnum", &MMCifInfoStructRefSeqDif::GetDBRNum) ; + + typedef std::pair<int, int> IntPair; + to_python_converter<IntPair, PairToTupleConverter<int, int> >(); + typedef std::vector<IntPair> VectorIntPair; + class_<VectorIntPair>("VectorIntPair", init<>()) + .def(vector_indexing_suite<VectorIntPair, true>()) + ; + class_<MMCifInfoBioUnit>("MMCifInfoBioUnit", init<>()) .def("SetDetails", &MMCifInfoBioUnit::SetDetails) .def("GetDetails", &MMCifInfoBioUnit::GetDetails) .def("AddChain", &MMCifInfoBioUnit::AddChain) + .def("SetChainList", &MMCifInfoBioUnit::SetChainList) .def("GetChainList", make_function(&MMCifInfoBioUnit::GetChainList, return_value_policy<copy_const_reference>())) + .def("GetChainIntervalList", + make_function(&MMCifInfoBioUnit::GetChainIntervalList, + return_value_policy<copy_const_reference>())) .def("AddOperations", &MMCifInfoBioUnit::AddOperations) .def("GetOperations", make_function(&MMCifInfoBioUnit::GetOperations, return_value_policy<copy_const_reference>())) + .def("GetOperationsIntervalList", + make_function(&MMCifInfoBioUnit::GetOperationsIntervalList, + return_value_policy<copy_const_reference>())) .def("SetID", &MMCifInfoBioUnit::SetID) .def("GetID", &MMCifInfoBioUnit::GetID) .add_property("details", &MMCifInfoBioUnit::GetDetails, &MMCifInfoBioUnit::SetDetails) .add_property("chains", make_function(&MMCifInfoBioUnit::GetChainList, return_value_policy<copy_const_reference>())) + .add_property("chainintervalls", make_function( + &MMCifInfoBioUnit::GetChainIntervalList, + return_value_policy<copy_const_reference>())) .add_property("operations", make_function(&MMCifInfoBioUnit::GetOperations, return_value_policy<copy_const_reference>())) + .add_property("operationsintervalls", make_function( + &MMCifInfoBioUnit::GetOperationsIntervalList, + return_value_policy<copy_const_reference>())) .add_property("id", &MMCifInfoBioUnit::GetID, &MMCifInfoBioUnit::SetID) ; diff --git a/modules/io/pymod/remote.py b/modules/io/pymod/remote.py new file mode 100644 index 0000000000000000000000000000000000000000..102cf680711ffafaeb98aab2c5f6a0aff082044d --- /dev/null +++ b/modules/io/pymod/remote.py @@ -0,0 +1,93 @@ +#------------------------------------------------------------------------------ +# This file is part of the OpenStructure project <www.openstructure.org> +# +# Copyright (C) 2008-2011 by the OpenStructure authors +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3.0 of the License, or (at your option) +# any later version. +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#------------------------------------------------------------------------------ + +import urllib2 +import tempfile + +from ost.io import LoadPDB, LoadMMCIF + +class RemoteRepository: + """ + A remote repository represents a structural database accessible through the + internet, e.g. the PDB or SWISS-MODEL template library. + """ + def __init__(self, name, url_pattern, type, id_transform='upper'): + self.name = name + self.url_pattern = url_pattern + self.type = type + if type not in ('cif', 'pdb'): + raise ValueError('only cif and pdb types are supported') + self.id_transform = id_transform + + def URLForID(self, id): + if self.id_transform == 'upper': + id = id.upper() + if self.id_transform == 'lower': + id = id.lower() + return self.url_pattern.replace('$ID', id) + + def Get(self, id): + remote_url = self.URLForID(id) + tmp_file_suffix = '.%s' % self.type + if remote_url.endswith('.gz'): + tmp_file_suffix+='.gz' + + try: + connection = urllib2.urlopen(remote_url) + status = connection.getcode() + except urllib2.HTTPError, e: + status = e.code + msg = 'Could not load %s from %s (status code %d)' + if status!=200: + raise IOError(msg % (id , self.name ,status)) + tmp_file = tempfile.NamedTemporaryFile(suffix=tmp_file_suffix) + contents = ''.join(connection) + tmp_file.write(contents) + tmp_file.flush() + return tmp_file + + def Load(self, id): + tmp_file = self.Get(id) + if self.type == 'pdb': + return LoadPDB(tmp_file.name) + if self.type == 'cif': + return LoadMMCIF(tmp_file.name) + +REMOTE_REPOSITORIES = { + 'pdb' : RemoteRepository('pdb.org (PDB)', 'http://www.pdb.org/pdb/files/$ID.ent.gz', + type='pdb', id_transform='upper'), + 'smtl' : RemoteRepository('SMTL', 'http://beta.swissmodel.expasy.org/templates/$ID.pdb', + type='pdb', id_transform='lower'), + 'cif' : RemoteRepository('pdb.org (mmCIF)', 'http://www.pdb.org/pdb/files/$ID.cif.gz', + type='cif', id_transform='lower'), + 'pdb_redo' : RemoteRepository('pdbredo', 'http://www.cmbi.ru.nl/pdb_redo/$ID/$ID_besttls.pdb', + type='pdb'), +} + +def RemoteGet(id, from_repo='pdb'): + remote_repo = REMOTE_REPOSITORIES.get(from_repo, None) + if not remote_repo: + raise ValueError('%s is not a valid repository' % from_repo) + return remote_repo.Get(id) + +def RemoteLoad(id ,from_repo='pdb'): + remote_repo = REMOTE_REPOSITORIES.get(from_repo, None) + if not remote_repo: + raise ValueError('%s is not a valid repository' % from_repo) + return remote_repo.Load(id) diff --git a/modules/io/src/mol/mmcif_info.cc b/modules/io/src/mol/mmcif_info.cc index 29f0db7463188068b3584a49457126d7ec1601d0..e7f391894cab4e8ace515de79fa14f6e047fd683 100644 --- a/modules/io/src/mol/mmcif_info.cc +++ b/modules/io/src/mol/mmcif_info.cc @@ -72,7 +72,75 @@ void MMCifInfo::AddAuthorsToCitation(StringRef id, std::vector<String> list) throw IOException("No citation for identifier '" + id.str() + "' found."); } +void MMCifInfo::AddBioUnit(MMCifInfoBioUnit bu) +{ + std::vector<MMCifInfoBioUnit>::iterator bu_it; + for (bu_it = biounits_.begin(); bu_it != biounits_.end(); ++bu_it) { + if (bu_it->GetID() == bu.GetID()) { + break; + } + } + if (bu_it != biounits_.end()) { + bu_it->Merge(bu); + return; + } + biounits_.push_back(bu); +} +void MMCifInfoBioUnit::AddChain(String chain) +{ + chains_.push_back(chain); + + if (tr_chains_.size()) { + tr_chains_.back().second = chains_.size(); + } + else { + std::pair<int, int> tr_interval = std::pair<int, int>(0, 1); + tr_chains_.push_back(tr_interval); + } +} + +void MMCifInfoBioUnit::SetChainList(std::vector<String> chains) +{ + chains_ = chains; + + if (tr_chains_.size()) { + tr_chains_.clear(); + } + std::pair<int, int> tr_interval = std::pair<int, int>(0, chains_.size()); + tr_chains_.push_back(tr_interval); +} + +void MMCifInfoBioUnit::AddOperations(std::vector<MMCifInfoTransOpPtr> operations) +{ + operations_.push_back(operations); + + if (tr_operations_.size()) { + tr_operations_.back().second = operations_.size(); + } + else { + std::pair<int, int> tr_interval = std::pair<int, int>(0, 1); + tr_operations_.push_back(tr_interval); + } +} + +void MMCifInfoBioUnit::Merge(MMCifInfoBioUnit& from) +{ + // merge chains + int old_size = chains_.size(); + chains_.insert(chains_.end(), from.chains_.begin(), from.chains_.end()); + std::pair<int, int> tr_interval = std::pair<int, int>(old_size, + chains_.size()); + tr_chains_.push_back(tr_interval); + // merge operations + old_size = operations_.size(); + operations_.insert(operations_.end(), + from.operations_.begin(), + from.operations_.end()); + tr_interval.first = old_size; + tr_interval.second = operations_.size(); + tr_operations_.push_back(tr_interval); +} MMCifInfoStructRefSeqPtr MMCifInfoStructRef::AddAlignedSeq(const String& aid, const String& chain_name, @@ -108,5 +176,4 @@ MMCifInfoStructRefSeq::AddDif(int seq_rnum, int db_rnum, const String& details) return d; } - }} //ns diff --git a/modules/io/src/mol/mmcif_info.hh b/modules/io/src/mol/mmcif_info.hh index f567af0520381f6b726be63046235e2dd0b9a87a..52a44aedc1baf2dcea4255f4a4980eeaec03570f 100644 --- a/modules/io/src/mol/mmcif_info.hh +++ b/modules/io/src/mol/mmcif_info.hh @@ -241,6 +241,11 @@ public: /// \brief Create a biounit. MMCifInfoBioUnit(): id_(""), details_("") {}; + /// \brief Merge chains & operations, set intervals + /// + /// \param from biounit to read data from + void Merge(MMCifInfoBioUnit& from); + /// \brief Set id /// /// \param id id @@ -262,19 +267,39 @@ public: /// \brief Add a chain name /// /// \param chain chain name - void AddChain(String chain) { chains_.push_back(chain); } + void AddChain(String chain); + + /// \brief Set a vector of chain names + /// + /// \param chains chain name + void SetChainList(std::vector<String> chains); + /// \brief Get vector of chain names /// /// \return chains const std::vector<String>& GetChainList() const { return chains_; } + /// \brief Get the list of intervals of chains + /// + /// \return pair-intervals + const std::vector<std::pair<int, int> >& GetChainIntervalList() + { + return tr_chains_; + } + /// \brief Add a set of operations /// /// \param operations vector of operations to be added - void AddOperations(std::vector<MMCifInfoTransOpPtr> operations) + void AddOperations(std::vector<MMCifInfoTransOpPtr> operations); + + /// \brief Get the list of intervals of operations + /// + /// \return pair-intervals + const std::vector<std::pair<int, int> >& GetOperationsIntervalList() { - operations_.push_back(operations); + return tr_operations_; } + /// \brief Get the list of operations /// /// \return vector of vectors of iterators. @@ -293,6 +318,12 @@ public: if (this->chains_ != bu.chains_) { return false; } + if (this->tr_chains_ != bu.tr_chains_) { + return false; + } + if (this->tr_operations_ != bu.tr_operations_) { + return false; + } if (this->operations_.size() == bu.operations_.size()) { std::vector<std::vector<MMCifInfoTransOpPtr> >::const_iterator th_ops_it; std::vector<std::vector<MMCifInfoTransOpPtr> >::const_iterator bu_ops_it; @@ -329,8 +360,10 @@ public: private: String id_; ///< pdbx_struct_assembly.id String details_; ///< pdbx_struct_assembly.details - std::vector<String> chains_; ///< chains involved in this assembly + std::vector<String> chains_; ///< all chains of this this assembly + std::vector<std::pair<int, int> > tr_chains_; //< chains of a transformation std::vector<std::vector<MMCifInfoTransOpPtr> > operations_; + std::vector<std::pair<int, int> > tr_operations_; //< ops. of a transformation }; class DLLEXPORT_OST_IO MMCifInfoCitation { @@ -888,10 +921,7 @@ public: /// \brief Add a biounit /// /// \param bu biounit to be added - void AddBioUnit(MMCifInfoBioUnit bu) // unit test - { - biounits_.push_back(bu); - } + void AddBioUnit(MMCifInfoBioUnit bu); /// \brief Get the list of biounits stored in an info object. /// diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index 33e71d4e3daeced0ddf26484cdfb4c0dfe9bbccf..91d46cb9b86646add1832a8ea972b6c316a3cba7 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -981,14 +981,13 @@ std::vector<std::vector<String> > MMCifReader::UnPackOperExperession(StringRef e void MMCifReader::ParsePdbxStructAssemblyGen(const std::vector<StringRef>& columns) { MMCifBioUAssembly assembly; - assembly.biounit = MMCifInfoBioUnit(); - assembly.biounit.SetID(columns[indices_[ASSEMBLY_ID]].str()); + assembly.biounit_id = columns[indices_[ASSEMBLY_ID]].str(); std::vector<StringRef> tmp_chains=columns[indices_[ASYM_ID_LIST]].split(','); std::vector<StringRef>::const_iterator tc_it; for (tc_it = tmp_chains.begin(); tc_it != tmp_chains.end(); ++tc_it) { - assembly.biounit.AddChain(tc_it->str()); + assembly.chains.push_back(tc_it->str()); } assembly.operations = @@ -1620,19 +1619,22 @@ void MMCifReader::OnEndData() std::vector<MMCifInfoTransOpPtr> operations = info_.GetOperations(); info_.SetStructRefs(struct_refs_); std::vector<MMCifInfoTransOpPtr>::const_iterator buop_it; + MMCifInfoBioUnit biounit; for (bua_it = bu_assemblies_.begin(); bua_it != bu_assemblies_.end(); ++bua_it) { + biounit = MMCifInfoBioUnit(); // pair with pdbx_struct_assembly entry - buom_it = bu_origin_map_.find(bua_it->biounit.GetID()); + buom_it = bu_origin_map_.find(bua_it->biounit_id); if (buom_it == bu_origin_map_.end()) { throw IOException(this->FormatDiagnostic(STAR_DIAG_ERROR, "No pdbx_struct_assembly.id '"+ - bua_it->biounit.GetID() + + bua_it->biounit_id + "' found as requested by pdbx_struct_assembly_gen.")); } - bua_it->biounit.SetDetails(buom_it->second); - bua_it->biounit.SetID(buom_it->first); + biounit.SetDetails(buom_it->second); + biounit.SetID(buom_it->first); + biounit.SetChainList(bua_it->chains); // pair with pdbx_struct_oper_list for (aol_it = bua_it->operations.begin(); @@ -1657,9 +1659,9 @@ void MMCifReader::OnEndData() "' found as requested by pdbx_struct_assembly_gen.")); } } - bua_it->biounit.AddOperations(operation_list); + biounit.AddOperations(operation_list); } - info_.AddBioUnit(bua_it->biounit); + info_.AddBioUnit(biounit); } bu_assemblies_.clear(); diff --git a/modules/io/src/mol/mmcif_reader.hh b/modules/io/src/mol/mmcif_reader.hh index b8f6daed068fd5c96293d4d8e6442d24a74b3e0b..d91cf340355be48f58664a4ada5e02966365e931 100644 --- a/modules/io/src/mol/mmcif_reader.hh +++ b/modules/io/src/mol/mmcif_reader.hh @@ -559,9 +559,11 @@ private: /// \struct assembly information typedef struct { - MMCifInfoBioUnit biounit; + String biounit_id; ///< identifier for the bu + std::vector<String> chains; ///< chains affected by + /// this operations std::vector<std::vector<String> > operations; ///< list of links to - /// MMCifBioUOperation + /// MMCifBioUOperation } MMCifBioUAssembly; typedef std::vector<MMCifBioUAssembly> MMCifBioUAssemblyVector; diff --git a/modules/io/tests/test_io_mmcif.py b/modules/io/tests/test_io_mmcif.py index ba3eb6b63e008060e267f3fd8cb97ed838ac5b33..be7594314f103c127f2c6297066daf45f24e7d21 100644 --- a/modules/io/tests/test_io_mmcif.py +++ b/modules/io/tests/test_io_mmcif.py @@ -69,14 +69,38 @@ class TestMMCifInfo(unittest.TestCase): b.SetDetails('Details') self.assertEquals(b.GetDetails(), 'Details') b.AddChain('A') + b.AddChain('B') cl = b.GetChainList() + il = b.GetChainIntervalList() self.assertEquals(cl[0], 'A') + self.assertEquals(il[0][0], 0) + self.assertEquals(il[0][1], 2) + s = ost.StringList() + s.append('B') + s.append('C') + s.append('D') + b.SetChainList(s) + cl = b.GetChainList() + il = b.GetChainIntervalList() + self.assertEquals(il[0][0], 0) + self.assertEquals(il[0][1], 3) + self.assertEquals(cl[0], 'B') + self.assertEquals(cl[1], 'C') + self.assertEquals(cl[2], 'D') i = io.MMCifInfo() i.AddBioUnit(b) + i.AddBioUnit(b) + b.SetID("2") + i.AddBioUnit(b) bl = i.GetBioUnits() - self.assertEquals(len(bl), 1) + il = bl[0].GetChainIntervalList() + self.assertEquals(il[0][0], 0) + self.assertEquals(il[0][1], 3) + self.assertEquals(il[1][0], 3) + self.assertEquals(il[1][1], 6) + self.assertEquals(len(bl), 2) def test_mmcifinfo_transoperation(self): @@ -102,6 +126,10 @@ class TestMMCifInfo(unittest.TestCase): b.AddOperations(ol) oll = b.GetOperations() self.assertEquals(oll[0][0].GetID(), '1') + tr_ol = b.GetOperationsIntervalList() + self.assertEquals(len(tr_ol), 1) + self.assertEquals(tr_ol[0][0], 0) + self.assertEquals(tr_ol[0][1], 1) def test_mmcifinfo_biounit_pdbize(self): ent, seqres, info = io.LoadMMCIF("testfiles/mmcif/3T6C.cif.gz", @@ -170,7 +198,7 @@ class TestMMCifInfo(unittest.TestCase): seqres=True, info=True) pdb_ent, t = info.GetBioUnits()[0].PDBize(ent, transformation=True) - self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[0], -915.759, 3) + self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[0], -915.8, 1) self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[1], -952.345, 2) self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[2], 3221.75, 2) self.assertEquals(geom.Equal(t, diff --git a/modules/io/tests/test_mmcif_info.cc b/modules/io/tests/test_mmcif_info.cc index 3f3e21baf4b8a9e3f10b8f65380338668015bfd3..71dc2ddf40d7433c60629497288cf6e989528a5d 100644 --- a/modules/io/tests/test_mmcif_info.cc +++ b/modules/io/tests/test_mmcif_info.cc @@ -109,10 +109,23 @@ BOOST_AUTO_TEST_CASE(mmcif_info_biounit) MMCifInfoBioUnit bu = MMCifInfoBioUnit(); bu.SetDetails("author_defined_assembly"); + bu.SetID("1"); + bu.AddChain("B"); bu.AddChain("A"); BOOST_CHECK(bu.GetDetails() == "author_defined_assembly"); BOOST_CHECK(bu.GetChainList().back() == "A"); + std::vector<std::pair<int, int> > tr = bu.GetChainIntervalList(); + BOOST_CHECK(tr[0].first == 0); + BOOST_CHECK(tr[0].second == 2); + + std::vector<String> chains; + chains.push_back("B"); + bu.SetChainList(chains); + BOOST_CHECK(bu.GetChainList().back() == "B"); + tr = bu.GetChainIntervalList(); + BOOST_CHECK(tr[0].first == 0); + BOOST_CHECK(tr[0].second == 1); MMCifInfo info = MMCifInfo(); info.AddBioUnit(bu); @@ -120,6 +133,18 @@ BOOST_AUTO_TEST_CASE(mmcif_info_biounit) BOOST_CHECK(biounits.size() == 1); BOOST_CHECK(biounits.back() == bu); + info.AddBioUnit(bu); + bu.SetID("2"); + info.AddBioUnit(bu); + biounits = info.GetBioUnits(); + BOOST_CHECK(biounits.size() == 2); + tr = biounits.front().GetChainIntervalList(); + BOOST_CHECK(tr.size() == 2); + BOOST_CHECK(tr[0].first == 0); + BOOST_CHECK(tr[0].second == 1); + BOOST_CHECK(tr[1].first == 1); + BOOST_CHECK(tr[1].second == 2); + BOOST_MESSAGE(" done."); } @@ -148,6 +173,10 @@ BOOST_AUTO_TEST_CASE(mmcif_info_transoperation) MMCifInfoBioUnit bu = MMCifInfoBioUnit(); bu.AddOperations(ops); BOOST_CHECK((*(bu.GetOperations().begin()->begin())) == op); + std::vector<std::pair<int, int> > tr = bu.GetOperationsIntervalList(); + BOOST_CHECK(tr.size() == 1); + BOOST_CHECK(tr.back().first == 0); + BOOST_CHECK(tr.back().second == 1); BOOST_MESSAGE(" done."); } diff --git a/modules/mol/alg/doc/molalg.rst b/modules/mol/alg/doc/molalg.rst index 66b14294022870a6dfe967ce407994388ef6679d..5a3e5e7c9ac93646263e05e18b45e198bcb734b3 100644 --- a/modules/mol/alg/doc/molalg.rst +++ b/modules/mol/alg/doc/molalg.rst @@ -276,7 +276,7 @@ The following function detects steric clashes in atomic structures. Two atoms ar :param clash_distance: minimum clashing distance (in Angstroms) :param tolerance: tolerance threshold (in Angstroms) - .. method GetClashingDistance() + .. method:: GetClashingDistance() Recovers a reference distance and a tolerance threshold from the list @@ -285,6 +285,15 @@ The following function detects steric clashes in atomic structures. Two atoms ar :returns: a tuple containing the minimum clashing distance and the tolerance threshold + .. method:: GetAdjustedClashingDistance() + + Recovers a reference distance from the list, already adjusted by the tolerance threshold + + :param ele1: string containing the first element's name + :param ele2: string containing the second element's name + + :returns: the adjusted minimum clashing distance + .. method:: GetMaxAdjustedDistance() Returns the longest clashing distance in the list, after adjustment with tolerance threshold diff --git a/modules/mol/alg/pymod/__init__.py b/modules/mol/alg/pymod/__init__.py index 126d0196f2d6ff25148a6724df5dd63a1e764d6a..b8c09d51d67b99b606ddc9c99af55afe37823dd4 100644 --- a/modules/mol/alg/pymod/__init__.py +++ b/modules/mol/alg/pymod/__init__.py @@ -6,11 +6,11 @@ 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): +def FillClashingDistancesFromFile(filename): fh=open(filename,'r') lines=fh.readlines() fh.close() - return FillClashingDistances(lines,default_clashing_distance,default_tolerance) + return FillClashingDistances(lines) # Fills a list of bond stereo-chemical statistics from a file (requires a path to the file) def FillBondStereoChemicalParamsFromFile(filename): @@ -33,7 +33,7 @@ def DefaultClashingDistances(): fh=open(filename,'r') lines=fh.readlines() fh.close() - return FillClashingDistances(lines,1.5,0.0) + return FillClashingDistances(lines) # Returns the default list of bond stereo-chemical statistics (from the default OpenStructure parameter file) def DefaultBondStereoChemicalParams(): diff --git a/modules/mol/alg/pymod/structure_analysis.py b/modules/mol/alg/pymod/structure_analysis.py index 7cbd0dd4b32bb7e6f4093ed23bbbb52a700fc320..1ad301618bc64e8d1673e2c95b1e9d1dd3a208ef 100644 --- a/modules/mol/alg/pymod/structure_analysis.py +++ b/modules/mol/alg/pymod/structure_analysis.py @@ -13,7 +13,7 @@ def GetFrameFromEntity(eh): Input: eh : EntityHandle """ - return ost.mol.CreateCoordFrame(eh.GetAtomPosList()) + return ost.mol.CreateCoordFrame(eh.GetAtomPosList(ordered_by_index=True)) def GetDistanceBetwCenterOfMass(sele1,sele2): """ diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc index 08ad6631efe89ce483e9cc653c2baec321db6927..b775b6396338c2ee45357bcfd56d259e6704b002 100644 --- a/modules/mol/alg/pymod/wrap_mol_alg.cc +++ b/modules/mol/alg/pymod/wrap_mol_alg.cc @@ -24,6 +24,7 @@ #include <ost/mol/alg/superpose_frames.hh> #include <ost/mol/alg/filter_clashes.hh> #include <ost/mol/alg/consistency_checks.hh> +#include <ost/export_helper/pair_to_tuple_conv.hh> using namespace boost::python; using namespace ost; @@ -60,7 +61,7 @@ ost::mol::alg::StereoChemicalParams fill_stereochemical_params_wrapper (const St return ost::mol::alg::FillStereoChemicalParams(header,stereo_chemical_props_file_vector); } -ost::mol::alg::ClashingDistances fill_clashing_distances_wrapper (const list& stereo_chemical_props_file, Real min_default_distance, Real min_distance_tolerance) +ost::mol::alg::ClashingDistances fill_clashing_distances_wrapper (const list& stereo_chemical_props_file) { int stereo_chemical_props_file_length = boost::python::extract<int>(stereo_chemical_props_file.attr("__len__")()); std::vector<String> stereo_chemical_props_file_vector(stereo_chemical_props_file_length); @@ -103,6 +104,9 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) export_entity_to_density(); #endif + to_python_converter<std::pair<Real,Real>, + PairToTupleConverter<Real, Real> >(); + 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)); @@ -124,6 +128,7 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) class_<mol::alg::ClashingDistances> ("ClashingDistances",init<>()) .def("SetClashingDistance",&mol::alg::ClashingDistances::SetClashingDistance) .def("GetClashingDistance",&mol::alg::ClashingDistances::GetClashingDistance) + .def("GetAdjustedClashingDistance",&mol::alg::ClashingDistances::GetAdjustedClashingDistance) .def("GetMaxAdjustedDistance",&mol::alg::ClashingDistances::GetMaxAdjustedDistance) .def("IsEmpty",&mol::alg::ClashingDistances::IsEmpty) @@ -162,7 +167,8 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) def("PrintGlobalRDMap",&mol::alg::PrintGlobalRDMap); def("PrintResidueRDMap",&mol::alg::PrintResidueRDMap); - def("ResidueNamesMatch",&mol::alg::ResidueNamesMatch); + def("ResidueNamesMatch",&mol::alg::ResidueNamesMatch, + (arg("probe"), arg("reference"), arg("log_as_error")=false)); } diff --git a/modules/mol/alg/src/consistency_checks.cc b/modules/mol/alg/src/consistency_checks.cc index 371f3c37b6b8fbc921ecd3a82fa647251992b216..bdc0ab646f8fb4bb42762034fa6c618b54a8ca98 100644 --- a/modules/mol/alg/src/consistency_checks.cc +++ b/modules/mol/alg/src/consistency_checks.cc @@ -24,19 +24,8 @@ namespace ost { namespace mol { namespace alg { -/// \brief Checks that residue types with the same ResNum in the two structures match -/// -/// Requires a reference structure and a probe structure. The function checks that all the -/// residues in the reference structure that appear in the probe structure (i.e., that have the -/// same ResNum) are of the same residue type. Chains are paired by index, not by chain name -/// (i.e., the first chain of the reference will be compared with the first chain of the probe, -/// the second with the second, etc.) - - - - - -bool ResidueNamesMatch (const mol::EntityView& probe, const mol::EntityView& reference) +bool ResidueNamesMatch(const EntityView& probe, const EntityView& reference, + bool log_as_error) { bool return_value = true; ChainViewList ref_chains = reference.GetChainList(); @@ -51,8 +40,12 @@ bool ResidueNamesMatch (const mol::EntityView& probe, const mol::EntityView& ref if (probe_residue.IsValid()) { if (probe_residue.GetName()!=rri->GetName()) { return_value = false; - LOG_VERBOSE("Name mismatch for residue " << probe_residue.GetNumber() << " in chain " << rci); - LOG_VERBOSE("In reference: " << rri->GetName() << ", in compared structure: " << probe_residue.GetName()); + if (log_as_error) { + LOG_ERROR("Name mismatch for residue " << probe_residue.GetNumber() << ": in the reference structure(s) is " << rri->GetName() << ", in the model " << probe_residue.GetName()); + } else { + LOG_WARNING("Name mismatch for residue " << probe_residue.GetNumber() << ": in the reference structure(s) is " << rri->GetName() << ", in the model " << probe_residue.GetName()); + } + } } } diff --git a/modules/mol/alg/src/consistency_checks.hh b/modules/mol/alg/src/consistency_checks.hh index 77cffda1ce3639c37111cc0b7d8fa120015e9958..34eb4568b82f54cdfba2e5b2423d176d322d9a2f 100644 --- a/modules/mol/alg/src/consistency_checks.hh +++ b/modules/mol/alg/src/consistency_checks.hh @@ -31,8 +31,9 @@ namespace ost { namespace mol { namespace alg { /// same ResNum) are of the same residue type. Chains are comapred by order, not by chain name /// (i.e.: the first chain of the reference will be compared with the first chain of the probe /// structure, etc.) - -bool DLLEXPORT_OST_MOL_ALG ResidueNamesMatch (const mol::EntityView& probe, const mol::EntityView& reference); +bool DLLEXPORT_OST_MOL_ALG ResidueNamesMatch(const EntityView& probe, + const EntityView& reference, + bool log_as_error=false); }}} diff --git a/modules/mol/alg/src/filter_clashes.cc b/modules/mol/alg/src/filter_clashes.cc index 27ffb844853f7d68821d3356ec6895ef4389b4f1..b7a22ba13b0e30852669e132cf77a089d0874428 100644 --- a/modules/mol/alg/src/filter_clashes.cc +++ b/modules/mol/alg/src/filter_clashes.cc @@ -19,6 +19,7 @@ #include <ost/log.hh> #include <ost/mol/mol.hh> #include <sstream> +#include <iomanip> #include <math.h> #include "filter_clashes.hh" #include <ost/units.hh> @@ -107,6 +108,12 @@ std::pair<Real,Real> ClashingDistances::GetClashingDistance(const String& ele1,c return find_ci->second; } +Real ClashingDistances::GetAdjustedClashingDistance(const String& ele1,const String& ele2) const +{ + std::pair <Real,Real> clash_dist = GetClashingDistance(ele1,ele2); + return clash_dist.first-clash_dist.second; +} + void ClashingDistances::PrintAllDistances() const { for (std::map <String,std::pair<float,float> >::const_iterator index = min_distance_.begin();index != min_distance_.end();++index) { @@ -460,6 +467,7 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam if (remove_bb) { LOG_INFO("ACTION: removing whole residue " << res); + res.SetBoolProp("stereo_chemical_violation_backbone",true); continue; } if (remove_sc) { @@ -472,15 +480,16 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam filtered.AddAtom(atom); } } + res.SetBoolProp("stereo_chemical_violation_sidechain",true); continue; } filtered.AddResidue(res, ViewAddFlag::INCLUDE_ATOMS); } Real avg_zscore_bonds = running_sum_zscore_bonds/static_cast<float>(bond_count); 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") + std::cout << "Average Z-Score for bond lengths: " << std::fixed << std::setprecision(5) << avg_zscore_bonds << std::endl; + std::cout << "Bonds outside of tolerance range: " << bad_bond_count << " out of " << bond_count << std::endl; + std::cout << "Bond\tAvg Length\tAvg zscore\tNum Bonds" << std::endl; 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; @@ -489,10 +498,11 @@ EntityView CheckStereoChemistry(const EntityView& ent, const StereoChemicalParam 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); + std::cout << key << "\t" << std::fixed << std::setprecision(5) << std::left << std::setw(10) << avg_length << "\t" << std::left << std::setw(10) << avg_zscore << "\t" << counter << std::endl; } - LOG_SCRIPT("Average Z-Score angle widths: " << avg_zscore_angles); - LOG_SCRIPT("Angles outside of tolerance range: " << bad_angle_count << " out of " << angle_count); + std::cout << "Average Z-Score angle widths: " << std::fixed << std::setprecision(5) << avg_zscore_angles << std::endl; + std::cout << "Angles outside of tolerance range: " << bad_angle_count << " out of " << angle_count << std::endl; + filtered.AddAllInclusiveBonds(); return filtered; } @@ -575,6 +585,7 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis if (remove_bb) { LOG_VERBOSE("ACTION: removing whole residue " << res); + res.SetBoolProp("steric_clash",true); continue; } if (remove_sc) { @@ -587,6 +598,7 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis filtered.AddAtom(atom); } } + res.SetBoolProp("steric_clash",true); continue; } filtered.AddResidue(res, ViewAddFlag::INCLUDE_ATOMS); @@ -595,8 +607,9 @@ EntityView FilterClashes(const EntityView& ent, const ClashingDistances& min_dis 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); + std::cout << bad_distance_count << " non-bonded short-range distances shorter than tolerance distance" << std::endl; + std::cout << "Distances shorter than tolerance are on average shorter by: " << std::fixed << std::setprecision(5) << average_offset << std::endl; + filtered.AddAllInclusiveBonds(); return filtered; } diff --git a/modules/mol/alg/src/filter_clashes.hh b/modules/mol/alg/src/filter_clashes.hh index f9d7473b6ce1eb0d5044c6f46a4bebadc86bff83..e294cd4895ad9790a3b001a73873f8b7b4812cc8 100644 --- a/modules/mol/alg/src/filter_clashes.hh +++ b/modules/mol/alg/src/filter_clashes.hh @@ -40,6 +40,9 @@ public: /// \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 a reference distance already adjusted by the tolerance threshold from the list + Real GetAdjustedClashingDistance(const String& ele1,const String& ele2) const; + /// \brief Recovers the longest distance in the list, corrected by tolerance Real GetMaxAdjustedDistance() const; diff --git a/modules/mol/alg/src/lddt.cc b/modules/mol/alg/src/lddt.cc index a7615007b548256067a4c2c093c7f248fc1b7012..ebf1a6e89f26f6144d4af58bd0efeea27d2f7e99 100644 --- a/modules/mol/alg/src/lddt.cc +++ b/modules/mol/alg/src/lddt.cc @@ -83,7 +83,6 @@ void usage() std::cerr << " -v <level> verbosity level (0=results only,1=problems reported, 2=full report)" << std::endl; std::cerr << " -b <value> tolerance in stddevs for bonds" << std::endl; 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; @@ -97,7 +96,11 @@ std::pair<int,int> compute_coverage (const EntityView& v,const GlobalRDMap& glob int second=0; int first=0; if (v.GetResidueList().size()==0) { - return std::make_pair<int,int>(0,1); + if (glob_dist_list.size()==0) { + return std::make_pair<int,int>(0,-1); + } else { + return std::make_pair<int,int>(0,glob_dist_list.size()); + } } ChainView vchain=v.GetChainList()[0]; for (GlobalRDMap::const_iterator i=glob_dist_list.begin();i!=glob_dist_list.end();++i) @@ -111,6 +114,17 @@ std::pair<int,int> compute_coverage (const EntityView& v,const GlobalRDMap& glob return std::make_pair<int,int>(first,second); } +bool is_resnum_in_globalrdmap(const ResNum& resnum, const GlobalRDMap& glob_dist_list) +{ + for (GlobalRDMap::const_iterator i=glob_dist_list.begin(), e=glob_dist_list.end(); i!=e; ++i) { + ResNum rn = i->first; + if (rn==resnum) { + return true; + } + } + return false; +} + int main (int argc, char **argv) { // sets some default values for parameters @@ -241,8 +255,9 @@ int main (int argc, char **argv) if (!ref) { exit(-1); } - ref_list.push_back(ref.CreateFullView()); - glob_dist_list = CreateDistanceList(ref.CreateFullView(),radius); + EntityView refview=ref.GetChainList()[0].Select("peptide=true"); + ref_list.push_back(refview); + glob_dist_list = CreateDistanceList(refview,radius); } else { std::cout << "Multi-reference mode: On" << std::endl; for (std::vector<StringRef>::const_iterator ref_file_split_sr_it = ref_file_split_sr.begin(); @@ -258,6 +273,7 @@ int main (int argc, char **argv) exit(-1); } } + EntityView refview=ref.GetChainList()[0].Select("peptide=true"); ref_list.push_back(ref.CreateFullView()); } glob_dist_list = CreateDistanceListFromMultipleReferences (ref_list,cutoffs,sequence_separation,radius); @@ -272,6 +288,7 @@ 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; @@ -284,6 +301,12 @@ int main (int argc, char **argv) } LOG_INFO("LDDT INFO FORMAT: Chain1 Residue1 ResNum1 Atom1 Chain2 Residue2 ResNum2 Atom2 ModelDist TargetDist Difference Tolerance Status"); + // error if the reference structure is empty + if (glob_dist_list.size()==0) { + std::cout << "ERROR: No valid distance to check in the reference structure(s). Please check that the first chain of the reference structure(s) contains a peptide." << std::endl; + exit(-1); + } + // cycles through the models to evaluate for (size_t i=0; i<files.size(); ++i) { EntityHandle model=load(files[i], profile); @@ -293,17 +316,17 @@ int main (int argc, char **argv) } continue; } - EntityView v=model.CreateFullView(); - + EntityView v=model.GetChainList()[0].Select("peptide=true"); + EntityView outv=model.GetChainList()[0].Select("peptide=true"); for (std::vector<EntityView>::const_iterator ref_list_it = ref_list.begin(); ref_list_it != ref_list.end(); ++ref_list_it) { - bool cons_check = ResidueNamesMatch(v,*ref_list_it); + bool cons_check = ResidueNamesMatch(v,*ref_list_it,consistency_checks); if (cons_check==false) { if (consistency_checks==true) { - LOG_ERROR("Residue names in model: " << files[i] << " are inconsistent with one or more references"); + LOG_ERROR("Residue names in model: " << files[i] << " and in reference structure(s) are inconsistent."); exit(-1); } else { - LOG_WARNING("Residue names in model: " << files[i] << " are inconsistent with one or more references"); + LOG_WARNING("Residue names in model: " << files[i] << " and in reference structure(s) are inconsistent."); } } } @@ -313,7 +336,11 @@ int main (int argc, char **argv) String filestring=BFPathToString(pathstring); 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 (cov.second == -1) { + std::cout << "Coverage: 0 (0 out of 0 residues)" << std::endl; + } else { + 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 @@ -355,8 +382,6 @@ int main (int argc, char **argv) std::cout << e.what() << std::endl; exit(-1); } - 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; try { v=alg::FilterClashes(v,nonbonded_table); } catch (std::exception& e) { @@ -364,8 +389,6 @@ int main (int argc, char **argv) std::cout << e.what() << std::endl; exit(-1); } - cov = compute_coverage(v,glob_dist_list); - 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 LDDT score: 0.0" << std::endl; @@ -381,20 +404,67 @@ int main (int argc, char **argv) << " 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 lddt_local = 0; - int conserved_dist = 0; - int total_dist = 0; - if (ritv.HasProp(label)) { + if (structural_checks) { + std::cout << "Local LDDT Scores:" << std::endl; + std::cout << "(A 'Yes' in the 'Quality Problems' column stands for problems" << std::endl; + std::cout << "in the side-chain of a residue, while a 'Yes+' for problems" << std::endl; + std::cout << "in the backbone)" << std::endl; + } else { + std::cout << "Local LDDT Scores:" << std::endl; + } + if (structural_checks) { + std::cout << "Chain\tResName\tResNum\tAsses.\tQ.Prob.\tScore\t(Conserved/Total, over " << cutoffs.size() << " thresholds)" << std::endl; + } else { + std::cout << "Chain\tResName\tResNum\tAsses.\tScore\t(Conserved/Total, over " << cutoffs.size() << " thresholds)" << std::endl; + } + for (ResidueViewIter rit=outv.ResiduesBegin();rit!=outv.ResiduesEnd();++rit){ + ResidueView ritv=*rit; + ResNum rnum = ritv.GetNumber(); + bool assessed = false; + String assessed_string="No"; + bool quality_problems = false; + String quality_problems_string="No"; + Real lddt_local = -1; + String lddt_local_string="-"; + int conserved_dist = -1; + int total_dist = -1; + String dist_string = "-"; + if (is_resnum_in_globalrdmap(rnum,glob_dist_list)) { + assessed = true; + assessed_string="Yes"; + } + if (ritv.HasProp("stereo_chemical_violation_sidechain") || ritv.HasProp("steric_clash_sidechain")) { + quality_problems = true; + quality_problems_string="Yes"; + } + if (ritv.HasProp("stereo_chemical_violation_backbone") || ritv.HasProp("steric_clash_backbone")) { + quality_problems = true; + quality_problems_string="Yes+"; + } + + if (assessed==true) { + if (ritv.HasProp(label)) { lddt_local=ritv.GetFloatProp(label); + std::stringstream stkeylddt; + stkeylddt << std::fixed << std::setprecision(4) << lddt_local; + lddt_local_string=stkeylddt.str(); conserved_dist=ritv.GetIntProp(label+"_conserved"); - total_dist=ritv.GetIntProp(label+"_total"); + total_dist=ritv.GetIntProp(label+"_total"); + std::stringstream stkeydist; + stkeydist << "("<< conserved_dist << "/" << total_dist << ")"; + dist_string=stkeydist.str(); + } else { + lddt_local = 0; + lddt_local_string="0.0000"; + conserved_dist = 0; + total_dist = 0; + dist_string="(0/0)"; + } } - 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; + if (structural_checks) { + std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string << '\t' << quality_problems_string << '\t' << lddt_local_string << "\t" << dist_string << std::endl; + } else { + std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string << '\t' << lddt_local_string << "\t" << dist_string << std::endl; } } std::cout << std::endl; diff --git a/modules/mol/base/pymod/export_bond.cc b/modules/mol/base/pymod/export_bond.cc index 5f7ab1154ad0c785cca591fd5ee47c5b01ee700c..fcad815704b856e8a86363e66c30f5cf18dfdb9b 100644 --- a/modules/mol/base/pymod/export_bond.cc +++ b/modules/mol/base/pymod/export_bond.cc @@ -52,6 +52,7 @@ void export_Bond() .def("GetBondOrder",&BondHandle::GetBondOrder) .def("SetBondOrder",&BondHandle::SetBondOrder) .def("IsValid", &BondHandle::IsValid) + .def("GetHashCode", &BondHandle::GetHashCode) .def(self == self) .def(self != self) .def(self_ns::str(self)) diff --git a/modules/mol/base/pymod/export_entity.cc b/modules/mol/base/pymod/export_entity.cc index bb55d9bd68234616da9d4bf69d646adccf559d71..280024f0a8f513bedd30a83790239446525b9563 100644 --- a/modules/mol/base/pymod/export_entity.cc +++ b/modules/mol/base/pymod/export_entity.cc @@ -155,7 +155,7 @@ void export_Entity() .def("GetMass", &EntityHandle::GetMass) .def("GetCenterOfMass", &EntityHandle::GetCenterOfMass) .def("GetCenterOfAtoms", &EntityHandle::GetCenterOfAtoms) - .def("GetAtomPosList", &EntityHandle::GetAtomPosList) + .def("GetAtomPosList", &EntityHandle::GetAtomPosList, arg("ordered_by_index")=false) .def("GetGeometricCenter", geom_center<EntityHandle>) .add_property("geometric_center", geom_center<EntityHandle>) diff --git a/modules/mol/base/src/atom_base.cc b/modules/mol/base/src/atom_base.cc index c818fbc1cec5ee0c0fa1be6fbb51eb59750133f0..a24ca3abb276770cebf67b00524e1ad4c401b970 100644 --- a/modules/mol/base/src/atom_base.cc +++ b/modules/mol/base/src/atom_base.cc @@ -240,5 +240,12 @@ unsigned long AtomBase::GetIndex() const return Impl()->GetIndex(); } +void AtomBase::SetIndex(const unsigned long index) +{ + this->CheckValidity(); + return impl_->SetIndex(index); +} + + }} // ns diff --git a/modules/mol/base/src/atom_base.hh b/modules/mol/base/src/atom_base.hh index 13795311560e4c81d46063156c75aa6459359131..4ddc13f2f46cea4c19c0e0372bb313b936d51386 100644 --- a/modules/mol/base/src/atom_base.hh +++ b/modules/mol/base/src/atom_base.hh @@ -141,6 +141,7 @@ public: void SetRadius(Real radius); + void SetIndex (const unsigned long index); const geom::Mat3& GetAnisou() const; diff --git a/modules/mol/base/src/coord_group.cc b/modules/mol/base/src/coord_group.cc index 5af231a559b8e07db90f6ec34d539aa238ed63ea..d02eecc2751e49fc66ac64579a102ce632615265 100644 --- a/modules/mol/base/src/coord_group.cc +++ b/modules/mol/base/src/coord_group.cc @@ -239,8 +239,12 @@ CoordGroupHandle CoordGroupHandle::Filter(const EntityView& selected, int first, indices.push_back(i->GetIndex()); } new_ent=CreateEntityFromView(selected, false); + //we have to correct the atom indices in the new entity + AtomHandleList new_atoms=new_ent.GetAtomList(); + for (int i=0,e=atoms.size();i!=e;++i){ + new_atoms[i].SetIndex(i); + } } - CoordGroupHandle filtered_cg=CreateCoordGroup(new_ent.GetAtomList()); std::vector<geom::Vec3> vecs(indices.size()); if (last==-1) last=this->GetFrameCount(); diff --git a/modules/mol/base/src/entity_handle.cc b/modules/mol/base/src/entity_handle.cc index e34e11d2e233ab4a60da62e20c3e085c4ece1f58..7bf3ed349d82cc621198d17be211f4a3b39b3b1a 100644 --- a/modules/mol/base/src/entity_handle.cc +++ b/modules/mol/base/src/entity_handle.cc @@ -402,16 +402,23 @@ AtomHandleList EntityHandle::GetAtomList() const return atoms; } -geom::Vec3List EntityHandle::GetAtomPosList() const { +bool less_index(const mol::AtomHandle& a1, const mol::AtomHandle& a2) +{ + return a1.GetIndex()<a2.GetIndex(); +} + +geom::Vec3List EntityHandle::GetAtomPosList(bool ordered_by_index) const { this->CheckValidity(); geom::Vec3List atom_pos_list; atom_pos_list.reserve(this->GetAtomCount()); AtomHandleList atom_list=this->GetAtomList(); + if (ordered_by_index){ + std::sort(atom_list.begin(),atom_list.end(),less_index); + } for (AtomHandleList::const_iterator a=atom_list.begin(), e=atom_list.end(); a!=e; ++a) { atom_pos_list.push_back(a->GetPos()); } return atom_pos_list; - //return Impl()->GetAtomPosList(); } EntityHandle EntityHandle::GetHandle() const diff --git a/modules/mol/base/src/entity_handle.hh b/modules/mol/base/src/entity_handle.hh index fe2a439135306d6f2a7c080ed91f1e15604faea0..c2888c9e2efbf790090164c253757dfb24b9553b 100644 --- a/modules/mol/base/src/entity_handle.hh +++ b/modules/mol/base/src/entity_handle.hh @@ -289,7 +289,7 @@ public: AtomHandleList GetAtomList() const; /// \brief get complete list of atom positions - geom::Vec3List GetAtomPosList() const; + geom::Vec3List GetAtomPosList(bool ordered_by_index = false) const; /// \brief Get editor for external coordinate system to manipulate atom /// positions diff --git a/scripts/ost_config.in b/scripts/ost_config.in index f756d7cd30c29db720aeba659643c18bb872e4c9..531d5a8ad5eb3a579a4ba608d2bc27159ff95d52 100644 --- a/scripts/ost_config.in +++ b/scripts/ost_config.in @@ -32,6 +32,9 @@ export DYLD_LIBRARY_PATH="$DNG_LIBDIR:${DYLD_LIBRARY_PATH}" export LD_LIBRARY_PATH="$DNG_LIBDIR:${LD_LIBRARY_PATH}" # set QT_PLUGIN_PATH for bundle (commented except in linux bundles) #export QT_PLUGIN_PATH="$BIN_DIR/plugins" +# unset PYTHONPATH for bundle (commented except in linux bundles) +#unset PYTHONPATH + # retrieve absolute path to python executable pyexec="@PYTHON_BINARY@" diff --git a/tools/molck/main.cc b/tools/molck/main.cc index 6b896ac68313eb65e8ed10c75040f6bdd2bfa3c2..94e5a97f5120b9522a3d8678518c44fbe84f4cb7 100644 --- a/tools/molck/main.cc +++ b/tools/molck/main.cc @@ -289,6 +289,7 @@ int main(int argc, char *argv[]) } std::cerr << " --> removed " << hremoved << " hydrogen atoms" << std::endl; } + if (rm_oxt_atoms) { std::cerr << "removing OXT atoms" << std::endl; int oremoved=0; @@ -302,19 +303,6 @@ int main(int argc, char *argv[]) std::cerr << " --> removed " << oremoved << " OXT atoms" << std::endl; } - if (rm_non_std) { - std::cerr << "removing OXT atoms" << std::endl; - int oremoved=0; - AtomHandleList atoms=ent.GetAtomList(); - for (AtomHandleList::const_iterator i=atoms.begin(), e=atoms.end(); i!=e; ++i) { - if (i->GetName()=="OXT") { - edi.DeleteAtom(*i); - oremoved++; - } - } - std::cerr << " --> removed " << oremoved << " OXT atoms" << std::endl; - } - checker.CheckForCompleteness(); checker.CheckForUnknownAtoms(); checker.CheckForNonStandard(); @@ -339,6 +327,7 @@ int main(int argc, char *argv[]) } std::cerr << std::endl; } + if (assign_elem) { ChainHandleList chains=ent.GetChainList(); for (ChainHandleList::const_iterator c=chains.begin();c!=chains.end();++c) {