Skip to content

Commit fe85011

Browse files
committed
Improve BatchProcessor
* Use ModuleService#createModule() to create module * Beautify and sort script names in dialog choice * Add FilenameFilter to filter file extensions * Add output table to collect script outputs for each file
1 parent 3f2f158 commit fe85011

File tree

1 file changed

+69
-25
lines changed

1 file changed

+69
-25
lines changed

src/main/java/org/scijava/batch/BatchProcessor.java

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
package org.scijava.batch;
22

33
import java.io.File;
4+
import java.io.FilenameFilter;
45
import java.util.ArrayList;
6+
import java.util.Collections;
7+
import java.util.HashMap;
58
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
611
import java.util.concurrent.ExecutionException;
712
import java.util.concurrent.Future;
813

914
import net.imagej.ImageJ;
15+
import net.imagej.table.Column;
16+
import net.imagej.table.DefaultGenericTable;
17+
import net.imagej.table.Table;
1018

19+
import org.scijava.ItemIO;
20+
import org.scijava.MenuPath;
1121
import org.scijava.command.Command;
1222
import org.scijava.command.DynamicCommand;
1323
import org.scijava.log.LogService;
1424
import org.scijava.module.Module;
15-
import org.scijava.module.ModuleException;
16-
import org.scijava.module.ModuleInfo;
1725
import org.scijava.module.ModuleItem;
1826
import org.scijava.module.ModuleService;
1927
import org.scijava.module.MutableModuleItem;
2028
import org.scijava.plugin.Parameter;
2129
import org.scijava.plugin.Plugin;
2230
import org.scijava.script.ScriptInfo;
23-
import org.scijava.script.ScriptModule;
2431
import org.scijava.script.ScriptService;
2532

2633
/**
@@ -29,7 +36,7 @@
2936
*
3037
* @author Jan Eglinger
3138
*/
32-
@Plugin(type = Command.class, label = "Batch Processor", initializer = "initScriptChoice", menuPath = "Process>Batch>SciJava Batch Processor")
39+
@Plugin(type = Command.class, label = "Batch Processor", initializer = "initScriptChoice", menuPath = "Process>Batch>Process Files with Script")
3340
public class BatchProcessor extends DynamicCommand {
3441

3542
// -- Parameters --
@@ -46,9 +53,19 @@ public class BatchProcessor extends DynamicCommand {
4653
@Parameter(label = "Input directory", style = "directory")
4754
private File inputFolder;
4855

56+
@Parameter(label = "File extension")
57+
private String extension;
58+
4959
@Parameter(label = "Script to run")
5060
private String scriptChoice;
5161

62+
@SuppressWarnings("rawtypes")
63+
@Parameter(type = ItemIO.OUTPUT)
64+
private Table outputTable;
65+
// -- Other fields --
66+
67+
private Map<String, Module> scriptMap = new HashMap<>();
68+
5269
// -- Initializer methods --
5370

5471
/**
@@ -57,43 +74,70 @@ public class BatchProcessor extends DynamicCommand {
5774
* identifiers.
5875
*/
5976
protected void initScriptChoice() {
60-
MutableModuleItem<String> input = getInfo().getMutableInput("scriptChoice", String.class);
77+
MutableModuleItem<String> input = getInfo().getMutableInput(
78+
"scriptChoice", String.class);
6179
List<String> choices = new ArrayList<>();
6280
for (ScriptInfo script : scripts.getScripts()) {
63-
try {
64-
if (modules.getSingleInput(script.createModule(), File.class) != null) {
65-
choices.add(script.getIdentifier());
66-
// choices.add(script.getPath());
67-
// TODO create map with readable names and modules
68-
}
69-
} catch (ModuleException exc) {
70-
log.warn("Could not create module for script: ", exc);
81+
Module scriptModule = modules.createModule(script);
82+
if (modules.getSingleInput(scriptModule, File.class) != null) {
83+
String scriptName = getNiceName(script);
84+
choices.add(scriptName);
85+
scriptMap.put(scriptName, scriptModule);
7186
}
7287
}
88+
Collections.sort(choices);
7389
input.setChoices(choices);
7490
}
7591

92+
// -- Helper methods --
93+
94+
private String getNiceName(ScriptInfo script) {
95+
MenuPath menu = script.getMenuPath();
96+
return menu.getLeaf().getName() + " (in " + menu.getMenuString(false)
97+
+ ")";
98+
}
99+
76100
// -- Main method --
77101

102+
@SuppressWarnings("unchecked")
78103
@Override
79104
public void run() {
80-
ModuleInfo moduleInfo = modules.getModuleById(scriptChoice);
81-
ScriptModule module;
82-
try {
83-
module = (ScriptModule) moduleInfo.createModule();
84-
} catch (ModuleException exc) {
85-
log.error("Error during module creation", exc);
86-
return;
87-
}
88-
module.setContext(getContext());
105+
Module module = scriptMap.get(scriptChoice);
89106
ModuleItem<File> fileInput = modules.getSingleInput(module, File.class);
90-
for (File file : inputFolder.listFiles()) {
107+
108+
/* Mark File input as resolved */
109+
module.resolveInput(fileInput.getName());
110+
111+
/* Create output Table and mark all outputs as resolved */
112+
outputTable = new DefaultGenericTable();
113+
@SuppressWarnings("rawtypes")
114+
List<Column> columns = new ArrayList<>();
115+
116+
for (String outputKey : module.getOutputs().keySet()) {
117+
columns.add(outputTable.appendColumn(outputKey));
118+
module.resolveOutput(outputKey);
119+
}
120+
121+
FilenameFilter filter = new FilenameFilter() {
122+
@Override
123+
public boolean accept(File dir, String name) {
124+
if (name.toLowerCase().endsWith(extension.toLowerCase()))
125+
return true;
126+
return false;
127+
}
128+
};
129+
130+
int i = 0;
131+
for (File file : inputFolder.listFiles(filter)) {
91132
fileInput.setValue(module, file);
92-
module.resolveInput(fileInput.getName());
133+
outputTable.appendRow(file.getName());
93134

94135
Future<Module> instance = modules.run(module, true);
95136
try {
96-
log.info(instance.get());
137+
Map<String, Object> outputs = instance.get().getOutputs();
138+
for (Entry<String, Object> output : outputs.entrySet()) {
139+
outputTable.set(output.getKey(), i++, output.getValue());
140+
}
97141
} catch (InterruptedException exc) {
98142
log.error("Error: interrupted module execution", exc);
99143
return;

0 commit comments

Comments
 (0)