So there is this software called “3DSlicer”. It is an open source tool to work with medical images (CT, MRI).
It actually has a python-API that is documented very extensively — but which is not easy to understand if you have no idea what you want to do and only get “this is the way I always set everything up”. What settings in the GUI are where in the API?
So what I did was not very nice: I used the API to gain access to the Qt objects of the tools and just clicked all buttons in the right order…
Usually I would have added empty lines, but then the file would not load in 3DSlicer.
#!python import os import time # OUTPUT="output.nii" # def get_all_files(d): for f in os.listdir(d): if os.path.exists(os.path.join(d, f, OUTPUT)): continue yield os.path.join(d, f) # class Waiter(qt.QWidget): def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.timer = qt.QTimer() self.timer.setInterval(1000) self.timer.connect('timeout()', self.test) self.running = False self.gaf = get_all_files(r"F:\where_ever") self.timer.start() def test(self): # If the apply-Button is enabled, we can click it! if apply.enabled and not self.running: # set new self.dir = next(self.gaf) mprage_name = os.listdir(os.path.join(self.dir, "MPRAge")) flair_name = os.listdir(os.path.join(self.dir, "3DFLAIR")) mprage = os.path.join(self.dir, "MPRAge", mprage_name) flair = os.path.join(self.dir, "3DFLAIR", flair_name) mprage_name = os.path.splitext(mprage_name) flair_name = os.path.splitext(flair_name) print("Starting new...", self.dir) loadVolume(mprage) loadVolume(flair) c = slicer.mrmlScene.GetNodes() # find the two loaded files in the file-selection list mprage_node = [x for x in [c.GetItemAsObject(i) for i in range(c.GetNumberOfItems())] if x.GetName() == mprage_name] flair_node = [x for x in [c.GetItemAsObject(i) for i in range(c.GetNumberOfItems())] if x.GetName() == flair_name] # and select them fixed.setCurrentNode(mprage_node) moving.setCurrentNode(flair_node) # then click "Apply" apply.click() self.running = True elif apply.enabled and self.running: # if the button is pressable and we are waiting for it to finish, it must have just finished! c = slicer.mrmlScene.GetNodes() # find the output-file output = [x for x in [c.GetItemAsObject(i) for i in range(c.GetNumberOfItems())] if x.GetName() == "output"] # and save it saveNode(output, os.path.join(self.dir, OUTPUT)) print("Finished.") self.running = False else: print("Waiting...") # # Get a handle to a loaded module m = getModuleGui('BRAINSFit') # find a handle of the input-file section of the GUI b = m.children().children().children().children() fixed = b.children().children() moving = b.children().children() # # get a handle to the "Apply"-Button apply = m.children()[-1] # Enter the loop w = Waiter()
Note: This was hacked together for a very specific task. You will most likely need to change at least some bits to use it. Also note, that this might break with new version of 3DSlicer or the BRAINSFit-module. This is tested on 3DSlicer v4.5.0-1.