MathOnco / valis

Virtual Alignment of pathoLogy Image Series
https://valis.readthedocs.io/en/latest/
MIT License
124 stars 29 forks source link

Don't see stacked images saved as OME-TIFF #169

Closed WillYe45 closed 5 days ago

WillYe45 commented 1 week ago

Hi, I have been running the pipeline several times for alignment, however, after running, I only see my original input svs files being converted to OME-TIFF format, but I do not see the stacked images. The pipeline did output the thumbnails of those stacked images, and I am wondering if there is something wrong with my code. My code looks like this:

Load the necessary environment

eval "$(/path/to/miniconda/bin/conda shell.bash hook)" source activate Valis

Define input and output directories

slide_src_dir="/path/to/slides" results_dst_dir="/path/to/output/results" registered_slide_dst_dir="/path/to/output/registered_slides"

Ensure output directories exist

[ ! -d "$results_dst_dir" ] && mkdir -p "$results_dst_dir" [ ! -d "$registered_slide_dst_dir" ] && mkdir -p "$registered_slide_dst_dir"

Run the Valis alignment

python -c ' from valis import registration

Reference slide

reference_slide = "reference_slide_name.svs"

Initialize registration

registrar = registration.Valis( "'"$slide_src_dir"'", "'"$results_dst_dir"'", reference_img_f=reference_slide, max_processed_image_dim_px=300 )

Perform registration

print("Running registration...") rigid_registrar, non_rigid_registrar, error_df = registrar.register() registrar.register_micro(max_non_rigid_registration_dim_px=2000, align_to_reference=True)

Warp and save slides

print("Warping and saving slides...") registrar.warp_and_save_slides("'"$registered_slide_dst_dir"'", crop="overlap")

Kill the JVM

registration.kill_jvm() ' I would greatly appreciate any help, thank you in advance.

cdgatenbee commented 6 days ago

Hi @WillYe45, The code looks correct, as registrar.warp_and_save_slides should save each registered image as an ome.tiff (one per svs). But could you please clarify your question for me? Is the issue that the saved ome.tiffs look the same as the original svs, as if they are not being warped? Or, is that that only one of the svs images is being saved? Or, finally, were you expecting that there would be a single ome.tiff that contains all of the aligned images, each as a "series"?

Best, -Chandler

WillYe45 commented 6 days ago

Hi Chandler,

my question was that for example, I have 3 original images in svs format, and after the pipeline, I also see 4 thumb nail pictures in the /overlaps folder. However, in the registered slide folder, I only see those 3 original images saved as ome-tiff format, without the overlapped images. I am wondering if this pipeline is also supposed to save those aligned images as ome-tiff for downstream analysis? It is hard to work on the thumbnails as they are low resolution png files.

Best, Will

cdgatenbee commented 6 days ago

Hi @WillYe45,

Unfortunately, valis doesn't save those overlap images at full resolution. They're mainly intended to provide a sense of how well the registration worked. To get a more quantitative estimate of registration quality, you can also examine the "summary.csv" file located in the "data" directory, with the registration error in the "non_rigid_D" column. These estimates are based on the average distance between the matched features used for rigid registration. However, as the features are detected on lower resolution images (based on your code, the maximum width or height of these images would be 300 pixels), these values to tend to overestimate the error (see 2nd plot in the ACROBAT section of the Datasets page). The ome.tiffs contain the full resolution registered images though, so you shouldn't need to work with the thumbnails. Having said all that, it is possible to create a full resolution version of that overlap image, one where each channel is a grayscale version of the images used for alignment. If that's something you're interested in, let me know and I can put some code together.

Best, -Chandler

WillYe45 commented 5 days ago

Hi Chandler,

Thank you very much for the information. The downstream analysis of my experiment would probably require those pictures remain in RGB rather than greyscale, so I will try to investigate this further using alternative methods. I really appreciate your help!

Best, Will

cdgatenbee commented 5 days ago

Hi @WillYe45,

Not sure if it will quite suite your needs, but I did want to mention that if you need a somewhat larger version of the overlap image, you can increase the size of the thumbnail images by setting the thumbnail_size argument when you initialize the Valis object, like this:

registrar = registration.Valis(src_dir, dst_dir, thumbnail_size=2048)
rigid_registrar, non_rigid_registrar, error_df = registrar.register()

If you want the full resolution RGB overlap image as an ome.tiff, that is also possible using the following save_overlap_full_rez function:


def save_overlap_full_rez(registrar, dst_f):
    warped_slide_list = [registrar.get_slide(f).warp_slide(level=0).colourspace(pyvips.enums.Interpretation.B_W).invert() for f in registrar.get_sorted_img_f_list()]
    full_rez_overlap = viz.create_overlap_img(warped_slide_list, blending="light")
    ref_slide = registrar.get_ref_slide()
    pixel_physical_size_xyu = ref_slide.reader.metadata.pixel_physical_size_xyu
    img_h, img_w, img_c = warp_tools.get_shape(full_rez_overlap)
    shape_xyzct = slide_io.get_shape_xyzct((img_w, img_h), img_c)
    bf_dtype = slide_io.vips2bf_dtype(full_rez_overlap.format)

    ome_obj = slide_io.create_ome_xml(shape_xyzct, bf_dtype, is_rgb=True, pixel_physical_size_xyu=pixel_physical_size_xyu)
    ome_xml = ome_obj.to_xml()

    slide_io.save_ome_tiff(full_rez_overlap, dst_f=dst_f, ome_xml=ome_xml, compression="jpeg")

registrar = registration.Valis(src_dir, dst_dir)
rigid_registrar, non_rigid_registrar, error_df = registrar.register()
save_overlap_full_rez(registrar, "full_rez_overlap.ome.tiff") 

It will look a little different than what is in the overlaps folder, since those are based on the processed images, but should be similar. When I use the above function on the IHC example dataset, I get an ome.tiff that looks like this in QuPath

full_rez_overlap_screenshot

Hopefully that will work for you, but if not, please let me know.

Best,

-Chandler