Exemplo n.º 1
0
                    vmax=1,
                    cmap=my_cmap,
                    title='Input amplitude')

#################################
# pad data to the original size #
#################################
print("Initial data size:", amp.shape)
if len(original_size) == 0:
    original_size = amp.shape
print("FFT size before accounting for binning", original_size)
original_size = tuple(
    [original_size[index] // binning[index] for index in range(len(binning))])
print("Binning used during phasing:", binning)
print("Padding back to original FFT size", original_size, '\n')
amp = pu.crop_pad(array=amp, output_shape=original_size)
nz, ny, nx = amp.shape

##########################################################
# calculate q for later regridding in the detector frame #
##########################################################
kin = 2 * np.pi / setup.wavelength * beam_direction  # in laboratory frame z downstream, y vertical, x outboard
kout = setup.exit_wavevector(
)  # in laboratory frame z downstream, y vertical, x outboard
q = kout - kin
Qnorm = np.linalg.norm(q)
q = q / Qnorm
Qnorm = Qnorm * 1e-10  # switch to angstroms
planar_dist = 2 * np.pi / Qnorm  # Qnorm should be in angstroms
print("Wavevector transfer [z, y, x]:", q * Qnorm)
print("Wavevector transfer: (angstroms)", str('{:.4f}'.format(Qnorm)))
Exemplo n.º 2
0
##################################################
# pad arrays to obtain the desired field of view #
##################################################
z_pixel_FOV = int(np.rint((field_of_view[0] / voxel_size) /
                          2))  # half-number of pixels corresponding to the FOV
y_pixel_FOV = int(np.rint((field_of_view[1] / voxel_size) /
                          2))  # half-number of pixels corresponding to the FOV
x_pixel_FOV = int(np.rint((field_of_view[2] / voxel_size) /
                          2))  # half-number of pixels corresponding to the FOV
new_shape = [
    max(numz, 2 * z_pixel_FOV),
    max(numy, 2 * y_pixel_FOV),
    max(numx, 2 * x_pixel_FOV)
]
amp = pu.crop_pad(array=amp, output_shape=new_shape, debugging=False)
phase = pu.crop_pad(array=phase, output_shape=new_shape, debugging=False)
strain = pu.crop_pad(array=strain, output_shape=new_shape, debugging=False)
numz, numy, numx = amp.shape
print("Cropped/padded data size: (", numz, ',', numy, ',', numx, ')')

##########################################################
# set the strain and phase to NAN outside of the support #
##########################################################
support = np.zeros((numz, numy, numx))
support[np.nonzero(amp)] = 1

strain[support == 0] = np.nan
phase[support == 0] = np.nan

############################################
Exemplo n.º 3
0
#############################
file_path = filedialog.askopenfilename(initialdir=detector.savedir, title="Select reconstructions (prtf)",
                                       filetypes=[("NPZ", "*.npz"), ("NPY", "*.npy"),
                                                  ("CXI", "*.cxi"), ("HDF5", "*.h5")])

obj, extension = util.load_file(file_path)
print('Opening ', file_path)

if extension == '.h5':
    comment = comment + '_mode'

# check if the shape of the real space object is the same as the measured diffraction pattern
# the real space object may have been further cropped to a tight support, to save memory space.
if obj.shape != diff_pattern.shape:
    print('Reconstructed object shape = ', obj.shape, 'different from the experimental diffraction pattern: crop/pad')
    obj = pu.crop_pad(array=obj, output_shape=diff_pattern.shape, debugging=False)

# calculate the retrieved diffraction amplitude
phased_fft = fftshift(fftn(obj)) / (np.sqrt(numz)*np.sqrt(numy)*np.sqrt(numx))  # complex amplitude
del obj
gc.collect()

if debug:
    plt.figure()
    plt.imshow(np.log10(abs(phased_fft).sum(axis=0)), cmap=my_cmap, vmin=0, vmax=3.5)
    plt.colorbar()
    plt.title('abs(retrieved amplitude).sum(axis=0) before alignment')
    plt.pause(0.1)

if align_pattern:
    # align the reconstruction with the initial diffraction data
Exemplo n.º 4
0
obj, extension = util.load_file(file_path[0])
# obj[0:40,:,:] = 0
# obj[65:,:,:] = 0
if extension == '.h5':
    comment = comment + '_mode'

nz, ny, nx = obj.shape
print("Initial data size: (", nz, ',', ny, ',', nx, ')')
if len(original_size) == 0:
    original_size = obj.shape
print("FFT size before accounting for binning", original_size)
original_size = tuple([original_size[index] // binning[index] for index in range(len(binning))])
print("Binning used during phasing:", binning)
print("Padding back to original FFT size", original_size)
obj = pu.crop_pad(array=obj, output_shape=original_size)
nz, ny, nx = obj.shape

###########################################################################
# define range for orthogonalization and plotting - speed up calculations #
###########################################################################
zrange, yrange, xrange =\
    pu.find_datarange(array=obj, plot_margin=plot_margin, amplitude_threshold=0.1, keep_size=keep_size)

numz = zrange * 2
numy = yrange * 2
numx = xrange * 2
print("Data shape used for orthogonalization and plotting: (", numz, ',', numy, ',', numx, ')')

####################################################################################
# find the best reconstruction from the list, based on mean amplitude and variance #
Exemplo n.º 5
0
file_path = filedialog.askopenfilename(initialdir=datadir,
                                       title="Select 3D data",
                                       filetypes=[("NPZ", "*.npz")])
data, _ = util.load_file(file_path)
nbz, nby, nbx = data.shape
print('data shape:', data.shape)

if crop_shape:
    assert len(
        crop_shape) == 3, 'crop should be a sequence of 3 voxels numbers'
    assert np.all(np.asarray(origin) - np.asarray(crop_shape) // 2 >= 0
                  ), 'origin incompatible with crop_shape'
    assert origin[0] + crop_shape[0] // 2 <= nbz and origin[1] + crop_shape[1] // 2 <= nby \
           and origin[2] + crop_shape[2] // 2 <= nbx, 'origin incompatible with crop_shape'

    data = pu.crop_pad(array=data, output_shape=crop_shape, crop_center=origin)
    gc.collect()
    nbz, nby, nbx = data.shape
    print('data shape after cropping:', data.shape)
    # calculate the new position of origin
    new_origin = (crop_shape[0] // 2, crop_shape[1] // 2, crop_shape[2] // 2)
else:
    new_origin = origin

if plots:
    gu.multislices_plot(data,
                        sum_frames=True,
                        scale='log',
                        plot_colorbar=True,
                        title='S' + str(scan) + '\n Data before rotation',
                        vmin=0,
Exemplo n.º 6
0
    print('Rocking curve ', idx + 1, ': Pearson correlation coefficient = ',
          str('{:.2f}'.format(correlation)))
    corr_coeff.append(str('{:.2f}'.format(correlation)))

    if correlation >= correlation_threshold:
        scanlist.append(scan_list[idx])
        sumdata = sumdata + data
        summask = summask + mask
    else:
        print('Scan ', scan_list[idx],
              ', correlation below threshold, skip concatenation')

summask[np.nonzero(summask)] = 1  # mask should be 0 or 1
sumdata = sumdata / len(scanlist)

summask = pu.crop_pad(array=summask, output_shape=output_shape)
sumdata = pu.crop_pad(array=sumdata, output_shape=output_shape)

savedir = homedir + sample_name + 'sum_S' + str(scanlist[0]) + '_to_S' + str(
    scanlist[-1]) + '/'
template = '_S'+str(scanlist[0]) + '_to_S' + str(scanlist[-1]) + '_' +\
           str(output_shape[0]) + '_' + str(output_shape[1]) + '_' + str(output_shape[2]) + '.npz'

pathlib.Path(savedir).mkdir(parents=True, exist_ok=True)
np.savez_compressed(savedir + 'pynx' + template, obj=sumdata)
np.savez_compressed(savedir + 'maskpynx' + template, obj=summask)
print('Sum of ', len(scanlist), 'scans')

fig, _, _ = gu.multislices_plot(sumdata,
                                sum_frames=True,
                                scale='log',
Exemplo n.º 7
0
            pixel_y=pixel_y)
        newvoxelsize_z, newvoxelsize_y, newvoxelsize_x = setup.voxel_sizes(
            unbinned_shape,
            tilt_angle=tilt_angle,
            pixel_x=pixel_x,
            pixel_y=pixel_y)

    print('Original voxel sizes zyx (nm):', str('{:.2f}'.format(voxelsize_z)),
          str('{:.2f}'.format(voxelsize_y)), str('{:.2f}'.format(voxelsize_x)))
    print('Output voxel sizes zyx (nm):', str('{:.2f}'.format(newvoxelsize_z)),
          str('{:.2f}'.format(newvoxelsize_y)),
          str('{:.2f}'.format(newvoxelsize_x)))

    # Interpolate the support
    print('\nInterpolating the support...')
    data = pu.crop_pad(
        data, pynx_shape)  # the data could be cropped near the support
    fig, _, _ = gu.multislices_plot(data,
                                    sum_frames=True,
                                    scale='linear',
                                    plot_colorbar=True,
                                    vmin=0,
                                    title='Support before interpolation\n',
                                    is_orthogonal=True,
                                    reciprocal_space=False)

    rgi = RegularGridInterpolator(
        (np.arange(-pynx_shape[0] // 2, pynx_shape[0] // 2, 1) * voxelsize_z,
         np.arange(-pynx_shape[1] // 2, pynx_shape[1] // 2, 1) * voxelsize_y,
         np.arange(-pynx_shape[2] // 2, pynx_shape[2] // 2, 1) * voxelsize_x),
        data,
        method='linear',
Exemplo n.º 8
0
numz, numy, numx = amp.shape
print("Initial data size: (", numz, ',', numy, ',', numx, ')')

#############################
#  pad arrays to obtain the desired field of view
#############################
pixel_spacing = tick_spacing / voxel_size
pixel_FOV = int(np.rint((field_of_view / voxel_size) /
                        2))  # half-number of pixels corresponding to the FOV
new_shape = [
    max(numz, 2 * pixel_FOV),
    max(numy, 2 * pixel_FOV),
    max(numx, 2 * pixel_FOV)
]
support = pu.crop_pad(array=support, output_shape=new_shape, debugging=False)
strain = pu.crop_pad(array=strain, output_shape=new_shape, debugging=False)
phase = pu.crop_pad(array=phase, output_shape=new_shape, debugging=False)
amp = pu.crop_pad(array=amp, output_shape=new_shape, debugging=False)
bulk = pu.crop_pad(array=bulk, output_shape=new_shape, debugging=False)
numz, numy, numx = amp.shape
print("Cropped/padded data size: (", numz, ',', numy, ',', numx, ')')

#############################
# center arrays based on the support
#############################
zcom, ycom, xcom = center_of_mass(support)
zcom, ycom, xcom = [int(np.rint(zcom)), int(np.rint(ycom)), int(np.rint(xcom))]
support = np.roll(support,
                  (numz // 2 - zcom, numy // 2 - ycom, numx // 2 - xcom),
                  axis=(0, 1, 2))
Exemplo n.º 9
0
        amp = amp * np.exp(1j * phase)  # amp is the complex amplitude
        del phase
        gc.collect()
    else:
        comment = comment + "_support"

    gu.multislices_plot(abs(amp),
                        sum_frames=False,
                        reciprocal_space=False,
                        is_orthogonal=True,
                        title='abs(amp)')

    ####################################################
    # pad array to improve reciprocal space resolution #
    ####################################################
    amp = pu.crop_pad(amp, (nz1, ny1, nx1))
    nz, ny, nx = amp.shape
    print('CDI data shape after padding', amp.shape)

    ####################################################
    # interpolate the array with isotropic voxel sizes #
    ####################################################
    if len(voxel_size) == 0:
        print('Using isotropic voxel size of 1 nm')
        voxel_size = [1, 1, 1]  # nm

    if not all(voxsize == voxel_size[0] for voxsize in voxel_size):
        newvoxelsize = min(voxel_size)  # nm
        # size of the original object
        rgi = RegularGridInterpolator(
            (np.arange(-nz // 2, nz // 2, 1) * voxel_size[0],
Exemplo n.º 10
0
                                                  ("HDF5", "*.h5")])
obj, _ = util.load_file(file_path)

if obj.ndim != 3:
    print('a 3D reconstruction array is expected')
    sys.exit()

obj = abs(obj)
numz, numy, numx = obj.shape
print("Initial data size: (", numz, ',', numy, ',', numx, ')')

#############################
# rotate the reconstruction #
#############################
new_shape = [int(1.2 * numz), int(1.2 * numy), int(1.2 * numx)]
obj = pu.crop_pad(array=obj, output_shape=new_shape, debugging=False)
numz, numy, numx = obj.shape

print("Cropped/padded data size before rotating: (", numz, ',', numy, ',',
      numx, ')')
print('Rotating object to have the crystallographic axes along array axes')
obj = pu.rotate_crystal(array=obj,
                        axis_to_align=axis_outofplane,
                        reference_axis=np.array([0, 1, 0]),
                        debugging=True)  # out of plane alignement
obj = pu.rotate_crystal(array=obj,
                        axis_to_align=axis_inplane,
                        reference_axis=np.array([1, 0, 0]),
                        debugging=True)  # inplane alignement

#################################################
Exemplo n.º 11
0
    plt.close(fig)

data = data / data.max()  # normalize
data[data < support_threshold] = 0
if binary_support:
    data[np.nonzero(data)] = 1  # change data into a support
############################################
# go back to original shape before binning #
############################################
if reload_support:
    binned_shape = [int(output_shape[idx] / binning_output[idx]) for idx in range(0, len(binning_output))]
else:
    binned_shape = [int(original_shape[idx] * binning_original[idx]) for idx in range(0, len(binning_original))]
nz, ny, nx = binned_shape

data = pu.crop_pad(data, binned_shape)
print('Data shape after considering original binning and shape:', data.shape)

######################
# center the support #
######################
if center:
    data = pu.center_com(data)
# Use user-defined roll when the center by COM is not optimal
data = np.roll(data, roll_centering, axis=(0, 1, 2))

#################################
# rescale the support if needed #
#################################
nbz, nby, nbx = output_shape
if ((nbz != nz) or (nby != ny) or (nbx != nx)) and not reload_support:
        f"({new_voxelsizes[0]:.2f} nm, {new_voxelsizes[1]:.2f} nm, {new_voxelsizes[2]:.2f} nm)"
    )
    obj = pu.regrid(array=obj,
                    old_voxelsize=voxel_sizes,
                    new_voxelsize=new_voxelsizes)

#######################################
# pad the object to the desired shape #
#######################################
if qvalues_shape != padding_shape:
    print(
        f'\nThe shape defined by q_values {qvalues_shape} is different from padding_shape {padding_shape}'
    )
    print(f"Overriding padding_shape with {qvalues_shape}")
    padding_shape = qvalues_shape
obj = pu.crop_pad(array=obj, output_shape=padding_shape, debugging=debug)

#####################################
# calculate the diffraction pattern #
#####################################
data = fftshift(fftn(obj)) / np.sqrt(reduce(
    lambda x, y: x * y, padding_shape))  # complex diffraction amplitude
data = abs(np.multiply(data, np.conjugate(data)))  # diffraction intensity

zcom, ycom, xcom = com = tuple(
    map(lambda x: int(np.rint(x)), center_of_mass(data)))
print('Center of mass of the diffraction pattern at pixel:', zcom, ycom, xcom)
print(f"\nintensity in a ROI of 7x7x7 voxels centered on the COM:"
      f" {int(data[zcom-3:zcom+4, ycom-3:ycom+4, xcom-3:xcom+4].sum())}")

if peak_value is not None:
Exemplo n.º 13
0
print('Loading ', nbfiles, 'objects')
if nbfiles == 1:
    print('More than one array is needed.')
    sys.exit()

##################################################################
# align objects against the first one and stack it in a 4D array #
##################################################################
obj0, _ = util.load_file(file_path[0])
ndim = obj0.ndim
if ndim != 3:
    print('3D objects are expected')
    sys.exit()

nz, ny, nx = obj0.shape
obj0 = pu.crop_pad(array=obj0, output_shape=(nz+10, ny+10, nx+10))
nz, ny, nx = obj0.shape
print('Array shape', obj0.shape)

amp0 = abs(obj0)
sum0 = amp0.sum()
phase0 = np.angle(obj0)
if alignment_method in ['modulus', 'skip']:
    piz0, piy0, pix0 = center_of_mass(amp0)
else:  # 'support'
    support = np.zeros(amp0.shape)
    support[amp0 > support_threshold * amp0.max()] = 1
    piz0, piy0, pix0 = center_of_mass(support)

piz0, piy0, pix0 = int(piz0), int(piy0), int(pix0)
phase0 = phase0 - phase0[piz0, piy0, pix0]  # set the phase to 0 at the COM of the support
Exemplo n.º 14
0
file_path = filedialog.askopenfilenames(initialdir=datadir,
                                        filetypes=[("NPZ", "*.npz"),
                                                   ("NPY", "*.npy"),
                                                   ("CXI", "*.cxi"),
                                                   ("HDF5", "*.h5")])
nbfiles = len(file_path)
print(nbfiles, 'files selected')
#################################################################
# loop through files and calculate the correlation coefficients #
#################################################################
correlation = np.zeros((nbfiles, nbfiles))
for raw in range(nbfiles):
    reference_obj, _ = util.load_file(file_path[raw])
    reference_obj = abs(reference_obj) / abs(reference_obj).max()
    nbz, nby, nbx = reference_obj.shape
    reference_obj = pu.crop_pad(array=reference_obj,
                                output_shape=[nbz + 10, nby + 10, nbx + 10])
    correlation[raw, raw] = 1
    for col in range(raw + 1, nbfiles):
        test_obj, _ = util.load_file(file_path[col])  # which index?
        test_obj = abs(test_obj) / abs(test_obj).max()
        test_obj = pu.crop_pad(array=test_obj,
                               output_shape=[nbz + 10, nby + 10, nbx + 10])
        # align reconstructions
        shiftz, shifty, shiftx = reg.getimageregistration(abs(reference_obj),
                                                          abs(test_obj),
                                                          precision=100)
        test_obj = reg.subpixel_shift(test_obj, shiftz, shifty, shiftx)
        print('\nReference =', raw, '  Test =', col)
        print('z shift', str('{:.2f}'.format(shiftz)), ', y shift',
              str('{:.2f}'.format(shifty)), ', x shift',
              str('{:.2f}'.format(shiftx)))
Exemplo n.º 15
0
    obj, extension = util.load_file(file_path)
    obj = abs(obj)
    obj = obj / obj.max()
    if extension == '.h5':
        comment = comment + '_mode'
else:
    file_path = filedialog.askopenfilename(initialdir=datadir, title="Select the reconstructed object",
                                           filetypes=[("NPZ", "*.npz")])
    obj = np.load(file_path)[field_name]
nbz, nby, nbx = obj.shape

#################
# rotate object #
#################
new_shape = [int(1.2*nbz), int(1.2*nby), int(1.2*nbx)]
obj = pu.crop_pad(array=obj, output_shape=new_shape, debugging=False)
nbz, nby, nbx = obj.shape

print("Cropped/padded object size before rotating: (", nbz, ',', nby, ',', nbx, ')')
print('Rotating object to have the crystallographic axes along array axes')
axis_to_align = np.array([0.2, 1, 0.02])  # in order x y z for rotate_crystal()
obj = pu.rotate_crystal(array=obj, axis_to_align=axis_to_align, reference_axis=np.array([0, 1, 0]),
                        debugging=True)  # out of plane alignement
axis_to_align = np.array([1, 0, -0.1])  # in order x y z for rotate_crystal()
obj = pu.rotate_crystal(array=obj, axis_to_align=axis_to_align, reference_axis=np.array([1, 0, 0]),
                        debugging=True)  # inplane alignement

###################
# apply threshold #
###################
if not np.isnan(threshold):
Exemplo n.º 16
0
        and crop_center[2]+output_shape[2]//2 <= nbx, 'crop_center incompatible with output_shape'

corr_roi = corr_roi or [0, nbz, 0, nby, 0, nbx
                        ]  # if None, use the full array for corr_roi

assert len(corr_roi) == 6, 'corr_roi should be a tuple or list of lenght 6'
if not 0 <= corr_roi[0] < corr_roi[1] <= nbz\
        or not 0 <= corr_roi[2] < corr_roi[3] <= nby\
        or not 0 <= corr_roi[4] < corr_roi[5] <= nbx:
    print('Incorrect value for the parameter corr_roi')
    sys.exit()

# crop the data directly to output_shape if no alignment is required, update corr_roi accordingly
if alignement_method == 'skip':
    refmask = pu.crop_pad(array=refmask,
                          output_shape=output_shape,
                          crop_center=crop_center)
    refdata = pu.crop_pad(array=refdata,
                          output_shape=output_shape,
                          crop_center=crop_center)
    # correct for the offset due to cropping
    corr_roi = [
        corr_roi[0] - (crop_center[0] - output_shape[0] // 2),
        corr_roi[1] - (crop_center[0] - output_shape[0] // 2),
        corr_roi[2] - (crop_center[1] - output_shape[1] // 2),
        corr_roi[3] - (crop_center[1] - output_shape[1] // 2),
        corr_roi[4] - (crop_center[2] - output_shape[2] // 2),
        corr_roi[5] - (crop_center[2] - output_shape[2] // 2)
    ]
    # check if this still fits the cropped data, default to the data range otherwise
    corr_roi[0] = max(0, corr_roi[0])