Skip to content

Instantly share code, notes, and snippets.

@NicoKiaru
Created March 29, 2021 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NicoKiaru/d08618d3b8b04bafe0ab9520c59edf5e to your computer and use it in GitHub Desktop.
Save NicoKiaru/d08618d3b8b04bafe0ab9520c59edf5e to your computer and use it in GitHub Desktop.
Takes a Nikon ND2 file and batch exports individual series, optionally Z Projected and rescaled #BIOP #Fiji #BigDataViewer #NikonStereology
// You need to activate https://biop.epfl.ch/Fiji-Bdv-Playground/ for this script to function
// It takes a Nikon ND2 file and batch exports individual series, optionally Z Projected and rescaled
// Nicolas Chiaruttini, BIOP, EPFL, 2021
#@CommandService cs
#@SourceAndConverterService sac_service
#@File(label="Select your Nikon ND2 file (single timepoint only)", style="open") nikonNd2File
#@File(label="Select directory to save images", style="directory", value="default") saveDir
#@Integer(label="Resize Factor (XY)", value=1) resize
#@Boolean(label="Project Z Slices", value=false) is_do_z_project
#@String(label="Z Projection Method", choices={"avg", "min", "max", "sum", "sd", "median"}) z_project_method
#@Integer(label="Number of images processed in parallel", value=8) nMaxThreads
// Opens Nikon nd2 dataset ( = multi series )
def dataset = cs.run(BasicOpenFilesWithBigdataviewerBioformatsBridgeCommand.class, true,
"unit", "MICROMETER",
"files", [nikonNd2File] as File[],
"splitRGBChannels", false
).get().getOutput("spimData")
// Sets a meaningful name to the opened dataset - if not it is called SpimData 0
sac_service.setSpimDataName(dataset, nikonNd2File.getName())
// Uses the Bdv UI to fetch the number of series ( how many nodes are there below dataset>SeriesNumber ?
def datasetPath = sac_service.getUI().getTreePathFromString(nikonNd2File.getName()+">SeriesNumber")
def int number_of_series = datasetPath.getLastPathComponent().getChildCount();
// For the user - IJ log starts
IJ.log("Starting processing "+number_of_series+" series contained in "+ nikonNd2File.getName()+"...")
// Times the whole process
def exporterTimer = new Timer("Export from file "+nikonNd2File.getName())
exporterTimer.tic()
// Sets output directory
def File outputDirectory;
if(!saveDir.getName().equals("default")) {
outputDirectory = new File(saveDir.getAbsolutePath())
} else {
outputDirectory = new File(nikonNd2File.getParent(), "output")
if (!outputDirectory.exists()) {
outputDirectory.mkdir()
}
}
// Processes series in parallel
GParsExecutorsPool.withPool(nMaxThreads as int) {
(0..number_of_series-1).eachParallel{ series_index ->
def seriesProcessTimer = new Timer("--- processing series "+series_index)
seriesProcessTimer.tic()
// Export dataset as a Virtual Image Plus
def original_imp = cs.run(ExportToImagePlusCommand.class, true,
"level",0,
"timepointBegin",0,
"timepointEnd",1,
"sacs", nikonNd2File.getName()+">SeriesNumber>Series_"+series_index).get().getOutput("imp_out");
def output_imp = original_imp
// Projects the image if set by the user
if (is_do_z_project) {
output_imp = ZProjector.run(output_imp, z_project_method)
}
// Resizes the image if set by the user
if (resize!=1) {
output_imp = Scaler.resize(
output_imp, output_imp.getWidth()/resize as int,
output_imp.getHeight()/resize as int,
output_imp.getNSlices() as int,
"bilinear")
}
output_imp.show()
original_imp.close()
// Sets series outputfilename
def fileName = FilenameUtils.getBaseName(nikonNd2File.getName())+"_S"+series_index
IJ.saveAs(output_imp, "Tiff", outputDirectory.getAbsolutePath()+"//"+fileName+".tif")
output_imp.close()
seriesProcessTimer.toc()
}
}
cs.run(SourcesRemoverCommand.class, true, "sacs", nikonNd2File.getName()) // Cleans source and converter service -> releases memory
// Ends timer
exporterTimer.toc()
/*
* Time class to 'tic-toc' a few steps and check time spent.
*/
class Timer{
Long startTime
Long endTime
def name
public Timer(String name){
this.name = name
}
public void tic(){
this.startTime = System.nanoTime()
}
public void toc(){
this.endTime = System.nanoTime()
IJ.log("'"+name+"' took : "+((endTime-startTime)/1e9)+" s")
}
}
import ch.epfl.biop.bdv.bioformats.command.BasicOpenFilesWithBigdataviewerBioformatsBridgeCommand
import sc.fiji.bdvpg.scijava.command.source.SourcesRemoverCommand
import ch.epfl.biop.bdv.command.exporter.ExportToImagePlusCommand
import ij.plugin.Scaler
import ij.plugin.ZProjector
import ij.IJ
import org.apache.commons.io.FilenameUtils
import ch.epfl.biop.bdv.bioformats.imageloader.SeriesNumber
import groovyx.gpars.GParsExecutorsPool
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment