def _process (lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, norm_sx, norm_dx, flat_end, 
			 half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average,
			 ringrem, dynamic_ff, EFF, filtEFF, im_dark, logfilename):

	# Process the required subset of images:
	for i in range(int_from, int_to + 1):                 
				
		# Read input image:
		t0 = time()
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_sino(dset,i).astype(float32)		
		f_in.close()
		t1 = time() 		

		# Perform pre-processing (flat fielding, extended FOV, ring removal):	
		if not skipflat:
			if dynamic_ff:
				# Dynamic flat fielding with downsampling = 2:
				im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
			else:
				im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx)			
		if ext_fov:
			im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average)
		if not skipflat and not dynamic_ff:
			im = ring_correction (im, ringrem, flat_end, plan['skip_flat_after'], half_half, half_half_line, ext_fov)
		else:
			im = ring_correction (im, ringrem, False, False, half_half, half_half_line, ext_fov)
		t2 = time() 		
								
		# Save processed image to HDF5 file (atomic procedure - lock used):
		_write_data(lock, im, i, outfile, outshape, outtype, logfilename, t2 - t1, t1 - t0)
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, flat_end, 
			 half_half, half_half_line, dynamic_ff, EFF, filtEFF, im_dark, rotation, interp, border, 
			 rescale_factor, logfilename):

	# Process the required subset of images:
	for i in range(int_from, int_to + 1):                 
				
		# Read input image:
		t0 = time()
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_tomo(dset,i).astype(float32)		
		f_in.close()
		t1 = time() 		

		# Perform pre-processing (flat fielding, extended FOV, ring removal):
		if not skipflat:
			if dynamic_ff:
				# Dynamic flat fielding with downsampling = 2:
				im = dynamic_flat_fielding(im, EFF, filtEFF, 2, im_dark)
			else:
				im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx)			
		t2 = time() 		

		# Rotate:
		rows, cols = im.shape
		#if (cols > rows):
		#	angle = - arctan(2.0 / cols) * (rows / 2.0) / 2.0
		#else:
		#	angle = - arctan(2.0 / rows) * (cols / 2.0) / 2.0
		#print(angle)
	
		M = cv2.getRotationMatrix2D((cols / 2, rows / 2), rotation, 1)

		if interp == 'nearest':
			interpflag = cv2.INTER_NEAREST
		elif interp == 'cubic':
			interpflag = cv2.INTER_CUBIC
		elif interp == 'lanczos':
			interpflag = cv2.INTER_LANCZOS4
		else:
			interpflag = cv2.INTER_LINEAR 

		if border == 'constant':
			borderflag = cv2.BORDER_CONSTANT
		else:
			borderflag = cv2.BORDER_REPLICATE


		im = cv2.warpAffine(im, M, (cols, rows), flags = interpflag, borderMode = borderflag)
								
		# Save processed image to HDF5 file (atomic procedure - lock used):
		_write_data(lock, im, i, outfile, outshape, outtype, rescale_factor, logfilename, t2 - t1, t1 - t0)
Esempio n. 3
0
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype,
             skipflat, plan, norm_sx, norm_dx, flat_end, half_half,
             half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap,
             ext_fov_normalize, ext_fov_average, ringrem, dynamic_ff, EFF,
             filtEFF, im_dark, logfilename):

    # Process the required subset of images:
    for i in range(int_from, int_to + 1):

        # Read input image:
        t0 = time()
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im = tdf.read_sino(dset, i).astype(float32)
        f_in.close()
        t1 = time()

        # Perform pre-processing (flat fielding, extended FOV, ring removal):
        if not skipflat:
            if dynamic_ff:
                # Dynamic flat fielding with downsampling = 2:
                im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark,
                                           norm_sx, norm_dx)
            else:
                im = flat_fielding(im, i, plan, flat_end, half_half,
                                   half_half_line, norm_sx, norm_dx)
        if ext_fov:
            im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap,
                                   ext_fov_normalize, ext_fov_average)
        if not skipflat and not dynamic_ff:
            im = ring_correction(im, ringrem, flat_end,
                                 plan['skip_flat_after'], half_half,
                                 half_half_line, ext_fov)
        else:
            im = ring_correction(im, ringrem, False, False, half_half,
                                 half_half_line, ext_fov)
        t2 = time()

        # Save processed image to HDF5 file (atomic procedure - lock used):
        _write_data(lock, im, i, outfile, outshape, outtype, logfilename,
                    t2 - t1, t1 - t0)
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype,
             skipflat, plan, flat_end, half_half, half_half_line, dynamic_ff,
             EFF, filtEFF, im_dark, rotation, interp, border, rescale_factor,
             logfilename):

    # Process the required subset of images:
    for i in range(int_from, int_to + 1):

        # Read input image:
        t0 = time()
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im = tdf.read_tomo(dset, i).astype(float32)
        f_in.close()
        t1 = time()

        # Perform pre-processing (flat fielding, extended FOV, ring removal):
        if not skipflat:
            if dynamic_ff:
                # Dynamic flat fielding with downsampling = 2:
                im = dynamic_flat_fielding(im, EFF, filtEFF, 2, im_dark)
            else:
                im = flat_fielding(im, i, plan, flat_end, half_half,
                                   half_half_line, norm_sx, norm_dx)
        t2 = time()

        # Rotate:
        rows, cols = im.shape
        #if (cols > rows):
        #	angle = - arctan(2.0 / cols) * (rows / 2.0) / 2.0
        #else:
        #	angle = - arctan(2.0 / rows) * (cols / 2.0) / 2.0
        #print(angle)

        M = cv2.getRotationMatrix2D((cols / 2, rows / 2), rotation, 1)

        if interp == 'nearest':
            interpflag = cv2.INTER_NEAREST
        elif interp == 'cubic':
            interpflag = cv2.INTER_CUBIC
        elif interp == 'lanczos':
            interpflag = cv2.INTER_LANCZOS4
        else:
            interpflag = cv2.INTER_LINEAR

        if border == 'constant':
            borderflag = cv2.BORDER_CONSTANT
        else:
            borderflag = cv2.BORDER_REPLICATE

        im = cv2.warpAffine(im,
                            M, (cols, rows),
                            flags=interpflag,
                            borderMode=borderflag)

        # Save processed image to HDF5 file (atomic procedure - lock used):
        _write_data(lock, im, i, outfile, outshape, outtype, rescale_factor,
                    logfilename, t2 - t1, t1 - t0)
def process(sino_idx, num_sinos, infile, outfile, preprocessing_required, corr_plan, skipflat, norm_sx, norm_dx, flat_end, half_half, 
			half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, 
			ringrem, phaseretrieval_required, phrtmethod, phrt_param1,
			phrt_param2, energy, distance, pixsize, phrtpad, approx_win, angles, angles_projfrom, angles_projto,
			offset, logtransform, recpar, circle, scale, pad, method, rolling, roll_shift,
			zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, 
            polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, nr_threads, logfilename, tmppath):
	"""To do...

	"""
	# Perform reconstruction (on-the-fly preprocessing and phase retrieval, if
	# required):
	if (phaseretrieval_required):
		
		# In this case a bunch of sinograms is loaded into memory:

		#
		# Load the temporary data structure reading the input TDF file.
		# To know the right dimension the first sinogram is pre-processed.
		#		

		# Open the TDF file and get the dataset:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		
		# Downscaling and decimation factors considered when determining the
		# approximation window:
		zrange = arange(sino_idx - approx_win * downsc_factor / 2, sino_idx + approx_win * downsc_factor / 2, downsc_factor)
		zrange = zrange[(zrange >= 0)]
		zrange = zrange[(zrange < num_sinos)]
		approx_win = zrange.shape[0]
		
		# Approximation window cannot be odd:
		if (approx_win % 2 == 1):
			approx_win = approx_win - 1 
			zrange = zrange[0:approx_win]
		
		# Read one sinogram to get the proper dimensions:
		test_im = tdf.read_sino(dset, zrange[0]*downsc_factor).astype(float32)	

		# Apply projection removal (if required):
		test_im = test_im[angles_projfrom:angles_projto, :]

		# Apply decimation and downscaling (if required):
		test_im = test_im[::decim_factor, ::downsc_factor]

		# Perform the pre-processing of the first sinogram to get the right
		# dimension:
		if (preprocessing_required):
			if not skipflat:			
				if dynamic_ff:
					# Dynamic flat fielding with downsampling = 2:
					#test_im = dynamic_flat_fielding(test_im, zrange[0] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
					test_im = dynamic_flat_fielding(test_im, zrange[0] , EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
				else:
					#test_im = flat_fielding(test_im, zrange[0] / downsc_factor, corr_plan, flat_end, half_half, 
					#						half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)
					test_im = flat_fielding(test_im, zrange[0], corr_plan, flat_end, half_half, 
											half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)
			if ext_fov:
				test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32)			
			if not skipflat and not dynamic_ff:
				test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line / decim_factor, ext_fov).astype(float32)	
			else:
				test_im = ring_correction(test_im, ringrem, False, False, half_half, 
											half_half_line / decim_factor, ext_fov).astype(float32)	
		
		# Now we can allocate memory for the bunch of slices:
		tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32)
		tmp_im[0,:,:] = test_im

		# Reading all the the sinos from TDF file and close:
		for ct in range(1, approx_win):

			# Read the sinogram:
			test_im = tdf.read_sino(dset, zrange[ct]*downsc_factor).astype(float32)

			# Apply projection removal (if required):
			test_im = test_im[angles_projfrom:angles_projto, :]

			# Apply decimation and downscaling (if required):
			test_im = test_im[::decim_factor, ::downsc_factor]
			
			# Perform the pre-processing for each sinogram of the bunch:
			if (preprocessing_required):
				if not skipflat:
					if dynamic_ff:
						# Dynamic flat fielding with downsampling = 2:
						#test_im = dynamic_flat_fielding(test_im, zrange[ct] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
						test_im = dynamic_flat_fielding(test_im, zrange[ct], EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
					else:
						#test_im = flat_fielding(test_im, zrange[ct] / downsc_factor, corr_plan, flat_end, half_half, 
						#					half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)	
						test_im = flat_fielding(test_im, zrange[ct], corr_plan, flat_end, half_half, 
											half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)	
				if ext_fov:
					test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32)
				if not skipflat and not dynamic_ff:
					test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line / decim_factor, ext_fov).astype(float32)	
				else:
					test_im = ring_correction(test_im, ringrem, False, False, half_half, 
											half_half_line / decim_factor, ext_fov).astype(float32)				

			tmp_im[ct,:,:] = test_im
	
		f_in.close()

		# Now everything has to refer to a downscaled dataset:
		sino_idx = ((zrange == sino_idx).nonzero())

		#
		# Perform phase retrieval:
		#

		# Prepare the plan:
		if (phrtmethod == 0):
			# Paganin's:
			phrtplan = tiehom_plan(tmp_im[:,0,:], phrt_param1, phrt_param2, energy, distance, pixsize * downsc_factor, phrtpad)
		else:
			phrtplan = phrt_plan(tmp_im[:,0,:], energy, distance, pixsize * downsc_factor, phrt_param2, phrt_param1, phrtmethod, phrtpad)
			#phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance,
			#pixsize*downsc_factor, padding=phrtpad)
		
		# Process each projection (whose height depends on the size of the bunch):
		for ct in range(0, tmp_im.shape[1]):
			#tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32)
			if (phrtmethod == 0):
				tmp_im[:,ct,:] = tiehom(tmp_im[:,ct,:], phrtplan).astype(float32)			
			else:
				tmp_im[:,ct,:] = phrt(tmp_im[:,ct,:], phrtplan, phrtmethod).astype(float32)					
		
		# Extract the requested sinogram:
		im = tmp_im[sino_idx[0],:,:].squeeze()	

	else:

		# Read only one sinogram:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_sino(dset,sino_idx * downsc_factor).astype(float32)		
		f_in.close()

		# Apply projection removal (if required):
		im = im[angles_projfrom:angles_projto, :]

		# Apply decimation and downscaling (if required):
		im = im[::decim_factor,::downsc_factor]
		#sino_idx = sino_idx / downsc_factor	# Downscaling for the index already applied
			
		# Perform the preprocessing of the sinogram (if required):
		if (preprocessing_required):
			if not skipflat:
				if dynamic_ff:
					# Dynamic flat fielding with downsampling = 2:
					im = dynamic_flat_fielding(im, sino_idx, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
				else:
					im = flat_fielding(im, sino_idx, corr_plan, flat_end, half_half, half_half_line / decim_factor, 
								norm_sx, norm_dx).astype(float32)	
			if ext_fov:	
				im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average)
			if not skipflat and not dynamic_ff:
				im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
								half_half_line / decim_factor, ext_fov)
			else:
				im = ring_correction(im, ringrem, False, False, half_half, 
								half_half_line / decim_factor, ext_fov)


	# Additional ring removal before reconstruction:
	#im = boinhaibel(im, '11;')
	#im = munchetal(im, '5;1.8')
	#im = rivers(im, '13;')
	#im = raven(im, '11;0.8')
	#im = oimoen(im, '51;51')

	# Actual reconstruction:
	im = reconstruct(im, angles, offset / downsc_factor, logtransform, recpar, circle, scale, pad, method, 
					zerone_mode, dset_min, dset_max, corr_offset, rolling, roll_shift, tmppath).astype(float32)	

	# Apply post-processing (if required):
	if postprocess_required:        
		im = polarfilter(im, polarfilt_opt)
		im = croprescale(im, convert_opt, crop_opt)
	else:
		# Create the circle mask for fancy output:
		if (circle == True):
			siz = im.shape[1]
			if siz % 2:
				rang = arange(-siz / 2 + 1, siz / 2 + 1)
			else:
				rang = arange(-siz / 2,siz / 2)
			x,y = meshgrid(rang,rang)
			z = x ** 2 + y ** 2
			a = (z < (siz / 2 - int(round(abs(offset) / downsc_factor))) ** 2)
			im = im * a			

	# Write down reconstructed preview file (file name modified with metadata):
	im = im.astype(float32)
	outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str(amin(im)) + '$' + str(amax(im))	
	im.tofile(outfile)	
def process(sino_idx, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, 
			half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average,
			ringrem, phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2, 
			energy, distance, pixsize, phrtpad, approx_win, angles, offset, logtransform, param1, circle, scale, pad, method, 
			zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, 
			crop_opt, nr_threads, angles_from, angles_to, logfilename, lock, slice_prefix):
	"""To do...

	"""
	slice_nr = sino_idx
	
	# Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required):
	if (phaseretrieval_required):
		
		# In this case a bunch of sinograms is loaded into memory:		

		#
		# Load the temporary data structure reading the input TDF file.
		# To know the right dimension the first sinogram is pre-processed.
		#		

		# Open the TDF file and get the dataset:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		
		# Downscaling and decimation factors considered when determining the approximation window:
		zrange = arange(sino_idx - approx_win*downsc_factor/2, sino_idx + approx_win*downsc_factor/2, downsc_factor)
		zrange = zrange[ (zrange >= 0) ]
		zrange = zrange[ (zrange < num_sinos) ]
		approx_win = zrange.shape[0]
		
		# Approximation window cannot be odd:
		if (approx_win % 2 == 1):
			approx_win = approx_win-1 
			zrange     = zrange[0:approx_win]
		
		# Read one sinogram to get the proper dimensions:
		test_im = tdf.read_sino(dset, zrange[0]*downsc_factor).astype(float32)		
		
		# Apply decimation and downscaling (if required):
		test_im = test_im[::decim_factor, ::downsc_factor]

		# Perform the pre-processing of the first sinogram to get the right dimension:
		if (preprocessing_required):
			test_im = flat_fielding (test_im, zrange[0], corr_plan, flat_end, half_half, 
										half_half_line/decim_factor, norm_sx, norm_dx).astype(float32)	
			if ext_fov:
				test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32)			
			test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line/decim_factor, ext_fov).astype(float32)	
		
		# Now we can allocate memory for the bunch of slices:		
		tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32)
		tmp_im[0,:,:] = test_im

		# Reading all the the sinos from TDF file and close:
		for ct in range(1, approx_win):
			
			test_im = tdf.read_sino(dset, zrange[ct]*downsc_factor).astype(float32)
			test_im = test_im[::decim_factor, ::downsc_factor]
			
			# Perform the pre-processing for each sinogram of the bunch:
			if (preprocessing_required):
				test_im = flat_fielding (test_im, zrange[ct], corr_plan, flat_end, half_half, 
											half_half_line/decim_factor, norm_sx, norm_dx).astype(float32)	
				if ext_fov:
					test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32)			
				test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line/decim_factor, ext_fov).astype(float32)	
			
			tmp_im[ct,:,:] = test_im
	
		f_in.close()

		# Now everything has to refer to a downscaled dataset:
		sino_idx = ((zrange == sino_idx).nonzero())

		#
		# Perform phase retrieval:
		#

		# Prepare the plan:		
		if (phrtmethod == 0):
			# Paganin's:
			phrtplan = tiehom_plan (tmp_im[:,0,:], phrt_param1, phrt_param2, energy, distance, pixsize*downsc_factor, padding=phrtpad)
		else:
			phrtplan = phrt_plan (tmp_im[:,0,:], energy, distance, pixsize*downsc_factor, phrt_param2, phrt_param1, phrtmethod, padding=phrtpad)
		
		# Process each projection (whose height depends on the size of the bunch):
		for ct in range(0, tmp_im.shape[1]):
			if (phrtmethod == 0):
				tmp_im[:,ct,:] = tiehom(tmp_im[:,ct,:], phrtplan).astype(float32)			
			else:
				tmp_im[:,ct,:] = phrt(tmp_im[:,ct,:], phrtplan, phrtmethod).astype(float32)	
		
		# Extract the requested sinogram:
		im = tmp_im[sino_idx[0],:,:].squeeze()	

	else:

		# Read only one sinogram:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_sino(dset,sino_idx * downsc_factor).astype(float32)		
		f_in.close()

		# Downscale and decimate the sinogram:
		im = im[::decim_factor,::downsc_factor]
		#sino_idx = sino_idx/downsc_factor	
			
		# Perform the preprocessing of the sinogram (if required):
		if (preprocessing_required):
			im = flat_fielding (im, sino_idx, corr_plan, flat_end, half_half, half_half_line/decim_factor, 
								norm_sx, norm_dx).astype(float32)		
			if ext_fov:
				test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32)			
			im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
								half_half_line/decim_factor, ext_fov)

	# Log infos:
	log = open(logfilename,"a")	
	log.write(linesep + "\tPerforming reconstruction with multiple centers of rotation...")			
	log.write(linesep + "\t--------------")		
	log.close()	

	# Split the computation into multiple processes:
	for num in range(nr_threads):
		start = ( (angles_to - angles_from + 1) / nr_threads)*num + angles_from
		if (num == nr_threads - 1):
			end = angles_to
		else:
			end = ( (angles_to - angles_from + 1) / nr_threads)*(num + 1) + angles_from - 1

		Process(target=reconstruct, args=(im, angles, offset/downsc_factor, logtransform, param1, circle, scale, pad, method, 
					   zerone_mode, dset_min, dset_max, corr_offset, postprocess_required, convert_opt, crop_opt, start, end, 
		               outpath, slice_nr, downsc_factor, decim_factor, logfilename, lock, slice_prefix)).start()
def process(lock, int_from, int_to, num_sinos, infile, outpath,
            preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx,
            flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right,
            ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem,
            angles, angles_projfrom, angles_projto, offset, logtransform,
            param1, circle, scale, pad, method, rolling, roll_shift,
            zerone_mode, dset_min, dset_max, decim_factor, downsc_factor,
            corr_offset, postprocess_required, polarfilt_opt, convert_opt,
            crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix,
            logfilename):
    """To do...

	"""
    # Process the required subset of images:
    for i in range(int_from, int_to + 1):

        # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if
        # required):
        #if (phaseretrieval_required):

        #	# Load into memory a bunch of sinograms:
        #	t0 = time()

        #	# Open the TDF file for reading:
        #	f_in = getHDF5(infile, 'r')
        #	if "/tomo" in f_in:
        #		dset = f_in['tomo']
        #	else:
        #		dset = f_in['exchange/data']

        #	# Prepare the data structure according to the approximation window:
        #	tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset),
        #	approx_win), dtype=float32)

        #	# Load the temporary data structure reading the input TDF file:
        #	# (It can be parallelized Open-MP style)
        #	ct = 0
        #	for j in range(i - approx_win/2, i + approx_win/2 + 1):
        #		if (j < 0):
        #			j = 0
        #		if (j >= num_sinos):
        #			j = num_sinos - 1
        #		a = tdf.read_sino(dset,j).astype(float32)
        #		tmp_im[:,:,ct] = a
        #		ct = ct + 1

        #	# Close the TDF file:
        #	f_in.close()
        #	t1 = time()

        #	# Perform the processing:
        #	if (preprocessing_required):
        #		ct = 0
        #		# (It can be parallelized Open-MP style)
        #		for j in range(i - approx_win/2, i + approx_win/2 + 1):
        #			if (j < 0):
        #				j = 0
        #			if (j >= num_sinos):
        #				j = num_sinos - 1

        #			tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end,
        #			half_half, half_half_line, norm_sx, norm_dx).astype(float32)
        #			tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov,
        #			ext_fov_rot_right, ext_fov_overlap).astype(float32)
        #			tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end,
        #			corr_plan['skip_flat_after'], half_half, half_half_line,
        #			ext_fov).astype(float32)
        #			ct = ct + 1

        #	# Perform phase retrieval:
        #	# (It can be parallelized Open-MP style)
        #	for ct in range(0, tmp_im.shape[0]):

        #		tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T,
        #		phrt_plan).astype(float32).T
        #		ct = ct + 1

        #	# Extract the central processed sinogram:
        #	im = tmp_im[:,:,approx_win/2]

        #else:

        # Read only one sinogram:
        t0 = time()
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im = tdf.read_sino(dset, i * downsc_factor).astype(float32)
        f_in.close()
        t1 = time()

        # Apply projection removal (if required):
        im = im[angles_projfrom:angles_projto, :]

        # Apply decimation and downscaling (if required):
        im = im[::decim_factor, ::downsc_factor]
        #i = i / downsc_factor

        # Perform the preprocessing of the sinogram (if required):
        if (preprocessing_required):
            if not skipflat:
                if dynamic_ff:
                    # Dynamic flat fielding with downsampling = 2:
                    im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark,
                                               norm_sx,
                                               norm_dx).astype(float32)
                else:
                    im = flat_fielding(im, i, corr_plan, flat_end, half_half,
                                       half_half_line / decim_factor, norm_sx,
                                       norm_dx).astype(float32)
            if ext_fov:
                im = extfov_correction(im, ext_fov_rot_right,
                                       ext_fov_overlap / downsc_factor,
                                       ext_fov_normalize, ext_fov_average)
            if not skipflat and not dynamic_ff:
                im = ring_correction(im, ringrem, flat_end,
                                     corr_plan['skip_flat_after'], half_half,
                                     half_half_line / decim_factor, ext_fov)
            else:
                im = ring_correction(im, ringrem, False, False, half_half,
                                     half_half_line, ext_fov)

        # Actual reconstruction:
        im = reconstruct(im, angles, offset / downsc_factor, logtransform,
                         param1, circle, scale, pad, method, rolling,
                         roll_shift, zerone_mode, dset_min, dset_max,
                         decim_factor, downsc_factor,
                         corr_offset).astype(float32)

        # Apply post-processing (if required):
        if postprocess_required:
            im = polarfilter(im, polarfilt_opt)
            im = croprescale(im, convert_opt, crop_opt)
        else:
            # Create the circle mask for fancy output:
            if (circle == True):
                siz = im.shape[1]
                if siz % 2:
                    rang = arange(-siz / 2 + 1, siz / 2 + 1)
                else:
                    rang = arange(-siz / 2, siz / 2)
                x, y = meshgrid(rang, rang)
                z = x**2 + y**2
                a = (z < (siz / 2 - abs(offset))**2)
                im = im * a

        # Write down reconstructed slice:
        t2 = time()
        fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif'
        imsave(fname, im)
        t3 = time()

        # Write log (atomic procedure - lock used):
        write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0))
Esempio n. 8
0
def process(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, 
			half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem,  
			angles, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, 
			downsc_factor, corr_offset,	postprocess_required, convert_opt, crop_opt, outprefix, logfilename):
	"""To do...

	"""
	# Process the required subset of images:
	for i in range(int_from, int_to + 1):                 
		
		# Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required):
		#if (phaseretrieval_required):
			
		#	# Load into memory a bunch of sinograms:
		#	t0 = time()

		#	# Open the TDF file for reading:
		#	f_in = getHDF5(infile, 'r')
		#	if "/tomo" in f_in:
		#		dset = f_in['tomo']
		#	else: 
		#		dset = f_in['exchange/data']

		#	# Prepare the data structure according to the approximation window:
		#	tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset), approx_win), dtype=float32)

		#	# Load the temporary data structure reading the input TDF file:
		#	# (It can be parallelized Open-MP style)
		#	ct = 0
		#	for j in range(i - approx_win/2, i + approx_win/2 + 1):
		#		if (j < 0):
		#			j = 0
		#		if (j >= num_sinos):
		#			j = num_sinos - 1
		#		a = tdf.read_sino(dset,j).astype(float32)
		#		tmp_im[:,:,ct] = a			
		#		ct = ct + 1
			
		#	# Close the TDF file:	
		#	f_in.close()
		#	t1 = time() 					

		#	# Perform the processing:
		#	if (preprocessing_required):
		#		ct = 0
		#		# (It can be parallelized Open-MP style)
		#		for j in range(i - approx_win/2, i + approx_win/2 + 1):
		#			if (j < 0):
		#				j = 0
		#			if (j >= num_sinos):
		#				j = num_sinos - 1					

		#			tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32)			
		#			tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov, ext_fov_rot_right, ext_fov_overlap).astype(float32)			
		#			tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov).astype(float32)
		#			ct = ct + 1

		#	# Perform phase retrieval:
		#	# (It can be parallelized Open-MP style)
		#	for ct in range(0, tmp_im.shape[0]):

		#		tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T, phrt_plan).astype(float32).T
		#		ct = ct + 1
			
		#	# Extract the central processed sinogram:
		#	im = tmp_im[:,:,approx_win/2]
			
		#else:

		# Read only one sinogram:
		t0 = time()
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_sino(dset,i).astype(float32)		
		f_in.close()
		t1 = time() 		
			
		# Perform the preprocessing of the sinogram (if required):
		if (preprocessing_required):
			im = flat_fielding (im, i, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32)			
			im = extfov_correction (im, ext_fov, ext_fov_rot_right, ext_fov_overlap)
			im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov)
		

		# Actual reconstruction:
		im = reconstruct(im, angles, offset, logtransform, param1, circle, scale, pad, method, 
						zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset).astype(float32)			
		
		# Appy post-processing (if required):
		if postprocess_required:
			im = postprocess(im, convert_opt, crop_opt)
		else:
			# Create the circle mask for fancy output:
			if (circle == True):
				siz = im.shape[1]
				if siz % 2:
					rang = arange(-siz / 2 + 1, siz / 2 + 1)
				else:
					rang = arange(-siz / 2,siz / 2)
				x,y = meshgrid(rang,rang)
				z = x ** 2 + y ** 2
				a = (z < (siz / 2 - abs(offset) ) ** 2)
				im = im * a			

		# Write down reconstructed slice:
		t2 = time() 	
		fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif'
		imsave(fname, im)
		t3 = time()
								
		# Write log (atomic procedure - lock used):
		write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )
Esempio n. 9
0
def process(sino_idx, num_sinos, infile, outfile, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, 
			half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem, phaseretrieval_required, beta, delta, 
			energy, distance, pixsize, phrtpad, approx_win, angles, offset, logtransform, param1, circle, scale, pad, method, 
			zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, 
			crop_opt, nr_threads, logfilename):
	"""To do...

	"""
	# Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required):
	if (phaseretrieval_required):
		
		# In this case a bunch of sinograms is loaded into memory:		

		#
		# Load the temporary data structure reading the input TDF file.
		# To know the right dimension the first sinogram is pre-processed.
		#		

		# Open the TDF file and get the dataset:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		
		# Downscaling and decimation factors considered when determining the approximation window:
		zrange = arange(sino_idx - approx_win*downsc_factor/2, sino_idx + approx_win*downsc_factor/2, downsc_factor)
		zrange = zrange[ (zrange >= 0) ]
		zrange = zrange[ (zrange < num_sinos) ]
		approx_win = zrange.shape[0]
		
		# Approximation window cannot be odd:
		if (approx_win % 2 == 1):
			approx_win = approx_win-1 
			zrange     = zrange[0:approx_win]
		
		# Read one sinogram to get the proper dimensions:
		test_im = tdf.read_sino(dset, zrange[0]).astype(float32)		
		test_im = test_im[::decim_factor, ::downsc_factor]

		# Perform the pre-processing of the first sinogram to get the right dimension:
		if (preprocessing_required):
			test_im = flat_fielding (test_im, zrange[0]/downsc_factor, corr_plan, flat_end, half_half, 
										half_half_line/decim_factor, norm_sx, norm_dx).astype(float32)	
			test_im = extfov_correction (test_im, ext_fov, ext_fov_rot_right, ext_fov_overlap/downsc_factor).astype(float32)			
			test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line/decim_factor, ext_fov).astype(float32)	
		
		# Now we can allocate memory for the bunch of slices:		
		tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32)
		tmp_im[0,:,:] = test_im

		# Reading all the the sinos from TDF file and close:
		for ct in range(1, approx_win):
			
			test_im = tdf.read_sino(dset, zrange[ct]).astype(float32)
			test_im = test_im[::decim_factor, ::downsc_factor]
			
			# Perform the pre-processing for each sinogram of the bunch:
			if (preprocessing_required):
				test_im = flat_fielding (test_im, zrange[ct]/downsc_factor, corr_plan, flat_end, half_half, 
											half_half_line/decim_factor, norm_sx, norm_dx).astype(float32)	
				test_im = extfov_correction (test_im, ext_fov, ext_fov_rot_right, ext_fov_overlap/downsc_factor).astype(float32)	
				test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
											half_half_line/decim_factor, ext_fov).astype(float32)	
			
			tmp_im[ct,:,:] = test_im
	
		f_in.close()

		# Now everything has to refer to a downscaled dataset:
		sino_idx = ((zrange == sino_idx).nonzero())

		#
		# Perform phase retrieval:
		#

		# Prepare the plan:		
		phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance, pixsize*downsc_factor, padding=phrtpad)
		
		# Process each projection (whose height depends on the size of the bunch):
		for ct in range(0, tmp_im.shape[1]):
			tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32)			
		
		# Extract the requested sinogram:
		im = tmp_im[sino_idx[0],:,:].squeeze()	

	else:

		# Read only one sinogram:
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im = tdf.read_sino(dset,sino_idx).astype(float32)		
		f_in.close()

		# Downscale and decimate the sinogram:
		im = im[::decim_factor,::downsc_factor]
		sino_idx = sino_idx/downsc_factor	
			
		# Perform the preprocessing of the sinogram (if required):
		if (preprocessing_required):
			im = flat_fielding (im, sino_idx, corr_plan, flat_end, half_half, half_half_line/decim_factor, 
								norm_sx, norm_dx).astype(float32)		
			im = extfov_correction (im, ext_fov, ext_fov_rot_right, ext_fov_overlap)
			#imsave('C:\\Temp\\StupidFolder\\sinoprimaringrem.tif', im.astype(float32))
			im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
								half_half_line/decim_factor, ext_fov)
			#imsave('C:\\Temp\\StupidFolder\\sinodoporingrem.tif', im.astype(float32))


	# Actual reconstruction:
	im = reconstruct(im, angles, offset/downsc_factor, logtransform, param1, circle, scale, pad, method, 
					zerone_mode, dset_min, dset_max, corr_offset).astype(float32)	

	# Apply post-processing (if required):
	if postprocess_required:
		im = postprocess(im, convert_opt, crop_opt)
	else:
		# Create the circle mask for fancy output:
		if (circle == True):
			siz = im.shape[1]
			if siz % 2:
				rang = arange(-siz / 2 + 1, siz / 2 + 1)
			else:
				rang = arange(-siz / 2,siz / 2)
			x,y = meshgrid(rang,rang)
			z = x ** 2 + y ** 2
			a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2)
			im = im * a			

    # Write down reconstructed preview file (file name modified with metadata):		
	im = im.astype(float32)
	outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( amin(im)) + '$' + str( amax(im) )	
	im.tofile(outfile)	
Esempio n. 10
0
def main(argv):
    """To do...


	"""
    # Get the zero-order index of the sinogram to pre-process:
    idx = int(argv[0])

    # Get paths:
    infile = argv[1]
    outfile = argv[2]

    # Normalization parameters:
    norm_sx = int(argv[3])
    norm_dx = int(argv[4])

    # Params for flat fielding with post flats/darks:
    flat_end = True if argv[5] == "True" else False
    half_half = True if argv[6] == "True" else False
    half_half_line = int(argv[7])

    # Flat fielding method (conventional or dynamic):
    dynamic_ff = True if argv[8] == "True" else False

    # Parameters for rotation:
    rotation = float(argv[9])
    interp = argv[10]
    border = argv[11]

    # Tmp path and log file:
    tmppath = argv[12]
    if not tmppath.endswith(sep): tmppath += sep
    logfilename = argv[13]

    # Open the HDF5 file:
    f_in = getHDF5(infile, 'r')

    try:
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']

    except:
        log = open(logfilename, "a")
        log.write(linesep + "\tError reading input dataset. Process will end.")
        log.close()
        exit()

    num_proj = tdf.get_nr_projs(dset)
    num_sinos = tdf.get_nr_sinos(dset)

    # Check if the HDF5 makes sense:
    if (num_sinos == 0):
        log = open(logfilename, "a")
        log.write(linesep + "\tNo projections found. Process will end.")
        log.close()
        exit()

    # Get flat and darks from cache or from file:
    skipflat = False
    skipdark = False
    if not dynamic_ff:
        try:
            corrplan = cache2plan(infile, tmppath)
        except Exception as e:
            #print "Error(s) when reading from cache"
            corrplan = extract_flatdark(f_in, flat_end, logfilename)
            if (isscalar(corrplan['im_flat'])
                    and isscalar(corrplan['im_flat_after'])):
                skipflat = True
            else:
                plan2cache(corrplan, infile, tmppath)
    else:
        # Dynamic flat fielding:
        if "/tomo" in f_in:
            if "/flat" in f_in:
                flat_dset = f_in['flat']
                if "/dark" in f_in:
                    im_dark = _medianize(f_in['dark'])
                else:
                    skipdark = True
            else:
                skipflat = True  # Nothing to do in this case
        else:
            if "/exchange/data_white" in f_in:
                flat_dset = f_in['/exchange/data_white']
                if "/exchange/data_dark" in f_in:
                    im_dark = _medianize(f_in['/exchange/data_dark'])
                else:
                    skipdark = True
            else:
                skipflat = True  # Nothing to do in this case

        # Prepare plan for dynamic flat fielding with 16 repetitions:
        if not skipflat:
            EFF, filtEFF = dff_prepare_plan(flat_dset, 16, im_dark)

    # Read input image:
    im = tdf.read_tomo(dset, idx).astype(float32)
    f_in.close()

    # Perform pre-processing (flat fielding, extended FOV, ring removal):
    if not skipflat:
        if dynamic_ff:
            # Dynamic flat fielding with downsampling = 2:
            im = dynamic_flat_fielding(im, EFF, filtEFF, 2, im_dark)
        else:
            im = flat_fielding(im, idx, corrplan, flat_end, half_half,
                               half_half_line, norm_sx, norm_dx)

    # Rotate:
    rows, cols = im.shape
    M = cv2.getRotationMatrix2D((cols / 2, rows / 2), rotation, 1)

    if interp == 'nearest':
        interpflag = cv2.INTER_NEAREST
    elif interp == 'cubic':
        interpflag = cv2.INTER_CUBIC
    elif interp == 'lanczos':
        interpflag = cv2.INTER_LANCZOS4
    else:
        interpflag = cv2.INTER_LINEAR

    if border == 'constant':
        borderflag = cv2.BORDER_CONSTANT
    else:
        borderflag = cv2.BORDER_REPLICATE

    im = cv2.warpAffine(im,
                        M, (cols, rows),
                        flags=interpflag,
                        borderMode=borderflag)

    # Write down reconstructed preview file (file name modified with metadata):
    im = im.astype(float32)
    outfile2 = outfile + '_' + str(im.shape[1]) + 'x' + str(
        im.shape[0]) + '_' + str(nanmin(im)) + '$' + str(
            nanmax(im)) + '_after.raw'
    im.tofile(outfile2)
Esempio n. 11
0
def _process(lock, int_from, int_to, num_sinos, infile_1, infile_2, infile_3,
             outfile_abs, outfile_ref, outfile_sca, r1, r2, r3, d1, d2, d3,
             dd1, dd2, dd3, shiftVert_1, shiftHoriz_1, shiftVert_2,
             shiftHoriz_2, shiftVert_3, shiftHoriz_3, outshape, outtype,
             skipflat_1, skipflat_2, skipflat_3, plan_1, plan_2, plan_3,
             norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov,
             ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize,
             ext_fov_average, ringrem, dynamic_ff, EFF_1, EFF_2, EFF_3,
             filtEFF_1, filtEFF_2, filtEFF_3, im_dark_1, im_dark_2, im_dark_3,
             logfilename):

    # Process the required subset of images:
    for i in range(int_from, int_to + 1):

        # Read input image for top, left and right:
        t0 = time()
        f_in = getHDF5(infile_1, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
            flat_avg1 = float(f_in['flat'].attrs['avg'])
            dark_avg1 = float(f_in['dark'].attrs['avg'])
        else:
            dset = f_in['exchange/data']
            flat_avg1 = float(f_in['exchange/data_white'].attrs['avg'])
            dark_avg1 = float(f_in['exchange/data_dark'].attrs['avg'])
        # Processing in the sinogram domain so a vertical shift of the
        # projection requires loading a different sinogram:
        idx1 = min(max(0, i - shiftVert_1), num_sinos - 1)
        im_1 = tdf.read_sino(dset, idx1).astype(float32)
        f_in.close()

        f_in = getHDF5(infile_2, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
            flat_avg2 = float(f_in['flat'].attrs['avg'])
            dark_avg2 = float(f_in['dark'].attrs['avg'])
        else:
            dset = f_in['exchange/data']
            flat_avg2 = float(f_in['exchange/data_white'].attrs['avg'])
            dark_avg2 = float(f_in['exchange/data_dark'].attrs['avg'])
        # Processing in the sinogram domain so a vertical shift of the
        # projection requires loading a different sinogram:
        idx2 = min(max(0, i - shiftVert_2), num_sinos - 1)
        im_2 = tdf.read_sino(dset, idx2).astype(float32)
        f_in.close()

        f_in = getHDF5(infile_3, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
            flat_avg3 = float(f_in['flat'].attrs['avg'])
            dark_avg3 = float(f_in['dark'].attrs['avg'])
        else:
            dset = f_in['exchange/data']
            flat_avg3 = float(f_in['exchange/data_white'].attrs['avg'])
            dark_avg3 = float(f_in['exchange/data_dark'].attrs['avg'])
        # Processing in the sinogram domain so a vertical shift of the projection
        # requires loading a different sinogram:
        idx3 = min(max(0, i - shiftVert_3), num_sinos - 1)
        im_3 = tdf.read_sino(dset, idx3).astype(float32)
        f_in.close()
        t1 = time()

        # Perform pre-processing (flat fielding, extended FOV, ring removal):
        if not skipflat_1:
            if dynamic_ff:
                # Dynamic flat fielding with downsampling = 2:
                im_1 = dynamic_flat_fielding(im_1, idx1, EFF_1, filtEFF_1, 2,
                                             im_dark_1, norm_sx, norm_dx)
            else:
                im_1 = flat_fielding(im_1, idx1, plan_1, flat_end, half_half,
                                     half_half_line, norm_sx, norm_dx)
        if ext_fov:
            im_1 = extfov_correction(im_1, ext_fov_rot_right, ext_fov_overlap,
                                     ext_fov_normalize, ext_fov_average)

        if not skipflat_1 and not dynamic_ff:
            im_1 = ring_correction(im_1, ringrem, flat_end,
                                   plan_1['skip_flat_after'], half_half,
                                   half_half_line, ext_fov)
        else:
            im_1 = ring_correction(im_1, ringrem, False, False, half_half,
                                   half_half_line, ext_fov)

        # Perform pre-processing (flat fielding, extended FOV, ring removal):
        if not skipflat_2:
            if dynamic_ff:
                # Dynamic flat fielding with downsampling = 2:
                im_2 = dynamic_flat_fielding(im_2, idx2, EFF_2, filtEFF_2, 2,
                                             im_dark_2, norm_sx, norm_dx)
            else:
                im_2 = flat_fielding(im_2, idx2, plan_2, flat_end, half_half,
                                     half_half_line, norm_sx, norm_dx)
        if ext_fov:
            im_2 = extfov_correction(im_2, ext_fov_rot_right, ext_fov_overlap,
                                     ext_fov_normalize, ext_fov_average)

        if not skipflat_2 and not dynamic_ff:
            im_2 = ring_correction(im_2, ringrem, flat_end,
                                   plan_2['skip_flat_after'], half_half,
                                   half_half_line, ext_fov)
        else:
            im_2 = ring_correction(im_2, ringrem, False, False, half_half,
                                   half_half_line, ext_fov)

        # Perform pre-processing (flat fielding, extended FOV, ring removal):
        if not skipflat_3:
            if dynamic_ff:
                # Dynamic flat fielding with downsampling = 2:
                im_3 = dynamic_flat_fielding(im_3, idx3, EFF_3, filtEFF_3, 2,
                                             im_dark_3, norm_sx, norm_dx)
            else:
                im_3 = flat_fielding(im_3, idx3, plan_3, flat_end, half_half,
                                     half_half_line, norm_sx, norm_dx)
        if ext_fov:
            im_3 = extfov_correction(im_3, ext_fov_rot_right, ext_fov_overlap,
                                     ext_fov_normalize, ext_fov_average)

        if not skipflat_3 and not dynamic_ff:
            im_3 = ring_correction(im_3, ringrem, flat_end,
                                   plan_3['skip_flat_after'], half_half,
                                   half_half_line, ext_fov)
        else:
            im_3 = ring_correction(im_3, ringrem, False, False, half_half,
                                   half_half_line, ext_fov)

        t2 = time()

        # Processing in the sinogram domain so a vertical shift of the
        # projection requires loading a different sinogram:
        # Only horizontal shift can be considered at a sinogram level:
        if (shiftHoriz_1 != 0):
            im_1 = _shift_horiz(im_1, shiftHoriz_1)

        if (shiftHoriz_2 != 0):
            im_2 = _shift_horiz(im_2, shiftHoriz_2)

        if (shiftHoriz_3 != 0):
            im_3 = _shift_horiz(im_3, shiftHoriz_3)

        # Re-normalize with average of the flat-field images:
        max_val = amax(
            array([
                mean(flat_avg1 - dark_avg1),
                mean(flat_avg2 - dark_avg2),
                mean(flat_avg3 - dark_avg3)
            ]))

        im_1 = im_1 * (flat_avg1 - dark_avg1) / max_val
        im_2 = im_2 * (flat_avg2 - dark_avg2) / max_val
        im_3 = im_3 * (flat_avg3 - dark_avg3) / max_val

        # Apply GDEI:
        (im_abs, im_ref, im_sca) = gdei(im_1, im_2, im_3, r1, r2, r3, d1, d2,
                                        d3, dd1, dd2, dd3)

        # Save processed image to HDF5 file (atomic procedure - lock used):
        lock.acquire()
        try:
            t3 = time()
            _write_data(im_abs, i, outfile_abs, outshape, outtype)
            _write_data(im_ref, i, outfile_ref, outshape, outtype)
            _write_data(im_sca, i, outfile_sca, outshape, outtype)
            t4 = time()

            # Print out execution time:
            log = open(logfilename, "a")
            log.write(
                linesep +
                "\tsino_%s processed (CPU: %0.3f sec - I/O: %0.3f sec)." %
                (str(i).zfill(4), t2 - t1, (t1 - t0) + (t4 - t3)))
            log.close()

        finally:
            lock.release()
Esempio n. 12
0
def main(argv):
    """To do...


	"""
    # Get the zero-order index of the sinogram to pre-process:
    idx = int(argv[0])

    # Get paths:
    infile = argv[1]
    outfile = argv[2]

    # Normalization parameters:
    norm_sx = int(argv[3])
    norm_dx = int(argv[4])

    # Params for flat fielding with post flats/darks:
    flat_end = True if argv[5] == "True" else False
    half_half = True if argv[6] == "True" else False
    half_half_line = int(argv[7])

    # Params for extended FOV:
    ext_fov = True if argv[8] == "True" else False
    ext_fov_rot_right = argv[9]
    if ext_fov_rot_right == "True":
        ext_fov_rot_right = True
        if (ext_fov):
            norm_sx = 0
    else:
        ext_fov_rot_right = False
        if (ext_fov):
            norm_dx = 0
    ext_fov_overlap = int(argv[10])

    ext_fov_normalize = True if argv[11] == "True" else False
    ext_fov_average = True if argv[12] == "True" else False

    # Method and parameters coded into a string:
    ringrem = argv[13]

    # Flat fielding method (conventional or dynamic):
    dynamic_ff = True if argv[14] == "True" else False

    # Tmp path and log file:
    tmppath = argv[15]
    if not tmppath.endswith(sep): tmppath += sep
    logfilename = argv[16]

    # Open the HDF5 file:
    f_in = getHDF5(infile, 'r')

    try:
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']

    except:
        log = open(logfilename, "a")
        log.write(linesep + "\tError reading input dataset. Process will end.")
        log.close()
        exit()

    num_proj = tdf.get_nr_projs(dset)
    num_sinos = tdf.get_nr_sinos(dset)

    # Check if the HDF5 makes sense:
    if (num_sinos == 0):
        log = open(logfilename, "a")
        log.write(linesep + "\tNo projections found. Process will end.")
        log.close()
        exit()

    # Get flat and darks from cache or from file:
    skipflat = False
    skipdark = False
    if not dynamic_ff:
        try:
            corrplan = cache2plan(infile, tmppath)
        except Exception as e:
            #print "Error(s) when reading from cache"
            corrplan = extract_flatdark(f_in, flat_end, logfilename)
            if (isscalar(corrplan['im_flat'])
                    and isscalar(corrplan['im_flat_after'])):
                skipflat = True
            else:
                plan2cache(corrplan, infile, tmppath)
    else:
        # Dynamic flat fielding:
        if "/tomo" in f_in:
            if "/flat" in f_in:
                flat_dset = f_in['flat']
                if "/dark" in f_in:
                    im_dark = _medianize(f_in['dark'])
                else:
                    skipdark = True
            else:
                skipflat = True  # Nothing to do in this case
        else:
            if "/exchange/data_white" in f_in:
                flat_dset = f_in['/exchange/data_white']
                if "/exchange/data_dark" in f_in:
                    im_dark = _medianize(f_in['/exchange/data_dark'])
                else:
                    skipdark = True
            else:
                skipflat = True  # Nothing to do in this case

        # Prepare plan for dynamic flat fielding with 16 repetitions:
        if not skipflat:
            EFF, filtEFF = dff_prepare_plan(flat_dset, 16, im_dark)

    # Read input image:
    im = tdf.read_sino(dset, idx).astype(float32)
    f_in.close()

    # Perform pre-processing (flat fielding, extended FOV, ring removal):
    if not skipflat:
        if dynamic_ff:
            # Dynamic flat fielding with downsampling = 2:
            im = dynamic_flat_fielding(im, idx, EFF, filtEFF, 2, im_dark,
                                       norm_sx, norm_dx)
        else:
            im = flat_fielding(im, idx, corrplan, flat_end, half_half,
                               half_half_line, norm_sx, norm_dx)
    if ext_fov:
        im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap,
                               ext_fov_normalize, ext_fov_average)
    if not skipflat and not dynamic_ff:
        im = ring_correction(im, ringrem, flat_end,
                             corrplan['skip_flat_after'], half_half,
                             half_half_line, ext_fov)
    else:
        im = ring_correction(im, ringrem, False, False, half_half,
                             half_half_line, ext_fov)

    # Write down reconstructed preview file (file name modified with metadata):
    im = im.astype(float32)
    outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(
        im.shape[0]) + '_' + str(nanmin(im)) + '$' + str(nanmax(im))
    im.tofile(outfile)
Esempio n. 13
0
def process(sino_idx, num_sinos, infile, outfile, preprocessing_required,
            corr_plan, skipflat, norm_sx, norm_dx, flat_end, half_half,
            half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap,
            ext_fov_normalize, ext_fov_average, ringrem,
            phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2,
            energy, distance, pixsize, phrtpad, approx_win, angles,
            angles_projfrom, angles_projto, offset, logtransform, recpar,
            circle, scale, pad, method, rolling, roll_shift, zerone_mode,
            dset_min, dset_max, decim_factor, downsc_factor, corr_offset,
            postprocess_required, polarfilt_opt, convert_opt, crop_opt,
            dynamic_ff, EFF, filtEFF, im_dark, nr_threads, logfilename,
            tmppath):
    """To do...

	"""
    # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if
    # required):
    if (phaseretrieval_required):

        # In this case a bunch of sinograms is loaded into memory:

        #
        # Load the temporary data structure reading the input TDF file.
        # To know the right dimension the first sinogram is pre-processed.
        #

        # Open the TDF file and get the dataset:
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']

        # Downscaling and decimation factors considered when determining the
        # approximation window:
        zrange = arange(sino_idx - approx_win * downsc_factor / 2,
                        sino_idx + approx_win * downsc_factor / 2,
                        downsc_factor)
        zrange = zrange[(zrange >= 0)]
        zrange = zrange[(zrange < num_sinos)]
        approx_win = zrange.shape[0]

        # Approximation window cannot be odd:
        if (approx_win % 2 == 1):
            approx_win = approx_win - 1
            zrange = zrange[0:approx_win]

        # Read one sinogram to get the proper dimensions:
        test_im = tdf.read_sino(dset,
                                zrange[0] * downsc_factor).astype(float32)

        # Apply projection removal (if required):
        test_im = test_im[angles_projfrom:angles_projto, :]

        # Apply decimation and downscaling (if required):
        test_im = test_im[::decim_factor, ::downsc_factor]

        # Perform the pre-processing of the first sinogram to get the right
        # dimension:
        if (preprocessing_required):
            if not skipflat:
                if dynamic_ff:
                    # Dynamic flat fielding with downsampling = 2:
                    #test_im = dynamic_flat_fielding(test_im, zrange[0] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
                    test_im = dynamic_flat_fielding(test_im, zrange[0], EFF,
                                                    filtEFF, 2, im_dark,
                                                    norm_sx, norm_dx)
                else:
                    #test_im = flat_fielding(test_im, zrange[0] / downsc_factor, corr_plan, flat_end, half_half,
                    #						half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)
                    test_im = flat_fielding(test_im, zrange[0], corr_plan,
                                            flat_end, half_half,
                                            half_half_line / decim_factor,
                                            norm_sx, norm_dx).astype(float32)
            if ext_fov:
                test_im = extfov_correction(test_im, ext_fov_rot_right,
                                            ext_fov_overlap / downsc_factor,
                                            ext_fov_normalize,
                                            ext_fov_average).astype(float32)
            if not skipflat and not dynamic_ff:
                test_im = ring_correction(test_im, ringrem, flat_end,
                                          corr_plan['skip_flat_after'],
                                          half_half,
                                          half_half_line / decim_factor,
                                          ext_fov).astype(float32)
            else:
                test_im = ring_correction(test_im, ringrem, False, False,
                                          half_half,
                                          half_half_line / decim_factor,
                                          ext_fov).astype(float32)

        # Now we can allocate memory for the bunch of slices:
        tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]),
                       dtype=float32)
        tmp_im[0, :, :] = test_im

        # Reading all the the sinos from TDF file and close:
        for ct in range(1, approx_win):

            # Read the sinogram:
            test_im = tdf.read_sino(dset,
                                    zrange[ct] * downsc_factor).astype(float32)

            # Apply projection removal (if required):
            test_im = test_im[angles_projfrom:angles_projto, :]

            # Apply decimation and downscaling (if required):
            test_im = test_im[::decim_factor, ::downsc_factor]

            # Perform the pre-processing for each sinogram of the bunch:
            if (preprocessing_required):
                if not skipflat:
                    if dynamic_ff:
                        # Dynamic flat fielding with downsampling = 2:
                        #test_im = dynamic_flat_fielding(test_im, zrange[ct] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
                        test_im = dynamic_flat_fielding(
                            test_im, zrange[ct], EFF, filtEFF, 2, im_dark,
                            norm_sx, norm_dx)
                    else:
                        #test_im = flat_fielding(test_im, zrange[ct] / downsc_factor, corr_plan, flat_end, half_half,
                        #					half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)
                        test_im = flat_fielding(test_im, zrange[ct], corr_plan,
                                                flat_end, half_half,
                                                half_half_line / decim_factor,
                                                norm_sx,
                                                norm_dx).astype(float32)
                if ext_fov:
                    test_im = extfov_correction(
                        test_im, ext_fov_rot_right,
                        ext_fov_overlap / downsc_factor, ext_fov_normalize,
                        ext_fov_average).astype(float32)
                if not skipflat and not dynamic_ff:
                    test_im = ring_correction(test_im, ringrem, flat_end,
                                              corr_plan['skip_flat_after'],
                                              half_half,
                                              half_half_line / decim_factor,
                                              ext_fov).astype(float32)
                else:
                    test_im = ring_correction(test_im, ringrem, False, False,
                                              half_half,
                                              half_half_line / decim_factor,
                                              ext_fov).astype(float32)

            tmp_im[ct, :, :] = test_im

        f_in.close()

        # Now everything has to refer to a downscaled dataset:
        sino_idx = ((zrange == sino_idx).nonzero())

        #
        # Perform phase retrieval:
        #

        # Prepare the plan:
        if (phrtmethod == 0):
            # Paganin 2002:
            phrtplan = tiehom_plan(tmp_im[:, 0, :], phrt_param1, phrt_param2,
                                   energy, distance, pixsize * downsc_factor,
                                   phrtpad)
        elif (phrtmethod == 1):
            # Paganin 2020:
            phrtplan = tiehom_plan2020(tmp_im[:, 0, :], phrt_param1,
                                       phrt_param2, energy, distance,
                                       pixsize * downsc_factor, phrtpad)
        else:
            phrtplan = phrt_plan(tmp_im[:, 0, :], energy, distance,
                                 pixsize * downsc_factor, phrt_param2,
                                 phrt_param1, phrtmethod, phrtpad)
            #phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance,
            #pixsize*downsc_factor, padding=phrtpad)

        # Process each projection (whose height depends on the size of the bunch):
        for ct in range(0, tmp_im.shape[1]):
            #tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32)
            if (phrtmethod == 0):
                tmp_im[:, ct, :] = tiehom(tmp_im[:, ct, :],
                                          phrtplan).astype(float32)
            elif (phrtmethod == 1):
                tmp_im[:, ct, :] = tiehom2020(tmp_im[:, ct, :],
                                              phrtplan).astype(float32)
            else:
                tmp_im[:, ct, :] = phrt(tmp_im[:, ct, :], phrtplan,
                                        phrtmethod).astype(float32)

        # Extract the requested sinogram:
        im = tmp_im[sino_idx[0], :, :].squeeze()

    else:

        # Read only one sinogram:
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im = tdf.read_sino(dset, sino_idx * downsc_factor).astype(float32)
        f_in.close()

        # Apply projection removal (if required):
        im = im[angles_projfrom:angles_projto, :]

        # Apply decimation and downscaling (if required):
        im = im[::decim_factor, ::downsc_factor]
        #sino_idx = sino_idx / downsc_factor	# Downscaling for the index already applied

        # Perform the preprocessing of the sinogram (if required):
        if (preprocessing_required):
            if not skipflat:
                if dynamic_ff:
                    # Dynamic flat fielding with downsampling = 2:
                    im = dynamic_flat_fielding(im, sino_idx, EFF, filtEFF, 2,
                                               im_dark, norm_sx, norm_dx)
                else:
                    im = flat_fielding(im, sino_idx, corr_plan, flat_end,
                                       half_half,
                                       half_half_line / decim_factor, norm_sx,
                                       norm_dx).astype(float32)
            if ext_fov:
                im = extfov_correction(im, ext_fov_rot_right,
                                       ext_fov_overlap / downsc_factor,
                                       ext_fov_normalize, ext_fov_average)
            if not skipflat and not dynamic_ff:
                im = ring_correction(im, ringrem, flat_end,
                                     corr_plan['skip_flat_after'], half_half,
                                     half_half_line / decim_factor, ext_fov)
            else:
                im = ring_correction(im, ringrem, False, False, half_half,
                                     half_half_line / decim_factor, ext_fov)

    # Additional ring removal before reconstruction:
    #im = boinhaibel(im, '11;')
    #im = munchetal(im, '5;1.8')
    #im = rivers(im, '13;')
    #im = raven(im, '11;0.8')
    #im = oimoen(im, '51;51')

    # Actual reconstruction:
    im = reconstruct(im, angles, offset / downsc_factor, logtransform, recpar,
                     circle, scale, pad, method, zerone_mode, dset_min,
                     dset_max, corr_offset, rolling, roll_shift,
                     tmppath).astype(float32)

    # Apply post-processing (if required):
    if postprocess_required:
        im = polarfilter(im, polarfilt_opt)
        im = croprescale(im, convert_opt, crop_opt)
    else:
        # Create the circle mask for fancy output:
        if (circle == True):
            siz = im.shape[1]
            if siz % 2:
                rang = arange(-siz / 2 + 1, siz / 2 + 1)
            else:
                rang = arange(-siz / 2, siz / 2)
            x, y = meshgrid(rang, rang)
            z = x**2 + y**2
            a = (z < (siz / 2 - int(round(abs(offset) / downsc_factor)))**2)
            im = im * a

    # Write down reconstructed preview file (file name modified with metadata):
    im = im.astype(float32)
    outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(
        im.shape[0]) + '_' + str(amin(im)) + '$' + str(amax(im))
    im.tofile(outfile)
Esempio n. 14
0
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, 
			norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, 
			ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto,
			offset, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, 
			downsc_factor, corr_offset,	postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, 
			outprefix, logfilename):
	"""To do...

	"""
	# Process the required subset of images:
	for i in range(int_from, int_to + 1, 2):               
		
		# Read two sinograms:
		t0 = time()
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im1 = tdf.read_sino(dset,i*downsc_factor).astype(float32)		
		if ( (i + downsc_factor) <= (int_to + 1) ):
			im2 = tdf.read_sino(dset,i*downsc_factor + downsc_factor).astype(float32)		
		else:
			im2 = im1
		f_in.close()
		t1 = time() 	


		# Apply projection removal (if required):
		im1 = im1[angles_projfrom:angles_projto, :]				
		im2 = im2[angles_projfrom:angles_projto, :]	
		
		# Apply decimation and downscaling (if required):
		im1 = im1[::decim_factor,::downsc_factor]
		im2 = im2[::decim_factor,::downsc_factor]
		#i = i / downsc_factor				
			
		# Perform the preprocessing of the sinograms (if required):
		if (preprocessing_required):
			if not skipflat:			
				if dynamic_ff:
					# Dynamic flat fielding with downsampling = 2:
					im1 = dynamic_flat_fielding(im1, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
				else:
					im1 = flat_fielding (im1, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)		
			if ext_fov:
				im1 = extfov_correction (im1, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average)
			if not skipflat:
				im1 = ring_correction (im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
						   half_half_line / decim_factor, ext_fov)
			else:
				im1 = ring_correction (im1, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov)

			if not skipflat:
				if dynamic_ff:
					# Dynamic flat fielding with downsampling = 2:
					im2 = dynamic_flat_fielding(im2, i + 1, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
				else:
					im2 = flat_fielding (im2, i + 1, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32)	
			if ext_fov:	
				im2 = extfov_correction (im2, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average)
			if not skipflat and not dynamic_ff:		
				im2 = ring_correction (im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, 
						   half_half_line / decim_factor, ext_fov)
			else:
				im2 = ring_correction (im2, ringrem, False, False, half_half, half_half_line, ext_fov)
		

		# Actual reconstruction:
		[im1, im2] = reconstruct_gridrec(im1, im2, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, rolling, roll_shift,
						zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset)					

		# Appy post-processing (if required):
		if postprocess_required:

			# Filter (if required):
			im1 = polarfilter(im1, polarfilt_opt)    
			im2 = polarfilter(im2, polarfilt_opt)

			im1 = croprescale(im1, convert_opt, crop_opt, circle)
			im2 = croprescale(im2, convert_opt, crop_opt, circle)

		else:
			# Create the circle mask for fancy output:
			if (circle == True):
				siz = im1.shape[1]
				if siz % 2:
					rang = arange(-siz / 2 + 1, siz / 2 + 1)
				else:
					rang = arange(-siz / 2,siz / 2)
				x,y = meshgrid(rang,rang)
				z = x ** 2 + y ** 2
				a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2)
				
				im1 = im1 * a			
				im2 = im2 * a	
	
		# Write down reconstructed slices:
		t2 = time() 	

		fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif'
		imsave(fname1, im1)

		fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif'
		imsave(fname2, im2)

		t3 = time()
								
		# Write log (atomic procedure - lock used):
		write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )		
def main(argv):          
	"""To do...


	"""
	# Get the zero-order index of the sinogram to pre-process:
	idx = int(argv[0])
	   
	# Get paths:
	infile = argv[1]
	outfile = argv[2]
	
	# Normalization parameters:
	norm_sx = int(argv[3])
	norm_dx = int(argv[4])
	
	# Params for flat fielding with post flats/darks:
	flat_end = True if argv[5] == "True" else False
	half_half = True if argv[6] == "True" else False
	half_half_line = int(argv[7])
		
	# Params for extended FOV:
	ext_fov = True if argv[8] == "True" else False
	ext_fov_rot_right = argv[9]
	if ext_fov_rot_right == "True":
		ext_fov_rot_right = True
		if (ext_fov):
			norm_sx = 0
	else:
		ext_fov_rot_right = False
		if (ext_fov):
			norm_dx = 0		
	ext_fov_overlap = int(argv[10])

	ext_fov_normalize = True if argv[11] == "True" else False
	ext_fov_average = True if argv[12] == "True" else False
		
	# Method and parameters coded into a string:
	ringrem = argv[13]	
	
	# Flat fielding method (conventional or dynamic):
	dynamic_ff = True if argv[14] == "True" else False
	
	# Tmp path and log file:
	tmppath = argv[15]	
	if not tmppath.endswith(sep): tmppath += sep		
	logfilename = argv[16]		

	
	# Open the HDF5 file:	
	f_in = getHDF5(infile, 'r')
	
	try:
		if "/tomo" in f_in:
			dset = f_in['tomo']		
		else: 
			dset = f_in['exchange/data']		
	
	except:
		log = open(logfilename,"a")
		log.write(linesep + "\tError reading input dataset. Process will end.")		
		log.close()			
		exit()
		
	num_proj = tdf.get_nr_projs(dset)
	num_sinos = tdf.get_nr_sinos(dset)
	
	# Check if the HDF5 makes sense:
	if (num_sinos == 0):
		log = open(logfilename,"a")
		log.write(linesep + "\tNo projections found. Process will end.")	
		log.close()			
		exit()		

	# Get flat and darks from cache or from file:
	skipflat = False
	skipdark = False
	if not dynamic_ff:
		try:
			corrplan = cache2plan(infile, tmppath)
		except Exception as e:
			#print "Error(s) when reading from cache"
			corrplan = extract_flatdark(f_in, flat_end, logfilename)
			if (isscalar(corrplan['im_flat']) and isscalar(corrplan['im_flat_after']) ):
				skipflat = True
			else:
				plan2cache(corrplan, infile, tmppath)					
	else:
		# Dynamic flat fielding:
		if "/tomo" in f_in:				
			if "/flat" in f_in:
				flat_dset = f_in['flat']
				if "/dark" in f_in:
					im_dark = _medianize(f_in['dark'])
				else:										
					skipdark = True
			else:
				skipflat = True # Nothing to do in this case			
		else: 
			if "/exchange/data_white" in f_in:
				flat_dset = f_in['/exchange/data_white']
				if "/exchange/data_dark" in f_in:
					im_dark = _medianize(f_in['/exchange/data_dark'])
				else:					
					skipdark = True
			else:
				skipflat = True # Nothing to do in this case
	
		# Prepare plan for dynamic flat fielding with 16 repetitions:
		if not skipflat:	
			EFF, filtEFF = dff_prepare_plan(flat_dset, 16, im_dark)

	# Read input image:
	im = tdf.read_sino(dset,idx).astype(float32)	
	f_in.close()	

	# Perform pre-processing (flat fielding, extended FOV, ring removal):	
	if not skipflat:
		if dynamic_ff:
			# Dynamic flat fielding with downsampling = 2:
			im = dynamic_flat_fielding(im, idx, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx)
		else:
			im = flat_fielding(im, idx, corrplan, flat_end, half_half, half_half_line, norm_sx, norm_dx)	
	if ext_fov:			
		im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average)
	if not skipflat and not dynamic_ff:
		im = ring_correction (im, ringrem, flat_end, corrplan['skip_flat_after'], half_half, half_half_line, ext_fov)		
	else:
		im = ring_correction (im, ringrem, False, False, half_half, half_half_line, ext_fov)						

	# Write down reconstructed preview file (file name modified with metadata):		
	im = im.astype(float32)
	outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( nanmin(im)) + '$' + str( nanmax(im) )	
	im.tofile(outfile)
Esempio n. 16
0
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, 
			norm_dx, flat_end, half_half, 
			half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem, 
			angles, offset, logtransform, param1, circle, scale, pad, zerone_mode, dset_min, dset_max, decim_factor, 
			downsc_factor, corr_offset,	postprocess_required, convert_opt, crop_opt, outprefix, logfilename):
	"""To do...

	"""
	# Process the required subset of images:
	for i in range(int_from, int_to + 1, 2):               
		
		# Read two sinograms:
		t0 = time()
		f_in = getHDF5(infile, 'r')
		if "/tomo" in f_in:
			dset = f_in['tomo']
		else: 
			dset = f_in['exchange/data']
		im1 = tdf.read_sino(dset,i).astype(float32)		
		if ( (i + 1) <= (int_to + 1) ):
			im2 = tdf.read_sino(dset,i + 1).astype(float32)		
		else:
			im2 = im1
		f_in.close()
		t1 = time() 		
			
		# Perform the preprocessing of the sinograms (if required):
		if (preprocessing_required):
			im1 = flat_fielding (im1, i, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32)			
			im1 = extfov_correction (im1, ext_fov, ext_fov_rot_right, ext_fov_overlap)
			im1 = ring_correction (im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov)

			im2 = flat_fielding (im2, i + 1, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32)			
			im2 = extfov_correction (im2, ext_fov, ext_fov_rot_right, ext_fov_overlap)
			im2 = ring_correction (im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov)
		

		# Actual reconstruction:
		[im1, im2] = reconstruct_gridrec(im1, im2, angles, offset, logtransform, param1, circle, scale, pad,  
						zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset)					

		# Appy post-processing (if required):
		if postprocess_required:
			im1 = postprocess(im1, convert_opt, crop_opt, circle)
			im2 = postprocess(im2, convert_opt, crop_opt, circle)
		else:
			# Create the circle mask for fancy output:
			if (circle == True):
				siz = im1.shape[1]
				if siz % 2:
					rang = arange(-siz / 2 + 1, siz / 2 + 1)
				else:
					rang = arange(-siz / 2,siz / 2)
				x,y = meshgrid(rang,rang)
				z = x ** 2 + y ** 2
				a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2)
				
				im1 = im1 * a			
				im2 = im2 * a	
	
		# Write down reconstructed slices:
		t2 = time() 	

		fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif'
		imsave(fname1, im1)

		fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif'
		imsave(fname2, im2)

		t3 = time()
								
		# Write log (atomic procedure - lock used):
		write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )		
Esempio n. 17
0
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath,
                    preprocessing_required, skipflat, corr_plan, norm_sx,
                    norm_dx, flat_end, half_half, half_half_line, ext_fov,
                    ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize,
                    ext_fov_average, ringrem, angles, angles_projfrom,
                    angles_projto, offset, logtransform, param1, circle, scale,
                    pad, rolling, roll_shift, zerone_mode, dset_min, dset_max,
                    decim_factor, downsc_factor, corr_offset,
                    postprocess_required, polarfilt_opt, convert_opt, crop_opt,
                    dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename):
    """To do...

	"""
    # Process the required subset of images:
    for i in range(int_from, int_to + 1, 2):

        # Read two sinograms:
        t0 = time()
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im1 = tdf.read_sino(dset, i * downsc_factor).astype(float32)
        if ((i + downsc_factor) <= (int_to + 1)):
            im2 = tdf.read_sino(dset, i * downsc_factor +
                                downsc_factor).astype(float32)
        else:
            im2 = im1
        f_in.close()
        t1 = time()

        # Apply projection removal (if required):
        im1 = im1[angles_projfrom:angles_projto, :]
        im2 = im2[angles_projfrom:angles_projto, :]

        # Apply decimation and downscaling (if required):
        im1 = im1[::decim_factor, ::downsc_factor]
        im2 = im2[::decim_factor, ::downsc_factor]
        #i = i / downsc_factor

        # Perform the preprocessing of the sinograms (if required):
        if (preprocessing_required):
            if not skipflat:
                if dynamic_ff:
                    # Dynamic flat fielding with downsampling = 2:
                    im1 = dynamic_flat_fielding(im1, i, EFF, filtEFF, 2,
                                                im_dark, norm_sx, norm_dx)
                else:
                    im1 = flat_fielding(im1, i, corr_plan, flat_end, half_half,
                                        half_half_line / decim_factor, norm_sx,
                                        norm_dx).astype(float32)
            if ext_fov:
                im1 = extfov_correction(im1, ext_fov_rot_right,
                                        ext_fov_overlap / downsc_factor,
                                        ext_fov_normalize, ext_fov_average)
            if not skipflat:
                im1 = ring_correction(im1, ringrem, flat_end,
                                      corr_plan['skip_flat_after'], half_half,
                                      half_half_line / decim_factor, ext_fov)
            else:
                im1 = ring_correction(im1, ringrem, False, False, half_half,
                                      half_half_line / decim_factor, ext_fov)

            if not skipflat:
                if dynamic_ff:
                    # Dynamic flat fielding with downsampling = 2:
                    im2 = dynamic_flat_fielding(im2, i + 1, EFF, filtEFF, 2,
                                                im_dark, norm_sx, norm_dx)
                else:
                    im2 = flat_fielding(im2, i + 1, corr_plan, flat_end,
                                        half_half,
                                        half_half_line / decim_factor, norm_sx,
                                        norm_dx).astype(float32)
            if ext_fov:
                im2 = extfov_correction(im2, ext_fov_rot_right,
                                        ext_fov_overlap / downsc_factor,
                                        ext_fov_normalize, ext_fov_average)
            if not skipflat and not dynamic_ff:
                im2 = ring_correction(im2, ringrem, flat_end,
                                      corr_plan['skip_flat_after'], half_half,
                                      half_half_line / decim_factor, ext_fov)
            else:
                im2 = ring_correction(im2, ringrem, False, False, half_half,
                                      half_half_line, ext_fov)

        # Actual reconstruction:
        [im1,
         im2] = reconstruct_gridrec(im1, im2, angles, offset / downsc_factor,
                                    logtransform, param1, circle, scale, pad,
                                    rolling, roll_shift, zerone_mode, dset_min,
                                    dset_max, decim_factor, downsc_factor,
                                    corr_offset)

        # Appy post-processing (if required):
        if postprocess_required:

            # Filter (if required):
            im1 = polarfilter(im1, polarfilt_opt)
            im2 = polarfilter(im2, polarfilt_opt)

            im1 = croprescale(im1, convert_opt, crop_opt, circle)
            im2 = croprescale(im2, convert_opt, crop_opt, circle)

        else:
            # Create the circle mask for fancy output:
            if (circle == True):
                siz = im1.shape[1]
                if siz % 2:
                    rang = arange(-siz / 2 + 1, siz / 2 + 1)
                else:
                    rang = arange(-siz / 2, siz / 2)
                x, y = meshgrid(rang, rang)
                z = x**2 + y**2
                a = (z <
                     (siz / 2 - int(round(abs(offset) / downsc_factor)))**2)

                im1 = im1 * a
                im2 = im2 * a

        # Write down reconstructed slices:
        t2 = time()

        fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif'
        imsave(fname1, im1)

        fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif'
        imsave(fname2, im2)

        t3 = time()

        # Write log (atomic procedure - lock used):
        write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1,
                          (t3 - t2) + (t1 - t0))
Esempio n. 18
0
def process(sino_idx, num_sinos, infile, outpath, preprocessing_required,
            corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line,
            ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize,
            ext_fov_average, ringrem, phaseretrieval_required, phrtmethod,
            phrt_param1, phrt_param2, energy, distance, pixsize, phrtpad,
            approx_win, angles, angles_projfrom, angles_projto, offset,
            logtransform, param1, circle, scale, pad, method, zerone_mode,
            dset_min, dset_max, decim_factor, downsc_factor, corr_offset,
            postprocess_required, convert_opt, crop_opt, nr_threads, off_from,
            off_to, logfilename, lock, slice_prefix):
    """To do...

	"""
    slice_nr = sino_idx

    # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required):
    if (phaseretrieval_required):

        # In this case a bunch of sinograms is loaded into memory:

        #
        # Load the temporary data structure reading the input TDF file.
        # To know the right dimension the first sinogram is pre-processed.
        #

        # Open the TDF file and get the dataset:
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']

        # Downscaling and decimation factors considered when determining the approximation window:
        zrange = arange(sino_idx - approx_win * downsc_factor / 2,
                        sino_idx + approx_win * downsc_factor / 2,
                        downsc_factor)
        zrange = zrange[(zrange >= 0)]
        zrange = zrange[(zrange < num_sinos)]
        approx_win = zrange.shape[0]

        # Approximation window cannot be odd:
        if (approx_win % 2 == 1):
            approx_win = approx_win - 1
            zrange = zrange[0:approx_win]

        # Read one sinogram to get the proper dimensions:
        test_im = tdf.read_sino(dset,
                                zrange[0] * downsc_factor).astype(float32)

        # Apply projection removal (if required):
        test_im = test_im[angles_projfrom:angles_projto, :]

        # Apply decimation and downscaling (if required):
        test_im = test_im[::decim_factor, ::downsc_factor]

        # Perform the pre-processing of the first sinogram to get the right dimension:
        if (preprocessing_required):
            test_im = flat_fielding(test_im, zrange[0], corr_plan, flat_end,
                                    half_half, half_half_line / decim_factor,
                                    norm_sx, norm_dx).astype(float32)
            if ext_fov:
                test_im = extfov_correction(test_im, ext_fov_rot_right,
                                            ext_fov_overlap / downsc_factor,
                                            ext_fov_normalize,
                                            ext_fov_average).astype(float32)
            test_im = ring_correction(test_im, ringrem, flat_end,
                                      corr_plan['skip_flat_after'], half_half,
                                      half_half_line / decim_factor,
                                      ext_fov).astype(float32)

        # Now we can allocate memory for the bunch of slices:
        tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]),
                       dtype=float32)
        tmp_im[0, :, :] = test_im

        # Reading all the the sinos from TDF file and close:
        for ct in range(1, approx_win):

            test_im = tdf.read_sino(dset,
                                    zrange[ct] * downsc_factor).astype(float32)

            # Apply projection removal (if required):
            test_im = test_im[angles_projfrom:angles_projto, :]

            # Apply decimation and downscaling (if required):
            test_im = test_im[::decim_factor, ::downsc_factor]

            # Perform the pre-processing for each sinogram of the bunch:
            if (preprocessing_required):
                test_im = flat_fielding(test_im, zrange[ct], corr_plan,
                                        flat_end, half_half,
                                        half_half_line / decim_factor, norm_sx,
                                        norm_dx).astype(float32)
                if ext_fov:
                    test_im = extfov_correction(
                        test_im, ext_fov_rot_right,
                        ext_fov_overlap / downsc_factor, ext_fov_normalize,
                        ext_fov_average).astype(float32)
                test_im = ring_correction(test_im, ringrem, flat_end,
                                          corr_plan['skip_flat_after'],
                                          half_half,
                                          half_half_line / decim_factor,
                                          ext_fov).astype(float32)

            tmp_im[ct, :, :] = test_im

        f_in.close()

        # Now everything has to refer to a downscaled dataset:
        sino_idx = ((zrange == sino_idx).nonzero())

        #
        # Perform phase retrieval:
        #

        # Prepare the plan:
        if (phrtmethod == 0):
            # Paganin's:
            phrtplan = tiehom_plan(tmp_im[:, 0, :],
                                   phrt_param1,
                                   phrt_param2,
                                   energy,
                                   distance,
                                   pixsize * downsc_factor,
                                   padding=phrtpad)
        else:
            phrtplan = phrt_plan(tmp_im[:, 0, :],
                                 energy,
                                 distance,
                                 pixsize * downsc_factor,
                                 phrt_param2,
                                 phrt_param1,
                                 phrtmethod,
                                 padding=phrtpad)

        # Process each projection (whose height depends on the size of the bunch):
        for ct in range(0, tmp_im.shape[1]):
            if (phrtmethod == 0):
                tmp_im[:, ct, :] = tiehom(tmp_im[:, ct, :],
                                          phrtplan).astype(float32)
            else:
                tmp_im[:, ct, :] = phrt(tmp_im[:, ct, :], phrtplan,
                                        phrtmethod).astype(float32)

        # Extract the requested sinogram:
        im = tmp_im[sino_idx[0], :, :].squeeze()

    else:

        # Read only one sinogram:
        f_in = getHDF5(infile, 'r')
        if "/tomo" in f_in:
            dset = f_in['tomo']
        else:
            dset = f_in['exchange/data']
        im = tdf.read_sino(dset, sino_idx * downsc_factor).astype(float32)
        f_in.close()

        # Apply projection removal (if required):
        im = im[angles_projfrom:angles_projto, :]

        # Downscale and decimate the sinogram:
        im = im[::decim_factor, ::downsc_factor]
        #sino_idx = sino_idx/downsc_factor

        # Perform the preprocessing of the sinogram (if required):
        if (preprocessing_required):
            im = flat_fielding(im, sino_idx, corr_plan, flat_end, half_half,
                               half_half_line / decim_factor, norm_sx,
                               norm_dx).astype(float32)
            if ext_fov:
                im = extfov_correction(im, ext_fov_rot_right,
                                       ext_fov_overlap / downsc_factor,
                                       ext_fov_normalize, ext_fov_average)
            im = ring_correction(im, ringrem, flat_end,
                                 corr_plan['skip_flat_after'], half_half,
                                 half_half_line / decim_factor, ext_fov)

    # Log infos:
    log = open(logfilename, "a")
    log.write(
        linesep +
        "\tPerforming reconstruction with multiple centers of rotation...")
    log.write(linesep + "\t--------------")
    log.close()

    # Split the computation into multiple processes:
    for num in range(nr_threads):
        start = ((off_to - off_from + 1) / nr_threads) * num + off_from
        if (num == nr_threads - 1):
            end = off_to
        else:
            end = ((off_to - off_from + 1) / nr_threads) * (num +
                                                            1) + off_from - 1

        Process(target=reconstruct,
                args=(im, angles, angles_projfrom, angles_projto,
                      offset / downsc_factor, logtransform, param1, circle,
                      scale, pad, method, zerone_mode, dset_min, dset_max,
                      corr_offset, postprocess_required, convert_opt, crop_opt,
                      start, end, outpath, slice_nr, downsc_factor,
                      logfilename, lock, slice_prefix)).start()
Esempio n. 19
0
def main(argv):          
	"""To do...

	Usage
	-----
	

	Parameters
	---------
		   
	Example
	--------------------------
	The following line processes the first ten TIFF files of input path 
	"/home/in" and saves the processed files to "/home/out" with the 
	application of the Boin and Haibel filter with smoothing via a Butterworth
	filter of order 4 and cutoff frequency 0.01:

	destripe /home/in /home/out 1 10 1 0.01 4    

	"""
	lock = Lock()

	skip_ringrem = False
	skip_flat = False
	skip_flat_after = True
	first_done = False	

	# Get the number of sino to pre-process:
	idx = int(argv[0])
	   
	# Get paths:
	infile = argv[1]
	outfile = argv[2]
	
	# Normalization parameters:
	norm_sx = int(argv[3])
	norm_dx = int(argv[4])
	
	# Params for flat fielding with post flats/darks:
	flat_end = True if argv[5] == "True" else False
	half_half = True if argv[6] == "True" else False
	half_half_line = int(argv[7])
		
	# Params for extended FOV:
	ext_fov = True if argv[8] == "True" else False
	ext_fov_rot_right = argv[9]
	if ext_fov_rot_right == "True":
		ext_fov_rot_right = True
		if (ext_fov):
			norm_sx = 0
	else:
		ext_fov_rot_right = False
		if (ext_fov):
			norm_dx = 0		
	ext_fov_overlap = int(argv[10])
		
	# Method and parameters coded into a string:
	ringrem = argv[11]	
	
	# Tmp path and log file:
	tmppath = argv[12]	
	if not tmppath.endswith(sep): tmppath += sep		
	logfilename = argv[13]		

	
	# Open the HDF5 file:	
	f_in = getHDF5(infile, 'r')
	if "/tomo" in f_in:
		dset = f_in['tomo']		
	else: 
		dset = f_in['exchange/data']
		prov_dset = f_in['provenance/detector_output']			
		
	num_proj = tdf.get_nr_projs(dset)
	num_sinos = tdf.get_nr_sinos(dset)
	
	# Check if the HDF5 makes sense:
	if (num_sinos == 0):
		log = open(logfilename,"a")
		log.write(linesep + "\tNo projections found. Process will end.")	
		log.close()			
		exit()		

	# Get flat and darks from cache or from file:
	try:
		corrplan = cache2plan(infile, tmppath)
	except Exception as e:
		#print "Error(s) when reading from cache"
		corrplan = extract_flatdark(f_in, flat_end, logfilename)
		plan2cache(corrplan, infile, tmppath)		

	# Read input image:
	im = tdf.read_sino(dset,idx).astype(float32)		
	f_in.close()	

	# Perform pre-processing (flat fielding, extended FOV, ring removal):	
	im = flat_fielding(im, idx, corrplan, flat_end, half_half, half_half_line, norm_sx, norm_dx)			
	im = extfov_correction(im, ext_fov, ext_fov_rot_right, ext_fov_overlap)
	im = ring_correction (im, ringrem, flat_end, corrplan['skip_flat_after'], half_half, half_half_line, ext_fov)							
	
	# Write down reconstructed preview file (file name modified with metadata):		
	im = im.astype(float32)
	outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( nanmin(im)) + '$' + str( nanmax(im) )	
	im.tofile(outfile)