Return two variables with different data types from MATLAB engine in Python

I am analyzing oscilloscope .csv files with Python. I have a signal that has one or two negative peaks (baseline is around 0 value), depending on the waveform analyzed. I use inside Python a MATLAB engine to call a MATLAB file that contains a function to find those peaks and return their position on the x (time) and y (amplitude) axis.
Inside MATLAB, the two cases (one / two peaks) give (for one variable, be it x or y; i will exemplify with x in this post) in the workspace a 1x1 double (eg: 0.020000000000000) or a 2x1 double ([0.016000000000000;4.628000000000000]) for one/two peaks (values and representation are copied from the workspace). So, for one waveform, MATLAB identified a peak at 0.02 seconds ; and for another waveform two peaks at 0.016 seconds (one of them) and at 4.628 seconds (the other one). All my .csv files contain one OR two peaks, and I need to study them further, so I have no way of knowing how many peaks a waveform has.
The MATLAB peak finder function has the following structure:
function [times, amplitudes] = peak_find_matlab(file, x, y)
where x and y come from the file and denote the oscilloscope times and amplitudes for each individual point (~10000 points per array). In Python I call the MATLAB engine and call the function as such:
eng = matlab.engine.start_matlab()
[times, amplitudes] = eng.peak_find_matlab(file, x_list, y_list, nargout=2)
For the cases where two peaks are found, everything is fine, the engine returns the following:
type times= <class 'matlab.mlarray.double'> with value = [[0.016],[4.628]]
type amplitudes = <class 'matlab.mlarray.double'> with value = [[-0.16],[-0.062]]
I convert the 'matlab.mlarray.double' into a list to further use it in the Python script and other scripts, using:
np.array(times._data).tolist()
np.array(amplitudes._data).tolist()
In the case of one peak, MATLAB engine returns a 'float' type:
type times= <type 'float'> with value = 0.02
type amps = <type 'float'> with value = -0.0792016896
Trying to convert this to list, yields different errors ( AttributeError: 'float' object has no attribute '_data', or 'float' object has no attribute '_getitem__'_ and IndexError: too many indices for array) if I try to use the float data type or try to convert it to simple numpy array or accessing any element of this array...
I am trying to understand why MATLAB outputs different data types for this operation and how to tell him to keep consistent with, for example 'matlab.mlarray.double' class which yields the necessary results. I would assume I will have, in the case one waveform has one peak, to tell MATLAB to output one value, and an empty value for the other one, something like: [[0.016],[]]. If so, how can this be done?
For consistency, the rest of my python code, where I plot a vertical line at each time value for the peaks and fill a histogram, depending on whether the script found a file with one peak (which I call primary event), or a file with two peaks (for which the first peak is coined a "primary" and the second one is a ... "secondary" :D).
secondaryTimes = []
primaryAmplitudes = []
secondaryAmplitudes = []
eng = matlab.engine.start_matlab()
[times, amplitudes] = eng.peak_find_matlab(file, x_list, y_list, nargout=2)
peakTimes = np.array(peaks._data).tolist()
peakAmps = np.array(amplitudes._data).tolist()
for peak in peaks._data: plt.axvline(x=peak, color='r', linestyle='-.') # plot a vertical line where the peak was found
primaryAmplitudes.append(peakAmps[0])
### need more than two values in peakTimes, the second value (index 1) is the time at which the secondary occurred
if len(peakTimes) > 1:
secondaryTimes.append(peakTimes[1])
secondaryAmplitudes.append(peakAmps[1])
if len(primaryAmplitudes) > 0:
making_some_nice_histogram # "highest amplitude" for primaries
if len(secondaryTimes) > 0:
making_another_nice_histogram # "timing histogram", in case there were secondary discharges
Thank you very much for your time!

 Accepted Answer

You could change peak_find_matlab or do a wrapper over it in order to check the type of the returned values.
myVar1 = []
myVar2 = []
[times, amplitudes] = eng.peak_find_matlab(file, x_list, y_list, nargout=2)
if isinstance(times, float):
myVar1.append(times)
else:
myVar1=times
if isinstance(amplitudes, float):
myVar2.append(amplitudes)
else:
myVar2 = amplitudes
And then you continue your program using myVar1 and myVar2.
Hope this solves the problem

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!