my team is currently developing a Slicer/Python module for a internal research project.
At the moment I am still waiting for the permission to publish parts of the source code here, so I cannot provide you with the entire plugin code so far (which hopefully will change soon ).
What the plugin is essentially loading multiple volumns and performs some registrations (via BRAINS).
This finally gives me the following (linear) transform tree:
volumeT2h -> volumeT2 -> volumeT1 -> volumeCiss
where “->” is the registration transform.
So I want to put volumeT1 into the “global” world coordinate system. To do so, I copy the transform from volumeT1 to volumeCISS, invert the linear matrix and perform the following commands:
volCiss.SetAndObserveTransformNodeID(tfCissToT1.GetID()) <— tfCissToT1 is the inverted transform
volT1.Modified() <— may not required
The registration steps as well as the transform handling and the three lines above are executed by a procedure inside my module.
And here is the weird behavior: After the procedure has finished, the transform tree remains unchanged (only) for volT1, which still “observes” the tfT1toCiss, whereas volT1 should actually be in world space.
So I tried to debug this issue with the debugger (PyCharm) and right after these three lines the evaluation of the volT1 node tells me that there is no transform node assigned to volT1. But again, after the procedure has finished, the SAME evaluation (done on the internal Slicer/Python console) tells me, that volT1 is assigned to tfT1toCiss.
In addition to that, if I then execute the three lines (above) manually inside the Slicer/Python console, the commands work “correctly” and I finally get the expected result.
I finally modified the procedure to the following scheme:
…[At this point, my debugger tells me that volT1 has no transform assigned anymore]
…[At this point, volT1 has the unwanted transform assigned, again]
…my_three_lines_from_above() [again ]
…[At this point, volT1 has the no transform assigned. Yeah!]
(Dots indicate whitespaces.)
At the call code.interact(), an interactive interpreter is accessable inside the Slicer/Python console, in which I always type in “exit()”. Now, aside that console-exit()-workaround-thing, the procedure works as desired.
This behavior is waaaaay unexpected to me and, unfortunately, out of my knowledge scope
May some of you folks have an idea, why Slicer currently behaves like this.
Again, I’m going to talk to my team in order to get the permission to publish the entire source ASAP.