Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore Updating Biotite and other deps. #733

Closed
wants to merge 20 commits into from
24 changes: 24 additions & 0 deletions .github/workflows/local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: test-in-blender

on:
push:
branches: ["main", "20250211-biotite1"]
pull_request:
branches: ["main", "4.2", "4.3", "20250211-biotite1"]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
max-parallel: 4
fail-fast: false
matrix:
version: ["4.3.2", "daily"]
os: [ubuntu-latest, macos-14, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Set up pixi
uses: prefix-dev/[email protected]
- name: Run Tests
run: |
pixi run pytest
44 changes: 23 additions & 21 deletions .github/workflows/test-daily.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
name: Test Daily Build

on:
schedule:
- cron: '0 0 * * *'
push:
branches: ["20250211-biotite1"]
pull_request:
branches: ["20250211-biotite1"]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
max-parallel: 4
fail-fast: false
matrix:
version: ["daily"]
os: [ubuntu-latest, macos-14, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: BradyAJohnston/[email protected]
with:
version: ${{ matrix.version }}
- name: Install in Blender
run: |
blender -b -P tests/python.py -- -m pip install ".[test]"
- name: Run Tests
run: |
blender -b -P tests/run.py -- -vv tests --cov --cov-report=xml
build:
runs-on: ${{ matrix.os }}
strategy:
max-parallel: 4
fail-fast: false
matrix:
version: ["daily"]
os: [ubuntu-latest, macos-14, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: BradyAJohnston/[email protected]
with:
version: ${{ matrix.version }}
- name: Install in Blender
run: |
blender -b -P tests/python.py -- -m pip install ".[test]"
- name: Run Tests
run: |
blender -b -P tests/run.py -- -vv tests --cov --cov-report=xml
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ docs/nodes/*.qmd
/.luarc.json
tests/data/starfile/montage.tiff
tests/data/cellpack/petworld/*.cif

# pixi environments
.pixi
*.egg-info
3 changes: 2 additions & 1 deletion molecularnodes/entities/molecule/oldcif.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def __init__(self, file_path, extra_fields=None, sec_struct=True):
self.n_atoms = self.array.array_length()

def _read(self, file_path):
return pdbx.legacy.PDBxFile.read(file_path)
# return pdbx.legacy.PDBxFile.read(file_path)
return pdbx.CIFFile().read(file_path)

def _get_structure(self, extra_fields: str = None, sec_struct=True, bonds=True):
fields = ["b_factor", "charge", "occupancy", "atom_id"]
Expand Down
3 changes: 1 addition & 2 deletions molecularnodes/entities/molecule/pdbx.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ def _ss_label_to_int(label):
else:
return 3


class CIF(PDBX):
def __init__(self, file_path):
super().__init__(file_path)
Expand Down Expand Up @@ -299,6 +298,7 @@ def list_assemblies(self):
return list(pdbx.list_assemblies(self._file).keys())

def get_transformations(self, assembly_id):

assembly_gen_category = self._file.block["pdbx_struct_assembly_gen"]

struct_oper_category = self._file.block["pdbx_struct_oper_list"]
Expand Down Expand Up @@ -341,7 +341,6 @@ def get_transformations(self, assembly_id):
"pdb_model_num": pdb_model_num,
}
)

return matrices

def get_assemblies(self):
Expand Down
3 changes: 2 additions & 1 deletion molecularnodes/entities/molecule/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

from ...download import FileDownloadPDBError, download, CACHE_DIR
from ...blender import path_resolve
from .oldcif import OldCIF
from .molecule import Molecule
from .oldcif import OldCIF
from .pdb import PDB
from .pdbx import BCIF, CIF
from .sdf import SDF
Expand Down Expand Up @@ -92,6 +92,7 @@ def load_local(
style="spheres",
build_assembly=False,
):
print("loading local")
mol = parse(file_path)
mol.create_object(
name=name,
Expand Down
42 changes: 42 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[workspace]
channels = [
"conda-forge",
"https://prefix.dev/pixi-build-backends",
"https://prefix.dev/conda-forge",
]
platforms = ["osx-arm64", "linux-64", "win-64"]
preview = ["pixi-build"]


[package]
name = "molecularnodes"
version = "0.1.0"

[package.build]
backend = { name = "pixi-build-python", version = "*" }

[package.host-dependencies]
hatchling = "==1.26.3"
python = "==3.11"


[package.run-dependencies]
python = "==3.11"


[tasks]

[dependencies]
python = "==3.11"
ipython = "*"
molecularnodes = { path = "." }

[pypi-dependencies]
bpy = "*"
databpy = "*"
pytest = "*"
syrupy = "*"
MDAnalysis = "*"
biotite = "*"
mrcfile = "*"
starfile = "*"
14 changes: 9 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@ name = "molecularnodes"
version = "4.2.11"
description = "Toolbox for molecular animations with Blender and Geometry Nodes."
readme = "README.md"
dependencies = ["databpy", "MDAnalysis>=2.7.0", "biotite~=0.40", "mrcfile", "starfile"]
maintainers = [
{name = "Brady Johnston", email = "[email protected]"}
]
dependencies = [
"databpy>=0.0.8",
"MDAnalysis>=2.7.0",
"biotite>=1.1",
"mrcfile",
"starfile",
]
maintainers = [{ name = "Brady Johnston", email = "[email protected]" }]

[project.urls]
Homepage = "https://bradyajohnston.github.io/MolecularNodes"
Repository = "https://github.com/bradyajohnston/MolecularNodes"
Documentation = "https://bradyajohnston.github.io/MolecularNodes"

[project.optional-dependencies]
bpy = ["bpy>=4.2"]
bpy = ["bpy>=4.2"]
dev = ["pytest", "pytest-cov", "syrupy", "scipy", "fake-bpy-module"]
test = ["pytest", "pytest-cov", "syrupy", "scipy"]
docs = ["quartodoc", "tomlkit", "nodepad"]
Expand Down
38 changes: 31 additions & 7 deletions tests/test_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
import biotite.structure.io.pdb as biotite_pdb
import biotite.structure.io.pdbx as biotite_cif
import molecularnodes.entities.molecule.pdb as pdb
import molecularnodes.entities.molecule.oldcif as oldcif
import molecularnodes.entities.molecule.pdbx as pdbx


DATA_DIR = join(dirname(realpath(__file__)), "data")

print(DATA_DIR)

@pytest.mark.parametrize(
"pdb_id, format", itertools.product(["1f2n", "5zng"], ["pdb", "cif"])
Expand All @@ -26,22 +27,42 @@ def test_get_transformations(pdb_id, format):
ref_assembly = biotite_pdb.get_assembly(pdb_file, model=1)
test_parser = pdb.PDBAssemblyParser(pdb_file)
elif format == "cif":
cif_file = biotite_cif.PDBxFile.read(path)
cif_file = biotite_cif.CIFFile().read(path)
atoms = biotite_cif.get_structure(
# Make sure `label_asym_id` is used instead of `auth_asym_id`
cif_file,
model=1,
use_author_fields=False,
)
ref_assembly = biotite_cif.get_assembly(cif_file, model=1)
test_parser = oldcif.CIFAssemblyParser(cif_file)
test_parser = pdbx.CIFAssemblyParser(cif_file)

else:
raise ValueError(f"Format '{format}' does not exist")


assembly_id = test_parser.list_assemblies()[0]
test_transformations = test_parser.get_transformations(assembly_id)

check_transformations(test_transformations, atoms, ref_assembly)
if format == "pdb":
# for idx, (chain_list, matrix_list ) in enumerate(test_transformations):
# if idx == 5:
# break
# print(format)
# print(chain_list, matrix_list)
check_transformations(test_transformations, atoms, ref_assembly)
elif format == "cif":

for idx, tdict in enumerate(test_transformations):
if idx == 5:
break
print(format)
print(tdict['chain_ids'], tdict['matrix'])
test_transformations2 = [( transformation['chain_ids'], transformation['matrix']) for transformation in test_transformations]
check_transformations(test_transformations2, atoms, ref_assembly)
else:
raise ValueError(f"Format '{format}' does not exist")



@pytest.mark.parametrize("assembly_id", [str(i + 1) for i in range(5)])
Expand All @@ -53,7 +74,7 @@ def test_get_transformations_cif(assembly_id):
In this case all assemblies from a structure with more complex
operation expressions are tested
"""
cif_file = biotite_cif.PDBxFile.read(join(DATA_DIR, "1f2n.cif"))
cif_file = biotite_cif.CIFFile.read(join(DATA_DIR, "1f2n.cif"))
atoms = biotite_cif.get_structure(
# Make sure `label_asym_id` is used instead of `auth_asym_id`
cif_file,
Expand All @@ -62,10 +83,12 @@ def test_get_transformations_cif(assembly_id):
)
ref_assembly = biotite_cif.get_assembly(cif_file, model=1, assembly_id=assembly_id)

test_parser = oldcif.CIFAssemblyParser(cif_file)
test_parser = pdbx.CIFAssemblyParser(cif_file)

test_transformations = test_parser.get_transformations(assembly_id)

check_transformations(test_transformations, atoms, ref_assembly)
test_transformations2 = [( transformation['chain_ids'], transformation['matrix']) for transformation in test_transformations]
check_transformations(test_transformations2, atoms, ref_assembly)


def check_transformations(transformations, atoms, ref_assembly):
Expand All @@ -75,6 +98,7 @@ def check_transformations(transformations, atoms, ref_assembly):
"""
test_assembly = None
for chain_ids, matrix in transformations:

matrix = np.array(matrix)
translation = matrix[:3, 3]
rotation = matrix[:3, :3]
Expand Down
1 change: 1 addition & 0 deletions tests/test_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def test_rcsb_nmr(snapshot_custom, del_hydrogen):


def test_load_small_mol(snapshot_custom):

mol = mn.entities.load_local(data_dir / "ASN.cif")
for att in ["position", "bond_type"]:
assert snapshot_custom == mol.named_attribute(att).tolist()
Expand Down
Loading