Skip to content

Instantly share code, notes, and snippets.

@lacan
Last active October 22, 2020 10:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lacan/280654785f7a2a79a5093997b50d92bf to your computer and use it in GitHub Desktop.
Save lacan/280654785f7a2a79a5093997b50d92bf to your computer and use it in GitHub Desktop.
[Rescale images in XYZ Parallel] Resamples images in parallel #Fiji #ImageJ #Bioformats #Groovy
//@File (label="Series File") image_file
//@Integer(label="XY Resampling") xy_resampling
//@Integer (label="Z Step") z_step
import loci.plugins.util.BFVirtualStack
import loci.formats.ChannelSeparator
import ij.ImagePlus
import ij.IJ
import groovyx.gpars.GParsExecutorsPool
/*
* Parallel resampling for large series files
*
* This script resizes the input image in xy and z and saves individual planes to an output folder.
*
* Tested with a 17GB dataset, resampling XY by 2 and Z by 10 took 23s over a 1Gb ethernet network
*
* Olivier Burri, BioImaging and Optics Platform (BIOP)
* December 2017
*
* Copyright 2017 Olivier Burri
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
def startTime = System.nanoTime()
// Define save directory
def main_dir = image_file.getParentFile()
def save_dir = new File(main_dir, "rescaled XY"+xy_resampling+"_Z"+z_step)
save_dir.mkdir()
//Define czi path as string to reuse later
def image_file_str = image_file.getAbsolutePath()
// Get the file name without the extension
def file_name = image_file.getName().take(image_file.getName().lastIndexOf('.'))
// Channel separator to manage the multiseries file
def final cs = new ChannelSeparator()
cs.setId(image_file.getAbsolutePath())
// Get number of series and define one virtual stack per series
def n_series = cs.getSeriesCount()
// We create as many bfvirtualstacks as there are series to process in parallel
def vr_stacks = []
(1..n_series).each{
cs.setSeries(it-1)
vr_stacks.add(new BFVirtualStack(image_file_str,cs, false, false, false))
}
// Work on stacks in parallel and on each series in parallel
GParsExecutorsPool.withPool(n_series) {
vr_stacks.eachWithIndexParallel{ stack, series ->
def n_c = cs.getSizeC()
def n_z = cs.getSizeZ()
def n_t = cs.getSizeT()
// Process 10 slices in parallel (could be optimized based on memory in a later version)
GParsExecutorsPool.withPool(10) {
(1..n_z).step(z_step).eachParallel{ the_z ->
print("\n series "+series+ "-- Z is:"+the_z)
(1..n_c).each{ the_c ->
(1..n_t).each{ the_t ->
def slice_name = file_name+"-S"+IJ.pad(series,4)+"-C"+IJ.pad(the_c,4)+"-Z"+IJ.pad((int) ((the_z-1)/z_step),4)+"-T"+IJ.pad(the_t,4)
def file = new File(save_dir, slice_name+".tif")
if(!file.exists()) {
def ip = stack.getProcessor(cs.getIndex(the_z-1, the_c-1, the_t-1)+1)
ip = ip.resize((int) (ip.getWidth()/xy_resampling))
IJ.saveAs(new ImagePlus("",ip),"tif", file.getAbsolutePath())
sleep(10)
if(!file.exists()) {
print("File "+file+" was not saved, trying again")
IJ.saveAs(new ImagePlus("",ip),"tif", file.getAbsolutePath())
}
}
}
}
}
}
}
}
def endTime = System.nanoTime()
IJ.log("Rescaling "+file_name+" ("+n_series+" series) took : "+((endTime-startTime)/1e9)+" seconds")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment