OK - I chose a compromise solution. I am still using the ADC to calculate
the predicted signal, but I am using the much simpler form with a newly
generated design matrix to calculate that. What do you think?


On Thu, Aug 15, 2013 at 2:20 PM, MrBago <notifications@github.com> wrote:

> In dipy/reconst/dti.py:
>
> > +
> > +    Notes
> > +    -----
> > +    The calculation of ADC, relies on the following relationship:
> > +
> > +    .. math ::
> > +            ADC = \vec{b} Q \vec{b}^T
> > +
> > +    Where Q is the quadratic form of the tensor.
> > +
> > +    """
> > +    bvecs = sphere.vertices
> > +    mult1 = np.tensordot(bvecs, q_form, (1, len(q_form.shape[:-2])))
> > +    transposer = list(np.arange(1, len(q_form.shape[:-2])+1))  + [0, -1]
> > +    mult2 = np.dot(np.transpose(mult1, transposer),  bvecs.T)
> > +    return mult2[..., np.arange(bvecs.shape[0]), np.arange(bvecs.shape[0])]
>
> Just gard code the b value to 1 for adc calculation, or we could refactor
> the design matrix function.
> … <#14083dec1696d73a_>
> On Aug 15, 2013 1:45 PM, "Ariel Rokem" <notifications@github.com> wrote:
> In dipy/reconst/dti.py: > + > + Notes > + ----- > + The calculation of ADC,
> relies on the following relationship: > + > + .. math :: > + ADC = \vec{b}
> Q \vec{b}^T > + > + Where Q is the quadratic form of the tensor. > + > +
> """ > + bvecs = sphere.vertices > + mult1 = np.tensordot(bvecs, q_form, (1,
> len(q_form.shape[:-2]))) > + transposer = list(np.arange(1,
> len(q_form.shape[:-2])+1)) + [0, -1] > + mult2 = np.dot(np.transpose(mult1,
> transposer), bvecs.T) > + return mult2[..., np.arange(bvecs.shape[0]),
> np.arange(bvecs.shape[0])] Good points. The math there is indeed a bit
> convoluted (took me a while to understand how to get `tensordot` to
> behave...) and the . In fact, the predicted signal is already being
> computed this way as part of the implementation of RESTORE:
> https://github.com/nipy/dipy/blob/master/dipy/reconst/dti.py#L1084 The
> only issue that I have with your suggestion is that the current
> implementation of `design_matrix` includes the b value in it, so we could
> not get the ADC using that, unless we refactor it to not have the b value,
> or divide it by the b value when it comes out from there. I will ultimately
> need the ADC computation as well, for this:
> https://github.com/arokem/dipy/blob/dki/dipy/reconst/dki.py which is WIP
> on yet another branch (!), so we may as well make it computable here.
> Either way, we would have to generate a new design_matrix with the new
> directions from the provided `gtab` input, but that's no big deal. …
> <#14083b99b885a61b_> On Thu, Aug 15, 2013 at 12:14 PM, MrBago <
> notifications@github.com> wrote: In dipy/reconst/dti.py: > + > + Notes >
> + ----- > + The calculation of ADC, relies on the following relationship: >
> + > + .. math :: > + ADC = \vec{b} Q \vec{b}^T > + > + Where Q is the
> quadratic form of the tensor. > + > + """ > + bvecs = sphere.vertices > +
> mult1 = np.tensordot(bvecs, q_form, (1, len(q_form.shape[:-2]))) > +
> transposer = list(np.arange(1, len(q_form.shape[:-2])+1)) + [0, -1] > +
> mult2 = np.dot(np.transpose(mult1, transposer), bvecs.T) > + return
> mult2[..., np.arange(bvecs.shape[0]), np.arange(bvecs.shape[0])] The math
> here looks a bit convoluted, you can get the adc by doing
> -np.dot(tensor.lower_triangular, desing_matrix.T), if you set bval to 1
> when you build the design_matrix. You can get the predicted signal by doing
> np.exp(np.dot(tensor.lower_triangular(b0_signal), desing_matrix.T)). Do you
> want me to take a closer look at this? — Reply to this email directly or
> view it on GitHub< https://github.com/nipy/dipy/pull/230/files#r5797817>
> . — Reply to this email directly or view it on GitHub<
> https://github.com/nipy/dipy/pull/230/files#r5800445> .
>
> —
> Reply to this email directly or view it on GitHub<https://github.com/nipy/dipy/pull/230/files#r5801673>
> .
>