Skip to content

KeyError: 'None' error while using warp_and_save_slide to save ome.tiff #78

@arundasan91

Description

@arundasan91

Hello,

I am using Valis '1.0.2' from the Docker Image to register two single-channel ome.tiff files using the following code. However, I get a KeyError: 'None' error when I attempt to warp and save the image using the warp_and_save_slide method. Could you please help? I'm happy to share/answer any environment or code-related questions.

from tifffile import imread
import valis

from valis import registration, valtils
import numpy as np

import sys
import os
import shutil


in_image_path = '/data/image_quadrants/membrane_quadrant1.ome.tiff'
out_folder = '/data/valis_pipeline_out/'
reference_img_fname = 'DAPI_quadrant1.ome.tiff' 
image_px = 2000
micro_px = 3000
rigid = True
save = True
verbose = True

in_folder = os.path.dirname(in_image_path) # "/Users/arundas/images/membrane.ome.tiff" --> /Users/arundas/images/
in_file = os.path.basename(in_image_path) # membrane.ome.tiff

img_list = [os.path.join(in_folder, reference_img_fname), 
            in_image_path]

# Define parameters for registration using the 'Valis' class
registrar = registration.Valis(
    in_folder,
    out_path,
    reference_img_f=reference_img_fname,
    crop='reference',
    img_list=img_list,
    imgs_ordered=True,
    align_to_reference=True,
    max_processed_image_dim_px=image_px
)

# Perform rigid registration
rigid_registrar, non_rigid_registrar, error_df = registrar.register()

if verbose:
    print('==== Rigid Registration Error')

    # Split and print error data into multiple columns
    num = 4
    delta = len(error_df.columns) // num
    for _num in range(num-1):
        print(error_df[error_df.columns[_num*delta:(_num+1)*delta]])

# Perform micro-registration on higher resolution images, aligning directly to the reference image
non_regid_registrar, error_df = registrar.register_micro(
    reference_img_f=reference_img_fname,
    align_to_reference=True,
    max_non_rigid_registartion_dim_px=micro_px
)

if verbose:
    print('==== Micro-Registration Error')
    num = 4
    delta = len(error_df.columns) // num
    for _num in range(num-1):
        print(error_df[error_df.columns[_num*delta:(_num+1)*delta]])
    print(error_df[error_df.columns[(num-1)*delta:]])

# Save all slides as ome.tiff
# If the non-rigid registration is deemed to have distorted the image too much,
# apply only the rigid transformation by setting non_rigid=False
if save:
    print('==== Saving ome.tiff file; Rigid:', rigid)

    # Save all slides
    # registrar.warp_and_save_slides(
    #     out_path,
    #     level=0,
    #     non_rigid=not args.rigid,
    #     crop=True,
    #     interp_method="bicubic",
    #     tile_wh=1024,
    #     compression="lzw",
    # )

    ch_name_f = valtils.get_name(in_image_path)
    ch_name_list = ch_name_f.split(" ")

    print(ch_name_list)



    # Save the object slide
    slide_f = os.path.splitext(in_file)[0]
    slide_obj = registrar.get_slide(slide_f)
    
    slide_obj.warp_and_save_slide(
        out_path,
        tile_wh=1024,
        level=0
        # compression="lzw",
        # channel_names = ["Channel:0"]
    )

    # slide_obj.warp_and_save_slide(
    #     out_path,
    #     level=0,
    #     non_rigid=not rigid,
    #     crop=True,
    #     src_f=None,
    #     channel_names=ch_name_list,
    #     colormap=None,
    #     interp_method="bicubic",
    #     tile_wh=1024,
    #     compression="lzw"
    # )

# Kill the JVM (Java Virtual Machine)
registration.kill_jvm()  # Make sure the 'registration' module has a 'kill_jvm' function

This is the error:


Start Image Registration...
/usr/local/src/valis/valtils.py:22: UserWarning: max_image_dim_px is 850 but needs to be less or equal to 2000. Setting max_image_dim_px to 2000
  warnings.warn(warning_msg, warning_type)

==== Converting images

Converting images:   0%|                                                                                           | 0/2 [00:00<?, ?image/s]
JVM has been initialized. Be sure to call registration.kill_jvm() or slide_io.kill_jvm() at the end of your script.
Converting images: 100%|███████████████████████████████████████████████████████████████████████████████████| 2/2 [01:53<00:00, 56.97s/image]

==== Processing images

Processing images : 100%|██████████████████████████████████████████████████████████████████████████████████| 2/2 [00:24<00:00, 12.35s/image]
Normalizing images: 100%|██████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.81image/s]
Denoising images  : 100%|██████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.27image/s]

==== Rigid registration

Detecting features   : 100%|███████████████████████████████████████████████████████████████████████████████| 2/2 [00:22<00:00, 11.14s/image]
Finding transforms   : 100%|██████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 707.06image/s]
Finalizing           : 100%|█████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 7981.55image/s]

======== Rigid registration complete in 32.441 seconds


==== Non-rigid registration

Preparing images for non-rigid registration: 100%|█████████████████████████████████████████████████████████| 2/2 [00:37<00:00, 18.73s/image]
Finding non-rigid transforms: 100%|████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.04image/s]

======== Non-rigid registration complete in 2.591 seconds

/usr/local/src/.venv/lib/python3.10/site-packages/interpolation/splines/eval_splines.py:318: NumbaPendingDeprecationWarning: Code using Numba extension API maybe depending on 'old_style' error-capturing, which is deprecated and will be replaced by 'new_style' in a future release. See details at https://numba.readthedocs.io/en/latest/reference/deprecation.html#deprecation-of-old-style-numba-captured-errors
Exception origin:
  File "/usr/local/src/.venv/lib/python3.10/site-packages/interpolation/splines/eval_splines.py", line 116, in __eval_spline
    kk = (order).literal_value

  return _eval_cubic(*args)

==== Measuring error

Measuring error: 100%|█████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00,  3.80image/s]
==== Rigid Registration Error
                                            filename                from  \
0      /data/image_quadrants/DAPI_quadrant1.ome.tiff      DAPI_quadrant1   
1  /data/image_quadrants/membrane_quadrant1.ome.tiff  membrane_quadrant1   

               to  original_D  original_rTRE  
0            None         NaN            NaN  
1  DAPI_quadrant1    0.049755       0.001782  
    rigid_D  rigid_rTRE  non_rigid_D  non_rigid_rTRE processed_img_shape
0       NaN         NaN          NaN             NaN        (2000, 1949)
1  0.027923       0.001     0.028261        0.001012        (2000, 1949)
            shape   aligned_shape  mean_original_D  mean_rigid_D  \
0  (21657, 21101)  (21668, 21112)         0.049755      0.027923   
1  (21657, 21101)  (21668, 21112)         0.049755      0.027923   

  physical_units  
0             µm  
1             µm  
/usr/local/src/valis/valtils.py:22: DeprecationWarning: max_non_rigid_registartion_dim_px is deprecated; use max_non_rigid_registration_dim_px instead
  warnings.warn(warning_msg, warning_type)
Preparing images for non-rigid registration: 100%|█████████████████████████████████████████████████████████| 2/2 [00:39<00:00, 19.53s/image]

==== Performing microregistration

Finding non-rigid transforms: 100%|████████████████████████████████████████████████████████████████████████| 2/2 [00:23<00:00, 11.66s/image]

======== Non-rigid registration complete in 24.765 seconds


==== Measuring error

Measuring error: 100%|█████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.62image/s]
==== Micro-Registration Error
                                            filename                from  \
0      /data/image_quadrants/DAPI_quadrant1.ome.tiff      DAPI_quadrant1   
1  /data/image_quadrants/membrane_quadrant1.ome.tiff  membrane_quadrant1   

               to  original_D  original_rTRE  
0            None         NaN            NaN  
1  DAPI_quadrant1    0.049755       0.001782  
    rigid_D  rigid_rTRE  non_rigid_D  non_rigid_rTRE processed_img_shape
0       NaN         NaN          NaN             NaN        (2000, 1949)
1  0.027923       0.001     0.024455        0.000876        (2000, 1949)
            shape   aligned_shape  mean_original_D  mean_rigid_D  \
0  (21657, 21101)  (21668, 21112)         0.049755      0.027923   
1  (21657, 21101)  (21668, 21112)         0.049755      0.027923   

  physical_units  
0             µm  
1             µm  
   resolution             name  rigid_time_minutes  mean_non_rigid_D  \
0        0.01  image_quadrants            2.897114          0.024455   
1        0.01  image_quadrants            2.897114          0.024455   

   non_rigid_time_minutes  
0                3.775857  
1                3.775857  


==== Saving ome.tiff file; Rigid: True
['membrane_quadrant1']
/usr/local/src/valis/slide_tools.py:330: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.
  all_colors =  cm.get_cmap(name)(np.linspace(0, 1, n))[..., 0:3]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[25], line 29
     26     slide_f = os.path.splitext(in_file)[0]
     27     slide_obj = registrar.get_slide(slide_f)
---> 29     slide_obj.warp_and_save_slide(
     30         out_path,
     31         tile_wh=1024,
     32         level=0
     33         # compression="lzw",
     34         # channel_names = ["Channel:0"]
     35     )
     37     # slide_obj.warp_and_save_slide(
     38     #     out_path,
     39     #     level=0,
   (...)
     56 #     reference_img_fname = 'DAPI_quadrant1.ome.tiff', 
     57 #     )

File /usr/local/src/valis/valtils.py:30, in deprecated_args.<locals>.deco.<locals>.wrapper(*args, **kwargs)
     27 @functools.wraps(f)
     28 def wrapper(*args, **kwargs):
     29     rename_kwargs(f.__name__, kwargs, aliases)
---> 30     return f(*args, **kwargs)

File /usr/local/src/valis/registration.py:1004, in Slide.warp_and_save_slide(self, dst_f, level, non_rigid, crop, src_f, channel_names, colormap, interp_method, tile_wh, compression, Q)
   1002 bf_dtype = slide_io.vips2bf_dtype(warped_slide.format)
   1003 out_xyczt = slide_io.get_shape_xyzct((warped_slide.width, warped_slide.height), warped_slide.bands)
-> 1004 ome_xml_obj = slide_io.update_xml_for_new_img(current_ome_xml_str=slide_meta.original_xml,
   1005                                               new_xyzct=out_xyczt,
   1006                                               bf_dtype=bf_dtype,
   1007                                               is_rgb=self.is_rgb,
   1008                                               series=self.series,
   1009                                               pixel_physical_size_xyu=px_phys_size,
   1010                                               channel_names=channel_names,
   1011                                               colormap=colormap
   1012                                               )
   1014 ome_xml = ome_xml_obj.to_xml()
   1015 if tile_wh is None:

File /usr/local/src/valis/valtils.py:30, in deprecated_args.<locals>.deco.<locals>.wrapper(*args, **kwargs)
     27 @functools.wraps(f)
     28 def wrapper(*args, **kwargs):
     29     rename_kwargs(f.__name__, kwargs, aliases)
---> 30     return f(*args, **kwargs)

File /usr/local/src/valis/slide_io.py:2692, in update_xml_for_new_img(current_ome_xml_str, new_xyzct, bf_dtype, is_rgb, series, pixel_physical_size_xyu, channel_names, colormap)
   2689 else:
   2690     og_valid_xml = False
-> 2692 temp_new_ome = create_ome_xml(new_xyzct, bf_dtype, is_rgb, pixel_physical_size_xyu, channel_names, colormap=colormap)
   2694 if og_valid_xml:
   2695     new_ome = og_ome.copy()

File /usr/local/src/valis/valtils.py:30, in deprecated_args.<locals>.deco.<locals>.wrapper(*args, **kwargs)
     27 @functools.wraps(f)
     28 def wrapper(*args, **kwargs):
     29     rename_kwargs(f.__name__, kwargs, aliases)
---> 30     return f(*args, **kwargs)

File /usr/local/src/valis/slide_io.py:2616, in create_ome_xml(shape_xyzct, bf_dtype, is_rgb, pixel_physical_size_xyu, channel_names, colormap)
   2613     else:
   2614         colormap = default_colormap
-> 2616     channels = [create_channel(i, name=channel_names[i], color=colormap[channel_names[i]]) for i in range(c)]
   2617     new_img.pixels.channels = channels
   2619 new_ome = ome_types.model.OME()

File /usr/local/src/valis/slide_io.py:2616, in <listcomp>(.0)
   2613     else:
   2614         colormap = default_colormap
-> 2616     channels = [create_channel(i, name=channel_names[i], color=colormap[channel_names[i]]) for i in range(c)]
   2617     new_img.pixels.channels = channels
   2619 new_ome = ome_types.model.OME()

KeyError: 'None'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions