.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/grp1_ArrSchema/plot_e11_using_schema.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_grp1_ArrSchema_plot_e11_using_schema.py: Using Annotated Arrays ====================== The primary use cases of AnnotatedArrays are to documenting datamodels for users and developers, annotate functions which are expecting specific kinds of data, validate data expected to conform to a paritcular model, and to facilitate instantiation datamodels with complex structures. .. GENERATED FROM PYTHON SOURCE LINES 12-17 .. code-block:: Python import rmellipse as rme import numpy as np from pydantic import BaseModel, ConfigDict .. GENERATED FROM PYTHON SOURCE LINES 18-28 Instantiation ------------- Having a defined schema makes it easier to initialized empty arrays for a given datatype by using the AnnotatedArray.zero() method. Coordinate dimensions can be supplied, along with metadata you may need. Information that is expected. For example, TimeDomainVoltage2x2 is a rather complex data structure with a lot of requirements, including specific metadata. Using the AnnotatedArray format, you can generate an empty data set fairly concisely. .. GENERATED FROM PYTHON SOURCE LINES 28-72 .. code-block:: Python class MeasurementMetadata(BaseModel): # Enable extra fields model_config = ConfigDict(extra='allow') operator: str temperature_celcius: float class TimeAndFrequencySweep(rme.AnnotatedArray): schema = rme.ArraySchema( shape=('N', 'M'), dims=('time', 'frequency'), dtype=float, coords={ 'time': rme.CoordinateSchema(dtype=float, units='s'), 'frequency': rme.CoordinateSchema(dtype=float, units='GHz'), }, attrs=MeasurementMetadata, ) voltages = TimeAndFrequencySweep.zeros( time=np.linspace(0, 100, 100), frequency=np.linspace(1, 10, 10), attrs={ 'operator': 'reader', 'temperature_celcius': 23.5, }, ) current = TimeAndFrequencySweep.zeros( time=np.linspace(0, 100, 100), frequency=np.linspace(1, 10, 10), attrs={ 'operator': 'reader', 'temperature_celcius': 22.5, }, ) # fill with random values voltages[...] = np.random.rand(*voltages.shape) current[...] = np.random.rand(*current.shape) .. GENERATED FROM PYTHON SOURCE LINES 73-78 Validation ---------- If you already have an array that you think should perform to a particular schema, you can try validating it. .. GENERATED FROM PYTHON SOURCE LINES 78-87 .. code-block:: Python my_sample = np.zeros((2, 2)) try: TimeAndFrequencySweep(my_sample).validate() except rme.ValidationError as e: print(f'array fails validation for : {e}') .. GENERATED FROM PYTHON SOURCE LINES 88-99 Annotating Functions -------------------- Since the type is available, you can use it as part of Python's type annotation system to help document your code. For example, annotating functions. Suppose we had a dataset of multiple time sweeps of voltage and current measurements at multiple different frequencies. We wanted to determine what frequency the time average power was the highest, and what the approximate temperature was. We could write a function to do that, and then annotate the inputs and outputs of that function using the AnnotatedArray types we defined. .. GENERATED FROM PYTHON SOURCE LINES 99-137 .. code-block:: Python def max_time_average_power_frequency( voltages: TimeAndFrequencySweep, current: TimeAndFrequencySweep ) -> tuple[float, float]: """ Get the frequency corresponding to the maximum time average power. Returns the frequency (in GHz) and the approximate temperature based on measurement metadata. Parameters ---------- voltages : TimeAndFrequencySweep Voltage measurements. current : TimeAndFrequencySweep Current measurements. Returns ------- frequency : float Frequency where the most time average power was measured temperature : float Approximate temperatue from metadata. """ mean_temp = np.mean( [voltages.attrs['temperature_celcius'], current.attrs['temperature_celcius']] ) power = voltages * current time_average = power.mean(dim='time') i_max = np.argmax(time_average.data) return float(time_average.frequency[i_max]), float(mean_temp) freq, temp = max_time_average_power_frequency(voltages, current) print(freq, temp) .. _sphx_glr_download_auto_examples_grp1_ArrSchema_plot_e11_using_schema.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_e11_using_schema.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_e11_using_schema.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_e11_using_schema.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_