Mercurial > repos > ufz > omero_metadata_import
changeset 1:588d6fa22fc4 draft
planemo upload for repository https://github.com/Helmholtz-UFZ/galaxy-tools/tree/main/tools/omero commit 5b1b30d409355cee98485815c1dd4ac48649bcc1
author | ufz |
---|---|
date | Thu, 05 Sep 2024 11:55:55 +0000 |
parents | 352e9d4eaf70 |
children | e41f70e69349 |
files | omero_metadata_import.xml omero_roi_upload.py test-data/input_roi.tsv test-data/omero_output.txt test-data/output_KV_import.txt test-data/output_table_import.txt test-data/output_table_roi.txt |
diffstat | 7 files changed, 199 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/omero_metadata_import.xml Wed Aug 07 12:54:19 2024 +0000 +++ b/omero_metadata_import.xml Thu Sep 05 11:55:55 2024 +0000 @@ -3,7 +3,7 @@ <description> with ezomero </description> <macros> <token name="@TOOL_VERSION@">5.18.0</token> - <token name="@VERSION_SUFFIX@">0</token> + <token name="@VERSION_SUFFIX@">1</token> </macros> <xrefs> <xref type="bio.tools">omero</xref> @@ -11,12 +11,13 @@ <requirements> <requirement type="package" version="3.0.1">ezomero</requirement> <requirement type="package" version="2.2.2">pandas</requirement> + <!-- openjdk is needed: https://github.com/conda-forge/omero-py-feedstock/pull/16 --> <requirement type="package" version="21.0.2">openjdk</requirement> </requirements> <command detect_errors="exit_code"><![CDATA[ python $__tool_directory__/omero_metadata_upload.py - --user $__user__.extra_preferences.get('omero|username', $test_username) - --pws $__user__.extra_preferences.get('omero|password', $test_password) + --user $__user__.extra_preferences.get('omero_account|username', $test_username) + --pws $__user__.extra_preferences.get('omero_account|username', $test_password) --host $omero_host --port $omero_port --obj_type $obj_type @@ -29,7 +30,10 @@ #end if ]]></command> <inputs> - <param argument="omero_host" type="text" optional="false" label="OMERO host URL"/> + <param name="omero_host" type="text" label="OMERO host URL"> + <validator type="regex" message="Enter a valid host location, for example, your.omero.server">^[a-zA-Z0-9._-]*$</validator> + <validator type="expression" message="No two dots (..) allowed">'..' not in value</validator> + </param> <param argument="omero_port" type="integer" optional="false" value="4064" label="OMERO port"/> <param argument="obj_type" type="select" optional="true" label="Target Object Type"> <option value="project">Project</option>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omero_roi_upload.py Thu Sep 05 11:55:55 2024 +0000 @@ -0,0 +1,165 @@ +import argparse +import re + +import pandas as pd +from ezomero import connect, post_roi +from ezomero.rois import Ellipse, Label, Line, Point, Polygon, Polyline, Rectangle + + +def parse_color(color_str): + if not color_str: + return None + return tuple(map(int, re.findall(r'\d+', color_str))) + + +def parse_points(points_str): + if not points_str: + return None + # Remove leading and trailing brackets and split into individual points + points_str = points_str.strip("[]") + points = points_str.split("),(") + points = [point.strip("()") for point in points] # Remove any remaining parentheses + return [tuple(map(float, point.split(','))) for point in points] + + +def create_shape(row): + shape_type = row['shape'] + shape = None + + if shape_type == 'Ellipse': + shape = Ellipse( + x=row['x'], + y=row['y'], + x_rad=row['x_rad'], + y_rad=row['y_rad'], + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Label': + shape = Label( + x=row['x'], + y=row['y'], + label=row['label'], + fontSize=row['fontSize'], + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Line': + shape = Line( + x1=row['x1'], + y1=row['y1'], + x2=row['x2'], + y2=row['y2'], + markerStart=row.get('markerStart', None), + markerEnd=row.get('markerEnd', None), + label=row.get('label', None), + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Point': + shape = Point( + x=row['x'], + y=row['y'], + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Polygon': + shape = Polygon( + points=parse_points(row['points']), + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Polyline': + shape = Polyline( + points=parse_points(row['points']), + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + elif shape_type == 'Rectangle': + shape = Rectangle( + x=row['x'], + y=row['y'], + width=row['width'], + height=row['height'], + z=row.get('z'), + c=row.get('c'), + t=row.get('t'), + fill_color=parse_color(row.get('fill_color')), + stroke_color=parse_color(row.get('stroke_color')), + stroke_width=row.get('stroke_width') + ) + return shape + + +def main(input_file, conn, image_id, log_file): + # Open log file + with open(log_file, 'w') as log: + df = pd.read_csv(input_file, sep='\t') + for index, row in df.iterrows(): + msg = f"Processing row {index + 1}/{len(df)}: {row.to_dict()}" + print(msg) + log.write(msg + "\n") + shape = create_shape(row) + if shape: + roi_name = row['roi_name'] if 'roi_name' in row else None + roi_description = row['roi_description'] if 'roi_description' in row else None + roi_id = post_roi(conn, image_id, [shape], name=roi_name, description=roi_description) + msg = f"ROI ID: {roi_id} for row {index + 1}" + print(msg) + log.write(msg + "\n") + else: + msg = f"Skipping row {index + 1}: Unable to create shape" + print(msg) + log.write(msg + "\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Create shapes from a tabular file and optionally post them as an ROI to OMERO.") + parser.add_argument("--input_file", help="Path to the input tabular file.") + parser.add_argument("--image_id", type=int, required=True, help="ID of the image to which the ROI will be linked") + parser.add_argument("--host", type=str, required=True, help="OMERO server host") + parser.add_argument("--user", type=str, required=True, help="OMERO username") + parser.add_argument("--psw", type=str, required=True, help="OMERO password") + parser.add_argument("--port", type=int, default=4064, help="OMERO server port") + parser.add_argument("--log_file", type=str, default="process.txt", help="Log file path") + + args = parser.parse_args() + + conn = connect( + host=args.host, + user=args.user, + password=args.psw, + port=args.port, + group="", + secure=True + ) + + try: + main(args.input_file, conn, args.image_id, args.log_file) + finally: + conn.close()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/input_roi.tsv Thu Sep 05 11:55:55 2024 +0000 @@ -0,0 +1,8 @@ +shape x y x_rad y_rad label fontSize x1 y1 x2 y2 points width height fill_color stroke_color stroke_width z c t roi_name roi_description +Ellipse 50.0 50.0 20.0 10.0 (255,0,0,128) (0,0,0,255) 2 0 0 0 Example ROI This is an example ROI +Label 100.0 100.0 Test Label 12.0 (255,255,255,0) (0,0,255,255) 1 0 0 0 Example ROI This is an example ROI +Line 200.0 200.0 250.0 250.0 (0,255,0,128) (0,0,0,255) 2 0 1 0 Example ROI This is an example ROI +Point 150.0 150.0 (0,0,255,128) (255,0,0,255) 3 0 2 0 Example ROI This is an example ROI +Polygon (300,300),(350,350),(300,400) (255,255,0,128) (0,0,0,255) 2 1 0 0 Example ROI This is an example ROI +Polyline (400,400),(450,450),(400,500) (0,255,255,128) (0,0,0,255) 3 0 0 0 Example ROI This is an example ROI +Rectangle 500.0 500.0 100.0 50.0 (255,0,255,128) (0,0,0,255) 2 0 0 0 Example ROI This is an example ROI
--- a/test-data/omero_output.txt Wed Aug 07 12:54:19 2024 +0000 +++ b/test-data/omero_output.txt Thu Sep 05 11:55:55 2024 +0000 @@ -1,2 +1,2 @@ -Image:1 -Image:2 +Image:3 +Image:4
--- a/test-data/output_KV_import.txt Wed Aug 07 12:54:19 2024 +0000 +++ b/test-data/output_KV_import.txt Thu Sep 05 11:55:55 2024 +0000 @@ -1,1 +1,1 @@ -SUCCESS: Successfully uploaded metadata for dataset with ID 1. Result: {'Key1': 'Value1', 'Key2': 'Value2'} +SUCCESS: Successfully uploaded metadata for dataset with ID 2. Result: {'Key1': 'Value1', 'Key2': 'Value2'}
--- a/test-data/output_table_import.txt Wed Aug 07 12:54:19 2024 +0000 +++ b/test-data/output_table_import.txt Thu Sep 05 11:55:55 2024 +0000 @@ -1,2 +1,2 @@ -SUCCESS: Successfully uploaded metadata for project with ID 1. Result: Key1 Key2 +SUCCESS: Successfully uploaded metadata for project with ID 2. Result: Key1 Key2 0 Value1 Value2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/output_table_roi.txt Thu Sep 05 11:55:55 2024 +0000 @@ -0,0 +1,14 @@ +Processing row 1/7: {'shape': 'Ellipse', 'x': 50.0, 'y': 50.0, 'x_rad': 20.0, 'y_rad': 10.0, 'label': nan, 'fontSize': nan, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': nan, 'width': nan, 'height': nan, 'fill_color': '(255,0,0,128)', 'stroke_color': '(0,0,0,255)', 'stroke_width': 2, 'z': 0, 'c': 0, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 1 for row 1 +Processing row 2/7: {'shape': 'Label', 'x': 100.0, 'y': 100.0, 'x_rad': nan, 'y_rad': nan, 'label': 'Test Label', 'fontSize': 12.0, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': nan, 'width': nan, 'height': nan, 'fill_color': '(255,255,255,0)', 'stroke_color': '(0,0,255,255)', 'stroke_width': 1, 'z': 0, 'c': 0, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 2 for row 2 +Processing row 3/7: {'shape': 'Line', 'x': nan, 'y': nan, 'x_rad': nan, 'y_rad': nan, 'label': nan, 'fontSize': nan, 'x1': 200.0, 'y1': 200.0, 'x2': 250.0, 'y2': 250.0, 'points': nan, 'width': nan, 'height': nan, 'fill_color': '(0,255,0,128)', 'stroke_color': '(0,0,0,255)', 'stroke_width': 2, 'z': 0, 'c': 1, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 3 for row 3 +Processing row 4/7: {'shape': 'Point', 'x': 150.0, 'y': 150.0, 'x_rad': nan, 'y_rad': nan, 'label': nan, 'fontSize': nan, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': nan, 'width': nan, 'height': nan, 'fill_color': '(0,0,255,128)', 'stroke_color': '(255,0,0,255)', 'stroke_width': 3, 'z': 0, 'c': 2, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 4 for row 4 +Processing row 5/7: {'shape': 'Polygon', 'x': nan, 'y': nan, 'x_rad': nan, 'y_rad': nan, 'label': nan, 'fontSize': nan, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': '(300,300),(350,350),(300,400)', 'width': nan, 'height': nan, 'fill_color': '(255,255,0,128)', 'stroke_color': '(0,0,0,255)', 'stroke_width': 2, 'z': 1, 'c': 0, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 5 for row 5 +Processing row 6/7: {'shape': 'Polyline', 'x': nan, 'y': nan, 'x_rad': nan, 'y_rad': nan, 'label': nan, 'fontSize': nan, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': '(400,400),(450,450),(400,500)', 'width': nan, 'height': nan, 'fill_color': '(0,255,255,128)', 'stroke_color': '(0,0,0,255)', 'stroke_width': 3, 'z': 0, 'c': 0, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 6 for row 6 +Processing row 7/7: {'shape': 'Rectangle', 'x': 500.0, 'y': 500.0, 'x_rad': nan, 'y_rad': nan, 'label': nan, 'fontSize': nan, 'x1': nan, 'y1': nan, 'x2': nan, 'y2': nan, 'points': nan, 'width': 100.0, 'height': 50.0, 'fill_color': '(255,0,255,128)', 'stroke_color': '(0,0,0,255)', 'stroke_width': 2, 'z': 0, 'c': 0, 't': 0, 'roi_name': 'Example ROI', 'roi_description': 'This is an example ROI'} +ROI ID: 7 for row 7