Пример #1
0
def gpuGridrec(tomo,angles,center,input_params):
        """
        Gridrec reconstruction using GPU based gridding
        Inputs: tomo : 3D numpy sinogram array with dimensions same as tomopy
        angles : Array of angles in radians
        center : Floating point center of rotation
        input_params : A dictionary with the keys
        'gpu_device' : Device id of the gpu (For a 4 GPU cluster ; 0-3)
        'oversamp_factor': A factor by which to pad the image/data for FFT
        'fbp_filter_param' : A number between 0-1 for setting the filter cut-off for FBP
        """

        print('Starting GPU NUFFT recon')
        #allocate space for final answer 
        af.set_device(input_params['gpu_device']) #Set the device number for gpu based code
        #Change tomopy format
        new_tomo=np.transpose(tomo,(1,2,0)) #slice, columns, angles
        im_size =  new_tomo.shape[1]
        num_slice = new_tomo.shape[0]
        num_angles=new_tomo.shape[2]
        pad_size=np.int16(im_size*input_params['oversamp_factor'])
#        nufft_scaling = (np.pi/pad_size)**2
        #Initialize structures for NUFFT
        sino={}
        geom={}
        sino['Ns'] =  pad_size#Sinogram size after padding
        sino['Ns_orig'] = im_size #size of original sinogram
        sino['center'] = center + (sino['Ns']/2 - sino['Ns_orig']/2)  #for padded sinogram
        sino['angles'] = angles
        sino['filter'] = input_params['fbp_filter_param'] #Paramter to control strength of FBP filter normalized to [0,1]

        #Initialize NUFFT parameters
        nufft_params = init_nufft_params(sino,geom)
        rec_nufft = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)
        Ax = afnp.zeros((sino['Ns'],num_angles),dtype=afnp.complex64)
        pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2)
        rec_nufft_final=np.zeros((num_slice,sino['Ns_orig'],sino['Ns_orig']),dtype=np.float32)
        
        #Move all data to GPU
        slice_1=slice(0,num_slice,2)
        slice_2=slice(1,num_slice,2)
        gdata=afnp.array(new_tomo[slice_1]+1j*new_tomo[slice_2],dtype=afnp.complex64)
        x_recon = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64)
        #loop over all slices
        for i in range(0,num_slice/2):
          Ax[pad_idx,:]=gdata[i]
          #filtered back-projection 
          rec_nufft[i] = (back_project(Ax,nufft_params))[pad_idx,pad_idx]


        #Move to CPU
        #Rescale result to match tomopy
        rec_nufft=np.array(rec_nufft,dtype=np.complex64) #*nufft_scaling
        rec_nufft_final[slice_1]=np.array(rec_nufft.real,dtype=np.float32)
        rec_nufft_final[slice_2]=np.array(rec_nufft.imag,dtype=np.float32)
        return rec_nufft_final
Пример #2
0
def test_empty_ndarray():
    a = afnumpy.zeros(())
    b = numpy.zeros(())
    iassert(a, b)
    a = afnumpy.ndarray(0)
    b = numpy.ndarray(0)
    iassert(a, b)
    a = afnumpy.ndarray((0, ))
    b = numpy.ndarray((0, ))
    iassert(a, b)
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a[0:0], b[0:0])
Пример #3
0
def test_empty_ndarray():
    a = afnumpy.zeros(())
    b = numpy.zeros(())
    iassert(a,b)
    a = afnumpy.ndarray(0)
    b = numpy.ndarray(0)
    iassert(a,b)
    a = afnumpy.ndarray((0,))
    b = numpy.ndarray((0,))
    iassert(a,b)
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a[0:0],b[0:0])
Пример #4
0
def gpuGridrec(tomo, angles, center, input_params):
    print('Starting GPU NUFFT recon')
    #allocate space for final answer
    af.set_device(
        input_params['gpu_device'])  #Set the device number for gpu based code
    #Change tomopy format
    new_tomo = np.transpose(tomo, (1, 2, 0))  #slice, columns, angles
    im_size = new_tomo.shape[1]
    num_slice = new_tomo.shape[0]
    num_angles = new_tomo.shape[2]
    pad_size = np.int16(im_size * input_params['oversamp_factor'])
    nufft_scaling = (np.pi / pad_size)**2
    #Initialize structures for NUFFT
    sino = {}
    geom = {}
    sino['Ns'] = pad_size  #Sinogram size after padding
    sino['Ns_orig'] = im_size  #size of original sinogram
    sino['center'] = center + (sino['Ns'] / 2 - sino['Ns_orig'] / 2
                               )  #for padded sinogram
    sino['angles'] = angles
    sino['filter'] = input_params[
        'fbp_filter_param']  #Paramter to control strength of FBP filter normalized to [0,1]

    #Initialize NUFFT parameters
    nufft_params = init_nufft_params(sino, geom)
    rec_nufft = afnp.zeros((num_slice / 2, sino['Ns_orig'], sino['Ns_orig']),
                           dtype=afnp.complex64)
    Ax = afnp.zeros((sino['Ns'], num_angles), dtype=afnp.complex64)
    pad_idx = slice(sino['Ns'] / 2 - sino['Ns_orig'] / 2,
                    sino['Ns'] / 2 + sino['Ns_orig'] / 2)
    rec_nufft_final = np.zeros((num_slice, sino['Ns_orig'], sino['Ns_orig']),
                               dtype=np.float32)

    #Move all data to GPU
    slice_1 = slice(0, num_slice, 2)
    slice_2 = slice(1, num_slice, 2)
    gdata = afnp.array(new_tomo[slice_1] + 1j * new_tomo[slice_2],
                       dtype=afnp.complex64)
    x_recon = afnp.zeros((sino['Ns'], sino['Ns']), dtype=afnp.complex64)
    #loop over all slices
    for i in range(0, num_slice / 2):
        Ax[pad_idx, :] = gdata[i]
        #filtered back-projection
        rec_nufft[i] = (back_project(Ax, nufft_params))[pad_idx, pad_idx]

    #Move to CPU
    #Rescale result to match tomopy
    rec_nufft = np.array(rec_nufft, dtype=np.complex64) * nufft_scaling
    rec_nufft_final[slice_1] = np.array(rec_nufft.real, dtype=np.float32)
    rec_nufft_final[slice_2] = np.array(rec_nufft.imag, dtype=np.float32)
    return rec_nufft_final
 def __init__(self, unitcell_size, det_shape, dtype=np.complex128):
     # only calculate the translations when they are needed
     self.translations = None
     
     self.unitcell_size = unitcell_size
     self.det_shape     = det_shape
     
     # keep an array for the 4 symmetry related coppies of the solid unit
     self.syms = afnumpy.zeros((4,) + tuple(det_shape), dtype=dtype)
 def __init__(self, unitcell_size, det_shape, dtype=np.complex128):
     # store the tranlation ramps
     # x = x
     T0 = 1
     
     self.translations = afnumpy.array([T0])
     
     # keep an array for the 1 symmetry related coppies of the solid unit
     self.syms = afnumpy.zeros((1,) + tuple(det_shape), dtype=dtype)
Пример #7
0
 def imag(self):
     ret_type = numpy.real(numpy.zeros((), dtype=self.dtype)).dtype
     shape = list(self.shape)
     if not numpy.issubdtype(self.dtype, numpy.complexfloating):
         return afnumpy.zeros(self.shape)
     shape[-1] *= 2
     dims = numpy.array(pu.c2f(shape), dtype=pu.dim_t)
     s = arrayfire.Array()
     arrayfire.backend.get().af_device_array(
         ctypes.pointer(s.arr), ctypes.c_void_p(self.d_array.device_ptr()),
         self.ndim, ctypes.c_void_p(dims.ctypes.data),
         pu.typemap(ret_type).value)
     arrayfire.backend.get().af_retain_array(ctypes.pointer(s.arr), s.arr)
     a = ndarray(shape, dtype=ret_type, af_array=s)
     ret = a[..., 1::2]
     ret._base = a
     ret._base_index = (Ellipsis, slice(1, None, 2))
     return ret
Пример #8
0
 def imag(self):
     ret_type = numpy.real(numpy.zeros((),dtype=self.dtype)).dtype
     shape = list(self.shape)
     if not numpy.issubdtype(self.dtype, numpy.complexfloating):
         return afnumpy.zeros(self.shape)
     shape[-1] *= 2
     dims = numpy.array(pu.c2f(shape),dtype=pu.dim_t)
     s = arrayfire.Array()
     arrayfire.backend.get().af_device_array(ctypes.pointer(s.arr),
                                             ctypes.c_void_p(self.d_array.device_ptr()),
                                             self.ndim,
                                             ctypes.c_void_p(dims.ctypes.data),
                                             pu.typemap(ret_type).value)
     arrayfire.backend.get().af_retain_array(ctypes.pointer(s.arr),s.arr)
     a = ndarray(shape, dtype=ret_type, af_array=s)
     ret = a[...,1::2]
     ret._base = a
     ret._base_index = (Ellipsis, slice(1,None,2))
     return ret
Пример #9
0
def test_cast():
    a = afnumpy.zeros(25).astype(numpy.complex64)
    a[0] = 1. + 0.j
    assert(a[0] == 1. + 0j)
Пример #10
0
#! /usr/bin/env python

import gnufft
import afnumpy as afnp


vol = afnp.ones((25,256,256), dtype='f')
vol = vol + 1j * vol
fcn = afnp.zeros((25,256,256), dtype='complex64')
mrf_sigma = afnp.ones(1, dtype='f')
gnufft.add_hessian(mrf_sigma[0], vol, fcn)

print fcn[0,:10,:10]
print fcn[0,:10,:10]
Пример #11
0
def test_zeros():
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a, b)
Пример #12
0
def test_zeros():
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a, b)
Пример #13
0
import time
import arrayfire as af

af.set_device(2)
nslice = 150
im_size = 2560
#obj = np.ones((nslice,im_size,im_size),dtype=np.float32)
#obj=tomopy.shepp3d((nslice,im_size,im_size),dtype=np.float32)
obj = np.random.rand(nslice, im_size, im_size).astype(np.float32)
x = obj[::2]
y = obj[1::2]
print(x.shape)
vol = x + 1j * y
t = time.time()
vol = afnp.array(vol.astype(np.complex64))  #255*
fcn = afnp.zeros((nslice / 2, im_size, im_size), dtype=np.complex64)
tvd_update(1.2, 1, vol, fcn)
elapsed = time.time() - t
print('Time taken for gradient %f' % (elapsed))
output = np.zeros((nslice, im_size, im_size), dtype=np.float32)
output[::2] = np.array(fcn).real
output[1::2] = np.array(fcn).imag
print(output.max())
print(output.min())
del fcn

fcn = afnp.zeros((nslice / 2, im_size, im_size), dtype=np.complex64)
t = time.time()
add_hessian(2, vol, fcn)
elapsed = time.time() - t
print('Time taken for Hessian %f' % (elapsed))
Пример #14
0
def gpuSIRT(tomo, angles, center, input_params):
    print('Starting GPU SIRT recon')
    #allocate space for final answer
    af.set_device(
        input_params['gpu_device'])  #Set the device number for gpu based code
    #Change tomopy format
    new_tomo = np.transpose(tomo, (1, 2, 0))  #slice, columns, angles
    im_size = new_tomo.shape[1]
    num_slice = new_tomo.shape[0]
    num_angles = new_tomo.shape[2]
    pad_size = np.int16(im_size * input_params['oversamp_factor'])
    nufft_scaling = (np.pi / pad_size)**2
    num_iter = input_params['num_iter']
    #Initialize structures for NUFFT
    sino = {}
    geom = {}
    sino['Ns'] = pad_size  #Sinogram size after padding
    sino['Ns_orig'] = im_size  #size of original sinogram
    sino['center'] = center + (sino['Ns'] / 2 - sino['Ns_orig'] / 2
                               )  #for padded sinogram
    sino['angles'] = angles

    #Initialize NUFFT parameters
    nufft_params = init_nufft_params(sino, geom)
    temp_y = afnp.zeros((sino['Ns'], num_angles), dtype=afnp.complex64)
    temp_x = afnp.zeros((sino['Ns'], sino['Ns']), dtype=afnp.complex64)
    x_recon = afnp.zeros((num_slice / 2, sino['Ns_orig'], sino['Ns_orig']),
                         dtype=afnp.complex64)
    pad_idx = slice(sino['Ns'] / 2 - sino['Ns_orig'] / 2,
                    sino['Ns'] / 2 + sino['Ns_orig'] / 2)

    #allocate output array
    rec_sirt_final = np.zeros((num_slice, sino['Ns_orig'], sino['Ns_orig']),
                              dtype=np.float32)

    #Pre-compute diagonal scaling matrices ; one the same size as the image and the other the same as data
    #initialize an image of all ones
    x_ones = afnp.ones((sino['Ns_orig'], sino['Ns_orig']),
                       dtype=afnp.complex64)
    temp_x[pad_idx, pad_idx] = x_ones
    temp_proj = forward_project(temp_x,
                                nufft_params) * (sino['Ns'] * afnp.pi / 2)
    R = 1 / afnp.abs(temp_proj)
    R[afnp.isnan(R)] = 0
    R[afnp.isinf(R)] = 0
    R = afnp.array(R, dtype=afnp.complex64)

    #Initialize a sinogram of all ones
    y_ones = afnp.ones((sino['Ns_orig'], num_angles), dtype=afnp.complex64)
    temp_y[pad_idx] = y_ones
    temp_backproj = back_project(temp_y, nufft_params) * nufft_scaling / 2
    C = 1 / (afnp.abs(temp_backproj))
    C[afnp.isnan(C)] = 0
    C[afnp.isinf(C)] = 0
    C = afnp.array(C, dtype=afnp.complex64)

    #Move all data to GPU
    slice_1 = slice(0, num_slice, 2)
    slice_2 = slice(1, num_slice, 2)
    gdata = afnp.array(new_tomo[slice_1] + 1j * new_tomo[slice_2],
                       dtype=afnp.complex64)

    #loop over all slices
    for i in range(num_slice / 2):
        for iter_num in range(num_iter):
            #filtered back-projection
            temp_x[pad_idx, pad_idx] = x_recon[i]
            Ax = (np.pi / 2) * sino['Ns'] * forward_project(
                temp_x, nufft_params)
            temp_y[pad_idx] = gdata[i]
            x_recon[i] = x_recon[i] + (
                C * back_project(R * (temp_y - Ax), nufft_params) *
                nufft_scaling / 2)[pad_idx, pad_idx]

    #Move to CPU
    #Rescale result to match tomopy
    rec_sirt = np.array(x_recon, dtype=np.complex64)
    rec_sirt_final[slice_1] = np.array(rec_sirt.real, dtype=np.float32)
    rec_sirt_final[slice_2] = np.array(rec_sirt.imag, dtype=np.float32)
    return rec_sirt_final
Пример #15
0
def test_cast():
    a = afnumpy.zeros(25).astype(numpy.complex64)
    a[0] = 1. + 0.j
    assert (a[0] == 1. + 0j)
Пример #16
0
    def test_gsm(self, beta = 1, nx = 10, ny = 1, pos = "end", export = False, outdir = ""):
        """
        Initialise GSM beam as a container of multiple coherent modes

        Modes dictionary is setup by order {wfr, eigenvalue/weight}

        :param p_mu: rms width of the degree of coherence
        :param p_I: rms width of the intensity profile
        :param n: number of values for eigenvalue calculation (almost arb.)
        """
        print("Initialising Gaussian-Schell Model Beam")
        self.log.info("Initialising Gaussian-Schell Model Beam")

        gauss_0 = primary_gaussian() # properties of gaussian
        N = nx*ny
        

        results = []

        if export == True:
            os.mkdir(outdir)
        else:
            pass

        for itr in range(N):
            self.wfr.eigenval.append(eigenvaluePartCoh(1, beta,itr))

        self.wfr.eigenval = self.wfr.eigenval[0:N]
        self.wfr.eigenfn = gen_modes(nx, ny)

        if pos == "start":
            gauss_0.d2waist = 0
        elif pos == "end":
            gauss_0.d2waist = 2.012
        else:
            assert("wavefront posn' should be 'start' or 'end'")

        print("Generating {} Coherent Modes".format(N))
        self.log.info("Generating {} Coherent Modes".format(N))
        
        eField = np.zeros((2048, 2048, 1))

        if pos == "start":
            gauss_0.d2waist = 0
        elif pos == "end":
            gauss_0.d2waist = 2.012
        else:
            assert("wavefront posn' should be 'start' or 'end'")
        
        print(self.wfr.eigenfn)
        print("Generating {} Coherent Modes".format(N))
        self.log.info("Generating {} Coherent Modes".format(N))
        for itr in range(N):
            
            res = []
            res.append(self.wfr.eigenfn[itr])
            res.append(self.wfr.eigenval[itr])

            if itr % 5 == 0:
                print("Generating Mode {}/{}".format(itr+1, N))
                self.log.info("Generating Mode {}/{}".format(itr+1, N))
                
            _mx = self.wfr.eigenfn[itr][0]
            _my = self.wfr.eigenfn[itr][1]

            M2x = (2*_mx)+1
            M2y = (2*_my)+1
            self.wfr.modes.append(Wavefront(build_gauss_wavefront_xy(gauss_0.nx ,gauss_0.ny,
                                           self.global_E*1e-03,
                                           gauss_0.xMin, gauss_0.xMax,
                                           gauss_0.yMin,gauss_0.yMax,
                                           gauss_0.sigX*M2x**-0.25,
                                           gauss_0.sigY*M2y**-0.25,
                                           gauss_0.d2waist,
                                           tiltX = 0,
                                           tiltY = 0,
                                           _mx = - _mx, ## NOTE NEGATIVE 
                                           _my = _my,
                                           pulseEn = 2.51516e-2)))


            self.wfr.type = 'gsm'

        print("Coherent Modes Generated")
        self.log.info("Coherent Modes Generated")
        
        print("Testing Coherent Modes")
        self.log.info("Testing Coherent Modes")
        
        axis_x = np.linspace(-0.002, 0.002, 2048)
        axis_y = np.linspace(-0.002, 0.002, 2048)
        
        eField = np.zeros((2048,2048,1))
        
        for itr in range(len(self.wfr.modes)):
            eField += self.wfr.modes[itr].data.arrEhor[:,:,:,0] * self.wfr.eigenval[itr]
            [cohx, cohy] = coherence_log(eField, axis_x, axis_y)
            
            
            self.log.info("**************************************************")
            self.log.info("Addition of Mode {}".format(itr))
            self.log.info("Mode Weighting {}".format(self.wfr.eigenval[itr]))
            self.log.info("Mode Weighting {}".format(self.wfr.eigenfn[itr]))
            self.log.info("\n")
            self.log.info("Ix: {} m\nJx: {} m".format(cohx[2], cohx[3]))
            self.log.info("Iy: {} m\nJy: {} m".format(cohy[2], cohy[3]))
            self.log.info("x-beta: {} \n y-beta: {}".format(cohx[4], cohy[4]))

            res.append(cohx[2])
            res.append(cohy[2])
            res.append(cohx[3])
            res.append(cohy[3])
            res.append(cohx[4])
            res.append(cohy[4])

            results.append(res)
        
        return results
Пример #17
0
sino={}
geom={}
sino['Ns'] = 1024 #3624#im_size*2 #Sinogram size after padding
sino['Ns_orig'] = im_size #size of original sinogram
sino['center'] = sino_center + (sino['Ns']/2 - sino['Ns_orig']/2)  #for padded sinogram
sino['angles'] = ang
sino['filter']=0.95

pad_size= sino['Ns']

params = init_nufft_params(sino,geom)

##Create a simulated object to test forward and back-projection routines
pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2)

temp_x = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64)
print(temp_x.shape)

Ax = afnp.zeros((num_slice/2,sino['Ns'],num_angles),dtype=afnp.complex64)
y = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)
t=time.time()
slice_1=slice(0,num_slice,2)
slice_2=slice(1,num_slice,2)
x=afnp.array(obj[slice_1]+1j*obj[slice_2],dtype=afnp.complex64)
print(x.shape)
for i in range(num_slice/2):
  temp_x[pad_idx,pad_idx]=x[i]
  Ax[i] = forward_project(temp_x,params) #(math.pi/2)*sino['Ns']
  y[i] = (back_project(Ax[i],params)[pad_idx,pad_idx]) # 
elapsed_time = (time.time()-t)
print('Time for Forward/Back-proj for %d slices: %f'% (num_slice,elapsed_time))
Пример #18
0
def gpuMBIR(tomo,angles,center,input_params):
        """
        MBIR reconstruction using GPU based gridding operators
        Inputs: tomo : 3D numpy sinogram array with dimensions same as tomopy
        angles : Array of angles in radians
        center : Floating point center of rotation
        input_params : A dictionary with the keys
        'gpu_device' : Device id of the gpu (For a 4 GPU cluster ; 0-3)
        'oversamp_factor': A factor by which to pad the image/data for FFT
        'num_iter' : Max number of MBIR iterations
        'smoothness' : Regularization constant
        'p': MRF shape param
        """
        print('Starting GPU MBIR recon')
        #allocate space for final answer 
        af.set_device(input_params['gpu_device']) #Set the device number for gpu based code
        #Change tomopy format
        new_tomo=np.transpose(tomo,(1,2,0)) #slice, columns, angles
        im_size =  new_tomo.shape[1]
        num_slice = new_tomo.shape[0]
        num_angles=new_tomo.shape[2]
        pad_size=np.int16(im_size*input_params['oversamp_factor'])
#        nufft_scaling = (np.pi/pad_size)**2
        num_iter = input_params['num_iter']
        mrf_sigma = input_params['smoothness']
        mrf_p = input_params['p']
        print('MRF params p=%f sigma=%f' %(mrf_p,mrf_sigma))
        #Initialize structures for NUFFT
        sino={}
        geom={}
        sino['Ns'] =  pad_size#Sinogram size after padding
        sino['Ns_orig'] = im_size #size of original sinogram
        sino['center'] = center + (sino['Ns']/2 - sino['Ns_orig']/2)  #for padded sinogram
        sino['angles'] = angles
        
        #Initialize NUFFT parameters
        print('Initialize NUFFT params')
        nufft_params = init_nufft_params(sino,geom)

        temp_y = afnp.zeros((sino['Ns'],num_angles),dtype=afnp.complex64)
        temp_x = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64)
        x_recon  = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)
        
        pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2)

        #allocate output array
        rec_mbir_final=np.zeros((num_slice,sino['Ns_orig'],sino['Ns_orig']),dtype=np.float32)
        
        #Move all data to GPU
        print('Moving data to GPU')
        slice_1=slice(0,num_slice,2)
        slice_2=slice(1,num_slice,2)
        gdata=afnp.array(new_tomo[slice_1]+1j*new_tomo[slice_2],dtype=afnp.complex64)
        gradient = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']), dtype=afnp.complex64)#temp array to store the derivative of cost func
        z_recon  = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)#Nesterov method variables
        t_nes = 1
        
        #Compute Lipschitz of gradient
        print('Computing Lipschitz of gradient')
        x_ones= afnp.ones((1,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)
        temp_x[pad_idx,pad_idx]=x_ones[0]
        temp_proj=forward_project(temp_x,nufft_params)
        temp_backproj=(back_project(temp_proj,nufft_params))[pad_idx,pad_idx]
        print('Adding Hessian of regularizer')
        temp_backproj2=afnp.zeros((1,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)
        temp_backproj2[0]=temp_backproj
        add_hessian(mrf_sigma,x_ones, temp_backproj2)
        L = np.max([temp_backproj2.real.max(),temp_backproj2.imag.max()])
        print('Lipschitz constant = %f' %(L))
        del x_ones,temp_proj,temp_backproj,temp_backproj2

        #loop over all slices
        for iter_num in range(num_iter):
          print('Iteration %d of %d'%(iter_num,num_iter))
        #Derivative of the data fitting term
          for i in range(num_slice/2):
            temp_x[pad_idx,pad_idx]=x_recon[i]
            Ax = forward_project(temp_x,nufft_params)
            temp_y[pad_idx]=gdata[i]
            gradient[i] =(back_project((Ax-temp_y),nufft_params))[pad_idx,pad_idx] #nufft_scaling
        #Derivative of regularization term
          tvd_update(mrf_p,mrf_sigma,x_recon, gradient) 
          #x_recon-=gradient/L
          x_recon,z_recon,t_nes=nesterovOGM2update(x_recon,z_recon,t_nes,gradient,L)
        
        #Move to CPU
        #Rescale result to match tomopy
        rec_mbir=np.array(x_recon,dtype=np.complex64)
        rec_mbir_final[slice_1]=np.array(rec_mbir.real,dtype=np.float32)
        rec_mbir_final[slice_2]=np.array(rec_mbir.imag,dtype=np.float32)
        return rec_mbir_final