Params

The adjustable model parameters, and the transform that turns them into physical quantities.

Refinement varies a set of unbounded numbers, but the physical quantities they stand for are bounded: atomic displacement parameters (ADPs) must stay positive-definite, site occupancies lie in [0, 1], and atoms sitting on symmetry elements have some coordinates fixed. Rather than restrict the optimizer, we store each quantity as an unbounded “raw” number and apply a fixed transform (constrain()) that maps it onto its physical range. RefinableParams holds the raw numbers the optimizer varies; PhysicalState holds the physical quantities the diffraction calculation consumes.

type diffBloch.params.AdpKind = Literal['Uiso', 'Uani', 'missing']
class diffBloch.params.ConstraintSpec(position_projection: Tensor, position_offset: Tensor, occupancies: Tensor, adp_kind: tuple[AdpKind, ...] | None = None, adp_constraints: AdpConstraints | None = None, reciprocal_basis: Tensor | None = None)[source][source]

Bases: object

The fixed information constrain() needs to turn raw numbers into physical quantities.

reciprocal_basis (B = reciprocal_cell, rows a*, b*, c*) is required whenever ADPs are converted: it carries the cell frame used to express the ADPs in the reciprocal U* frame that diffBloch.core.scattering.structure_factors() expects.

position_projection is a (N, 3, 3) per-atom site-symmetry projector P and position_offset the (N, 3) on-site offset (I - P) @ x0; together they constrain the atomic coordinates via P @ raw + offset in diffBloch.core.constraints.apply_symmetry_projection(), holding each atom on its special-position manifold. A general-position atom has P = I (unconstrained); an axis-aligned special position reduces to a diagonal P (the freeze mask); a coupled site (x = y) needs the off-diagonal projector. Built by diffBloch.io.symmetry_setup.symmetry_constraints().

adp_constraints holds, per atom, the site-symmetry Uij equalities Uij[i,j] = coeff * Uij[src_i, src_j] (empty per atom when the ADP is unconstrained; None when no ADP constraints apply at all), enforced by diffBloch.core.constraints.apply_adp_constraints() in the CIF Uij frame.

position_projection: Tensor
position_offset: Tensor
occupancies: Tensor
adp_kind: tuple[AdpKind, ...] | None = None
adp_constraints: AdpConstraints | None = None
reciprocal_basis: Tensor | None = None
type diffBloch.params.Device = device | str
class diffBloch.params.PhysicalState(positions: Tensor, uij_star: Tensor, occupancies: Tensor)[source][source]

Bases: object

The physical quantities the diffraction calculation consumes, after bounds are applied.

uij_star is the ADP tensor for the asymmetric-unit atoms, already expressed in the reciprocal U* frame (Uani via the d* relation, Uiso via Uiso G*), so diffBloch.core.scattering.structure_factors() can use it directly with no further frame conversion.

positions: Tensor
uij_star: Tensor
occupancies: Tensor
class diffBloch.params.RefinableParams(asu_positions: Tensor, uij_raw: Tensor | None = None, u_iso_raw: Tensor | None = None, occupancy_raw: Tensor | None = None)[source][source]

Bases: object

The adjustable numbers the optimizer varies, before physical bounds are applied.

Each field is an unbounded tensor; the physical bounds (positivity, [0, 1], positive-definite ADPs) are applied later by constrain(). An optional field is None when that quantity is not being refined.

asu_positions: Tensor
uij_raw: Tensor | None = None
u_iso_raw: Tensor | None = None
occupancy_raw: Tensor | None = None
to(device: Device) RefinableParams[source][source]

Move every present parameter tensor to device (the device knob’s single primitive).

params.asu_positions.device is the authoritative device for the whole forward model – constrain() and the engine co-locate every invariant (spec projector, ASU plan, scattering grid, beam sets) onto it at the use site – so placing the params on an accelerator is all it takes to run there. A no-op (returns tensors already on device) when nothing moves, so to("cpu") on a CPU params is an identity.

diffBloch.params.constrain(params: RefinableParams, spec: ConstraintSpec) PhysicalState[source][source]

Apply the crystallographic constraints, mapping raw parameters to the physical state.

This is the hard-constraint layer on the raw parameters: per-atom site-symmetry position projection, ADP site-symmetry equalities, and positivity/bounded transforms (occupancy, ADP). It produces the crystallographically valid PhysicalState, which the refinement objective may further transform – molecular hard constraints (e.g. hydrogen riding, a future ConstraintTransform layer) – before the diffraction term and soft penalties (diffBloch.engine.forward.RefinementEngine.objective_value()).