Metric#

class nextnano_optimizers.metric.Metric(input_length=None, output_length=None, extraction_function: Callable | None = None, input_shape=None, output_shape=None)#

Bases: object

Defines how simulation output datafiles are converted into numerical objective values using a user-defined extraction function.

Supports both single-objective and multi-objective optimization.

Parameters:
input_shapetuple of int, optional

Shape of the array of nextnanopy.DataFile objects passed to the extraction function: (k,) without sweep or (k, n1, n2, ...) with sweep, where k is the number of target output files and n1, n2, etc. are the sweep dimensions. Mutually exclusive with input_length.

input_lengthint, optional

Shorthand for input_shape=(input_length,), only usable without sweep. Mutually exclusive with input_shape.

output_shapetuple of int, optional

Shape of the array returned by the extraction function. Must be one-dimensional: (1,) for single-objective optimization or (p,) for multi-objective optimization with p objectives.

output_lengthint, optional

Shorthand for output_shape=(output_length,). Mutually exclusive with output_shape.

extraction_functioncallable, optional

User-defined function f(dfiles) -> numpy.ndarray that converts the array od DataFile objects into a one-dimnesional array of objective values. Defaults to default_extractor.

Attributes:
input_shapetuple of int

Shape of the array of nextnanopy.DataFile objects passed to the extraction function.

output_shapetuple of int

Shape of the array returned by the extraction function.

extraction_functioncallable

User-defined function f(dfiles) -> numpy.ndarray that converts the array od DataFile objects into a one-dimnesional array of objective values.

input_lengthint

First dimension of input_shape (= number of target output files k).

output_lengthint

First dimension of output_shape (= number of objectives).

Examples

Without sweep

Define an extraction function that calculates the confinement energy of the first excited state:

>>> import numpy as np
>>> def extract_confinement_energy(datafiles):
...     band_edge = datafiles[0].variables["Gamma"].value
...     energies = datafiles[1].variables["Energy"].value
...     return np.array([band_edge.max() - energies[1]])
>>> metric = Metric(
...     input_shape=(2,),
...     output_shape=(1,),
...     extraction_function=extract_confinement_energy,
... )

With sweep

For an IO instance configured with sweep={"temperature": [200, 300, 400]}, calculate the average confinement energy across the three temperatures:

>>> def extract_average_confinement(datafiles):
...     confinement = []
...     for i in range(3):
...         band_edge = datafiles[0, i].variables["Gamma"].value
...         energies = datafiles[1, i].variables["Energy"].value
...         confinement.append(band_edge.max() - energies[1])
...     return np.array([np.mean(confinement)])
>>> metric = Metric(
...     input_shape=(2, 3),
...     output_shape=(1,),
...     extraction_function=extract_average_confinement,
... )
extract(input_datafiles, *args, **kwargs)#

Computes the metric array from the input datafiles.

Parameters:
input_datafilesnumpy.ndarray or list

ndarray of shape input_shape (object dtype, elements are DataFiles), or a plain list for backward-compatible 1D-input callers.

Returns:
numpy.ndarray

Array of shape output_shape returned by the extraction function.

Raises:
ValueError

If input_datafiles’ shape (or length, for a plain list) does not match input_shape, or if the extraction function’s result shape does not match output_shape.

TypeError

If the extraction function does not return a numpy.ndarray.