Ejemplo n.º 1
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()
Ejemplo n.º 2
0
def main(argv):
	"""To do...

	"""
	lock = Lock()

	skip_flat = True
	first_done = False	
	pyfftw_cache_disable()
	pyfftw_cache_enable()
	pyfftw_set_keepalive_time(1800)	

	# Get the from and to number of files to process:
	int_from = int(argv[0])
	int_to = int(argv[1])
	   
	# Get full paths of input TDF and output TDF:
	infile = argv[2]
	outfile = argv[3]
	
	# Get the phase retrieval parameters:
	method = int(argv[4])
	param1 = double(argv[5])   # e.g. regParam, or beta
	param2 = double(argv[6])   # e.g. thresh or delta
	energy = double(argv[7])
	distance = double(argv[8])    
	pixsize = double(argv[9]) / 1000.0 # pixsixe from micron to mm:	
	pad = True if argv[10] == "True" else False
	
	# Number of threads (actually processes) to use and logfile:
	nr_threads = int(argv[11])
	logfilename = argv[12]		

	# Log infos:
	log = open(logfilename,"w")
	log.write(linesep + "\tInput TDF file: %s" % (infile))	
	log.write(linesep + "\tOutput TDF file: %s" % (outfile))		
	log.write(linesep + "\t--------------")
	if (method == 0):
		log.write(linesep + "\tMethod: TIE-Hom (Paganin et al., 2002)")		
		log.write(linesep + "\t--------------")	
		log.write(linesep + "\tDelta/Beta: %0.1f" % ((param2/param1))	)
	#else:
	#	log.write(linesep + "\tMethod: Projected CTF (Moosmann et al., 2011)")		
	#	log.write(linesep + "\t--------------")	
	#	log.write(linesep + "\tDelta/Beta: %0.1f" % ((param2/param1))	)
	log.write(linesep + "\tEnergy: %0.1f keV" % (energy))
	log.write(linesep + "\tDistance: %0.1f mm" % (distance))
	log.write(linesep + "\tPixel size: %0.3f micron" % (pixsize*1000))
	log.write(linesep + "\t--------------")	
	log.write(linesep + "\tBrowsing input files...")	
	log.close()
	
	# Remove a previous copy of output:
	if exists(outfile):
		remove(outfile)
	
	# Open the HDF5 file:
	f_in = getHDF5(infile, 'r')
	if "/tomo" in f_in:
		dset = f_in['tomo']
	else: 
		dset = f_in['exchange/data']
	num_proj = tdf.get_nr_projs(dset)
	num_sinos = tdf.get_nr_sinos(dset)
	
	if (num_proj == 0):
		log = open(logfilename,"a")
		log.write(linesep + "\tNo projections found. Process will end.")	
		log.close()			
		exit()	
	
	log = open(logfilename,"a")
	log.write(linesep + "\tInput files browsed correctly.")	
	log.close()					

	# Check extrema (int_to == -1 means all files):
	if ( (int_to >= num_proj) or (int_to == -1) ):
		int_to = num_proj - 1

	if ( (int_from < 0) ):
		int_from = 0

	# Prepare the plan:
	log = open(logfilename,"a")
	log.write(linesep + "\tPreparing the work plan...")	
	log.close()			

	im = tdf.read_tomo(dset,0).astype(float32)	
	

	outshape = tdf.get_dset_shape(im.shape[1], im.shape[0], num_proj)			
	f_out = getHDF5(outfile, 'w')
	f_out_dset = f_out.create_dataset('exchange/data', outshape, float32) 
	f_out_dset.attrs['min'] = str(amin(im[:]))
	f_out_dset.attrs['max'] = str(amax(im[:]))
	
	f_out_dset.attrs['version'] = '1.0'
	f_out_dset.attrs['axes'] = "y:theta:x"

	f_in.close()
	f_out.close()
				
	if (method == 0):
		# Paganin's:
		plan = tiehom_plan (im, param1, param2, energy, distance, pixsize, pad)
	else:
		plan = phrt_plan (im, energy, distance, pixsize, param2, param1, method, pad)

	# Run several threads for independent computation without waiting for threads completion:
	for num in range(nr_threads):
		start = (num_proj / nr_threads)*num
		if (num == nr_threads - 1):
			end = num_proj - 1
		else:
			end = (num_proj / nr_threads)*(num + 1) - 1
		Process(target=_process, args=(lock, start, end, infile, outfile, outshape, float32, method, plan, logfilename)).start()
Ejemplo n.º 3
0
def main(argv):
    """To do...

	"""
    lock = Lock()

    skip_flat = True
    first_done = False
    pyfftw_cache_disable()
    pyfftw_cache_enable()
    pyfftw_set_keepalive_time(1800)

    # Get the from and to number of files to process:
    int_from = int(argv[0])
    int_to = int(argv[1])

    # Get full paths of input TDF and output TDF:
    infile = argv[2]
    outfile = argv[3]

    # Get the phase retrieval parameters:
    method = int(argv[4])
    param1 = double(argv[5])  # e.g. regParam, or beta
    param2 = double(argv[6])  # e.g. thresh or delta
    energy = double(argv[7])
    distance = double(argv[8])
    pixsize = double(argv[9]) / 1000.0  # pixsixe from micron to mm:
    pad = True if argv[10] == "True" else False

    # Number of threads (actually processes) to use and logfile:
    nr_threads = int(argv[11])
    logfilename = argv[12]

    # Log infos:
    log = open(logfilename, "w")
    log.write(linesep + "\tInput TDF file: %s" % (infile))
    log.write(linesep + "\tOutput TDF file: %s" % (outfile))
    log.write(linesep + "\t--------------")
    if (method == 0):
        log.write(linesep + "\tMethod: TIE-Hom (Paganin et al., 2002)")
        log.write(linesep + "\t--------------")
        log.write(linesep + "\tDelta/Beta: %0.1f" % ((param2 / param1)))
    elif (method == 1):
        log.write(linesep +
                  "\tMethod: Generalized TIE-Hom (Paganin et al., 2020)")
        log.write(linesep + "\t--------------")
        log.write(linesep + "\tDelta/Beta: %0.1f" % ((param2 / param1)))
    else:
        log.write(linesep + "\tMethod: Projected CTF (Moosmann et al., 2011)")
        log.write(linesep + "\t--------------")
        log.write(linesep + "\tRegularization: %0.3f" % (param2))
        log.write(linesep + "\tThreshold: %0.3f" % (param1))
    log.write(linesep + "\tEnergy: %0.1f keV" % (energy))
    log.write(linesep + "\tDistance: %0.1f mm" % (distance))
    log.write(linesep + "\tPixel size: %0.3f micron" % (pixsize * 1000))
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tBrowsing input files...")
    log.close()

    # Remove a previous copy of output:
    if exists(outfile):
        remove(outfile)

    # Open the HDF5 file:
    f_in = getHDF5(infile, 'r')
    if "/tomo" in f_in:
        dset = f_in['tomo']
    else:
        dset = f_in['exchange/data']
    num_proj = tdf.get_nr_projs(dset)
    num_sinos = tdf.get_nr_sinos(dset)

    if (num_proj == 0):
        log = open(logfilename, "a")
        log.write(linesep + "\tNo projections found. Process will end.")
        log.close()
        exit()

    log = open(logfilename, "a")
    log.write(linesep + "\tInput files browsed correctly.")
    log.close()

    # Check extrema (int_to == -1 means all files):
    if ((int_to >= num_proj) or (int_to == -1)):
        int_to = num_proj - 1

    if ((int_from < 0)):
        int_from = 0

    # Prepare the plan:
    log = open(logfilename, "a")
    log.write(linesep + "\tPreparing the work plan...")
    log.close()

    im = tdf.read_tomo(dset, 0).astype(float32)

    outshape = tdf.get_dset_shape(im.shape[1], im.shape[0], num_proj)
    f_out = getHDF5(outfile, 'w')
    f_out_dset = f_out.create_dataset('exchange/data', outshape, float32)
    f_out_dset.attrs['min'] = str(amin(im[:]))
    f_out_dset.attrs['max'] = str(amax(im[:]))

    f_out_dset.attrs['version'] = '1.0'
    f_out_dset.attrs['axes'] = "y:theta:x"

    f_in.close()
    f_out.close()

    if (method == 0):
        # Paganin 2020:
        plan = tiehom_plan(im, param1, param2, energy, distance, pixsize, pad)
    elif (method == 1):
        # Paganin 2020:
        plan = tiehom_plan2020(im, param1, param2, energy, distance, pixsize,
                               pad)
    else:
        plan = phrt_plan(im, energy, distance, pixsize, param2, param1, method,
                         pad)

    # Run several threads for independent computation without waiting for threads completion:
    for num in range(nr_threads):
        start = (num_proj / nr_threads) * num
        if (num == nr_threads - 1):
            end = num_proj - 1
        else:
            end = (num_proj / nr_threads) * (num + 1) - 1
        Process(target=_process,
                args=(lock, start, end, infile, outfile, outshape, float32,
                      method, plan, logfilename)).start()
Ejemplo n.º 4
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'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)	
Ejemplo n.º 5
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, 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 main(argv):
    """To do...

	"""
    lock = Lock()

    skip_flat = True
    first_done = False
    pyfftw_cache_disable()
    pyfftw_cache_enable()
    pyfftw_set_keepalive_time(1800)

    # Get the from and to number of files to process:
    idx = int(argv[0])

    # Get full paths of input TDF and output TDF:
    infile = argv[1]
    outfile = argv[2]

    # Get the phase retrieval parameters:
    method = int(argv[3])
    param1 = double(argv[4])  # param1( e.g. regParam, or beta)
    param2 = double(argv[5])  # param2( e.g. thresh or delta)
    energy = double(argv[6])
    distance = double(argv[7])
    pixsize = double(argv[8]) / 1000.0  # pixsixe from micron to mm:
    pad = True if argv[9] == "True" else False

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

    # Open the HDF5 file and check it contains flat files:
    skipflat = False
    f_in = getHDF5(infile, 'r')
    if "/tomo" in f_in:
        dset = f_in['tomo']
        if not "/flat" in f_in:
            skipflat = True
    else:
        dset = f_in['exchange/data']
        if not "/exchange/data_white" in f_in:
            skipflat = True
    num_proj = tdf.get_nr_projs(dset)
    num_sinos = tdf.get_nr_sinos(dset)

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

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

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

    # Apply simple flat fielding (if applicable):
    if not skipflat:
        if (isinstance(corrplan['im_flat_after'], ndarray)
                and isinstance(corrplan['im_flat'], ndarray)
                and isinstance(corrplan['im_dark'], ndarray)
                and isinstance(corrplan['im_dark_after'], ndarray)):
            if (idx < num_proj / 2):
                im = (im - corrplan['im_dark']) / (
                    abs(corrplan['im_flat'] - corrplan['im_dark']) +
                    finfo(float32).eps)
            else:
                im = (im - corrplan['im_dark_after']) / (
                    abs(corrplan['im_flat_after'] - corrplan['im_dark_after'])
                    + finfo(float32).eps)

    # Prepare plan:
    im = im.astype(float32)
    if (method == 0):
        # Paganin 2002:
        plan = tiehom_plan(im, param1, param2, energy, distance, pixsize, pad)
        im = tiehom(im, plan).astype(float32)
    elif (method == 1):
        # Paganin 2020:
        plan = tiehom_plan2020(im, param1, param2, energy, distance, pixsize,
                               pad)
        im = tiehom2020(im, plan).astype(float32)
    else:
        plan = phrt_plan(im, energy, distance, pixsize, param2, param1, method,
                         pad)
        im = phrt(im, plan, method).astype(float32)

    # 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)
Ejemplo n.º 7
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)
def main(argv):
	"""To do...

	"""
	lock = Lock()

	skip_flat = True
	first_done = False	
	pyfftw_cache_disable()
	pyfftw_cache_enable()
	pyfftw_set_keepalive_time(1800)	

	# Get the from and to number of files to process:
	idx = int(argv[0])
	   
	# Get full paths of input TDF and output TDF:
	infile = argv[1]
	outfile = argv[2]
	
	# Get the phase retrieval parameters:
	method = int(argv[3])
	param1 = double(argv[4])   # param1( e.g. regParam, or beta)
	param2 = double(argv[5])   # param2( e.g. thresh or delta)
	energy = double(argv[6])
	distance = double(argv[7])    
	pixsize = double(argv[8]) / 1000.0 # pixsixe from micron to mm:	
	pad = True if argv[9] == "True" else False
	
	# Tmp path and log file:
	tmppath = argv[10]	
	if not tmppath.endswith(sep): tmppath += sep		
	logfilename = argv[11]		

	
	# Open the HDF5 file and check it contains flat files:
	skipflat = False
	f_in = getHDF5(infile, 'r')
	if "/tomo" in f_in:
		dset = f_in['tomo']
		if not "/flat" in f_in:
			skipflat = True
	else: 
		dset = f_in['exchange/data']
		if not "/exchange/data_white" in f_in:
			skipflat = True
	num_proj = tdf.get_nr_projs(dset)
	num_sinos = tdf.get_nr_sinos(dset)
	
	# Check if the HDF5 makes sense:
	if (num_proj == 0):
		log = open(logfilename,"a")
		log.write(linesep + "\tNo projections found. Process will end.")	
		log.close()			
		exit()		

	


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

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

	# Apply simple flat fielding (if applicable):
	if not skipflat:
		if (isinstance(corrplan['im_flat_after'], ndarray) and isinstance(corrplan['im_flat'], ndarray) and
			isinstance(corrplan['im_dark'], ndarray) and isinstance(corrplan['im_dark_after'], ndarray)) :	
			if (idx < num_proj/2):
				im = (im - corrplan['im_dark']) / (abs(corrplan['im_flat'] - corrplan['im_dark']) + finfo(float32).eps)
			else:
				im = (im - corrplan['im_dark_after']) / (abs(corrplan['im_flat_after'] - corrplan['im_dark_after']) 
					+ finfo(float32).eps)	
					
	# Prepare plan:
	im = im.astype(float32)
	if (method == 0):
		# Paganin's:
		plan = tiehom_plan (im, param1, param2, energy, distance, pixsize, pad)		
		im = tiehom(im, plan).astype(float32)	
	else:
		plan = phrt_plan (im, energy, distance, pixsize, param2, param1, method, pad)
		im = phrt(im, plan, method).astype(float32)				
	
	# 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)