I am writing a script in Jython/Python for image analysis (using ImageJ). My goal is to compare the images to eachother...
(edit for clarity: Each element in the list must be compared to every other element, but self-comparisons are not allowed.)
...but I have some specific requirements. These requirements are based on the fact that I'm using a predefined plugin.
For example:
imagefiles = ["A", "B", "C"]
First: order matters. "A"
vs "B"
is different than "B"
vs. "A"
.
Second: the list is of variable size, based on user input. In this example, the user has input 3 files: A,B,C
, but the code needs to accomodate instances where the number of elements does not equal three.
Third: self-comparison is not allowed. Ie: "A"
vs. "A"
cannot occur.
Fourth: I would like the comparisons be reciprocated before moving onto the next element. For example:
"A" vs "B"
then "B" vs "A"
rather than "A" vs "B"
then "A" vs "C"
Fifth: I ultimately need to access the elements in the form of a string (requirement due to calling user-defined variables into a preexisting plugin).
For clarity, the comparisons that must be made are:
"A" vs "B"
"B" vs "A"
"A" vs "C"
"C" vs "A"
"B" vs "C"
"C" vs "B"
I'm able to produce a code that does everything except the FOURTH requirement...that is reciprocal comparisons first. But I'm really stuck on how to make the the order of comparisons what I want. Here's the current working snipped, that does not meet my 4th requirement.
from ij import IJ #using Jython scripting in the ImageJ program
imagefiles = ["A", "B", "C"]
for index, imgs in enumerate(imagefiles):
for s, secondimage in enumerate(imagefiles):
if s != index:
IJ.run("PluginFE", "element1="+imgs+" element2="+secondimage) #this calls the plugin (PluginFE) within the ImageJ program)
I'm trying to think about how to accomplish the comparison order requirement...and coming up with something like this:
for imgs in imagefiles:
for index in range(len(imagefiles)):
if index < len(imagefiles):
IJ.run("PluginFE", "element1="+imgs+"element2="+imagefiles[index+1])
but this fails with the error
IndexError: index out of range: 3
I understand the error,and the problem...I just can't figure out how to work around. I'm still pretty new to coding, so I may be missing an obvious python function!
Thanks for any input
Try this:
for index, imgs in enumerate(imagefiles[:-1]):
for secondimage in imagefiles[index+1:]:
IJ.run("PluginFE", "element1="+imgs+" element2="+secondimage)
IJ.run("PluginFE", "element1="+secondimage+" element2="+imgs)
Starting the inner loop from the next element after the one in the outer loop ensures that each pair is only processed once, and imgs
will always be the earlier one. Then it calls IJ.run()
with the images in the two orders, first with imgs vs secondimage
, then secondimage vs imgs
.
I think you can use itertools.combinations
as well:
import itertools
for imgs, secondimage in itertools.combinationa(imagefiles, 2):
IJ.run("PluginFE", "element1="+imgs+" element2="+secondimage)
IJ.run("PluginFE", "element1="+secondimage+" element2="+imgs)