Skip to content

Commit

Permalink
add new tools (omero get and omero filter) and updated the ci/pr pipe…
Browse files Browse the repository at this point in the history
…line to add metadat to the dummy set)
  • Loading branch information
rmassei committed Oct 11, 2024
1 parent dca5f94 commit 55b8878
Show file tree
Hide file tree
Showing 12 changed files with 408 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ jobs:
DID=$(omero obj new Dataset name='test_dts')
omero obj new ProjectDatasetLink parent=$PID child=$DID
omero import -d $DID .github/dummy-dts-omero
omero tag create --name test_tag --desc 'description of my_tag'
omero tag link Image:1 1
echo "Created the dummy dataset into OMERO"
# download or create large test data via script
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ jobs:
DID=$(omero obj new Dataset name='test_dts')
omero obj new ProjectDatasetLink parent=$PID child=$DID
omero import -d $DID .github/dummy-dts-omero
omero tag create --name test_tag --desc 'description of my_tag'
omero tag link Image:1 1
echo "Created the dummy dataset into OMERO"
# download or create large test data via script
Expand Down
6 changes: 3 additions & 3 deletions tools/omero/.shed.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
categories:
- Imaging
name: omero_upload
description: Import images, region of interest, metadata into an OMERO.server using omero-py
long_description: Tool to import and link different objects into OMERO
description: Interact with an OMERO.server using omero-py and ezomero.
long_description: This set of tool allows to import images and metadata into an OMERO.server.
owner: ufz
remote_repository_url: https://github.com/Helmholtz-UFZ/galaxy-tools/tree/main/tools/omero
homepage_url: https://github.com/ome/omero-py/
Expand All @@ -13,4 +13,4 @@ suite:
name: "suite_omero_py"
description: "A suite of tools that brings the omero-py and ezomero project into Galaxy."
long_description: |
OMERO.py provides an interface to the OMERO.blitz server.
OMERO.py and ezomero provides an interface to the OMERO.blitz server.
80 changes: 80 additions & 0 deletions tools/omero/omero_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import argparse
import csv
import json

import ezomero as ez


def filter_ids_ezo(user, pws, host, port, filter, id, value1, value2=None, tsv_file="filter_list.tsv"):

# Transform the id input in a list of integer
id = id.split(',')
id = list(map(int, id))

# Function to write tabular file from the ezomero output
def write_ids_to_tsv(data, header):
with open(tsv_file, 'a+', newline='') as f:
f.seek(0)
is_empty = f.tell() == 0 # Check if file is empty
writer = csv.writer(f, delimiter='\t')
if is_empty:
writer.writerow([header]) # Write the header
for item in data:
writer.writerow([item]) # Write each ID

try:
with ez.connect(user, pws, "", host, port, secure=True) as conn:
if filter == "filename":
fn_ids = ez.filter_by_filename(conn, id, value1)
write_ids_to_tsv(fn_ids, [f"Images with filename {value1}"])
return fn_ids
elif filter == "KP":
kp_ims = ez.filter_by_kv(conn, id, value1, value2)
write_ids_to_tsv(kp_ims, [f"Images with KV {value1} and {value2}"])
return kp_ims
elif filter == "tag":
tg_dict = ez.filter_by_tag_value(conn, id, value1)
write_ids_to_tsv(tg_dict, [f"Images with tag {value1}"])
return tg_dict

else:
raise ValueError(f"Unsupported object type")

except Exception as e:
print(f"Connection error: {str(e)}")
return None


# Argument parsing
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Fetch and save data as TSV based on object type.")
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="Host server address.")
parser.add_argument('--port', required=True, type=int,
help='OMERO port')
parser.add_argument('--filter', required=True,
help="Filter type - Filename, Key-Value Pairs, Tag")
parser.add_argument('--id', required=True,
help="List of images IDs")
parser.add_argument('--value1', required=True,
help="First searching values - Filename, Key, Tag")
parser.add_argument('--value2', required=False,
help="Second searching values - Value (necessary just for Key-Value Pairs filter")
parser.add_argument('--tsv_file', default='filter_list.tsv', required=True,
help="Output TSV file path.")

args = parser.parse_args()

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

# Call the main function to get the object and save it as a TSV
filter_ids_ezo(user=crds['username'], pws=crds['password'], host=args.host,
port=args.port,
filter=args.filter,
value1=args.value1,
value2=args.value2,
id=args.id,
tsv_file=args.tsv_file)
102 changes: 102 additions & 0 deletions tools/omero/omero_filter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<tool id="omero_filter_id" name="OMERO IDs" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@"
profile="20.01" license="MIT">
<description> with ezomero </description>
<macros>
<token name="@TOOL_VERSION@">5.18.0</token>
<token name="@VERSION_SUFFIX@">0</token>
</macros>
<xrefs>
<xref type="bio.tools">omero</xref>
</xrefs>
<requirements>
<requirement type="package" version="3.0.1">ezomero</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_filter.py
--credential-file '$credentials'
--host $omero_host
--port $omero_port
--filter $filter
--value1 $value1
--id $did
--tsv_file $tsv
#if $filter == "KP"
--value2 $value2
#end if
]]></command>
<configfiles>
<configfile name="credentials"><![CDATA[
{
"username": "$__user__.extra_preferences.get('omero_account|username', $test_username)",
"password": "$__user__.extra_preferences.get('omero_account|password', $test_password)"
}
]]></configfile>
</configfiles>
<inputs>
<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="filter" type="select" optional="true" label="Select filter">
<option value="filename">Project</option>
<option value="KP">Screen</option>
<option value="tag">Dataset</option>
</param>
<param argument="value1" type="text" optional="false" label="First filter criteria (i.e. filename)"/>
<param argument="value2" type="text" optional="true" label="Second filter criteria (just valid for KP search)"/>
<param name="did" type="text" optional="false" label="List of images IDs"/>
<param name="test_username" type="hidden" value=""/>
<param name="test_password" type="hidden" value=""/>
</inputs>
<outputs>
<data name="tsv" format="tabular"/>
</outputs>
<tests>
<test>
<param name="omero_host" value="host.docker.internal"/>
<param name="omero_port" value="6064"/>
<param name="filter" value="filename"/>
<param name="value1" value="sample_image_2.jpg"/>
<param name="did" value="1,2"/>
<param name="test_username" value="root"/>
<param name="test_password" value="omero"/>
<output name="tsv" value="output_filter_filename.tsv" ftype="tabular">
<assert_contents>
<has_text text="Images with filename sample_image_2.jpg"/>
<has_text text="2"/>
</assert_contents>
</output>
</test>
<test>
<param name="omero_host" value="host.docker.internal"/>
<param name="omero_port" value="6064"/>
<param name="filter" value="tag"/>
<param name="value1" value="test_tag"/>
<param name="did" value="1,2"/>
<param name="test_username" value="root"/>
<param name="test_password" value="omero"/>
<output name="tsv" value="output_filter_tag.tsv" ftype="tabular">
<assert_contents>
<has_text text="Images with tag test_tag"/>
<has_text text="1"/>
</assert_contents>
</output>
</test>
</tests>
<help>
Description
-----------

Tool to filter images IDs by filename, Key-Value Pairs and Tag value.
For Key-Value Pairs search, two values are required (Value1 = Key, Value2 = Pair).
IDs are a list of image IDs which can be fetched using the omero_get tool.

</help>
<citations>
<citation type="doi">10.1038/nmeth.1896</citation>
</citations>
</tool>
90 changes: 90 additions & 0 deletions tools/omero/omero_get.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import argparse
import csv
import json

import ezomero as ez


def get_object_ezo(user, pws, host, port, obj_type, id=None, tsv_file="id_list.tsv"):
# Function to write tabular file from the ezomero output
def write_ids_to_tsv(data, header):
with open(tsv_file, 'a+', newline='') as f:
f.seek(0)
is_empty = f.tell() == 0 # Check if file is empty
writer = csv.writer(f, delimiter='\t')
if is_empty:
writer.writerow([header]) # Write the header
for item in data:
writer.writerow([item]) # Write each ID

# Function to write tabular file from a dictionary ezomero output
def write_dict_to_tsv(data, headers):
with open(tsv_file, 'a+', newline='') as f:
f.seek(0)
is_empty = f.tell() == 0 # Check if file is empty
writer = csv.writer(f, delimiter='\t')
if is_empty:
writer.writerow(headers) # Write the headers
for key, value in data.items():
writer.writerow([key, value]) # Write each key-value pair

try:
with ez.connect(user, pws, "", host, port, secure=True) as conn:
if obj_type == "dataset":
ds_ids = ez.get_dataset_ids(conn, project=int(id))
write_ids_to_tsv(ds_ids, "Dataset IDs")
return ds_ids
elif obj_type == "image":
ds_ims = ez.get_image_ids(conn, dataset=int(id))
write_ids_to_tsv(ds_ims, "Image IDs")
return ds_ims
elif obj_type == "annotation":
ma_dict = ez.get_map_annotation(conn, int(id))
write_dict_to_tsv(ma_dict, ["Annotation ID", "Annotation Value"])
return ma_dict
elif obj_type == "project":
proj_ids = ez.get_project_ids(conn)
write_ids_to_tsv(proj_ids, "Project IDs")
return proj_ids
elif obj_type == "roi":
roi_ids = ez.get_roi_ids(conn, int(id))
write_ids_to_tsv(roi_ids, "ROI IDs")
return roi_ids
elif obj_type == "table":
table = ez.get_table(conn, int(id))
write_dict_to_tsv(table, ["Table ID", "Table Value"])
return table
else:
raise ValueError(f"Unsupported object type: {obj_type}")

except Exception as e:
print(f"Connection error: {str(e)}")
return None


# Argument parsing
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Fetch and save data as TSV based on object type.")
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="Host server address.")
parser.add_argument('--port', required=True, type=int,
help='OMERO port')
parser.add_argument('--obj_type', required=True,
help="Type of object to fetch: dataset, image, annotation, project, roi, or table.")
parser.add_argument('--id', required=False,
help="ID of the specific OMERO object.")
parser.add_argument('--tsv_file', default='id_list.tsv', required=True,
help="Output TSV file path.")
args = parser.parse_args()

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

# Call the main function to get the object and save it as a TSV
get_object_ezo(user=crds['username'], pws=crds['password'], host=args.host,
port=args.port,
obj_type=args.obj_type,
id=args.id,
tsv_file=args.tsv_file)
Loading

0 comments on commit 55b8878

Please sign in to comment.