TASBE / TASBEFlowAnalytics

Flow cytometry unit conversion and analytics
Other
7 stars 8 forks source link

JSON object serialization #402

Open jakebeal opened 5 years ago

jakebeal commented 5 years ago

CSV serialization has brought up the possibility that many objects might be JSON serialized rather than stored in .mat files. If we can do that, then we can potentially entirely work around the issues of Matlab vs. Octave serialization, allowing us to use modern classes as well as obsoleting #87.

coverney commented 4 years ago

I figured out a way to save objects in a json format! Shall we have the default be saving it in a .mat file and create a TASBE Config variable for the output type?

jakebeal commented 4 years ago

Yes, that sounds like the right plan.

coverney commented 4 years ago

Currently, I am trying to find a way to load back in the JSON files. I created a recursive outside function that goes through a struct version of a json file and converts nested structs into objects. Everything works except for creating a gmdistribution object when creating the GMMGating object for the CM's prefilters property.

When I run obj = eval('gmdistribution'); I get the following error: Method 'gmdistribution' is not defined for class 'gmdistribution' or is removed from MATLAB's search path.

The constructor for gmdistribution is the only class that isn't in the code directory. I was wondering if there is a reason for that. I am not sure how to fix this problem without trying to move the folder into the code directory. (I manually added the gmdistribution folder to Path, but it still didn't work.)

jakebeal commented 4 years ago

Running obj = eval('gmdistribution') works on my Matlab and on my octave.

The gmdistribution code in the TASBE distribution is only there for use if one doesn't have the appropriate Matlab package installed. Use which gmdistribution to check and see whether you're getting that code or if you're using Matlab's own package code, which is different. I don't have the Matlab package, but perhaps you do and perhaps that's the source of the problem?

coverney commented 4 years ago

Yep! I had to uninstall a Matlab toolbox, but now that part is working!

jakebeal commented 4 years ago

I wonder why the Matlab code wasn't working... that's a significant problem, since we need to be able to use the matlab gmdistribution if it's there, rather than using our own.

coverney commented 4 years ago

True! I tried searching the internet for using eval to create objects from a Matlab toolbox/ add-in and couldn't find a solution.

coverney commented 4 years ago

I looked into the problem a bit more, and I think the reason it doesn't work is that the Matlab gmdistribution class does not take in the same properties as the local version, so it can't read in the necessary information from the colormodel JSON file.

jakebeal commented 4 years ago

Is there any way to special-case for handling the gmdistribution class, based on whether we're using the Matlab version or not? The "which" command should be able to check.

coverney commented 4 years ago

the which command does differentiate between the two but what do you mean by handling the gmdistribution class? Would this be whenever we deal with it in our analyses?

coverney commented 4 years ago

I might have been wrong about the different properties statement. I wrote the following test function:

function obj = testgmdistribution()
    obj = eval('gmdistribution')
    obj.('mu') = 1;
    disp('success')
end

When I ran it, I got the following error with obj.('mu') = 1;

You cannot set the read-only property 'mu' of gmdistribution.

Error in classreg.learning.internal.DisallowVectorOps/subsasgn (line 34)
                [varargout{1:nargout}] = builtin('subsasgn',this,s,data);

However when I ran these lines, it worked fine.

obj = eval('ColorModel');
obj.('ERF_channel_name') = 'FITC-A';

This might have something to do with premissions for Matlab toolbox objects.

jakebeal commented 4 years ago

Sounds like a special-case constructor might be possible...

coverney commented 4 years ago

I was wondering if you could clarify what a special-case constructor would look like. The built-in Matlab gmdistribution class has an access list where all properties have SetAccess=protected. I can't really modify that file because other users wouldn't have that change. (If we just do that, then we can just create a new class that doesn't conflict with a Matlab package.) Also, I thought about making a subclass, but it shares the access list with its superclass.

jakebeal commented 4 years ago

Can the usual public constructor for gmdistribution be called in such a way that we end up with the properties having the desired values?