mobie / mobie-io

BSD 2-Clause "Simplified" License
4 stars 8 forks source link

Command errored: Open Multiple Images and Labels... [ilastik .h5] #167

Open ovalerio opened 1 month ago

ovalerio commented 1 month ago

Dear MoBIE developers,

Thank you for creating this Plugin.

I learnt about it while researching about QC tools for Pixel Classification jobs in ilastik.

As you can see in the FIJI log, I tried to open my images with MoBIE:

# MoBIE
Opening images: [/gpfs/soma_fs/scratch/valerio/nmr/li-data/results_orig/chunk.*.h5, /gpfs/soma_fs/scratch/valerio/nmr/li-data/results_orig/chunk.*_Probabilities.h5]
Opening labels: []
Opening tables: []
Fetching metadata for chunk.*, channel 0
Source: /gpfs/soma_fs/scratch/valerio/nmr/li-data/results_orig/chunk0.h5

The problem is that I got an IllegalArgumentException:

[ERROR] Command errored: Open Multiple Images and Labels...
java.lang.RuntimeException: java.lang.IllegalArgumentException: provided axes doesn't match dimensionality of image
    at org.embl.mobie.io.imagedata.IlastikImageData.open(IlastikImageData.java:141)
    at org.embl.mobie.io.imagedata.IlastikImageData.getMetadata(IlastikImageData.java:106)
    at org.embl.mobie.lib.data.ImageGridSources.setMetadata(ImageGridSources.java:188)
    at org.embl.mobie.lib.data.ImageGridSources.<init>(ImageGridSources.java:91)
    at org.embl.mobie.lib.data.GridSourcesFromPathsCreator.<init>(GridSourcesFromPathsCreator.java:51)
    at org.embl.mobie.MoBIE.<init>(MoBIE.java:169)
    at org.embl.mobie.command.open.OpenMultipleImagesAndLabelsCommand.run(OpenMultipleImagesAndLabelsCommand.java:103)
    at org.scijava.command.CommandModule.run(CommandModule.java:196)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:125)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:64)
    at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:247)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.IllegalArgumentException: provided axes doesn't match dimensionality of image
    at org.embl.mobie.io.imagedata.IlastikImageData.splitIntoChannels(IlastikImageData.java:201)
    at org.embl.mobie.io.imagedata.IlastikImageData.open(IlastikImageData.java:134)
    ... 15 more
[ERROR] Command errored: Open Multiple Images and Labels...
java.lang.RuntimeException: java.lang.IllegalArgumentException: provided axes doesn't match dimensionality of image
    at org.embl.mobie.io.imagedata.IlastikImageData.open(IlastikImageData.java:141)
    at org.embl.mobie.io.imagedata.IlastikImageData.getMetadata(IlastikImageData.java:106)
    at org.embl.mobie.lib.data.ImageGridSources.setMetadata(ImageGridSources.java:188)
    at org.embl.mobie.lib.data.ImageGridSources.<init>(ImageGridSources.java:91)
    at org.embl.mobie.lib.data.GridSourcesFromPathsCreator.<init>(GridSourcesFromPathsCreator.java:51)
    at org.embl.mobie.MoBIE.<init>(MoBIE.java:169)
    at org.embl.mobie.command.open.OpenMultipleImagesAndLabelsCommand.run(OpenMultipleImagesAndLabelsCommand.java:103)
    at org.scijava.command.CommandModule.run(CommandModule.java:196)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:125)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:64)
    at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:247)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.IllegalArgumentException: provided axes doesn't match dimensionality of image
    at org.embl.mobie.io.imagedata.IlastikImageData.splitIntoChannels(IlastikImageData.java:201)
    at org.embl.mobie.io.imagedata.IlastikImageData.open(IlastikImageData.java:134)
    ... 15 more

I am using ilastik in headless mode. Here is the log for one of the substacks:

 substack data size (GB): 2.0982
 Ilastik sucessfully initialized from path: /opt/ilastik-1.4.1b20-Linux
 Number of CPU cores: 48
 Available memory: 386448.82421875 MB
 Lazyflow memory (90% of available memory): 347803 MB
 Ilastik running: LAZYFLOW_TOTAL_RAM_MB=347803 LAZYFLOW_THREADS=48 /opt/ilastik-1.4.1b20-Linux/run_ilastik.sh --headless --readonly --project=/gpfs/soma_fs/scratch/valerio/nmr/li-data/L3_Molerat_4x_v3.ilp --output_format=hdf5 --output_filename_format=/gpfs/soma_fs/scratch/valerio/nmr/li-data/results_full/chunk73_{result_type}.h5 /gpfs/soma_fs/scratch/valerio/nmr/li-data/results_full/chunk73.h5/exported_data
 Ilastik command output: INFO ilastik.app: Using tiktorch executable: ['/opt/ilastik-1.4.1b20-Linux/bin/python', '-m', 'tiktorch.server']
 Ilastik command output: INFO ilastik.app: config file location: <none>
 Ilastik command output: INFO ilastik.app: Starting ilastik from "/opt/ilastik-1.4.1b20-Linux/lib/python3.9".
 Ilastik command output: Starting ilastik from "/opt/ilastik-1.4.1b20-Linux/lib/python3.9".
 Ilastik command output: INFO ilastik.app: Resetting lazyflow thread pool with 48 threads.
 Ilastik command output: INFO ilastik.app: Configuring lazyflow RAM limit to 339.7GiB
 Ilastik command output: INFO lazyflow.utility.memory: Available memory set to 339.7GiB
 Ilastik command output: INFO ilastik.shell.projectManager: Opening Project: /gpfs/soma_fs/scratch/valerio/nmr/li-data/L3_Molerat_4x_v3.ilp
 Ilastik command output: INFO ilastik.workflows.pixelClassification.pixelClassificationWorkflow: Beginning Batch Processing
 Ilastik command output: INFO ilastik.applets.dataSelection.dataSelectionApplet: Using axistags from previous lane: [z y x, None]
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command output: INFO ilastik.applets.batchProcessing.batchProcessingApplet: Exporting to /gpfs/soma_fs/scratch/valerio/nmr/li-data/results_full/chunk73_Probabilities.h5/exported_data
 Ilastik command output: INFO lazyflow.operators.ioOperators.ioOperators.OpH5N5WriterBigDataset: Data shape: (25, 7291, 6180, 2)
 Ilastik command output: INFO lazyflow.utility.bigRequestStreamer: Estimated RAM usage per pixel is 564.0B * safety factor (2.0)
 Ilastik command output: INFO lazyflow.utility.bigRequestStreamer: determining blockshape assuming available_ram is 254.7GiB, split between 48 threads
 Ilastik command output: INFO lazyflow.utility.bigRequestStreamer: Chose blockshape: (25, 449, 450, 2)
 Ilastik command output: INFO lazyflow.utility.bigRequestStreamer: Estimated RAM usage per block is 5.3GiB
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 3.379539 seconds. Prediction took 8.65195 seconds. Subregion: start '[0, 0, 900, 0]' stop '[25, 449, 1350, 2]'
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 7.333808 seconds. Prediction took 6.592758 seconds. Subregion: start '[0, 0, 1800, 0]' stop '[25, 449, 2250, 2]'
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 6.162322 seconds. Prediction took 9.876106 seconds. Subregion: start '[0, 0, 0, 0]' stop '[25, 449, 450, 2]'
  *************************    OUTPUT LINES  REMOVED   *****************************
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 10.037568 seconds. Prediction took 3.349243 seconds. Subregion: start '[0, 6735, 4050, 0]' stop '[25, 7184, 4500, 2]'
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 11.764084 seconds. Prediction took 1.641348 seconds. Subregion: start '[0, 7184, 450, 0]' stop '[25, 7291, 900, 2]'
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 9.901315 seconds. Prediction took 3.540533 seconds. Subregion: start '[0, 6735, 4950, 0]' stop '[25, 7184, 5400, 2]'
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators: Features took 11.681749 seconds. Prediction took 1.8063630000000002 seconds. Subregion: start '[0, 6735, 5400, 0]' stop '[25, 7184, 5850, 2]'
 Ilastik command output: INFO ilastik.workflows.pixelClassification.pixelClassificationWorkflow: Completed Batch Processing
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command output: DEBUG lazyflow.operators.classifierOperators.OpBaseClassifierPredict: classifier changed, setting dirty
 Ilastik command completed successfully

Thanks in advance for your help.

k-dominik commented 1 month ago

Hi @ovalerio,

sorry that ran into issues with the ilastik output in MoBiE - it's so nice when it works...

Do you think you could share the images with us?

I hope we can resolve this quickly

Cheers Dominik

ovalerio commented 1 month ago

Hello Dominik:

Certainly. =)

In Github I am restricted to max 25 MB file upload size. Therefore, I uploaded the files here

For context, I am creating the chunk files using h5py:

import h5py
import tifffile as tff

data = tff.imread(image_sequence.files[substack['z'][0]:substack['z'][1]])

## ilastik performance optimization: convert data into h5 file  ##
chunk_name = 'chunk' + str(i)
chunksize = substack['z'][1] - substack['z'][0]
ilinp_h5 = io.join(res_dir,chunk_name +'.h5')
with h5py.File(ilinp_h5, 'w') as f:
    f.create_dataset('exported_data', data=data, dtype='uint16', chunks=(min(64, chunksize), 64, 64))

Thanks! ~ Omar

k-dominik commented 1 month ago

Hello @ovalerio,

thank you so much for providing the data, and apologies for the delayed response!

Also, your details on how you created the h5 files in the first place was super helpful! You're very close, even more of a pity it took me so long to reply :/

The reason MoBiE cannot load the data is that it is missing some attribute that helps MoBiE understand the meaning of the axes in your data.

Your data has 3 dimensions, so I assume it should be likely either "tyx" or "zyx". From the exported files I can see that you treated your data as 3D (3 spatial dimensions) ilastik. Generating the compatible metadata would entails somehting like this:

import h5py
# optional, in case you don't mind adding this dependency
import vigra

# then open your h5 file
with h5py.File("chunk0.h5", "a") as f:
    f["exported_data"].attrs["axistags"] = vigra.defaultAxistags("zyx").toJSON()

# if you don't want to use vigra, so also no need to import at the beginning,
# no problem, you would alternatively do:

axistags = """
{
  "axes": [
    {
      "key": "z",
      "typeFlags": 2,
      "resolution": 0,
      "description": ""
    },
    {
      "key": "y",
      "typeFlags": 2,
      "resolution": 0,
      "description": ""
    },
    {
      "key": "x",
      "typeFlags": 2,
      "resolution": 0,
      "description": ""
    }
  ]
}
"""
with h5py.File("chunk0.h5", "a") as f:
    f["exported_data"].attrs["axistags"] = axistags

# for the rest of the input files, you'd do the same. The exported probabilities have this metadata attached.

also, reference to our jupyter notebook for h5 conversion: https://github.com/ilastik/ilastik/blob/main/notebooks/h5convert/convert_to_h5.ipynb

Hope this helps. And please if you have any further questions, let me know.

Cheers Dominik

ovalerio commented 1 month ago

Hello Dominik,

Thank you. That was the solution. I am now able to open the h5 images using MoBIE. :rocket: :+1: image

I am getting an error in the log.
Before that error the log show messages about two missing files. (keymaps.yaml, appearance.yaml)

[Fri Oct 04 09:41:47 UTC 2024] [ERROR] [] Command errored: Open Multiple Images and Labels...
java.lang.NullPointerException
    at org.embl.mobie.lib.bdv.ImageNameOverlay.addImage(ImageNameOverlay.java:168)
    at org.embl.mobie.lib.bdv.ImageNameOverlay.updateImages(ImageNameOverlay.java:162)
    at org.embl.mobie.lib.bdv.ImageNameOverlay.setActive(ImageNameOverlay.java:111)
    at org.embl.mobie.lib.view.ViewManager.show(ViewManager.java:309)
    at org.embl.mobie.MoBIE.initUiAndShowView(MoBIE.java:288)
    at org.embl.mobie.MoBIE.openImageAndLabelGrids(MoBIE.java:231)
    at org.embl.mobie.MoBIE.<init>(MoBIE.java:175)
    at org.embl.mobie.command.open.OpenMultipleImagesAndLabelsCommand.run(OpenMultipleImagesAndLabelsCommand.java:103)
    at org.scijava.command.CommandModule.run(CommandModule.java:196)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:125)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:64)
    at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:247)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)

I wonder if it can be fixed because it seems to slowdown the MoBIE viewer. This is the version of ImageJ I am currently running:

(Fiji Is Just) ImageJ 2.14.0/1.54f; Java 1.8.0_322 [64-bit]; Linux 3.10.0-1160.el7.x86_64; 5728MB of 130953MB (4%)

For completeness I was running ImageJ as a superuser (root). I needed that to perform the plugin updates.

Best, Omar

tischi commented 1 month ago

Hi @ovalerio,

Could you please share the files and how you exactly open them in MoBIE such that we can try reproducing this error?

Thanks!