11import hashlib
22import os
33import warnings
4- from shutil import copyfileobj , rmtree
4+ from shutil import copyfileobj
55
66import numpy as np
77import requests
88import torch
99import vigra
1010import zarr
1111
12- from PyQt5 import QtCore , QtWidgets
1312from elf .io import open_file
1413from nifty .tools import blocking
1514from skimage .measure import regionprops
@@ -316,54 +315,12 @@ def _precompute_3d(input_, predictor, save_path, lazy_loading, tile_shape=None,
316315 }
317316 return image_embeddings
318317
319- def show_wrong_file_warning (file_path ):
320- """If the data signature does not match to the signature, user will can choose from the following options in this dialog:
321- - Ignore: continue with input file (return file_path).
322- - Overwrite: delete file_path and recompute the embeddings at same location.
323- - Select a different file
324- - Select a new file
325-
326- Arguments:
327- file_path (string or os.path): path of the problematic file
328-
329- Returns:
330- string or os.path: path to a file (new or old) depending on user decision
331- """
332- msgbox = QtWidgets .QMessageBox ()
333- msgbox .setWindowFlags (QtCore .Qt .CustomizeWindowHint | QtCore .Qt .WindowTitleHint )
334- msgbox .setWindowTitle ("Warning" )
335- msgbox .setText ('The input data does not match the embeddings file.' )
336- ignore_btn = msgbox .addButton ("Ignore" , QtWidgets .QMessageBox .RejectRole )
337- overwrite_btn = msgbox .addButton ("Overwrite file" , QtWidgets .QMessageBox .DestructiveRole )
338- select_btn = msgbox .addButton ("Select different file" ,QtWidgets .QMessageBox .AcceptRole )
339- create_btn = msgbox .addButton ("Create new file" ,QtWidgets .QMessageBox .AcceptRole )
340- msgbox .setDefaultButton (create_btn )
341-
342- msgbox .exec ()
343- msgbox .clickedButton ()
344- if msgbox .clickedButton () == ignore_btn :
345- return file_path
346- elif msgbox .clickedButton () == overwrite_btn :
347- rmtree (file_path )
348- return file_path
349- elif msgbox .clickedButton () == create_btn :
350- # unfortunately there exists no dialog to create a directory so we have to use "create new file" dialog with some adjustments.
351- dialog = QtWidgets .QFileDialog (None )
352- dialog .setFileMode (QtWidgets .QFileDialog .AnyFile )
353- dialog .setOption (QtWidgets .QFileDialog .ShowDirsOnly )
354- dialog .setNameFilter ("Archives (*.zarr)" )
355- new_path = ""
356- while os .path .splitext (new_path )[1 ] != ".zarr" :
357- dialog .exec ()
358- new_path = dialog .selectedFiles ()[0 ]
359- os .makedirs (new_path )
360- return (new_path )
361- elif msgbox .clickedButton () == select_btn :
362- return QtWidgets .QFileDialog .getExistingDirectory (None , "Open a folder" , os .path .split (file_path )[0 ], QtWidgets .QFileDialog .ShowDirsOnly )
363-
364318
365319def precompute_image_embeddings (
366- predictor , input_ , save_path = None , lazy_loading = False , ndim = None , tile_shape = None , halo = None
320+ predictor , input_ ,
321+ save_path = None , lazy_loading = False ,
322+ ndim = None , tile_shape = None , halo = None ,
323+ wrong_file_callback = None ,
367324):
368325 """Compute the image embeddings (output of the encoder) for the input.
369326
@@ -380,23 +337,31 @@ def precompute_image_embeddings(
380337 tile_shape [tuple] - shape of tiles for tiled prediction.
381338 By default prediction is run without tiling. (default: None)
382339 halo [tuple] - additional overlap of the tiles for tiled prediction. (default: None)
340+ wrong_file_callback [callable] - function to call when an embedding file with wrong file signature
341+ is passed. If none is given a wrong file signature will cause a warning.
342+ If passed, the callback should have the signature 'def callback(save_path): return str',
343+ where the return value is the (potentially updated) embedding save path (default: None)
383344 """
384345 ndim = input_ .ndim if ndim is None else ndim
385346 if tile_shape is not None :
386347 assert save_path is not None , "Tiled prediction is only supported when the embeddings are saved to file."
387-
348+
388349 if save_path is not None :
389350 data_signature = hashlib .sha1 (input_ .tobytes ()).hexdigest ()
390-
351+
391352 f = zarr .open (save_path , "a" )
392- if "input_size" in f .attrs :
353+ if "input_size" in f .attrs : # we have computed the embeddings already
354+
355+ # data signature does not match or is not in the file
393356 if "data_signature" not in f .attrs or f .attrs ["data_signature" ] != data_signature :
394- warnings .warn ("Embeddings file is invalid. Please recompute embeddings to new file." )
395- save_path = show_wrong_file_warning (save_path )
357+ warnings .warn ("Embeddings file is invalid. Please recompute embeddings in a new file." )
358+ if wrong_file_callback is not None :
359+ save_path = wrong_file_callback (save_path )
396360 f = zarr .open (save_path , "a" )
397361 if "data_signature" not in f .attrs :
398- f .attrs ["data_signature" ] = data_signature
399- else :
362+ f .attrs ["data_signature" ] = data_signature
363+
364+ else : # embeddings have not yet been computed
400365 f .attrs ["data_signature" ] = data_signature
401366
402367 if ndim == 2 :
0 commit comments