Total Pageviews

Saturday, December 17, 2011

Well, I am finally nearing completion of the stability overhaul which has sidetracked me for almost 2 weeks now. The important thing is that I am now getting reproducible and more accurate results.  It turns out that my concepts were significantly more sound than my code.  At any rate, now I will finally be able to get back to finishing up the iliac tracking algorithm.  From there, I will be able to re-enable the bone segmentation algorithms and so I should have all of that completed by the end of the year.
I had never intended to start the vascular segmentation until after the bone segmentation algorithm had already run, but I ran into problems with the bone propagation algorithm.  Then, I was only going to track the aorta and leave the iliac until later, but there ended up being a handful (<3) studies in the set where the iliac became an issue and so now I have ended up performing the entire vascular tracking out of necessity rather than intentionally.  That being said, the current vascular tracking is leaps and bounds ahead of the previous (primarily CPU based) code.
For this code, I had to go with sensitivity rather than specificity because even minor missed points can send the bone segmentation out of whack.  At least now I have an accurate center-line extraction so that once the bone segmentation is completed, it will be straight forward to go back and fine tune the vascular lumen segmentation.

Friday, December 16, 2011

The implementation of the iliac tracking algorithm is actually fairly straight forward.  The aortic tracking algorithm passes a pair of starting points to the iliac algorithm.  At that point, the algorithm tracks in a N x M grid in spherical coordinates and finds the longest continuous path which is contained in the vessel.  The immediate problem that comes up is that you end up tracking forward as well as backwards in this method.  That is not as much of a problem as one might think because we have already tracked the aorta up to that point and we know the general direction of the iliac course (down and to the side).  Using those two bits of information allows the algorithm to cast the wide net of potential paths and exclude paths that are illogical.
Once the longest path is determined, the algorithm takes a step in that direction by a fraction of the actual length.  The reason for the fractional step is basically to minimize the number of time that the internal iliac artery is accidentally tracked.
In order to determine the direction of the fractional step, the simplest solution would be to just continue in the direction that is the longest continuous vessel path, but that will often lead the algorithm down undesireable paths. The one alternative is to average the longest path vector with some other set of vectors which represent a directional bias (i.e. the left iliac artery should tend out, down, and anterior).  There are an infinite number of other vectors which you could use and get a result.  The problem is that you don't know beforehand which combination of vectors will result in proper lumen tracking for an arbitrary scan.  
This is where the search for the chaotic attractor comes into play.  If you think of the iliac tracking as an abstract algorithm which depends on a set of variable X1,X2, X3..., then you can conceptualize the iliac tracking as a means of probing the variable space.  The purpose of this exercise is of course to identify the attractor which is assumed to be attainable.  Whether or not that is possible is something we shall have to wait and see
Well, I got side tracked for a bit on a non-convergence issue which has been a thorn in my side for the past couple of months.  Part of the aortic tracking algorithm was varying between runs by a degree small enough for the overall result to relatively consistent but large enough to cause downstream problems.  I have gone through the major portions of the algorithm with a fine tooth comb and nothing seemed to stop the result from varying.  After almost a week of meticulous debugging of each individual line of code to isolate the portion that was causing the problem, I found that the root cause of the error was not necessarily the code itself, but rather the interaction between the code and the run time driver which determines how the GPU code is executed.  Specifically, during the very first step of the algorithm, the modified gradient algorithm is applied to the data.  For some reason, this otherwise straight forward code was producing slightly different results with sequential runs.  I actually narrowed it down to 1 line of code which, if removed, would stop the variability all together.  Interestingly, the drift did not show up in every scan.  As best I can determine, the root cause of the problem is that the memory access pattern for that portion of the code is pretty rough and so there must be some issue that arises there.  At any rate, now that it is "fixed", I can get back to sorting the paths traced out by the iliac tracking algorithm.
The next issue is that in the process of debugging the code, I uncovered numerous small issues which were contributing to the overall issues.  Now I have to go back and piece it all back together to make sure that nothing got broken in the process.  Specifically, I had to go through and clean up how the statistical data and results are stored.  The aortic tracking algorithm is running much more smoothly now that the code has been streamlined.