The ApplicationController
Some more advanced features are only available through an imfusion.ApplicationController
.
It manages loaded data, can visualize data and records executed algorithms, among other things.
If you are using the embedded Python interpreter of the ImFusionSuite, a imfusion.ApplicationController
is already instantiated.
Otherwise we create a imfusion.ConsoleController
which is a special controller that does not provide or require a GUI:
>>> if not imfusion.app:
... imfusion.app = imfusion.ConsoleController()
All the previously introduced functions are independent of the imfusion.ApplicationController
but some can also be called on the imfusion.ApplicationController
instance with some additional side effects:
>>> imfusion.app.open('ct_image.png')
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]
If you executed the previous code in the ImFusionSuite, you might have noted that the image is directly displayed in the main view area.
This is because the data gets automatically added to the imfusion.DataModel
.
This is not the case if you load data with imfusion.io.open()
.
DataModel
The imfusion.DataModel
stores all data that is managed by the imfusion.ApplicationController
and
you can retrieve, add or delete data from it:
>>> dm = imfusion.app.data_model
>>> len(dm)
1
>>> img = dm[0]
>>> img
imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])
Be careful when removing data: Since the data is owned by the underlying C++ framework, Python cannot track the lifetime of the data. This means that any variable still referring a deleted data might lead to a crash.
When adding data created in Python to the imfusion.DataModel
it will get copied.
The reference to the copy is returned:
>>> new_img = imfusion.SharedImageSet(np.zeros([1, 8, 8, 8, 1], dtype=np.uint8))
>>> new_img = dm.add(new_img)
Running algorithms
We can also execute algorithms directly on the imfusion.ApplicationController
.
Any output data will then be added automatically to the imfusion.DataModel
:
>>> imfusion.app.execute_algorithm('Base.MorphologicalOperations', [img])
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]
>>> len(dm)
2
The imfusion.ApplicationController
will also keep track of all executed algorithms.
You can save the algorithm history in the ImFusionSuite as a workspace (.iws) and replay the algorithms with the same settings.
Check the C++ documentation for more details about workspaces.
Instead of executing the algorithm right away, we can also just open it:
>>> imfusion.app.add_algorithm('Base.MorphologicalOperations', [img])
<imfusion._bindings.BaseAlgorithm object at...>
This returns a reference to the algorithm instance and will open the corresponding UI element (which we call “Algorithm Controller”) in the ImFusionSuite.
Recommendations
If you are only writing simple scripts, you most likely don’t need the added complexity of the imfusion.ApplicationController
and should use the functions that don’t require it like imfusion.execute_algorithm()
.
Also if you write custom algorithm, you should not rely on imfusion.app
being available.
If, on the other hand, you are using Python in combination with the ImFusionSuite application, the imfusion.ApplicationController
interface is much more convenient.