示例#1
0
def quantitative_fm(Mxys, dfs, T1s, T2s, PDs, TR, alpha, phase_cyc, mask=None):
    '''Find field map given quantitative maps.
    '''

    resps = {}
    orig_size = np.asarray(T1s).shape

    if mask is None:
        mask = np.ones(Mxys.shape)

    Mxys = np.asarray(Mxys).flatten()
    T1s = np.asarray(T1s).flatten()
    T2s = np.asarray(T2s).flatten()
    PDs = np.asarray(PDs).flatten()
    mask = np.asarray(mask).flatten()

    fm = np.zeros(Mxys.size)
    for ii in range(Mxys.size):

        if mask[ii]:
            # Cache results for later in case we come across the same T1,T2,PD
            if (PDs[ii], T1s[ii], T2s[ii]) not in resps:
                resps[(PDs[ii], T1s[ii],
                       T2s[ii])] = get_df_responses(T1s[ii], T2s[ii], PDs[ii],
                                                    TR, alpha, phase_cyc, dfs)

            # Find the appropriate off-resonance value for this T1,T2,PD,Mxy
            idx, val = find_nearest(resps[(PDs[ii], T1s[ii], T2s[ii])],
                                    Mxys[ii])
            fm[ii] = dfs[idx]
        else:
            fm[ii] = 0

    return (fm.reshape(orig_size))
def quantitative_fm(Mxys, dfs, T1s, T2s, PDs, TR, alpha, phase_cyc, mask=None):
    '''Find field map given quantitative maps.

    Parameters
    ==========
    Mxys : array_like
        Complex transverse signal we measure.
    dfs : array_like
        Off-resonance values to simulate over.
    T1s : array_like
        scalar T1 longitudinal recovery value in seconds.
    T2s : array_like
        scalar T2 transverse decay value in seconds.
    PDs : array_like
        scalar proton density value scaled the same as acquisiton.
    TR : float
        Repetition time in seconds.
    alpha : float
        Flip angle in radians.
    phase_cyc : float
        RF phase cycling in radians.
    mask : array_like
        Boolean mask to tell which pixels we should compute df for.

    Returns
    =======
    fm : array_like
        Field map.
    '''

    resps = {}
    orig_size = np.asarray(T1s).shape

    if mask is None:
        mask = np.ones(Mxys.shape)

    Mxys = np.asarray(Mxys).flatten()
    T1s = np.asarray(T1s).flatten()
    T2s = np.asarray(T2s).flatten()
    PDs = np.asarray(PDs).flatten()
    mask = np.asarray(mask).flatten()

    fm = np.zeros(Mxys.size)
    for ii in range(Mxys.size):

        if mask[ii]:
            # Cache results for later in case we come across the same T1,T2,PD
            if (PDs[ii], T1s[ii], T2s[ii]) not in resps:
                resps[(PDs[ii], T1s[ii],
                       T2s[ii])] = get_df_responses(T1s[ii], T2s[ii], PDs[ii],
                                                    TR, alpha, phase_cyc, dfs)

            # Find the appropriate off-resonance value for this T1,T2,PD,Mxy
            idx, _val = find_nearest(resps[(PDs[ii], T1s[ii], T2s[ii])],
                                     Mxys[ii])
            fm[ii] = dfs[idx]
        else:
            fm[ii] = 0

    return fm.reshape(orig_size)
示例#3
0
def random_match_by_col(x, T, return_sorted=False):
    '''Given matrix T, choose reordering of x that matches it col by col.

    Parameters
    ==========
    x : array_like
        Array to find ordering of.
    T : array_like
        Target matrix.
    return_sorted : bool, optional
        Whether or not to return the sorted matrix.

    Returns
    =======
    idx : array_like
        Flattened indices giving sorted order.
    array_like, optional
        Sorted array.
    '''

    # Find number of basis functions, fi, and number of samples, M
    M, N = T.shape[:]

    # Keep a list of fij that we haven't done yet
    fijs = list(range(M))

    # Find a good ordering for each basis function
    done = False
    xk = x.copy()
    f = np.zeros(T.shape, dtype=x.dtype)
    indices = np.arange(x.size).reshape(x.shape)
    with tqdm(desc='Matching', total=M, leave=False) as pbar:
        while not done:

            # Choose a row
            idx = np.random.choice(np.arange(len(fijs)))
            jj = fijs[idx]

            # Choose a column
            for ii in np.random.permutation(list(range(N))):
                ind, f[ii, jj] = find_nearest(xk, T[ii, jj])
                indices[ii, jj] = ind
                xk[np.unravel_index(ind, x.shape)] = np.inf

            # Finalize the best fit, i.e., min || f[:, jj] - X[jj] ||
            min_err = np.abs((f - T)**2).mean(axis=0).argsort().tolist()
            min_err = [me for me in min_err if me in fijs]
            fijs.remove(min_err[0])

            # Check the stopping condition
            if not fijs:
                done = True
            pbar.update(1)

    # If we asked for the sorted matrix, send it back, too
    if return_sorted:
        return(indices.flatten(), f)
    return indices.flatten()
示例#4
0
def quantitative_fm_scalar(Mxy, dfs, T1, T2, PD, TR, alpha, phase_cyc):
    '''For scalar T1,T2,PD'''

    # Simulate over the total range of off-resonance values
    resp = get_df_responses(T1, T2, PD, TR, alpha, phase_cyc, dfs)

    # Find the response that matches Mxy most closely
    idx, val = find_nearest(resp, Mxy)

    # Return the df's value, because that's really what the caller wanted
    return (dfs[idx])
示例#5
0
def gen_sort1d(x, T):
    '''Given 1D transform T, sort 1d signal, x.

    Parameters
    ==========
    x : array_like
        1D signal to find ordering of.
    T : array_like
        Transform matrix.

    Returns
    =======
    array_like
        Flattened indices giving sorted order.
    '''

    M, N = T.shape[:]
    assert x.size == N, 'T, x must be conformal!'

    # Get a list of all columns
    cols = list(range(N))

    f = np.zeros(T.shape, dtype=x.dtype)
    indices = np.tile(np.arange(x.size)[:, None], (1, N))

    # Order x to approximate a single column of T
    for col in cols:
        xk = x.copy()
        for row in range(M):
            ind, f[row, col] = find_nearest(xk, T[row, col])
            indices[row, col] = ind
            xk[ind] = np.inf

    min_err = np.abs((f - T)**2).mean(axis=0).argsort()

    return indices[:, min_err[0]]
def quantitative_fm_scalar(Mxy, dfs, T1, T2, PD, TR, alpha, phase_cyc):
    '''For scalar T1, T2, PD.

    Parameters
    ==========
    Mxy : float
        Complex transverse signal we measure.
    dfs : array_like
        Off-resonance values to simulate over.
    T1 : float
        scalar T1 longitudinal recovery value in seconds.
    T2 : float
        scalar T2 transverse decay value in seconds.
    PD : float
        scalar proton density value scaled the same as acquisiton.
    TR : float
        Repetition time in seconds.
    alpha : float
        Flip angle in radians.
    phase_cyc : float
        RF phase cycling in radians.

    Returns
    =======
    float
        Off-resonace value that most closely matches Mxy prior.
    '''

    # Simulate over the total range of off-resonance values
    resp = get_df_responses(T1, T2, PD, TR, alpha, phase_cyc, dfs)

    # Find the response that matches Mxy most closely
    idx, _val = find_nearest(resp, Mxy)

    # Return the df's value, because that's really what the caller wanted
    return dfs[idx]