-
Notifications
You must be signed in to change notification settings - Fork 879
Metaspace submit #8170
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
base: master
Are you sure you want to change the base?
Metaspace submit #8170
Changes from all commits
cf20cfa
1f88e61
a727319
f2d59b4
ef14739
afe57fe
78b5084
b36a05e
8de1a00
e793aff
58729a2
4bee093
5a1f152
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
channels: | ||
- conda-forge | ||
- bioconda | ||
dependencies: | ||
- bioconda::metaspace2020=2.0.9 | ||
- conda-forge::python=3.11.11 | ||
- conda-forge::pip=25.0.1 | ||
- conda-forge::pyyaml=6.0.2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
process METASPACE_SUBMIT { | ||
label 'process_low' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tag is missing |
||
|
||
conda "${moduleDir}/environment.yml" | ||
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? | ||
'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c3/c317f9380b8b631acacad83ab362b2badb42e8782f6bfa03e5befe59f2382283/data': | ||
'community.wave.seqera.io/library/python_pip_metaspace-converter:958b8906de66e072' }" | ||
|
||
input: | ||
path imzml | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't seen the pipeline context, but wouldn't it make sense to have a meta map? |
||
path ibd | ||
path config | ||
|
||
output: | ||
path("ds_id.txt") , emit: ds_id | ||
path("versions.yml"), emit: versions | ||
|
||
when: | ||
task.ext.when == null || task.ext.when | ||
|
||
script: | ||
def metaspaceApi = secrets.METASPACE_API_KEY ? | ||
"export API_KEY=\$(mktemp);echo -n \"${secrets.METASPACE_API_KEY}\" > \$API_KEY; " : | ||
"" | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general, modules should handle |
||
""" | ||
$metaspaceApi | ||
""" | ||
template 'submit.py' | ||
|
||
stub: | ||
|
||
""" | ||
touch ds_id.txt | ||
|
||
cat <<-END_VERSIONS > versions.yml | ||
"${task.process}": | ||
python: \$(python --version | cut -d ' ' -f 2) | ||
metaspace: \$(python3 -c 'import metaspace; print(metaspace.__version__)') | ||
yaml: \$(python3 -c 'import yaml; print(yaml.__version__)') | ||
END_VERSIONS | ||
""" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json | ||
name: "metaspace_submit" | ||
description: Submit imaging mass spectrometry data to METASPACE for metabolite annotation | ||
keywords: | ||
- imaging | ||
- mass_spectrometry | ||
- metabolomics | ||
- annotation | ||
tools: | ||
- "metaspace2020": | ||
description: "Python package providing programmatic access to the METASPACE platform" | ||
homepage: "https://metaspace2020.readthedocs.io" | ||
documentation: "https://metaspace2020.readthedocs.io" | ||
tool_dev_url: "https://github.com/metaspace2020/metaspace/tree/master/metaspace/python-client" | ||
licence: ["Apache-2.0 license"] | ||
identifier: biotools:metaspace | ||
|
||
input: | ||
- - imzml: | ||
type: file | ||
description: Path to .imzML file | ||
- - ibd: | ||
type: file | ||
description: Path to .ibd file | ||
- - config: | ||
type: file | ||
description: Path to .yml file containing dataset configuration and metadata | ||
output: | ||
- ds_id: | ||
- "ds_id.txt": | ||
type: file | ||
description: File containing METASPACE dataset ID | ||
pattern: "ds_id.txt" | ||
|
||
- versions: | ||
- "versions.yml": | ||
type: file | ||
description: File containing software versions | ||
pattern: "versions.yml" | ||
|
||
authors: | ||
- "@bisho2122" | ||
maintainers: | ||
- "@bisho2122" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#!/usr/bin/env python | ||
|
||
import yaml | ||
import metaspace | ||
import platform | ||
import os | ||
|
||
with open("${config}") as f: | ||
config = yaml.safe_load(f) | ||
|
||
api_key_path = os.getenv('API_KEY') | ||
|
||
if api_key_path and os.path.isfile(api_key_path): | ||
with open(api_key_path, "r") as f: | ||
API_key = f.read() | ||
else: | ||
API_key = api_key_path | ||
|
||
sm = metaspace.SMInstance(api_key=API_key) | ||
|
||
ds_name = config['Dataset_name'] | ||
|
||
Annot_settings = config['Annotation_settings'] | ||
|
||
metadata = {k: v for k, v in config.items() if k not in ['User_info','Dataset_name','Annotation_settings']} | ||
metadata = {'Data_Type': 'Imaging MS', **metadata} | ||
|
||
dbs = [tuple(item) for item in Annot_settings["Metabolite_database"]] | ||
|
||
if len(Annot_settings['Adducts']) == 0: | ||
adduct_list = None | ||
else: | ||
adduct_list = Annot_settings['Adducts'] | ||
|
||
if len(Annot_settings['Chemical_modifications']) == 0: | ||
chem_modif = None | ||
else: | ||
chem_modif = Annot_settings['Chemical_modifications'] | ||
|
||
scoring_model_id_map = { | ||
'MSM': 2, | ||
'METASPACE_ML_Animal': 3, | ||
'METASPACE_ML_Plant': 4 | ||
} | ||
|
||
scoring_model_id = scoring_model_id_map[Annot_settings['Analysis_version']] | ||
|
||
# Submit dataset | ||
|
||
ds_id = sm.submit_dataset( | ||
imzml_fn = "${imzml}", | ||
ibd_fn = "${ibd}", | ||
name = ds_name, | ||
metadata = metadata, | ||
is_public = False, | ||
databases = dbs, | ||
adducts = adduct_list, | ||
chem_mods = chem_modif, | ||
scoring_model = scoring_model_id, | ||
ppm = float(Annot_settings['ppm']) | ||
) | ||
|
||
with open("ds_id.txt", 'w') as f: | ||
f.write(ds_id) | ||
|
||
# Versions | ||
versions = {"${task.process}": {"python": platform.python_version(), | ||
"metaspace": metaspace.__version__, | ||
"yaml": yaml.__version__}} | ||
|
||
def format_yaml_like(data: dict, indent: int = 0) -> str: | ||
"""Formats a dictionary to a YAML-like string. | ||
|
||
Args: | ||
data (dict): The dictionary to format. | ||
indent (int): The current indentation level. | ||
|
||
Returns: | ||
str: A string formatted as YAML. | ||
""" | ||
yaml_str = "" | ||
for key, value in data.items(): | ||
spaces = " " * indent | ||
if isinstance(value, dict): | ||
yaml_str += f"{spaces}{key}:\\n{format_yaml_like(value, indent + 1)}" | ||
else: | ||
yaml_str += f"{spaces}{key}: {value}\\n" | ||
return yaml_str | ||
|
||
with open("versions.yml", "w") as f: | ||
f.write(format_yaml_like(versions)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
nextflow_process { | ||
|
||
name "Test Process METASPACE_SUBMIT" | ||
script "../main.nf" | ||
process "METASPACE_SUBMIT" | ||
config "./nextflow.config" | ||
|
||
tag "modules" | ||
tag "modules_nfcore" | ||
tag "metaspace" | ||
tag "metaspace/submit" | ||
|
||
test("metaspace_submit_test") { | ||
|
||
when { | ||
process { | ||
""" | ||
input[0] = file(params.test_data_base_path + 'test_metaspace_submit/test.imzML', checkIfExists: true) | ||
input[1] = file(params.test_data_base_path + 'test_metaspace_submit/test.ibd', checkIfExists: true) | ||
input[2] = file(params.test_data_base_path + 'test_metaspace_submit/ds_config.yml') | ||
""" | ||
} | ||
} | ||
|
||
then { | ||
assertAll( | ||
{ assert process.success } | ||
) | ||
} | ||
} | ||
test("metaspace_submit - stub") { | ||
tag "versions_test" | ||
|
||
options '-stub' | ||
when { | ||
process { | ||
""" | ||
input[0] = file(params.test_data_base_path + 'test_metaspace_submit/test.imzML', checkIfExists: true) | ||
input[1] = file(params.test_data_base_path + 'test_metaspace_submit/test.ibd', checkIfExists: true) | ||
input[2] = file(params.test_data_base_path + 'test_metaspace_submit/ds_config.yml') | ||
""" | ||
} | ||
} | ||
then { | ||
assertAll( | ||
{ assert process.success }, | ||
{ assert snapshot(process.out).match() } | ||
) | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"metaspace_submit - stub": { | ||
"content": [ | ||
{ | ||
"0": [ | ||
"ds_id.txt:md5,d41d8cd98f00b204e9800998ecf8427e" | ||
], | ||
"1": [ | ||
"versions.yml:md5,db6244919f766cddc2cd20502db9403d" | ||
], | ||
"ds_id": [ | ||
"ds_id.txt:md5,d41d8cd98f00b204e9800998ecf8427e" | ||
], | ||
"versions": [ | ||
"versions.yml:md5,db6244919f766cddc2cd20502db9403d" | ||
] | ||
} | ||
], | ||
"meta": { | ||
"nf-test": "0.9.2", | ||
"nextflow": "24.10.5" | ||
}, | ||
"timestamp": "2025-03-31T21:55:03.550137605" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,11 @@ | ||||||||||||||||||||||
env { | ||||||||||||||||||||||
// NOTE This is how nf-core/metaspace/submit users will use METASPACE submission in real world use | ||||||||||||||||||||||
API_KEY = "$METASPACE_API_KEY" | ||||||||||||||||||||||
|
||||||||||||||||||||||
// NOTE This is how nf-core/metaspace/submit users will test out METASPACE submission with a user API key | ||||||||||||||||||||||
// nextflow secrets set METASPACE_API_KEY "USER_API_KEY" | ||||||||||||||||||||||
Comment on lines
+2
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? Which of these would be the real use case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get the confusion. I think secrets has to be defined by the user using So it can be tested locally without the need to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
@SPPearce Is this more clear ? |
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
params { | ||||||||||||||||||||||
test_data_base_path = "https://raw.githubusercontent.com/nf-core/test-datasets/spatialmetabo/" | ||||||||||||||||||||||
} |
Uh oh!
There was an error while loading. Please reload this page.