Ejemplo n.º 1
0
    def _backproject_block(self, proj_data, proj_geom, vol_data, vol_geom,
                           algorithm):
        '''
        Backproject a single block of data
        '''

        # TODO:
        # Do we need to introduce ShortScan parameter?
        # At the moment we will ignore MinConstraint / MaxConstraint

        try:
            sin_id = astra.data3d.link('-sino', proj_geom,
                                       numpy.ascontiguousarray(proj_data))

            vol_id = astra.data3d.link('-vol', vol_geom, vol_data)

            projector_id = astra.create_projector('cuda3d', proj_geom,
                                                  vol_geom)

            if algorithm == 'BP3D_CUDA':
                asex.accumulate_BP(projector_id, vol_id, sin_id)
            elif algorithm == 'FDK_CUDA':
                asex.accumulate_FDK(projector_id, vol_id, sin_id)
            else:
                raise ValueError('Unknown ASTRA algorithm type.')

        except:
            print("ASTRA error:", sys.exc_info())

        finally:
            astra.data3d.delete(sin_id)
            astra.data3d.delete(vol_id)
            astra.projector.delete(projector_id)

        return vol_data
Ejemplo n.º 2
0
def _backproject_block_add_(projections,
                            volume,
                            proj_geom,
                            vol_geom,
                            algorithm='BP3D_CUDA',
                            negative=False):
    """
    Additive backprojection of a single block. 
    Use negative = True if you want subtraction instead of addition.
    """
    try:
        if negative:
            projections *= -1

        # If volume is a memmap - create a temporary copy in RAM
        if isinstance(volume, numpy.memmap):
            vol_temp = numpy.ascontiguousarray(volume)

            vol_id = astra.data3d.link('-vol', vol_geom, vol_temp)
        else:
            vol_id = astra.data3d.link('-vol', vol_geom, volume)

        sin_id = astra.data3d.link('-sino', proj_geom, projections)

        projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom)

        # We are using accumulate version to avoid creating additional copies of data.
        if algorithm == 'BP3D_CUDA':
            asex.accumulate_BP(projector_id, vol_id, sin_id)
        elif algorithm == 'FDK_CUDA':
            asex.accumulate_FDK(projector_id, vol_id, sin_id)
        else:
            raise ValueError('Unknown ASTRA algorithm type.')

        if isinstance(volume, numpy.memmap):
            volume[:] = vol_temp

    except:
        # The idea here is that we try to delete data3d objects even if ASTRA crashed
        try:
            if negative:
                projections *= -1

            astra.algorithm.delete(projector_id)
            astra.data3d.delete(sin_id)
            astra.data3d.delete(vol_id)

        finally:
            info = sys.exc_info()
            traceback.print_exception(*info)

    if negative:
        projections *= -1

    astra.algorithm.delete(projector_id)
    astra.data3d.delete(sin_id)
    astra.data3d.delete(vol_id)
Ejemplo n.º 3
0
def _backproject_block_(projections,
                        volume,
                        proj_geom,
                        vol_geom,
                        algorithm='BP3D_CUDA',
                        operation='+'):
    """
    Use this internal function to compute backprojection of a single block of data.
    """
    try:

        if (operation == '+'):
            volume_ = volume

        elif (operation == '*') | (operation == '/'):
            volume_ = np.zeros_like(volume)

        else:
            ValueError('Unknown operation type!')

        sin_id = astra.data3d.link('-sino', proj_geom, projections)
        vol_id = astra.data3d.link('-vol', vol_geom, volume_)

        projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom)

        if algorithm == 'BP3D_CUDA':
            asex.accumulate_BP(projector_id, vol_id, sin_id)

        elif algorithm == 'FDK_CUDA':
            asex.accumulate_FDK(projector_id, vol_id, sin_id)

        else:
            raise ValueError('Unknown ASTRA algorithm type.')

        if (operation == '*'):
            volume *= volume_
        elif (operation == '/'):
            volume_[volume_ < 1e-10] = numpy.inf
            volume /= volume_

    except:
        print("ASTRA error:", sys.exc_info())

    finally:
        astra.algorithm.delete(projector_id)
        astra.data3d.delete(sin_id)
        astra.data3d.delete(vol_id)
Ejemplo n.º 4
0
def _backproject_block_mult_(projections,
                             volume,
                             proj_geom,
                             vol_geom,
                             algorithm='BP3D_CUDA',
                             operation='+'):
    """
    Multiplicative backprojection of a single block. 
    """
    try:
        # Need to create a copy of the volume:
        volume_ = numpy.zeros_like(volume)

        sin_id = astra.data3d.link('-sino', proj_geom, projections)
        vol_id = astra.data3d.link('-vol', vol_geom, volume_)

        projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom)

        # We are using accumulate version to avoid creating additional copies of data.
        if algorithm == 'BP3D_CUDA':
            asex.accumulate_BP(projector_id, vol_id, sin_id)
        elif algorithm == 'FDK_CUDA':
            asex.accumulate_FDK(projector_id, vol_id, sin_id)
        else:
            raise ValueError('Unknown ASTRA algorithm type.')

    except:
        # The idea here is that we try to delete data3d objects even if ASTRA crashed
        try:

            astra.algorithm.delete(projector_id)
            astra.data3d.delete(sin_id)
            astra.data3d.delete(vol_id)

        finally:
            info = sys.exc_info()
            traceback.print_exception(*info)

    volume *= volume_

    astra.algorithm.delete(projector_id)
    astra.data3d.delete(sin_id)
    astra.data3d.delete(vol_id)
Ejemplo n.º 5
0
def _backproject_block_(projections, volume, proj_geom, vol_geom, algorithm = 'BP3D_CUDA', operation = '+'):
    """
    Use this internal function to compute backprojection of a single block of data.
    """           
    
    # Unfortunately need to hide the experimental ASTRA
    import astra.experimental as asex 
    
    try:
        
        if (operation == '+'):
            volume_ = volume
            
        elif (operation == '*') | (operation == '/'):
            volume_ = numpy.zeros_like(volume)
            
        else: ValueError('Unknown operation type!')
                    
        sin_id = astra.data3d.link('-sino', proj_geom, projections)        
        vol_id = astra.data3d.link('-vol', vol_geom, volume_)    
        
        projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom)
    
        if algorithm == 'BP3D_CUDA':
            asex.accumulate_BP(projector_id, vol_id, sin_id)
            
        elif algorithm == 'FDK_CUDA':
            asex.accumulate_FDK(projector_id, vol_id, sin_id)
            
        else:
            raise ValueError('Unknown ASTRA algorithm type.')
        
        if (operation == '*'):
            
             volume *= volume_
            
             #flexUtil.display_slice(volume, dim = 0, title = 'worm')
            
             # This is really slow but needed in case of overlap for EM: 
             volume_ *= 0
             astra.data3d.delete(sin_id)
             sin_id = astra.data3d.link('-sino', proj_geom, projections * 0 + 1)
             
             asex.accumulate_BP(projector_id, vol_id, sin_id)
             
             #flexUtil.display_slice(volume_, dim = 0, title = 'norm')
             
             volume_[volume_ < 0.01] = 0.01
             
             volume /= volume_
             
             #flexUtil.display_slice(volume, dim = 0, title = 'rorm')
             
             
        elif (operation == '/'):
             volume_[volume_ < 1e-3] = numpy.inf
             volume /= volume_
             
    except:
        print("ASTRA error:", sys.exc_info())
        
    finally:
        astra.algorithm.delete(projector_id)
        astra.data3d.delete(sin_id)
        astra.data3d.delete(vol_id)