Skip to content

Commit

Permalink
propagate allow_missing_coord and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
davegrays committed Jan 6, 2025
1 parent 1b110f4 commit c519913
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 13 deletions.
13 changes: 11 additions & 2 deletions src/biotite/structure/info/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# fmt: on


def residue(res_name):
def residue(res_name, allow_missing_coord=False):
"""
Get an atom array, representing the residue with the given name.
Expand All @@ -30,6 +30,11 @@ def residue(res_name):
----------
res_name : str
The up to 3-letter name of the residue.
allow_missing_coord: bool, optional
Whether to allow missing coordinate values in the residue.
If ``True``, these will be represented as ``nan`` values.
If ``False``, a ``ValueError`` is raised when missing coordinates
are encountered.
Returns
-------
Expand Down Expand Up @@ -74,7 +79,11 @@ def residue(res_name):
from biotite.structure.io.pdbx import get_component

try:
component = get_component(get_ccd(), res_name=res_name)
component = get_component(
get_ccd(),
res_name=res_name,
allow_missing_coord=allow_missing_coord,
)
except KeyError:
raise KeyError(f"No atom information found for residue '{res_name}' in CCD")
component.hetero[:] = res_name not in NON_HETERO_RESIDUES
Expand Down
22 changes: 11 additions & 11 deletions src/biotite/structure/io/pdbx/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,7 @@ def get_component(
data_block=None,
use_ideal_coord=True,
res_name=None,
allow_missing_coords=False,
allow_missing_coord=False,
):
"""
Create an :class:`AtomArray` for a chemical component from the
Expand Down Expand Up @@ -1215,10 +1215,10 @@ def get_component(
In this case, the component with the given residue name is
read.
By default, all rows would be read in this case.
allow_missing_coords: bool
allow_missing_coord: bool, optional
Whether to allow missing coordinate values in components.
If `True`, these will be represented as `nan` values.
If `False`, a `ValueError` is raised when missing coordinates
If ``True``, these will be represented as ``nan`` values.
If ``False``, a ``ValueError`` is raised when missing coordinates
are encountered.
Returns
Expand Down Expand Up @@ -1311,7 +1311,7 @@ def get_component(
raise
array.coord = _parse_component_coordinates(
[atom_category[field] for field in alt_coord_fields],
keep_missing=allow_missing_coords,
allow_missing=allow_missing_coord,
)

try:
Expand Down Expand Up @@ -1342,19 +1342,19 @@ def get_component(
return array


def _parse_component_coordinates(coord_columns, keep_missing=False):
def _parse_component_coordinates(coord_columns, allow_missing=False):
coord = np.zeros((len(coord_columns[0]), 3), dtype=np.float32)
for i, column in enumerate(coord_columns):
if column.mask is not None and column.mask.array.any():
if not keep_missing:
raise ValueError(
"Missing coordinates for some atoms",
)
else:
if allow_missing:
warnings.warn(
"Missing coordinates for some atoms. Those will be set to nan",
UserWarning,
)
else:
raise ValueError(
"Missing coordinates for some atoms",
)
coord[:, i] = column.as_array(np.float32, masked_value=np.nan)
return coord

Expand Down
30 changes: 30 additions & 0 deletions tests/structure/test_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,33 @@ def test_set_ccd_path(fake_ccd_path):

# The new fake CCD has only a single compound
assert strucinfo.all_residues() == ["FOO"]


@pytest.mark.parametrize(
"res_name, allow_missing_coord, should_raise",
[
("ALA", False, False),
("ALA", True, False),
("A1IQW", True, False),
("A1IQW", False, True),
("RRE", True, False),
("RRE", False, True),
],
)
def test_residue(res_name, allow_missing_coord, should_raise):
"""
Test if the residue function returns an atom array or not.
ALA --> standard amino acid, yes in both conditions
A1IQW --> yes only with allow_missing_coord=True
RRE --> yes only with allow_missing_coord=True
Make sure correct exceptions are raised when the non-standard residue
is used with allow_missing_coord=False.
"""
if should_raise:
with pytest.raises(ValueError):
strucinfo.residue(res_name, allow_missing_coord=allow_missing_coord)
else:
result = strucinfo.residue(res_name, allow_missing_coord=allow_missing_coord)
assert isinstance(result, struc.AtomArray)
assert result.array_length() > 0
assert np.all(result.res_name == res_name)

0 comments on commit c519913

Please sign in to comment.