Analyse the Results

The Analysis is tightly bound with the Measurement because this will determine how the data is shaped and which features you want to extract from it. Therefore, the base class should be extended as explained in this tutorial:

However, in the following example, the base class will be used to show the basic functionality.

Generate Data

Since the MA8X8 interface was used in the previous examples, the initialized Dataset should be filled with data accordingly. With the HDF5 file from the Basic Usage example, this script should do the job:

import numpy as np
from cohesivm.database import Database

# load existing data and corresponding metadata
db = Database('Test.h5')
dataset = db.filter_by_sample_id('test_sample_42')[0]
metadata = db.load_metadata(dataset)

# create a new dataset to not interfere with previous examples
dataset = db.initialize_dataset(metadata)

# iterate over contact_ids and save data arrays
for contact_id in metadata.contact_ids:
    db.save_data(np.array(range(10), dtype=[('Voltage (V)', float)]), dataset, contact_id)

# load the data
data, metadata = db.load_dataset(dataset)

Define Functions

Next, functions and plots must be defined:

>>> def maximum(contact_id: str) -> float:
...     return max(data[contact_id]['Voltage (V)'])
>>> functions = {'Maximum': maximum}
>>> plots = {}  # will be spared for simplicity (refer to the tutorial instead)

This approach seems too complex for what the function does, but it makes sense if you consider that this should be implemented in a separate Analysis class. There, the data is stored as a property and the functions (i.e., methods) have direct access to it. Due to the use of structured arrays, the label also needs to be stated explicitly. But, again, this will normally be available as a property of the class.

With vs. without Metadata

In the following, the class is initialized with and without using the Metadata from the dataset. The former approach has the advantage that all available fields could be accessed by the functions, e.g., values that are stored in the measurement_settings.

>>> from cohesivm.analysis import Analysis
# without metadata, the contact_position_dict must be provided
>>> analysis = Analysis(functions, plots, data, metadata.contact_position_dict)
# with metadata, additional metadata fields can be used in the analysis
>>> analysis = Analysis(functions, plots, (data, metadata))
>>> analysis.metadata.measurement_settings['illuminated']
True

Use the Class

The main purposes of the Analysis are bundling functions for quick data analysis and providing the framework for the Analysis GUI. But it is also useful to generate maps of analysis results:

>>> analysis.generate_result_maps('Maximum')[0]
array([[9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.],
       [9., 9., 9., 9., 9., 9., 9., 9.]])

As expected, the maximum value of the generated data is placed in a 2D numpy array on locations corresponding to the contact_positions.