sorting a stack

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

sorting a stack

Kenneth Sloan
I would like a bit of help writing a utility Java plug-in.  

Given a stack of images, with names of the form abcKEYxyz, I want to sort on "KEY".  So, for example, I could
define:

static int compareOnKey(<slice>a, <slice>b)
{
 return extractKey(a).compareTo(extractKey(b));
}

Where "extractKey" produces a String (for example, part of the filename).

Then, I need:

static void exchange(<slice>a, <slice>b)

What I need help on is the details of:

a) what's the data type for a "<slice>"?
b) how do I get the name of a <slice>?
c) how do I "exchange" two slices in the stack?

The sort is no problem (I'll probably use InsertionSort).  The details of compareOnKey may vary (I may write several such StackSorters, or I might (eventually) write one with a dialog box for options.

The idea is to order the stack of images according to various criteria which can be derived from the filename associated with each image.  In particular, we have an age-series of images, where the age appears in a fixed location in the filename.  I'd like to sort the stack by age, and then make a montage.

I'll go off and dive into the API now - but I suspect that someone has this knowledge "off the top of their head".  All clues gratefully rented.

The perfect reply would be the guts of a plugin that sorts on filename (keeping in mind that I will have to modify it by altering "extractKey()")

--
Kenneth Sloan
[hidden email]

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: sorting a stack

dscho
Hi Ken,

On Mon, 12 Aug 2013, Kenneth Sloan wrote:

> I would like a bit of help writing a utility Java plug-in.  
>
> Given a stack of images, with names of the form abcKEYxyz, I want to
> sort on "KEY".  So, for example, I could define:
>
> static int compareOnKey(<slice>a, <slice>b)
> {
>  return extractKey(a).compareTo(extractKey(b));
> }
>
> Where "extractKey" produces a String (for example, part of the filename).
>
> Then, I need:
>
> static void exchange(<slice>a, <slice>b)
>
> What I need help on is the details of:
>
> a) what's the data type for a "<slice>"?
> b) how do I get the name of a <slice>?
> c) how do I "exchange" two slices in the stack?
>
> The sort is no problem (I'll probably use InsertionSort).  The details
> of compareOnKey may vary (I may write several such StackSorters, or I
> might (eventually) write one with a dialog box for options.

Don't use InsertionSort. The Java API offers much better (and more
convenient) sorting options.

> The idea is to order the stack of images according to various criteria
> which can be derived from the filename associated with each image.  In
> particular, we have an age-series of images, where the age appears in a
> fixed location in the filename.  I'd like to sort the stack by age, and
> then make a montage.
>
> I'll go off and dive into the API now - but I suspect that someone has
> this knowledge "off the top of their head".  All clues gratefully
> rented.
>
> The perfect reply would be the guts of a plugin that sorts on filename
> (keeping in mind that I will have to modify it by altering
> "extractKey()")

Sorry, you will have to write it yourself. But here are a couple of hints:

- You should first make an array of Integers and populate it with the
  indices 1..<stackSize>

- Make this array final so that you can use it in an anonymous instance of
  the comparator class:

        // assuming that stack is the instance of the ImageStack
        final Integer[] array = stack.getSize();
        ...

        java.util.Arrays.sort(array, new Comparator<Integer>() {
                @Override
                public int compare(Integer a, Integer b) {
                        final int indexA = a.intValue();
                        final int indexB = b.intValue();
                        final String labelA = stack.getSliceLabel(indexA);
                        final String labelB = stack.getSliceLabel(indexB);
                        final ImageProcessor ipA = stack.getProcessor(indexA);
                        final ImageProcessor ipB = stack.getProcessor(indexB);
                        // return negative if a is "smaller than" b,
                        // positive if it is "larger", 0 if it is
                        // equivalent
                }
        });

- The construct a new ImageStack and add the slices of the old one with
  the order given by the array

Good luck,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html