Cyril
Cyril

Reputation: 41

Matlab save Handle instance doesn't save its properties values

I have created the following class, which inherits both from handle and enum.

classdef ShiftType < handle
%SHIFTTYPE Defines shift per frame
    properties
        shift = 0
        num_shifts = 0
    end
    enumeration
        LateralCst %in meters
        RadialCst % in radians
        RadialVar % in beam distance ratio
        LateralVar % Same. Lateral shift calculated at focus range.
    end
end

If I create an instance of ShiftType and use it within a script, everything goes well. But I realized that, if I save this instance into a .mat file and then load it, its properies are set to their default value (0). Here is an example to illustrate the problem:

>> shift_type = ShiftType.RadialVar;
>> shift_type.shift = 0.5;
>> shift_type.num_shifts = 4;
>> shift_type

shift_type = 

    RadialVar

>> shift_type.shift

ans =

    0.5000

>> save test.mat shift_type
>> clear all
>> load test.mat
>> shift_type

shift_type = 

    RadialVar

>> shift_type.shift

ans =

     0

How can I have the properties saved in the .mat files along with the ShiftType instance? Note that those properties are independant of the Enum type, so I don't want to just have a ShiftType(val) function and default values for each enum (such as LateralCst (1, 4)).

Thanks ahead!

Upvotes: 3

Views: 92

Answers (3)

Cyril
Cyril

Reputation: 41

Thanks for your answers. I have reported the bug to Matlab. In the meantime I have fixed the issue by dividing ShiftType into two classes. The class Shift is a generic class with editable properties, one of which is an instance of the enum type of before (ShiftType).

classdef Shift
%SHIFT Defines shift per frame
properties
    type = ShiftType.RadialVar;
    val = 0; % Ref ShiftType
    num_shifts = 0;
end
methods
    function obj = Shift(type, val, num_shift)
        obj.type = type;
        obj.val = val;
        obj.num_shifts = num_shift;
    end
end
end

And:

classdef ShiftType
%SHIFTTYPE Defines shift type
enumeration
    LateralCst %in meters
    RadialCst % in radians
    RadialVar % in beam distance ratio(1 = moves from one beam to another).
    LateralVar % Same. Lateral shift calculated at focus range.
end
end

I think it is the most straightforward approach until the bug is fixed. Thanks again for your answers :)

Upvotes: 1

Rijul Sudhir
Rijul Sudhir

Reputation: 2132

Here is something I wrote. I won't say its perfect. But gets the job done for now. There is no change required in the class file (Same class file). Just run this code

%% Initialise data
shift_type = ShiftType.RadialVar;
shift_type.shift = 0.5;
shift_type.num_shifts = 4;

%% save file
file_name='test11.mat'; % write filename
class_object='shift_type';
class_name=class(eval(class_object));
propNames=properties(class_name);
data=cell(1,size(propNames,1)+1);
data{1}=class_object;
for index=2:size(propNames,1)+1
    propertyName=strcat(class_object,'.',propNames{index-1});
    data{index}=[propNames(index-1) eval(propertyName)];
end
save(file_name,class_object,'data');

%% clear workspace
clear all;

%% load file
file_name='test11.mat'; %read filename
load(file_name);
for index=2:size(data,2)
    property=data{index};
    propertyName=strcat(data{1},'.',property{1});
    expresn=strcat(propertyName,'=',num2str(property{2}),';');
    eval(expresn);
end

%% Display data
shift_type.shift
shift_type.num_shifts

Upvotes: 0

Mohsen Nosratinia
Mohsen Nosratinia

Reputation: 9864

It is most probably a bug. The documentation says that the property set methods should be called when the object is loaded however if you add this method to your class:

    function set.shift(obj, shift)
        obj.shift = shift;
        disp('Set method called!');
    end

You'll see that it is not being called. If you remove the enumeration part of the class, it works fine. Appears that loading of enumeration types have their own specific handling which doesn't take care of other properties.

Upvotes: 1

Related Questions