diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py index b88f983bef4c94aeaae19b6c777bd9c3b9cc41a6..8af2ab6cc20f088401c9e80038d8bc98e31f8561 100644 --- a/modules/base/pymod/table.py +++ b/modules/base/pymod/table.py @@ -1142,7 +1142,8 @@ class Table(object): def PlotHistogram(self, col, x_range=None, num_bins=10, normed=False, histtype='stepfilled', align='mid', x_title=None, - y_title=None, title=None, clear=True, save=False): + y_title=None, title=None, clear=True, save=False, + color=None, y_range=None): """ Create a histogram of the data in col for the range *x_range*, split into *num_bins* bins and plot it using Matplotlib. @@ -1153,9 +1154,16 @@ class Table(object): :param x_range: start and end value for first dimension (e.g. [start_x, end_x]) :type x_range: :class:`list` of length two + :param y_range: start and end value for second dimension (e.g. [start_y, end_y]) + :type y_range: :class:`list` of length two + :param num_bins: number of bins in range :type num_bins: :class:`int` + :param color: Color to be used for the histogram. If not set, color will be + determined by matplotlib + :type color: :class:`str` + :param normed: normalize histogram :type normed: :class:`bool` @@ -1202,7 +1210,9 @@ class Table(object): if len(self.rows)==0: return None - + kwargs={} + if color: + kwargs['color']=color idx = self.GetColIndex(col) data = [] for r in self.rows: @@ -1213,21 +1223,23 @@ class Table(object): plt.clf() n, bins, patches = plt.hist(data, bins=num_bins, range=x_range, - normed=normed, histtype=histtype, align=align) + normed=normed, histtype=histtype, align=align, + **kwargs) - if x_title: + if x_title!=None: nice_x=x_title else: nice_x=MakeTitle(col) plt.xlabel(nice_x, size='x-large') - - if y_title: + if y_range: + plt.ylim(y_range) + if y_title!=None: nice_y=y_title else: nice_y="bin count" plt.ylabel(nice_y, size='x-large') - if title: + if title!=None: nice_title=title else: nice_title="Histogram of %s"%nice_x diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index dbf9ce5bbc39da3573fb4482258c349d3ab6b5e9..18728c2cf3feee60f5727efffd5a61c098f4151b 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -107,6 +107,8 @@ void export_Scene() .def("Autoslab", autoslab3) // DEPRECATED .def("AutoslabMax",&Scene::AutoslabMax) // DEPRECATED .def("Remove", remove1) + .def("Register", &Scene::Register) + .def("Unregister", &Scene::Unregister) .def("Remove", remove2) .add_property("viewport", &Scene::GetViewport) .def("RequestRedraw", &Scene::RequestRedraw) diff --git a/modules/gui/pymod/CMakeLists.txt b/modules/gui/pymod/CMakeLists.txt index 122745ba46772dc3fd9679db6d6ac4f4fbd528fe..4ac7f7cfe75a5fe6a0e843a4389e64e02e8228ed 100644 --- a/modules/gui/pymod/CMakeLists.txt +++ b/modules/gui/pymod/CMakeLists.txt @@ -85,6 +85,7 @@ set(OST_GUI_PYMOD_MODULES init_splash.py traj.py helpwidget.py + table.py ) set(OST_GUI_PYMOD_DNG_MODULES diff --git a/modules/gui/pymod/init_spacenav.py b/modules/gui/pymod/init_spacenav.py index 847ec5d4b983057a715c85882924daabb87cc6cb..c05a59a2dbee5d372870ec12db1090bb485c5e46 100644 --- a/modules/gui/pymod/init_spacenav.py +++ b/modules/gui/pymod/init_spacenav.py @@ -23,7 +23,9 @@ class SpacenavControl(QtCore.QObject): if r==0.0: return 0.0 rr=r/abs(r)*max(0.0,abs(r)-0.9) - return rr/abs(rr)*(math.pow(1.01,abs(rr))-1.0)*40.0/self.speed if abs(rr)>0.0 else 0.0 + if abs(rr)>0: + return rr/abs(rr)*(math.pow(1.01,abs(rr))-1.0)*40.0/self.speed + return 0.0 if(self.trans): tf.ApplyXAxisTranslation(d(tx)) tf.ApplyYAxisTranslation(d(ty)) diff --git a/modules/gui/pymod/table.py b/modules/gui/pymod/table.py new file mode 100644 index 0000000000000000000000000000000000000000..fd65e9ff69ad2a9f496894c3e30b58ad5f18e52e --- /dev/null +++ b/modules/gui/pymod/table.py @@ -0,0 +1,49 @@ +from PyQt4.QtGui import * +from PyQt4.QtCore import * + + +__all__=('Table', ) + +class TableModel(QAbstractTableModel): + def __init__(self, table, parent=None): + QAbstractTableModel.__init__(self, parent) + self.table=table + + def rowCount(self, index): + return len(self.table.rows) + + def headerData(self, section, orientation, role): + if role!=Qt.DisplayRole or orientation!=Qt.Horizontal: + return QVariant() + return self.table.col_names[section] + + def columnCount(self, index): + return len(self.table.col_names) + + def sort(self, column, order): + o='+' + if order!=Qt.AscendingOrder: + o='-' + self.table.Sort(by=self.table.col_names[column], order=o) + self.reset() + + def data(self, index, role): + if not index.isValid() or role!=Qt.DisplayRole: + return QVariant() + row=self.table.rows[index.row()] + return QVariant(row[index.column()]) + +class Table(QTableView): + def __init__(self, table): + QTableView.__init__(self) + self._model=TableModel(table) + self.setFrameShape(QFrame.NoFrame) + self.setAttribute(Qt.WA_MacSmallSize) + self.setShowGrid(False) + #self.horizontalHeader().setStretchLastSection(True) + self.setContextMenuPolicy(Qt.CustomContextMenu) + self.setSelectionBehavior(QAbstractItemView.SelectRows) + self.setSizePolicy(QSizePolicy.MinimumExpanding, + QSizePolicy.MinimumExpanding) + self.setSortingEnabled(True) + self.setModel(self._model) \ No newline at end of file diff --git a/modules/gui/src/python_shell/python_shell_widget.cc b/modules/gui/src/python_shell/python_shell_widget.cc index e1891ae2c6e8f9148b363747eac05784e4be605c..8b0fd88d3456405632b9068fb98fed33359e5aea 100644 --- a/modules/gui/src/python_shell/python_shell_widget.cc +++ b/modules/gui/src/python_shell/python_shell_widget.cc @@ -332,6 +332,13 @@ void PythonShellWidget::setup_state_machine_() single_line->addTransition(clear_all_tr_sl); connect(clear_all_tr_sl,SIGNAL(triggered()),this,SLOT(handle_clear_all_())); + single_line->addTransition(new KeyEventTransition(Qt::Key_Left, + DNG_ARROW_MODIFIERS, + single_line, + true, + new EditPositionGuard(this,EditPositionGuard::EQUAL, + EditPositionGuard::ANCHOREQUAL |EditPositionGuard::ANCHORBIGGER))); + //multi line inactive transitions multi_line_inactive->addTransition(new KeyEventTransition(Qt::Key_Return, Qt::NoModifier, @@ -878,6 +885,7 @@ void PythonShellWidget::insertFromMimeData(const QMimeData * source) if(lines.size()>0){ set_block_type_(block_edit_start_,document()->lastBlock(),BLOCKTYPE_BLOCKEDIT); } + setFocus(); } GutterBlockList PythonShellWidget::GetGutterBlocks(const QRect& rect) diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.cc b/modules/gui/src/sequence_viewer/sequence_viewer.cc index 024355c1b5325b87f60b67b462c55a4abef73b75..a34e917b6c20e86e2ba752c08d3b5e2ced3a2c29 100644 --- a/modules/gui/src/sequence_viewer/sequence_viewer.cc +++ b/modules/gui/src/sequence_viewer/sequence_viewer.cc @@ -96,6 +96,7 @@ SequenceViewer::SequenceViewer(bool stand_alone, bool observe_scene, layout->setSpacing(0); this->setLayout(layout); + toolbar_ = new QToolBar(this); this->InitActions(); @@ -120,7 +121,6 @@ SequenceViewer::SequenceViewer(bool stand_alone, bool observe_scene, void SequenceViewer::InitMenuBar() { - toolbar_ = new QToolBar(this); toolbar_->setToolButtonStyle(Qt::ToolButtonIconOnly); toolbar_->setIconSize(QSize(16,16)); toolbar_->addActions(action_list_); @@ -164,7 +164,7 @@ void SequenceViewer::InitActions() icon_path.cd("gui"); icon_path.cd("icons"); - QAction* find_action = new QAction(this); + QAction* find_action = new QAction(toolbar_); find_action->setText("Find Dialog"); find_action->setShortcut(QKeySequence(tr("Ctrl+F"))); find_action->setCheckable(true); @@ -173,8 +173,8 @@ void SequenceViewer::InitActions() action_list_.append(find_action); connect(find_action, SIGNAL(triggered(bool)), this, SLOT(FindInSequence())); - display_mode_actions_ = new QActionGroup(this); - QAction* menu_action = new QAction(this); + display_mode_actions_ = new QActionGroup(toolbar_); + QAction* menu_action = new QAction(toolbar_); menu_action->setText("Menubar"); menu_action->setShortcut(QKeySequence(tr("Ctrl+M"))); menu_action->setToolTip("Display Options (Ctrl+M)"); diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index 758862eeb797c966b2336edd499ba00a930b065a..da1bed9d710d3ec33a4c7dfc16cbc02f6812348e 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -179,6 +179,23 @@ of the annotation available. :type cif_chain_id: :class:`str` :returns: atom_site.auth_asym_id as :class:`str` + .. method:: AddPDBCMMCifhainTr(pdb_chain_id, cif_chain_id) + + Set up a translation for a certain PDB chain name to the mmCIF chain name. + + :param pdb_chain_id: atom_site.label_asym_id + :type pdb_chain_id: :class:`str` + :param cif_chain_id: atom_site.auth_asym_id + :type cif_chain_id: :class:`str` + + .. method:: GetPDBMMCifChainTr(pdb_chain_id) + + Get the translation of a certain PDB chain name to the mmCIF chain name. + + :param pdb_chain_id: atom_site.auth_asym_id + :type pdb_chain_id: :class:`str` + :returns: atom_site.label_asym_id as :class:`str` + .. class:: MMCifInfoCitation This stores citation information from an input file. @@ -813,4 +830,4 @@ of the annotation available. .. LocalWords: cas isbn pubmed asu seqres conop ConnectAll casp COMPND OBSLTE .. LocalWords: SPRSDE pdb func autofunction exptl attr pdbx oper conf spr dif .. LocalWords: biounits biounit uniprot UNP seqs AddMMCifPDBChainTr cif asym -.. LocalWords: auth GetMMCifPDBChainTr +.. LocalWords: auth GetMMCifPDBChainTr AddPDBCMMCifhainTr GetPDBMMCifChainTr diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc index f94c257e647a6499992dea5172169a029ddd8d85..f2527066afca1d2d715c97dcc1413276eafa7a6b 100644 --- a/modules/io/pymod/export_mmcif_io.cc +++ b/modules/io/pymod/export_mmcif_io.cc @@ -282,6 +282,8 @@ void export_mmcif_io() .def("GetObsoleteInfo", &MMCifInfo::GetObsoleteInfo) .def("AddMMCifPDBChainTr", &MMCifInfo::AddMMCifPDBChainTr) .def("GetMMCifPDBChainTr", &MMCifInfo::GetMMCifPDBChainTr) + .def("AddPDBMMCifChainTr", &MMCifInfo::AddPDBMMCifChainTr) + .def("GetPDBMMCifChainTr", &MMCifInfo::GetPDBMMCifChainTr) .add_property("citations", make_function(&MMCifInfo::GetCitations, return_value_policy<copy_const_reference>())) .add_property("biounits", make_function(&MMCifInfo::GetBioUnits, diff --git a/modules/io/src/mol/mmcif_info.cc b/modules/io/src/mol/mmcif_info.cc index 140676fe6c409c03e2da8a427c2a502da2a936c3..29f0db7463188068b3584a49457126d7ec1601d0 100644 --- a/modules/io/src/mol/mmcif_info.cc +++ b/modules/io/src/mol/mmcif_info.cc @@ -40,6 +40,24 @@ String MMCifInfo::GetMMCifPDBChainTr(String cif) const return tr_it->second; } +void MMCifInfo::AddPDBMMCifChainTr(String pdb, String cif) +{ + std::map<String, String>::iterator tr_it = pdb_2_cif_chain_id_.find(pdb); + if (tr_it != pdb_2_cif_chain_id_.end()) { + throw IOException("PDB chain id '"+ pdb +"' is already mapped to '"+ + tr_it->second+"'."); + } + pdb_2_cif_chain_id_.insert(std::pair<String, String>(pdb, cif)); +} + +String MMCifInfo::GetPDBMMCifChainTr(String pdb) const +{ + std::map<String, String>::const_iterator tr_it = + pdb_2_cif_chain_id_.find(pdb); + if (tr_it == pdb_2_cif_chain_id_.end()) { return ""; } + return tr_it->second; +} + void MMCifInfo::AddAuthorsToCitation(StringRef id, std::vector<String> list) { // find citation diff --git a/modules/io/src/mol/mmcif_info.hh b/modules/io/src/mol/mmcif_info.hh index 68aa79befa08c11015178075d7daceea3d86c051..3eebf54b2369947c9d007e616c4d33c2f968750c 100644 --- a/modules/io/src/mol/mmcif_info.hh +++ b/modules/io/src/mol/mmcif_info.hh @@ -22,6 +22,7 @@ #include <vector> #include <map> #include <boost/shared_ptr.hpp> +#include <ost/seq/sequence_list.hh> #include <ost/geom/geom.hh> #include <ost/string_ref.hh> #include <ost/io/module_config.hh> @@ -783,6 +784,18 @@ public: /// \return chain name as used in the PDB file (auth_asym_id) String GetMMCifPDBChainTr(String cif) const; + /// \brief Add a new PDB/ mmCIF chain name tuple. + /// + /// \param pdb chain name as used by the PDB file (auth_asym_id) + /// \param cif chain name as used in the mmCIF file (label_asym_id) + void AddPDBMMCifChainTr(String pdb, String cif); + + /// \brief Get a CIF chain name for a PDB chain name + /// + /// \param pdb chain name as used by the mmCIF file (auth_asym_id) + /// \return chain name as used in the PDB file (label_asym_id) + String GetPDBMMCifChainTr(String pdb) const; + /// \brief Add a biounit /// /// \param bu biounit to be added @@ -861,6 +874,7 @@ private: std::vector<MMCifInfoTransOpPtr> transops_; MMCifInfoStructRefs struct_refs_; std::map<String, String> cif_2_pdb_chain_id_; + std::map<String, String> pdb_2_cif_chain_id_; }; diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index 6f35d4a2f206286578d20339fff710a1d0d1a2eb..762939ca817800366ee487ffadef9da493f5103a 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -500,8 +500,6 @@ void MMCifReader::ParseAndAddAtom(const std::vector<StringRef>& columns) // store entity id chain_id_pairs_.push_back(std::pair<mol::ChainHandle,String>(curr_chain_, columns[indices_[LABEL_ENTITY_ID]].str())); - // store mmCIF - PDB chain name mapping - info_.AddMMCifPDBChainTr(cif_chain_name, auth_chain_name); } assert(curr_chain_.IsValid()); } else if (chain_id_pairs_.back().second != // unit test @@ -1541,6 +1539,7 @@ void MMCifReader::OnEndData() // process chain types std::vector<std::pair<mol::ChainHandle, String> >::const_iterator css; MMCifEntityDescMap::const_iterator edm_it; + String pdb_auth_chain_name; for (css = chain_id_pairs_.begin(); css != chain_id_pairs_.end(); ++css) { edm_it = entity_desc_map_.find(css->second); @@ -1550,6 +1549,9 @@ void MMCifReader::OnEndData() if (edm_it->second.seqres.length() > 0) { seqres_.AddSequence(seq::CreateSequence(css->first.GetName(), edm_it->second.seqres)); + pdb_auth_chain_name = css->first.GetStringProp("pdb_auth_chain_name"); + info_.AddMMCifPDBChainTr(css->first.GetName(), pdb_auth_chain_name); + info_.AddPDBMMCifChainTr(pdb_auth_chain_name, css->first.GetName()); } else if (edm_it->second.type!=mol::CHAINTYPE_WATER) { // mark everything that doesn't have SEQRES as ligand and isn't of type // water as ligand diff --git a/modules/io/tests/test_mmcif_info.cc b/modules/io/tests/test_mmcif_info.cc index d5a1ac1a465edbbe121d173b4167244adf804b27..65e4fdaecb42ec54fb50d3c579f24ba8b7ae8adb 100644 --- a/modules/io/tests/test_mmcif_info.cc +++ b/modules/io/tests/test_mmcif_info.cc @@ -208,6 +208,11 @@ BOOST_AUTO_TEST_CASE(mmcif_info) BOOST_CHECK("B" == info.GetMMCifPDBChainTr("A")); BOOST_CHECK("" == info.GetMMCifPDBChainTr("C")); + info.AddPDBMMCifChainTr("A", "B"); + BOOST_CHECK_THROW(info.AddPDBMMCifChainTr("A", "B"), IOException); + BOOST_CHECK("B" == info.GetPDBMMCifChainTr("A")); + BOOST_CHECK("" == info.GetPDBMMCifChainTr("C")); + BOOST_MESSAGE(" done."); } diff --git a/modules/io/tests/testfiles/mmcif/atom_site.mmcif b/modules/io/tests/testfiles/mmcif/atom_site.mmcif index ce890cf9d3be305019cbc431726433df8a06beee..68b2fbb5769c6e735ec7e30cb7311f002f9b3346 100644 --- a/modules/io/tests/testfiles/mmcif/atom_site.mmcif +++ b/modules/io/tests/testfiles/mmcif/atom_site.mmcif @@ -168,10 +168,10 @@ ATOM C CB ILE A 13 . 1 21.236 34.463 16.492 1.00 22.67 . 13 21 ? A ATOM C CG1 ILE A 13 . 1 20.478 33.469 17.371 1.00 22.14 . 13 22 ? A ATOM C CG2 ILE A 13 . 1 21.357 33.986 15.016 1.00 21.75 . 13 23 ? A # - - - - data truncated for brevity - - - - -HETATM C C1 APS C 1 1 1 4.171 29.012 7.116 0.58 17.27 1 300 101 ? A -HETATM C C2 APS C 1 1 1 4.949 27.758 6.793 0.58 16.95 1 300 102 ? A -HETATM O O3 APS C 1 1 1 4.800 26.678 7.393 0.58 16.85 1 300 103 ? A -HETATM N N4 APS C 1 1 1 5.930 27.841 5.869 0.58 16.43 1 300 104 ? A +HETATM C C1 APS C 1 1 1 4.171 29.012 7.116 0.58 17.27 1 300 101 ? C +HETATM C C2 APS C 1 1 1 4.949 27.758 6.793 0.58 16.95 1 300 102 ? C +HETATM O O3 APS C 1 1 1 4.800 26.678 7.393 0.58 16.85 1 300 103 ? C +HETATM N N4 APS C 1 1 1 5.930 27.841 5.869 0.58 16.43 1 300 104 ? C # - - - - data truncated for brevity - - - - # chain to be ignored by 'restrict_chains' feature ATOM N N ILE Z 1 . 1 23.664 33.855 16.884 1.00 22.08 . 1 17 ? Z