de_twin.specimen.Specimen#

class de_twin.specimen.Specimen(config=None)[source]#

Bases: object

A deterministic virtual specimen: holder + preparation + time evolution.

>>> s = Specimen(SpecimenConfig(seed=1))
>>> fm = s.rasterize(ViewWindow(center_um=(0.0, 0.0), pixel_um=0.002, shape=(256, 256)))
Parameters:

config (SpecimenConfig | None)

__init__(config=None)[source]#
Parameters:

config (SpecimenConfig | None)

Methods

__init__([config])

bounds_um()

crystallinity(grain_id)

Crystalline fraction in [0, 1] per grain id.

drift_um()

Accumulated specimen drift (um) at the current time index.

features()

home_um()

Stage position (µm) a twin starts at: somewhere there is specimen to see.

nearest_feature(x_um, y_um)

overview([shape])

Whole-holder projected-thickness image (DebugOverview), float32 nm, 5 % padding.

rasterize(view[, layers, span_px, threads])

The specimen on view.

required_layers()

Optional FieldMap layers this specimen can fill (descan/strain for FIB lamellae).

reset_clock()

set_options(**options)

Change options live.

update(time_s[, holder])

Advance the scene clock to time_s and integrate the thermal budget.

Attributes

crystallization_enabled

raster_is_local

Every raster pixel depends only on where it is and the pixel size, not on the rest of the view, so a raster can be assembled from rasters of its parts (the renderer does that on a stage move; tests/test_render_caches.py checks it).

temperature_c

thermal_budget_s

time_dependent

time_index

time_s

raster_is_local = True#

Every raster pixel depends only on where it is and the pixel size, not on the rest of the view, so a raster can be assembled from rasters of its parts (the renderer does that on a stage move; tests/test_render_caches.py checks it).

home_um()[source]#

Stage position (µm) a twin starts at: somewhere there is specimen to see.

The stage origin is often not: on a waffle grid it is a bar, on a heating chip the frame, on a sparse grid a bare patch of film. So: the placement area (grid square, well, lamella, chip window) nearest the origin whose film is intact where the holder has a film, and inside it the largest particle cluster when the preparation clusters, else the area’s centre.

Return type:

tuple[float, float]

set_options(**options)[source]#

Change options live. World-changing options regenerate the scene (and reset the thermal budget, as a new specimen is a new experiment); others apply in place.

Return type:

None

property time_s: float#
property time_index: int#
property thermal_budget_s: float#
property temperature_c: float#
property crystallization_enabled: bool#
property time_dependent: bool#
update(time_s, holder=None)[source]#

Advance the scene clock to time_s and integrate the thermal budget.

The temperature is holder.temperature_c when a holder state is given (and is not a kind == "none" placeholder), else options.specimen_temperature_c. It is taken as constant over the interval since the previous update. The first call only sets the reference time. Time going backwards moves the clock but never un-crystallises.

Parameters:
Return type:

None

reset_clock()[source]#
Return type:

None

crystallinity(grain_id)[source]#

Crystalline fraction in [0, 1] per grain id.

Grain -1 on crystalline material means “not yet nucleated” (glassy, 0) in a time-evolving in-situ scene, and “unresolved fine grains” (powder, 1) elsewhere.

Return type:

ndarray

bounds_um()[source]#
Return type:

tuple[float, float, float, float]

required_layers()[source]#

Optional FieldMap layers this specimen can fill (descan/strain for FIB lamellae).

Return type:

frozenset

rasterize(view, layers=frozenset({}), *, span_px=None, threads=1)[source]#

The specimen on view. span_px: the size of the whole view when view is a piece of one (the scene draws a piece as it draws the whole). threads > 1 rasterises row strips of a large view in parallel (the pixels are local, so the strips are the rows of the whole), when numba’s threading layer allows it.

Parameters:
Return type:

FieldMap

drift_um()[source]#

Accumulated specimen drift (um) at the current time index.

Return type:

tuple[float, float]

features()[source]#
Return type:

list[Feature]

nearest_feature(x_um, y_um)[source]#
Parameters:
Return type:

Feature | None

overview(shape=(1024, 1024))[source]#

Whole-holder projected-thickness image (DebugOverview), float32 nm, 5 % padding.

Return type:

ndarray