ImageD11.sinograms package

Submodules

ImageD11.sinograms.assemble_label module

ImageD11.sinograms.assemble_label.filterpixels(cutimage, row, col, intensity, nnz)

cutimage = 2D image of thresholds to use row, col, intensity = pixels nnz = pixels per frame for a stack of images in row/col/intensity

ImageD11.sinograms.assemble_label.getsparse(dsobj, num)

dsobj = DataSet object returns the pixels from the sparse segmentation

ImageD11.sinograms.assemble_label.harvest_masterfile(dset, outname, scanmotors=('diffrz', 'diffrz_cen360', 'diffrz_center', 'fpico4', 'fpico3', 'diffty', 'diffty_center', 'rot', 'rot_cen360', 'rot_center', 'fpico6', 'dty', 'dty_center'), headermotors=('diffty', 'diffrz', 'samtx', 'samty', 'samtz', 'diffry', 'samrx', 'samry', 'dty', 'rot', 'pz', 'px', 'py', 'shtz', 'shty', 'shtx'), cutimage=None)

dset = ImageD11.sinograms.dataset.DataSet object outname = sparse file to write

cut = image = 2D image of cutoffs for keeping pixels (e.g. keep high angle

and use a higher threshold for low angle or noisy)

ImageD11.sinograms.assemble_label.main(dsname, outname=None, cutimage=None)

dsname = Dataset describing the masterfile + segmentation etc outname = sparse pixels file to write. Defaults to dset.sparsefile

ImageD11.sinograms.assemble_label.testready(dsobj)

assume they are finish if they exist. Might be still writing ???

ImageD11.sinograms.dataset module

class ImageD11.sinograms.dataset.DataSet(dataroot='.', analysisroot='.', sample='sample', dset='dataset', detector='eiger', omegamotor='rot_center', dtymotor='dty', filename=None, analysispath=None)

Bases: object

One DataSet instance per detector!

ATTRNAMES = ('dataroot', 'analysisroot', 'sample', 'dset', 'shape', 'dsname', 'datapath', 'analysispath', 'masterfile', 'limapath', 'detector', 'omegamotor', 'dtymotor', 'monitorname', 'pksfile', 'sparsefile', 'parfile', 'e2dxfile', 'e2dyfile', 'splinefile', 'maskfile', 'bgfile', 'pksfile', 'col4dfile', 'col3dfile', 'col2dfile', 'grainsfile', 'sparsefile', 'icolfile', 'pbpfile')
NDNAMES = ('omega', 'dty', 'nnz', 'frames_per_file', 'nlm', 'frames_per_scan', 'monitor')
STRINGLISTS = ('scans', 'imagefiles', 'sparsefiles')
check_files(path, filenames, verbose=0)

See whether files are created or not

check_images()

Is the experiment finished ?

check_sparse()

Has the segmentation been done ?

compare(other)

Try to see if the load/save is working

correct_bins_for_half_scan(y0=0)

Pads the dataset to become bigger and symmetric

get_cf_2d()
get_cf_2d_from_disk()
get_cf_3d_from_disk()
get_cf_4d()
get_cf_4d_from_disk()
get_colfile_from_peaks_dict(peaks_dict=None)

Converts a dictionary of peaks (peaks_dict) into an ImageD11 columnfile adds on the geometric computations (tth, eta, gvector, etc) Uses self.pk2d if no peaks_dict provided

get_grains_from_disk(phase_name=None)
get_monitor(name='fpico6')
get_monitor_pk2d(pk2d, name='fpico6')

To be used to normalise the peaks 2d

get_phases_from_disk()
get_ring_current_per_scan()

Gets the ring current for each scan (i.e rotation/y-step) Stores it inside self.ring_currents_per_scan and a scaled version inside self.ring_currents_per_scan_scaled

guess_detector()

Guess which detector we are using from the masterfile

guess_shape()

Guess the shape if it was not given

guessbins()
import_all(scans=None, shape=None)
import_from_sparse(hname, scans=None, shape=None)

hname = hdf5 file containing sparse pixels (and motors) dataset = a dataset instance to import into scans = defaults to reading all “%d.1” scans in the file

give a list to read in some other order or a subset

import_imagefiles()

Get the Lima file names from the bliss master file, also scan_npoints

import_motors_from_master()

read the motors from the lima file you need to import the imagefiles first these will be the motor positions to accompany the images # could also get these from sparse files if saved

import_nnz()

Read the nnz arrays from the sparsefiles

import_nnz_from_sparse()

Read the nnz arrays from the sparsefiles

import_scans(scans=None, hname=None)

Reads in the scans from the bliss master file

load(h5name=None, h5group='/')
property peaks_table
property pk2d
property pk4d
report()
save(h5name=None, h5group='/')
save_grains_to_disk(grains, phase_name=None)
sinohist(weights=None, omega=None, dty=None, method='fast')

Bin some data onto the sinogram histogram

update_colfile_pars(cf, phase_name=None)

Load parameters and update geometry for colfile

update_paths(force=False, verbose=False)
ImageD11.sinograms.dataset.check(dataroot, analysisroot, sample, dset, destination, scans=None)
ImageD11.sinograms.dataset.guess_chunks(name, shape)
ImageD11.sinograms.dataset.load(h5name, h5group='/')

ImageD11.sinograms.geometry module

Sinogram-related geometric functions pulled from various places. The choice of reference frames is tricky. In regular 3DXRD, the origin of the lab reference frame is defined as the intersection between the middle of the beam and the rotation axis. However, because the rotation axis is moving, this gets more difficult for scanning 3DXRD. I have therefore defined the reference frames in the following way:

  1. Static lab frame - vectors defined by the beam vector and the dty translation axis vector. Its origin is defined directly as (0,0,0): x: The intersection of the beam vector and the dty translation axis vector y: The centre of the beam horizontally z: The centre of the beam vertically dtyi is a discretisation of the dty motor values.

  2. Sample frame Origin is the rotation axis The rotation axis is translated by dty. The sample frame rotates with omega This translates with dty and rotates with omega, CW about the rotation axis (looking top down). This has the rotation axis at its origin. y0 is the true value of dty when the rotation axis intersects the beam.

  3. Step space This is simply an integer discretisation of the sample frame.

  4. Reconstruction space: units are (ystep), origin in corner (matches iradon output) when plotted with origin=”lower”, coords are (ri, rj)

Diagrams are below, S indicates the rotation axis

lab frame:

x

<——- O (0, 0) centre of beam

y

sample frame (could be rotated about omega then translated along lab y by dty):

x

<——- S (0, 0)

y

Step space:

+ve ^ |

i |

-ve <——– S (0, 0)——–> +ve
j


v

-ve

Reconstruction space (iradon output when plotted with origin=”lower”):

i | S

(0, 0) ——->

j

ImageD11.sinograms.geometry.dty_to_dtyi(dty, ystep, ymin)

We take continuous dty space and discretise it We do this by counting the number of ysteps away from ymin ymin should probably be ds.ymin This should be equivalent to determining the closest bin in ds.ybincens But this is neater as it accounts for values outside the ds.ybincens range

dtyi = (dty - ymin) / ystep

ImageD11.sinograms.geometry.dty_values_grain_in_beam(sx, sy, y0, omega)

Calls dty_values_grain_in_beam_sincos after converting omega (degrees) into sinomega, cosomega

ImageD11.sinograms.geometry.dty_values_grain_in_beam_sincos(sx, sy, y0, sinomega, cosomega)

Take a grain positioned at (sx, sy) in the sample reference frame Determine the dty values needed to bring the grain into the beam as you rotate by omega. Equivalently, solve the sample<->lab conversion where ly = 0 (grain is in-beam). From sample_to_lab_sincos:

sxr = sx * cosomega - sy * sinomega syr = sx * sinomega + sy * cosomega

lx = sxr ly = syr + dty - y0

Therefore: ly = sx * sinomega + sy * cosomega + dty - y0

Solving for ly = 0: 0 = sx * sinomega + sy * cosomega + dty - y0 dty = y0 - sx * sinomega - sy * cosomega

ImageD11.sinograms.geometry.dtyi_to_dty(dtyi, ystep, ymin)

Simply: dty = (dtyi * ystep) + ymin

ImageD11.sinograms.geometry.dtyimask_from_recon(ri, rj, omega, dtyi, y0, ystep, ymin, recon_shape)

Given a position in recon space (ri, rj) and arrays of (omega, dtyi) values Convert recon space (ri, rj) to sample space (sx, sy) Mask each (omega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.dtyimask_from_recon_sincos(ri, rj, sinomega, cosomega, dtyi, y0, ystep, ymin, recon_shape)

Given a position in recon space (ri, rj) and arrays of (sinomega, cosomega, dtyi) values Convert recon space (ri, rj) to sample space (sx, sy) Mask each (sinomega, cosomega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.dtyimask_from_sample(sx, sy, omega, dtyi, y0, ystep, ymin)

Given a position in the sample (sx, sy) and arrays of (omega, dtyi) values Mask each (omega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.dtyimask_from_sample_sincos(sx, sy, sinomega, cosomega, dtyi, y0, ystep, ymin)

Given a position in the sample (sx, sy) and arrays of (sinomega, cosomega, dtyi) values Mask each (sinomega, cosomega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.dtyimask_from_step(si, sj, omega, dtyi, y0, ystep, ymin)

Given a position in step space (si, sj) and arrays of (omega, dtyi) values Convert step space (si, sj) to sample space (sx, sy) Mask each (omega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.dtyimask_from_step_sincos(si, sj, sinomega, cosomega, dtyi, y0, ystep, ymin)

Given a position in step space (si, sj) and arrays of (sinomega, cosomega, dtyi) values Convert step space (si, sj) to sample space (sx, sy) Mask each (sinomega, cosomega, dtyi) value if they put the position (sx, sy) into the beam

ImageD11.sinograms.geometry.fit_sample_position_from_recon(recon, ystep)

Fits grain position in sample space by doing a LoG search with skimage on the reconstruction image Useful if grain is very small (close to pointlike) Returns position in sample frame (unit matches ystep) Returns None if we couldn’t find any blobs

ImageD11.sinograms.geometry.fit_sine_wave(omega, dty, initial_guess, weights=None)

Take a series of (omega, dty) values that originate from the same point in the sample. Determine the point in sample coordinates (sx, sy) by fitting a sine wave to the data. Includes a possible shift of the rotation axis in y (y0). In practice, we perform a curve_fit on dty_values_grain_in_beam to determine sx, sy, y0

ImageD11.sinograms.geometry.lab_to_recon(lx, ly, y0, dty, omega, recon_shape, ystep)

Converts lab space (lx, ly) to recon space (ri, rj)

ImageD11.sinograms.geometry.lab_to_sample(lx, ly, y0, dty, omega)

Calls lab_to_sample_sincos after converting omega (degrees) into sinomega, cosomega

ImageD11.sinograms.geometry.lab_to_sample_sincos(lx, ly, y0, dty, sinomega, cosomega)

Converts position in lab frame (lx, ly) to position in lab frame (sx, sy). The units of sx, sy, y0, and dty must agree.

Parameters:
  • lx ((float, np.ndarray)) – X-coordinate in lab reference frame

  • ly ((float, np.ndarray)) – Y-coordinate in lab reference frame

  • y0 (float) – the true value of dty when the rotation axis intersects the beam

  • dty ((float, np.ndarray)) – the dty motor underneath the rotation axis

  • sinomega ((float, np.ndarray)) – the sine of the omega value of the rotation axis

  • cosomega ((float, np.ndarray)) – the cosine of the omega value of the rotation axis

Returns:

sx, su: the x and y coordinates in the sample reference frame

Return type:

((float, np.ndarray), (float, np.ndarray))

ImageD11.sinograms.geometry.lab_to_step(lx, ly, y0, dty, omega, ystep)

Converts lab space (lx, ly) to step space (si, sj)

ImageD11.sinograms.geometry.recon_omega_to_dty(ri, rj, omega, y0, recon_shape, ystep)

Convert recon space (ri, rj) to step space (si, sj) Then get corresponding dty values which puts (si, sj) into the beam given omega

ImageD11.sinograms.geometry.recon_omega_to_dtyi(ri, rj, omega, y0, recon_shape, ystep, ymin)

Convert recon space (ri, rj) to step space (si, sj) Then get corresponding dtyi values which puts (si, sj) into the beam given omega Then converts dty to dtyi

ImageD11.sinograms.geometry.recon_to_lab(ri, rj, y0, dty, omega, recon_shape, ystep)

Converts recon space (ri, rj) to lab space (lx, ly)

ImageD11.sinograms.geometry.recon_to_sample(ri, rj, recon_shape, ystep)

Converts reconstruction space (ri, rj) to sample space (sx, sy)

ImageD11.sinograms.geometry.recon_to_step(ri, rj, recon_shape)

Converts reconstruction space (ri, rj) to step space (si, sj)

ImageD11.sinograms.geometry.sample_to_lab(sx, sy, y0, dty, omega)

Calls sample_to_lab_sincos after converting omega (degrees) into sinomega, cosomega

ImageD11.sinograms.geometry.sample_to_lab_sincos(sx, sy, y0, dty, sinomega, cosomega)

Converts position in sample frame (sx, sy) to position in lab frame (lx, ly). The units of sx, sy, y0, and dty must agree.

Parameters:
  • sx ((float, np.ndarray)) – X-coordinate in sample reference frame

  • sy ((float, np.ndarray)) – Y-coordinate in sample reference frame

  • y0 (float) – the true value of dty when the rotation axis intersects the beam

  • dty ((float, np.ndarray)) – the dty motor underneath the rotation axis

  • sinomega ((float, np.ndarray)) – the sine of the omega value of the rotation axis

  • cosomega ((float, np.ndarray)) – the cosine of the omega value of the rotation axis

Returns:

lx, ly: the x and y coordinates in the lab reference frame

Return type:

((float, np.ndarray), (float, np.ndarray))

ImageD11.sinograms.geometry.sample_to_recon(sx, sy, recon_shape, ystep)

Converts sample space (sx, sy) to reconstruction space (ri, rj)

ImageD11.sinograms.geometry.sample_to_step(sx, sy, ystep)

Converts sample (sx, sy) position to step space (si, sj)

ImageD11.sinograms.geometry.sino_shift_and_pad(y0, ny, ymin, ystep)

Determine the difference in sinogram pixels between the central dtyi value of the sinogram and the dtyi value of the rotation axis (from y0) To do this, we convert y0 into dtyi without rounding Also determine the minimum pad to get the whole sample in the frame Which should be double the shift

ImageD11.sinograms.geometry.step_grid_from_ybincens(ybincens, step_size, gridstep, y0)

Produce a grid in (si, sj) step space to reconstruct on. Constructs a symmetric grid with the origin on y0 Therefore the step space is truly aligned to the rotation axis. The size of the grid is determined by the extremes of ybincens. The grid will always be symmetric such that (0, 0) is the centre of an image formed from the grid :param ybincens: An evenly sampled dty space :type ybincens: np.ndarray :param step_size: the step size of the grid (same units as ybincens and y0) :type step_size: float :param gridstep: the sampling resolution of the grid (e.g 2 = [0, 2, 4, 6, …]) :type gridstep: int :return: (si, sj) for si in ints for sj in ints :rtype: tuple(int, int)

ImageD11.sinograms.geometry.step_omega_to_dty(si, sj, omega, y0, ystep)

Convert step space (si, sj) to sample space (sx, sy) Then get corresponding dty values which puts (sx, sy) into the beam given omega

ImageD11.sinograms.geometry.step_omega_to_dtyi(si, sj, omega, y0, ystep, ymin)

Convert step space (si, sj) to sample space (sx, sy) Then get corresponding dty values which puts (sx, sy) into the beam given omega Then converts dty to dtyi

ImageD11.sinograms.geometry.step_to_lab(si, sj, y0, dty, omega, ystep)

Converts step space (si, sj) to lab space (lx, ly)

ImageD11.sinograms.geometry.step_to_recon(si, sj, recon_shape)

Converts step space (si, sj) to reconstruction space (ri, rj)

ImageD11.sinograms.geometry.step_to_sample(si, sj, ystep)

Converts step space (si, sj) to sample position (sx, sy)

ImageD11.sinograms.geometry.sx_sy_y0_from_dty_omega(dty, omega, weights=None)

Fits sine wave to dty vs omega plot, extracts sx, sy, y0

ImageD11.sinograms.lima_segmenter module

class ImageD11.sinograms.lima_segmenter.SegmenterOptions(cut=1, howmany=100000, pixels_in_spot=3, maskfile='', bgfile='', cores_per_job=1, files_per_core=8)

Bases: object

datasetnames = ('limapath', 'analysispath', 'datapath', 'imagefiles', 'sparsefiles')
jobnames = ('cut', 'howmany', 'pixels_in_spot', 'maskfile', 'bgfile', 'cores_per_job', 'files_per_core')
load(h5name, h5group)
save(h5name, h5group)
setup()
ImageD11.sinograms.lima_segmenter.clean(nnz, row, col, val)
class ImageD11.sinograms.lima_segmenter.frmtosparse(mask, dtype)

Bases: object

ImageD11.sinograms.lima_segmenter.initOptions(h5name, jobid)
ImageD11.sinograms.lima_segmenter.main(h5name, jobid)
ImageD11.sinograms.lima_segmenter.reader(frms, mask, cut, start=0)

iterator to read chunks or frames and segment them returns sparseframes

ImageD11.sinograms.lima_segmenter.sbatchlocal(fname, cores=None)

Execute a grid batch job on the local machine Loops over the array submission for you

ImageD11.sinograms.lima_segmenter.segment()
ImageD11.sinograms.lima_segmenter.segment_lima(args)

Does segmentation on a single hdf5 srcname, destname, dataset

ImageD11.sinograms.lima_segmenter.select(img, mask, row, col, val, cut)
ImageD11.sinograms.lima_segmenter.setup(dsname, cut=None, howmany=100000, pixels_in_spot=3, maskfile='', bgfile='', cores_per_job=8, files_per_core=8, pythonpath=None)

Writes options into the dataset file cut=None is replaced by 1 for eiger, 25 otherwise pythonpath -> point to a non-default install

ImageD11.sinograms.lima_segmenter.setup_slurm_array(dsname, dsgroup='/', pythonpath=None)

Send the tasks to slurm

ImageD11.sinograms.lima_segmenter.top_pixels(nnz, row, col, val, howmany, thresholds)

selects the strongest pixels from a sparse collection - THRESHOLDS should be a sorted array of potential cutoff values to try that are higher than the original cutoff used to select data - howmany is the maximum number of pixels to return

ImageD11.sinograms.point_by_point module

class ImageD11.sinograms.point_by_point.PBP(parfile, dset, hkl_tol=0.01, fpks=0.7, ds_tol=0.005, etacut=0.1, ifrac=None, gmax=5, cosine_tol=0.0017453283658982615, y0=0, symmetry='cubic', loglevel=3, foridx=None, forgen=None, uniqcut=0.75, phase_name=None)

Bases: object

iplot(skip=1)
point_by_point(grains_filename, icolf_filename=None, nprocs=None, gridstep=1, debugpoints=None, loglevel=3)

grains_filename = output file icolf_filename = hdf5file to write. Allows mmap to be used.

setpeaks(colf, icolf_filename=None)

This is called on the main parent process

The peaks will be written to file

class ImageD11.sinograms.point_by_point.PBPMap(*args, **kwargs)

Bases: columnfile

Columnfile for point-by-point indexing and refinement results. The results of point-by-point indexing and refinement can be multi-valued e.g there can be more than one UBI found at a given map pixel Therefore this class stores pixel results in the following way:

# i j ntotal nuniq ubi00 ubi01 ubi02 ubi10 ubi11 ubi12 ubi20 ubi21 ubi22

We have an extra method to get all the results at one pixel: self.get_pixel_mask() There’s another concept: selecting a single best UBI at each pixel This will fill in self.best_UBI, self.best_npks, self.best_nuniq

property NI
property NJ
property NY
property UBI
choose_best(minpeaks=6)
property eps

eps computed on-demand from reshaping eps columns shape is (3, 3, nrows) to match previous PBPMap definition

get_pixel_mask(i, j)

Return mask to columnfile with those specified i and j values

property i_shift
property j_shift
plot_best(minpeaks=6)
plot_nuniq_hist()
property ubi

ubi computed on-demand from reshaping ubi columns. shape is (3, 3, nrows) to match previous PBPMap definition

class ImageD11.sinograms.point_by_point.PBPRefine(dset, phase_name, hkl_tol_origins=0.05, hkl_tol_refine=0.1, hkl_tol_refine_merged=0.05, ds_tol=0.005, etacut=0.1, ifrac=None, forref=None, y0=0.0, min_grain_npks=6)

Bases: object

Class to manage point-by-point refinement. The maps in this class are set up on a grid that matches the PBPMap reference frame This is in step space in geometry.py

classmethod from_h5(filename, h5group='PBPRefine')
get_origins(guess_speed=True, guess_npks=10000, save_peaks_after=True)
iplot(skip=1)

Same as PBP.iplot for now

loadmap(filename=None, refined=False)

Load an existing input/refined PBPMap from h5. If you only have a .txt file, you want self.setmap()

loadpeaks(icolf_filename=None)

Load icolf from disk

run_refine(points_step_space=None, npoints=None, output_filename=None, use_cluster=False, pythonpath=None)

Call ImageD11.sinograms.point_by_point.refine_map to refine If you say use_cluster, will save the refinement object to disk Then submit a job to slurm to refine

savemap(filename=None, refined=False)

Save self.pbpmap/self.refinedmap to an H5 file

savepeaks(icolf_filename=None, del_existing=False)
setmap(pbpmap)

Set an input PBPMap Python object to use

setmask(manual_threshold=None, doplot=False, use_icolf=True)

Set a mask for choosing what to refine or not. You can choose whether to use self.colf (all peaks) or self.icolf (selected peaks) At the moment it does an iradon on the sinogram of all the 2D peaks in self.colf

setpeaks(colf, icolf_filename=None, del_existing=True, prompt_del=True)

Similar to PBP.setpeaks for now

setsingle(pbpmap, method='best', **method_args)

Function to go from a multi-valued PBPMap to a single-valued PBPMap

to_h5(filename=None, h5group='PBPRefine')
ImageD11.sinograms.point_by_point.compute_g_from_k(k, omega, wedge=0, chi=0)

Compute g-vectors with cached k-vectors

ImageD11.sinograms.point_by_point.compute_g_vectors(tth, eta, omega, wvln, wedge=0.0, chi=0.0)
Generates spot positions in reciprocal space from

twotheta, wavelength, omega and eta

Assumes single axis vertical … unless a wedge angle is specified

ImageD11.sinograms.point_by_point.compute_grain_origins(omega, wedge, chi, t_x, t_y, t_z)
ImageD11.sinograms.point_by_point.compute_gve(sc, fc, omega, xpos, distance, y_center, y_size, tilt_y, z_center, z_size, tilt_z, tilt_x, o11, o12, o21, o22, t_x, t_y, t_z, wedge, chi, wavelength)
ImageD11.sinograms.point_by_point.compute_k_vectors(tth, eta, wvln)

generate k vectors - scattering vectors in laboratory frame

ImageD11.sinograms.point_by_point.compute_origins(singlemap, sample_mask, gve, sinomega, cosomega, omega, dty, sx_grid, sy_grid, y0, ystep, hkl_tol, sorter)

Compute origins of diffraction for each peak For each dty, omega value, we cast a ray through singlemap Along the ray, we get the UBIs in singlemap If the UBI indexes the peak, we consider it For each peak, we then work out the weighted origin position in x Adapted from Axel codebase

ImageD11.sinograms.point_by_point.compute_tth_eta(sc, fc, omega, y_center=0.0, y_size=0.0, tilt_y=0.0, z_center=0.0, z_size=0.0, tilt_z=0.0, tilt_x=0.0, distance=0.0, o11=1.0, o12=0.0, o21=0.0, o22=-1.0, t_x=0.0, t_y=0.0, t_z=0.0, wedge=0.0, chi=0.0)
ImageD11.sinograms.point_by_point.compute_tth_eta_from_xyz(peaks_xyz, omega, t_x=0.0, t_y=0.0, t_z=0.0, wedge=0.0, chi=0.0)
ImageD11.sinograms.point_by_point.compute_xyz_lab(sc, fc, y_center=0.0, y_size=0.0, tilt_y=0.0, z_center=0.0, z_size=0.0, tilt_z=0.0, tilt_x=0.0, distance=0.0, o11=1.0, o12=0.0, o21=0.0, o22=-1.0)
ImageD11.sinograms.point_by_point.count_unique_peaks(hkl, etasign, dtyi)
ImageD11.sinograms.point_by_point.count_unique_peaks_no_dtyi(hkl, etasign)
ImageD11.sinograms.point_by_point.detector_rotation_matrix(tilt_x, tilt_y, tilt_z)
ImageD11.sinograms.point_by_point.divide_where(arr1, arr2, out, wherearr)

Do arr1/arr2. In locations where wherearr == 0, return out instead

ImageD11.sinograms.point_by_point.get_local_gv(si, sj, ystep, omega, sinomega, cosomega, xl, yl, zl)

Given a point (si, sj) in step space, compute the x values in the lab frame for each omega angle Then subtract them from xl to account for the change in the diffraction origin point. Then re-compute the g-vectors.

ImageD11.sinograms.point_by_point.get_voxel_idx(y0, xi0, yi0, sinomega, cosomega, dty, ystep)

get peaks at xi0, yi0 basically just geometry.dty_values_grain_in_beam_sincos

ImageD11.sinograms.point_by_point.gve_norm(gve)
ImageD11.sinograms.point_by_point.hkluniq(ubi, gx, gy, gz, eta, m, tol, hmax)

count uniq peaks - move to cImageD11 in the future

ImageD11.sinograms.point_by_point.idxpoint(si, sj, isel, omega, sinomega, cosomega, dtyi, xl, yl, zl, eta, ystep=2.0, y0=0.0, ymin=-2.0, minpks=1000, hkl_tol=0.1, ds_tol=0.005, cosine_tol=0.0017453283658982615, forgen=None, hmax=-1, uniqcut=0.75)

Indexing function called at one point in space. Selects peaks from the sinogram and attempts to index. More of this could be indexing.py I guess.

si, sj = position in step space (origin is rotation axis)

Effectively a columnfile:

isel = column of rings to use sinomega = column of sinomega cosomega = column of cosomega dtyi = column of dty on integer bins gx/gy/gz/eta = peak co-ordinates

ystep, y0 = compute the dtyi bins to select peaks (dtymask function above)

forgen = the rings to use for INDEXING / orientation searching (a speedup effect)

minpks = number of peaks to find with rings hkl_tol = ImageD11 tolerance of indexed == | h-int(h) | < hkl_tol cosine_tol = ImageD11 tolerance for finding pairs of peaks

uniqcut = unique peaks cutoff (uniq> ucut * max are returned)

returns a list of :

(npks, nuniq, ubi)

ImageD11.sinograms.point_by_point.initializer(parfile, phase_name, symmetry, colfile, loglevel=3)
ImageD11.sinograms.point_by_point.merge(hkl, etasign, dtyi, sum_intensity, sc, fc, omega, dty, xpos_refined, eta)

merge peaks with the same (h, k, l, etasign, dtyi) weighted by sum_intensity

ImageD11.sinograms.point_by_point.nb_choose_best(i, j, u, n, NY, ubiar, minpeaks=6)
ImageD11.sinograms.point_by_point.nb_inv(mats, imats)
ImageD11.sinograms.point_by_point.nb_inv_3d(mats, imats)
ImageD11.sinograms.point_by_point.prepare_refine_bash(pbp_object, id11_code_path, output_filename)
ImageD11.sinograms.point_by_point.proxy(args)

Wrapper function for multiprocessing

ImageD11.sinograms.point_by_point.refine_map(refine_points, all_pbpmap_ubis, ri_col, rj_col, sx_grid, sy_grid, mask, sc, fc, eta, sum_intensity, sinomega, cosomega, omega, dty, dtyi, xpos, ystep, y0, B0, distance, y_center, y_size, tilt_y, z_center, z_size, tilt_z, tilt_x, o11, o12, o21, o22, t_x, t_y, t_z, wedge, chi, wavelength, tol=0.1, merge_tol=0.05, min_grain_npks=6, gnoise_std=0.0001)

Refine UBIs in all_pbpmap_ubis Adapted from Axel codebase

refine_points: list or Nx2 array of points in reconstruction space (ri, rj) to refine at all_pbpmap_ubis: 3x3xM array of many-valued UBIs from point-by-point map ri_col, rj_col: length-M array of ri and rj coordinates (reconstruction space) for each UBI in all_pbpmap_ubis sx_grid, sy_grid: same as before (sample space sx, sy positions) a bunch of icolf columns ystep, y0: same as before B0: B matrix of dzero_cell then a bunch of pars from the parameter file then assignment tolerances: tol is the assignment hkl tolerance for non-merged peaks merge_tol is the assignment hkl tolerance for merged peaks

ImageD11.sinograms.point_by_point.ubi_and_ucell_to_u(ubi, ucell)
ImageD11.sinograms.point_by_point.ubi_to_unitcell(ubi)
ImageD11.sinograms.point_by_point.unique_with_counts(a)
ImageD11.sinograms.point_by_point.weighted_lstsq_ubi_fit(ydist, gve, hkl)

ImageD11.sinograms.polefigures module

WARNING: work in progress

ImageD11.sinograms.polefigures.main(pars, dataset)
class ImageD11.sinograms.polefigures.splatter(parfile, dxfile='/data/id11/nanoscope/Eiger/spatial_20210415_JW/e2dx.edf', dyfile='/data/id11/nanoscope/Eiger/spatial_20210415_JW/e2dy.edf')

Bases: object

splats pixels onto polefigures

process(dsfile)

ImageD11.sinograms.pread module

WARNING: work in progress - look at mpi and/or uncompressed data instead?

ImageD11.sinograms.pread.create(hname, dset)
ImageD11.sinograms.pread.getse(shape, chunks, nproc)
ImageD11.sinograms.pread.pread(tbl, hname, dset='pks2d', nproc=0)
ImageD11.sinograms.pread.read2pipe(dest, hname, dset, selection)
ImageD11.sinograms.pread.readN(hname, dset, NPROC=40)
ImageD11.sinograms.pread.read_segment(args)
ImageD11.sinograms.pread.readpartial(args)

ImageD11.sinograms.properties module

ImageD11.sinograms.properties.compute_storage(peaks)

make the cumulative sums of peaks to figure out storage space holds the row, npks, nii, nij

ImageD11.sinograms.properties.countse(se)

counts the points in a block of start/end

ImageD11.sinograms.properties.find_ND_labels(i, j, npks, verbose=1)
ImageD11.sinograms.properties.get_clean_labels(labels)

Given the labelling in l, put clean labels in the place.

l = integer array with value = label of lowest 2d peak in this ND group.

ImageD11.sinograms.properties.get_start_end(n, p)

For splitting up the scan row over processes n = number of jobs p = number of processes

All processes must do at least two rows to get the overlaps between rows. The work sharing is based on these overlaps.

rows : 0 1 2 3 4 5 etc. overlap 01 12 23 34 45

ImageD11.sinograms.properties.goforit(ds, sparsename, options)
dsfilename = ImageD11.sinograms.dataset FILE

This is how processes all get omega data

sparsename = pixels to read options

ImageD11.sinograms.properties.main(dsfilename, sparsefile=None, pksfile=None, options={})

dsname = ImageD11.sinograms.dataset file sparsename = File containing sparse pixels (None = use dsname.sparsefile) pkname = File to receive output peaks (None = use dsname.pksfile)

options : dictionary of options, to override

ImageD11.sinograms.properties.n_pk2d(s1, sI, srI, scI, frm, omega, dty)
ImageD11.sinograms.properties.numbalabelNd(i, j, pkid, flip=0)

i, j are the pairs of overlapping peaks pkid are the current labels of the peaks

This scans all pairs and for each pair it makes

pkid[i] = pkid[j] = min(pkid[i], pkid[j])

Run this enough times and eventually all peaks point back to the first one they overlap.

Using parallel seems dodgy to me. Might be a race condition, but it seems like the code is legal so long as only these addresses are touched?

ImageD11.sinograms.properties.numbapkmerge(labels, pks, omega, dty, out)
ImageD11.sinograms.properties.pairrow(s, row)

s = SparseScan

returns SparseScan which adds a dictionary of pairs:

sourceFrame destFrame

[ idty, iomega, idty, iomega ]nedge, array( (nedge, 3) )

(src, dest, npixels)

ImageD11.sinograms.properties.pairscans(s1, s2, omegatol=0.051)
class ImageD11.sinograms.properties.pks_table(npk=None, ipk=None, pk_props=None, rc=None, rpk=None, glabel=None, nlabel=0, use_shm=False)

Bases: object

create(npk)
export()
find_uniq(outputfile=None, use_scipy=False)

find the unique labels from the rc array

classmethod fromSHM(dct)
guesschunk(ar, m=2560)
classmethod load(h5name, h5group='pks2d')
pk2d(omega, dty)
pk2dmerge(omega, dty)

creates a dictionary of the 3D peaks

save(h5name, group='pks2d', rc=False)
share(name, *args, **kwds)

puts the array into shared memory returns the shared copy

ImageD11.sinograms.properties.pks_table_from_scan(sparsefilename, ds, row)

Labels one rotation scan to a peaks table

sparsefilename = sparse pixels file dataset = ImageD11.sinograms.dataset row = index for dataset.scan[ row ]

returns a pks_table.

You might want to call one of “save” or “pk2d” or “pk2dmerge” on the result

This is probably not threadsafe

ImageD11.sinograms.properties.process(qin, qshm, qout, hname, dsfilename, options)
Worker process.

qin : gives a block of scans from qin to label (start, end) qshm : gives us shared memory to store/return results qout : numbers of overlaps hname = sparse pixels dsfilename = load omega options (passed through)

ImageD11.sinograms.properties.props(scan, i, algorithm='lmlabel', wtmax=None)

scan = sparseframe.SparseScan object i = sinogram row id : used for tagging pairs algorithm = ‘lmlabel’ | ‘cplabel’

Labels the peaks with lmlabel Assumes a regular scan for labelling frames returns ( row, properties[(s1,sI,sRow,sCol,frame),:], pairs, scan )

ImageD11.sinograms.properties.remove_shm_from_resource_tracker()

Monkey-patch multiprocessing.resource_tracker so SharedMemory won’t be tracked More details at: https://bugs.python.org/issue38119

class ImageD11.sinograms.properties.shared_numpy_array(ary=None, shape=None, dtype=None, shmname=None, fill=None)

Bases: object

See: https://bugs.python.org/issue38119 The multiprocessing pool must stick around until the process exits

export()
ImageD11.sinograms.properties.testit(NPROC)

sanity check

class ImageD11.sinograms.properties.tictoc

Bases: object

ImageD11.sinograms.roi_iradon module

This code came from skimage.transform and then was modified

  • Added mask ROI for back projection. Optimisation for small grains in big maps. Should allow threading (one thread per tile)

  • Added projection shifts (sinogram shaped array of dty shifts). Should work the same way for both forward and back projection. Probably only for small offsets

ImageD11.sinograms.roi_iradon.apply_halfmask_to_sino(sino)

Applies halfmask correction to sinogram

ImageD11.sinograms.roi_iradon.correct_recon_central_zingers(recon, radius=25)
ImageD11.sinograms.roi_iradon.fxyrot(colrow, angle=0, center=0, projection_shifts=None)
ImageD11.sinograms.roi_iradon.iradon(radon_image, theta, output_size=None, filter_name='ramp', interpolation='linear', projection_shifts=None, mask=None, workers=1)

Inverse radon transform. From skimage.transform. Simplified then ruined.

  • allow projection offset/shifts to be used

    1D = constant offset for this projection (why?) 2D = offset versus dty for this projection

  • allow a mask to be used for roi reconstruction

  • run over several threads (each one doing a different roi)

ImageD11.sinograms.roi_iradon.mlem(sino, theta, startvalue=1, projection_shifts=None, output_size=None, mask=None, workers=1, niter=50, divtol=1e-05)

# Also called “MART” for Multiplicative ART # This keeps a positivity constraint for both the data and reconstruction # # This implementation was inspired from from: # https://www.youtube.com/watch?v=IhETD4nSJec # by Andrew Reader # # ToDo : implement a mask # ToDo : check about the corners / circle=False aspects #

An “MLEM” algorithm from XRDUA was used in this paper:

“Impurity precipitation in atomized particles evidenced by nano x-ray diffraction computed tomography” Anne Bonnin; Jonathan P. Wright; Rémi Tucoulou; Hervé Palancher Appl. Phys. Lett. 105, 084103 (2014) https://doi.org/10.1063/1.4894009

This python code implements something similar based on a youtube video (https://www.youtube.com/watch?v=IhETD4nSJec)

There are lots of papers from mathematicians in the literature about MART (multiplicative ART). The conversion of latex algebra back and forth into computer code seems to be a bit of a problem for me (Jon Wright - Nov 2023).

ImageD11.sinograms.roi_iradon.radon(image, theta, output_size=None, projection_shifts=None, mask=None, workers=1)

From skimage.transform. Modified to have projection shifts and roi to match the masked iradon here. And spread theta over threads.

Calculates the radon transform of an image given specified projection angles.

Parameters

imagearray_like

Input image. The rotation axis will be located in the pixel with indices (image.shape[0] // 2, image.shape[1] // 2).

thetaarray_like

Projection angles (in degrees).

output_size : shape of the output sinogram. Matches [:, len(theta)]

Returns

radon_imagendarray

Radon transform (sinogram). The tomography rotation axis will lie at the pixel index radon_image.shape[0] // 2 along the 0th dimension of radon_image.

References

Notes

Based on code of Justin K. Romberg (https://www.clear.rice.edu/elec431/projects96/DSP/bpanalysis.html)

ImageD11.sinograms.roi_iradon.recon_cens(omega, dty, ybins, imsize, wt, y0=0.0)

Back project the peak centers into a map

omega, dty = peak co-ordinates in the sinogram ybins = spatial binning imsize = probably len(ybins)+1 wt = intensity, probably ones()

ImageD11.sinograms.roi_iradon.run_iradon(sino, angles, pad=20, shift=0, workers=1, mask=None, apply_halfmask=False, mask_central_zingers=False, central_mask_radius=25, filter_name='hamming')

Applies an iradon to a sinogram, with an optional pad Calculates scaled-up output size from pad value Applies projection shifts of shift Optionally mask the returned reconstruction with sample_mask Optionally apply halfmask to correct artifacts with half-scans (from -ny to 0 rather than -ny/2 to +ny/2 Optionally apply a circular median filter mask to the center of the reconstruction given a radius in central_mask_radius

ImageD11.sinograms.roi_iradon.run_mlem(sino, angles, mask=None, pad=20, shift=0, workers=1, niter=20, apply_halfmask=False, mask_central_zingers=False, central_mask_radius=25)

Applies an MLEM reconstruction to a sinogram, with an optional pad Calculates scaled-up output size from pad value Applies projection shifts of shift Optionally mask the returned reconstruction with sample_mask Optionally apply halfmask to correct artifacts with half-scans (from -ny to 0 rather than -ny/2 to +ny/2 Optionally apply a circular median filter mask to the center of the reconstruction given a radius in central_mask_radius

ImageD11.sinograms.sinogram module

class ImageD11.sinograms.sinogram.GrainSinogram(grain_obj, dataset)

Bases: object

Class to build, hold and reconstruct sinograms of grains for Scanning 3DXRD data

build_sinogram(columns=('omega',))

Computes sinogram for this grain using all peaks in self.cf_for_sino

columns = list of columns to produce sinograms of intensity*value

for example: “ds”, “eta”, “omega”, etc

correct_halfmask()

Applies halfmask correction to sinogram

correct_ring_current(is_half_scan=False, min_ring_current_frac=0.5)

Corrects each row of the sinogram to the ring current of the corresponding scan

classmethod from_h5py_group(group, ds, grain)

Creates a GrainSinogram object from an h5py group, dataset and grain object

get_shape_mask(method='iradon', cutoff=None)

Gets a boolean mask representing the grain shape from the grain reconstruction. Performs a binary threshold of the reconstruction. Uses manual threshold value if cutoff value provided. Performs global Otsu threshold if no value provided.

mask_central_zingers(method='iradon', radius=25)
prepare_peaks_from_2d(cf_2d, grain_label, hkltol=0.25)

Prepare peaks used for sinograms from 2D peaks data Performs greedy assignment of all 2d peaks to each grain

prepare_peaks_from_4d(cf_4d, gord, inds, grain_label, hkltol=0.25)

Prepares peaks used for sinograms from 4D peaks data. cf_4d should contain grain assignments grain_label should be the label for this grain

recon(method='iradon', workers=1, projections=None, **extra_args)

Performs reconstruction given reconstruction method

method = “iradon”, “mlem”, “astra” workers = threads to use - passed to the method

projections = which projections to use for reconstruction using a subset of data (twins)

iradon( self.sino[ :, projections ], theta = self.sinoangles[ projections ], … ) effectively a sinogram mask - perhaps this should move to iradon code.

extra_args = passed to the projection function

iradon -> ImageD11.sinograms.roi_iradon.run_iradon { pad=20, shift=0, workers=1, mask=None,

apply_halfmask=False, mask_central_zingers=False, central_mask_radius=25, filter_name=’hamming’}

mlemImageD11.sinograms.roi_iradon.run_mlem

{ mask=None, pad=20, shift=0, workers=1, niter=20, apply_halfmask=False,

mask_central_zingers=False, central_mask_radius=25 }

astrarun_astra in this file

{ shift=0, pad=0, mask=None, niter=100, astra_method=’SIRT_CUDA’, workers=None }

to_h5py_group(parent_group, group_name)

Creates a H5Py group for this GrainSinogram. parent_group is the parent H5py Group group_name is the name of the H5py Group for this name Very useful for saving lists of GrainSinograms to an H5 file

update_lab_position_from_peaks(cf_4d, grain_label)

Updates translation of self.grain using peaks in assigned 4D colfile. Also updates self.recon_y0 with centre

update_lab_position_from_recon(method='iradon')

Updates translation of self.grain by finding centre-of-mass of reconstruction Only really valid for very small grains. Does not update translation if no fitting result found.

update_recon_parameters(pad=None, shift=None, mask=None, niter=None, y0=None)

Update some or all of the reconstruction parameters in one go

ImageD11.sinograms.sinogram.build_slice_arrays(grainsinos, cutoff_level=0.0, method='iradon', grain_labels=None)

Build grain maps from individual grain reonstructions Optionally provide a different list of grain labels to label the grains

ImageD11.sinograms.sinogram.build_slice_arrays_clean(grainsinos, method='iradon', grain_labels=None)

Build grain maps from individual grain reonstructions Cleans and normalises reconstructions before building slice arrays Saves cleaned and normalised reconstruction to gs.recons[method_norm] Optionally provide a different list of grain labels to label the grains

ImageD11.sinograms.sinogram.counting_sort(ary, maxval=None, minval=None)

Radix sort for integer array. Single threaded. O(n) Numpy should be doing this…

ImageD11.sinograms.sinogram.filter_normalise_recon(recon)

Function to filter and normalise reconstructions

ImageD11.sinograms.sinogram.find_grain_id(spot3d_id, grain_id, spot2d_label, grain_label, order, nthreads=20)

Assignment grain labels into the peaks 2d array spot3d_id = the 3d spot labels that are merged and indexed grain_id = the grains assigned to the 3D merged peaks spot2d_label = the 3d label for each 2d peak grain_label => output, which grain is this peak order = the order to traverse spot2d_label sorted

ImageD11.sinograms.sinogram.get_2d_peaks_from_4d_peaks(p2d, cf)

inds is an array which tells you which 2D spots each grain owns the 2D spots are sorted by spot ID inds tells you for each grain were you can find its associated 2D spots

ImageD11.sinograms.sinogram.norm(r)
ImageD11.sinograms.sinogram.palloc(shape, dtype)

Allocate and fill an array with zeros in parallel

ImageD11.sinograms.sinogram.pmax(ary)

Find the min/max of an array in parallel

ImageD11.sinograms.sinogram.read_h5(filename, ds, group_name='grains')

Read list of GrainSinogram objects from H5Py file Will also create self.grain objects from the H5Py file Because GrainSinogram objects can’t exist without corresponding grain objects

ImageD11.sinograms.sinogram.read_slice_recon(filename)
ImageD11.sinograms.sinogram.run_astra(sino, angles, shift=0, pad=0, mask=None, niter=100, astra_method='SIRT_CUDA', workers=None)
ImageD11.sinograms.sinogram.save_array(grp, name, ary)
ImageD11.sinograms.sinogram.write_h5(filename, list_of_sinos, overwrite_grains=False, group_name='grains')

Write list of GrainSinogram objects to H5Py file If overwrite_grains is True, will replace grains in group_name

ImageD11.sinograms.sinogram.write_pbp_strain(filename, pbp_strain_slice_arrays)
ImageD11.sinograms.sinogram.write_slice_recon(filename, slice_arrays)

ImageD11.sinograms.sinogram2crysalis module

WARNING: work in in progress

class ImageD11.sinograms.sinogram2crysalis.SinoScan(dataset, num=0)

Bases: LimaImage

Inherit limaimage to be allowed by converter

close()
ImageD11.sinograms.sinogram2crysalis.accumulate(npixels, values, indices, dest, num)
class ImageD11.sinograms.sinogram2crysalis.empty

Bases: object

ImageD11.sinograms.sinogram2crysalis.integrate_sino(ds, image_mask, sinomask=None, nomega=10)

ds = ImageD11.sinograms.dataset that describes scandata sinomask = which frames to use nomega = number of omegasteps to combine

ImageD11.sinograms.sinogram2crysalis.makecmdline(wvln=0.2845715990727352, xbeam=1024, ybeam=1024, omegastart=90, step=0.1, distance=140, savepath='.', run=1)
ImageD11.sinograms.sinogram2crysalis.name_decorator(method)
ImageD11.sinograms.sinogram2crysalis.padd(values, destination)
ImageD11.sinograms.sinogram2crysalis.sum_sinogram(dsname, output_name, nomega=10, nthreads=None)

ImageD11.sinograms.tensor_map module

class ImageD11.sinograms.tensor_map.TensorMap(maps=None, phases=None, steps=None)

Bases: object

This is a class to store a contiguous voxel-based representation of a sample. At its core is the self.maps attribute, which is a dictionary of Numpy arrays. Each Numpy array should represent a 3D voxel grid of the sample. The dimensions of the array are aligned with the laboratory reference frame in the order (Z, Y, X, …) The shape of the first three axes should therefore be (NZ, NY, NX, …) The total number of dimensions can vary E.g a phase ID map might be (1, 15, 20) but a UBI map might be (1, 15, 20, 3, 3)

property B

The B matrix via the unitcell

property U

The U matrix - via UBI and B, the same way as in ImageD11.grain

property UB

The UB matrix

property UBI

The UBI matrix

add_map(name, array)

Required to clear caches if UBI is set

check_shape()

Checks that all the maps in self.maps have equal shape for their first 3 dimensions

clear_cache()
property dzero_unitcell

The dzero unitcell for each voxel from the reference phase for that voxel.

property eps_crystal

The per-voxel Biot strain tensor in the crystal reference frame, relative to the B0 of the unitcell of the reference phase for that voxel.

Equivalent to calling ImageD11.grain.eps_sample_matrix(dzero_cell).

Will compute from eps_sample by rotating the tensor if we have it. If not, will compute from UBI.

property eps_devia

The per-voxel deviatoric strain tensor

property eps_hydro

The per-voxel hydrostatic strain tensor (frame invariant)

property eps_sample

The per-voxel Biot strain tensor in the sample frame, relative to the B0 of the unitcell of the reference phase for that voxel.

Equivalent to calling ImageD11.grain.eps_grain_matrix(dzero_cell).

Will compute from eps_crystal by rotating the tensor if we have it. If not, will compute from UBI.

property euler

The euler angles from the U matrix, the same way as in xfab.tools

classmethod from_combine_phases(tensormaps)

Combine multiple mono-phase TensorMaps with different phases into one TensorMap. For now, this handles grain label collisions by offsetting the grain labels of subsequent tensormaps before adding

classmethod from_grainsinos(grainsinos, method='iradon', use_gids=True, cutoff_level=0.1, steps=None)

Build a TensorMap object from a list of GrainSinos. method is the recon that we look for inside each grainsino use_gids will look for grainsino.grain.gid inside each grainsino to use as the label if it can’t find it, it will use the increment

classmethod from_h5(h5file, h5group='TensorMap')

Load TensorMap object from an HDF5 file

classmethod from_pbpmap(pbpmap, steps=None, phases=None)

Create TensorMap from a pbpmap object

classmethod from_stack(tensormaps, zstep=1.0)

Stack multiple TensorMaps together along Z. The order of tensormaps will determine the Z-order, lowest-index first. All Tensor Maps in tensormaps must have the same phase mapping (i.e phase 0 is always the same unitcell)

classmethod from_ubis(ubi_array)

Make simplest possible TensorMap object from a UBI array in reconstuction space (X, -Y)

get_ipf_maps()

Calculate all IPF maps and add them to self.maps

get_meta_orix_orien(phase_id=0)

Get a meta orix orientation for all voxels of a given phase ID

get_stress(stiffness_tensor, phase_id)

Convert Biot strain tensor (ImageD11 coordinate system) to Biot stress tensor (ImageD11 coordinate system). Does this for a given phase_id. Needs Voigt-format IEEE coordinate system stiffness tensor.

Parameters:
  • stiffness_tensor (np.ndarray) – 6x6 stiffness tensor in GPa, Voigt notation, IEEE 1976 coordinate system

  • phase_id (int) – ID of phase you want to compute for (makes phase mask)

keys()

allows you to use dictionary syntax

static map_index_to_recon(mj, mk, yshape)

From a 3D array index (mi, mj, mk) and the Y shape of the map, determine the corresponding position in reconstruction space

static map_order_to_recon_order(map_arr, z_layer=0)

Transform a 2D slice of a TensorMap to reconstruction space. The opposite of recon_order_to_map_order

property mt

The metric tensor

plot(map_name, z_layer=0)
static recon_index_to_map(ri, rj, yshape)

From a 2D reconstruction space index (ri, rj) and the Y shape of the map, determine the corresponding position in TensorMap space

static recon_order_to_map_order(recon_arr)

Transform a 2D array from reconstruction space (first axis X, second axis is -Y) to TensorMap space (Z, Y ,X) The input array must have the first two dimensions (X, -Y) as is the case for reconstructed grain shapes from sinogram or PBP methods

property shape

The shape of the map (NZ, NY, NX)

property sig_crystal

The per-voxel Biot stress tensor in the crystal reference frame

property sig_devia

The per-voxel deviatoric stress tensor

property sig_hydro

The per-voxel hydrostatic stress tensor (frame invariant)

property sig_mises

The per-voxel von-Mises stress scalar (frame invariant)

property sig_sample

The per-voxel Biot stress tensor in the sample reference frame

to_ctf_mtex(ctf_path, z_index=0)

Export a Z slice to a CTF file for MTEX processing. The resulting ctf file can be loaded in MTEX with the command: ebsd = EBSD.load(ctf_path) Note that no Euler or spatial conversions are needed

to_h5(h5file, h5group='TensorMap')

Write all maps to an HDF5 file (h5file) with a parent group h5group. Creates h5group if doesn’t already exist

to_paraview(h5name, h5group='TensorMap')

Exports to H5, then writes an XDMF file that lets you read the data with ParaView

to_pbpmap(z_layer=0, default_npks=20, default_nuniq=20)

Get a PBPMap object from this TensorMap object (good for refining strains)

property unitcell

The unitcell - from metric tensor

Module contents

Instructions:

# create the dataset file

python3 -m ImageD11.sinograms.dataset /data/visitor/ma5415/id11/20221027 /data/visitor/ma5415/id11/20221027/analysis/test NSCOPE_SiMo1000_6 DT600nm_Z50 dstest_NSCOPE_SiMo1000_6_DT600nm_Z50.h5

# do some segmentation python3 -m ImageD11.sinograms.lima_segmenter setup dataset.h5 sbatch /data/visitor/ma5415/id11/20221027/analysis/test/NSCOPE_SiMo1000_6/NSCOPE_SiMo1000_6_DT600nm_Z50/slurm/lima_segmenter_slurm.sh

# next step(s) label the pixels (save that or not?)

cost = np.cumsum( dataset.nnz )

save the peaks from each frame?

s_raw f_raw S_I float32, float32, float32 == 4 * 3 = 12 bytes (number of pixels?) sc fc 1 pixel is (uint16, uint16, uint16) = (2 * 3) = 6 bytes

determine dataset.npks_per_frame # keeping all? Keeping Some?

make the graph of all the p