def _process(lock, int_from, int_to, files, outpath, polarfilt_opt, convert_opt, crop_opt, outprefix, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read i-th slice: t0 = time() im = imread(files[i]) t1 = time() # Filter (if required): im = polarfilter(im, polarfilt_opt) # Post process the image: im = croprescale(im, convert_opt, crop_opt) # Write down post-processed slice: t2 = time() fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname, im) t3 = time() # Write log (atomic procedure - lock used): _write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0))
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: reconstruct 0 4 C:\Temp\Dullin_Aug_2012\sino_noflat C:\Temp\Dullin_Aug_2012\sino_noflat\output 9.0 10.0 0.0 0.0 0.0 true sino slice C:\Temp\Dullin_Aug_2012\sino_noflat\tomo_conv flat dark """ lock = Lock() # Get the from and to number of files to process: idx = int(argv[0]) # Get input and output paths: inpath = argv[1] outfile = argv[2] if not inpath.endswith(sep): inpath += sep # Get parameters: polarfilt_opt = argv[3] convert_opt = argv[4] crop_opt = argv[5] outprefix = argv[6] logfilename = argv[7] # Get the files in infile: files = sorted(glob(inpath + '*.tif*')) num_files = len(files) if ((idx >= num_files) or (idx == -1)): idx = num_files - 1 # Read the image: im = imread(files[idx]) # Filter (if required): im = polarfilter(im, polarfilt_opt) # Process the image: im = croprescale(im, convert_opt, crop_opt) # 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: reconstruct 0 4 C:\Temp\Dullin_Aug_2012\sino_noflat C:\Temp\Dullin_Aug_2012\sino_noflat\output 9.0 10.0 0.0 0.0 0.0 true sino slice C:\Temp\Dullin_Aug_2012\sino_noflat\tomo_conv flat dark """ lock = Lock() # Get the from and to number of files to process: idx = int(argv[0]) # Get input and output paths: inpath = argv[1] outfile = argv[2] if not inpath.endswith(sep): inpath += sep # Get parameters: polarfilt_opt = argv[3] convert_opt = argv[4] crop_opt = argv[5] outprefix = argv[6] logfilename = argv[7] # Get the files in infile: files = sorted(glob(inpath + '*.tif*')) num_files = len(files) if ((idx >= num_files) or (idx == -1)): idx = num_files - 1 # Read the image: im = imread(files[idx]) # Filter (if required): im = polarfilter(im, polarfilt_opt) # Process the image: im = croprescale(im, convert_opt, crop_opt) # 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 process(sino_idx, num_sinos, infile, outfile, preprocessing_required, corr_plan, skipflat, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2, energy, distance, pixsize, phrtpad, approx_win, angles, angles_projfrom, angles_projto, offset, logtransform, recpar, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, nr_threads, logfilename, tmppath): """To do... """ # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if # required): if (phaseretrieval_required): # In this case a bunch of sinograms is loaded into memory: # # Load the temporary data structure reading the input TDF file. # To know the right dimension the first sinogram is pre-processed. # # Open the TDF file and get the dataset: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] # Downscaling and decimation factors considered when determining the # approximation window: zrange = arange(sino_idx - approx_win * downsc_factor / 2, sino_idx + approx_win * downsc_factor / 2, downsc_factor) zrange = zrange[(zrange >= 0)] zrange = zrange[(zrange < num_sinos)] approx_win = zrange.shape[0] # Approximation window cannot be odd: if (approx_win % 2 == 1): approx_win = approx_win - 1 zrange = zrange[0:approx_win] # Read one sinogram to get the proper dimensions: test_im = tdf.read_sino(dset, zrange[0]*downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing of the first sinogram to get the right # dimension: if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: #test_im = dynamic_flat_fielding(test_im, zrange[0] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) test_im = dynamic_flat_fielding(test_im, zrange[0] , EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: #test_im = flat_fielding(test_im, zrange[0] / downsc_factor, corr_plan, flat_end, half_half, # half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) test_im = flat_fielding(test_im, zrange[0], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) if not skipflat and not dynamic_ff: test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) else: test_im = ring_correction(test_im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov).astype(float32) # Now we can allocate memory for the bunch of slices: tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32) tmp_im[0,:,:] = test_im # Reading all the the sinos from TDF file and close: for ct in range(1, approx_win): # Read the sinogram: test_im = tdf.read_sino(dset, zrange[ct]*downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing for each sinogram of the bunch: if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: #test_im = dynamic_flat_fielding(test_im, zrange[ct] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) test_im = dynamic_flat_fielding(test_im, zrange[ct], EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: #test_im = flat_fielding(test_im, zrange[ct] / downsc_factor, corr_plan, flat_end, half_half, # half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) test_im = flat_fielding(test_im, zrange[ct], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) if not skipflat and not dynamic_ff: test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) else: test_im = ring_correction(test_im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov).astype(float32) tmp_im[ct,:,:] = test_im f_in.close() # Now everything has to refer to a downscaled dataset: sino_idx = ((zrange == sino_idx).nonzero()) # # Perform phase retrieval: # # Prepare the plan: if (phrtmethod == 0): # Paganin's: phrtplan = tiehom_plan(tmp_im[:,0,:], phrt_param1, phrt_param2, energy, distance, pixsize * downsc_factor, phrtpad) else: phrtplan = phrt_plan(tmp_im[:,0,:], energy, distance, pixsize * downsc_factor, phrt_param2, phrt_param1, phrtmethod, phrtpad) #phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance, #pixsize*downsc_factor, padding=phrtpad) # Process each projection (whose height depends on the size of the bunch): for ct in range(0, tmp_im.shape[1]): #tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32) if (phrtmethod == 0): tmp_im[:,ct,:] = tiehom(tmp_im[:,ct,:], phrtplan).astype(float32) else: tmp_im[:,ct,:] = phrt(tmp_im[:,ct,:], phrtplan, phrtmethod).astype(float32) # Extract the requested sinogram: im = tmp_im[sino_idx[0],:,:].squeeze() else: # Read only one sinogram: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,sino_idx * downsc_factor).astype(float32) f_in.close() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im = im[::decim_factor,::downsc_factor] #sino_idx = sino_idx / downsc_factor # Downscaling for the index already applied # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, sino_idx, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im = flat_fielding(im, sino_idx, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im = ring_correction(im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov) # Additional ring removal before reconstruction: #im = boinhaibel(im, '11;') #im = munchetal(im, '5;1.8') #im = rivers(im, '13;') #im = raven(im, '11;0.8') #im = oimoen(im, '51;51') # Actual reconstruction: im = reconstruct(im, angles, offset / downsc_factor, logtransform, recpar, circle, scale, pad, method, zerone_mode, dset_min, dset_max, corr_offset, rolling, roll_shift, tmppath).astype(float32) # Apply post-processing (if required): if postprocess_required: im = polarfilter(im, polarfilt_opt) im = croprescale(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset) / downsc_factor))) ** 2) im = im * a # Write down reconstructed preview file (file name modified with metadata): im = im.astype(float32) outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str(amin(im)) + '$' + str(amax(im)) im.tofile(outfile)
def process(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1): # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if # required): #if (phaseretrieval_required): # # Load into memory a bunch of sinograms: # t0 = time() # # Open the TDF file for reading: # f_in = getHDF5(infile, 'r') # if "/tomo" in f_in: # dset = f_in['tomo'] # else: # dset = f_in['exchange/data'] # # Prepare the data structure according to the approximation window: # tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset), # approx_win), dtype=float32) # # Load the temporary data structure reading the input TDF file: # # (It can be parallelized Open-MP style) # ct = 0 # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # a = tdf.read_sino(dset,j).astype(float32) # tmp_im[:,:,ct] = a # ct = ct + 1 # # Close the TDF file: # f_in.close() # t1 = time() # # Perform the processing: # if (preprocessing_required): # ct = 0 # # (It can be parallelized Open-MP style) # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end, # half_half, half_half_line, norm_sx, norm_dx).astype(float32) # tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov, # ext_fov_rot_right, ext_fov_overlap).astype(float32) # tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end, # corr_plan['skip_flat_after'], half_half, half_half_line, # ext_fov).astype(float32) # ct = ct + 1 # # Perform phase retrieval: # # (It can be parallelized Open-MP style) # for ct in range(0, tmp_im.shape[0]): # tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T, # phrt_plan).astype(float32).T # ct = ct + 1 # # Extract the central processed sinogram: # im = tmp_im[:,:,approx_win/2] #else: # Read only one sinogram: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset, i * downsc_factor).astype(float32) f_in.close() t1 = time() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im = im[::decim_factor, ::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx).astype(float32) else: im = flat_fielding(im, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im = ring_correction(im, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: im = reconstruct(im, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset).astype(float32) # Apply post-processing (if required): if postprocess_required: im = polarfilter(im, polarfilt_opt) im = croprescale(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2, siz / 2) x, y = meshgrid(rang, rang) z = x**2 + y**2 a = (z < (siz / 2 - abs(offset))**2) im = im * a # Write down reconstructed slice: t2 = time() fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname, im) t3 = time() # Write log (atomic procedure - lock used): write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0))
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1, 2): # Read two sinograms: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im1 = tdf.read_sino(dset, i * downsc_factor).astype(float32) if ((i + downsc_factor) <= (int_to + 1)): im2 = tdf.read_sino(dset, i * downsc_factor + downsc_factor).astype(float32) else: im2 = im1 f_in.close() t1 = time() # Apply projection removal (if required): im1 = im1[angles_projfrom:angles_projto, :] im2 = im2[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im1 = im1[::decim_factor, ::downsc_factor] im2 = im2[::decim_factor, ::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinograms (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im1 = dynamic_flat_fielding(im1, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im1 = flat_fielding(im1, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im1 = extfov_correction(im1, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat: im1 = ring_correction(im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im1 = ring_correction(im1, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov) if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im2 = dynamic_flat_fielding(im2, i + 1, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im2 = flat_fielding(im2, i + 1, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im2 = extfov_correction(im2, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im2 = ring_correction(im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im2 = ring_correction(im2, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: [im1, im2] = reconstruct_gridrec(im1, im2, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset) # Appy post-processing (if required): if postprocess_required: # Filter (if required): im1 = polarfilter(im1, polarfilt_opt) im2 = polarfilter(im2, polarfilt_opt) im1 = croprescale(im1, convert_opt, crop_opt, circle) im2 = croprescale(im2, convert_opt, crop_opt, circle) else: # Create the circle mask for fancy output: if (circle == True): siz = im1.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2, siz / 2) x, y = meshgrid(rang, rang) z = x**2 + y**2 a = (z < (siz / 2 - int(round(abs(offset) / downsc_factor)))**2) im1 = im1 * a im2 = im2 * a # Write down reconstructed slices: t2 = time() fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname1, im1) fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif' imsave(fname2, im2) t3 = time() # Write log (atomic procedure - lock used): write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0))
def 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 process(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1): # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required): #if (phaseretrieval_required): # # Load into memory a bunch of sinograms: # t0 = time() # # Open the TDF file for reading: # f_in = getHDF5(infile, 'r') # if "/tomo" in f_in: # dset = f_in['tomo'] # else: # dset = f_in['exchange/data'] # # Prepare the data structure according to the approximation window: # tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset), approx_win), dtype=float32) # # Load the temporary data structure reading the input TDF file: # # (It can be parallelized Open-MP style) # ct = 0 # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # a = tdf.read_sino(dset,j).astype(float32) # tmp_im[:,:,ct] = a # ct = ct + 1 # # Close the TDF file: # f_in.close() # t1 = time() # # Perform the processing: # if (preprocessing_required): # ct = 0 # # (It can be parallelized Open-MP style) # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32) # tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov, ext_fov_rot_right, ext_fov_overlap).astype(float32) # tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov).astype(float32) # ct = ct + 1 # # Perform phase retrieval: # # (It can be parallelized Open-MP style) # for ct in range(0, tmp_im.shape[0]): # tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T, phrt_plan).astype(float32).T # ct = ct + 1 # # Extract the central processed sinogram: # im = tmp_im[:,:,approx_win/2] #else: # Read only one sinogram: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,i*downsc_factor).astype(float32) f_in.close() t1 = time() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im = im[::decim_factor,::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx).astype(float32) else: im = flat_fielding (im, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction (im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im = ring_correction (im, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: im = reconstruct(im, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset).astype(float32) # Apply post-processing (if required): if postprocess_required: im = polarfilter(im, polarfilt_opt) im = croprescale(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - abs(offset) ) ** 2) im = im * a # Write down reconstructed slice: t2 = time() fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname, im) t3 = time() # Write log (atomic procedure - lock used): write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1, 2): # Read two sinograms: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im1 = tdf.read_sino(dset,i*downsc_factor).astype(float32) if ( (i + downsc_factor) <= (int_to + 1) ): im2 = tdf.read_sino(dset,i*downsc_factor + downsc_factor).astype(float32) else: im2 = im1 f_in.close() t1 = time() # Apply projection removal (if required): im1 = im1[angles_projfrom:angles_projto, :] im2 = im2[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im1 = im1[::decim_factor,::downsc_factor] im2 = im2[::decim_factor,::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinograms (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im1 = dynamic_flat_fielding(im1, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im1 = flat_fielding (im1, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im1 = extfov_correction (im1, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat: im1 = ring_correction (im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im1 = ring_correction (im1, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov) if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im2 = dynamic_flat_fielding(im2, i + 1, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im2 = flat_fielding (im2, i + 1, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im2 = extfov_correction (im2, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im2 = ring_correction (im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im2 = ring_correction (im2, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: [im1, im2] = reconstruct_gridrec(im1, im2, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset) # Appy post-processing (if required): if postprocess_required: # Filter (if required): im1 = polarfilter(im1, polarfilt_opt) im2 = polarfilter(im2, polarfilt_opt) im1 = croprescale(im1, convert_opt, crop_opt, circle) im2 = croprescale(im2, convert_opt, crop_opt, circle) else: # Create the circle mask for fancy output: if (circle == True): siz = im1.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2) im1 = im1 * a im2 = im2 * a # Write down reconstructed slices: t2 = time() fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname1, im1) fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif' imsave(fname2, im2) t3 = time() # Write log (atomic procedure - lock used): write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )