diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index 1c7d17c98ed50a92261d15ba90175914fd39d1ed..5c18744549199a3094bb4f7d69b6cd7e12369fc4 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -105,6 +105,9 @@ Notes: It is a known limitation of the mmCIF format to allow ambiguous identifiers for waters (and ligands to some extent) and so we have to require these additional identifiers. +* An mmCIF file can contain several models (``atom.site.pdbx_PDB_model_num``). + Only the first model occurring in the mmCIF file is read (regardless of the + actual model number). If extra models are ignored, a warning is logged. Info Classes diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index 66a518def1a71f81b638090da38f3a743584e2ae..ea3be23a85b688a37946a55d298681aa5472979d 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -348,9 +348,10 @@ def LoadCHARMMTraj(crd, dcd_file=None, profile='CHARMM', def LoadMMCIF(filename, fault_tolerant=None, calpha_only=None, profile='DEFAULT', remote=False, seqres=False, info=False): """ - Load a mmCIF file and return one or more entities. Several options allow to - customize the exact behaviour of the mmCIF import. For more information on - these options, see :doc:`profile`. + Load an mmCIF file and return the first model as an entity. + + Several options allow to customize the exact behaviour of the mmCIF import. + For more information on these options, see :doc:`profile`. Residues are flagged as ligand if they are not waters nor covered by an ``entity_poly`` record (ie. they are non-polymer entities in diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index fd440812ea485a3174501f438ff9e82ac4d4ed62..5ebb954dc2dccf1564d044275bfa83212a1e720c 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -478,15 +478,21 @@ void MMCifReader::ParseAndAddAtom(const std::vector<StringRef>& columns) mol::ResNum res_num(0); bool valid_res_num = false; if (indices_[PDBX_PDB_MODEL_NUM] != -1) { + int model_id = TryGetInt(columns[indices_[PDBX_PDB_MODEL_NUM]], + "atom_site.pdbx_PDB_model_num"); if (has_model_) { - if (curr_model_ != TryGetInt(columns[indices_[PDBX_PDB_MODEL_NUM]], - "atom_site.pdbx_PDB_model_num")) { + if (curr_model_ != model_id) { + if (warned_ignored_model_.find(model_id) == warned_ignored_model_.end()) { + LOG_WARNING("Ignorning new model " << model_id << + ". Only model " << curr_model_ << " was read."); + warned_ignored_model_.insert(model_id); + } return; } } else { + LOG_INFO("Reading model " << model_id << "."); has_model_ = true; - curr_model_ = TryGetInt(columns[indices_[PDBX_PDB_MODEL_NUM]], - "atom_site.pdbx_PDB_model_num"); + curr_model_ = model_id; } } diff --git a/modules/io/src/mol/mmcif_reader.hh b/modules/io/src/mol/mmcif_reader.hh index 23cfc2f4bc50c66bc4312680e1fbddeb6d77e879..8521c048d71c94c00d7cd8f63978130073fcd6f0 100644 --- a/modules/io/src/mol/mmcif_reader.hh +++ b/modules/io/src/mol/mmcif_reader.hh @@ -691,6 +691,7 @@ private: String subst_res_id_; ///< work around for missing label_seq_id's bool has_model_; ///< keep track of models through different atom_sites int curr_model_; ///< if we have pdbx_PDB_model_num, store no. + std::set<int> warned_ignored_model_; // keep track of ignored model warnings std::vector<std::pair<mol::ChainHandle, String> > chain_id_pairs_; ///< chain and label_entity_id MMCifEntityDescMap entity_desc_map_; ///< stores entity items