de_twin.specimen.Specimen#
- class de_twin.specimen.Specimen(config=None)[source]#
Bases:
objectA 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])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.Optional FieldMap layers this specimen can fill (descan/strain for FIB lamellae).
set_options(**options)Change options live.
update(time_s[, holder])Advance the scene clock to
time_sand integrate the thermal budget.Attributes
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).
- 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.
- 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
- update(time_s, holder=None)[source]#
Advance the scene clock to
time_sand integrate the thermal budget.The temperature is
holder.temperature_cwhen a holder state is given (and is not akind == "none"placeholder), elseoptions.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:
time_s (float)
holder (HolderState | None)
- 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:
- required_layers()[source]#
Optional FieldMap layers this specimen can fill (descan/strain for FIB lamellae).
- Return type:
- rasterize(view, layers=frozenset({}), *, span_px=None, threads=1)[source]#
The specimen on
view.span_px: the size of the whole view whenviewis 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.