Traco Redesign

I've put together a pull request to help clarify some of the ideas I proposed earlier on this thread.

In this pull request there is an example called newApi.py this example still needs some work, but I hope it will help show how this new tracking framework is meant to be used. In the example I've done some probabilistic tracking with the CSA and CSD models and some deterministic tracking with the CSA model. Be warned that the CSD fitting takes about 45 min.

To describe how this works, in each of the three tracking examples I create a direction getter and a tissue classifier which I pass with seeds and affine and a step_size to LocalTracking.

LocalTracking is an example of what we've been calling a “streamline manager” it tracks each seed and yields a streamline if the streamline doesn't hit any invalid points during tracking.

For the deterministic tracking I've modified the PeaksAndMetrics class to make it a bonefied DirectionGetter. It calls existing cython code that was written for EuDx.

For something to be a  DirectionGetter it needs to subclass from dipy.tracking.local.DirectionGetter and implement a cython cdef method called get_direction. The cython requirement is so the inner tracking loop can be compiled. A DirectionGetter needs to also have an initial_direction method. This method is python for now (but we can change this).

For the probabilist tracking the direction getter is ProbabilisticOdfWightedDirectionGetter (I'm open to a more succinct name). I've written the it in python, but used a cython helper type to make it work. Let me know if anyone wants to hear me rant about how this awesomeness works.

I've implemented one example tissue classifier,  ThresholdTissueClassifier, which like direction getter has a cython method called check_point. This method returns the type of tissue to the streamline manager/framework which then has to decide what to do next.

This PR needs more tests, a better example and there are some corner cases to deal with (literally the interpolation breaks at the corners of the image). But I promised you guys some code so here it is
Could you explain here what you mean by "the input is clearly an odf,"
because I don't agree with that statement. Maybe because my background is
using bootstrap methods to estimate the PMF. Let me give you an example,
here is some psudo code:

pmf = zeros(sphere.theta.shape[0])
tensor_fit = tensor_model.fit(data)
for i in range(1000):
    boot_fit = tensor_fit.boostrap()
    direction = boot_fit.evecs[:, 0]
    closest_vert = closest(direction, sphere.vertices)
    pmf[closest_vert] += 1

There have been a few papers published on using bootstrap to estimate the
"cone of uncertainty" for fiber tracking, and, for a single fiber
population, this is a very good way to estimate the PMF. Much better than
using the FOD for example. I can dig up the references if you'd like. I
don't think dipy should be so ODF centric, especially because I've put so
much time into this and I'd like to represent some of the work that me and
my lab mates have been doing over the last 5-10 years.


On Tue, Sep 30, 2014 at 3:39 PM, Eleftherios Garyfallidis <
notifications@github.com> wrote:

> In dipy/tracking/local/direction_getter_py.py:
>
> > +        return peak_directions(blob, self.sphere, **self._pf_kwargs)[0]
> > +
> > +
> > +class ProbabilisticDirectionGetter(PeakDirectionGetter):
> > +    """Randomly samples direction of a sphere based on probability mass
> > +    function (pmf).
> > +
> > +    The main constructors for this class are current from_pmf and from_shfit.
> > +    The pmf gives the probability that each direction on the sphere should be
> > +    chosen as the next direction. To get the true pmf from the "raw pmf"
> > +    directions more than ``max_angle`` degrees from the incoming direction are
> > +    set to 0 and the result is normalized.
> > +
> > +    """
> > +    @classmethod
> > +    def from_pmf(klass, pmf, max_angle, sphere, **kwargs):
>
> Hi @MrBago <https://github.com/MrBago>. I had a meeting with @gabknight
> <https://github.com/gabknight> and still we see that it is not clear at
> this stage to use pmf in this method. The input here is clearly an odf. For
> example in Pandas when we use from_excel the input is an excel filename but
> the output is something else. You should use here from_odf but keep the
> classes above with the Pmf term SimplePmfGen. Then later if we had a method
> that uses the entire pdf we can say from_pdf but still it creates
> internally a Pfm. I think this change will clarify your design incredibly.
> Keep it up! @gabknight <https://github.com/gabknight> is back and will
> try to start the tractometer experiments tomorrow. GGT!!!
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/nipy/dipy/pull/341/files#r18252305>.
>