Skip to content

HSPEP1: Save models in the same hdf5 file as the data

francisco-dlp edited this page Dec 10, 2013 · 1 revision
key value
Status Active
Author Magnus, Francisco
Created 8th December, 2013
Updated 10th December, 2013
Discussion Issue #112
Implementation

Background

Currently HyperSpy models cannot be saved, only the parameter value arrays can be saved using the save_parameters method. Therefore, to recreate a model the user must save the commands used to create it to a file and the parameter values to a different file. This is inconvenient and brittle because there is no way to guarantee that the script will be able to recreate the model in future versions of HyperSpy.

Proposed feature

HyperSpy should be able to save a model to the same file that contains the data and loading the file should recreate the model automatically. Workflow example:

m = s.create_model("amodel") # This returns a Model instance. The instance is also stored in mapped_parameters.models.amodel
# [Create components, fit model to data...]
s.save("my_data_fitted")
s = load("my_data_fitted.hdf5") # Loading should recreate all models
m = s.mapped_parameters.models.amodel

Implementation details

Write an as_dictionary method for all model objects (Model, Component, Parameter) which can "convert" the object into a dict. The __init__ method of these objects should be able to recreate the object from the dict e.g:

def __init__(..., object_dict=None):
    if component_dict:
        self._dict_to_object(object_dict)
    else:
        # (normal initiziation)

On saving to hdf5, the hdf5 writer calls {Model|Component|Parameter}.as_dictionary() on encountering a {Model|Component|Parameter} instance. Model.as_dictionary returns a dictionary containing all the information needed to recreate the model, including all Component instances. Component.as_dictionary returns a dictionary with all the information needed to recreate the component, including all Parameter instances. and Parameter.as_dictionary returns a dictionary with all the information required to recreate the Parameter:

model.as_dictionary() returns:

{   "model_attr1" : value1,
    "model_attr2" : value2,
    # ...
    "model_attrn" : valuen,
    "components" : [component1, component2, ..., componentn]}

component.as_dictionary() returns:

{   "component_attr1" : value1,
    "component_attr2" : value2,
    # ...
    "component_attrn" : valuen,
    "parameters" : [parameter1, parameter2, ..., parametern]}

parameter.as_dictionary() returns:

{   "parameter_attr1" : value1,
    "parameter_attr2" : value2,
    # ...
    "parameter_attrn" : valuen,}

model_to_dict function:

    def model_to_dict(self, model_name):
        model_dict = {}
        model_dict['metadata'] = self._get_metadata_as_dict()
        temp_component_dict = {}
        for component_index, component in enumerate(self):
            temp_component_dict['component'+str(component_index)] = component._get_component_as_dict()
        model_dict['components'] = temp_component_dict
        model_dict['spectrum'] = self.spectrum._get_spectrum_as_dict()
        model_dict['axes_manager'] = self.axes_manager._get_axes_manager_as_dict()
        np.savez(model_name + ".npz", model_dict = model_dict)
Clone this wiki locally