reborn package

Subpackages

Submodules

reborn.config module

Standard configs for reborn. Has global effect.

reborn.const module

reborn.dataframe module

Classes for handling dataframes.

class reborn.dataframe.DataFrame(raw_data=None, processed_data=None, mask=None, beam=None, pad_geometry=None, frame_id=0)[source]

Bases: object

A dataframe is a new concept in reborn. It corresponds to a recording event, which is most often an XFEL pulse or a synchrotron exposure. The interface of this class will be changing in the coming weeks. At minimum, it should hold the following data:

  • A Beam instance.

  • A PADGeometryList.

  • The “raw” PAD data arrays.

  • The “processed” PAD data arrays. (Copy the “raw” data if there are no processing steps.)

  • An event ID. This may be an integer, or any other data type (such as a tuple in the case of LCLS).

parameters = {}
validate()[source]

Check that this dataframe is valid. A valid dataframe must at minimum have a frame ID, a valid Beam instance, a valid PADGeometryList instance, and raw data.

copy()[source]

Makes a copy of the dataframe, including all internal data.

property is_dark
has_beam()[source]
concat_data(data)[source]
split_data(data)[source]
property n_pads

Number of PADs.

property raw_data

Raw data (closest to the source).

property processed_data

Some modification of the raw data.

property q_mags

Concatenates the output of the corresponding function for each PADGeometry.

property q_vecs

Concatenates the output of the corresponding function for each PADGeometry.

property solid_angles

Concatenates the output of the corresponding function for each PADGeometry.

property polarization_factors

Concatenates the output of the corresponding function for each PADGeometry.

clear_cache()[source]

Deletes cached q_mags, q_vecs, solid_angles, polarization_factors

get_frame_index()[source]

This is an integer index the is unique to this frame. It is understood to be a context-dependent parameter that might, for example, be the index in a list of frames.

set_frame_index(index)[source]

See corresponding get_frame_index method.

get_dataset_id()[source]

Unique identifier for the parent dataset.

For LCLS-I this would follow the “data source” convention: for example, “exp=cxil2316:run=56”

set_dataset_id(val)[source]

See the corresponding get_dataset_id method.

get_frame_id()[source]

Unique identifier for this dataframe. Most often this is an integer, but in some cases, such as the LCLS, it may be something else such as a tuple. LCLS uses a tuple of integers: seconds, nanoseconds, and fiducial.

set_frame_id(frame_id)[source]

See the corresponding get_frame_id method.

get_beam()[source]

Get the Beam instance, which contains x-ray wavelength, beam direction, etc.

set_beam(beam)[source]

See the corresponding get_beam method.

get_pad_geometry()[source]

Get the PADGeometryList of all PADs in the event. A future version of this will likely accommodate multiple collections of PADs (e.g. when we have a SAXS detector and WAXS detector that are most reasonably analyzed separately.).

set_pad_geometry(geom)[source]

See the corresponding get_pad_geometry method.

get_raw_data_list()[source]

Get the raw data as a list of 2D arrays.

get_raw_data_flat()[source]

Get the raw data as a contiguous 1D array, with all PADs concatenated.

set_raw_data(data)[source]

Set the raw data. You may pass a list or an ndarray. Has the side effect of setting the ‘writeable’ flag of the array to False.

get_mask_list()[source]

Get the mask as a list of 2D arrays.

get_mask_flat()[source]

Get the mask as a contiguous 1D array, with all PADs concatenated.

set_mask(mask)[source]

Set the mask. You may pass a list or an ndarray.

get_processed_data_list()[source]

See corresponding _raw_ method.

get_processed_data_flat()[source]

See corresponding _raw_ method.

set_processed_data(data)[source]

See corresponding _raw_ method.

clear_processed_data()[source]

Clear the processed data. After this operation, the get_processed_data method will return a copy of the raw data.

get_q_vecs()[source]

Get q vectors as an Nx3 array with all PADs concatenated.

get_q_mags_flat()[source]

Get q magnitudes as a flat array.

get_q_mags_list()[source]

Get q magnitudes as a list of 2D arrays.

get_solid_angles_flat()[source]

Get pixel solid angles as flat array.

get_polarization_factors_flat()[source]

Get polarization factors as a flat array.

reborn.dataframe.save_pickled_dataframe(df, filename)[source]
reborn.dataframe.load_pickled_dataframe(filename)[source]

reborn.detector module

Classes for analyzing/simulating diffraction data contained in pixel array detectors (PADs).

reborn.detector.cached(method)[source]

Experimental decorator for caching results from a method. Assumes no arguments are needed.

reborn.detector.clear_cache(self)[source]

Function to clear cache created by the cached decorator above.

class reborn.detector.PADGeometry(distance=None, pixel_size=None, shape=None, **kwargs)[source]

Bases: object

A container for pixel-array detector (PAD) geometry specification. By definition, a PAD consists of a single 2D grid of pixels; see the extended description in the documentation.

Note

A common point of confusion is that XFEL detectors typically consist of multiple PADs, in which case your code must handle multiple PADGeometry instances. If that is the case for your data, then you should look to the PADGeometryList documentation as it extends Python’s built-in list class with useful methods for PADGeometry instances. Before you look to PADGeometryList, you should finish reading this documentation.

The complete specification of an individual PAD geometry is understood to be the following 5 parameters, which must be defined for a proper instance of PADGeometry:

  • n_fs: The number of pixels along the fast-scan direction.

  • n_ss: The number of pixels along the slow-scan direction.

  • t_vec: The vector that points from the origin (interaction point) to the center of the first pixel in memory.

  • fs_vec: The vector that points from the first pixel in memory, to the next pixel in the fast-scan direction.

  • ss_vec: The vector that points from the first pixel in memory, to the next pixel in the slow-scan direction.

In the above:

  • The lengths of the fs_vec and ss_vec vectors encode the size of the (possibly rectangular) pixel. They moreover form the basis of the 2D grid that maps the pixel positions in the 3D space of the measurement.

  • The term “fast-scan” corresponds to the right-most index of a 2D numpy ndarray containing PAD data.

  • The term “slow-scan” corresponds to the left-most index of a 2D ndarray containing PAD data.

  • In the default memory buffer layout of an ndarray, the fast-scan direction corresponds to pixels that are contiguous in memory, and which therefore have the smallest stride. If the phrase “contiguous in memory” and the term “stride” does not mean anything to you, then you need to read the numpy documentation for ndarray.

In addition to providing a standard way to specify PAD geometry, the PADGeometry class also provides methods that make it easy to generate:

  • Vectors from sample to pixel.

  • Scattering vectors (i.e. “q” vectors… provided beam information).

  • Scattering vector magnitudes.

  • Scattering angles (twice the Bragg angle).

  • Polarization factors.

  • Pixel solid angles.

  • Maximum resolution.

  • etc.

Some of the above parameters require more than a PADGeometry instance – they also require information about the x-ray beam. The Beam class in reborn provides a standard way to specify the properties of an x-ray beam.

Although PADGeometry is primarily meant to deal with geometry, you may also include the information needed to slice the PAD data from a parent data array (as of January 2022). For example, data from the CSPAD detector is presented as a 3D ndarray when accessed using the LCLS psana python package. In order to specify slicing, you must add the following parameters:

  • parent_data_shape: The shape of the parent data array (example: (32, 185, 392) ).

  • parent_data_slice: The slice of the parent data array (example: np.s_[4, :, 196:]).

On initialization, optional arguments may be provided (you must provide all of them):

Parameters:
  • shape (tuple) – (optional) Shape of the PAD.

  • distance (float) – (optional) Sample-to-detector distance.

  • pixel_size (float) – (optional) Size of the pixels in SI units.

do_cache = False
property hash

Return a hash of the geometry parameters. Useful if you want to avoid re-computing things like q_mags.

validate()[source]

Determine if this instance has all the needed parameters defined.

Returns:

True if validation passes.

Return type:

bool

Raises:

ValueError – If any of n_fs, n_ss, fs_vec, ss_vec, t_vec are not defined properly.

clear_cache()[source]

Clear the cache (e.g. cached q_vecs).

property name

(str) The unique name of this panel.

property n_fs

(int) Number of fast-scan pixels.

property n_ss

Number of slow-scan pixels.

property n_pixels

Total number of pixels (\(n_{fs} \cdot n_{ss}\))

property fs_vec

(ndarray) Fast-scan basis vector.

property ss_vec

(ndarray) Slow-scan basis vector.

property t_vec

(ndarray) Translation vector pointing from origin to center of corner pixel, which is first in memory.

property parent_data_slice

Optionally, this defines the slice of an ndarray that this geometry corresponds to. This is helpful if you wish to work with the 3D arrays in psana, for example.

property parent_data_shape

Optionally, this defines the shape of the ndarray from which this PAD is sliced.

is_different(geom, precision=1e-05)[source]

Compare this PAD to another and check if it is the same within specified precision.

slice_from_parent(data)[source]

Slice this 2D array from the parent data array.

change_parent_shape(shape)[source]

Change the parent data shape (e.g from [400, 150] to [4, 100, 150]).

to_dict()[source]

Convert geometry to a dictionary.

Returns: (dict): Dictionary containing the keys name, n_fs, n_ss, fs_vec, ss_vec, t_vec,

parent_data_shape, and parent_data_slice.

from_dict(dictionary)[source]

Loads geometry from dictionary. This goes along with the to_dict method.

copy()[source]

Make a copy of this class instance.

save_json(file_name)[source]

Save the geometry as a json file.

load_json(file_name)[source]

Save the geometry as a json file.

simple_setup(pixel_size=None, distance=None, shape=None, **kwargs)[source]

Make this a square PAD with beam at center.

Parameters:
  • shape (tuple) – The shape of the 2D panel.

  • pixel_size (float) – Pixel size in SI units.

  • distance (float) – Detector distance in SI units.

pixel_size()[source]

Return pixel size, assuming square pixels.

shape()[source]

Return tuple corresponding to the ndarray shape of this PAD.

indices_to_vectors(idx_ss, idx_fs)[source]

Convert pixel indices to translation vectors pointing from origin to position on panel. The positions need not lie on the actual panel; this assumes an infinite plane.

Parameters:
  • idx_fs (float, ndarray) – Fast-scan index.

  • idx_ss (float, ndarray) – Slow-scan index.

Returns:

Nx3 vector array.

Return type:

ndarray

vectors_to_indices(vecs, insist_in_pad=True, round_to_nearest=False, **kwargs)[source]

Suppose you have a vector pointing away from the origin and you want to know which pixel the vector will intercept. This function will do that calculation for you. It will return the indices corresponding to the point where the vector intercepts the PAD. Note that the indices are floating points, so you might need to convert to integers if you use them for indexing.

Parameters:
  • vecs (ndarray) – An array of vectors, with shape (N, 3) or shape (3)

  • insist_in_pad (bool) – If you want to allow out-of-range indices, set this to True. Otherwise, out-of-range values will be set to nan.

  • round_to_nearest (bool) – Round to the nearest pixel position. Default: False.

Returns:

Slow-scan indices, Fast-scan indices.

Return type:

(tuple)

pixel_corner_position_vecs()[source]

Compute vectors pointing from origin to pixel corners. To get the corners we simply shift the pixel indices by +/- 0.5. The output array is of shape (N, 4, 3), interpreted as follows:

vecs[:, 0, :] corresponds to the corners with indices (j-0.5, i-0.5) vecs[:, 1, :] corresponds to the corners with indices (j-0.5, i+0.5) vecs[:, 2, :] corresponds to the corners with indices (j+0.5, i+0.5) vecs[:, 3, :] corresponds to the corners with indices (j+0.5, i-0.5)

Returns: ndarray of shape (N, 4, 3)

position_vecs()[source]

Compute vectors pointing from origin to pixel centers.

Returns: ndarray of shape (N, 3)

center_pos_vec()[source]

The vector that points from the origin to the center of the PAD

Returns: ndarray

average_detector_distance(beam=None, beam_vec=None)[source]

Get the average detector distance, which is equal to the dot product between the beam direction vector and the vector pointing to the center of the PAD.

Parameters:
  • beam (Beam) – Beam parameters.

  • beam_vec (ndarray) – Beam direction (if Beam not specified)

Returns:

float

set_average_detector_distance(distance, beam=None, beam_vec=None)[source]

Set the average detector distance. The translation moves along the beam direction by default.

Parameters:
  • distance (float) – The desired distance

  • beam (Beam) – Beam properties (the direction is needed).

  • beam_vec (ndarray) – Beam direction (if Beam not specified)

Returns:

None

norm_vec(beam=None)[source]

The vector that is normal to the PAD plane.

Parameters:

beam (Beam) – The beam information, if you want to ensure that the signs are chosen so that the normal vector points toward the interaction point.

Returns: ndarray

s_vecs()[source]

Outgoing unit-vectors (length 1) pointing from sample to pixel.

Returns: ndarray

ds_vecs(beam=None, **kwargs)[source]

Scattering vectors \(\hat{s} - \hat{s}_0\) where \(\hat{s}_0\) is the incident beam direction and \(\hat{s}\) is the outgoing vector pointing from sample to pixel. This does not have the \(2\pi/\lambda\) factor that is included in q_mags.

Parameters:

beam (Beam) – specify incident beam properties. If provided, you may omit the specification of beam_vec ect.

Returns: ndarray

q_vecs(beam=None, **kwargs)[source]

Calculate scattering vectors \(\frac{2\pi}{\lambda}(\hat{s} - \hat{s}_0)\)

(1)\[\vec{q}_{ij}=\frac{2\pi}{\lambda}\left(\hat{v}_{ij} - \hat{b}\right)\]
Parameters:

beam (source.Beam instance) – specify incident beam properties. If provided, you may omit the specification of beam_vec ect.

Returns: ndarray

ds_mags(beam=None, **kwargs)[source]

These are the magnitudes that correspond to

Parameters:

beam (Beam)

Returns: ndarray

q_mags(beam=None, **kwargs)[source]

Calculate scattering vector magnitudes:

Parameters:

beam (source.Beam instance) – specify incident beam properties. If provided, you may omit the specification of beam_vec ect.

Returns: ndarray

solid_angles()[source]

Calculate solid angles of pixels. See solid_angles2 method.

Returns: ndarray

solid_angles1()[source]

Calculate solid angles of pixels vectorally, assuming the pixels have small angular extent.

Returns: ndarray

solid_angles2()[source]

Pixel solid angles calculated using the method of Van Oosterom, A. & Strackee, J. Biomed. Eng., IEEE T ransactions on BME-30, 125-126 (1983). Divide each pixel up into two triangles with vertices R1,R2,R3 and R2,R3,R4. Then use analytical form to find the solid angle of each triangle. Sum them to get the solid angle of pixel.

Thanks to Derek Mendez, who thanks Jonas Sellberg.

Returns: ndarray

polarization_factors(beam=None, e1=None, b=None, a=None)[source]

The scattering polarization factors.

Parameters:
  • beam (Beam) – Incident beam.

  • e1 (ndarray) – Optional: Principle polarization vector.

  • b (ndarray) – Optional: Incident beam vector.

  • a (float) – Optional: The weight of the first polarization component.

Returns: ndarray

scattering_angles(beam=None, **kwargs)[source]

Scattering angles (i.e. twice the Bragg angles).

Parameters:

beam (source.Beam instance) – specify incident beam properties. If provided, you may omit the specification of beam_vec ect.

Returns: ndarray

azimuthal_angles(beam)[source]

The azimuthal angles of pixels in spherical coordinates. In the physics convention, the incident beam points along the zenith \(\hat{z}\), the outgoing wavevector points to the pixel at position \(\vec{r}\), the “polar angle” \(\theta\) is the scattering angle, and the “azimuthal angle” is \(\phi = \arctan(y/x)\).

Since reborn does not enforce any particular coordinate convention or beam direction, we define the azimuthal angles according to the definition of the incident Beam :

(2)\[\phi = \arctan(\hat{e}_2 \cdot \hat{r} / \hat{e}_1 \cdot \hat{r})\]

where \(\hat{e}_1\) is the principle polarization component of the incident x-ray beam, and \(\hat{e}_2\) is the complementary polarization component.

Parameters:

beam (source.Beam instance) – specify incident beam properties.

Returns: ndarray

streak_mask(vec=None, angle=None)[source]

Create a streak mask. Given the “streak vector” \(\vec{s}\) that defines the plane of the streak, calculate the angles between outgoing pixel vector \(\vec{p}\) and that plane: \(\phi = \pi/2 - |\arccos(\vec{s}\cdot \vec{p})|\). Then mask all pixels for which \(\phi\) is less than the specified angle.

Note

If you want to mask a liquid jet, then the streak vector should be \(\vec{s} \times \vec{b}\) where the vector \(\vec{b}\) points along the beam direction and \(\vec{s}\) points along the liquid jet.

Parameters:
  • vec (ndarray) – Vector describing plane of streak

  • angle (float) – Mask everything within this angle

Returns: ndarray

edge_mask(n=1)[source]

Mask pixels along the perimeter of the PAD.

Parameters:

n (int) – How many pixels to mask.

Returns: ndarray

beamstop_mask(beam=None, q_min=None, q_max=None, min_angle=None, max_angle=None, min_radius=None, max_radius=None)[source]
Parameters:
  • beam (Beam) – Instance of the Beam class (for wavelength)

  • q_min (float) – Minimum q magnitude (mask smaller q values)

  • q_max (float) – Maximum q magnitude (mask larger q values)

  • min_angle (float) – Minimum scattering angle (mask smaller angles)

  • max_angle (float) – Maximum scattering angle (mask larger angles)

  • min_radius (float) – Minimum size (mask pixels within)

  • max_radius (float) – Maximum size (mask pixels beyond)

Returns: ndarray

f2phot(beam=None)[source]

Returns the conversion factor needed to convert structure factors \(|F(\vec q)|^2\) to photon counts. Specifically, this function returns \(\alpha_i\) in the expression

(3)\[I_i = \alpha_i |F_i|^2 = J_0 r_e^2 P_i \Delta\Omega_i |F_i|^2\]

where

  • \(I_i\) is the photon counts in pixel \(i\)

  • \(J_0\) is the incident photon fluence (photons per area)

  • \(r_e^2\) is the classical electron scattering cross section

  • \(P_i\) is the polarization factor for pixel \(i\)

  • \(\Delta\Omega_i\) is the solid angle of pixel \(i\)

Parameters:

beam (Beam) – The beam properties

Returns: ndarray

reshape(dat)[source]

Re-shape a flattened array to a 2D array.

Parameters:

dat (ndarray) – The flattened data array

Returns: ndarray

zeros(*args, **kwargs)[source]

For convenience: np.zeros((self.n_ss, self.n_fs))

ones(*args, **kwargs)[source]

For convenience: np.ones((self.n_ss, self.n_fs))

random(*args, **kwargs)[source]

For convenience: np.random.random((self.n_ss, self.n_fs))

poisson(lam=1.0)[source]

For convenience: np.random.poisson(lam=lam, size=(self.n_ss, self.n_fs))

max_resolution(beam=None)[source]

Maximum resolution over all pixels: 2*pi/q

Parameters:

beam – A Beam class instance.

Returns:

float

corner_position_vectors()[source]

Returns the coordinates of all four corners of the detector. The output is an ndarray with shape (5, 3) and the following entries [t, t+nf*f, t+nf*f+ns*s, t+ns*s] .

Returns:

The corner positions of the PAD.

Return type:

ndarray

binned(binning=2)[source]

Make the pixel size bigger by an integer multiple, while keeping the array size approximately the same.

Note

This may result in loss of information. Example: with binning set to 2, a 5x7 PAD results in a 2x3 PAD with pixels twice the size. There is no way to recover the initial 5x7 shape from the binned PAD.

Note

This operation is not inplace. It does not affect the current instance of PADGeometry. It returns a new PADGeometry.

Parameters:

binning (int) – An integer value of 1,2,3,etc. The pixel size will be increased by this factor.

Returns:

The new, binned, PAD geometry.

Return type:

PADGeometry

translate(vec)[source]

Translate the geometry. Equivalent to self.t_vec += vec.

rotate(matrix=None)[source]

Apply a rotation matrix to t_vec, fs_vec, ss_vec. Equivalent to self.t_vec = np.dot(self.t_vec, matrix.T)

class reborn.detector.PADGeometryList(pad_geometry=None, filepath=None)[source]

Bases: list

A subclass of list that does operations on lists of PADGeometry instances. Is helpful, for example. when getting q vectors for many separate PADs.

Parameters:

pad_geometry (PADGeometry or list of) – The PAD geometry that will form the PADGeometryList.

do_cache = False
append(item)[source]

Override append method. Check the type, name the panel if it has no name.

copy()[source]

Same as the matching method in PADGeometry.

property hash

Return a hash of the geometry parameters. Useful if you want to avoid re-computing things like q_mags.

validate()[source]

Same as the matching method in PADGeometry.

is_different(geom, precision=1e-05)[source]
to_dict_list()[source]

Convert each PADGeometry to a dictionary, return as a list.

from_dict_list(dicts)[source]

Populate elements from list of dictionary objects.

clear_cache()[source]
save(filename)[source]

Save this PADGeometryList in default json format.

load(filename)[source]

Load the data from saved PADGeometryList.

add_group(pads, group_name=None)[source]

Extend the PADGeometryList, and create a group name for the new members. Helpful if you have multiple “detectors” that you wish to combine into a single PADGeometryList.

get_group_indices(group_name)[source]

Get the list indices for a named group.

get_group(group_name)[source]

Return a named group in the form of a PADGeometryList .

set_group(indices, group_name)[source]

Assign a group name to a set of indices.

get_all_groups()[source]

Equivalent to get_group, but sets the argument to all group names. Beware: you may have redundancies!

get_group_names()[source]

Get a list of all group names. Will be empty list if there are no groups.

get_by_name(name)[source]

Return a PADGeometry with a given name.

assign_names()[source]

Make sure that all PADGeometry instances have unique names.

defines_slicing()[source]

False if any of the PADGeometry instances does not have a parent_data_slice or parent_data_shape defined. True otherwise.

property parent_data_shape

Return parent data shape, or None if undefined. Raise ValueError if mis-matched parent data shapes.

change_parent_shape(shape)[source]

See equivalent method in PADGeometry.

reshape(data)[source]

If parent_data_shape is defined, then reshape the data to that shape.

concat_data(data)[source]

Concatenate a list of ndarray instances into a single concatenated 1D ndarray .

split_data(data)[source]

Slice this PAD data from a parent data array.

concat_vecs(data)[source]

Concatenate a list of (N, 3) ndarray instances into a single concatenated (N, 3) ndarray .

property n_pixels

Sums the output of the matching method in PADGeometry

save_json(file_name)[source]

Same as the matching method in PADGeometry.

position_vecs()[source]

Concatenates the output of the matching method in PADGeometry

pixel_corner_position_vecs()[source]

Concatenates the output of the matching method in PADGeometry

average_detector_distance(beam=None, beam_vec=None)[source]

Same as the matching method in PADGeometry, but averaged over all PADs.

set_average_detector_distance(distance, beam=None, beam_vec=None)[source]

Same as the matching method in PADGeometry.

s_vecs()[source]

Concatenates the output of the matching method in PADGeometry

ds_vecs(beam)[source]

Concatenates the output of the matching method in PADGeometry

q_vecs(beam)[source]

Concatenates the output of the matching method in PADGeometry

q_mags(beam)[source]

Concatenates the output of the matching method in PADGeometry

solid_angles()[source]

Concatenates the output of the matching method in PADGeometry

solid_angles1()[source]

Concatenates the output of the matching method in PADGeometry

solid_angles2()[source]

Concatenates the output of the matching method in PADGeometry

polarization_factors(beam)[source]

Concatenates the output of the matching method in PADGeometry

scattering_angles(beam)[source]

Concatenates the output of the matching method in PADGeometry

f2phot(beam)[source]

Concatenates the output of the matching method in PADGeometry

azimuthal_angles(beam)[source]

Concatenates the output of the matching method in PADGeometry

beamstop_mask(beam=None, q_min=None, q_max=None, min_angle=None, max_angle=None, min_radius=None, max_radius=None)[source]

Concatenates the output of the matching method in PADGeometry

edge_mask(*args, **kwargs)[source]

Concatenates the output of the matching method in PADGeometry

streak_mask(*args, **kwargs)[source]

Concatenates the output of the matching method in PADGeometry

zeros(*args, **kwargs)[source]

Concatenates the output of the matching method in PADGeometry

ones(*args, **kwargs)[source]

Concatenates the output of the matching method in PADGeometry

random(*args, **kwargs)[source]

Concatenates the output of the matching method in PADGeometry

poisson(lam=1.0)[source]

Concatenates the output of the matching method in PADGeometry

max_resolution(beam)[source]

Concatenates the output of the matching method in PADGeometry

binned(binning=2)[source]

See corresponding method in PADGeometry.

translate(vec)[source]

See corresponding method in PADGeometry.

rotate(matrix)[source]

See corresponding method in PADGeometry.

center_at_origin()[source]

Translate such that the PADs are roughly centered at the origin. This is lazy; just subtract the average pixel position…

reborn.detector.f2_to_photon_counts(f_squared, beam=None, pad_geometry=None)[source]

Convert computed scattering factors \(F(\vec{q})^2\) into photon counts. This multiplies \(F(\vec{q})^2\) by the incident beam fluence, the classical electron area, the pixel solid angles, and the beam polarization factor.

Parameters:
  • f_squared

  • beam

  • pad_geometry

Returns:

reborn.detector.save_pad_geometry_list(file_name, geom_list)[source]

Save a list of PADGeometry instances as a json file.

reborn.detector.load_pad_geometry_list(file_name)[source]

Load a list of PADGeometry instances stored in json format.

reborn.detector.tiled_pad_geometry_list(pad_shape=(512, 1024), pixel_size=0.0001, distance=0.1, tiling_shape=(4, 2), pad_gap=0)[source]

Make a list of PADGeometry instances with identical panel sizes, tiled in a regular grid.

Parameters:
  • pad_shape (tuple) – Shape of the pads (slow scan, fast scan)

  • pixel_size (float) – Pixel size in SI units

  • distance (float) – Detector distance in SI units

  • tiling_shape (tuple) – Shape of tiling (n tiles along slow scan, n tiles along fast scan)

  • pad_gap (float) – Gap between pad tiles in SI units

Returns: PADGeometryList

reborn.detector.concat_pad_data(data)[source]

Given a list of numpy arrays, concatenate them into a single 1D array. This is a very simple command:

return np.concatenate([d.ravel() for d in data])

This should exist in numpy but I couldn’t find it.

Parameters:

data (list or ndarray) – A list of 2D ndarray s. If data is an ndarray, then data.ravel() is returned

Returns: 1D ndarray

reborn.detector.split_pad_data(pad_list, data)[source]

Given a contiguous block of data produced by the function concat_pad_data, split the data into individual 2D PAD panels.

Parameters:
  • pad_list – A list of PADGeometry instances

  • data – A contiguous array with data values (total pixels to add up to sum of pixels in all PADs)

Returns:

A list of 2D ndarray s

reborn.detector.edge_mask(data, n_edge)[source]

Make an “edge mask”; an array of ones with zeros around the edges. The mask will be the same type as the data (e.g. double).

Parameters:
  • data (2D numpy array) – a data array (for shape reference)

  • n_edge (int) – number of pixels to mask around edges

Returns: ndarray

reborn.detector.subtract_pad_friedel_mate(data, mask, geom)[source]

Subtract the intensities related by Fridel symmetry

class reborn.detector.PADAssembler(pad_geometry=None, centered=True, shape=None, **kwargs)[source]

Bases: object

Assemble PAD data into a fake single-panel PAD. Take the average of pixel values that fall within the re-mapped PAD. This assumes you want to project in the “x-y” plane.

Parameters:
  • pad_geometry (PADGeometryList) – PAD Geometry

  • centered (bool) – If set to False, the resulting re-mapped PAD will not be centered. it will be a “snug fit” to the PAD

  • shape (bool) – The desired shape of the re-mapped PAD. Optional. Use the pixel size to determine binning/shape if shape not set (or set to None).

assemble_data(data)[source]

Given a contiguous block of data, create the fake single-panel PAD.

Parameters:

data (ndarray) – Image data

Returns: ndarray

class reborn.detector.IcosphereGeometry(n_subdivisions=1, radius=1)[source]

Bases: object

Experimental class for a spherical detector that follows the “icosphere” geometry. The Icosphere is generated by subdividing the vertices of an icosahedron. The following blog was helpful: http://sinestesia.co/blog/tutorials/python-icospheres/

The code is quite slow; needs to be vectorized with numpy. There are definitely better spherical detectors - the solid angles of these pixels are not very uniform.

n_subdivisions = 1
radius = 1
compute_vertices_and_faces()[source]

Compute vertex and face coordinates.

class reborn.detector.PolarPADAssembler(*args, **kwargs)[source]

Bases: object

class reborn.detector.RadialProfiler(*args, **kwargs)[source]

Bases: object

reborn.detector.polarization_factors(beam, kout_vecs)[source]
reborn.detector.get_radial_profile(*args, **kwargs)[source]
reborn.detector.save_mask_as_om_h5(mask, pad_geometry, filename)[source]
reborn.detector.save_pad_masks(file_name, mask_list, packbits=True)[source]

Save list of 2D mask arrays in a compressed format. It is assumed that masks consist of values of zero or one. We presently use the numpy.packbits function along with numpy.savez_compressed function.

Note

The file name extension will be ‘.mask’. If you provide a name without an extension, or with a different extension, the extension will be changed. It is recommended that you explicitly provide the extension.

Parameters:
  • file_name (str) – Path to file that will be saved.

  • mask_list (list) – A list of ndarray masks. Will be converted to bool type before saving.

  • packbits (bool) – Specify if numpy.packbits should be used to reduce file size. (Default: True).

Returns: str: File name.

reborn.detector.load_pad_masks(file_name)[source]

Load a mask created using the save_pad_masks function.

Parameters:

file_name (str) – The path to the file you want to open.

Returns: List of ndarray objects with int type.

reborn.detector.pnccd_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the pnCCD detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.cspad_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the CSPAD detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.cspad_2x2_pad_geometry_list(detector_distance=2.4, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the CSPAD detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.jungfrau4m_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the Jungfrau 4M detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.epix10k_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the epix10k detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units.

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.epix100_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by the epix100 detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units.

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.mpccd_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by SACLA’s MPCCD detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units.

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.agipd_pad_geometry_list(detector_distance=0.1, binning=None)[source]

Generate a list of PADGeometry instances that are inspired by EuXFEL’s AGIPD detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units.

  • binning (int) – Binning factor (to make smaller arrays with bigger pixels)

Returns: PADGeometryList

reborn.detector.rayonix_mx340_xfel_pad_geometry_list(detector_distance=0.1, binning=None, return_mask=False)[source]

Generate a list of PADGeometry instances that are inspired by the Rayonix MX340-XFEL detector.

Parameters:
  • detector_distance (float) – Detector distance in SI units.

  • return_mask (bool) – The Rayonix has a hole in the center; setting this to True will return the corresponding mask along with .

Returns: PADGeometryList

reborn.detector.eiger4M_pad_geometry_list(detector_distance=0.1, binning=None, return_mask=False)[source]

Generate a list of PADGeometry instances that are inspired by the Eiger 4M detector at CXLS.

Parameters:

detector_distance (float) – Detector distance in SI units.

Returns: PADGeometryList

reborn.detector.pilatus100k_pad_geometry_list(detector_distance=0.1, binning=None, return_mask=False)[source]

Generate a list of PADGeometry instances that are inspired by the Eiger 4M detector at CXLS.

Parameters:

detector_distance (float) – Detector distance in SI units.

Returns: PADGeometryList

reborn.detector.dict_default(dictionary, key, default)[source]

Sometimes we want to fetch a dictionary value for a given key, but the key might be absent in which case we accept a default value. This function does that.

reborn.source module

Classes related to x-ray sources.

class reborn.source.Beam(file_name=None, beam_vec=array([0, 0, 1]), photon_energy=1.602e-15, wavelength=None, polarization_vec=array([1, 0, 0]), polarization_weight=1, pulse_energy=0.001, diameter_fwhm=1e-06)[source]

Bases: object

A minimal container to gather x-ray beam properties.

Parameters:
  • beam_vec (ndarray) – Direction of incident beam.

  • photon_energy (float) – Photon energy in SI units.

  • wavelength (float) – Wavelength in SI units (an alternative to photon energy).

  • polarization_vec (ndarray) – Direction of the first component of the electric field. Must be orthogonal to the beam vector. Second component is E2 = E1 x B .

  • pulse_energy (float) – Total energy of x-ray pulse.

  • diameter_fwhm (float) – Beam diameter. Default is a tophat beam profile, so this is the tophat diameter.

photon_energy_fwhm = 0
divergence_fwhm = 0
pulse_energy_fwhm = 0
photon_energy = None
diameter_fwhm = None
validate()[source]

Validate this Beam instance. Presently, this method only checks that there is a wavelength.

property hash

Hash the Beam instance in order to determine if the beam properties have changed.

Returns:

int

property beam_profile

In the future this will be a means of specifying the profile of the incident x-rays. The only option is ‘tophat’ for the time being. Possibly in the future we could allow for complex wavefronts.

property beam_vec

The nominal direction of the incident x-ray beam.

property k_in

Incident wavevector.

property polarization_vec

The principle polarization vector \(\hat{E}_1\). This should be orthogonal to the incident beam direction. The complementary polarization vector is \(\hat{E}_2 = \hat{b} \times \hat{E}_1\)

property e1_vec

The principle polarization vector \(\hat{E}_1\).

property e2_vec

The secondary polarization vector \(\hat{E}_2 = \hat{k}_0 \times \hat{E}_1\).

property polarization_weight

The fraction of f of energy that goes into the principle polarization vector specified by the polarization_vec attribute. The fraction of the energy in the complementary polarization is of course (1-f).

property wavelength

Photon wavelength in meters.

property pulse_energy

Pulse energy in J.

property n_photons

Number of photons per pulse.

property fluence

Same as energy_fluence. Don’t use this method.

property photon_number_fluence

Pulse fluence in photons/m^2.

property energy_fluence

Pulse fluence in J/m^2.

is_different(beam, photon_energy_percent=1)[source]
to_dict()[source]

Convert beam to a dictionary. It contains the following keys: - photon_energy - beam_profile - beam_vec - polarization_vec - polarization_weight - photon_energy_fwhm - pulse_energy - divergence_fwhm - diameter_fwhm - pulse_energy_fwhm

from_dict(dictionary)[source]

Loads beam from dictionary. This goes along with the to_dict method.

copy()[source]

Make a copy of this class instance.

save_json(file_name)[source]

Save the beam as a json file.

load_json(file_name)[source]

Save the beam as a json file.

save(file_name)[source]

Save the beam to file.

load(file_name)[source]

Load the beam from a file.

reborn.source.load_beam(file_path)[source]

Load a beam from a json file (loaded with Beam.load_json() method)

Parameters:

file_path (str) – Path to beam json file

Returns: Beam

reborn.source.save_beam(beam, file_path)[source]

Save a Beam to a json file (saved with Beam.save_json() method)

Parameters:
  • beam (Beam) – The Beam instance to save.

  • file_path (str) – Where to save the json file.

reborn.source.float_tuple(val)[source]

Convert to float. If object is a tuple, convert each element to a float.

Parameters:

val – Input to convert to floats.

Returns:

reborn.utils module

Some utility functions that might be useful throughout reborn. Don’t put highly specialized functions here.

reborn.utils.log_to_terminal(level: (<class 'int'>, <class 'str'>) = 10)[source]

For convenience, create a logger that prints to the terminal.

reborn.utils.print_all_loggers_and_handlers(logger_name=None)[source]
reborn.utils.resource_path(path=None)[source]

Fetch the path to a resource file in reborn.

Parameters:
  • path (str or path) – Path to resource, relative to the reborn package base directory (NOT the base directory of

  • repo!). (the git)

reborn.utils.docs()[source]

Open the reborn documentation in a web browser (if available).

reborn.utils.ensure_list(obj)[source]

Make sure that some object is a list. This is helpful because, for example, we frequently write code around the assumption that detector geometry comes in the form of a list of PADGeometry instances. However, it is also not so uncommon to have a single PADGeometry.

This function does the following simple task:

def ensure_list(obj):
    if isinstance(obj, list):
        return obj
    if isinstance(obj, tuple):
        return list(obj)
    return [obj]
Parameters:

obj (object) – The object that we want to ensure is a list.

Returns: list

reborn.utils.vec_norm(vec)[source]

Compute normal vectors, which have lengths of one.

Parameters:

vec (ndarray) – Input vectors. Array shape: (N, 3).

Returns:

New unit vectors. Array shape: (N, 3).

Return type:

(ndarray)

reborn.utils.vec_mag(vec)[source]

Compute the scalar magnitude of an array of vectors.

Parameters:

vec (ndarray) – Input array of vectors, shape (N, 3)

Returns:

Scalar vector magnitudes

Return type:

ndarray

reborn.utils.vec_shape(vec)[source]

Ensure that an array has the proper shape that is expected of 3-vector arrays. They should always be 2-dimensional, with shape (N, 3).

Parameters:

vec (ndarray) – The vector array.

Returns:

ndarray with shape (N, 3)

reborn.utils.random_rotation()[source]

Create a random rotation matrix.

from scipy.spatial.transform import Rotation
rotmat = Rotation.random().as_matrix()'
reborn.utils.rotation_about_axis(theta, vec)[source]

This needs to be tested. It was taken from https://stackoverflow.com/questions/17763655/rotation-of-a-point-in-3d-about-an-arbitrary-axis-using-python

Parameters:
  • theta (float) – Rotation angle

  • vec (numpy array) – 3D vector specifying rotation axis

Returns (numpy array): The shape (3, 3) rotation matrix

reborn.utils.random_unit_vector()[source]

Generate a totally random unit vector.

Returns:

ndarray

reborn.utils.random_beam_vector(div_fwhm)[source]

A random vector for emulating beam divergence. Generates a random normal vector that is nominally along the [0,0,1] direction but with a random rotation along the [1,0,0] axis with given FWHM (Gaussian distributed and centered about zero) followed by a random rotation about the [0,0,1] axis with uniform distribution in the interval [0,2*pi).

Parameters:

div_fwhm (float) – FWHM of divergence angle. Assuming Gaussian, where sigma = FWHM / 2.3548

Returns:

(numpy array) of length 3

reborn.utils.triangle_solid_angle(r1, r2, r3)[source]

Compute solid angle of a triangle whose vertices are r1,r2,r3, using the method of Van Oosterom, A. & Strackee, J. Biomed. Eng., IEEE Transactions on BME-30, 125-126 (1983).

Parameters:
  • r1 (ndarray) – Vectors to vertices 1; array of shape (N, 3)

  • r2 (ndarray) – Vectors to vertices 1; array of shape (N, 3)

  • r3 (ndarray) – Vectors to vertices 1; array of shape (N, 3)

Returns:

(ndarray) of length N with solid angles

reborn.utils.memoize(function)[source]

This is a function decorator for caching results from a function. It is used, for example, to avoid re-loading data files containing scattering factors. We assume that your computer has enough RAM to handle this, and we assume that the developers will not abuse this feature. FIXME: This needs to be tested. It was blindly copied from the internet… FIXME: Consider adding a configuration to reborn that disallows the use of memoize.

reborn.utils.max_pair_distance(*args, **kwargs)[source]

Depreciated. Use reborn.utils.vectors.max_pair_distance

reborn.utils.make_label_radial_shell(r_bin_vec, n_vec)[source]

For fast radial statistics calculations - done through a precomputed label array.

Produce a 3D volume with concentric shells of thickness specified by r_bin_vec. Each shell is labelled incrementally by integers starting with 1 at the centre. (the label zero is reserved for masked values in the volume).

Voxels outside the maximum radius is given a label of zero.

Parameters:
  • units (r_bin_vec - Radii of the shells - in voxel)

  • volume (n_vec - Shape of the desired)

Returns:

labels_radial

reborn.utils.radial_stats(f, labels_radial, n_radials, mode)[source]

Calculate the statistics of the voxels in each shell.

Input:

f - The input 3D array of numbers labels_radial - The labels n_radials - Maximum label value mode - The desired statistics that we wish to calculate

Output:

radial_stats_vec

reborn.utils.get_FSC(f1, f2, labels_radial, n_radials)[source]

Calculate the Fourier shell correlation (FSC) between two 3D numpy arrays.

reborn.utils.atleast_1d(x)[source]

Expand dimensions of ndarray. Add dimensions to the left-most index.

reborn.utils.atleast_2d(x)[source]

Expand dimensions of ndarray. Add dimensions to the left-most index.

reborn.utils.atleast_3d(x)[source]

Expand dimensions of ndarray. Add dimensions to the left-most index.

reborn.utils.atleast_4d(x)[source]

Expand dimensions of ndarray. Add dimensions to the left-most index.

reborn.utils.binned_statistic(x, y, func, n_bins, bin_edges, fill_value=0)[source]

Similar to binned_statistic but faster because regular bin spacing is assumed, and sparse matrix algorithms are used. Speedups of ~30-fold have been observed.

Based on the discussion found here: https://stackoverflow.com/questions/26783719/efficiently-get-indices-of-histogram-bins-in-python

Parameters:
  • x (ndarray) – The coordinates that correspond to values y below. Bin indices derive from x.

  • y (ndarray) – The values that enter into the statistic.

  • func (function) – The function that will be applied to values in each bin

  • n_bins (int) – Desired number of bins

  • bin_edges (tuple of floats) – The min and max edges of bins (edges, not the centers, of the bins)

  • fill_value (float) – Initialize output array with these values.

Returns:

ndarray

reborn.utils.get_caller(n=0)[source]

Get the name of the function that calls this one.

reborn.utils.check_file_md5(file_path, md5_path=None)[source]

Utility for checking if a file has been modified from a previous version.

Given a file path, check for a file with “.md5” appended to the path. If it exists, check if the md5 hash saved in the file matches the md5 hash of the current file and return True. Otherwise, return False.

Parameters:
  • file_path (str) – Path to the file.

  • md5_path (str) – Optional path to the md5 file.

Returns:

bool

reborn.utils.write_file_md5(file_path, md5_path=None)[source]

Save the md5 hash of a file. The output will be the same as the original file but with a ‘.md5’ extension appended.

Parameters:
  • file_path (str) – The path of the file to make an md5 from.

  • md5_path (str) – Optional path to the md5 file.

Returns:

the md5

Return type:

str

reborn.utils.git_sha()[source]

Return the SHA of the git repo is in the current directory. Return None if the repo is not totally clean. Useful if you wish to keep track of the git version that produced your results.

Returns: str

reborn.utils.google_docstring_test()[source]

This is an example docstring for developers. This function does nothing.

You might link to other reborn docs, such as reborn.detector.PADGeometry . Linking also works for some external packages, for example np.median.

There are various shortcuts in doc/conf.py, such as PADGeometry and Henke et al. (1993).

You can put an equation inline like this \(f(q)\), or on a separate line like this:

(4)\[a_i = \sum_n f_n \exp(-i \vec{q}_i \cdot (\mathbf{R} \vec{r} + \vec{U}))\]

Note

This is a note to emphasize something important.

Parameters:
  • data (ndarray or list of ndarray) – Data to get profiles from.

  • beam (Beam) – Beam info.

  • pad_geometry (PADGeometryList) – PAD geometry info.

  • mask (ndarray or list of ndarray) – Mask (one is good, zero is bad).

  • n_bins (int) – Number of radial bins.

  • q_range (tuple of floats) – Centers of the min and max q bins.

  • statistic (function) – The function you want to apply to each bin (default: np.mean).

Returns:

  • statistic (ndarray) – Radial statistic.

  • bins (ndarray) – The values of q at the bin centers.

Return type:

(tuple)

Module contents

reborn python package for simulation and analysis of x-ray diffraction.