Esempio n. 1
0
    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        self.log_parameters = False
        self.re_init_at_iteration = 0
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history['alpha'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['beta'] = np.zeros([iterations],
                                                 dtype=np.float32)
            parameter_history['gamma'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['q_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            parameter_history['s_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            self.parameter_history = parameter_history

        self.__r__ = self.proj - \
            Ax(self.res, self.geo, self.angles, 'Siddon', gpuids = self.gpuids)
        self.__p__ = Atb(self.__r__, self.geo, self.angles, gpuids=self.gpuids)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm
Esempio n. 2
0
 def reinitialise_cgls(self):
     self.__r__ = self.proj - Ax(
         self.res, self.geo, self.angles, "Siddon", gpuids=self.gpuids)
     self.__p__ = Atb(self.__r__,
                      self.geo,
                      self.angles,
                      backprojection_type="matched",
                      gpuids=self.gpuids)
     p_norm = np.linalg.norm(self.__p__.ravel(), 2)
     self.__gamma__ = p_norm * p_norm
Esempio n. 3
0
    def run_main_iter(self):
        self.res[self.res < 0.0] = 0.0
        for i in range(self.niter):
            self._estimate_time_until_completion(i)

            den = Ax(self.res,
                     self.geo,
                     self.angles,
                     "interpolated",
                     gpuids=self.gpuids)
            # toc = time.process_time()
            # print('Ax time: {}'.format(toc-tic))
            den[den == 0.0] = np.inf
            auxmlem = self.proj / den
            # auxmlem[auxmlem == np.nan] = 0.
            # auxmlem[auxmlem == np.inf] = 0.

            # update
            # tic = time.process_time()
            img = Atb(auxmlem,
                      self.geo,
                      self.angles,
                      backprojection_type="matched",
                      gpuids=self.gpuids) / self.W
            # toc = time.process_time()
            # print('Atb time: {}'.format(toc-tic))
            # img[img == np.nan] = 0.
            # img[img == np.inf] = 0.

            self.res = self.res * img
            self.res[self.res < 0.0] = 0.0
Esempio n. 4
0
    def update_image(self, geo, angle, iteration):
        """
        VERBOSE:
         for j in range(angleblocks):
             angle = np.array([alpha[j]], dtype=np.float32)
             proj_err = proj[angle_index[j]] - Ax(res, geo, angle, 'Siddon')
             weighted_err = W[angle_index[j]] * proj_err
             backprj = Atb(weighted_err, geo, angle, 'FDK')
             weighted_backprj = 1 / V[angle_index[j]] * backprj
             res += weighted_backprj
             res[res<0]=0

        :return: None
        """

        ang_index = self.angle_index[iteration].astype(np.int)

        self.res += (
            self.lmbda
            * 1.0
            / self.V[iteration]
            * Atb(
                self.W[ang_index]
                * (self.proj[ang_index] - Ax(self.res, geo, angle, "Siddon", gpuids=self.gpuids)),
                geo,
                angle,
                "FDK",
                gpuids=self.gpuids,
            )
        )
Esempio n. 5
0
    def run_main_iter(self):
        self.res[self.res < 0.0] = 0.0
        for i in range(self.niter):
            if self.Quameasopts is not None:
                res_prev = copy.deepcopy(self.res)
            self._estimate_time_until_completion(i)

            den = Ax(self.res,
                     self.geo,
                     self.angles,
                     "interpolated",
                     gpuids=self.gpuids)
            den[den == 0.0] = np.inf
            auxmlem = self.proj / den

            # update
            img = Atb(auxmlem,
                      self.geo,
                      self.angles,
                      backprojection_type="matched",
                      gpuids=self.gpuids) / self.W

            self.res = self.res * img
            self.res[self.res < 0.0] = 0.0
            if self.Quameasopts is not None:
                self.error_measurement(res_prev, i)
Esempio n. 6
0
    def run_main_iter(self):
        self.res[self.res < 0.] = 0.
        for i in range(self.niter):
            if i == 0:
                if self.verbose:
                    print("MLEM Algorithm in progress.")
                toc = default_timer()
            if i == 1:
                tic = default_timer()
                if self.verbose:
                    print(
                        'Esitmated time until completetion (s): {:.4f}'.format(
                            (self.niter - 1) * (tic - toc)))


#            tic = time.process_time()
            den = Ax(self.res, self.geo, self.angles, 'interpolated')
            # toc = time.process_time()
            # print('Ax time: {}'.format(toc-tic))
            den[den == 0.] = np.inf
            auxmlem = self.proj / den
            # auxmlem[auxmlem == np.nan] = 0.
            # auxmlem[auxmlem == np.inf] = 0.

            # update
            # tic = time.process_time()
            img = Atb(auxmlem, self.geo, self.angles) / self.W
            # toc = time.process_time()
            # print('Atb time: {}'.format(toc-tic))
            # img[img == np.nan] = 0.
            # img[img == np.inf] = 0.

            self.res = self.res * img
            self.res[self.res < 0.] = 0.
Esempio n. 7
0
    def set_v(self):
        """
        Computes value of V parameter if this is not given.
        :return: None
        """
        geo = self.geo
        V = np.ones((self.angleblocks.shape[0], geo.nVoxel[1], geo.nVoxel[2]),
                    dtype=np.float32)

        for i in range(self.angleblocks.shape[0]):
            if geo.mode != 'parallel':

                geox = copy.deepcopy(self.geo)
                geox.angles = self.angleblocks[i]
                # shrink the volume size to avoid zeros in backprojection
                geox.sVoxel = geox.sVoxel * np.max(
                    geox.sVoxel[1:] / np.linalg.norm(geox.sVoxel[1:])) * 0.9
                geox.dVoxel = geox.sVoxel / geox.nVoxel
                proj_one = np.ones((len(
                    self.angleblocks[i]), geo.nDetector[0], geo.nDetector[1]),
                                   dtype=np.float32)
                V[i] = Atb(proj_one, geox, self.angleblocks[i],
                           'FDK').mean(axis=0)

            else:
                V[i] *= len(self.angleblocks[i])

        setattr(self, 'V', V)
    def run_main_iter(self):
        self.l2l = np.zeros([self.niter], dtype=np.float32)
        for i in range(self.niter):
            if i == 0:
                print("CGLS Algorithm in progress.")
                toc = time.clock()
            if i == 1:
                tic = time.clock()
                print('Esitmated time until completetion (s): ' + str((self.niter - 1) * (tic - toc)))
            q = Ax(self._p, self.geo, self.angles, 'ray-voxel')
            q_norm = np.linalg.norm(q.ravel(), 2)
            alpha = self._gamma / (q_norm * q_norm)
            self.res += alpha * self._p
            error = False
            for item in self.__dict__:
                if type(getattr(self,item)) == np.ndarray:
                    if np.isnan(getattr(self,item)).any():
                        print(item, i)
                        error = True
            if error:
                break

            aux = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
            self.l2l[i] = np.linalg.norm(aux.ravel(), 2)

            if i > 0 and self.l2l[i] > self.l2l[i - 1]:
                print('re-initialization was called at iter:' + str(i))
                self.res -= alpha * self._p
                self.initialise_cgls()

            self._r -= alpha * q
            s = Atb(self._r, self.geo, self.angles)
            s_norm = np.linalg.norm(s.ravel(), 2)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self._gamma
            if self.log_parameters:
                self.parameter_history['alpha'][i] = alpha
                self.parameter_history['beta'][i] = beta
                self.parameter_history['gamma'][i] = self._gamma
                self.parameter_history['q_norm'][i] = q_norm
                self.parameter_history['s_norm'][i] = s_norm

            self._gamma = gamma1
            self._p = s + beta * self._p
Esempio n. 9
0
 def test_backproj_parallel_spherical_shape(self):
     setattr(self.geo, 'mode', 'parallel')
     angles_1 = self.angles
     angles_2 = np.ones(
         (len(angles_1)), dtype=np.float32) * np.array([np.pi / 4],
                                                       dtype=np.float32)
     angles_3 = np.zeros((len(angles_1)), dtype=np.float32)
     new_angles = np.vstack((angles_1, angles_2, angles_3)).T
     self.assertTupleEqual(
         Atb(self.proj, self.geo, new_angles).shape, (63, 62, 61))
Esempio n. 10
0
def fbp(proj,geo,angles,filter=None,verbose=False):
    if geo.mode != 'parallel':
        raise ValueError("Only use FBP for parallel beam. Check geo.mode.")
    geox = copy.deepcopy(geo)
    geox.check_geo(angles)
    proj_filt = filtering(proj,geox,angles,parker=False,verbose=verbose)

    res = Atb(proj_filt,geo,angles)*geo.DSO/geo.DSD

    return res
Esempio n. 11
0
    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.init is None:
            self.res += 1.

        self.W = Atb(np.ones(proj.shape, dtype=np.float32), geo, angles)
        self.W[self.W <= 0.] = np.inf
Esempio n. 12
0
    def run_main_iter(self):
        self.l2l = np.zeros([self.niter], dtype=np.float32)
        for i in range(self.niter):
            if i == 0:
                print("CGLS Algorithm in progress.")
                toc = time.clock()
            if i == 1:
                tic = time.clock()
                print('Esitmated time until completetion (s): ' + str((self.niter - 1) * (tic - toc)))
            q = Ax(self.__p__, self.geo, self.angles, 'ray-voxel')
            q_norm = np.linalg.norm(q.ravel(), 2)
            alpha = self.__gamma__ / (q_norm * q_norm)
            self.res += alpha * self.__p__

            for item in self.__dict__:
                if type(getattr(self, item)) == np.ndarray:
                    if np.isnan(getattr(self, item)).any():
                        raise ValueError('nan found for ' + item + ' at iteraton ' + str(i))

            aux = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
            self.l2l[i] = np.linalg.norm(aux.ravel(), 2)
            if i > 0 and self.l2l[i] > self.l2l[i - 1]:
                print('re-initialization was called at iter:' + str(i))
                self.res -= alpha * self.__p__
                self.reinitialise_cgls()

            self.__r__ -= alpha * q
            s = Atb(self.__r__, self.geo, self.angles)
            s_norm = np.linalg.norm(s.ravel(), 2)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self.__gamma__
            if self.log_parameters:
                self.parameter_history['alpha'][i] = alpha
                self.parameter_history['beta'][i] = beta
                self.parameter_history['gamma'][i] = self.__gamma__
                self.parameter_history['q_norm'][i] = q_norm
                self.parameter_history['s_norm'][i] = s_norm

            self.__gamma__ = gamma1
            self.__p__ = s + beta * self.__p__
Esempio n. 13
0
def fbp(proj, geo, angles, **kwargs):  # noqa: D103
    __doc__ = FDK.__doc__  # noqa: F841
    if geo.mode != "parallel":
        raise ValueError("Only use FBP for parallel beam. Check geo.mode.")
    geox = copy.deepcopy(geo)
    geox.check_geo(angles)
    verbose = kwargs["verbose"] if "verbose" in kwargs else False
    gpuids = kwargs["gpuids"] if "gpuids" in kwargs else None
    proj_filt = filtering(copy.deepcopy(proj),
                          geox,
                          angles,
                          parker=False,
                          verbose=verbose)
    return Atb(proj_filt, geo, angles, gpuids=gpuids) * geo.DSO / geo.DSD
Esempio n. 14
0
    def update_image(self, geo, angle, iteration):
        """
        VERBOSE:
         for j in range(angleblocks):
             angle = np.array([alpha[j]], dtype=np.float32)
             proj_err = proj[angle_index[j]] - Ax(res, geo, angle, 'ray-voxel')
             weighted_err = W[angle_index[j]] * proj_err
             backprj = Atb(weighted_err, geo, angle, 'FDK')
             weighted_backprj = 1 / V[angle_index[j]] * backprj
             res += weighted_backprj
             res[res<0]=0

        :return: None
        """
        self.res += self.lmbda * 1. / self.V[iteration] * Atb(self.W[self.angle_index[iteration]] * (
            self.proj[self.angle_index[iteration]] - Ax(self.res, geo, angle, 'interpolated')), geo, angle, 'FDK')
Esempio n. 15
0
def fbp(proj, geo, angles, **kwargs):
    __doc__ = FDK.__doc__
    if geo.mode != 'parallel':
        raise ValueError("Only use FBP for parallel beam. Check geo.mode.")
    geox = copy.deepcopy(geo)
    geox.check_geo(angles)
    if 'verbose' in kwargs:
        verbose = kwargs['verbose']
    else:
        verbose = False

    proj_filt = filtering(copy.deepcopy(proj),
                          geox,
                          angles,
                          parker=False,
                          verbose=verbose)
    res = Atb(proj_filt, geo, angles) * geo.DSO / geo.DSD

    return res
Esempio n. 16
0
    def set_v(self):
        """
        Computes value of V parameter if this is not given.
        :return: None
        """
        block_count = len(self.angleblocks)
        geo = self.geo
        V = np.ones((block_count, geo.nVoxel[1], geo.nVoxel[2]),
                    dtype=np.float32)

        for i in range(block_count):
            if geo.mode != "parallel":

                geox = copy.deepcopy(self.geo)
                geox.angles = self.angleblocks[i]

                geox.DSD = geo.DSD[self.angle_index[i]]
                geox.DSO = geo.DSO[self.angle_index[i]]
                geox.offOrigin = geo.offOrigin[self.angle_index[i], :]
                geox.offDetector = geo.offDetector[self.angle_index[i], :]
                geox.rotDetector = geo.rotDetector[self.angle_index[i], :]
                geox.COR = geo.COR[self.angle_index[i]]

                # shrink the volume size to avoid zeros in backprojection
                geox.sVoxel = (geox.sVoxel * np.max(
                    geox.sVoxel[1:] / np.linalg.norm(geox.sVoxel[1:])) * 0.9)
                geox.dVoxel = geox.sVoxel / geox.nVoxel
                proj_one = np.ones((len(
                    self.angleblocks[i]), geo.nDetector[0], geo.nDetector[1]),
                                   dtype=np.float32)
                V[i] = Atb(proj_one,
                           geox,
                           self.angleblocks[i],
                           "FDK",
                           gpuids=self.gpuids).mean(axis=0)

            else:
                V[i] *= len(self.angleblocks[i])
        V[V == 0.0] = np.inf

        self.V = V
Esempio n. 17
0
    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        self.log_parameters = False
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history['alpha'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['beta'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['gamma'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['q_norm'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['s_norm'] = np.zeros([iterations], dtype=np.float32)
            self.parameter_history = parameter_history

        self.__r__ = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
        self.__p__ = Atb(self.__r__, self.geo, self.angles)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm
Esempio n. 18
0
    def art_data_minimizing(self):
        """
        VERBOSE:
        for j in range(angleblocks):
            angle = np.array([alpha[j]], dtype=np.float32)
            proj_err = proj[angle_index[j]] - Ax(res, geo, angle, 'ray-voxel')
            weighted_err = W[angle_index[j]] * proj_err
            backprj = Atb(weighted_err, geo, angle, 'FDK')
            weighted_backprj = 1 / V[angle_index[j]] * backprj
            res += weighted_backprj
            res[res<0]=0

        :return: None
        """
        geo = copy.deepcopy(self.geo)
        for j in range(len(self.angleblocks)):
            if self.blocksize == 1:
                angle = np.array([self.angleblocks[j]], dtype=np.float32)
            else:
                angle = self.angleblocks[j]
            if geo.offOrigin.shape[0] == self.angles.shape[0]:
                geo.offOrigin = self.geo.offOrigin[j]
            if geo.offDetector.shape[0] == self.angles.shape[0]:
                geo.offOrin = self.geo.offDetector[j]
            if geo.rotDetector.shape[0] == self.angles.shape[0]:
                geo.rotDetector = self.geo.rotDetector[j]
            if hasattr(geo.DSD, 'shape'):
                if geo.DSD.shape[0] == self.angles.shape[0]:
                    geo.DSD = self.geo.DSD[j]
            if hasattr(geo.DSO, 'shape'):
                if geo.DSO.shape[0] == self.angles.shape[0]:
                    geo.DSO = self.geo.DSO[j]
            self.res += self.lmbda * 1 / self.third_dim_sum(
                self.V[:, :, self.angle_index[j]]) * Atb(
                    self.W[self.angle_index[j]] *
                    (self.proj[self.angle_index[j]] -
                     Ax(self.res, geo, angle, 'interpolated')), geo, angle,
                    'FDK')
            if self.noneg:
                self.res = self.res.clip(min=0)
Esempio n. 19
0
 def reinitialise_cgls(self):
     self.__r__ = self.proj - \
         Ax(self.res, self.geo, self.angles, 'Siddon', gpuids = self.gpuids)
     self.__p__ = Atb(self.__r__, self.geo, self.angles, gpuids=self.gpuids)
     p_norm = np.linalg.norm(self.__p__.ravel(), 2)
     self.__gamma__ = p_norm * p_norm
Esempio n. 20
0
class CGLS(IterativeReconAlg):
    __doc__ = (
        " CGLS_CBCT solves the CBCT problem using the conjugate gradient least\n"
        " squares\n"
        " \n"
        "  CGLS_CBCT(PROJ,GEO,ANGLES,NITER) solves the reconstruction problem\n"
        "  using the projection data PROJ taken over ALPHA angles, corresponding\n"
        "  to the geometry descrived in GEO, using NITER iterations."
    ) + IterativeReconAlg.__doc__

    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        self.log_parameters = False
        self.re_init_at_iteration = 0
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history['alpha'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['beta'] = np.zeros([iterations],
                                                 dtype=np.float32)
            parameter_history['gamma'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['q_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            parameter_history['s_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            self.parameter_history = parameter_history

        self.__r__ = self.proj - \
            Ax(self.res, self.geo, self.angles, 'Siddon', gpuids = self.gpuids)
        self.__p__ = Atb(self.__r__, self.geo, self.angles, gpuids=self.gpuids)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    def reinitialise_cgls(self):
        self.__r__ = self.proj - \
            Ax(self.res, self.geo, self.angles, 'Siddon', gpuids = self.gpuids)
        self.__p__ = Atb(self.__r__, self.geo, self.angles, gpuids=self.gpuids)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    # Overide
    def run_main_iter(self):
        self.l2l = np.zeros([self.niter], dtype=np.float32)
        avgtime = []
        for i in range(self.niter):
            if i == 0:
                if self.verbose:
                    print("CGLS Algorithm in progress.")
                toc = default_timer()
            if i == 1:
                tic = default_timer()
                if self.verbose:
                    print('Esitmated time until completetion (s): ' +
                          str((self.niter - 1) * (tic - toc)))
            avgtic = default_timer()
            q = tigre.Ax(self.__p__,
                         self.geo,
                         self.angles,
                         'Siddon',
                         gpuids=self.gpuids)
            q_norm = np.linalg.norm(q)
            alpha = self.__gamma__ / (q_norm * q_norm)
            self.res += alpha * self.__p__
            avgtoc = default_timer()
            avgtime.append(abs(avgtic - avgtoc))
            for item in self.__dict__:
                if isinstance(getattr(self, item), np.ndarray):
                    if np.isnan(getattr(self, item)).any():
                        raise ValueError('nan found for ' + item +
                                         ' at iteraton ' + str(i))

            aux = self.proj - \
                tigre.Ax(self.res, self.geo, self.angles, 'Siddon', gpuids = self.gpuids)
            self.l2l[i] = np.linalg.norm(aux)
            if i > 0 and self.l2l[i] > self.l2l[i - 1]:
                if self.verbose:
                    print('re-initilization of CGLS called at iteration:' +
                          str(i))
                if self.re_init_at_iteration + 1 == i:
                    if self.verbose:
                        print(
                            'Algorithm exited with two consecutive reinitializations.'
                        )
                    return self.res
                self.res -= alpha * self.__p__
                self.reinitialise_cgls()
                self.re_init_at_iteration = i

            self.__r__ -= alpha * q
            s = tigre.Atb(self.__r__,
                          self.geo,
                          self.angles,
                          gpuids=self.gpuids)
            s_norm = np.linalg.norm(s)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self.__gamma__
            if self.log_parameters:
                self.parameter_history['alpha'][i] = alpha
                self.parameter_history['beta'][i] = beta
                self.parameter_history['gamma'][i] = self.__gamma__
                self.parameter_history['q_norm'][i] = q_norm
                self.parameter_history['s_norm'][i] = s_norm

            self.__gamma__ = gamma1
            self.__p__ = s + beta * self.__p__
        if self.verbose:
            print('Average time taken for each iteration for CGLS:' +
                  str(sum(avgtime) / len(avgtime)) + '(s)')
Esempio n. 21
0
class CGLS(IterativeReconAlg):
    __doc__ = (
        " CGLS_CBCT solves the CBCT problem using the conjugate gradient least\n"
        " squares\n"
        " \n"
        "  CGLS_CBCT(PROJ,GEO,ANGLES,NITER) solves the reconstruction problem\n"
        "  using the projection data PROJ taken over ALPHA angles, corresponding\n"
        "  to the geometry descrived in GEO, using NITER iterations."
    ) + IterativeReconAlg.__doc__

    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        self.log_parameters = False
        # Avoid typo checking
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        self.initialise_cgls()

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history['alpha'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['beta'] = np.zeros([iterations],
                                                 dtype=np.float32)
            parameter_history['gamma'] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history['q_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            parameter_history['s_norm'] = np.zeros([iterations],
                                                   dtype=np.float32)
            self.parameter_history = parameter_history

    def initialise_cgls(self):
        self._r = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
        self._p = Atb(self._r, self.geo, self.angles)
        p_norm = np.linalg.norm(self._p.ravel(), 2)
        self._gamma = p_norm * p_norm

    # Overide
    def run_main_iter(self):
        self.l2l = np.zeros([self.niter], dtype=np.float32)
        for i in range(self.niter):
            if i == 0:
                print("CGLS Algorithm in progress.")
                toc = time.clock()
            if i == 1:
                tic = time.clock()
                print('Esitmated time until completetion (s): ' +
                      str((self.niter - 1) * (tic - toc)))
            q = Ax(self._p, self.geo, self.angles, 'ray-voxel')
            q_norm = np.linalg.norm(q.ravel(), 2)
            alpha = self._gamma / (q_norm * q_norm)
            self.res += alpha * self._p

            aux = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
            self.l2l[i] = np.linalg.norm(aux.ravel(), 2)

            if i > 0 and self.l2l[i] > self.l2l[i - 1]:
                print('re-initialization was called at iter:' + str(i))
                self.res -= alpha * self._p
                self.initialise_cgls()

            self._r -= alpha * q

            s = Atb(self._r, self.geo, self.angles)
            s_norm = np.linalg.norm(s.ravel(), 2)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self._gamma
            if self.log_parameters:
                self.parameter_history['alpha'][i] = alpha
                self.parameter_history['beta'][i] = beta
                self.parameter_history['gamma'][i] = self._gamma
                self.parameter_history['q_norm'][i] = q_norm
                self.parameter_history['s_norm'][i] = s_norm

            self._gamma = gamma1
            self._p = s + beta * self._p
Esempio n. 22
0
 def initialise_cgls(self):
     self._r = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
     self._p = Atb(self._r, self.geo, self.angles)
     p_norm = np.linalg.norm(self._p.ravel(), 2)
     self._gamma = p_norm * p_norm
Esempio n. 23
0
def FDK(proj, geo, angles, **kwargs):
    """
    solves CT image reconstruction.

    :param proj: np.array(dtype=float32),
    Data input in the form of 3d

    :param geo: tigre.utilities.geometry.Geometry
    Geometry of detector and image (see examples/Demo code)

    :param angles: np.array(dtype=float32)
    Angles of projection, shape = (nangles,3) or (nangles,)

    :param filter: str
    Type of filter used for backprojection
    opts: "shep_logan"
          "cosine"
          "hamming"
          "hann"

    :param verbose: bool
    Feedback print statements for algorithm progress

    :param kwargs: dict
    keyword arguments

    :return: np.array(dtype=float32)

    Usage:
    -------
    >>> import tigre
    >>> import tigre.algorithms as algs
    >>> import numpy
    >>> from tigre.demos.Test_data import data_loader
    >>> geo = tigre.geometry(mode='cone',default_geo=True,
    >>>                         nVoxel=np.array([64,64,64]))
    >>> angles = np.linspace(0,2*np.pi,100)
    >>> src_img = data_loader.load_head_phantom(geo.nVoxel)
    >>> proj = tigre.Ax(src_img,geo,angles)
    >>> output = algs.FDK(proj,geo,angles)

    tigre.demos.run() to launch ipython notebook file with examples.

    --------------------------------------------------------------------
    This file is part of the TIGRE Toolbox

    Copyright (c) 2015, University of Bath and
                        CERN-European Organization for Nuclear Research
                        All rights reserved.

    License:            Open Source under BSD.
                        See the full license at
                        https://github.com/CERN/TIGRE/license.txt

    Contact:            [email protected]
    Codes:              https://github.com/CERN/TIGRE/
    --------------------------------------------------------------------
    Coded by:           MATLAB (original code): Ander Biguri
                        PYTHON : Reuben Lindroos
    """
    if "niter" in kwargs:
        kwargs.pop("niter")
    if "verbose" in kwargs:
        verbose = kwargs["verbose"]
    else:
        verbose = False

    if "gpuids" in kwargs:
        gpuids = kwargs["gpuids"]
    else:
        gpuids = None

    geo = copy.deepcopy(geo)
    geo.check_geo(angles)
    geo.checknans()
    if "filter" in kwargs:
        filter = kwargs["filter"]
    else:
        filter = None
    if filter is not None:
        geo.filter = kwargs["filter"]
    # Weight
    proj_filt = np.zeros(proj.shape, dtype=np.float32)
    for ii in range(angles.shape[0]):
        xv = (np.arange((-geo.nDetector[1] / 2) + 0.5, 1 +
                        (geo.nDetector[1] / 2) - 0.5) * geo.dDetector[1])
        yv = (np.arange((-geo.nDetector[0] / 2) + 0.5, 1 +
                        (geo.nDetector[0] / 2) - 0.5) * geo.dDetector[0])
        (yy, xx) = np.meshgrid(xv, yv)

        w = geo.DSD[0] / np.sqrt((geo.DSD[0]**2 + xx**2 + yy**2))
        proj_filt[ii] = copy.deepcopy(proj[ii]) * w

    proj_filt = filtering(proj_filt,
                          geo,
                          angles,
                          parker=False,
                          verbose=verbose)
    # m = {
    #     'py_projfilt': proj_filt,
    #
    # }
    # scipy.io.savemat('Tests/Filter_data', m)
    res = Atb(proj_filt, geo, geo.angles, "FDK", gpuids=gpuids)
    # res = 0
    # res = Atb(proj,geo,angles,'FDK')
    return res
Esempio n. 24
0
 def gradient_descent(self, geo, angle, iteration):
     self.res += self.lmbda * 1. / self.V[iteration] * Atb(
         self.W[self.angle_index[iteration]] *
         (self.proj[self.angle_index[iteration]] -
          Ax(self.res, geo, angle, 'interpolated')), geo, angle, 'FDK')
Esempio n. 25
0
class CGLS(IterativeReconAlg):  # noqa: D101
    __doc__ = (
        " CGLS solves the CBCT problem using the conjugate gradient least\n"
        " squares\n"
        " \n"
        "  CGLS(PROJ,GEO,ANGLES,NITER) solves the reconstruction problem\n"
        "  using the projection data PROJ taken over ALPHA angles, corresponding\n"
        "  to the geometry descrived in GEO, using NITER iterations."
    ) + IterativeReconAlg.__doc__

    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        self.log_parameters = False
        self.re_init_at_iteration = 0
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history["alpha"] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history["beta"] = np.zeros([iterations],
                                                 dtype=np.float32)
            parameter_history["gamma"] = np.zeros([iterations],
                                                  dtype=np.float32)
            parameter_history["q_norm"] = np.zeros([iterations],
                                                   dtype=np.float32)
            parameter_history["s_norm"] = np.zeros([iterations],
                                                   dtype=np.float32)
            self.parameter_history = parameter_history

        self.__r__ = self.proj - Ax(
            self.res, self.geo, self.angles, "Siddon", gpuids=self.gpuids)
        self.__p__ = Atb(self.__r__,
                         self.geo,
                         self.angles,
                         backprojection_type="matched",
                         gpuids=self.gpuids)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    def reinitialise_cgls(self):
        self.__r__ = self.proj - Ax(
            self.res, self.geo, self.angles, "Siddon", gpuids=self.gpuids)
        self.__p__ = Atb(self.__r__,
                         self.geo,
                         self.angles,
                         backprojection_type="matched",
                         gpuids=self.gpuids)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    # Overide
    def run_main_iter(self):
        self.l2l = np.zeros((1, self.niter), dtype=np.float32)
        avgtime = []
        for i in range(self.niter):
            if self.verbose:
                self._estimate_time_until_completion(i)
            if self.Quameasopts is not None:
                res_prev = copy.deepcopy(self.res)

            avgtic = default_timer()
            q = tigre.Ax(self.__p__,
                         self.geo,
                         self.angles,
                         "Siddon",
                         gpuids=self.gpuids)
            q_norm = np.linalg.norm(q)
            alpha = self.__gamma__ / (q_norm * q_norm)
            self.res += alpha * self.__p__
            avgtoc = default_timer()
            avgtime.append(abs(avgtic - avgtoc))
            for item in self.__dict__:
                if (isinstance(getattr(self, item), np.ndarray)
                        and np.isnan(getattr(self, item)).any()):
                    raise ValueError("nan found for " + item +
                                     " at iteraton " + str(i))

            aux = self.proj - tigre.Ax(
                self.res, self.geo, self.angles, "Siddon", gpuids=self.gpuids)
            self.l2l[0, i] = np.linalg.norm(aux)
            if i > 0 and self.l2l[0, i] > self.l2l[0, i - 1]:
                if self.verbose:
                    print("re-initilization of CGLS called at iteration:" +
                          str(i))
                if self.re_init_at_iteration + 1 == i:
                    if self.verbose:
                        print(
                            "Algorithm exited with two consecutive reinitializations."
                        )
                    return self.res
                self.res -= alpha * self.__p__
                self.reinitialise_cgls()
                self.re_init_at_iteration = i

            self.__r__ -= alpha * q
            s = tigre.Atb(self.__r__,
                          self.geo,
                          self.angles,
                          backprojection_type="matched",
                          gpuids=self.gpuids)
            s_norm = np.linalg.norm(s)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self.__gamma__
            if self.log_parameters:
                self.parameter_history["alpha"][i] = alpha
                self.parameter_history["beta"][i] = beta
                self.parameter_history["gamma"][i] = self.__gamma__
                self.parameter_history["q_norm"][i] = q_norm
                self.parameter_history["s_norm"][i] = s_norm

            self.__gamma__ = gamma1
            self.__p__ = s + beta * self.__p__
            if self.Quameasopts is not None:
                self.error_measurement(res_prev, i)

        if self.verbose:
            print("Average time taken for each iteration for CGLS:" +
                  str(sum(avgtime) / len(avgtime)) + "(s)")
 def reinitialise_cgls(self):
     self.__r__ = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
     self.__p__ = Atb(self.__r__, self.geo, self.angles)
     p_norm = np.linalg.norm(self.__p__.ravel(), 2)
     self.__gamma__ = p_norm * p_norm
Esempio n. 27
0
 def test_backproj_parallel_shape(self):
     setattr(self.geo, 'mode', 'parallel')
     self.assertTupleEqual(
         Atb(self.proj, self.geo, self.angles, 'matched').shape,
         (63, 62, 61))
Esempio n. 28
0
def FDK(proj, geo, angles, filter=None,verbose=False):
    ('\n'
     'FDK solves Cone Beam CT image reconstruction'
     '\n'
     'Parameters \n'
     '-------------------------------------------------------------------\n'
     '\n'
     'proj:         Data input in the form of 3d, np.array(dtype=float32)\n'
     '\n'
     'geo:          Geometry of detector and image (see examples/Demo code)\n'
     '\n'
     'alpha:        1d array of angles corresponding to image data, np.array(dtype=float32)\n'
     '\n'
     'filter:       default="ram_lak" \n'
     '              opts: \n'
     '                  "shep_logan"'
     '                  "cosine"   '
     '                  "hamming" '
     '                  "hann" '
     'Examples \n'
     '---------------------------------------------------------------------------\n'
     'See Demos/Example code for further instructions.\n'
     '---------------------------------------------------------------------------'
     '\n'
     """This file is part of the TIGRE Toolbox

        Copyright (c) 2015, University of Bath and
                            CERN-European Organization for Nuclear Research
                            All rights reserved.

        License:            Open Source under BSD.
                            See the full license at
                            https://github.com/CERN/TIGRE/license.txt

        Contact:            [email protected]
        Codes:              https://github.com/CERN/TIGRE/
      --------------------------------------------------------------------------
        Coded by:          MATLAB (original code): Ander Biguri
                           PYTHON : Reuben Lindroos,Sam Loescher, """)
    geo = copy.deepcopy(geo)
    geo.check_geo(angles)
    if filter is not None:
        geo.filter = filter
    # Weight
    proj_filt = np.zeros(proj.shape, dtype=np.float32)
    for ii in range(angles.shape[0]):
        xv = np.arange((-geo.nDetector[1] / 2) + 0.5, 1 + (geo.nDetector[1] / 2) - 0.5) * geo.dDetector[1]
        yv = np.arange((-geo.nDetector[0] / 2) + 0.5, 1 + (geo.nDetector[0] / 2) - 0.5) * geo.dDetector[0]
        (xx, yy) = np.meshgrid(xv, yv)

        w = geo.DSD[0] / np.sqrt((geo.DSD[0] ** 2 + xx ** 2 + yy ** 2))
        proj_filt[ii] = proj[ii] * w

    proj_filt = filtering(proj_filt, geo, angles, parker=False,verbose=verbose)
    # m = {
    #     'py_projfilt': proj_filt,
    #
    # }
    # scipy.io.savemat('Tests/Filter_data', m)
    res = Atb(proj_filt, geo, geo.angles, 'FDK')
    # res = 0
    # res = Atb(proj,geo,angles,'FDK')
    return res
Esempio n. 29
0
class CGLS(IterativeReconAlg):
    __doc__ = (" CGLS_CBCT solves the CBCT problem using the conjugate gradient least\n"
               " squares\n"
               " \n"
               "  CGLS_CBCT(PROJ,GEO,ANGLES,NITER) solves the reconstruction problem\n"
               "  using the projection data PROJ taken over ALPHA angles, corresponding\n"
               "  to the geometry descrived in GEO, using NITER iterations.") + IterativeReconAlg.__doc__

    def __init__(self, proj, geo, angles, niter, **kwargs):
        # Don't precompute V and W.
        kwargs.update(dict(W=None, V=None))
        kwargs.update(dict(blocksize=angles.shape[0]))
        self.log_parameters = False
        IterativeReconAlg.__init__(self, proj, geo, angles, niter, **kwargs)

        if self.log_parameters:
            parameter_history = {}
            iterations = self.niter
            parameter_history['alpha'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['beta'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['gamma'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['q_norm'] = np.zeros([iterations], dtype=np.float32)
            parameter_history['s_norm'] = np.zeros([iterations], dtype=np.float32)
            self.parameter_history = parameter_history

        self.__r__ = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
        self.__p__ = Atb(self.__r__, self.geo, self.angles)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    def reinitialise_cgls(self):
        self.__r__ = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
        self.__p__ = Atb(self.__r__, self.geo, self.angles)
        p_norm = np.linalg.norm(self.__p__.ravel(), 2)
        self.__gamma__ = p_norm * p_norm

    # Overide
    def run_main_iter(self):
        self.l2l = np.zeros([self.niter], dtype=np.float32)
        for i in range(self.niter):
            if i == 0:
                print("CGLS Algorithm in progress.")
                toc = time.clock()
            if i == 1:
                tic = time.clock()
                print('Esitmated time until completetion (s): ' + str((self.niter - 1) * (tic - toc)))
            q = Ax(self.__p__, self.geo, self.angles, 'ray-voxel')
            q_norm = np.linalg.norm(q.ravel(), 2)
            alpha = self.__gamma__ / (q_norm * q_norm)
            self.res += alpha * self.__p__

            for item in self.__dict__:
                if type(getattr(self, item)) == np.ndarray:
                    if np.isnan(getattr(self, item)).any():
                        raise ValueError('nan found for ' + item + ' at iteraton ' + str(i))

            aux = self.proj - Ax(self.res, self.geo, self.angles, 'ray-voxel')
            self.l2l[i] = np.linalg.norm(aux.ravel(), 2)
            if i > 0 and self.l2l[i] > self.l2l[i - 1]:
                print('re-initialization was called at iter:' + str(i))
                self.res -= alpha * self.__p__
                self.reinitialise_cgls()

            self.__r__ -= alpha * q
            s = Atb(self.__r__, self.geo, self.angles)
            s_norm = np.linalg.norm(s.ravel(), 2)

            gamma1 = s_norm * s_norm
            beta = gamma1 / self.__gamma__
            if self.log_parameters:
                self.parameter_history['alpha'][i] = alpha
                self.parameter_history['beta'][i] = beta
                self.parameter_history['gamma'][i] = self.__gamma__
                self.parameter_history['q_norm'][i] = q_norm
                self.parameter_history['s_norm'][i] = s_norm

            self.__gamma__ = gamma1
            self.__p__ = s + beta * self.__p__
Esempio n. 30
0
 def test_backproj_FDK_cone_shape(self):
     setattr(self.geo, 'mode', 'cone')
     self.assertTupleEqual(
         Atb(self.proj, self.geo, self.angles, 'FDK').shape, (63, 62, 61))