Page 1 of 1

Macro to extract files from .lif throws error on last file

PostPosted: Tue Apr 03, 2018 5:02 pm
by sokipdx
I have large (~10 GB, ~800 images) .lif files from a Leica microscope that I am extracting to individual TIFFs with an ImageJ macro. For some reason, it throws an error on the last image in the series.


Here is the macro:
Code: Select all
start = getTime(); // Print timestamp for log
path = File.openDialog("Select a File");

run("Bio-Formats Macro Extensions");
setBatchMode(true);
Ext.setId(path);
Ext.getCurrentFile(file);
Ext.getSeriesCount(seriesCount);
print (path);
print ("Found " + seriesCount + " files to save");

for (s=1; s<=seriesCount; s++) {
   start_time = getTime();
   getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec);
   hour = IJ.pad(hour,2);
   minute = IJ.pad(minute,2);
   second = IJ.pad(second,2);

   Ext.openImagePlus(path);
   Ext.setSeries(s);
   title = strip_lif_prefix(getTitle());
   if (s == 1) {
      tile_counter = 1;
      last_filename = "";
   }
   if (indexOf(title,"TileScan") > 0) {
      if (last_filename == title) {
         tile_counter++;
      } else {
         last_filename = title;
         tile_counter = 1;
      }
      title = title + "_" + IJ.pad(tile_counter,3);
   }
   
   out_path = getDirectory("image") + title + ".tif";
   saveAs("tiff", out_path);
   end_time = getTime();
   processing_time = (end_time-start_time)/1000; // seconds
   elapsed_time = ((end_time-start)/1000/60); // minutes
   total_time = (elapsed_time/(s/seriesCount)); // minutes
   time_remaining  = d2s(total_time-elapsed_time,0); // minutes
   processing_time = d2s(processing_time,0);
   elapsed_time = d2s(elapsed_time,0);
   print ("[" + hour + ":" + minute + ":" + second + " | " + s + "/" + seriesCount + "] " + title + " (" + processing_time + " sec | " + elapsed_time + " min elapsed | " + time_remaining + " min remaining)");
   run("Close All");
   call("java.lang.System.gc");
}

setBatchMode(false);
print ("Done in " + (((getTime()-start)/1000)/60) + " minutes :)");
selectWindow("Log");





function strip_lif_prefix (filename) {
   pos = lastIndexOf(filename,".lif - ");
   filename = substring(filename,pos+7);
   return filename;
}


The error message below contains the line Invalid series: 809 which is the last image of the series. If I manually open the .lif in Bio-Formats and enter 809, it opens normally.
Code: Select all
java.lang.reflect.InvocationTargetException
   at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:497)
   at loci.plugins.macro.MacroFunctions.handleExtension(MacroFunctions.java:82)
   at ij.macro.ExtensionDescriptor.dispatch(ExtensionDescriptor.java:288)
   at ij.macro.Functions.doExt(Functions.java:4684)
   at ij.macro.Functions.getStringFunction(Functions.java:275)
   at ij.macro.Interpreter.getStringTerm(Interpreter.java:1335)
   at ij.macro.Interpreter.getString(Interpreter.java:1314)
   at ij.macro.Interpreter.doStatement(Interpreter.java:299)
   at ij.macro.Interpreter.doBlock(Interpreter.java:631)
   at ij.macro.Interpreter.doStatement(Interpreter.java:290)
   at ij.macro.Interpreter.doFor(Interpreter.java:553)
   at ij.macro.Interpreter.doStatement(Interpreter.java:272)
   at ij.macro.Interpreter.doStatements(Interpreter.java:234)
   at ij.macro.Interpreter.run(Interpreter.java:117)
   at ij.macro.Interpreter.run(Interpreter.java:88)
   at ij.macro.Interpreter.run(Interpreter.java:99)
   at ij.plugin.Macro_Runner.runMacro(Macro_Runner.java:161)
   at ij.IJ.runMacro(IJ.java:138)
   at ij.IJ.runMacro(IJ.java:127)
   at net.imagej.legacy.IJ1Helper$3.call(IJ1Helper.java:1096)
   at net.imagej.legacy.IJ1Helper$3.call(IJ1Helper.java:1092)
   at net.imagej.legacy.IJ1Helper.runMacroFriendly(IJ1Helper.java:1043)
   at net.imagej.legacy.IJ1Helper.runMacro(IJ1Helper.java:1092)
   at net.imagej.legacy.plugin.IJ1MacroEngine.eval(IJ1MacroEngine.java:137)
   at org.scijava.script.ScriptModule.run(ScriptModule.java:160)
   at org.scijava.module.ModuleRunner.run(ModuleRunner.java:168)
   at org.scijava.module.ModuleRunner.call(ModuleRunner.java:127)
   at org.scijava.module.ModuleRunner.call(ModuleRunner.java:66)
   at org.scijava.thread.DefaultThreadService$3.call(DefaultThreadService.java:238)
   at java.util.concurrent.FutureTask.run(FutureTask.java:266)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
   at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Invalid series: 809
   at loci.formats.FormatReader.seriesToCoreIndex(FormatReader.java:1255)
   at loci.formats.FormatReader.setSeries(FormatReader.java:936)
   at loci.formats.ImageReader.setSeries(ImageReader.java:483)
   at loci.formats.ReaderWrapper.setSeries(ReaderWrapper.java:375)
   at loci.formats.ReaderWrapper.setSeries(ReaderWrapper.java:375)
   at loci.plugins.macro.LociFunctions.setSeries(LociFunctions.java:320)
   ... 35 more



It's not a huge deal since I can just manually open and save the last image when the macro is "finished", but I'm curious as to why it fails on the last image.

My computer:
Windows 10 (64-bit)
ImageJ 1.51w (Fiji)
Java 1.8.0_66 (64-bit)
Bio-Formats 5.8.2-SNAPSHOT (22 March 2018)

Re: Macro to extract files from .lif throws error on last fi

PostPosted: Wed Apr 04, 2018 9:34 am
by dgault
Hi,

I believe the error you are seeing is due to Bio-Formats using zero based indexing. The loop being used should instead be as below:
Code: Select all
for (s=0; s<=seriesCount; s++) {


Also, you will want to call setSeries before the call to openImagePlus:
Code: Select all
   
Ext.setSeries(s);
Ext.openImagePlus(path);


David Gault

Re: Macro to extract files from .lif throws error on last fi

PostPosted: Wed Apr 04, 2018 11:13 pm
by sokipdx
dgault wrote:Hi,

I believe the error you are seeing is due to Bio-Formats using zero based indexing. The loop being used should instead be as below:
Code: Select all
for (s=0; s<=seriesCount; s++) {


Also, you will want to call setSeries before the call to openImagePlus:
Code: Select all
Ext.setSeries(s);
Ext.openImagePlus(path);


David Gault

That fixed it, with an added bonus that now the macro went from 10-30 sec/image (depending on the .lif file size) to <1 sec/image. THANK YOU!

I think I originally had the loop start at s=1 when I was using this line to open files:
Code: Select all
run("Bio-Formats Importer", "open=&path autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+s);

but when I started using this instead, I didn't realize indexing might start at 0:
Code: Select all
   Ext.setSeries(s);
   Ext.openImagePlus(path);


Edit: For posterity, in case anyone else reads this, the loop I used is this:
Code: Select all
for (s=0; s<seriesCount; s++) {