Running CSBDeep from within JUnit

Hi @frauzufall,
I am trying to run CSBDeep from within a JUnit test (see code below: runNetworkTest()). It fails, because it tries to cache the model to location in JUnit, which needs root-level access right. I therefore get this error (where /snap/intellij-idea-ultimate/181/plugins/junit exists, but needs root-permission):

java.lang.IllegalArgumentException: Not a directory: /snap/intellij-idea-ultimate/181/plugins/junit/models
	at org.scijava.download.DiskLocationCache.setBaseDirectory(DiskLocationCache.java:63)
	at net.imagej.tensorflow.DefaultTensorFlowService.initModelCache(DefaultTensorFlowService.java:205)
	at net.imagej.tensorflow.DefaultTensorFlowService.modelCache(DefaultTensorFlowService.java:194)
	at net.imagej.tensorflow.DefaultTensorFlowService.modelDir(DefaultTensorFlowService.java:216)
	at net.imagej.tensorflow.DefaultTensorFlowService.loadModel(DefaultTensorFlowService.java:109)
	at de.csbdresden.csbdeep.network.model.tensorflow.TensorFlowNetwork.loadModel(TensorFlowNetwork.java:141)
	at de.csbdresden.csbdeep.network.model.DefaultNetwork.loadModel(DefaultNetwork.java:52)
	at de.csbdresden.csbdeep.network.DefaultModelLoader.loadNetwork(DefaultModelLoader.java:41)
	at de.csbdresden.csbdeep.network.DefaultModelLoader.run(DefaultModelLoader.java:20)
	at de.csbdresden.csbdeep.commands.GenericNetwork.tryToPrepareInputAndNetwork(GenericNetwork.java:494)
	at de.csbdresden.csbdeep.commands.GenericNetwork.initiateModelIfNeeded(GenericNetwork.java:291)
	at de.csbdresden.csbdeep.commands.GenericNetwork.mainThread(GenericNetwork.java:426)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

If I call the test-method from within the main method the code runs, because it uses the working-directory as the cache-directory.
So what is the correct way for calling CSBDeep from within a JUnit test? Is there a way to specifiy the cache-directory or disable caching?

This is my test-class:

public class UnetProcessorTest {

    public static void main(String[] args) throws FileNotFoundException {
        new UnetProcessorTest().runNetworkTest();
    }

    @Test
    public void runNetworkTest() throws FileNotFoundException {
        ImageJ ij = new ImageJ();
        String path = "/path/to/tiffFile.tif";
        ImagePlus imp = IJ.openImage(path);
        int minTime = 1;
        int maxTime = imp.getNFrames();
        int minChannelIdx = 1;
        int maxChannelIdx = imp.getNChannels();

        ArrayList<Img<FloatType>> rawChannelImgs = FloatTypeImgLoader.loadTiffsFromFileOrFolder(path, minTime, maxTime, minChannelIdx, maxChannelIdx);

        Img<FloatType> imgTemp = rawChannelImgs.get( 0 );
        Img<FloatType> imgProbs = new UnetProcessor().runNetwork(imgTemp);
        System.out.println("bla");
    }
}

This is the relevent code inside UnetProcessor:

            final CommandModule module = commandService.run(
                    GenericNetwork.class, false,
                    "input", dataset,
                    "modelFile", modelFile,
                    "normalizeInput", false,
                    "blockMultiple", 8,
                    "nTiles", 1,
                    "showProgressDialog", true).get();
1 Like

Hi @michaelmell,

you can change the cache directory for imagej-tensorflow by setting the system variable imagej.tensorflow.models.dir to your directory of choice. So programmatically for a test you should be able to do something like this:

System.setProperty("imagej.tensorflow.models.dir", "/some/directory");

Let me know how it goes!

Best,
Debo