Import mit omero-py bricht ohne Fehlermeldung ab
Unser Ziel ist es, Bilddaten in einer Verzeichnisstruktur im (lokalen) Dateisystem zusammen mit Metadaten in OMERO mit omero-py zu importieren. Die Verzeichnisnamen, in denen sich die Bilddaten befinden sollen dabei in OMERO als Projekte und Datensätze abgebildet werden. Metadaten sind in CSV-Dateien hinterlegt und sollen als Schlüssel-Wert-Paare hinterlegt werden. Die Zuordnung erfolgt über den Dateinamen.
Das Script friert während der Ausführung in unregelmäßigen Abständen ein. Das passiert teilweise innerhalb der ersten Minuten nach Ausführung oder nach mehreren Tausend importierten Bildern. Weder auf Clientseite wo das Script ausgeführt wird noch auf Serverseite sind offensichtliche Fehler in den Logs ersichtlich.
Für das Script benötigt man die Bilddaten und CSVs.
- Bilder:
- entweder großer Datensatz (~27GB): https://www.ufz.de/record/dmp/archive/11922/de/
- oder kleiner Datensatz (~4,9MB): https://nc.ufz.de/s/8WJeQT99X25eT74 Passwort:rGSbmDMj
- das Script unten kann unverändert für beide Datensätze genutzt werden
- CSVs: https://nc.ufz.de/s/zjySot8KwbyWxq9 Passwort:eic3nu3Y
Im Script müssen die Pfade DIR_CSV
(CSV-Verzeichnis) und DIR_EXTRACTED
(Bild-Verzeichnis) angepasst werden:
import omero
from getpass import getpass
from omero.gateway import BlitzGateway, DatasetWrapper
from omero.model import ProjectI,DatasetI
import glob
import numpy as np
from PIL import Image
import json
from omero.rtypes import rstring, rint
import csv
import os
import pandas
from pathlib import Path
import tifffile
DIR_CSV = '/csv'
PREFIX_CSV = 'elena-classifications-21-11-22-'
DIR_EXTRACTED='/extracted'
DEFAULT_GROUP = 'default'
DEFAULT_HOST = 'omero.intranet.ufz.de'
DEFAULT_PORT = 4064
USERNAME = input('Username: ')
PASSWORD = getpass('Password: ')
GROUP = input(f'Group ({DEFAULT_GROUP}): ') or DEFAULT_GROUP
HOST = input(f'Host ({DEFAULT_HOST}): ') or DEFAULT_HOST
PORT = input(f'Port ({DEFAULT_PORT}): ') or DEFAULT_PORT
print(f'USERNAME:{USERNAME} PASSWORD:[redacted] GROUP:{GROUP} HOST:{HOST} PORT:{PORT}')
def get_or_create_project(project):
projects = list(conn.getObjects("Project", attributes={"name": project}))
if len(projects) == 0:
project_obj = ProjectI()
project_obj.setName(omero.rtypes.rstring(project))
project_obj = conn.getUpdateService().saveAndReturnObject(project_obj, conn.SERVICE_OPTS)
else:
project_obj = projects[0]
return project_obj
def get_or_create_dataset(project_obj, dataset_name):
datasets = list(conn.getObjects("Dataset", attributes={"name": dataset_name}))
if len(datasets) == 0:
dataset_obj = DatasetI()
dataset_obj.setName(omero.rtypes.rstring(dataset_name))
dataset_obj = conn.getUpdateService().saveAndReturnObject(dataset_obj, conn.SERVICE_OPTS)
link = omero.model.ProjectDatasetLinkI()
link.setChild(omero.model.DatasetI(dataset_obj.id.val, False))
link.setParent(omero.model.ProjectI(project_obj.id, False))
conn.getUpdateService().saveObject(link)
else:
dataset_obj = datasets[0]
return dataset_obj
def plane_gen(image):
for c in range(image.shape[-1]):
yield image[:,:,c]
def import_image(tif_file, dataset_obj, dataset_name):
filename = os.path.basename(tif_file)
image = tifffile.imread(tif_file)
image_obj = conn.createImageFromNumpySeq(
plane_gen(image), filename, sizeZ=1, sizeC=image.shape[-1], sizeT=1, dataset=dataset_obj)
key_value_data = df.loc[df['dir2'] == dataset_name].loc[df['filename'] == filename][['pred1 name','pred1 probability','pred2 name','pred2 probability','pred3 name','pred3 probability']].T.reset_index().astype(str).values.tolist()
map_ann = omero.gateway.MapAnnotationWrapper(conn)
namespace = omero.constants.metadata.NSCLIENTMAPANNOTATION
map_ann.setNs(namespace)
map_ann.setValue(key_value_data)
map_ann.save()
image_obj.linkAnnotation(map_ann)
conn = BlitzGateway(USERNAME, PASSWORD, host=HOST, port=PORT, group=GROUP, secure=True)
conn.connect()
for project_name in next(os.walk(DIR_EXTRACTED))[1]:
print(f'Project: {project_name}')
file = f'{DIR_CSV}/{PREFIX_CSV}{project_name}.csv'
df = pandas.read_csv(file)
project_obj = get_or_create_project(project_name)
SUBDIR = f'{DIR_EXTRACTED}/{project_name}'
for dataset_name in next(os.walk(SUBDIR))[1]:
dataset_obj = get_or_create_dataset(project_obj, dataset_name)
tif_files = list(Path(f'{SUBDIR}/{dataset_name}').rglob('*.tif'))
i = 0
for tif_file in tif_files:
import_image(tif_file, dataset_obj, dataset_name)
i += 1
print(f'\r-> Dataset: {dataset_name} - {i} images imported...', end='', flush=True)
conn.close()
Dockerfile mit Jupyter Notebook und allen Dependencies für obiges Script:
FROM alpine:3.9
RUN apk add --no-cache sudo bash libffi-dev build-base zlib-dev jpeg-dev python3-dev openssl-dev bzip2-dev openjdk8
ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
RUN python3 -m ensurepip
RUN pip3 install --no-cache-dir --upgrade pip setuptools wheel
RUN pip3 install --no-cache-dir --global-option=build_ext --global-option="-D__USE_UNIX98" omero-py
RUN pip3 install --no-cache-dir jupyter omero-cli-duplicate pandas xlrd pillow tifffile
RUN mkdir /src
WORKDIR /src
CMD ["jupyter", "notebook", "--port=8888", "--no-browser", "--ip=0.0.0.0", "--allow-root"]
docker build -t omero-py .
docker run -p 8888:8888 -v $HOME/path/to/extracted:/extracted -v $HOME/path/to/csv:/csv omero-py
Ich habe das Blitz.log mit dem Zeitpunkt des Abbruchs hochgeladen. Es ist kein Fehler erkennbar, ggf. stimmt aber etwas mit dem Session-Management nicht.