''' # Previous GUI # @File(label="Image directory", style="directory") inFolder # @String(label="Image File Extension", required=false, value=".tif") image_extension # @Boolean(label="Show stack ?", value="True") ShowStack # @Boolean(label="Save Stack ?", description="Stacks will be saved in a 'HyperStack' folder in the image folder",value = "True") SaveStack HYPERSTACK GENERATOR Read all tif images from an experiment inFolder that contains tif images for the different wells, channel, slices and timepoints The script will automatically reads the field from the filename (using index in the string - FOLLOWING ACQUIFER-IM04 NAMING CONVENTION ex: -A001--...) to generate the well's stack TO DO : - Prevent exception if no well selected ''' import os, ij import ij.plugin as plugin from ij import IJ from fiji.util.gui import GenericDialogPlus from java.awt.event import ActionListener class ListenerClass_All(ActionListener): # extends action listener '''Class associated to the Select all button''' def actionPerformed(this,event): '''Called when 'Select All' is clicked''' global Win for checkbox in Win.getCheckboxes()[2:]: checkbox.setState(True) class ListenerClass_None(ActionListener): # extends action listener '''Class associated to the Select none button''' def actionPerformed(this,event): '''Called when 'Select None' is clicked''' global Win for checkbox in Win.getCheckboxes()[2:]: checkbox.setState(False) ListenerAll = ListenerClass_All() # create an instance of the EventListener class ListenerNone = ListenerClass_None() # create an instance of the EventListener class # Input GUI window Win = GenericDialogPlus("Hyperstack generator - Parameters") # Title of the window Win.enableYesNoCancel('OK','Cancel') # OK, Cancel (chosen) and Cancel button Win.hideCancelButton() # keep only one cancel button Win.addDirectoryField("Image directory","MyPath") Win.addStringField("Image file extension",".tif") Win.addCheckbox("Show stack ?",True) Win.addCheckbox("Save stack ?",True) #Disclaimer = "This is my link" # this will pop up a small window with some documentation Disclaimer = "https://github.com/acquifer/ImageInLife/wiki/Stacks" # this will directly open the doc page Win.addHelp(Disclaimer) # Generate tick box with plate layout to select well Wells = [] for letter in ['A','B','C','D','E','F','G','H']: for column in range(1,13): Wells.append(letter+'%(column)03d' %{"column":column}) # force max 3 digits and leading 0 Win.addCheckboxGroup(8,12,Wells,[True]*96) Win.addButton('Select all' ,ListenerAll) # add our event listener to the button. Button clicked -> event -> call actionPerformed(MyEvent) Win.addButton('Select none',ListenerNone) Win.showDialog() # Recover Path to template if (Win.wasOKed()): inFolder = Win.getNextString() image_extension = Win.getNextString() Bool = [checkbox.getState() for checkbox in Win.getCheckboxes()] ShowStack = Bool[0] SaveStack = Bool[1] BoolWell = Bool[2:] Selection = {well:choice for well,choice in zip(Wells,BoolWell)} #print Selection #print len(Wells) # OK 96 # Find image files for the given channel #inFolder = str(inFolder) # convert filename object to string object WellList = [] # full list of well to know how many iteration for stacking TimeList = [] ChannelList = [] SliceList = [] MainList = [] # contains tuple with (Filename, Well, TimePoint, Channel, Z-Slice) for fname in os.listdir(inFolder): if fname.endswith(image_extension): Well = fname[1:5] if Selection[Well]: # selected in the GUI try : # int conversion through an error if the argument string is empty Time = int(fname[15:18]) Channel = int(fname[22:23]) Slice = int(fname[27:30]) except : raise Exception("Could not get experimental parameters from filename. Check filename pattern (IM04 convention)") WellList.append(Well) TimeList.append(Time) ChannelList.append(Channel) SliceList.append(Slice) MainList.append((fname,Well,Time,Channel,Slice)) else : # the well was not selected in the GUI continue if len(MainList) < 1: raise Exception("No image files found in %s. Check if extension match and if filenames match IM04 naming convention" % inFolder) # Sort list to prepare iteration WellList = list(set(WellList)) # turn to a set object to have unique item once only WellList.sort() # sort should be after set since set may change order TimeList = list(set(TimeList)) TimeList.sort() ChannelList = list(set(ChannelList)) ChannelList.sort() SliceList = list(set(SliceList)) SliceList.sort() # Verification print 'Well : ', WellList print 'Time : ', TimeList print 'ChannelIdx : ', ChannelList print 'Z-Slice : ' , SliceList MainList.sort( key = lambda field:(field[1], field[2], field[4], -field[3]) ) # sort by Well, Time, Z-slice then Channel (- to have C06 ie BF first) since the hyperstack is created following the default "xyczt" order ''' for i in MainList : print i ''' # Open first image to get the image size (needed to setup the stack) or find another way to do the stack ImagePath = os.path.join(inFolder,MainList[0][0]) Image = ij.IJ.openImage(ImagePath) Width = Image.width Height = Image.height # Initialise HyperStackConverter object HyperStacker = plugin.HyperStackConverter() for well in WellList: # Loop over well to do stack and projection IJ.log('Process well : '+well+'...') SubList = [item for item in MainList if item[1]==well] # Sublist containing (fname,Well,Time,Channel,Slice) for one given well ex: only A001 #print 'StackSize : ',len(SubList) Stack = ij.ImageStack(Width,Height) # create stack objet that will contains all images of this well (further turned into an hyperstack) for item in SubList : # Loop over tuples of SubList, open associated images and append it to the stack filename = item[0] ImagePath = os.path.join(inFolder,filename) Image = ij.IJ.openImage(ImagePath) Stack.addSlice(filename,Image.getProcessor()) # conversion to ImageProcessor object to append to stack Stack = ij.ImagePlus(well,Stack) # reconverting back to an ImagePlus object to be able to show and save it #print Stack #Stack.show() # Good if Stack.getNSlices()>1 : # Convert to Hyperstack HyperStack = HyperStacker.toHyperStack(Stack,len(ChannelList), len(SliceList), len(TimeList),"xyczt","grayscale") # convert PROPERLY ORDERED Stack to Hyperstack else: # Keep as single image HyperStack = Stack if ShowStack : HyperStack.show() if SaveStack : outFolder = os.path.join(inFolder,'HyperStack') if not os.path.exists(outFolder): os.makedirs(outFolder) # create folder if it does not exist (for the first image to save basicly) outPath = os.path.join(outFolder,well+'.tif') IJ.save(HyperStack,outPath) IJ.log('Done')