labsyspharm / quantification

Quantification module for mcmicro
https://github.com/labsyspharm/mcmicro
9 stars 13 forks source link

Add spot counting #20

Open DenisSch opened 4 years ago

DenisSch commented 4 years ago

https://github.com/labsyspharm/mcmicro-nf/issues/126

DenisSch commented 4 years ago

@clarenceyapp Are the spots are already binary at this point? Should we specify which position they are? Something like: If RNA in the marker.csv perform spot detection?

clarenceyapp commented 4 years ago

@DenisSch the spots will be like a binary mask. Instead of all spots having a value of '1', they will have an intensity that corresponds to the cell it belongs to so you can loop through them. It will be called punctaMask.tif. Can we specify which channels we want to count spots in --quantification-opts?

DenisSch commented 4 years ago

@clarenceyapp Why not keeping the spots binary (0/1) and we count them in the quantification step. This way you could redo segmentation and still use the same tiff file?

clarenceyapp commented 4 years ago

If you think it's easier in binary, you can just binarize the spot mask (punctaMask>0) . I thought it was going to be easier for you if they are labelled. The spot detection is affected by segmentation quality such as the spots near the cell membrane, so if segmentation has to be redone, it's better to just detect new spots again

FloWuenne commented 2 years ago

Hi @clarenceyapp,

I would like to add RS-FISH as a module for spot counting. I have a Docker container that runs without issues locally at the moment, which for now simply counts spots without assigning them to cells or nuclei.

Since the walkthroughs at Adding Modules only mention segmentation and cell state caller modules, I was wondering how I should go about adding a quantification module that performs spot counting.

Thanks for the help and suggestions!

DenisSch commented 2 years ago

Dear Florian,

We should be able to modify the quantification module in a way that would allow us to count spots. What exactly is the output of the RS-FISH module?

On Wed 9. Feb 2022 at 09:20, Florian Wuennemann @.***> wrote:

Hi @clarenceyapp https://github.com/clarenceyapp,

I would like to add RS-FISH https://github.com/PreibischLab/RS-FISH as a module for spot counting. I have a Docker container that runs without issues locally at the moment, which for now simply counts spots without assigning them to cells or nuclei.

Since the walkthroughs at Adding Modules https://mcmicro.org/tutorials/adding.html only mention segmentation and cell state caller modules, I was wondering how I should go about adding a quantification module that performs spot counting.

Thanks for the help and suggestions!

— Reply to this email directly, view it on GitHub https://github.com/labsyspharm/quantification/issues/20#issuecomment-1033534616, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABVPRBJANPNKNSVBC262HY3U2IWT7ANCNFSM4M4LPGTA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

FloWuenne commented 2 years ago

The output of the standard RS-FISH implementation is a .csv file containing the following measures: x and y positions, channel, time and intensity per detected spot.

x,y,t,c,intensity
358.6463,381.4636,1,1,885.8648
368.0854,382.5119,1,1,944.9607

I tried running this with an .ome.tiff file from the registration step of MCMICRO and it seems to currently fail if there are multiple channels in the same image. I have opened an issue on the RS-FISH repo to ask the authors for their thoughts on mutli-channel support : https://github.com/PreibischLab/RS-FISH/issues/8

So currently, we would have to split images into single-channel .tifs before processing with RS-FISH.

clarenceyapp commented 2 years ago

Hi @FloWuenne and @DenisSch We actually already have spot detection in S3segmenter starting 2 years ago that we are using for RNAscope in heart tissue. Please see section 6 here: https://mcmicro.org/tuning/s3seg.html The output is a csv file with number of spots PER cell PER channel. You would not need to separate into single-channel tifs using this. You just want the number of spots, right? Do you need the coordinates and intensities at the moment? It would be easy to add these using regionprops for each cell or the whole image.

@ArtemSokolov can comment on how to add modules to MCMICRO. I know I said 'adding modules is easy' in the tutorial video, but I defer this action to him.

Clarence

FloWuenne commented 2 years ago

@clarenceyapp

Thanks for letting me know about the spot detection in S3segmenter. One of the reasons I used RS-FISH was, that for some images, we don't have good cell segmentations, only nuclear segmentations and we wanted to get all x-y positions for spots instead of only those inside segmented cells.

I will see what @ArtemSokolov has to say about adding spot counting modules and whether it would still be interesting to add RS-FISH as an alternative or not.

clarenceyapp commented 2 years ago

@FloWuenne if you want total spot count, you could feed in a mask image that spans the entire image instead of a cell mask into s3segmenter. That would be an image that is all white with a value of '1' so that the entire image is treated as a 'cell'. I have to confirm that this is possible. Use the --nucleiRegion bypass parameter to let s3segmenter know you are feeding your own mask in instead of computing it.

One issue of not using cell masks that I've encountered is that any debris from non-cell objects will give false positive spots even across different spot detection modules. The cell segmentation masks can help reduce false positives from the background. What cell segmentation method are you currently using? Maybe that can be improved.

Clarence

FloWuenne commented 2 years ago

So far I had tried the Mesmser module and unmicst for segmentation. Mesmer was working for nuclear segmentation out of the box, haven't tried whole cell segmentation inside MCMICRO with it yet. Using Mesmer outside MCMICRO with other RNASCOPE channels as membrane channels did not give good cell segmentation results though.

For Unmicst, I haven't been able to get good cell segmentation (or even nuclei) results so far, as I think I have to adjust settings a bit for the confocal images we are dealing with. I just experimented a bit and realized that I probably have to crank up the scaling factor quite a bit. (Our image is 0.1 micron pixel and the default scaling factor is for 0.65 micron pixel, so I guess I should use a --unmicst-opts '--scalingFactor 3 ? Once I get good nuclear segmentation with unmicst, the plan was to use --cytoMethod ring to try and get reasonable cell segmentations.

I launched that job a while ago but it seems to take quite some time due to the upscaling?

Thanks for all the advise and help @clarenceyapp !

clarenceyapp commented 2 years ago

No problem, @FloWuenne Just to clarify, UnMicst will need --scalingFactor 6. Because of the significant mismatch of pixel sizes and drop in photon sensitivity on a confocal microscope, UnMicst will never give good results under those conditions and it will take forever without GPU. The training data is all from widefield microscopy. As a solution on a previous project, I trained a cytoplasm detector called Cypository (result can be found in section 5 ). This is trained on a confocal at similar pixel size to what you used (I think we used a Zeiss confocal?). The experiment requires a membrane marker though which we used wheat germ agglutin in combination with the RNAscope probes. We took out Hoechst nuclei staining because we didn't need it for segmentation/quantification and some cells didn't stain for it anyway. If you have good blue emitting dyes, that channel is actually better for resolving densely packed spots since resolution will be better.

Let me know if you want to try Cypository out.

Clarence

ArtemSokolov commented 2 years ago

Hi @FloWuenne,

What does RS-FISH require as input? From the above discussion, it sounds like it works independent of cell segmentation, so I assume that a segmentation mask is not one of its inputs. Is it just the original .ome.tif + some parameters?

If that's the case, then maybe quantification is not the right step for it. We have been discussing adding a new pipeline step for modules that work directly on pixel-level data. Modules that don't require a segmentation mask can then run in parallel to cell/nuclei segmenters. We could structure this pipeline step the same way we did with segmenters and cell type callers, which would allow users to specify any Docker container that works directly with the input .ome.tif in a configuration file.

Thoughts?

FloWuenne commented 2 years ago

Hi @ArtemSokolov

you are absolutely right, RS-FISH works directly on a single channel .ome.tiff image and doesnt require a segmentation mask. Assignment of spots to nuclei, cells or anything else with a mask would be done afterward.

So because RS-FISH currently only takes single channel images, my suggestion would be to run a first step splitting the .ome.tiff into the single channel images defined by the user (default all channels) and then run RS-FISH on each single channel image, returning one .csv file per channel. This could change if the authors enable multi-channel support. We would then have to add another step for spot assignment. That is actually how the authors of RS-FISH have incorporated their tool into their multifish pipeline (https://github.com/JaneliaSciComp/multifish), which aims to solve a similar goal to MCMICRO. (Here is a schematic of their workflow : https://github.com/JaneliaSciComp/multifish/blob/master/docs/images/pipeline_diagram.png). I guess it might even be possible to simply port their containers to MCMICRO, since they are using nextflow as well.

How does all that sound?

ArtemSokolov commented 2 years ago

Thanks for the pointers, @FloWuenne. I'll have to poke around and see how they are splitting the image. There is a non-trivial amount of "fluff" for a simple operation like that (command-line interface, containerization, Nextflow wrapper), if this not handled by an existing container.

FloWuenne commented 2 years ago

Thanks @ArtemSokolov !

I have created a working docker container image based on a maven/jdk build that is on dockerhub: https://hub.docker.com/repository/docker/wuennemannflorian/rs_fish

docker pull wuennemannflorian/rs_fish:2.3.1
docker run  wuennemannflorian/rs_fish:2.3.1 /RS-FISH/rs-fish

This works locally for me to call spots on a single-channel .tif image. I used bfconvert prior to running RS-FISH to split multi-channel images to single-channels that I wanted to process. The main parameters to use with RS-FISH would be --threshold and --sigma to determine intensity thresholds and spot size.

Let me know if you think it makes sense to include RS-FISH as a module and if I can help with the nextflow part or anything else!

ArtemSokolov commented 2 years ago

Hi @FloWuenne,

Sorry for the slow response. We are all in the middle of an image analysis hackathon this week.

Would you be able to share a small example image that you would apply rs-fish to?

My other thought is whether we could install bfconvert inside your container. This would allow us to extract a single-channel image directly in the same execution environment, which would simplify the encompassing workflow.

FloWuenne commented 1 year ago

@ArtemSokolov I believe this issue can be closed with the latest PR #43 that added intensity_sum(), effectively allowing for summing of spots across masks.

ArtemSokolov commented 1 year ago

@clarenceyapp Can you please verify that intensity_sum() is sufficient? I seem to remember that the original intention was to count spots per cell.

FloWuenne commented 1 year ago

@clarenceyapp Just pinging here again to check if intensity_sum() adds the desired functionality.

Also, I would suggest we add an option to only get desired props and not always force mean intensity (as one doesn't much care about mean intensity in FISH count situations).