Esempio n. 1
0
def _check_data_size(par, data, sigmodel):
    if data.ndim == 5:
        pass
    elif data.ndim == 4 and "IRLL" in sigmodel:
        Nproj_new = 13
        print("4D Data passed and IRLL model used. Reordering Projections "
              "into " + str(Nproj_new) + " Spokes/Frame")
        [NC, reco_Slices, Nproj, N] = data.shape
        NScan = np.floor_divide(Nproj, Nproj_new)
        par["Nproj_measured"] = Nproj
        Nproj = Nproj_new
        data = np.require(
            np.transpose(
                np.reshape(data[..., :Nproj * NScan, :],
                           (NC, reco_Slices, NScan, Nproj, N)),
                (2, 0, 1, 3, 4),
            ),
            requirements="C",
        )
        par["traj"] = np.require(
            np.reshape(par["traj"][:Nproj * NScan, :], (NScan, Nproj, N)),
            requirements="C",
        )
        par["dcf"] = np.sqrt(goldcomp.cmp(par["traj"]))
        par["dcf"] = np.require(np.abs(par["dcf"]),
                                par["DTYPE_real"],
                                requirements="C")
    elif data.ndim == 4 and "ImageReco" in sigmodel:
        data = data[None]
    else:
        raise ValueError("Wrong data dimension / model incompatible.")
    return data
Esempio n. 2
0
def setupPar(par):
    par["NScan"] = 10
    par["NC"] = 8
    par["NSlice"] = 12
    par["dimX"] = 128
    par["dimY"] = 128
    par["Nproj"] = 34
    par["N"] = 256
    par["unknowns_TGV"] = 2
    par["unknowns_H1"] = 0
    par["unknowns"] = 2
    par["dz"] = 1
    par["weights"] = np.array([1, 1])
    par["overlap"] = 1
    file = h5py.File('./test/smalltest.h5', 'r')

    par["traj"] = file['real_traj'][()].astype(DTYPE) + \
        1j*file['imag_traj'][()].astype(DTYPE)

    par["dcf"] = np.sqrt(np.array(goldcomp.cmp(par["traj"]),
                                  dtype=DTYPE_real)).astype(DTYPE_real)
    par["dcf"] = np.require(np.abs(par["dcf"]), DTYPE_real, requirements='C')
    par["fft_dim"] = (-2, -1)
Esempio n. 3
0
def est_coils(data, par, file, args, off):
    """Estimate coil sensitivity profiles.

    This function estimates coil sensitivity profiles based on the
    non-linear inversion method from Uecker et al. It first checks if
    coil information is present in the given data file and if the size
    matches the number of slices that should be reconstructed. If the
    check fails, new coil sensitivity information is estimated and saved to
    the data file.

    Parameters
    ----------
      data : numpy.array
        The complex k-space data.
      par : dict
        Parameter dictionary.
      file : h5py.File
          A h5py.File possibly containing the coil profiles. Also used for
          storing newly computed profile information.
      args : argparse.ArgumentParser
        Commandline arguments passed to the script.
      off : int
        A possible offset of the zero slice.

    Returns
    -------
        numpy.array
            The complex coilsensitivity information.
    """
    ###########################################################################
    # Initiate parallel interface #############################################
    ###########################################################################
    c = ipp.Client()
    nlinvNewtonSteps = 6
    nlinvRealConstr = False
    if args.sms or "Coils_real" in list(file.keys()):
        print("Using precomputed coil sensitivities")
        slices_coils = file['Coils_real'][()].shape[1]
        par["C"] = file['Coils_real'][
            :,
            int(slices_coils / 2) - int(np.floor((par["NSlice"]) / 2)) + off:
            int(slices_coils / 2) + int(np.ceil(par["NSlice"] / 2)) + off,
            ...] + 1j * file['Coils_imag'][
            :,
            int(slices_coils / 2) - int(np.floor((par["NSlice"]) / 2)) + off:
            int(slices_coils / 2) + int(np.ceil(par["NSlice"] / 2)) + off,
            ...]
        par["C"] = par["C"].astype(par["DTYPE"])
    elif not args.sms and "Coils" in list(file.keys()):
        if args.trafo and not file['Coils'].shape[1] >= par["NSlice"]:

            traj_coil = np.reshape(
                par["traj"], (par["NScan"] * par["Nproj"], par["N"]))
            dcf_coil = np.sqrt(goldcomp.cmp(traj_coil))
            dcf_coil = np.require(dcf_coil,
                                  requirements='C',
                                  dtype=par["DTYPE_real"])

            par["C"] = np.zeros(
                (par["NC"], par["NSlice"], par["dimY"], par["dimX"]),
                dtype=par["DTYPE"])
            par["phase"] = np.zeros(
                (par["NSlice"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])

            par_coils = {}
            par_coils["traj"] = traj_coil
            par_coils["dcf"] = dcf_coil
            par_coils["N"] = par["N"]
            par_coils["NScan"] = 1
            par_coils["NC"] = 1
            par_coils["NSlice"] = 1
            par_coils["ctx"] = par["ctx"]
            par_coils["queue"] = par["queue"]
            par_coils["dimX"] = par["dimX"]
            par_coils["dimY"] = par["dimY"]
            par_coils["fft_dim"] = [-2, -1]
            FFT = utils.NUFFT(par_coils)

            result = []
            for i in range(0, (par["NSlice"])):
                sys.stdout.write(
                    "Computing coil sensitivity map of slice %i \r" %
                    (i))
                sys.stdout.flush()

                # RADIAL PART
                combinedData = np.transpose(
                    data[:, :, i, :, :], (1, 0, 2, 3))
                combinedData = np.require(
                    np.reshape(
                        combinedData,
                        (1,
                         par["NC"],
                            1,
                            par["NScan"] * par["Nproj"],
                            par["N"])),
                    requirements='C') * dcf_coil
                tmp_coilData = clarray.zeros(
                    FFT.queue, (1, 1, 1, par["dimY"], par["dimX"]),
                    dtype=par["DTYPE"])
                coilData = np.zeros(
                    (par["NC"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])
                for j in range(par["NC"]):
                    tmp_combinedData = clarray.to_device(
                        FFT.queue, combinedData[None, :, j, ...])
                    FFT.FFTH(tmp_coilData, tmp_combinedData)
                    coilData[j, ...] = np.squeeze(tmp_coilData.get())

                combinedData = np.require(
                    np.fft.fft2(
                        coilData,
                        norm=None) /
                    np.sqrt(
                        par["dimX"] *
                        par["dimY"]),
                    dtype=par["DTYPE"],
                    requirements='C')

                dview = c[int(np.floor(i * len(c) / par["NSlice"]))]
                result.append(
                    dview.apply_async(
                        nlinvns.nlinvns,
                        combinedData,
                        nlinvNewtonSteps,
                        True,
                        nlinvRealConstr,
                        DTYPE=par["DTYPE"],
                        DTYPE_real=par["DTYPE_real"]))

            for i in range(par["NSlice"]):
                par["C"][:, i, :, :] = result[i].get()[2:, -1, :, :]
                sys.stdout.write("slice %i done \r"
                                 % (i))
                sys.stdout.flush()
                if not nlinvRealConstr:
                    par["phase"][i, :, :] = np.exp(
                        1j * np.angle(result[i].get()[0, -1, :, :]))
            # standardize coil sensitivity profiles
            sumSqrC = np.sqrt(
                np.sum(
                    (par["C"] *
                     np.conj(
                        par["C"])),
                    0))
            par["InScale"] = sumSqrC
            if par["NC"] == 1:
                par["C"] = sumSqrC
            else:
                par["C"] = par["C"] / \
                    np.tile(sumSqrC, (par["NC"], 1, 1, 1))
            del file['Coils']
            del FFT
            file.create_dataset(
                "Coils",
                par["C"].shape,
                dtype=par["C"].dtype,
                data=par["C"])
            file.flush()
        elif not args.trafo and not \
                file['Coils'].shape[1] >= par["NSlice"]:

            par["C"] = np.zeros(
                (par["NC"], par["NSlice"], par["dimY"], par["dimX"]),
                dtype=par["DTYPE"])
            par["phase"] = np.zeros(
                (par["NSlice"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])

            result = []
            combinedData = np.sum(data, 0)
            for i in range(0, (par["NSlice"])):
                sys.stdout.write(
                    "Computing coil sensitivity map of slice %i \r" %
                    (i))
                sys.stdout.flush()

                tmp = combinedData[:, i, ...]
                dview = c[int(np.floor(i * len(c) / par["NSlice"]))]
                result.append(
                    dview.apply_async(
                        nlinvns.nlinvns,
                        tmp,
                        nlinvNewtonSteps,
                        True,
                        nlinvRealConstr,
                        DTYPE=par["DTYPE"],
                        DTYPE_real=par["DTYPE_real"]))

            for i in range(par["NSlice"]):
                par["C"][:, i, :, :] = result[i].get()[2:, -1, :, :]
                sys.stdout.write("slice %i done \r"
                                 % (i))
                sys.stdout.flush()
                if not nlinvRealConstr:
                    par["phase"][i, :, :] = np.exp(
                        1j * np.angle(result[i].get()[0, -1, :, :]))

                    # standardize coil sensitivity profiles
            sumSqrC = np.sqrt(
                np.sum(
                    (par["C"] *
                     np.conj(
                        par["C"])),
                    0))
            par["InScale"] = sumSqrC
            if par["NC"] == 1:
                par["C"] = sumSqrC
            else:
                par["C"] = par["C"] / \
                    np.tile(sumSqrC, (par["NC"], 1, 1, 1))
            del file['Coils']
            file.create_dataset(
                "Coils",
                par["C"].shape,
                dtype=par["C"].dtype,
                data=par["C"])
            file.flush()
        else:
            print("Using precomputed coil sensitivities")
            slices_coils = file['Coils'].shape[1]
            par["C"] = \
                file['Coils'][
                    :,
                    int(slices_coils / 2) -
                    int(np.floor((par["NSlice"]) / 2)) + off:
                    int(slices_coils / 2) +
                    int(np.ceil(par["NSlice"] / 2)) + off, ...]
            par["C"] = par["C"].astype(par["DTYPE"])

    else:
        if args.trafo:

            traj_coil = np.reshape(
                par["traj"], (par["NScan"] * par["Nproj"], par["N"]))
            dcf_coil = np.sqrt(goldcomp.cmp(traj_coil))
            dcf_coil = np.require(dcf_coil,
                                  requirements='C',
                                  dtype=par["DTYPE_real"])

            par["C"] = np.zeros(
                (par["NC"],
                 par["NSlice"],
                    par["dimY"],
                    par["dimX"]),
                dtype=par["DTYPE"])
            par["phase"] = np.zeros(
                (par["NSlice"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])

            par_coils = {}
            par_coils["traj"] = traj_coil
            par_coils["dcf"] = dcf_coil
            par_coils["dimX"] = par["dimX"]
            par_coils["dimY"] = par["dimY"]
            par_coils["N"] = par["N"]
            par_coils["NScan"] = 1
            par_coils["NC"] = 1
            par_coils["NSlice"] = 1
            par_coils["ctx"] = par["ctx"]
            par_coils["queue"] = par["queue"]
            par_coils["fft_dim"] = [-2, -1]
            FFT = utils.NUFFT(par_coils)

            result = []
            for i in range(0, (par["NSlice"])):
                sys.stdout.write(
                    "Computing coil sensitivity map of slice %i \r" %
                    (i))
                sys.stdout.flush()

                combinedData = np.transpose(data[:, :, i, :, :], (1, 0, 2, 3))
                combinedData = np.require(
                    np.reshape(
                        combinedData,
                        (1,
                         par["NC"],
                            1,
                            par["NScan"] * par["Nproj"],
                            par["N"])),
                    requirements='C') * dcf_coil
                tmp_coilData = clarray.zeros(
                    FFT.queue, (1, 1, 1, par["dimY"], par["dimX"]),
                    dtype=par["DTYPE"])
                coilData = np.zeros(
                    (par["NC"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])
                for j in range(par["NC"]):
                    tmp_combinedData = clarray.to_device(
                        FFT.queue, combinedData[None, :, j, ...])
                    FFT.FFTH(tmp_coilData, tmp_combinedData)
                    coilData[j, ...] = np.squeeze(tmp_coilData.get())

                combinedData = np.require(
                    np.fft.fft2(
                        coilData,
                        norm=None) /
                    np.sqrt(
                        par["dimX"] *
                        par["dimY"]),
                    dtype=par["DTYPE"],
                    requirements='C')

                dview = c[int(np.floor(i * len(c) / par["NSlice"]))]
                result.append(
                    dview.apply_async(
                        nlinvns.nlinvns,
                        combinedData,
                        nlinvNewtonSteps,
                        True,
                        nlinvRealConstr,
                        DTYPE=par["DTYPE"],
                        DTYPE_real=par["DTYPE_real"]))

            for i in range(par["NSlice"]):
                par["C"][:, i, :, :] = result[i].get()[2:, -1, :, :]
                sys.stdout.write("slice %i done \r"
                                 % (i))
                sys.stdout.flush()
                if not nlinvRealConstr:
                    par["phase"][i, :, :] = np.exp(
                        1j * np.angle(result[i].get()[0, -1, :, :]))

                    # standardize coil sensitivity profiles
            sumSqrC = np.sqrt(
                np.sum(
                    (par["C"] *
                     np.conj(
                        par["C"])),
                    0))
            par["InScale"] = sumSqrC
            if par["NC"] == 1:
                par["C"] = sumSqrC
            else:
                par["C"] = par["C"] / np.tile(sumSqrC, (par["NC"], 1, 1, 1))
            del FFT
        else:

            par["C"] = np.zeros(
                (par["NC"],
                 par["NSlice"],
                    par["dimY"],
                    par["dimX"]),
                dtype=par["DTYPE"])
            par["phase"] = np.zeros(
                (par["NSlice"], par["dimY"], par["dimX"]), dtype=par["DTYPE"])

            result = []
            combinedData = np.sum(data, 0)
            for i in range(0, (par["NSlice"])):
                sys.stdout.write(
                    "Computing coil sensitivity map of slice %i \r" %
                    (i))
                sys.stdout.flush()

                # RADIAL PART
                tmp = combinedData[:, i, ...]
                dview = c[int(np.floor(i * len(c) / par["NSlice"]))]
                result.append(
                    dview.apply_async(
                        nlinvns.nlinvns,
                        tmp,
                        nlinvNewtonSteps,
                        True,
                        nlinvRealConstr,
                        DTYPE=par["DTYPE"],
                        DTYPE_real=par["DTYPE_real"]))

            for i in range(par["NSlice"]):
                par["C"][:, i, :, :] = result[i].get()[2:, -1, :, :]
                sys.stdout.write("slice %i done \r"
                                 % (i))
                sys.stdout.flush()
                if not nlinvRealConstr:
                    par["phase"][i, :, :] = np.exp(
                        1j * np.angle(result[i].get()[0, -1, :, :]))
                    # standardize coil sensitivity profiles
            sumSqrC = np.sqrt(
                np.sum(
                    (par["C"] *
                     np.conj(
                        par["C"])),
                    0))
            par["InScale"] = sumSqrC
            if par["NC"] == 1:
                par["C"] = sumSqrC[None, ...]
            else:
                par["C"] = par["C"] / np.tile(sumSqrC, (par["NC"], 1, 1, 1))
        file.create_dataset(
            "Coils",
            par["C"].shape,
            dtype=par["C"].dtype,
            data=par["C"])
        file.flush()
Esempio n. 4
0
def _read_data_from_file(par, myargs):
    reco_Slices = myargs.slices
    dimX, dimY, NSlice = (par["file"].attrs["image_dimensions"]).astype(int)
    if reco_Slices == -1:
        reco_Slices = NSlice
    off = 0

    if myargs.sms or myargs.is3Ddata:
        data = par["file"]["real_dat"][()].astype(
            par["DTYPE"]) + 1j * par["file"]["imag_dat"][
                ()].astype(par["DTYPE"])
    else:
        data = (par["file"]["real_dat"][...,
                                        int(NSlice / 2) -
                                        int(np.floor((reco_Slices) / 2)) +
                                        off:int(NSlice / 2) +
                                        int(np.ceil(reco_Slices / 2)) +
                                        off, :, :, ].astype(par["DTYPE"]) +
                1j * par["file"]["imag_dat"]
                [...,
                 int(NSlice / 2) - int(np.floor((reco_Slices) / 2)) +
                 off:int(NSlice / 2) + int(np.ceil(reco_Slices / 2)) +
                 off, :, :, ].astype(par["DTYPE"]))

    dimreduction = 0
    if myargs.trafo:
        if "real_traj" in par["file"].keys():
            par["traj"] = np.stack(
                (
                    par["file"]["imag_traj"][()].astype(par["DTYPE_real"]),
                    par["file"]["real_traj"][()].astype(par["DTYPE_real"]),
                ),
                axis=-1,
            )
        else:
            par["traj"] = par["file"]["traj"][()].astype(par["DTYPE_real"])

        if "dcf" in par["file"].keys():
            par["dcf"] = np.sqrt(par["file"]["dcf"][()].astype(
                par["DTYPE_real"]))
        else:
            par["dcf"] = np.sqrt(goldcomp.cmp(par["traj"]))
        par["dcf"] = np.require(np.abs(par["dcf"]),
                                par["DTYPE_real"],
                                requirements="C")

        # Check if traj is scaled
        max_traj_val = np.max(np.abs(par["traj"]))
        if np.allclose(max_traj_val, 0.5, rtol=1e-1):
            par["traj"] *= dimX
        elif np.allclose(max_traj_val, 1, rtol=1e-1):
            par["traj"] *= dimX / 2

        overgrid_factor_a = 1 / np.linalg.norm(
            par["traj"][..., -2, :] - par["traj"][..., -1, :], axis=-1)
        overgrid_factor_b = 1 / np.linalg.norm(
            par["traj"][..., 0, :] - par["traj"][..., 1, :], axis=-1)
        par["ogf"] = np.min((overgrid_factor_a, overgrid_factor_b))
        print("Estimated OGF: ", par["ogf"])
        par["traj"] *= par["ogf"]
    else:
        par["traj"] = None
        par["dcf"] = None

    #### Need to rework this as it might introduce unknown errors in
    #### Cartesian data!
    if np.max(utils.prime_factors(data.shape[-1])) > 13:
        print("Samples along the spoke need to have their largest prime factor"
              " to be 13 or lower. Finding next smaller grid.")
        dimreduction = 2
        while np.max(utils.prime_factors(data.shape[-1] - dimreduction)) > 13:
            dimreduction += 2
        print("Decrease grid size by %i" % dimreduction)
        dimX -= dimreduction
        dimY -= dimreduction
        if myargs.trafo:
            data = np.require(
                data[...,
                     int(dimreduction / 2):data.shape[-1] -
                     int(dimreduction / 2)],
                requirements="C",
            )
            par["traj"] = np.require(
                par["traj"][...,
                            int(dimreduction / 2):par["traj"].shape[-1] -
                            int(dimreduction / 2), ],
                requirements="C",
            )
            par["dcf"] = np.sqrt(goldcomp.cmp(par["traj"]))
            par["dcf"] = np.require(np.abs(par["dcf"]),
                                    par["DTYPE_real"],
                                    requirements="C")
        else:
            data = np.require(
                data[...,
                     int(dimreduction /
                         2):data.shape[-1] - int(dimreduction / 2),
                     int(dimreduction / 2):data.shape[-1] -
                     int(dimreduction / 2), ],
                requirements="C",
            )
    return data, dimX, dimY, NSlice, reco_Slices, dimreduction, off
Esempio n. 5
0
def _read_data_from_file(par, myargs):
    reco_Slices = myargs.slices
    dimX, dimY, NSlice = ((par["file"].attrs['image_dimensions']).astype(int))
    if reco_Slices == -1:
        reco_Slices = NSlice
    off = 0

    if myargs.sms:
        data = par["file"]['real_dat'][()].astype(par["DTYPE"])\
               + 1j*par["file"]['imag_dat'][()].astype(par["DTYPE"])
    else:
        data = par["file"]['real_dat'][
          ...,
          int(NSlice/2)-int(np.floor((reco_Slices)/2))+off:
          int(NSlice/2)+int(np.ceil(reco_Slices/2))+off, :, :
              ].astype(par["DTYPE"])\
               + 1j*par["file"]['imag_dat'][
          ...,
          int(NSlice/2)-int(np.floor((reco_Slices)/2))+off:
          int(NSlice/2)+int(np.ceil(reco_Slices/2))+off, :, :
              ].astype(par["DTYPE"])

    dimreduction = 0
    if myargs.trafo:
        par["traj"] = par["file"]['real_traj'][()].astype(par["DTYPE"]) + \
                      1j*par["file"]['imag_traj'][()].astype(par["DTYPE"])

        par["dcf"] = np.sqrt(goldcomp.cmp(par["traj"]))
        par["dcf"] = np.require(np.abs(par["dcf"]),
                                par["DTYPE_real"],
                                requirements='C')
    else:
        par["traj"] = None
        par["dcf"] = None
    if np.max(utils.prime_factors(data.shape[-1])) > 13:
        print("Samples along the spoke need to have their largest prime factor"
              " to be 13 or lower. Finding next smaller grid.")
        dimreduction = 2
        while np.max(utils.prime_factors(data.shape[-1] - dimreduction)) > 13:
            dimreduction += 2
        print('Decrease grid size by %i' % dimreduction)
        dimX -= dimreduction
        dimY -= dimreduction
        if myargs.trafo:
            data = np.require(data[...,
                                   int(dimreduction / 2):data.shape[-1] -
                                   int(dimreduction / 2)],
                              requirements='C')
            par["traj"] = np.require(par["traj"][...,
                                                 int(dimreduction /
                                                     2):par["traj"].shape[-1] -
                                                 int(dimreduction / 2)],
                                     requirements='C')
            par["dcf"] = np.sqrt(goldcomp.cmp(par["traj"]))
            par["dcf"] = np.require(np.abs(par["dcf"]),
                                    par["DTYPE_real"],
                                    requirements='C')
        else:
            data = np.require(data[...,
                                   int(dimreduction / 2):data.shape[-1] -
                                   int(dimreduction / 2),
                                   int(dimreduction / 2):data.shape[-1] -
                                   int(dimreduction / 2)],
                              requirements='C')
    return data, dimX, dimY, NSlice, reco_Slices, dimreduction, off