def _process (lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, dynamic_ff, EFF, filtEFF, im_dark, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read input image: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,i).astype(float32) f_in.close() t1 = time() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction (im, ringrem, flat_end, plan['skip_flat_after'], half_half, half_half_line, ext_fov) else: im = ring_correction (im, ringrem, False, False, half_half, half_half_line, ext_fov) t2 = time() # Save processed image to HDF5 file (atomic procedure - lock used): _write_data(lock, im, i, outfile, outshape, outtype, logfilename, t2 - t1, t1 - t0)
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, flat_end, half_half, half_half_line, dynamic_ff, EFF, filtEFF, im_dark, rotation, interp, border, rescale_factor, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read input image: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_tomo(dset,i).astype(float32) f_in.close() t1 = time() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, EFF, filtEFF, 2, im_dark) else: im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx) t2 = time() # Rotate: rows, cols = im.shape #if (cols > rows): # angle = - arctan(2.0 / cols) * (rows / 2.0) / 2.0 #else: # angle = - arctan(2.0 / rows) * (cols / 2.0) / 2.0 #print(angle) M = cv2.getRotationMatrix2D((cols / 2, rows / 2), rotation, 1) if interp == 'nearest': interpflag = cv2.INTER_NEAREST elif interp == 'cubic': interpflag = cv2.INTER_CUBIC elif interp == 'lanczos': interpflag = cv2.INTER_LANCZOS4 else: interpflag = cv2.INTER_LINEAR if border == 'constant': borderflag = cv2.BORDER_CONSTANT else: borderflag = cv2.BORDER_REPLICATE im = cv2.warpAffine(im, M, (cols, rows), flags = interpflag, borderMode = borderflag) # Save processed image to HDF5 file (atomic procedure - lock used): _write_data(lock, im, i, outfile, outshape, outtype, rescale_factor, logfilename, t2 - t1, t1 - t0)
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, dynamic_ff, EFF, filtEFF, im_dark, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read input image: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset, i).astype(float32) f_in.close() t1 = time() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction(im, ringrem, flat_end, plan['skip_flat_after'], half_half, half_half_line, ext_fov) else: im = ring_correction(im, ringrem, False, False, half_half, half_half_line, ext_fov) t2 = time() # Save processed image to HDF5 file (atomic procedure - lock used): _write_data(lock, im, i, outfile, outshape, outtype, logfilename, t2 - t1, t1 - t0)
def _process(lock, int_from, int_to, infile, outfile, outshape, outtype, skipflat, plan, flat_end, half_half, half_half_line, dynamic_ff, EFF, filtEFF, im_dark, rotation, interp, border, rescale_factor, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read input image: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_tomo(dset, i).astype(float32) f_in.close() t1 = time() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, EFF, filtEFF, 2, im_dark) else: im = flat_fielding(im, i, plan, flat_end, half_half, half_half_line, norm_sx, norm_dx) t2 = time() # Rotate: rows, cols = im.shape #if (cols > rows): # angle = - arctan(2.0 / cols) * (rows / 2.0) / 2.0 #else: # angle = - arctan(2.0 / rows) * (cols / 2.0) / 2.0 #print(angle) M = cv2.getRotationMatrix2D((cols / 2, rows / 2), rotation, 1) if interp == 'nearest': interpflag = cv2.INTER_NEAREST elif interp == 'cubic': interpflag = cv2.INTER_CUBIC elif interp == 'lanczos': interpflag = cv2.INTER_LANCZOS4 else: interpflag = cv2.INTER_LINEAR if border == 'constant': borderflag = cv2.BORDER_CONSTANT else: borderflag = cv2.BORDER_REPLICATE im = cv2.warpAffine(im, M, (cols, rows), flags=interpflag, borderMode=borderflag) # Save processed image to HDF5 file (atomic procedure - lock used): _write_data(lock, im, i, outfile, outshape, outtype, rescale_factor, logfilename, t2 - t1, t1 - t0)
def process(sino_idx, num_sinos, infile, outfile, preprocessing_required, corr_plan, skipflat, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2, energy, distance, pixsize, phrtpad, approx_win, angles, angles_projfrom, angles_projto, offset, logtransform, recpar, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, nr_threads, logfilename, tmppath): """To do... """ # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if # required): if (phaseretrieval_required): # In this case a bunch of sinograms is loaded into memory: # # Load the temporary data structure reading the input TDF file. # To know the right dimension the first sinogram is pre-processed. # # Open the TDF file and get the dataset: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] # Downscaling and decimation factors considered when determining the # approximation window: zrange = arange(sino_idx - approx_win * downsc_factor / 2, sino_idx + approx_win * downsc_factor / 2, downsc_factor) zrange = zrange[(zrange >= 0)] zrange = zrange[(zrange < num_sinos)] approx_win = zrange.shape[0] # Approximation window cannot be odd: if (approx_win % 2 == 1): approx_win = approx_win - 1 zrange = zrange[0:approx_win] # Read one sinogram to get the proper dimensions: test_im = tdf.read_sino(dset, zrange[0]*downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing of the first sinogram to get the right # dimension: if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: #test_im = dynamic_flat_fielding(test_im, zrange[0] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) test_im = dynamic_flat_fielding(test_im, zrange[0] , EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: #test_im = flat_fielding(test_im, zrange[0] / downsc_factor, corr_plan, flat_end, half_half, # half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) test_im = flat_fielding(test_im, zrange[0], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) if not skipflat and not dynamic_ff: test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) else: test_im = ring_correction(test_im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov).astype(float32) # Now we can allocate memory for the bunch of slices: tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32) tmp_im[0,:,:] = test_im # Reading all the the sinos from TDF file and close: for ct in range(1, approx_win): # Read the sinogram: test_im = tdf.read_sino(dset, zrange[ct]*downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing for each sinogram of the bunch: if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: #test_im = dynamic_flat_fielding(test_im, zrange[ct] / downsc_factor, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) test_im = dynamic_flat_fielding(test_im, zrange[ct], EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: #test_im = flat_fielding(test_im, zrange[ct] / downsc_factor, corr_plan, flat_end, half_half, # half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) test_im = flat_fielding(test_im, zrange[ct], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) if not skipflat and not dynamic_ff: test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) else: test_im = ring_correction(test_im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov).astype(float32) tmp_im[ct,:,:] = test_im f_in.close() # Now everything has to refer to a downscaled dataset: sino_idx = ((zrange == sino_idx).nonzero()) # # Perform phase retrieval: # # Prepare the plan: if (phrtmethod == 0): # Paganin's: phrtplan = tiehom_plan(tmp_im[:,0,:], phrt_param1, phrt_param2, energy, distance, pixsize * downsc_factor, phrtpad) else: phrtplan = phrt_plan(tmp_im[:,0,:], energy, distance, pixsize * downsc_factor, phrt_param2, phrt_param1, phrtmethod, phrtpad) #phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance, #pixsize*downsc_factor, padding=phrtpad) # Process each projection (whose height depends on the size of the bunch): for ct in range(0, tmp_im.shape[1]): #tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32) if (phrtmethod == 0): tmp_im[:,ct,:] = tiehom(tmp_im[:,ct,:], phrtplan).astype(float32) else: tmp_im[:,ct,:] = phrt(tmp_im[:,ct,:], phrtplan, phrtmethod).astype(float32) # Extract the requested sinogram: im = tmp_im[sino_idx[0],:,:].squeeze() else: # Read only one sinogram: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,sino_idx * downsc_factor).astype(float32) f_in.close() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im = im[::decim_factor,::downsc_factor] #sino_idx = sino_idx / downsc_factor # Downscaling for the index already applied # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, sino_idx, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im = flat_fielding(im, sino_idx, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im = ring_correction(im, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov) # Additional ring removal before reconstruction: #im = boinhaibel(im, '11;') #im = munchetal(im, '5;1.8') #im = rivers(im, '13;') #im = raven(im, '11;0.8') #im = oimoen(im, '51;51') # Actual reconstruction: im = reconstruct(im, angles, offset / downsc_factor, logtransform, recpar, circle, scale, pad, method, zerone_mode, dset_min, dset_max, corr_offset, rolling, roll_shift, tmppath).astype(float32) # Apply post-processing (if required): if postprocess_required: im = polarfilter(im, polarfilt_opt) im = croprescale(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset) / downsc_factor))) ** 2) im = im * a # Write down reconstructed preview file (file name modified with metadata): im = im.astype(float32) outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str(amin(im)) + '$' + str(amax(im)) im.tofile(outfile)
def process(sino_idx, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2, energy, distance, pixsize, phrtpad, approx_win, angles, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, crop_opt, nr_threads, angles_from, angles_to, logfilename, lock, slice_prefix): """To do... """ slice_nr = sino_idx # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required): if (phaseretrieval_required): # In this case a bunch of sinograms is loaded into memory: # # Load the temporary data structure reading the input TDF file. # To know the right dimension the first sinogram is pre-processed. # # Open the TDF file and get the dataset: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] # Downscaling and decimation factors considered when determining the approximation window: zrange = arange(sino_idx - approx_win*downsc_factor/2, sino_idx + approx_win*downsc_factor/2, downsc_factor) zrange = zrange[ (zrange >= 0) ] zrange = zrange[ (zrange < num_sinos) ] approx_win = zrange.shape[0] # Approximation window cannot be odd: if (approx_win % 2 == 1): approx_win = approx_win-1 zrange = zrange[0:approx_win] # Read one sinogram to get the proper dimensions: test_im = tdf.read_sino(dset, zrange[0]*downsc_factor).astype(float32) # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing of the first sinogram to get the right dimension: if (preprocessing_required): test_im = flat_fielding (test_im, zrange[0], corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov).astype(float32) # Now we can allocate memory for the bunch of slices: tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32) tmp_im[0,:,:] = test_im # Reading all the the sinos from TDF file and close: for ct in range(1, approx_win): test_im = tdf.read_sino(dset, zrange[ct]*downsc_factor).astype(float32) test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing for each sinogram of the bunch: if (preprocessing_required): test_im = flat_fielding (test_im, zrange[ct], corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov).astype(float32) tmp_im[ct,:,:] = test_im f_in.close() # Now everything has to refer to a downscaled dataset: sino_idx = ((zrange == sino_idx).nonzero()) # # Perform phase retrieval: # # Prepare the plan: if (phrtmethod == 0): # Paganin's: phrtplan = tiehom_plan (tmp_im[:,0,:], phrt_param1, phrt_param2, energy, distance, pixsize*downsc_factor, padding=phrtpad) else: phrtplan = phrt_plan (tmp_im[:,0,:], energy, distance, pixsize*downsc_factor, phrt_param2, phrt_param1, phrtmethod, padding=phrtpad) # Process each projection (whose height depends on the size of the bunch): for ct in range(0, tmp_im.shape[1]): if (phrtmethod == 0): tmp_im[:,ct,:] = tiehom(tmp_im[:,ct,:], phrtplan).astype(float32) else: tmp_im[:,ct,:] = phrt(tmp_im[:,ct,:], phrtplan, phrtmethod).astype(float32) # Extract the requested sinogram: im = tmp_im[sino_idx[0],:,:].squeeze() else: # Read only one sinogram: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,sino_idx * downsc_factor).astype(float32) f_in.close() # Downscale and decimate the sinogram: im = im[::decim_factor,::downsc_factor] #sino_idx = sino_idx/downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): im = flat_fielding (im, sino_idx, corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction (test_im, ext_fov_rot_right, ext_fov_overlap/downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov) # Log infos: log = open(logfilename,"a") log.write(linesep + "\tPerforming reconstruction with multiple centers of rotation...") log.write(linesep + "\t--------------") log.close() # Split the computation into multiple processes: for num in range(nr_threads): start = ( (angles_to - angles_from + 1) / nr_threads)*num + angles_from if (num == nr_threads - 1): end = angles_to else: end = ( (angles_to - angles_from + 1) / nr_threads)*(num + 1) + angles_from - 1 Process(target=reconstruct, args=(im, angles, offset/downsc_factor, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, corr_offset, postprocess_required, convert_opt, crop_opt, start, end, outpath, slice_nr, downsc_factor, decim_factor, logfilename, lock, slice_prefix)).start()
def process(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1): # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if # required): #if (phaseretrieval_required): # # Load into memory a bunch of sinograms: # t0 = time() # # Open the TDF file for reading: # f_in = getHDF5(infile, 'r') # if "/tomo" in f_in: # dset = f_in['tomo'] # else: # dset = f_in['exchange/data'] # # Prepare the data structure according to the approximation window: # tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset), # approx_win), dtype=float32) # # Load the temporary data structure reading the input TDF file: # # (It can be parallelized Open-MP style) # ct = 0 # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # a = tdf.read_sino(dset,j).astype(float32) # tmp_im[:,:,ct] = a # ct = ct + 1 # # Close the TDF file: # f_in.close() # t1 = time() # # Perform the processing: # if (preprocessing_required): # ct = 0 # # (It can be parallelized Open-MP style) # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end, # half_half, half_half_line, norm_sx, norm_dx).astype(float32) # tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov, # ext_fov_rot_right, ext_fov_overlap).astype(float32) # tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end, # corr_plan['skip_flat_after'], half_half, half_half_line, # ext_fov).astype(float32) # ct = ct + 1 # # Perform phase retrieval: # # (It can be parallelized Open-MP style) # for ct in range(0, tmp_im.shape[0]): # tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T, # phrt_plan).astype(float32).T # ct = ct + 1 # # Extract the central processed sinogram: # im = tmp_im[:,:,approx_win/2] #else: # Read only one sinogram: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset, i * downsc_factor).astype(float32) f_in.close() t1 = time() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im = im[::decim_factor, ::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx).astype(float32) else: im = flat_fielding(im, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im = ring_correction(im, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: im = reconstruct(im, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, method, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset).astype(float32) # Apply post-processing (if required): if postprocess_required: im = polarfilter(im, polarfilt_opt) im = croprescale(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2, siz / 2) x, y = meshgrid(rang, rang) z = x**2 + y**2 a = (z < (siz / 2 - abs(offset))**2) im = im * a # Write down reconstructed slice: t2 = time() fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname, im) t3 = time() # Write log (atomic procedure - lock used): write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0))
def process(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem, angles, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, crop_opt, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1): # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required): #if (phaseretrieval_required): # # Load into memory a bunch of sinograms: # t0 = time() # # Open the TDF file for reading: # f_in = getHDF5(infile, 'r') # if "/tomo" in f_in: # dset = f_in['tomo'] # else: # dset = f_in['exchange/data'] # # Prepare the data structure according to the approximation window: # tmp_im = numpy.empty((tdf.get_nr_projs(dset),tdf.get_det_size(dset), approx_win), dtype=float32) # # Load the temporary data structure reading the input TDF file: # # (It can be parallelized Open-MP style) # ct = 0 # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # a = tdf.read_sino(dset,j).astype(float32) # tmp_im[:,:,ct] = a # ct = ct + 1 # # Close the TDF file: # f_in.close() # t1 = time() # # Perform the processing: # if (preprocessing_required): # ct = 0 # # (It can be parallelized Open-MP style) # for j in range(i - approx_win/2, i + approx_win/2 + 1): # if (j < 0): # j = 0 # if (j >= num_sinos): # j = num_sinos - 1 # tmp_im[:,:,ct] = flat_fielding (tmp_im[:,:,ct], j, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32) # tmp_im[:,:,ct] = extfov_correction (tmp_im[:,:,ct], ext_fov, ext_fov_rot_right, ext_fov_overlap).astype(float32) # tmp_im[:,:,ct] = ring_correction (tmp_im[:,:,ct], ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov).astype(float32) # ct = ct + 1 # # Perform phase retrieval: # # (It can be parallelized Open-MP style) # for ct in range(0, tmp_im.shape[0]): # tmp_im[ct,:,:] = phase_retrieval(tmp_im[ct,:,:].T, phrt_plan).astype(float32).T # ct = ct + 1 # # Extract the central processed sinogram: # im = tmp_im[:,:,approx_win/2] #else: # Read only one sinogram: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,i).astype(float32) f_in.close() t1 = time() # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): im = flat_fielding (im, i, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32) im = extfov_correction (im, ext_fov, ext_fov_rot_right, ext_fov_overlap) im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov) # Actual reconstruction: im = reconstruct(im, angles, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset).astype(float32) # Appy post-processing (if required): if postprocess_required: im = postprocess(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - abs(offset) ) ** 2) im = im * a # Write down reconstructed slice: t2 = time() fname = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname, im) t3 = time() # Write log (atomic procedure - lock used): write_log(lock, fname, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )
def process(sino_idx, num_sinos, infile, outfile, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem, phaseretrieval_required, beta, delta, energy, distance, pixsize, phrtpad, approx_win, angles, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, crop_opt, nr_threads, logfilename): """To do... """ # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required): if (phaseretrieval_required): # In this case a bunch of sinograms is loaded into memory: # # Load the temporary data structure reading the input TDF file. # To know the right dimension the first sinogram is pre-processed. # # Open the TDF file and get the dataset: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] # Downscaling and decimation factors considered when determining the approximation window: zrange = arange(sino_idx - approx_win*downsc_factor/2, sino_idx + approx_win*downsc_factor/2, downsc_factor) zrange = zrange[ (zrange >= 0) ] zrange = zrange[ (zrange < num_sinos) ] approx_win = zrange.shape[0] # Approximation window cannot be odd: if (approx_win % 2 == 1): approx_win = approx_win-1 zrange = zrange[0:approx_win] # Read one sinogram to get the proper dimensions: test_im = tdf.read_sino(dset, zrange[0]).astype(float32) test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing of the first sinogram to get the right dimension: if (preprocessing_required): test_im = flat_fielding (test_im, zrange[0]/downsc_factor, corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) test_im = extfov_correction (test_im, ext_fov, ext_fov_rot_right, ext_fov_overlap/downsc_factor).astype(float32) test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov).astype(float32) # Now we can allocate memory for the bunch of slices: tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32) tmp_im[0,:,:] = test_im # Reading all the the sinos from TDF file and close: for ct in range(1, approx_win): test_im = tdf.read_sino(dset, zrange[ct]).astype(float32) test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing for each sinogram of the bunch: if (preprocessing_required): test_im = flat_fielding (test_im, zrange[ct]/downsc_factor, corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) test_im = extfov_correction (test_im, ext_fov, ext_fov_rot_right, ext_fov_overlap/downsc_factor).astype(float32) test_im = ring_correction (test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov).astype(float32) tmp_im[ct,:,:] = test_im f_in.close() # Now everything has to refer to a downscaled dataset: sino_idx = ((zrange == sino_idx).nonzero()) # # Perform phase retrieval: # # Prepare the plan: phrtplan = prepare_plan (tmp_im[:,0,:], beta, delta, energy, distance, pixsize*downsc_factor, padding=phrtpad) # Process each projection (whose height depends on the size of the bunch): for ct in range(0, tmp_im.shape[1]): tmp_im[:,ct,:] = phase_retrieval(tmp_im[:,ct,:], phrtplan).astype(float32) # Extract the requested sinogram: im = tmp_im[sino_idx[0],:,:].squeeze() else: # Read only one sinogram: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset,sino_idx).astype(float32) f_in.close() # Downscale and decimate the sinogram: im = im[::decim_factor,::downsc_factor] sino_idx = sino_idx/downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): im = flat_fielding (im, sino_idx, corr_plan, flat_end, half_half, half_half_line/decim_factor, norm_sx, norm_dx).astype(float32) im = extfov_correction (im, ext_fov, ext_fov_rot_right, ext_fov_overlap) #imsave('C:\\Temp\\StupidFolder\\sinoprimaringrem.tif', im.astype(float32)) im = ring_correction (im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line/decim_factor, ext_fov) #imsave('C:\\Temp\\StupidFolder\\sinodoporingrem.tif', im.astype(float32)) # Actual reconstruction: im = reconstruct(im, angles, offset/downsc_factor, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, corr_offset).astype(float32) # Apply post-processing (if required): if postprocess_required: im = postprocess(im, convert_opt, crop_opt) else: # Create the circle mask for fancy output: if (circle == True): siz = im.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2) im = im * a # Write down reconstructed preview file (file name modified with metadata): im = im.astype(float32) outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( amin(im)) + '$' + str( amax(im) ) im.tofile(outfile)
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 _process(lock, int_from, int_to, num_sinos, infile_1, infile_2, infile_3, outfile_abs, outfile_ref, outfile_sca, r1, r2, r3, d1, d2, d3, dd1, dd2, dd3, shiftVert_1, shiftHoriz_1, shiftVert_2, shiftHoriz_2, shiftVert_3, shiftHoriz_3, outshape, outtype, skipflat_1, skipflat_2, skipflat_3, plan_1, plan_2, plan_3, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, dynamic_ff, EFF_1, EFF_2, EFF_3, filtEFF_1, filtEFF_2, filtEFF_3, im_dark_1, im_dark_2, im_dark_3, logfilename): # Process the required subset of images: for i in range(int_from, int_to + 1): # Read input image for top, left and right: t0 = time() f_in = getHDF5(infile_1, 'r') if "/tomo" in f_in: dset = f_in['tomo'] flat_avg1 = float(f_in['flat'].attrs['avg']) dark_avg1 = float(f_in['dark'].attrs['avg']) else: dset = f_in['exchange/data'] flat_avg1 = float(f_in['exchange/data_white'].attrs['avg']) dark_avg1 = float(f_in['exchange/data_dark'].attrs['avg']) # Processing in the sinogram domain so a vertical shift of the # projection requires loading a different sinogram: idx1 = min(max(0, i - shiftVert_1), num_sinos - 1) im_1 = tdf.read_sino(dset, idx1).astype(float32) f_in.close() f_in = getHDF5(infile_2, 'r') if "/tomo" in f_in: dset = f_in['tomo'] flat_avg2 = float(f_in['flat'].attrs['avg']) dark_avg2 = float(f_in['dark'].attrs['avg']) else: dset = f_in['exchange/data'] flat_avg2 = float(f_in['exchange/data_white'].attrs['avg']) dark_avg2 = float(f_in['exchange/data_dark'].attrs['avg']) # Processing in the sinogram domain so a vertical shift of the # projection requires loading a different sinogram: idx2 = min(max(0, i - shiftVert_2), num_sinos - 1) im_2 = tdf.read_sino(dset, idx2).astype(float32) f_in.close() f_in = getHDF5(infile_3, 'r') if "/tomo" in f_in: dset = f_in['tomo'] flat_avg3 = float(f_in['flat'].attrs['avg']) dark_avg3 = float(f_in['dark'].attrs['avg']) else: dset = f_in['exchange/data'] flat_avg3 = float(f_in['exchange/data_white'].attrs['avg']) dark_avg3 = float(f_in['exchange/data_dark'].attrs['avg']) # Processing in the sinogram domain so a vertical shift of the projection # requires loading a different sinogram: idx3 = min(max(0, i - shiftVert_3), num_sinos - 1) im_3 = tdf.read_sino(dset, idx3).astype(float32) f_in.close() t1 = time() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat_1: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im_1 = dynamic_flat_fielding(im_1, idx1, EFF_1, filtEFF_1, 2, im_dark_1, norm_sx, norm_dx) else: im_1 = flat_fielding(im_1, idx1, plan_1, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im_1 = extfov_correction(im_1, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat_1 and not dynamic_ff: im_1 = ring_correction(im_1, ringrem, flat_end, plan_1['skip_flat_after'], half_half, half_half_line, ext_fov) else: im_1 = ring_correction(im_1, ringrem, False, False, half_half, half_half_line, ext_fov) # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat_2: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im_2 = dynamic_flat_fielding(im_2, idx2, EFF_2, filtEFF_2, 2, im_dark_2, norm_sx, norm_dx) else: im_2 = flat_fielding(im_2, idx2, plan_2, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im_2 = extfov_correction(im_2, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat_2 and not dynamic_ff: im_2 = ring_correction(im_2, ringrem, flat_end, plan_2['skip_flat_after'], half_half, half_half_line, ext_fov) else: im_2 = ring_correction(im_2, ringrem, False, False, half_half, half_half_line, ext_fov) # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat_3: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im_3 = dynamic_flat_fielding(im_3, idx3, EFF_3, filtEFF_3, 2, im_dark_3, norm_sx, norm_dx) else: im_3 = flat_fielding(im_3, idx3, plan_3, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im_3 = extfov_correction(im_3, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat_3 and not dynamic_ff: im_3 = ring_correction(im_3, ringrem, flat_end, plan_3['skip_flat_after'], half_half, half_half_line, ext_fov) else: im_3 = ring_correction(im_3, ringrem, False, False, half_half, half_half_line, ext_fov) t2 = time() # Processing in the sinogram domain so a vertical shift of the # projection requires loading a different sinogram: # Only horizontal shift can be considered at a sinogram level: if (shiftHoriz_1 != 0): im_1 = _shift_horiz(im_1, shiftHoriz_1) if (shiftHoriz_2 != 0): im_2 = _shift_horiz(im_2, shiftHoriz_2) if (shiftHoriz_3 != 0): im_3 = _shift_horiz(im_3, shiftHoriz_3) # Re-normalize with average of the flat-field images: max_val = amax( array([ mean(flat_avg1 - dark_avg1), mean(flat_avg2 - dark_avg2), mean(flat_avg3 - dark_avg3) ])) im_1 = im_1 * (flat_avg1 - dark_avg1) / max_val im_2 = im_2 * (flat_avg2 - dark_avg2) / max_val im_3 = im_3 * (flat_avg3 - dark_avg3) / max_val # Apply GDEI: (im_abs, im_ref, im_sca) = gdei(im_1, im_2, im_3, r1, r2, r3, d1, d2, d3, dd1, dd2, dd3) # Save processed image to HDF5 file (atomic procedure - lock used): lock.acquire() try: t3 = time() _write_data(im_abs, i, outfile_abs, outshape, outtype) _write_data(im_ref, i, outfile_ref, outshape, outtype) _write_data(im_sca, i, outfile_sca, outshape, outtype) t4 = time() # Print out execution time: log = open(logfilename, "a") log.write( linesep + "\tsino_%s processed (CPU: %0.3f sec - I/O: %0.3f sec)." % (str(i).zfill(4), t2 - t1, (t1 - t0) + (t4 - t3))) log.close() finally: lock.release()
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)
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_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, skipflat, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, polarfilt_opt, convert_opt, crop_opt, dynamic_ff, EFF, filtEFF, im_dark, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1, 2): # Read two sinograms: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im1 = tdf.read_sino(dset,i*downsc_factor).astype(float32) if ( (i + downsc_factor) <= (int_to + 1) ): im2 = tdf.read_sino(dset,i*downsc_factor + downsc_factor).astype(float32) else: im2 = im1 f_in.close() t1 = time() # Apply projection removal (if required): im1 = im1[angles_projfrom:angles_projto, :] im2 = im2[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): im1 = im1[::decim_factor,::downsc_factor] im2 = im2[::decim_factor,::downsc_factor] #i = i / downsc_factor # Perform the preprocessing of the sinograms (if required): if (preprocessing_required): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im1 = dynamic_flat_fielding(im1, i, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im1 = flat_fielding (im1, i, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im1 = extfov_correction (im1, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat: im1 = ring_correction (im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im1 = ring_correction (im1, ringrem, False, False, half_half, half_half_line / decim_factor, ext_fov) if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im2 = dynamic_flat_fielding(im2, i + 1, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im2 = flat_fielding (im2, i + 1, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im2 = extfov_correction (im2, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im2 = ring_correction (im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) else: im2 = ring_correction (im2, ringrem, False, False, half_half, half_half_line, ext_fov) # Actual reconstruction: [im1, im2] = reconstruct_gridrec(im1, im2, angles, offset / downsc_factor, logtransform, param1, circle, scale, pad, rolling, roll_shift, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset) # Appy post-processing (if required): if postprocess_required: # Filter (if required): im1 = polarfilter(im1, polarfilt_opt) im2 = polarfilter(im2, polarfilt_opt) im1 = croprescale(im1, convert_opt, crop_opt, circle) im2 = croprescale(im2, convert_opt, crop_opt, circle) else: # Create the circle mask for fancy output: if (circle == True): siz = im1.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2) im1 = im1 * a im2 = im2 * a # Write down reconstructed slices: t2 = time() fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname1, im1) fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif' imsave(fname2, im2) t3 = time() # Write log (atomic procedure - lock used): write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )
def main(argv): """To do... """ # Get the zero-order index of the sinogram to pre-process: idx = int(argv[0]) # Get paths: infile = argv[1] outfile = argv[2] # Normalization parameters: norm_sx = int(argv[3]) norm_dx = int(argv[4]) # Params for flat fielding with post flats/darks: flat_end = True if argv[5] == "True" else False half_half = True if argv[6] == "True" else False half_half_line = int(argv[7]) # Params for extended FOV: ext_fov = True if argv[8] == "True" else False ext_fov_rot_right = argv[9] if ext_fov_rot_right == "True": ext_fov_rot_right = True if (ext_fov): norm_sx = 0 else: ext_fov_rot_right = False if (ext_fov): norm_dx = 0 ext_fov_overlap = int(argv[10]) ext_fov_normalize = True if argv[11] == "True" else False ext_fov_average = True if argv[12] == "True" else False # Method and parameters coded into a string: ringrem = argv[13] # Flat fielding method (conventional or dynamic): dynamic_ff = True if argv[14] == "True" else False # Tmp path and log file: tmppath = argv[15] if not tmppath.endswith(sep): tmppath += sep logfilename = argv[16] # Open the HDF5 file: f_in = getHDF5(infile, 'r') try: if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] except: log = open(logfilename,"a") log.write(linesep + "\tError reading input dataset. Process will end.") log.close() exit() num_proj = tdf.get_nr_projs(dset) num_sinos = tdf.get_nr_sinos(dset) # Check if the HDF5 makes sense: if (num_sinos == 0): log = open(logfilename,"a") log.write(linesep + "\tNo projections found. Process will end.") log.close() exit() # Get flat and darks from cache or from file: skipflat = False skipdark = False if not dynamic_ff: try: corrplan = cache2plan(infile, tmppath) except Exception as e: #print "Error(s) when reading from cache" corrplan = extract_flatdark(f_in, flat_end, logfilename) if (isscalar(corrplan['im_flat']) and isscalar(corrplan['im_flat_after']) ): skipflat = True else: plan2cache(corrplan, infile, tmppath) else: # Dynamic flat fielding: if "/tomo" in f_in: if "/flat" in f_in: flat_dset = f_in['flat'] if "/dark" in f_in: im_dark = _medianize(f_in['dark']) else: skipdark = True else: skipflat = True # Nothing to do in this case else: if "/exchange/data_white" in f_in: flat_dset = f_in['/exchange/data_white'] if "/exchange/data_dark" in f_in: im_dark = _medianize(f_in['/exchange/data_dark']) else: skipdark = True else: skipflat = True # Nothing to do in this case # Prepare plan for dynamic flat fielding with 16 repetitions: if not skipflat: EFF, filtEFF = dff_prepare_plan(flat_dset, 16, im_dark) # Read input image: im = tdf.read_sino(dset,idx).astype(float32) f_in.close() # Perform pre-processing (flat fielding, extended FOV, ring removal): if not skipflat: if dynamic_ff: # Dynamic flat fielding with downsampling = 2: im = dynamic_flat_fielding(im, idx, EFF, filtEFF, 2, im_dark, norm_sx, norm_dx) else: im = flat_fielding(im, idx, corrplan, flat_end, half_half, half_half_line, norm_sx, norm_dx) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average) if not skipflat and not dynamic_ff: im = ring_correction (im, ringrem, flat_end, corrplan['skip_flat_after'], half_half, half_half_line, ext_fov) else: im = ring_correction (im, ringrem, False, False, half_half, half_half_line, ext_fov) # Write down reconstructed preview file (file name modified with metadata): im = im.astype(float32) outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( nanmin(im)) + '$' + str( nanmax(im) ) im.tofile(outfile)
def process_gridrec(lock, int_from, int_to, num_sinos, infile, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ringrem, angles, offset, logtransform, param1, circle, scale, pad, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, crop_opt, outprefix, logfilename): """To do... """ # Process the required subset of images: for i in range(int_from, int_to + 1, 2): # Read two sinograms: t0 = time() f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im1 = tdf.read_sino(dset,i).astype(float32) if ( (i + 1) <= (int_to + 1) ): im2 = tdf.read_sino(dset,i + 1).astype(float32) else: im2 = im1 f_in.close() t1 = time() # Perform the preprocessing of the sinograms (if required): if (preprocessing_required): im1 = flat_fielding (im1, i, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32) im1 = extfov_correction (im1, ext_fov, ext_fov_rot_right, ext_fov_overlap) im1 = ring_correction (im1, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov) im2 = flat_fielding (im2, i + 1, corr_plan, flat_end, half_half, half_half_line, norm_sx, norm_dx).astype(float32) im2 = extfov_correction (im2, ext_fov, ext_fov_rot_right, ext_fov_overlap) im2 = ring_correction (im2, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line, ext_fov) # Actual reconstruction: [im1, im2] = reconstruct_gridrec(im1, im2, angles, offset, logtransform, param1, circle, scale, pad, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset) # Appy post-processing (if required): if postprocess_required: im1 = postprocess(im1, convert_opt, crop_opt, circle) im2 = postprocess(im2, convert_opt, crop_opt, circle) else: # Create the circle mask for fancy output: if (circle == True): siz = im1.shape[1] if siz % 2: rang = arange(-siz / 2 + 1, siz / 2 + 1) else: rang = arange(-siz / 2,siz / 2) x,y = meshgrid(rang,rang) z = x ** 2 + y ** 2 a = (z < (siz / 2 - int(round(abs(offset)/downsc_factor)) ) ** 2) im1 = im1 * a im2 = im2 * a # Write down reconstructed slices: t2 = time() fname1 = outpath + outprefix + '_' + str(i).zfill(4) + '.tif' imsave(fname1, im1) fname2 = outpath + outprefix + '_' + str(i + 1).zfill(4) + '.tif' imsave(fname2, im2) t3 = time() # Write log (atomic procedure - lock used): write_log_gridrec(lock, fname1, fname2, logfilename, t2 - t1, (t3 - t2) + (t1 - t0) )
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, outpath, preprocessing_required, corr_plan, norm_sx, norm_dx, flat_end, half_half, half_half_line, ext_fov, ext_fov_rot_right, ext_fov_overlap, ext_fov_normalize, ext_fov_average, ringrem, phaseretrieval_required, phrtmethod, phrt_param1, phrt_param2, energy, distance, pixsize, phrtpad, approx_win, angles, angles_projfrom, angles_projto, offset, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, decim_factor, downsc_factor, corr_offset, postprocess_required, convert_opt, crop_opt, nr_threads, off_from, off_to, logfilename, lock, slice_prefix): """To do... """ slice_nr = sino_idx # Perform reconstruction (on-the-fly preprocessing and phase retrieval, if required): if (phaseretrieval_required): # In this case a bunch of sinograms is loaded into memory: # # Load the temporary data structure reading the input TDF file. # To know the right dimension the first sinogram is pre-processed. # # Open the TDF file and get the dataset: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] # Downscaling and decimation factors considered when determining the approximation window: zrange = arange(sino_idx - approx_win * downsc_factor / 2, sino_idx + approx_win * downsc_factor / 2, downsc_factor) zrange = zrange[(zrange >= 0)] zrange = zrange[(zrange < num_sinos)] approx_win = zrange.shape[0] # Approximation window cannot be odd: if (approx_win % 2 == 1): approx_win = approx_win - 1 zrange = zrange[0:approx_win] # Read one sinogram to get the proper dimensions: test_im = tdf.read_sino(dset, zrange[0] * downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing of the first sinogram to get the right dimension: if (preprocessing_required): test_im = flat_fielding(test_im, zrange[0], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction(test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) # Now we can allocate memory for the bunch of slices: tmp_im = empty((approx_win, test_im.shape[0], test_im.shape[1]), dtype=float32) tmp_im[0, :, :] = test_im # Reading all the the sinos from TDF file and close: for ct in range(1, approx_win): test_im = tdf.read_sino(dset, zrange[ct] * downsc_factor).astype(float32) # Apply projection removal (if required): test_im = test_im[angles_projfrom:angles_projto, :] # Apply decimation and downscaling (if required): test_im = test_im[::decim_factor, ::downsc_factor] # Perform the pre-processing for each sinogram of the bunch: if (preprocessing_required): test_im = flat_fielding(test_im, zrange[ct], corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: test_im = extfov_correction( test_im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average).astype(float32) test_im = ring_correction(test_im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov).astype(float32) tmp_im[ct, :, :] = test_im f_in.close() # Now everything has to refer to a downscaled dataset: sino_idx = ((zrange == sino_idx).nonzero()) # # Perform phase retrieval: # # Prepare the plan: if (phrtmethod == 0): # Paganin's: phrtplan = tiehom_plan(tmp_im[:, 0, :], phrt_param1, phrt_param2, energy, distance, pixsize * downsc_factor, padding=phrtpad) else: phrtplan = phrt_plan(tmp_im[:, 0, :], energy, distance, pixsize * downsc_factor, phrt_param2, phrt_param1, phrtmethod, padding=phrtpad) # Process each projection (whose height depends on the size of the bunch): for ct in range(0, tmp_im.shape[1]): if (phrtmethod == 0): tmp_im[:, ct, :] = tiehom(tmp_im[:, ct, :], phrtplan).astype(float32) else: tmp_im[:, ct, :] = phrt(tmp_im[:, ct, :], phrtplan, phrtmethod).astype(float32) # Extract the requested sinogram: im = tmp_im[sino_idx[0], :, :].squeeze() else: # Read only one sinogram: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] im = tdf.read_sino(dset, sino_idx * downsc_factor).astype(float32) f_in.close() # Apply projection removal (if required): im = im[angles_projfrom:angles_projto, :] # Downscale and decimate the sinogram: im = im[::decim_factor, ::downsc_factor] #sino_idx = sino_idx/downsc_factor # Perform the preprocessing of the sinogram (if required): if (preprocessing_required): im = flat_fielding(im, sino_idx, corr_plan, flat_end, half_half, half_half_line / decim_factor, norm_sx, norm_dx).astype(float32) if ext_fov: im = extfov_correction(im, ext_fov_rot_right, ext_fov_overlap / downsc_factor, ext_fov_normalize, ext_fov_average) im = ring_correction(im, ringrem, flat_end, corr_plan['skip_flat_after'], half_half, half_half_line / decim_factor, ext_fov) # Log infos: log = open(logfilename, "a") log.write( linesep + "\tPerforming reconstruction with multiple centers of rotation...") log.write(linesep + "\t--------------") log.close() # Split the computation into multiple processes: for num in range(nr_threads): start = ((off_to - off_from + 1) / nr_threads) * num + off_from if (num == nr_threads - 1): end = off_to else: end = ((off_to - off_from + 1) / nr_threads) * (num + 1) + off_from - 1 Process(target=reconstruct, args=(im, angles, angles_projfrom, angles_projto, offset / downsc_factor, logtransform, param1, circle, scale, pad, method, zerone_mode, dset_min, dset_max, corr_offset, postprocess_required, convert_opt, crop_opt, start, end, outpath, slice_nr, downsc_factor, logfilename, lock, slice_prefix)).start()
def main(argv): """To do... Usage ----- Parameters --------- Example -------------------------- The following line processes the first ten TIFF files of input path "/home/in" and saves the processed files to "/home/out" with the application of the Boin and Haibel filter with smoothing via a Butterworth filter of order 4 and cutoff frequency 0.01: destripe /home/in /home/out 1 10 1 0.01 4 """ lock = Lock() skip_ringrem = False skip_flat = False skip_flat_after = True first_done = False # Get the number of sino to pre-process: idx = int(argv[0]) # Get paths: infile = argv[1] outfile = argv[2] # Normalization parameters: norm_sx = int(argv[3]) norm_dx = int(argv[4]) # Params for flat fielding with post flats/darks: flat_end = True if argv[5] == "True" else False half_half = True if argv[6] == "True" else False half_half_line = int(argv[7]) # Params for extended FOV: ext_fov = True if argv[8] == "True" else False ext_fov_rot_right = argv[9] if ext_fov_rot_right == "True": ext_fov_rot_right = True if (ext_fov): norm_sx = 0 else: ext_fov_rot_right = False if (ext_fov): norm_dx = 0 ext_fov_overlap = int(argv[10]) # Method and parameters coded into a string: ringrem = argv[11] # Tmp path and log file: tmppath = argv[12] if not tmppath.endswith(sep): tmppath += sep logfilename = argv[13] # Open the HDF5 file: f_in = getHDF5(infile, 'r') if "/tomo" in f_in: dset = f_in['tomo'] else: dset = f_in['exchange/data'] prov_dset = f_in['provenance/detector_output'] num_proj = tdf.get_nr_projs(dset) num_sinos = tdf.get_nr_sinos(dset) # Check if the HDF5 makes sense: if (num_sinos == 0): log = open(logfilename,"a") log.write(linesep + "\tNo projections found. Process will end.") log.close() exit() # Get flat and darks from cache or from file: try: corrplan = cache2plan(infile, tmppath) except Exception as e: #print "Error(s) when reading from cache" corrplan = extract_flatdark(f_in, flat_end, logfilename) plan2cache(corrplan, infile, tmppath) # Read input image: im = tdf.read_sino(dset,idx).astype(float32) f_in.close() # Perform pre-processing (flat fielding, extended FOV, ring removal): im = flat_fielding(im, idx, corrplan, flat_end, half_half, half_half_line, norm_sx, norm_dx) im = extfov_correction(im, ext_fov, ext_fov_rot_right, ext_fov_overlap) im = ring_correction (im, ringrem, flat_end, corrplan['skip_flat_after'], half_half, half_half_line, ext_fov) # Write down reconstructed preview file (file name modified with metadata): im = im.astype(float32) outfile = outfile + '_' + str(im.shape[1]) + 'x' + str(im.shape[0]) + '_' + str( nanmin(im)) + '$' + str( nanmax(im) ) im.tofile(outfile)