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

New Tool: OMERO convert dataset to plate #74

Merged
merged 38 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3d6fc74
New tool for converting dataset to plate. CI/PR updated
rmassei Nov 19, 2024
0d85c62
Change Dataset 1 as target
rmassei Nov 19, 2024
cc89974
Update omero_dataset_to_plate.xml
rmassei Nov 19, 2024
55cea23
Delete .github/dummy_hcs_dataset directory
rmassei Nov 19, 2024
afa13b6
Update ci.yaml
rmassei Nov 19, 2024
559cf9f
Update pr.yaml
rmassei Nov 19, 2024
fa02c00
Update omero_dataset_to_plate.py
rmassei Nov 19, 2024
45d7b3b
Update omero_dataset_to_plate.xml
rmassei Nov 19, 2024
69ad20a
Update omero_dataset_to_plate.py
rmassei Nov 19, 2024
bf212ea
updated the python script, more clear log file, add a dummy hcs datas…
rmassei Nov 20, 2024
2687d6d
correct the out file and the python script for writing
rmassei Nov 20, 2024
604127a
further correction of the log file
rmassei Nov 20, 2024
873422a
further correction of the test
rmassei Nov 20, 2024
de15bbc
Correction for the test output (xml + log file)
rmassei Nov 20, 2024
3781acd
Further testing fixing
rmassei Nov 20, 2024
71ce6b8
Further testing fixing - Worng ID
rmassei Nov 20, 2024
7524ecb
Correction of the log output file
rmassei Nov 20, 2024
1a508c3
Update tools/omero/omero_dataset_to_plate.xml
rmassei Nov 20, 2024
fec66c0
Added two additional inputs to the python file, mapping file plus dat…
rmassei Nov 27, 2024
1c5f896
Merge branch 'omero_development' of github.com:rmassei/mb-galaxy-tool…
rmassei Nov 27, 2024
2ebb150
PEP8 and log output file corrections
rmassei Nov 27, 2024
8f0aa84
Further correction of the python code, changed append to write
rmassei Nov 27, 2024
9b0e00a
Correct the log output file according to the new python script
rmassei Nov 27, 2024
07cbbba
Corrected the xml file
rmassei Nov 27, 2024
324363d
Corrected the python file
rmassei Nov 27, 2024
ba6b946
Added to the the metadata import script the OMERO objects Plate and Well
rmassei Dec 2, 2024
72b963f
Add a min value id to all tools having an id as input
rmassei Dec 2, 2024
73735d3
Update tools/omero/omero_dataset_to_plate.py
rmassei Dec 16, 2024
4794e9d
Update tools/omero/omero_metadata_import.xml
rmassei Dec 16, 2024
8d53f5d
Update omero_dataset_to_plate.py
rmassei Dec 16, 2024
f1e8a22
Update omero_dataset_to_plate.xml
rmassei Dec 16, 2024
ed816ef
correct the xml (data type missing)
rmassei Dec 16, 2024
2fd7e8b
string -> text as data type in the xml
rmassei Dec 16, 2024
2e2bf32
Update omero_dataset_to_plate.xml
rmassei Dec 16, 2024
9b1bab7
Update omero_dataset_to_plate.xml
rmassei Dec 16, 2024
1eca639
Update omero_filter.xml
rmassei Dec 16, 2024
9f4b282
Update omero_filter.xml
rmassei Dec 16, 2024
f481521
test correction
rmassei Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/dummy-hcs-omero/sample_A03_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/dummy-hcs-omero/sample_H11_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ jobs:
omero tag create --name test_tag --desc 'description of my_tag'
omero tag link Image:1 1
echo "Created the dummy dataset into OMERO"
DID_HCS=$(omero obj new Dataset name='test_hcs_dts')
omero import -d $DID_HCS .github/dummy-hcs-omero
echo "Created the hcs dummy dataset into OMERO"

# download or create large test data via script
- name: Create test data
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ jobs:
omero tag create --name test_tag --desc 'description of my_tag'
omero tag link Image:1 1
echo "Created the dummy dataset into OMERO"
DID_HCS=$(omero obj new Dataset name='test_hcs_dts')
omero import -d $DID_HCS .github/dummy-hcs-omero
echo "Created the hcs dummy dataset into OMERO"

# download or create large test data via script
- name: Create test data
Expand Down
127 changes: 127 additions & 0 deletions tools/omero/omero_dataset_to_plate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import argparse
import csv
import json
import re
import sys
from collections import defaultdict


import omero
from omero.gateway import BlitzGateway
from omero.rtypes import rint, rstring


def convert_dataset_to_plate(host, user, pws, port, dataset_id, log_file, mapping_file, delete_dataset):
"""
Connect to OMERO server, convert a dataset to a plate using the specified well mapping file
"""
conn = BlitzGateway(user, pws, host=host, port=port, secure=True)
if not conn.connect():
sys.exit("ERROR: Failed to connect to OMERO server")

def log_message(message, status="INFO"):
with open(log_file, 'w') as f:
f.write(f"{message}")

dataset = conn.getObject("Dataset", dataset_id)
if dataset is None:
conn.close()
sys.exit("ERROR: Dataset not found")

update_service = conn.getUpdateService()

# Create a Plate
plate = omero.model.PlateI()
plate.name = rstring(dataset.getName())
plate = update_service.saveAndReturnObject(plate)

# Parse the mapping file
image_to_well_mapping = {}
if mapping_file:
with open(mapping_file, 'r') as f:
reader = csv.DictReader(f, delimiter='\t')
for row in reader:
filename = row['Filename']
well = row['Well']
match = re.match(r"([A-Z])(\d+)", well)
if match:
row_char, col = match.groups()
row = ord(row_char.upper()) - ord('A')
col = int(col) - 1
image_to_well_mapping[filename] = (row, col)
else:
conn.close()
sys.exit(f"Invalid well format '{well}' for file '{filename}'")

# List the dataset children
images = list(dataset.listChildren())
if not images:
conn.close()
sys.exit("ERROR: No images found in dataset")

# Compare images in the mapping file and in the dataset
grouped_images = defaultdict(list)
for image in images:
image_name = image.getName()
if image_to_well_mapping:
if image_name in image_to_well_mapping:
row, col = image_to_well_mapping[image_name]
grouped_images[(row, col)].append(image)
rmassei marked this conversation as resolved.
Show resolved Hide resolved
else:
conn.close()
sys.exit(f"Image '{image_name}' not found in mapping file.")

# Assign images to the well based on the mapping file
for (row, col), imgs_in_group in grouped_images.items():
well = omero.model.WellI()
well.plate = omero.model.PlateI(plate.id.val, False)
bernt-matthias marked this conversation as resolved.
Show resolved Hide resolved
well.column = rint(col)
well.row = rint(row)

for image in imgs_in_group:
ws = omero.model.WellSampleI()
ws.image = omero.model.ImageI(image.id, False)
ws.well = well
well.addWellSample(ws)

try:
update_service.saveObject(well)
except ValueError as e:
conn.close()
sys.exit("ERROR: Failed to update plate for dataset '{}' due to: {}".format(dataset.getName(), str(e)))

# Close the connection and, in case, delete the dataset
if delete_dataset is True:
conn.deleteObjects("Dataset", [dataset_id], wait=True)
log_message(f"Images from Dataset {dataset_id} successfully added to Plate {plate.id.val}")
conn.close()


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Convert an OMERO dataset to a plate.")
parser.add_argument("--credential-file", dest="credential_file", type=str, required=True,
help="Credential file (JSON file with username and password for OMERO)")
parser.add_argument('--host', required=True, help='OMERO host')
parser.add_argument('--port', required=True, type=int, help='OMERO port')
parser.add_argument('--dataset_id', type=int, required=True, help="Dataset ID to convert plate")
parser.add_argument('--log_file', default='metadata_import_log.txt',
help='Path to the log file')
parser.add_argument('--mapping_file',
help='Tabular file mapping filenames to well positions (2 columns: filename, Well)')
parser.add_argument('--delete_dataset', action='store_true',
help='Flag to delete the original dataset')
args = parser.parse_args()

with open(args.credential_file, 'r') as f:
crds = json.load(f)

convert_dataset_to_plate(
user=crds['username'],
pws=crds['password'],
host=args.host,
port=args.port,
dataset_id=args.dataset_id,
log_file=args.log_file,
mapping_file=args.mapping_file,
delete_dataset=args.delete_dataset
)
67 changes: 67 additions & 0 deletions tools/omero/omero_dataset_to_plate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<tool id="omero_dataset_to_plate" name="OMERO Dataset to Plate" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@" license="MIT">
rmassei marked this conversation as resolved.
Show resolved Hide resolved
<description> with omero-py </description>
<macros>
<import>macros.xml</import>
<token name="@VERSION_SUFFIX@">3</token>
</macros>
<xrefs>
<xref type="bio.tools">omero</xref>
</xrefs>
<expand macro="omeropy_requirements"/>
<command detect_errors="exit_code"><![CDATA[
python '$__tool_directory__/omero_dataset_to_plate.py'
--credential-file '$credentials'
@HOST_PORT@
--dataset_id '$dataset_id'
--log_file '$log'
--mapping_file '$mapping'
'$delete_dataset'
]]></command>
<configfiles>
<expand macro="credentials"/>
</configfiles>
<inputs>
<expand macro="host_port"/>
<param name="dataset_id" type="integer" optional="false" min = "1" label="Dataset ID to convert to a plate"/>
<param name="mapping" type="data" format= "tabular" optional="false" label="Mapping file"/>
<param name="delete_dataset" type="boolean" truevalue="--delete_dataset" falsevalue="" checked="false" label="Delete Dataset" help="Delete dataset after import"/>
</inputs>
<outputs>
<data name="log" format="txt"/>
</outputs>
<tests>
<test>
<param name="omero_host" value="host.docker.internal"/>
<param name="omero_port" value="6064"/>
<param name="dataset_id" value="2"/>
<param name="test_username" value="root"/>
<param name="test_password" value="omero"/>
<param name="mapping" value="mapping.tsv"/>
<param name="delete_dataset" value="True"/>
<output name="log" value="dataset_conversion_log.txt" ftype="txt">
<assert_contents>
<has_text text="Images from Dataset 2 successfully added to Plate 1"/>
</assert_contents>
</output>
</test>
</tests>
<help>
Description
-----------
- Tool to convert an existing dataset to a plate in OMERO
- The tool is taking as input a mapping tabular file with Filename and Well Position:
+------------+---------------+
| Filename | Well |
+============+===============+
| image1.tiff| A2 |
+------------+---------------+
| image2.tiff| B5 |
+------------+---------------+
| image3.tiff| H12 |
+------------+---------------+
@SECURITY_DISCLAIMER@
</help>
<citations>
<citation type="doi">10.1038/nmeth.1896</citation>
</citations>
</tool>
4 changes: 2 additions & 2 deletions tools/omero/omero_filter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<param name="test_password" value="omero"/>
<output name="tsv" value="output_filter_filename.tsv" ftype="tabular">
<assert_contents>
<has_text text="2"/>
<has_text text="1"/>
<has_n_columns n="1"/>
</assert_contents>
</output>
Expand Down Expand Up @@ -114,4 +114,4 @@ Description
<citations>
<citation type="doi">10.1038/nmeth.1896</citation>
</citations>
</tool>
</tool>
2 changes: 1 addition & 1 deletion tools/omero/omero_get_value.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</param>
</when>
<when value="file">
<param argument="--ids_path" type="data" format="txt,tabular" label="Dataset with ID(s) of the object(s) to fetch on OMERO (one per line)"/>
<param argument="--ids_path" type="data" format="txt,tabular" min="1" label="Dataset with ID(s) of the object(s) to fetch on OMERO (one per line)"/>
</when>
</conditional>
</inputs>
Expand Down
6 changes: 4 additions & 2 deletions tools/omero/omero_metadata_import.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@
<option value="project">Project</option>
<option value="screen">Screen</option>
<option value="dataset">Dataset</option>
<option value="plate">Plate</option>
<option value="well">Well</option>
<option value="image">Image</option>
</param>
<conditional name="object_id">
<param name="object_id_selection" type="select" label="Selection" help="Create a new OMERO object or target an existing one">
<param name="object_id_selection" type="select" label="Selection" help="Create a new OMERO object or target an existing one">
<option value="new_object">Create new object</option>
<option value="existing_object">Target an existing object</option>
</param>
<when value="new_object"/>
<when value="existing_object">
<param name="did" type="integer" value="" optional="false" label="Object ID"/>
<param name="did" type="integer" min = "1" optional="false" label="Object ID"/>
</when>
</conditional>
<param argument="ann_type" type="select" optional="false" label="Annotation type" help="Select annotation format">
Expand Down
10 changes: 8 additions & 2 deletions tools/omero/omero_metadata_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ def log_success(message):
if did is None:
did = ez.post_dataset(conn, dataset_name=str(datetime.now()))
result = upload_metadata(conn, "Dataset", did, data_dict, df, ann_type, an_name)
elif obj_type == "plate":
result = upload_metadata(conn, "Plate", did, data_dict, df, ann_type, an_name)
elif obj_type == "well":
result = upload_metadata(conn, "Well", did, data_dict, df, ann_type, an_name)
elif obj_type == "image":
result = upload_metadata(conn, "Image", did, data_dict, df, ann_type, an_name)
else:
Expand All @@ -74,10 +78,12 @@ def log_success(message):

if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Import metadata into OMERO.')
parser.add_argument("--credential-file", dest="credential_file", type=str, required=True, help="Credential file (JSON file with username and password for OMERO)")
parser.add_argument("--credential-file", dest="credential_file", type=str, required=True,
help="Credential file (JSON file with username and password for OMERO)")
parser.add_argument('--host', required=True, help='OMERO host')
parser.add_argument('--port', required=True, type=int, help='OMERO port')
parser.add_argument('--obj_type', required=True, choices=['project', 'screen', 'dataset', 'image'],
parser.add_argument('--obj_type', required=True, choices=['project', 'screen', 'dataset', 'plate',
'well ', 'image'],
help='Type of OMERO object')
parser.add_argument('--did', type=int, help='ID of the object (if it exists)')
parser.add_argument('--ann_type', required=True, choices=['table', 'KV'], help='Annotation type')
Expand Down
2 changes: 1 addition & 1 deletion tools/omero/omero_roi_import.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<inputs>
<expand macro="host_port"/>
<param argument="input" type="data" format="tabular" optional="false" label="Tab File with ROIs" help="Select ROIs Tabular file"/>
<param argument="id" type="integer" value="" optional="false" label="Image ID where annotate the ROIs"/>
<param argument="id" type="integer" value="" optional="false" min = "1" label="Image ID where annotate the ROIs"/>
</inputs>
<outputs>
<data name="log" format="txt"/>
Expand Down
1 change: 1 addition & 0 deletions tools/omero/test-data/dataset_conversion_log.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Images from Dataset 2 successfully added to Plate 1
3 changes: 3 additions & 0 deletions tools/omero/test-data/mapping.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Filename Well
sample_A03_image.jpg A2
sample_H11_image.jpg H5
4 changes: 2 additions & 2 deletions tools/omero/test-data/omero_output.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Image:3
Image:4
Image:5
Image:6
bernt-matthias marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion tools/omero/test-data/output_KV_import.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
SUCCESS: Successfully uploaded metadata for dataset with ID 3. Result: {'Key1': 'Value1', 'Key2': 'Value2'}
SUCCESS: Successfully uploaded metadata for dataset with ID 4. Result: {'Key1': 'Value1', 'Key2': 'Value2'}
Loading