diff --git a/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1.20230822.b6e751e-foss-2023a-CUDA-12.1.1.eb b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1.20230822.b6e751e-foss-2023a-CUDA-12.1.1.eb new file mode 100644 index 000000000000..46bfe09eb1aa --- /dev/null +++ b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1.20230822.b6e751e-foss-2023a-CUDA-12.1.1.eb @@ -0,0 +1,82 @@ +# Thomas Hoffmann, EMBL Heidelberg, structures-it@embl.de, 2023/11 +easyblock = 'PythonBundle' + +name = 'relion-classranker' +_v = '0.0.1' +_sha = 'b6e751e5cb4205d8e9b36d0ae38c3687b3395acb' +_date = '20230822' +version = '%s.%s.%s' % (_v, _date, _sha[:7]) + +versionsuffix = '-CUDA-%(cudaver)s' + +homepage = 'https://github.com/3dem/%(name)s' +description = """The class ranker is part of the cryogenic electron microscopy (cryo-EM) dataset +processing pipeline in RELION. It is used to automatically select suitable +particles (EM images) assigned to 2D class averages for further downstream +processing. + +This model comprises two main components: a CNN responsible for extracting image +features, and an MLP that combines the image features with additional statistics +to assigns a score ranging from zero to one for each 2D class average. + +The selection is subsequently done in RELION through a user defined cutoff for +the predicted score. + +For training, a supervised approach is adopted, where pairs of 2D classes and +corresponding human-assigned scores are used to teach the model. +""" + +toolchain = {'name': 'foss', 'version': '2023a'} + +patches = [] + +dependencies = [ + ('Python', '3.11.3'), + ('CUDA', '12.1.1', '', SYSTEM), + ('PyTorch-bundle', '2.1.2', versionsuffix), + ('relion-classranker_data', '1.0', '', SYSTEM), +] + +use_pip = True + +exts_list = [ + ('loguru', '0.7.2', { + 'checksums': ['e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac'], + }), + ('relion_classranker', '0.0.1.20230822', { + 'patches': [ + 'relion-classranker-0.0.1_relax_requirements.patch', + 'relion-classranker-0.0.1_multi_torch_home.patch', + 'relion-classranker-0.0.1_add_script.patch', + ], + 'source_urls': ['https://github.com/3dem/relion-classranker/archive/'], + 'sources': [{ + 'download_filename': 'b6e751e5cb4205d8e9b36d0ae38c3687b3395acb.tar.gz', + 'filename': '%(name)s-%(version)s.tar.gz' + }], + 'checksums': [ + {'relion_classranker-0.0.1.20230822.tar.gz': + 'f5fa204831a47155a6a509d7dc427ee216eef7c391784eb8844006d5dce6f014'}, + {'relion-classranker-0.0.1_relax_requirements.patch': + '943728e60498ff154f65b29a73cccf759018f56f90970ed728d94f1a2f4b1958'}, + {'relion-classranker-0.0.1_multi_torch_home.patch': + '2b1c612b687d6a552492da75dc05003c04ed677862514dfa7317941f500c9033'}, + {'relion-classranker-0.0.1_add_script.patch': + 'cb2c9c362f79faa25527f58fad3bdaaed4090b791c46aca70447587742600907'}, + ], + }), +] + +fix_python_shebang_for = ['bin/command_line.py'] + +postinstallcmds = ['mv %(installdir)s/bin/{command_line.py,relion_classranker}'] + +sanity_pip_check = True + +sanity_check_paths = { + 'files': [], + 'dirs': ['lib/python%(pyshortver)s/site-packages/relion_classranker'], +} +sanity_check_commands = ['relion_classranker -h'] + +moduleclass = 'bio' diff --git a/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_add_script.patch b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_add_script.patch new file mode 100644 index 000000000000..e0fd8bf91a95 --- /dev/null +++ b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_add_script.patch @@ -0,0 +1,17 @@ +# Thomas Hoffmann, EMBL Heidelberg, structures-it@embl.de, 2023/11 +# install command_line.py to bin. (to be renamed later by postinstall) +diff -ru relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/setup.py relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_add_script.patch/setup.py +--- relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/setup.py 2023-08-22 19:15:52.000000000 +0200 ++++ relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_add_script.patch/setup.py 2023-11-16 18:28:25.274552072 +0100 +@@ -35,8 +35,9 @@ + packages=find_packages(), + install_requires=install_requires, + python_requires=">=3.5", ++ scripts = ["relion_classranker/command_line.py"] + ) + + # Download, install and load model + # import relion_classranker +-# relion_classranker.install_and_load_model("v1.0") +\ No newline at end of file ++# relion_classranker.install_and_load_model("v1.0") diff --git a/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_multi_torch_home.patch b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_multi_torch_home.patch new file mode 100644 index 000000000000..30c6d8d6ffcf --- /dev/null +++ b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_multi_torch_home.patch @@ -0,0 +1,45 @@ +# Thomas Hoffmann, EMBL Heidelberg, structures-it@embl.de, 2023/11 +# allow to use TORCH_HOME with modextrapaths. +# Automatic download of v1.0.ckpt is disabled for multi TORCH_HOME. +diff -ru relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/relion_classranker/command_line.py relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_multi_torch_home/relion_classranker/command_line.py +--- relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/relion_classranker/command_line.py 2023-08-22 19:15:52.000000000 +0200 ++++ relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_multi_torch_home/relion_classranker/command_line.py 2023-11-16 18:57:48.509605576 +0100 +@@ -1,3 +1,4 @@ ++#!/usr/bin/env python + import sys + + if sys.version_info < (3, 0): +@@ -42,9 +43,9 @@ + model_path = os.path.join(dest_dir, f"{name}.ckpt") + model_path_gz = model_path + ".gz" + completed_check_path = os.path.join(dest_dir, f"{name}_installed.txt") +- ++ is_torch_home_multi=False if os.getenv('TORCH_HOME')==None else len(os.getenv('TORCH_HOME').split(':'))>1 + # Download file and install it if not already done +- if not os.path.isfile(completed_check_path): ++ if not os.path.isfile(completed_check_path) and not is_torch_home_multi: + if verbose: + print(f"Installing Classranker model ({name})...") + os.makedirs(dest_dir, exist_ok=True) +@@ -63,8 +64,19 @@ + print(f"Model ({name}) successfully installed in {dest_dir}") + + # Load checkpoint file +- checkpoint = torch.load(model_path, map_location="cpu") +- ++ checkpoint = None ++ if is_torch_home_multi: ++ for _p in os.getenv('TORCH_HOME').split(':'): ++ model_path = os.path.join(_p, "hub", "checkpoints", "relion_classranker",f"{name}.ckpt") ++ try: ++ checkpoint = torch.load(model_path, map_location="cpu") ++ except: ++ if verbose: ++ print(f'Cannot load model {model_path}') ++ else: ++ break ++ else: ++ checkpoint = torch.load(model_path, map_location="cpu") + # Dynamically include model as a module + # Make sure to check download integrity for this, otherwise major security risk + model_module = types.ModuleType("classranker_model") diff --git a/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_relax_requirements.patch b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_relax_requirements.patch new file mode 100644 index 000000000000..8e25bf614555 --- /dev/null +++ b/easybuild/easyconfigs/r/relion-classranker/relion-classranker-0.0.1_relax_requirements.patch @@ -0,0 +1,14 @@ +# Thomas Hoffmann, EMBL Heidelberg, structures-it@embl.de, 2023/11 +# adapt versions to foss/2022a. +# downgrading torch to 1.12.0 from 2.0.1 might be a problem. +diff -ru relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/requirements.txt relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_relax_requirements/requirements.txt +--- relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb/requirements.txt 2023-08-22 19:15:52.000000000 +0200 ++++ relion-classranker-b6e751e5cb4205d8e9b36d0ae38c3687b3395acb_relax_requirements/requirements.txt 2023-11-16 18:21:03.394135835 +0100 +@@ -1,3 +1,3 @@ +-torch>=2.0.1 +-torchvision>=0.15.2 +-numpy>=1.24.4 +\ No newline at end of file ++torch>=1.12.0 ++torchvision>=0.13.1 ++numpy>=1.22.3 diff --git a/easybuild/easyconfigs/r/relion-classranker_data/relion-classranker_data-1.0.eb b/easybuild/easyconfigs/r/relion-classranker_data/relion-classranker_data-1.0.eb new file mode 100644 index 000000000000..d84f27be6370 --- /dev/null +++ b/easybuild/easyconfigs/r/relion-classranker_data/relion-classranker_data-1.0.eb @@ -0,0 +1,53 @@ +# Thomas Hoffmann, EMBL Heidelberg, structures-it@embl.de, 2023/11 +easyblock = 'Binary' +# TODO: use generic data easyblock + +name = 'relion-classranker_data' +version = '1.0' + +homepage = 'https://github.com/3dem/relion-classranker' +description = """This file serves as the model weights for for the class ranking functionality of RELION. +""" +toolchain = SYSTEM + +_prepare = '' +# Uncomment and adapt to store data (10GB) elsewhere: +# _common_data = '/easybuild/data' +# _prepare = 'mkdir -p %s/%%(name)s/%%(version)s/torch_home &&' % _common_data +# _prepare += 'ln -s %s/%%(name)s/%%(version)s/torch_home %%(installdir)s/torch_home &&' % _common_data + +buildininstalldir = True + +_models = [ + 'relion_classranker_v%(version)s', +] + +_torch_home = 'torch_home/' +_checkpoints_rel = '%s/hub/checkpoints' % _torch_home +_checkpoints = '%%(installdir)s/%s' % _checkpoints_rel + + +source_urls = ['ftp://ftp.mrc-lmb.cam.ac.uk/pub/dari/'] +sources = ['classranker_v%(version)s.ckpt.gz'] +checksums = ['68a9855c16d7bab64b7e73e1e1442c7bf898f227ffd9a19c48ddfd2cf0646d73'] + +skipsteps = ['configure', 'build', 'test'] +extract_sources = True + + +preinstallopts = _prepare +install_cmd = 'mkdir -p %s/relion_classranker/ &&' % _checkpoints +install_cmd += 'cd %s/relion_classranker && ' % _checkpoints +install_cmd += 'mv %(installdir)s/classranker_v%(version)s.ckpt v%(version)s.ckpt &&' +install_cmd += 'echo Sucessfully downloaded model>v%(version)s_installed.txt' + +modextrapaths = {'TORCH_HOME': '%s' % _torch_home} + +sanity_check_paths = { + 'files': [ + '%s/relion_classranker/v%%(version)s.ckpt' % _checkpoints_rel, + ], + 'dirs': [_checkpoints_rel] +} + +moduleclass = 'data'