Skip to content

Commit eb8382f

Browse files
authored
Merge pull request #16 from JHKru/master
Separate for test data generation for compatibility with Biotite >= 1.0 and Numpy >= 2.0; Ruff formatting
2 parents 914b997 + 1335b52 commit eb8382f

File tree

121 files changed

+15230
-13030
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+15230
-13030
lines changed

.github/workflows/test.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ name: Testing Springcraft
33
on: [push, pull_request]
44

55
jobs:
6+
lint:
7+
name: Check code style
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: actions/setup-python@v5
12+
with:
13+
python-version: "3.12"
14+
- name: Install ruff
15+
run: pip install ruff==0.5.2
16+
- name: Check code formatting
17+
run: ruff format --diff
18+
- name: Lint code base
19+
run: ruff check
620
test:
721
name: Testing
822

@@ -19,7 +33,7 @@ jobs:
1933
auto-update-conda: true
2034
python-version: '3.10'
2135
- name: Installing dependencies
22-
run: conda install -c conda-forge poetry prody pytest r-bio3d rpy2
36+
run: conda install -c conda-forge poetry pytest
2337
- name: Building distribution
2438
run: poetry build -f wheel
2539
- name: Installing distribution

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ via *pip*:
4141
$ git clone https://github.com/biotite-dev/springcraft.git
4242
$ pip install ./springcraft
4343
44+
A development conda environment with all required dependencies for testing
45+
can be installed from `environment.yml`
46+
47+
Scripts to generate reference files for tests are stored in tests/data;
48+
a separate environment to rerun these locally can be found in `test_create_data_env.yml`.
49+
BioPhysConnectoR has to be installed separately.
50+
4451
Example
4552
=======
4653

doc/conf.py

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,34 @@
44

55
__author__ = "Patrick Kunzmann"
66

7-
from os.path import realpath, dirname, join
8-
import types
97
import sys
8+
import types
9+
from os.path import dirname, join, realpath
10+
11+
import scraper
12+
import springcraft
1013

1114
# Include 'src/' in PYTHONPATH
1215
# in order to import the 'Ammolite' package
1316
doc_path = dirname(realpath(__file__))
1417
package_path = join(dirname(doc_path), "src")
1518
sys.path.insert(0, package_path)
16-
import springcraft
1719

1820
# Include springcraft/doc in PYTHONPATH
1921
# in order to import modules for example generation etc.
2022
sys.path.insert(0, doc_path)
21-
import scraper
22-
2323

2424
#### General ####
2525

26-
extensions = ["sphinx.ext.autodoc",
27-
"sphinx.ext.autosummary",
28-
"sphinx.ext.doctest",
29-
"sphinx.ext.mathjax",
30-
"sphinx.ext.viewcode",
31-
"sphinx_gallery.gen_gallery",
32-
"numpydoc"]
26+
extensions = [
27+
"sphinx.ext.autodoc",
28+
"sphinx.ext.autosummary",
29+
"sphinx.ext.doctest",
30+
"sphinx.ext.mathjax",
31+
"sphinx.ext.viewcode",
32+
"sphinx_gallery.gen_gallery",
33+
"numpydoc",
34+
]
3335

3436
templates_path = ["templates"]
3537
source_suffix = [".rst"]
@@ -42,9 +44,7 @@
4244
exclude_patterns = ["build"]
4345

4446
numpydoc_show_class_members = False
45-
autodoc_default_options = {
46-
"show-inheritance": True
47-
}
47+
autodoc_default_options = {"show-inheritance": True}
4848

4949
pygments_style = "sphinx"
5050

@@ -68,41 +68,47 @@
6868
html_favicon = "static/assets/springcraft_logo_32p.png"
6969
htmlhelp_basename = "SpringcraftDoc"
7070
html_theme_options = {
71-
"description" : "Investigate molecular dynamics by elastic network models",
72-
"logo" : "assets/springcraft_logo.svg",
73-
"logo_name" : "true",
74-
"github_user" : "biotite-dev",
75-
"github_repo" : "springcraft",
76-
"github_banner" : "true",
77-
"github_type" : "star",
78-
"fixed_sidebar" : "true",
79-
"page_width" : "1200px",
71+
"description": "Investigate molecular dynamics by elastic network models",
72+
"logo": "assets/springcraft_logo.svg",
73+
"logo_name": "true",
74+
"github_user": "biotite-dev",
75+
"github_repo": "springcraft",
76+
"github_banner": "true",
77+
"github_type": "star",
78+
"fixed_sidebar": "true",
79+
"page_width": "1200px",
8080
}
8181
sphinx_gallery_conf = {
82-
"examples_dirs" : "examples/scripts",
83-
"gallery_dirs" : "examples/gallery",
84-
'filename_pattern' : "",
85-
"download_all_examples" : False,
82+
"examples_dirs": "examples/scripts",
83+
"gallery_dirs": "examples/gallery",
84+
"filename_pattern": "",
85+
"download_all_examples": False,
8686
# Never report run time
87-
"min_reported_time" : sys.maxsize,
88-
"image_scrapers" : ("matplotlib", scraper.pymol_scraper,),
87+
"min_reported_time": sys.maxsize,
88+
"image_scrapers": (
89+
"matplotlib",
90+
scraper.pymol_scraper,
91+
),
8992
# Replace 'ammolite.show()'
90-
"reset_modules" : (scraper.overwrite_display_func,),
93+
"reset_modules": (scraper.overwrite_display_func,),
9194
# Do not capture file path string output
9295
# by the overwritten 'ammolite.show()'
93-
"capture_repr" : (),
96+
"capture_repr": (),
9497
}
9598

9699

97100
#### App setup ####
98101

102+
99103
def skip_non_methods(app, what, name, obj, skip, options):
100104
if skip:
101105
return True
102106
if what == "class":
103107
# Functions
104108
if type(obj) in [
105-
types.FunctionType, types.BuiltinFunctionType, types.MethodType
109+
types.FunctionType,
110+
types.BuiltinFunctionType,
111+
types.MethodType,
106112
]:
107113
return False
108114
return True

doc/examples/scripts/basic_nma.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
"""
22
Basic NMA of a Protein-ENM
33
==========================
4-
In this example script, a basic normal mode analysis (NMA) of a protein
4+
In this example script, a basic normal mode analysis (NMA) of a protein
55
coarse-grained elastic network model (ENM) is conducted.
66
"""
77

88

99
# Code source: Jan Krumbach
1010
# License: BSD 3 clause
1111

12-
import numpy as np
13-
import matplotlib.pyplot as plt
1412
import biotite
13+
import biotite.database.rcsb as rcsb
1514
import biotite.structure as struc
1615
import biotite.structure.io.mmtf as mmtf
17-
import biotite.database.rcsb as rcsb
16+
import matplotlib.pyplot as plt
17+
import numpy as np
1818
import springcraft
1919

20-
2120
# Fetch G:T/U Mismatch-specific DNA glycosylase from E. coli
2221
PDB_ID = "1MUG"
2322
mmtf_file = mmtf.MMTFFile.read(rcsb.fetch(PDB_ID, "mmtf"))
@@ -30,7 +29,7 @@
3029
eanm = springcraft.ANM(ca, ff)
3130

3231
## NMA
33-
# Compute eigenvalues and eigenvectors.
32+
# Compute eigenvalues and eigenvectors.
3433
# The first 6 eigenvals./eigenvecs corresponding to trivial modes are omitted.
3534
# -> analyse modes 7-107
3635
eigenval, eigenvec = eanm.eigen()
@@ -49,9 +48,9 @@
4948

5049
biotite_c = biotite.colors["orange"]
5150

52-
ax00.bar(x=np.arange(7, len(eigenval)+7), height=eigenval, color=biotite_c)
53-
ax01.bar(x=np.arange(7, len(freq)+7), height=freq, color=biotite_c)
54-
ax1.bar(x=np.arange(1, len(msqf)+1), height=msqf, color=biotite_c)
51+
ax00.bar(x=np.arange(7, len(eigenval) + 7), height=eigenval, color=biotite_c)
52+
ax01.bar(x=np.arange(7, len(freq) + 7), height=freq, color=biotite_c)
53+
ax1.bar(x=np.arange(1, len(msqf) + 1), height=msqf, color=biotite_c)
5554

5655
ax00.set_xlabel("Mode", size=16)
5756
ax00.set_ylabel(r"Eigenvalue $\lambda$", size=16)

doc/examples/scripts/normal_mode.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99
# Code source: Patrick Kunzmann
1010
# License: BSD 3 clause
1111

12-
import numpy as np
12+
import ammolite
13+
import biotite.database.rcsb as rcsb
1314
import biotite.structure as struc
1415
import biotite.structure.io.mmtf as mmtf
15-
import biotite.database.rcsb as rcsb
16-
import ammolite
16+
import numpy as np
1717
import springcraft
1818

19-
2019
PNG_SIZE = (800, 800)
2120

2221

@@ -37,8 +36,7 @@
3736

3837
# Filter first peptide chain
3938
protein_chain = structure[
40-
struc.filter_amino_acids(structure)
41-
& (structure.chain_id == structure.chain_id[0])
39+
struc.filter_amino_acids(structure) & (structure.chain_id == structure.chain_id[0])
4240
]
4341
# Filter CA atoms
4442
ca_mask = (protein_chain.atom_name == "CA") & (protein_chain.element == "C")
@@ -57,15 +55,28 @@
5755
pymol_object.show_as("cartoon")
5856
# Show eigenvectors as arrows
5957
ammolite.draw_arrows(
60-
ca.coord, ca.coord + vector,
61-
radius=0.2, head_radius=0.4, head_length=1.0
58+
ca.coord, ca.coord + vector, radius=0.2, head_radius=0.4, head_length=1.0
59+
)
60+
ammolite.cmd.set_view(
61+
(
62+
0.605540633,
63+
0.363677770,
64+
-0.707855821,
65+
-0.416691631,
66+
0.902691007,
67+
0.107316799,
68+
0.678002179,
69+
0.229972601,
70+
0.698157668,
71+
0.000000000,
72+
0.000000000,
73+
-115.912551880,
74+
32.098876953,
75+
31.005725861,
76+
78.377349854,
77+
89.280677795,
78+
142.544403076,
79+
-20.000000000,
80+
)
6281
)
63-
ammolite.cmd.set_view((
64-
0.605540633, 0.363677770, -0.707855821,
65-
-0.416691631, 0.902691007, 0.107316799,
66-
0.678002179, 0.229972601, 0.698157668,
67-
0.000000000, 0.000000000, -115.912551880,
68-
32.098876953, 31.005725861, 78.377349854,
69-
89.280677795, 142.544403076, -20.000000000
70-
))
71-
ammolite.show(PNG_SIZE)
82+
ammolite.show(PNG_SIZE)

doc/scraper.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
from glob import glob
1+
import datetime
22
import shutil
33
import tempfile
4-
import datetime
4+
import time
55
from os.path import getsize
6+
67
from sphinx_gallery.scrapers import figure_rst
78

89
NO_ASSIGN = "___"
910

1011

1112
def pymol_scraper(block, block_vars, gallery_conf):
12-
block_type,_, _ = block
13+
block_type, _, _ = block
1314
if block_type == "code":
1415
globals = block_vars["example_globals"]
1516
# Look for replaced show() output:
@@ -20,54 +21,54 @@ def pymol_scraper(block, block_vars, gallery_conf):
2021
image_path = globals[NO_ASSIGN]
2122
# Copy the images into the 'gallery' directory under a canonical
2223
# sphinx-gallery name
23-
image_path_iterator = block_vars['image_path_iterator']
24+
image_path_iterator = block_vars["image_path_iterator"]
2425
image_destination = image_path_iterator.next()
2526
shutil.copy(image_path, image_destination)
26-
return figure_rst([image_destination], gallery_conf['src_dir'])
27-
return figure_rst([], gallery_conf['src_dir'])
27+
return figure_rst([image_destination], gallery_conf["src_dir"])
28+
return figure_rst([], gallery_conf["src_dir"])
2829

2930

3031
def overwrite_display_func(gallery_conf, fname):
3132
import ammolite
3233

3334
def show(size=None, use_ray=False, timeout=60.0, pymol_instance=None):
3435
INTERVAL = 0.1
35-
36+
3637
if size is None:
3738
width = 0
3839
height = 0
3940
else:
4041
width, height = size
41-
42+
4243
if use_ray:
4344
ray = 1
4445
else:
4546
ray = 0
46-
47+
4748
image_file = tempfile.NamedTemporaryFile(
4849
delete=False, prefix="ammolite_", suffix=".png"
4950
)
5051
image_file.close()
51-
52+
5253
start_time = datetime.datetime.now()
5354

5455
ammolite.cmd.png(image_file.name, width, height, ray=ray)
55-
56+
5657
while True:
5758
# After 'timeout' seconds the loop exits with an error
5859
if (datetime.datetime.now() - start_time).total_seconds() > timeout:
5960
raise TimeoutError(
6061
"No PNG image was output within the expected time limit"
6162
)
62-
63+
6364
# Check if PyMOL has already written image data to file
6465
if getsize(image_file.name) > 0:
6566
break
6667

6768
time.sleep(INTERVAL)
68-
69+
6970
return image_file.name
7071

7172
ammolite.show = show
7273
ammolite.cmd.reinitialize()
73-
ammolite.setup_parameters(ammolite.pymol)
74+
ammolite.setup_parameters(ammolite.pymol)

environment.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ channels:
77
- conda-forge
88

99
dependencies:
10-
- numpy >=1.15
11-
- biotite >=0.32
12-
- prody >=2.1
10+
- numpy >=2.0
11+
- biotite >=1.0.1
1312
- pytest >=5.2
1413
- matplotlib >=3.3
1514
- poetry >=1.0
@@ -18,5 +17,4 @@ dependencies:
1817
- sphinx-gallery =0.9.0
1918
- numpydoc >=0.8
2019
- ammolite >=0.8
21-
- rpy2
22-
- r-bio3d
20+
- ruff >=0.6.7

0 commit comments

Comments
 (0)