Ashlar: how to pass multiple images to be stitched?

Hi all! I am trying to figure out ASHLAR for stitching images together, but I am stuck at what input it accepts.

From the few lines of description on the CyCIF page, I read that:

ASHLAR uses Bioformats software to read virtually any microscope image files and write the OME-TIFF format files.

and from the help of the command itself I get:

[...]
Stitch and align one or more multi-series images

positional arguments:
  FILE                  an image file to be processed (one file per cycle)
[...]

I am not practical with imaging formats, what I have is a set of individual TIFF files, one file per tile per channel, and I can’t figure out how to pass them to Ashlar to be stitched. I assume I’ll need to convert them into a single object of some type?

Thanks in advance for the help

Hi Stefano, sorry for the lack of documentation – we’re working on it! What kind of microscope and software are you using? The preferred Ashlar input format is whatever your microscope produces natively, as we can directly read useful metadata such as stage positions for each tile and the pixel size rather than requiring you to specify that stuff manually. If your microscope is not BioFormats compatible, Ashlar does have an as-yet-undocumented “escape hatch” for reading a directory of TIFFS using a naming convention. Once we establish which instrument you’re using we can proceed from there.

1 Like

Hi Jeremy, thanks for the answer! To be honest, I always worked with the raw images only, and mostly directly in Python (with a couple steps in FIJI for stitching). I can ask my colleagues if the native microscope files are available but for the moment let’s pretend they are not. I do know the pixel size, at least! :slight_smile:

What I have then is three folders, one per acquisition, of TIFF files named W0001F{iiii}T0001Z001C{x}.tif with i = tile number and c = channel number (4 channels per acquisition, for all of them channel 1 = DAPI, reference to ideally superimpose the three acquisitions). The tile numbering is progressive and it goes row-by-row, but it is no effort to rename the files with the X,Y position in the grid if needed.

Also I am not sure about how much superposition between near tiles we got, so far I always kept the default 20% in FIJI stitcher and it worked fine.

My procedure so far was to use the automatic FIJI stitcher on channel 1, detect and register the shift for each tile and apply the same value to the remaining channels, then superimpose (and normalize, enhance and whatever) everything in Python. Now we have multiple stainings and scans of the same tissue tho…

The undocumented solution you need is the “fileseries” reader. Where the instructions say FILE, you use a quoted string that looks like this instead:

"fileseries|/path/to/images|pattern=..."

The general format for the rest of the string is a list of key=value strings separated by |. You can supply as many fileseries arguments as you want for each of your cycles, but you should start with just the first one for now to get the stitching parameters nailed down.

Here’s what this will look like for one cycle of your data. I guessed your grid is 10x10 so you will have to change the width and height. Note this all goes on one line but it may get wrapped here:

"fileseries|/path/to/cycle1|pattern=W0001F{series:4}T0001Z001C{channel:1}.tif|overlap=0.2|width=10|height=10"

While testing, it is helpful to specify --output-channels 0 so Ashlar only spends time assembling the mosaic image for your first (DAPI) channel.

Depending on how accurate your 20% overlap guess is, you may need to pass the -m SHIFT argument to Ashlar with a fairly high value for SHIFT. By default Ashlar will assume that if a pair of tiles needs their relative positions corrected by more than 15 microns (i.e. -m 15), that it’s due to noise or other problems and will fall back on a value extrapolated from other tile alignments. However there’s no reporting that tells you about this (this is also in the works…) so it’s hard to diagnose if you’re not familiar with the internals. Probably a better solution for you would be to figure out what the actual overlap is and specify that instead of 0.2. :slight_smile: You can open two neighboring tiles in Photshop or equivalent, using additive blending mode on a sufficiently large canvas, and move them until they align. Then you can easily determine what the percent overlap is. If you get it really close, the default -m 15 (which is 15 pixels in your case since fileseries defaults to 1 pixel = 1 micron) will probably work OK. I can help you diagnose this more once you at least get it running to completion.

1 Like

Super, I’ve given it a try and so far I can tell you that:

  • I’m drowning in skimage_deprecation: Function register_translation is deprecated and will be removed in version 0.19. Use skimage.registration.phase_cross_correlation instead. removed_version='0.19') warnings
  • I originally got an actual error because of import skimage.external.tifffile, which apparently no longer exists, in utils.py > imsave. I replaced it with import tifffile directly and got rid of the error.

Now I am getting some result, although with wrong overlapping factors it looks kinda… trippy (0.2 was just stacking everything in a weird way). I’ll use your method to estimate it directly, thanks for that too!

an update: it seems that as soon as I set the overlap value at or above 10% the result gets compressed into a single column, even if I set the -m option to higher values (200 and more, which is slightly less than 10%).

I experimented with a few values between 10 and 20% and the problem remains. The measured overlap value is around 13%, and I’ve been told that the settings in the microscope stated 15%, so we’re not that far from “reality”…

Try adding --flip-x. It’s possible the positive-X direction in each tile image is flipped from your stage position positive-X, and that option will correct for this.

1 Like

Oh, and sorry about the deprecation warnings and tifffile error. I need to update my code to be current with some API changes in skimage.

1 Like

Nope, still only getting a single column as a result with --flip-x :frowning:

You can also try --filter-sigma 1 to add a small gaussian blur during the stitching which helps if the images are a bit noisy. If that still doesn’t help, do you want to share the images with me privately?

There are some internal diagnostics I use to figure out what’s happening in situations like this, but they’re not exposed from the command line tool yet unfortunately.

Yes I’ll send you a link privately in a few minutes. Thanks again!

1 Like