Estimator#
- class torchsim.Estimator(acquisition=None)[source]#
Bases:
ModuleWhat every mapping method is, and the machinery all of them share.
DictionaryMatcher,LookupTable,NonlinearLeastSquaresandPERKare all one of these. What they inherit is the whole problem statement –fit()naming the unknowns and drawing the training set fromacquisition,map()returning one named map per unknown – so a method differs from the next only in what it does with plain tensors.Writing another one is those two tensor steps. Subclass this, take the method’s own settings in the constructor, and implement
_fit_arrays()and_estimate_arrays(), which see signals and parameters as matrices and know nothing about names, subspaces or simulators. Everything above them then works unchanged.- Parameters:
acquisition (Simulator, optional) – The sequence being inverted, with any tissue property that is neither unknown nor measured already fixed on it. Left out where the estimator is given signals directly.
Methods
Fit the estimator over a sampling of the tissue it will meet.
Map coefficients that are already in this estimator's basis.
Estimate the tissue a measurement came from.
Simulate a training set: signals, unknowns, and knowns.
The standard deviation the measurement noise leaves on each map.
- property unknown#
The properties being estimated, in the order the maps come back.
- property known#
The properties measured separately, in the order they are given.
- property subspace#
The temporal basis in use, or
Noneif the estimator works in full.
- property trained#
Whether the estimator has what it needs to map.
A dictionary handed straight to the constructor counts, which is why this consults the subclass rather than only recording that
fit()was called.
- fit(unknown=None, *, known=None, noise_std=0.0, rank=None, subspace=None, seed=None, samples=None, chunk=_CHUNK, signals=None, parameters=None, **ranges)[source]#
Fit the estimator over a sampling of the tissue it will meet.
- Parameters:
unknown (mapping, optional) – The properties being estimated, as
{name: (low, high)}to draw uniformly over, or an array of values to use as given. The order is the order of the maps that come back. Naming them as keywords instead is the same thing and is usually shorter; a mapping is the way to name one that collides with a keyword here.known (mapping or torch.Tensor, optional) – Properties measured separately, as
{name: range}or{name: values}. They are drawn over here and reach the simulator, so the training signals carry their effect, and the measured maps are given again tomap(). A tensor alongsidesignals, where the columns are given outright.noise_std (float or torch.Tensor, optional) – Standard deviation of the noise added to the training signals, in the units the signal is in – a fully relaxed voxel is 1. This is what teaches a method how far to trust a measurement, so it should be the noise the scan actually has.
rank (int, optional) – Fit a temporal
Subspaceof this rank to the training signals and work in it. Every contrast dropped is arithmetic neither training nor mapping has to do;subspacereports what the compression kept.subspace (Subspace, optional) – Work in a basis fitted elsewhere rather than fitting one here – the one another estimator carries, or one
simulate_subspace()produced. This is what lets a reconstruction and the estimator that reads its coefficients agree on the basis by construction. Not withrank, which asks for a basis to be fitted.seed (int, optional) – Seed for the training draw.
samples (int, optional) – How many tissues to draw. Stating a property as an array of values fixes this, so it may be left out; where everything is a range to draw from, it defaults to ten thousand.
chunk (int, optional) – How many to simulate at a time.
signals (torch.Tensor, optional) –
(samples, contrasts)given outright, instead of simulated. The acquisition is then not consulted andmap()returns a tensor rather than named maps, unless names were given as well.parameters (torch.Tensor, optional) –
(samples, unknowns), alongsidesignals.ranges – The unknown properties, named as keywords.
- Return type:
This estimator, fitted.
- Raises:
RuntimeError – If nothing is given to fit from: no signals, and no acquisition to simulate them.
ValueError – If a name is both unknown and known, if a range is not a pair, if
rankis not positive, or if bothrankandsubspaceare given.
- training_set(samples, *, chunk=_CHUNK)[source]#
Simulate a training set: signals, unknowns, and knowns.
Memory is
samplesby contrasts, because the signals are held once rather than resimulated for each pass a method makes over them. The properties are the onesfit()was given, so this is what a caller wanting the training signals themselves calls after fitting.- Parameters:
- Returns:
(signals, parameters, known), the lastNonewhen nothing is measured separately.- Return type:
- Raises:
RuntimeError – If the estimator has no acquisition, or was never told what is unknown.
ValueError – If
samplesorchunkis not positive, or if an array given for a property has a different length.
- map(volume, known=None, *, uncertainty=False)[source]#
Estimate the tissue a measurement came from.
- Parameters:
volume (array-like) –
(..., contrasts). Every leading axis is the voxel axis and comes back on the maps unchanged.known (mapping or torch.Tensor, optional) – The measured maps, under the names the estimator was given. Each is broadcast to the voxel shape.
uncertainty (bool, optional) – Also return the standard deviation the noise leaves on each map. See
uncertainty_of()for what that number is and what it is not. Not every method can state one.
- Returns:
{name: map}where the estimator was told what it is solving for, each shaped likevolumewithout its contrast axis. Where it was fitted from bare arrays, the parameter columns as a tensor. Withuncertainty=True, a pair of those – the maps, and the standard deviations beside them.- Return type:
dict or torch.Tensor
- Raises:
RuntimeError – If the estimator has not been fitted.
NotImplementedError – If
uncertaintyis asked of a method that does not state one.ValueError – If a measured map is missing, or has the wrong voxel count.
- forward(volume, known=None, *, uncertainty=False)[source]#
Alias of
map(), so a fitted estimator is callable.
- uncertainty_of(volume, known=None)[source]#
The standard deviation the measurement noise leaves on each map.
The noise
fit()was told about, propagated through the estimate this method makes – so it says how much the answer would move if the scan were repeated, and it is a property of the method as much as of the sequence.It is not the error. An estimator that is biased is biased the same way in every realization, so repeating the measurement never reveals that part and this number does not contain it. Read against
crlb(), which is the lowest standard deviation an unbiased estimate could have, it says how much of the distance to the truth the acquisition is responsible for.- Parameters:
- Returns:
One standard deviation per unknown, shaped like the maps.
- Return type:
dict or torch.Tensor
- Raises:
NotImplementedError – If this method does not state one.
- from_coefficients(coefficients, known=None)[source]#
Map coefficients that are already in this estimator’s basis.
A subspace reconstruction solves for the coefficients directly and never forms the contrast images, so what it returns is already projected.
map()would project it a second time; this does not. The basis it is in issubspace, which is also what the reconstruction was given.- Parameters:
coefficients (array-like) –
(..., rank). Every leading axis is a voxel axis.known (mapping, optional) – The measured maps, as for
map().
- Returns:
{name: map}, shaped likecoefficientswithout its last axis.- Return type:
- Raises:
RuntimeError – If the estimator has not been fitted, or was fitted without a rank, in which case there is no basis for these to be in.
ValueError – If the last axis is not the rank of that basis.