From 2836a3b5f86bf8370048b8ae09b372282f119beb Mon Sep 17 00:00:00 2001 From: sebherbert Date: Wed, 5 Jun 2019 12:28:42 +0200 Subject: [PATCH 1/6] Browse in files to find images Script parameters allow for the search of files in the computer, simplifying the search --- script/CARE_generic.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index 73db8a1..16961da 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -1,17 +1,17 @@ -# @String(label="Input path (.tif or folder with .tifs)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script') input -# @String(label="Output path (.tif or folder)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script/out') output -# @String(label="Model file", required=false, value='/home/random/Development/imagej/project/CSBDeep/data/Tobias Boothe/models/phago_C2_no_transform_model.zip') modelFile -# @String(label="Model file", required=false, value='phago_C2_no_transform_model') _modelName -# @Integer(label="Number of tiles", required=false, value=8) nTiles -# @Integer(label="Tile overlap", required=false, value=32) overlap -# @Boolean(label="Normalize input", required=false, value=true) normalizeInput -# @Float(label="Bottom percentile", required=false, value=3.0, stepSize=0.1) percentileBottom -# @Float(label="Top percentile", required=false, value=99.8, stepSize=0.1) percentileTop -# @Boolean(label="Clip", required=false, value=false) clip -# @Boolean(label="Show progress dialog", required=false, value=true) showProgressDialog -# @DatasetIOService io -# @CommandService command -# @ModuleService module +#@ File(label="Input path (.tif or folder with .tifs)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script', style="both") input +#@ File(label="Output path (.tif or folder)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script/out', style="directory") output +#@ File(label="Model file", required=false, value='/home/random/Development/imagej/project/CSBDeep/data/Tobias Boothe/models/phago_C2_no_transform_model.zip', style="file") modelFile +#@ String(label="Model file", required=false, value='phago_C2_no_transform_model') _modelName +#@ Integer(label="Number of tiles", required=false, value=8) nTiles +#@ Integer(label="Tile overlap", required=false, value=32) overlap +#@ Boolean(label="Normalize input", required=false, value=true) normalizeInput +#@ Float(label="Bottom percentile", required=false, value=3.0, stepSize=0.1) percentileBottom +#@ Float(label="Top percentile", required=false, value=99.8, stepSize=0.1) percentileTop +#@ Boolean(label="Clip", required=false, value=false) clip +#@ Boolean(label="Show progress dialog", required=false, value=true) showProgressDialog +#@ DatasetIOService io +#@ CommandService command +#@ ModuleService module from java.io import File import sys @@ -38,6 +38,10 @@ def runNetwork(inputPath, outputPath): print(myoutput) io.save(myoutput, outputPath) + +input = str(input) # change object from file to str +output = str(output) # change object from file to str + if input.endswith(".tif"): if output.endswith(".tif"): runNetwork(input, output) From 4b7b2ba692605d6cd82f485b2877953949a76119 Mon Sep 17 00:00:00 2001 From: sebherbert Date: Wed, 5 Jun 2019 14:28:18 +0200 Subject: [PATCH 2/6] Adapt script for accepting an hyperstack input This modification allows the selection of an hyperstack with multiple frames as an input. This doesn't apply to the selection of a folder of images yet, but could be done later. --- script/CARE_generic.py | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index 16961da..d0a5ca7 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -16,14 +16,16 @@ from java.io import File import sys from de.csbdresden.csbdeep.commands import GenericNetwork +from ij import IJ +from ij.plugin import Duplicator +import os def getFileName(path): fileparts = path.split("/") return fileparts[len(fileparts)-1] -def runNetwork(inputPath, outputPath): +def runNetwork(inputPath, outputPath, imp): print("input: " + inputPath + ", output: " + outputPath) - imp = io.open(inputPath) mymod = (command.run(GenericNetwork, False, "input", imp, "nTiles", nTiles, @@ -39,16 +41,42 @@ def runNetwork(inputPath, outputPath): io.save(myoutput, outputPath) + input = str(input) # change object from file to str output = str(output) # change object from file to str if input.endswith(".tif"): if output.endswith(".tif"): - runNetwork(input, output) + impSource = io.open(input) + runNetwork(input, output, impSource) else: if not(output.endswith("/")): output += "/" - runNetwork(input, output + getFileName(input)) + + impSource = IJ.openImage(input) + + [width, height, nChannels, nSlices, nFrames] = impSource.getDimensions() + + if nChannels > 1: # if more than 1 channel, exit + print("ERROR: please provide an image with a single channel") + sys.exit() + + print("Processing: " + getFileName(input)) + print("Found "+str(impSource.getNFrames())+" frames to process") + + for dt in xrange(nFrames): # For each frame + # Frames in the movie will begin at 1 + frame = dt+1 + # Duplicate the frame of interest + impSingleTp = Duplicator().run(impSource, 1, 1, 1, nSlices, frame, frame) + # Create a new output fileName + root, ext = os.path.splitext(getFileName(input)) + outputFileName = root + "_frame" + str(frame) + ".tif" + # Run the network + print("Processing: " + outputFileName) + runNetwork(input, output + outputFileName, impSingleTp) + + else: if output.endswith(".tif"): print("ERROR: please provide a directory as output, because your input is also a directory") @@ -65,4 +93,5 @@ def runNetwork(inputPath, outputPath): for file in listOfFilesInFolder: if file.toString().endswith(".tif"): - runNetwork(file.toString(), output + getFileName(file.toString())) + impSource = io.open(file.toString()) + runNetwork(file.toString(), output + getFileName(file.toString()), impSource) From d3f154aad63fa46c9356fcdc5d4b3f7967b717bb Mon Sep 17 00:00:00 2001 From: sebherbert Date: Thu, 6 Jun 2019 12:16:39 +0200 Subject: [PATCH 3/6] Windows architecture compatible I changed the tests directory tests and file name handling using path.join instead of adding a "/". This should make the script Windows compatible. --- script/CARE_generic.py | 91 +++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index d0a5ca7..573f372 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -1,17 +1,17 @@ -#@ File(label="Input path (.tif or folder with .tifs)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script', style="both") input -#@ File(label="Output path (.tif or folder)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script/out', style="directory") output -#@ File(label="Model file", required=false, value='/home/random/Development/imagej/project/CSBDeep/data/Tobias Boothe/models/phago_C2_no_transform_model.zip', style="file") modelFile -#@ String(label="Model file", required=false, value='phago_C2_no_transform_model') _modelName -#@ Integer(label="Number of tiles", required=false, value=8) nTiles -#@ Integer(label="Tile overlap", required=false, value=32) overlap -#@ Boolean(label="Normalize input", required=false, value=true) normalizeInput -#@ Float(label="Bottom percentile", required=false, value=3.0, stepSize=0.1) percentileBottom -#@ Float(label="Top percentile", required=false, value=99.8, stepSize=0.1) percentileTop -#@ Boolean(label="Clip", required=false, value=false) clip -#@ Boolean(label="Show progress dialog", required=false, value=true) showProgressDialog -#@ DatasetIOService io -#@ CommandService command -#@ ModuleService module +# @File(label="Input path (.tif or folder with .tifs)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script', style="both") input +# @File(label="Output path (.tif or folder)", required=false, value='/home/random/Development/imagej/project/CSBDeep/script/out', style="directory") output +# @File(label="Model file", required=false, value='/home/random/Development/imagej/project/CSBDeep/data/Tobias Boothe/models/phago_C2_no_transform_model.zip', style="file") modelFile +# @String(label="Model file", required=false, value='phago_C2_no_transform_model') _modelName +# @Integer(label="Number of tiles", required=false, value=8) nTiles +# @Integer(label="Tile overlap", required=false, value=32) overlap +# @Boolean(label="Normalize input", required=false, value=true) normalizeInput +# @Float(label="Bottom percentile", required=false, value=3.0, stepSize=0.1) percentileBottom +# @Float(label="Top percentile", required=false, value=99.8, stepSize=0.1) percentileTop +# @Boolean(label="Clip", required=false, value=false) clip +# @Boolean(label="Show progress dialog", required=false, value=true) showProgressDialog +# @DatasetIOService io +# @CommandService command +# @ModuleService module from java.io import File import sys @@ -20,10 +20,6 @@ from ij.plugin import Duplicator import os -def getFileName(path): - fileparts = path.split("/") - return fileparts[len(fileparts)-1] - def runNetwork(inputPath, outputPath, imp): print("input: " + inputPath + ", output: " + outputPath) mymod = (command.run(GenericNetwork, False, @@ -41,57 +37,50 @@ def runNetwork(inputPath, outputPath, imp): io.save(myoutput, outputPath) +inputPath = input.getPath() # Extract input file path +outputPath = output.getPath() # Extract output file path -input = str(input) # change object from file to str -output = str(output) # change object from file to str - -if input.endswith(".tif"): - if output.endswith(".tif"): - impSource = io.open(input) - runNetwork(input, output, impSource) - else: - if not(output.endswith("/")): - output += "/" - - impSource = IJ.openImage(input) +if inputPath.endswith(".tif"): # If processing a single .tif file + + impSource = IJ.openImage(inputPath) - [width, height, nChannels, nSlices, nFrames] = impSource.getDimensions() + [width, height, nChannels, nSlices, nFrames] = impSource.getDimensions() + if nChannels > 1: # if more than 1 channel, exit + print("ERROR: please provide an image with a single channel") + sys.exit() - if nChannels > 1: # if more than 1 channel, exit - print("ERROR: please provide an image with a single channel") - sys.exit() + if outputPath.endswith(".tif"): + runNetwork(inputPath, outputPath, impSource) - print("Processing: " + getFileName(input)) + else: + print("Processing: " + input.getName()) print("Found "+str(impSource.getNFrames())+" frames to process") for dt in xrange(nFrames): # For each frame - # Frames in the movie will begin at 1 - frame = dt+1 + frame = dt+1 # Frames in the movie will begin at 1 # Duplicate the frame of interest impSingleTp = Duplicator().run(impSource, 1, 1, 1, nSlices, frame, frame) # Create a new output fileName - root, ext = os.path.splitext(getFileName(input)) + root, ext = os.path.splitext(input.getName()) outputFileName = root + "_frame" + str(frame) + ".tif" # Run the network print("Processing: " + outputFileName) - runNetwork(input, output + outputFileName, impSingleTp) - + runNetwork(inputPath, os.path.join(outputPath, outputFileName), impSingleTp) -else: - if output.endswith(".tif"): +elif input.isDirectory(): + if outputPath.endswith(".tif"): print("ERROR: please provide a directory as output, because your input is also a directory") sys.exit() - if not(output.endswith("/")): - output += "/" - if not(input.endswith("/")): - input += "/" - if(output == input): + if(outputPath == inputPath): print("ERROR: please provide an output directory that is not the same as the input directory") sys.exit() - directory = File(input); - listOfFilesInFolder = directory.listFiles(); + listOfFilesInFolder = input.listFiles(); for file in listOfFilesInFolder: - if file.toString().endswith(".tif"): + if file.getName().endswith(".tif"): impSource = io.open(file.toString()) - runNetwork(file.toString(), output + getFileName(file.toString()), impSource) + runNetwork(file.toString(), os.path.join(outputPath, file.getName()), impSource) + +else: # input is not a directory but not a .tif file either + print("ERROR: please provide a .tif file or directory for input") + sys.exit() From 405582621888f4432db2f866f364ad5896bf2f0b Mon Sep 17 00:00:00 2001 From: sebherbert Date: Thu, 6 Jun 2019 12:18:38 +0200 Subject: [PATCH 4/6] Fix overwrite if output is tif and input is multitif Added a test to exit the process if user specified a single tif file output while processing a multiframe input --- script/CARE_generic.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index 573f372..0172266 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -50,6 +50,9 @@ def runNetwork(inputPath, outputPath, imp): sys.exit() if outputPath.endswith(".tif"): + if nFrames > 1: # If there is only 1 specified .tif file but multiple frames + print("ERROR: To process an hyperstack with multiple frames, please provide a directory as output") + sys.exit() runNetwork(inputPath, outputPath, impSource) else: From 1c426b9e7adccfaf556e7f14656bcb794cbff30f Mon Sep 17 00:00:00 2001 From: sebherbert Date: Thu, 6 Jun 2019 15:03:44 +0200 Subject: [PATCH 5/6] homogeneize image opening method change the io.open for IJ.openImage. IJ.openImage is needed in the first call since it requires ImagePlus methods --- script/CARE_generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index 0172266..774ee28 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -81,7 +81,7 @@ def runNetwork(inputPath, outputPath, imp): listOfFilesInFolder = input.listFiles(); for file in listOfFilesInFolder: if file.getName().endswith(".tif"): - impSource = io.open(file.toString()) + impSource = IJ.openImage(file.toString()) runNetwork(file.toString(), os.path.join(outputPath, file.getName()), impSource) else: # input is not a directory but not a .tif file either From 3ef7427cfc3b7a10f2dee521434d10a07abbc174 Mon Sep 17 00:00:00 2001 From: sebherbert Date: Thu, 6 Jun 2019 15:22:07 +0200 Subject: [PATCH 6/6] Simpler runNetwork call Got rid of the inputPath argument. It is now directly extracted from the imp. --- script/CARE_generic.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/script/CARE_generic.py b/script/CARE_generic.py index 774ee28..0285caa 100755 --- a/script/CARE_generic.py +++ b/script/CARE_generic.py @@ -20,7 +20,8 @@ from ij.plugin import Duplicator import os -def runNetwork(inputPath, outputPath, imp): +def runNetwork(outputPath, imp): + inputPath = imp.getOriginalFileInfo().fileName print("input: " + inputPath + ", output: " + outputPath) mymod = (command.run(GenericNetwork, False, "input", imp, @@ -53,7 +54,7 @@ def runNetwork(inputPath, outputPath, imp): if nFrames > 1: # If there is only 1 specified .tif file but multiple frames print("ERROR: To process an hyperstack with multiple frames, please provide a directory as output") sys.exit() - runNetwork(inputPath, outputPath, impSource) + runNetwork(outputPath, impSource) else: print("Processing: " + input.getName()) @@ -68,7 +69,7 @@ def runNetwork(inputPath, outputPath, imp): outputFileName = root + "_frame" + str(frame) + ".tif" # Run the network print("Processing: " + outputFileName) - runNetwork(inputPath, os.path.join(outputPath, outputFileName), impSingleTp) + runNetwork(os.path.join(outputPath, outputFileName), impSingleTp) elif input.isDirectory(): if outputPath.endswith(".tif"): @@ -82,7 +83,7 @@ def runNetwork(inputPath, outputPath, imp): for file in listOfFilesInFolder: if file.getName().endswith(".tif"): impSource = IJ.openImage(file.toString()) - runNetwork(file.toString(), os.path.join(outputPath, file.getName()), impSource) + runNetwork(os.path.join(outputPath, file.getName()), impSource) else: # input is not a directory but not a .tif file either print("ERROR: please provide a .tif file or directory for input")