Example #1
0
def _medianize(dset):

	num_imgs = get_nr_projs ( dset )

	# Return error if there are no images:
	if (num_imgs == 0):      
		return -1 # Error:

	# Return the only image in case of one image:
	elif (num_imgs == 1):
		return read_tomo(dset,0).astype(float32)
	
	# Do the median of all the images if there is more than one image:
	if num_imgs > 1:

		# Get first image:
		im = read_tomo(dset,0).astype(float32)
		
		# Read all the remaining files (if any) and save it in a volume:
		for i in range(1, num_imgs):                 
		
			# Read i-th image from input folder:
			#im = im + dset[i,:,:].astype(float32)   
			im = im + read_tomo(dset,i).astype(float32) 
		
		# Medianize volume along the third-dimension:
		im = im / num_imgs

		# Reshape output and return:
		return im.astype(float32)  	
Example #2
0
def main(argv):
    """
	Print dimensions of HDF5 file
	"""
    #
    # Get the parameters:
    #

    infile = argv[0]

    f = getHDF5(infile, 'r')

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

    print("Projections: " + tdf.get_nr_projs(dset))
    print("Slices: " + tdf.get_nr_sinos(dset))
    print("DetectorSize: " + tdf.get_det_size(dset))
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()
Example #4
0
def dff_prepare_plan(white_dset, repetitions, dark):
    """ Prepare the Eigen Flat Fields (EFFs) and the filtered EFFs to
	be used for dynamic flat fielding.

	(Function to be called once before the actual filtering of each projection).
	
	Parameters
	----------
	white_dset : array_like
		3D matrix where each flat field image is stacked along the 3rd dimension.

	repetitions: int
		Number of iterations to consider during parallel analysis.

	dark : array_like
		Single dark image (perhaps the average of a series) to be subtracted from
		each flat field image. If the images are already dark corrected or dark
		correction is not required (e.g. due to a photon counting detector) a matrix
		of the proper shape with zeros has to be passed.

	Return value
	------------
	EFF : array_like
		Eigen flat fields stacked along the 3rd dimension.

	filtEFF : array_like
		Filtered eigen flat fields stacked along the 3rd dimension.

	Note
	----
	In this implementation all the collected white field images have to be loaded into
	memory and an internal 32-bit copy of the white fields is created. Considering also
	that the method better performs with several (i.e. hundreds) flat field images, this 
	function might raise memory errors.

	References
	----------
	V. Van Nieuwenhove, J. De Beenhouwer, F. De Carlo, L. Mancini, F. Marone, 
	and J. Sijbers, "Dynamic intensity normalization using eigen flat fields 
	in X-ray imaging", Optics Express, 23(11), 27975-27989, 2015.

	"""
    # Get dimensions of flat-field (or white-field) images:
    num_flats = get_nr_projs(white_dset) / 4
    num_rows = get_nr_sinos(white_dset)
    num_cols = get_det_size(white_dset)

    # Create local copy of white-field dataset:
    tmp_dset = zeros((num_rows * num_cols, num_flats), dtype=float32)
    avg = zeros((num_rows * num_cols), dtype=float32)

    # For all the flat images:
    for i in range(0, tmp_dset.shape[1]):

        # Read i-th flat image and dark-correct:
        tmp_dset[:, i] = read_tomo(
            white_dset,
            i).astype(float32).flatten() - dark.astype(float32).flatten()

        # Sum the image:
        avg = avg + tmp_dset[:, i]

    # Compute the mean:
    avg = avg / num_flats

    # Subtract mean white-field:
    for i in range(0, tmp_dset.shape[1]):
        tmp_dset[:, i] = tmp_dset[:, i] - avg

    # Calculate the number of Eigen Flat Fields (EFF) to use:
    V, nrEFF = _parallelAnalysis(tmp_dset, repetitions)

    # Compute the EFFs (0-th image is the average "conventional" flat field):
    EFF = zeros((num_rows, num_cols, nrEFF + 1), dtype=float32)
    EFF[:, :, 0] = avg.reshape((num_rows, num_cols))
    for i in range(0, nrEFF):
        EFF[:, :, i + 1] = dot(tmp_dset, V[:, num_flats - (i + 1)]).reshape(
            (num_rows, num_cols))

    # Filter the EFFs:
    filtEFF = zeros((num_rows, num_cols, 1 + nrEFF), dtype=float32)
    for i in range(1, 1 + nrEFF):
        filtEFF[:, :, i] = median_filter(EFF[:, :, i], 3)

    return EFF, filtEFF
def main(argv):          
	"""Try to guess the center of rotation of the input CT dataset.

    Parameters
    ----------
    infile  : array_like
        HDF5 input dataset

    outfile : string
        Full path where the identified center of rotation will be written as output

	scale   : int
        If sub-pixel precision is interesting, use e.g. 2.0 to get a center of rotation 
		of .5 value. Use 1.0 if sub-pixel precision is not required

	angles  : int
        Total number of angles of the input dataset	

	proj_from : int
        Initial projections to consider for the assumed angles

	proj_to : int
        Final projections to consider for the assumed angles

	method : string
		(not implemented yet)

	tmppath : string
        Temporary path where look for cached flat/dark files
       
    """ 	   
	# Get path:
	infile  = argv[0]          # The HDF5 file on the
	outfile = argv[1]          # The txt file with the proposed center
	scale   = float(argv[2])
	angles  = float(argv[3])
	proj_from  = int(argv[4])
	proj_to  = int(argv[5])
	method  = argv[6]
	tmppath = argv[7]	
	if not tmppath.endswith(sep): tmppath += sep	

	pyfftw_cache_disable()
	pyfftw_cache_enable()
	pyfftw_set_keepalive_time(1800)	

	# Create a silly temporary log:
	tmplog  = tmppath + basename(infile) + str(time.time())
			
	# Open the HDF5 file (take into account also older TDF versions):
	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)	

	# Get flats 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, True, tmplog)
		remove(tmplog)
		plan2cache(corrplan, infile, tmppath)

	# Get first and the 180 deg projections: 	
	im1 = tdf.read_tomo(dset,proj_from).astype(float32)	

	idx = int(round( (proj_to - proj_from)/angles * pi)) + proj_from
	im2 = tdf.read_tomo(dset,idx).astype(float32)		

	# Apply simple flat fielding (if applicable):
	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)) :		
		im1 = ((abs(im1 - corrplan['im_dark'])) / (abs(corrplan['im_flat'] - corrplan['im_dark']) 
			+ finfo(float32).eps)).astype(float32)	
		im2 = ((abs(im2 - corrplan['im_dark_after'])) / (abs(corrplan['im_flat_after'] - corrplan['im_dark_after']) 
			+ finfo(float32).eps)).astype(float32)	

	# Scale projections (if required) to get subpixel estimation:
	if ( abs(scale - 1.0) > finfo(float32).eps ):	
		im1 = imresize(im1, (int(round(scale*im1.shape[0])), int(round(scale*im1.shape[1]))), interp='bicubic', mode='F');	
		im2 = imresize(im2, (int(round(scale*im2.shape[0])), int(round(scale*im2.shape[1]))), interp='bicubic', mode='F');	

	# Find the center (flipping left-right im2):
	cen = findcenter.usecorrelation(im1, im2[ :,::-1])
	cen = cen / scale
	
	# Print center to output file:
	text_file = open(outfile, "w")
	text_file.write(str(int(cen)))
	text_file.close()
	
	# Close input HDF5:
	f_in.close()
def main(argv):          
	"""Try to guess the amount of overlap in the case of extended FOV CT.

    Parameters
    ----------
    infile  : array_like
        HDF5 input dataset

    outfile : string
        Full path where the identified overlap will be written as output

	scale   : int
        If sub-pixel precision is interesting, use e.g. 2.0 to get an overlap 
		of .5 value. Use 1.0 if sub-pixel precision is not required

	tmppath : int
        Temporary path where look for cached flat/dark files
       
    """ 	
	   
	# Get path:
	infile  = argv[0]  # The HDF5 file on the SSD
	outfile  = argv[1]  # The txt file with the proposed center
	scale  = float(argv[2])
	tmppath = argv[3]	
	if not tmppath.endswith(sep): tmppath += sep	

	# Create a silly temporary log:
	tmplog  = tmppath + basename(infile) + str(time.time())	
			

	# 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)

	
	# Get first and 180 deg projections: 	
	im1 = tdf.read_tomo(dset,0).astype(float32)
	im2 = tdf.read_tomo(dset,num_proj/2).astype(float32)

	
	# Get flats 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, True, tmplog)
		remove(tmplog)
		plan2cache(corrplan, infile, tmppath)

	# Apply simple flat fielding (if applicable):
	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)) :		
		im1 = ((abs(im1 - corrplan['im_dark'])) / (abs(corrplan['im_flat'] - corrplan['im_dark'])  + finfo(float32).eps)).astype(float32)	
		im2 = ((abs(im2 - corrplan['im_dark_after'])) / (abs(corrplan['im_flat_after'] - corrplan['im_dark_after'])  + finfo(float32).eps)).astype(float32)		


	# Scale projections (if required) to get subpixel estimation:
	if ( abs(scale - 1.0) > finfo(float32).eps ):	
		im1 = imresize(im1, (int(round(scale*im1.shape[0])), int(round(scale*im1.shape[1]))), interp='bicubic', mode='F');	
		im2 = imresize(im2, (int(round(scale*im2.shape[0])), int(round(scale*im2.shape[1]))), interp='bicubic', mode='F');

			
	# Find the center (flipping left-right im2): DISTINGUISH BETWEEN AIR ON THE RIGHT AND ON THE LEFT??????
	cen = findcenter.usecorrelation(im1, im2[ :,::-1])
	cen = (cen / scale)*2.0	
	
	# Print center to output file:
	text_file = open(outfile, "w")
	text_file.write(str(int(abs(cen))))
	text_file.close()
	
	# Close input HDF5:
	f_in.close()
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)		
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)
Example #9
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)
def dff_prepare_plan(white_dset, repetitions, dark):
	""" Prepare the Eigen Flat Fields (EFFs) and the filtered EFFs to
	be used for dynamic flat fielding.

	(Function to be called once before the actual filtering of each projection).
	
	Parameters
	----------
	white_dset : array_like
		3D matrix where each flat field image is stacked along the 3rd dimension.

	repetitions: int
		Number of iterations to consider during parallel analysis.

	dark : array_like
		Single dark image (perhaps the average of a series) to be subtracted from
		each flat field image. If the images are already dark corrected or dark
		correction is not required (e.g. due to a photon counting detector) a matrix
		of the proper shape with zeros has to be passed.

	Return value
	------------
	EFF : array_like
		Eigen flat fields stacked along the 3rd dimension.

	filtEFF : array_like
		Filtered eigen flat fields stacked along the 3rd dimension.

	Note
	----
	In this implementation all the collected white field images have to be loaded into
	memory and an internal 32-bit copy of the white fields is created. Considering also
	that the method better performs with several (i.e. hundreds) flat field images, this 
	function might raise memory errors.

	References
	----------
	V. Van Nieuwenhove, J. De Beenhouwer, F. De Carlo, L. Mancini, F. Marone, 
	and J. Sijbers, "Dynamic intensity normalization using eigen flat fields 
	in X-ray imaging", Optics Express, 23(11), 27975-27989, 2015.

	"""	
	# Get dimensions of flat-field (or white-field) images:
	num_flats = get_nr_projs(white_dset)/4
	num_rows  = get_nr_sinos(white_dset)
	num_cols  = get_det_size(white_dset)
		
	# Create local copy of white-field dataset:
	tmp_dset = zeros((num_rows * num_cols, num_flats), dtype=float32)
	avg      = zeros((num_rows * num_cols), dtype=float32)
					
	# For all the flat images:
	for i in range(0, tmp_dset.shape[1]):                 
		
		# Read i-th flat image and dark-correct:
		tmp_dset[:,i] =  read_tomo(white_dset,i).astype(float32).flatten()	- dark.astype(float32).flatten()
					
		# Sum the image:
		avg = avg + tmp_dset[:,i]

	# Compute the mean:
	avg = avg / num_flats

	# Subtract mean white-field:
	for i in range(0, tmp_dset.shape[1]): 
		tmp_dset[:,i] = tmp_dset[:,i] - avg
			
	# Calculate the number of Eigen Flat Fields (EFF) to use:
	V, nrEFF = _parallelAnalysis(tmp_dset, repetitions)

	# Compute the EFFs (0-th image is the average "conventional" flat field):
	EFF  = zeros((num_rows, num_cols, nrEFF + 1), dtype=float32)
	EFF[:,:,0] = avg.reshape((num_rows, num_cols))			
	for i in range(0, nrEFF): 		
		EFF[:,:,i + 1] = dot(tmp_dset, V[:,num_flats - (i + 1)]).reshape((num_rows, num_cols))	
		
	# Filter the EFFs:
	filtEFF = zeros((num_rows, num_cols, 1 + nrEFF), dtype=float32)
	for i in range(1, 1 + nrEFF):		
		filtEFF[:,:,i] = median_filter(EFF[:,:,i], 3)		

	return EFF, filtEFF
Example #11
0
def main(argv):
    """To do...

	Usage
	-----
	

	Parameters
	---------
		   
	Example
	--------------------------    

	"""
    lock = Lock()

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

    # Get paths:
    infile_1 = argv[2]
    infile_2 = argv[3]
    infile_3 = argv[4]

    outfile_abs = argv[5]
    outfile_ref = argv[6]
    outfile_sca = argv[7]

    # Normalization parameters:
    norm_sx = int(argv[8])
    norm_dx = int(argv[9])

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

    # Params for extended FOV:
    ext_fov = True if argv[13] == "True" else False
    ext_fov_rot_right = argv[14]
    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[15])

    ext_fov_normalize = True if argv[16] == "True" else False
    ext_fov_average = True if argv[17] == "True" else False

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

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

    # Shift parameters:
    shiftVert_1 = int(argv[20])
    shiftHoriz_1 = int(argv[21])
    shiftVert_2 = int(argv[22])
    shiftHoriz_2 = int(argv[23])
    shiftVert_3 = int(argv[24])
    shiftHoriz_3 = int(argv[25])

    # DEI coefficients:
    r1 = float(argv[26])
    r2 = float(argv[27])
    r3 = float(argv[28])
    d1 = float(argv[29])
    d2 = float(argv[30])
    d3 = float(argv[31])
    dd1 = float(argv[32])
    dd2 = float(argv[33])
    dd3 = float(argv[34])

    # Nr of threads and log file:
    nr_threads = int(argv[35])
    logfilename = argv[36]

    # Log input parameters:
    log = open(logfilename, "w")
    log.write(linesep + "\tInput TDF file #1: %s" % (infile_1))
    log.write(linesep + "\tInput TDF file #2: %s" % (infile_2))
    log.write(linesep + "\tInput TDF file #3: %s" % (infile_3))
    log.write(linesep + "\tOutput TDF file for Absorption: %s" % (outfile_abs))
    log.write(linesep + "\tOutput TDF file for Refraction: %s" % (outfile_ref))
    log.write(linesep + "\tOutput TDF file for Scattering: %s" % (outfile_sca))
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tOpening input dataset...")
    log.close()

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

    # Open the HDF5 files:
    f_in_1 = getHDF5(infile_1, 'r')
    f_in_2 = getHDF5(infile_2, 'r')
    f_in_3 = getHDF5(infile_3, 'r')

    if "/tomo" in f_in_1:
        dset_1 = f_in_1['tomo']

        tomoprefix_1 = 'tomo'
        flatprefix_1 = 'flat'
        darkprefix_1 = 'dark'
    else:
        dset_1 = f_in_1['exchange/data']
        if "/provenance/detector_output" in f_in_1:
            prov_dset_1 = f_in_1['provenance/detector_output']

            tomoprefix_1 = prov_dset_1.attrs['tomo_prefix']
            flatprefix_1 = prov_dset_1.attrs['flat_prefix']
            darkprefix_1 = prov_dset_1.attrs['dark_prefix']

    if "/tomo" in f_in_2:
        dset_2 = f_in_2['tomo']

        tomoprefix_2 = 'tomo'
        flatprefix_2 = 'flat'
        darkprefix_2 = 'dark'
    else:
        dset_2 = f_in_2['exchange/data']
        if "/provenance/detector_output" in f_in_2:
            prov_dset_2 = f_in_2['provenance/detector_output']

            tomoprefix_2 = prov_dset_2.attrs['tomo_prefix']
            flatprefix_2 = prov_dset_2.attrs['flat_prefix']
            darkprefix_2 = prov_dset_2.attrs['dark_prefix']

    if "/tomo" in f_in_3:
        dset_3 = f_in_3['tomo']

        tomoprefix_3 = 'tomo'
        flatprefix_3 = 'flat'
        darkprefix_3 = 'dark'
    else:
        dset_3 = f_in_3['exchange/data']
        if "/provenance/detector_output" in f_in_3:
            prov_dset_3 = f_in_1['provenance/detector_output']

            tomoprefix_3 = prov_dset_3.attrs['tomo_prefix']
            flatprefix_3 = prov_dset_3.attrs['flat_prefix']
            darkprefix_3 = prov_dset_3.attrs['dark_prefix']

    # Assuming that what works for the dataset #1 works for the other two:
    num_proj = tdf.get_nr_projs(dset_1)
    num_sinos = tdf.get_nr_sinos(dset_1)

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

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

    # Prepare the work plan for flat and dark images:
    log = open(logfilename, "a")
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tPreparing the work plan...")
    log.close()

    # Extract flat and darks:
    skipflat_1 = False
    skipdark_1 = False
    skipflat_2 = False
    skipdark_2 = False
    skipflat_3 = False
    skipdark_3 = False

    # Following variables make sense only for dynamic flat fielding:
    EFF_1 = -1
    filtEFF_1 = -1
    im_dark_1 = -1

    EFF_2 = -1
    filtEFF_2 = -1
    im_dark_2 = -1

    EFF_3 = -1
    filtEFF_3 = -1
    im_dark_3 = -1

    # Following variable makes sense only for conventional flat fielding:
    plan_1 = -1
    plan_2 = -1
    plan_3 = -1

    if not dynamic_ff:
        plan_1 = extract_flatdark(f_in_1, flat_end, logfilename)
        if (isscalar(plan_1['im_flat']) and isscalar(plan_1['im_flat_after'])):
            skipflat_1 = True
        else:
            skipflat_1 = False

        plan_2 = extract_flatdark(f_in_2, flat_end, logfilename)
        if (isscalar(plan_2['im_flat']) and isscalar(plan_2['im_flat_after'])):
            skipflat_2 = True
        else:
            skipflat_2 = False

        plan_3 = extract_flatdark(f_in_3, flat_end, logfilename)
        if (isscalar(plan_3['im_flat']) and isscalar(plan_3['im_flat_after'])):
            skipflat_3 = True
        else:
            skipflat_3 = False

    else:
        # Dynamic flat fielding:
        if "/tomo" in f_in_1:
            if "/flat" in f_in_1:
                flat_dset_1 = f_in_1['flat']
                if "/dark" in f_in_1:
                    im_dark_1 = _medianize(f_in_1['dark'])
                else:
                    skipdark_1 = True
            else:
                skipflat_1 = True  # Nothing to do in this case
        else:
            if "/exchange/data_white" in f_in_1:
                flat_dset_1 = f_in_1['/exchange/data_white']
                if "/exchange/data_dark" in f_in_1:
                    im_dark_1 = _medianize(f_in_1['/exchange/data_dark'])
                else:
                    skipdark_1 = True
            else:
                skipflat_1 = True  # Nothing to do in this case

        # Prepare plan for dynamic flat fielding with 16 repetitions:
        if not skipflat_1:
            EFF_1, filtEFF_1 = dff_prepare_plan(flat_dset_1, 16, im_dark_1)

        # Dynamic flat fielding:
        if "/tomo" in f_in_2:
            if "/flat" in f_in_2:
                flat_dset_2 = f_in_2['flat']
                if "/dark" in f_in_2:
                    im_dark_2 = _medianize(f_in_2['dark'])
                else:
                    skipdark_2 = True
            else:
                skipflat_2 = True  # Nothing to do in this case
        else:
            if "/exchange/data_white" in f_in_2:
                flat_dset_2 = f_in_2['/exchange/data_white']
                if "/exchange/data_dark" in f_in_2:
                    im_dark_2 = _medianize(f_in_2['/exchange/data_dark'])
                else:
                    skipdark_2 = True
            else:
                skipflat_2 = True  # Nothing to do in this case

        # Prepare plan for dynamic flat fielding with 16 repetitions:
        if not skipflat_2:
            EFF_2, filtEFF_2 = dff_prepare_plan(flat_dset_2, 16, im_dark_2)

        # Dynamic flat fielding:
        if "/tomo" in f_in_3:
            if "/flat" in f_in_3:
                flat_dset_3 = f_in_3['flat']
                if "/dark" in f_in_3:
                    im_dark_3 = _medianize(f_in_3['dark'])
                else:
                    skipdark_3 = True
            else:
                skipflat_3 = True  # Nothing to do in this case
        else:
            if "/exchange/data_white" in f_in_3:
                flat_dset_3 = f_in_3['/exchange/data_white']
                if "/exchange/data_dark" in f_in_3:
                    im_dark_3 = _medianize(f_in_3['/exchange/data_dark'])
                else:
                    skipdark_3 = True
            else:
                skipflat_3 = True  # Nothing to do in this case

        # Prepare plan for dynamic flat fielding with 16 repetitions:
        if not skipflat_3:
            EFF_3, filtEFF_3 = dff_prepare_plan(flat_dset_3, 16, im_dark_3)

    # Outfile shape can be determined only after first processing in ext FOV mode:
    if (ext_fov):

        # Read input sino:
        idx = num_sinos / 2
        im = tdf.read_sino(dset_1, idx).astype(float32)
        im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap,
                               ext_fov_normalize, ext_fov_average)

        # Get the corrected outshape:
        outshape = tdf.get_dset_shape(im.shape[1], num_sinos, im.shape[0])

    else:
        # Get the corrected outshape (in this case it's easy):
        im = tdf.read_tomo(dset_1, 0).astype(float32)
        outshape = tdf.get_dset_shape(im.shape[1], im.shape[0], num_proj)

    f_in_1.close()
    f_in_2.close()
    f_in_3.close()

    # Create the output HDF5 files:
    f_out_abs = getHDF5(outfile_abs, 'w')
    f_out_dset_abs = f_out_abs.create_dataset('exchange/data', outshape,
                                              float32)
    f_out_dset_abs.attrs['min'] = str(finfo(float32).max)
    f_out_dset_abs.attrs['max'] = str(finfo(float32).min)
    f_out_dset_abs.attrs['version'] = '1.0'
    f_out_dset_abs.attrs['axes'] = "y:theta:x"
    f_out_abs.close()

    f_out_ref = getHDF5(outfile_ref, 'w')
    f_out_dset_ref = f_out_ref.create_dataset('exchange/data', outshape,
                                              float32)
    f_out_dset_ref.attrs['min'] = str(finfo(float32).max)
    f_out_dset_ref.attrs['max'] = str(finfo(float32).min)
    f_out_dset_ref.attrs['version'] = '1.0'
    f_out_dset_ref.attrs['axes'] = "y:theta:x"
    f_out_ref.close()

    f_out_sca = getHDF5(outfile_sca, 'w')
    f_out_dset_sca = f_out_sca.create_dataset('exchange/data', outshape,
                                              float32)
    f_out_dset_sca.attrs['min'] = str(finfo(float32).max)
    f_out_dset_sca.attrs['max'] = str(finfo(float32).min)
    f_out_dset_sca.attrs['version'] = '1.0'
    f_out_dset_sca.attrs['axes'] = "y:theta:x"
    f_out_sca.close()

    # Log infos:
    log = open(logfilename, "a")
    log.write(linesep + "\tWork plan prepared correctly.")
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tPerforming GDEI...")
    log.close()

    # Run several threads for independent computation without waiting for threads
    # completion:
    for num in range(nr_threads):
        start = (num_sinos / nr_threads) * num
        if (num == nr_threads - 1):
            end = num_sinos - 1
        else:
            end = (num_sinos / nr_threads) * (num + 1) - 1
        Process(
            target=_process,
            args=(lock, start, end, 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, float32,
                  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)).start()
Example #12
0
def main(argv):          
	"""
	Converts a TDF file (HDF5 Tomo Data Format) into a sequence of TIFF (uncompressed) files.
	    
	Parameters
	----------
	from : scalar, integer
		among all the projections (or sinogram) data, a subset of the volume can 
		be specified, ranging from the parameter "from" to the parameter "to" 
		(see next). In most cases, this parameter is 0.
		
	to : scalar, integer
		among all the projections (or sinogram) data, a subset of the volume can 
		be specified, ranging from the parameter "from" (see previous parameter) to 
		the parameter "to". If the value -1 is specified, all the projection (or sinogram)
		data will be considered.
		
	in_file : string
		path with filename of the TDF to read from (e.g. "Z:\\sample1.tdf").
		
	out_path : string
		path that will contain the sequence of TIFF files (e.g. "Z:\\sample1\\tomo\\"). WARNING: 
		the program does NOT automatically create non-existing folders and subfolders specified 
		in the path. Moreover, if files with the same name already exist they will be automatically 
		overwritten.
		
	file_prefix : string
		string to be assumed as the filename prefix of the TIFF files to create for the projection (or 
		sinogram) data. E.g. "tomo" will create files having name "tomo_0001.tif", "tomo_0002.tif".
		
	flat_prefix : string
		string to be assumed as the filename prefix of the TIFF files to create for the flat (white field)
		data. E.g. "flat" will create files having name "flat_1.tif", "flat_2.tif". If dark or flat data have
		to be skipped the string "-" can be specified.
		
	dark_prefix : string
		string to be assumed as the filename prefix of the TIFF files to create for the dark (dark field)
		data. E.g. "dark" will create files having name "dark_1.tif", "dark_2.tif". If dark or flat data have
		to be skipped the string "-" can be specified.
		
	projection_order : boolean string
		specify the string "True" to create TIFF files for projections (the most common case), "False" 
		for sinograms.		

	TIFF_format : boolean string
		specify the string "True" to create TIFF files, "False" for RAW files.	

	nr_threads : int
		number of multiple threads (actually processes) to consider to speed up the whole conversion process.
		
	log_file : string
		path with filename of a log file (e.g. "R:\\log.txt") where info about the conversion is reported.

	Returns
	-------
	no return value
		
	Example
	-------
	Example call to convert all the projections data to a sequence of tomo*.tif files:
	
		python tdf2tiff.py 0 -1 "C:\Temp\wet12T4part2.tdf" "C:\Temp\tomo" tomo flat dark True True 3 "C:\Temp\log.txt"
	
	Requirements
	-------
	- Python 2.7 with the latest NumPy, SciPy, H5Py.
	- TIFFFile from C. Gohlke
	- tdf.py
	
	Tests
	-------
	Tested with WinPython-64bit-2.7.6.3 (Windows) and Anaconda 2.1.0 (Linux 64-bit).		

	"""	

	lock = Lock()

	# To be used without flat fielding (just conversion):
	first_done = False	

	# Get the from and to number of files to process:
	int_from = int(argv[0])
	int_to = int(argv[1]) # -1 means "all files"
	   
	# Get paths:
	infile = argv[2]
	outpath = argv[3]
	
	fileprefix = argv[4]
	flatprefix = argv[5]
	darkprefix = argv[6]
	
	if (flatprefix == "-"):
		skipflat = True
	else:
		skipflat = False

	if (darkprefix == "-"):
		skipdark = True
	else:
		skipdark = False

	if (fileprefix == "-"):
		skiptomo = True
	else:
		skiptomo = False
	
	projorder = argv[7]
	if projorder == "True":
		projorder = True
	else:
		projorder = False	
		
	TIFFFormat = argv[8]
	if TIFFFormat == "True":
		TIFFFormat = True
	else:
		TIFFFormat = False	
		
	nr_threads = int(argv[9])
	logfilename = argv[10]
	
	# Check prefixes and path:
	if not outpath.endswith(os.path.sep): outpath += os.path.sep
	
	# Init variables:
	num_files = 0
	num_flats = 0
	num_darks = 0

	# Get the files in infile:
	log = open(logfilename,"w")
	log.write(os.linesep + "\tInput TDF: %s" % (infile))
	if (TIFFFormat):
		log.write(os.linesep + "\tOutput path where TIFF files will be created: %s" % (outpath))		
	else:
		log.write(os.linesep + "\tOutput path where RAW files will be created: %s" % (outpath))		
	log.write(os.linesep + "\t--------------")			
	log.write(os.linesep + "\tFile output prefix: %s" % (fileprefix))
	log.write(os.linesep + "\tFlat images output prefix: %s" % (flatprefix))
	log.write(os.linesep + "\tDark images output prefix: %s" % (darkprefix))
	log.write(os.linesep + "\t--------------")	
	
	if (not (skiptomo)):
		if (int_to != -1):
			log.write(os.linesep + "\tThe subset [%d,%d] of the data will be considered." % (int_from, int_to))
	
		if (projorder):
			log.write(os.linesep + "\tProjection order assumed.")
		else:
			log.write(os.linesep + "\tSinogram order assumed.")
	
		log.write(os.linesep + "\t--------------")	
	log.close()	

	if not os.path.exists(infile):		
		log = open(logfilename,"a")
		log.write(os.linesep + "\tError: input TDF file not found. Process will end.")				
		log.close()			
		exit()	

	# Open the HDF5 file:
	f = getHDF5(infile, 'r')
	
	oldTDF = False
	
	try:		
		dset = f['tomo']			
		oldTDF = True
		
	except Exception:
		
		pass
		
	if not oldTDF:
		
		#try:
			dset = f['exchange/data']
			
		#except Exception:
			
		#	log = open(logfilename,"a")
		#	log.write(os.linesep + "\tError: invalid TDF format.  Process will end.")
		#	log.close()
		#	exit()
	
	if projorder:
		num_files = tdf.get_nr_projs(dset)	
	else:
		num_files = tdf.get_nr_sinos(dset)			
	f.close()
	


	# Get attributes:
	try:
		f = getHDF5(infile, 'r')
		if ('version' in f.attrs) and (f.attrs['version'] == 'TDF 1.0'):	
			log = open(logfilename,"a")
			log.write(os.linesep + "\tTDF version 1.0 found.")
			log.write(os.linesep + "\t--------------")
			log.close()
		f.close()				
			
	except:		
		log = open(logfilename,"a")
		log.write(os.linesep + "\tWarning: TDF version unknown. Some features will not be available.")				
		log.write(os.linesep + "\t--------------")
		log.close()			

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


	# Spawn the process for the conversion of flat images:
	if not skipflat:

		f = getHDF5(infile, 'r')
		if oldTDF:
			dset_str = 'flat'
		else:
			dset_str = 'exchange/data_white'
		num_flats = tdf.get_nr_projs(f[dset_str])
		f.close()	

		if (num_flats > 0):
			Process(target=_process, args=(lock, 0, num_flats - 1, infile, dset_str, TIFFFormat, 
											True, outpath, flatprefix, logfilename)).start()
			#_process(lock, 0, num_flats - 1, infile, dset_str, TIFFFormat, projorder,
			#outpath, flatprefix, logfilename)

	# Spawn the process for the conversion of dark images:
	if not skipdark:

		f = getHDF5(infile, 'r')
		if oldTDF:
			dset_str = 'dark'
		else:
			dset_str = 'exchange/data_dark'
		num_darks = tdf.get_nr_projs(f[dset_str])
		f.close()	

		if (num_darks > 0):
			Process(target=_process, args=(lock, 0, num_darks - 1, infile, dset_str, TIFFFormat, 
											True, outpath, darkprefix, logfilename)).start()
			#_process(lock, 0, num_darks - 1, infile, dset_str, TIFFFormat, projorder,
			#outpath, darkprefix, logfilename)

	# Spawn the processes for the conversion of projection or sinogram images:
	if not skiptomo:

		if oldTDF:
			dset_str = 'tomo'
		else:
			dset_str = 'exchange/data'
		
		# Start the process for the conversion of the projections (or sinograms) in a
		# multi-threaded way:
		for num in range(nr_threads):
			start = ((int_to - int_from + 1) / nr_threads) * num + int_from
			if (num == nr_threads - 1):
				end = int_to
			else:
				end = ((int_to - int_from + 1) / nr_threads) * (num + 1) + int_from - 1

			Process(target=_process, args=(lock, start, end, infile, dset_str, TIFFFormat, 
											projorder, outpath, fileprefix, logfilename)).start()
Example #13
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)
Example #14
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()
def main(argv):
    """Try to guess the amount of overlap in the case of extended FOV CT.

    Parameters
    ----------
    infile  : array_like
        HDF5 input dataset

    outfile : string
        Full path where the identified overlap will be written as output

	scale   : int
        If sub-pixel precision is interesting, use e.g. 2.0 to get an overlap 
		of .5 value. Use 1.0 if sub-pixel precision is not required

	tmppath : int
        Temporary path where look for cached flat/dark files
       
    """

    # Get path:
    infile = argv[0]  # The HDF5 file on the SSD
    outfile = argv[1]  # The txt file with the proposed center
    scale = float(argv[2])
    tmppath = argv[3]
    if not tmppath.endswith(sep): tmppath += sep

    # Create a silly temporary log:
    tmplog = tmppath + basename(infile) + str(time.time())

    # 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)

    # Get first and 180 deg projections:
    im1 = tdf.read_tomo(dset, 0).astype(float32)
    im2 = tdf.read_tomo(dset, num_proj / 2).astype(float32)

    # Get flats 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, True, tmplog)
        remove(tmplog)
        plan2cache(corrplan, infile, tmppath)

    # Apply simple flat fielding (if applicable):
    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)):
        im1 = ((abs(im1 - corrplan['im_dark'])) /
               (abs(corrplan['im_flat'] - corrplan['im_dark']) +
                finfo(float32).eps)).astype(float32)
        im2 = ((abs(im2 - corrplan['im_dark_after'])) /
               (abs(corrplan['im_flat_after'] - corrplan['im_dark_after']) +
                finfo(float32).eps)).astype(float32)

    # Scale projections (if required) to get subpixel estimation:
    if (abs(scale - 1.0) > finfo(float32).eps):
        im1 = imresize(im1, (int(round(
            scale * im1.shape[0])), int(round(scale * im1.shape[1]))),
                       interp='bicubic',
                       mode='F')
        im2 = imresize(im2, (int(round(
            scale * im2.shape[0])), int(round(scale * im2.shape[1]))),
                       interp='bicubic',
                       mode='F')

    # Find the center (flipping left-right im2): DISTINGUISH BETWEEN AIR ON THE RIGHT AND ON THE LEFT??????
    cen = findcenter.usecorrelation(im1, im2[:, ::-1])
    cen = (cen / scale) * 2.0

    # Print center to output file:
    text_file = open(outfile, "w")
    text_file.write(str(int(abs(cen))))
    text_file.close()

    # Close input HDF5:
    f_in.close()
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()
    rescale_factor = 10000.0  # For 16-bit floating point

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

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

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

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

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

    # Nr of threads and log file:
    nr_threads = int(argv[11])
    logfilename = argv[12]

    # Log input parameters:
    log = open(logfilename, "w")
    log.write(linesep + "\tInput TDF file: %s" % (infile))
    log.write(linesep + "\tOutput TDF file: %s" % (outfile))
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tOpening input dataset...")
    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']

        tomoprefix = 'tomo'
        flatprefix = 'flat'
        darkprefix = 'dark'
    else:
        dset = f_in['exchange/data']
        if "/provenance/detector_output" in f_in:
            prov_dset = f_in['provenance/detector_output']

            tomoprefix = prov_dset.attrs['tomo_prefix']
            flatprefix = prov_dset.attrs['flat_prefix']
            darkprefix = prov_dset.attrs['dark_prefix']

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

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

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

    # Prepare the work plan for flat and dark images:
    log = open(logfilename, "a")
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tPreparing the work plan...")
    log.close()

    # Extract flat and darks:
    skipflat = False
    skipdark = False

    # Following variables make sense only for dynamic flat fielding:
    EFF = -1
    filtEFF = -1
    im_dark = -1

    # Following variable makes sense only for conventional flat fielding:
    plan = -1

    if not dynamic_ff:
        plan = extract_flatdark(f_in, flat_end, logfilename)
        if (isscalar(plan['im_flat']) and isscalar(plan['im_flat_after'])):
            skipflat = True
        else:
            skipflat = False
    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)

    # Get the corrected outshape (in this case it's easy):
    im = tdf.read_tomo(dset, 0).astype(float32)
    outshape = tdf.get_dset_shape(im.shape[1], im.shape[0], num_proj)

    # Create the output HDF5 file:
    f_out = getHDF5(outfile, 'w')
    #f_out_dset = f_out.create_dataset('exchange/data', outshape, im.dtype)
    f_out_dset = f_out.create_dataset('exchange/data', outshape, float16)
    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_out_dset.attrs['rescale_factor'] = str(rescale_factor)

    f_out.close()
    f_in.close()

    # Log infos:
    log = open(logfilename, "a")
    log.write(linesep + "\tWork plan prepared correctly.")
    log.write(linesep + "\t--------------")
    log.write(linesep + "\tPerforming pre processing...")
    log.close()

    # 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, float16,
                      skipflat, plan, flat_end, half_half, half_half_line,
                      dynamic_ff, EFF, filtEFF, im_dark, rotation, interp,
                      border, rescale_factor, logfilename)).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)
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()
	rescale_factor = 10000.0 # For 16-bit floating point

	# Get the from and to number of files to process:
	int_from = int(argv[0])
	int_to = int(argv[1])
	   
	# Get paths:
	infile = argv[2]
	outfile = argv[3]	
	
	# Params for flat fielding with post flats/darks:
	flat_end = True if argv[4] == "True" else False
	half_half = True if argv[5] == "True" else False
	half_half_line = int(argv[6])

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

	# Parameters for rotation:
	rotation = float(argv[8])
	interp = argv[9]
	border = argv[10]
	
	# Nr of threads and log file:
	nr_threads = int(argv[11])
	logfilename = argv[12]		




	# Log input parameters:
	log = open(logfilename,"w")
	log.write(linesep + "\tInput TDF file: %s" % (infile))	
	log.write(linesep + "\tOutput TDF file: %s" % (outfile))		
	log.write(linesep + "\t--------------")	
	log.write(linesep + "\tOpening input dataset...")	
	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']

		tomoprefix = 'tomo'
		flatprefix = 'flat'
		darkprefix = 'dark'
	else: 
		dset = f_in['exchange/data']
		if "/provenance/detector_output" in f_in:
			prov_dset = f_in['provenance/detector_output']		
	
			tomoprefix = prov_dset.attrs['tomo_prefix']
			flatprefix = prov_dset.attrs['flat_prefix']
			darkprefix = prov_dset.attrs['dark_prefix']
			
	num_proj = tdf.get_nr_projs(dset)
	num_sinos = tdf.get_nr_sinos(dset)
	
	if (num_sinos == 0):
		log = open(logfilename,"a")
		log.write(linesep + "\tNo projections found. Process will end.")	
		log.close()			
		exit()		

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

	# Prepare the work plan for flat and dark images:
	log = open(logfilename,"a")
	log.write(linesep + "\t--------------")
	log.write(linesep + "\tPreparing the work plan...")				
	log.close()

	# Extract flat and darks:
	skipflat = False
	skipdark = False

	# Following variables make sense only for dynamic flat fielding:
	EFF = -1
	filtEFF = -1
	im_dark = -1
	
	# Following variable makes sense only for conventional flat fielding:
	plan = -1

	if not dynamic_ff:
		plan = extract_flatdark(f_in, flat_end, logfilename)
		if (isscalar(plan['im_flat']) and isscalar(plan['im_flat_after'])):
			skipflat = True
		else:
			skipflat = False		
	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)
	
	# Get the corrected outshape (in this case it's easy):
	im = tdf.read_tomo(dset,0).astype(float32)	
	outshape = tdf.get_dset_shape(im.shape[1], im.shape[0], num_proj)			
	
	# Create the output HDF5 file:
	f_out = getHDF5(outfile, 'w')
	#f_out_dset = f_out.create_dataset('exchange/data', outshape, im.dtype)
	f_out_dset = f_out.create_dataset('exchange/data', outshape, float16) 
	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_out_dset.attrs['rescale_factor'] = str(rescale_factor)

	f_out.close()
	f_in.close()
		
	# Log infos:
	log = open(logfilename,"a")
	log.write(linesep + "\tWork plan prepared correctly.")	
	log.write(linesep + "\t--------------")
	log.write(linesep + "\tPerforming pre processing...")			
	log.close()	

	# 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, float16, skipflat, plan, 
				   flat_end, half_half, half_half_line, dynamic_ff, EFF, filtEFF, im_dark, rotation, interp, border, 
				   rescale_factor, logfilename)).start()
def main(argv):
    """Try to guess the center of rotation of the input CT dataset.

    Parameters
    ----------
    infile  : array_like
        HDF5 input dataset

    outfile : string
        Full path where the identified center of rotation will be written as output

	scale   : int
        If sub-pixel precision is interesting, use e.g. 2.0 to get a center of rotation 
		of .5 value. Use 1.0 if sub-pixel precision is not required

	angles  : int
        Total number of angles of the input dataset	

	proj_from : int
        Initial projections to consider for the assumed angles

	proj_to : int
        Final projections to consider for the assumed angles

	method : string
		(not implemented yet)

	tmppath : string
        Temporary path where look for cached flat/dark files
       
    """
    # Get path:
    infile = argv[0]  # The HDF5 file on the
    outfile = argv[1]  # The txt file with the proposed center
    scale = float(argv[2])
    angles = float(argv[3])
    proj_from = int(argv[4])
    proj_to = int(argv[5])
    method = argv[6]
    tmppath = argv[7]
    if not tmppath.endswith(sep): tmppath += sep

    pyfftw_cache_disable()
    pyfftw_cache_enable()
    pyfftw_set_keepalive_time(1800)

    # Create a silly temporary log:
    tmplog = tmppath + basename(infile) + str(time.time())

    # Open the HDF5 file (take into account also older TDF versions):
    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)

    # Get flats 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, True, tmplog)
        remove(tmplog)
        plan2cache(corrplan, infile, tmppath)

    # Get first and the 180 deg projections:
    im1 = tdf.read_tomo(dset, proj_from).astype(float32)

    idx = int(round((proj_to - proj_from) / angles * pi)) + proj_from
    im2 = tdf.read_tomo(dset, idx).astype(float32)

    # Apply simple flat fielding (if applicable):
    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)):
        im1 = ((abs(im1 - corrplan['im_dark'])) /
               (abs(corrplan['im_flat'] - corrplan['im_dark']) +
                finfo(float32).eps)).astype(float32)
        im2 = ((abs(im2 - corrplan['im_dark_after'])) /
               (abs(corrplan['im_flat_after'] - corrplan['im_dark_after']) +
                finfo(float32).eps)).astype(float32)

    # Scale projections (if required) to get subpixel estimation:
    if (abs(scale - 1.0) > finfo(float32).eps):
        im1 = imresize(im1, (int(round(
            scale * im1.shape[0])), int(round(scale * im1.shape[1]))),
                       interp='bicubic',
                       mode='F')
        im2 = imresize(im2, (int(round(
            scale * im2.shape[0])), int(round(scale * im2.shape[1]))),
                       interp='bicubic',
                       mode='F')

    # Find the center (flipping left-right im2):
    cen = findcenter.usecorrelation(im1, im2[:, ::-1])
    cen = cen / scale

    # Print center to output file:
    text_file = open(outfile, "w")
    text_file.write(str(int(cen)))
    text_file.close()

    # Close input HDF5:
    f_in.close()