fair-metadata-integration 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fair_metadata_integration/__init__.py +3 -0
- fair_metadata_integration/metadata_integration.py +95 -0
- fair_metadata_integration-0.1.0.dist-info/METADATA +124 -0
- fair_metadata_integration-0.1.0.dist-info/RECORD +7 -0
- fair_metadata_integration-0.1.0.dist-info/WHEEL +5 -0
- fair_metadata_integration-0.1.0.dist-info/licenses/LICENSE +21 -0
- fair_metadata_integration-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
from rocrate.rocrate import ROCrate
|
|
3
|
+
from rocrate.model import ComputerLanguage, ContextEntity
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def create_ro_crate(dest_path, workflow_schema_filename, input_path, output_paths=[]):
|
|
7
|
+
crate = ROCrate()
|
|
8
|
+
|
|
9
|
+
crate.metadata.extra_terms = {
|
|
10
|
+
"organism_classification": "https://schema.org/taxonomicRange",
|
|
11
|
+
"BioChemEntity": "https://schema.org/BioChemEntity",
|
|
12
|
+
"channel": "https://www.openmicroscopy.org/Schemas/Documentation/Generated/OME-2016-06/ome_xsd.html#Channel",
|
|
13
|
+
"obo": "http://purl.obolibrary.org/obo/",
|
|
14
|
+
"FBcv": "http://ontobee.org/ontology/FBcv/",
|
|
15
|
+
"acquisiton_method": {
|
|
16
|
+
"@reverse": "https://schema.org/result",
|
|
17
|
+
"@type": "@id",
|
|
18
|
+
},
|
|
19
|
+
"biological_entity": "https://schema.org/about",
|
|
20
|
+
"biosample": "http://purl.obolibrary.org/obo/OBI_0002648",
|
|
21
|
+
"preparation_method": "https://www.wikidata.org/wiki/Property:P1537",
|
|
22
|
+
"specimen": "http://purl.obolibrary.org/obo/HSO_0000308",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
output_entities = []
|
|
26
|
+
for image_path in output_paths:
|
|
27
|
+
rel_path = os.path.basename(image_path.rstrip('\\/'))
|
|
28
|
+
output_entities.append(crate.add_dataset(
|
|
29
|
+
source=image_path, dest_path=rel_path,
|
|
30
|
+
properties=get_additional_filetype_property(image_path)))
|
|
31
|
+
|
|
32
|
+
input_entity = crate.add_dataset(source=input_path,
|
|
33
|
+
dest_path=os.path.basename(input_path.rstrip('\\/')),
|
|
34
|
+
properties=get_additional_filetype_property(input_path))
|
|
35
|
+
|
|
36
|
+
# main=True sets the root dataset's mainEntity and declares the Workflow RO-Crate
|
|
37
|
+
# profile in conformsTo (on the metadata descriptor for rocrate < 0.16, on the
|
|
38
|
+
# root dataset for rocrate >= 0.16).
|
|
39
|
+
workflow = crate.add_workflow(source=workflow_schema_filename,
|
|
40
|
+
dest_path=os.path.basename(workflow_schema_filename),
|
|
41
|
+
main=True, lang=get_bilayers_language(crate))
|
|
42
|
+
|
|
43
|
+
# The Workflow RO-Crate profile ranges input/output over FormalParameter rather
|
|
44
|
+
# than over the data entities themselves; each data entity is linked back to its
|
|
45
|
+
# parameter with exampleOfWork.
|
|
46
|
+
workflow['input'] = [add_formal_parameter(crate, input_entity, 'input')]
|
|
47
|
+
if output_entities:
|
|
48
|
+
workflow['output'] = [
|
|
49
|
+
add_formal_parameter(crate, entity, 'output' if i == 0 else f'output_{i + 1}')
|
|
50
|
+
for i, entity in enumerate(output_entities)
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
crate.write(dest_path)
|
|
54
|
+
return crate
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_additional_filetype_property(path):
|
|
58
|
+
ext = os.path.splitext(path)[1]
|
|
59
|
+
ref = None
|
|
60
|
+
if '.zar' in ext:
|
|
61
|
+
ref = 'http://edamontology.org/format_3915'
|
|
62
|
+
elif '.tif' in ext:
|
|
63
|
+
ref = 'http://edamontology.org/format_3591'
|
|
64
|
+
if ref:
|
|
65
|
+
return {'additionalType': ref}
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_bilayers_language(crate):
|
|
70
|
+
"""Return the ComputerLanguage entity for a bilayers workflow specification.
|
|
71
|
+
|
|
72
|
+
Identified by the Zenodo concept DOI, which is version-independent and
|
|
73
|
+
resolves to the latest release of the specification.
|
|
74
|
+
"""
|
|
75
|
+
return crate.add(ComputerLanguage(
|
|
76
|
+
crate,
|
|
77
|
+
identifier='https://doi.org/10.5281/zenodo.17652333',
|
|
78
|
+
properties={
|
|
79
|
+
'name': 'Bilayers',
|
|
80
|
+
'alternateName': 'Bilayers workflow specification',
|
|
81
|
+
'identifier': {'@id': 'https://doi.org/10.5281/zenodo.17652333'},
|
|
82
|
+
'url': {'@id': 'https://github.com/bilayer-containers/bilayers'},
|
|
83
|
+
},
|
|
84
|
+
))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def add_formal_parameter(crate, data_entity, name):
|
|
88
|
+
"""Add a FormalParameter describing *data_entity* and link the two together."""
|
|
89
|
+
properties = {'@type': 'FormalParameter', 'name': name}
|
|
90
|
+
format_ref = data_entity.get('additionalType')
|
|
91
|
+
if format_ref:
|
|
92
|
+
properties['format'] = {'@id': format_ref}
|
|
93
|
+
parameter = crate.add(ContextEntity(crate, f'#{name}', properties))
|
|
94
|
+
data_entity['exampleOfWork'] = parameter
|
|
95
|
+
return parameter
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fair-metadata-integration
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Integrate and package all metadata into RO-Crate, linking to other metadata files
|
|
5
|
+
Author-email: Joost de Folter <folterj@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/NL-BioImaging/fair-metadata-integration
|
|
8
|
+
Project-URL: Repository, https://github.com/NL-BioImaging/fair-metadata-integration
|
|
9
|
+
Keywords: RO-Crate,FAIR,metadata,bioimaging,OME-Zarr
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: rocrate>=0.15.1
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# fair-metadata-integration
|
|
24
|
+
|
|
25
|
+
Integrate and package all metadata into RO-Crate, linking to other metadata files.
|
|
26
|
+
|
|
27
|
+
Given a [Bilayers](https://github.com/bilayer-containers/bilayers) workflow
|
|
28
|
+
specification and the image data an analysis consumed and produced, this package
|
|
29
|
+
writes a [Workflow RO-Crate](https://w3id.org/workflowhub/workflow-ro-crate/1.0):
|
|
30
|
+
an `ro-crate-metadata.json` describing the run, alongside copies of the files it
|
|
31
|
+
describes.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install fair-metadata-integration
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Requires Python 3.12 or newer. [`rocrate`](https://pypi.org/project/rocrate/) is
|
|
40
|
+
installed automatically.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from fair_metadata_integration import create_ro_crate
|
|
46
|
+
|
|
47
|
+
create_ro_crate(
|
|
48
|
+
dest_path="crate",
|
|
49
|
+
workflow_schema_filename="config.yaml",
|
|
50
|
+
input_path="input.ome.zarr",
|
|
51
|
+
output_paths=["output.ome.zarr"],
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- `dest_path` — directory the crate is written to, created if it does not exist.
|
|
56
|
+
- `workflow_schema_filename` — the Bilayers `config.yaml` describing the workflow.
|
|
57
|
+
- `input_path` — the input image (an OME-Zarr directory or a TIFF file).
|
|
58
|
+
- `output_paths` — the images the workflow produced. Each gets its own parameter.
|
|
59
|
+
|
|
60
|
+
The source files are copied into the crate, so `dest_path` ends up
|
|
61
|
+
self-contained:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
crate/
|
|
65
|
+
├── config.yaml
|
|
66
|
+
├── input.ome.zarr/
|
|
67
|
+
├── output.ome.zarr/
|
|
68
|
+
└── ro-crate-metadata.json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### What the crate contains
|
|
72
|
+
|
|
73
|
+
The workflow specification is the crate's `mainEntity`, typed as a
|
|
74
|
+
`ComputationalWorkflow`, and the metadata descriptor declares the Workflow
|
|
75
|
+
RO-Crate profile:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"@id": "ro-crate-metadata.json",
|
|
80
|
+
"@type": "CreativeWork",
|
|
81
|
+
"about": { "@id": "./" },
|
|
82
|
+
"conformsTo": [
|
|
83
|
+
{ "@id": "https://w3id.org/ro/crate/1.2" },
|
|
84
|
+
{ "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" }
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The workflow's `programmingLanguage` is a `ComputerLanguage` entity for the
|
|
90
|
+
Bilayers specification, identified by its Zenodo concept DOI
|
|
91
|
+
[`10.5281/zenodo.17652333`](https://doi.org/10.5281/zenodo.17652333), which
|
|
92
|
+
resolves to the latest release of the spec.
|
|
93
|
+
|
|
94
|
+
Inputs and outputs are modelled as `FormalParameter` entities carrying an
|
|
95
|
+
[EDAM](https://edamontology.org/) format IRI — `format_3915` for Zarr,
|
|
96
|
+
`format_3591` for TIFF. Each image dataset points back at the parameter it
|
|
97
|
+
realises via `exampleOfWork`:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"@id": "input.ome.zarr/",
|
|
102
|
+
"@type": "Dataset",
|
|
103
|
+
"additionalType": "http://edamontology.org/format_3915",
|
|
104
|
+
"exampleOfWork": { "@id": "#input" }
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The crate's JSON-LD context is extended with terms for describing biological
|
|
109
|
+
imaging metadata — `biosample`, `specimen`, `organism_classification`,
|
|
110
|
+
`preparation_method`, `channel` and others — so those properties can be added to
|
|
111
|
+
the crate's entities.
|
|
112
|
+
|
|
113
|
+
## Development
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
git clone https://github.com/NL-BioImaging/fair-metadata-integration.git
|
|
117
|
+
cd fair-metadata-integration
|
|
118
|
+
pip install -e ".[test]"
|
|
119
|
+
pytest
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
fair_metadata_integration/__init__.py,sha256=SnFC0fNZ4TLsdr8KaOZNgONT0xJVWk1I2x6h7xYAWwo,81
|
|
2
|
+
fair_metadata_integration/metadata_integration.py,sha256=HicirGwXaKwR-MUg18Jd6PVZkf3IeT8g7q8fwdj52Q8,3966
|
|
3
|
+
fair_metadata_integration-0.1.0.dist-info/licenses/LICENSE,sha256=lM752AVCWLqhoLjgYBwOn6aZPSyJF4F37p5HTp9rmLw,1070
|
|
4
|
+
fair_metadata_integration-0.1.0.dist-info/METADATA,sha256=Wz5PzsqjzLX-tgBPbLQcQMbTXxyK3ssDXICGbvSyGI4,3853
|
|
5
|
+
fair_metadata_integration-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
6
|
+
fair_metadata_integration-0.1.0.dist-info/top_level.txt,sha256=MCH6Wq-pmgeqiPsZvydDNhn6hI6Ox96rJSvbYgGafAQ,26
|
|
7
|
+
fair_metadata_integration-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NL-BioImaging
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fair_metadata_integration
|