// Reduce HyperStack
//
// This macro reduces the dimensionality of an hyperstack. It will create
// a new hyperstack with all the channels and time points at a given
// z position, or all the z slices for the current channel and time point, etc.

  macro "Reduce HyperStack" {
     requires("1.40a");
     if (!Stack.isHyperStack) exit ("HyperStack required");
     setBatchMode(true);
     Stack.getDimensions(width, height, channels, slices, frames);
     Stack.getPosition(c1, z1, t1);
     Stack.getDisplayMode(mode);
     title = getTitle();
     b = bitDepth();
     id = getImageID();

     Dialog.create('Reduce HyperStack');
     Dialog.addMessage('Create a new image with');
     if (channels!=1) Dialog.addCheckbox('Channels ('+channels+')',true);
     if (slices!=1) Dialog.addCheckbox('Slices ('+slices+')',true);
     if (frames!=1) Dialog.addCheckbox('Frames ('+frames+')',true);
     Dialog.show();
     if (channels!=1) channels = channels*Dialog.getCheckbox();
     if (channels==0) channels = 1;
     if (slices!=1) slices=slices*Dialog.getCheckbox();
     if (slices==0) slices = 1;
     if (frames!=1) frames=frames*Dialog.getCheckbox();
     if (frames==0) frames = 1;

     run("New HyperStack...", "title=ExtractOf_"+title+" type="+b+"-bit display=Color width="+width+" height="+height+" channels="+channels+" slices="+slices+" frames="+frames+" ");
     id2 = getImageID();
     n = channels*slices*frames; 
     i = 0;

     for (c=1; c<=channels; c++) {
        if (channels==1) c=c1;
        selectImage(id);
        Stack.setPosition(c,1,1);
        getVoxelSize(vw, vh, vd, unit); 
         if (b!=24) getLut(reds, greens, blues);
        getMinAndMax(min, max);
        for (z=1; z<=slices; z++) {
           if (slices==1) z=z1;
           for (t=1; t<=frames; t++) {
              showProgress(i++, n);
              if (frames==1) t=t1;
              selectImage(id);
              Stack.setPosition(c,z,t);
              run("Copy");
              selectImage(id2);
              Stack.setPosition(c,z,t);
              run("Paste");
           }
        }
        selectImage(id2);
        Stack.setPosition(c,1,1);
        setVoxelSize(vw, vh, vd, unit);
        if (b!=24) setLut(reds, greens, blues); 
        setMinAndMax(min, max);
     }

     setBatchMode(false);
     selectImage(id);
     Stack.setPosition(c1, z1, t1);
     selectImage(id2);
     Stack.setPosition(1, 1, 1);
     if (is("composite")) Stack.setDisplayMode(mode);
     run("Select None");

  }