Page 1 of 2

Error "Attempt to reference field of non-structure array"

Posted: Wed Jul 12, 2017 6:59 am
by thanasis
I had been using a custom function to deconvolute and plot two subspectra during a fit (viewtopic.php?f=3&t=209#p1111).

It had been working until 5.1.8. As of 5.1.11 I get an error:
Attempt to reference field of non-structure array.

Error in decompose (line 4)
if Sys.g(1,1)>=2.0
Error in esfit>assess (line 803)
Error in esfit_simplex (line 77)
Error in esfit>runFitting (line 660)
Error while evaluating UIControl Callback
The behavior is reversible: upon switching back to 5.1.8 I get my script working again.

Thanks!

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 8:17 am
by Stefan Stoll
Please post a self-containted script with your fitting function that reproduces the error.

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 8:48 am
by thanasis
Here is the script:

Code: Select all

fname = 'myspectrum.spc';
[B, spc, params] = eprload(fname);
%--------------------------------------------------------------------------
%The spin system
%--------------------------------------------------------------------------
Sys1.S=1/2;
Sys1.g=[2.064 2.244];
Sys1.lwpp = [0 6];
Sys1.Nucs = 'Cu';
Sys1.A = [0 515];

Sys2.S = 1/2;
Sys2.g = [1.74 2.18];
Sys2.gStrain = [0.29 0];
Sys2.lwpp = [0 13];
Sys2.weight = 0.8;

Exp.Temperature = 4.1; Exp.mwFreq=params.MF; Exp.CenterSweep=[params.HCF/10 params.HSW/10]; Exp.nPoints=params.RES;

%--------------------------------------------------------------------------
Vary1.g = [0.0 0.0];
Vary1.lwpp = [0 2];
Vary1.A = [0 0];

Vary2.g = [0.0 0.01];
Vary2.gStrain = [0 0];
Vary2.lwpp = [0 2];
Vary2.weight = 0.;

% Call the fitting function
FitOpt.Method = 'simplex diff';
FitOpt.Scaling = 'lsq1';
esfit('decompose',spc,{Sys1,Sys2},{Vary1,Vary2},Exp,[],FitOpt);
An here is the decompose function:

Code: Select all

function [x,y] = decompose(Sys,Exp,Opt)
figure(234)
if Sys.g(1,1)>=2.0
[x,y] = pepper(Sys,Exp,Opt);
monomer=y' ; save('monomer','monomer','-ascii');
plot(x,y)
drawnow
hold on

elseif Sys.g(1,1)<2.0
[x,y] = pepper(Sys,Exp,Opt);
trimer=y' ; save('trimer','trimer','-ascii');
plot(x,y)
drawnow
hold off
end

end

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 8:54 am
by Stefan Stoll
Please post the spectral files as well.

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 9:01 am
by thanasis
skg10607.zip
(4.48 KiB) Downloaded 215 times

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 9:27 am
by Stefan Stoll
I can reproduce this now, thanks. This changed in 5.1.9. esfit now calls the custom fit function just once per iteration and passes all spin systems along in a cell array. Here is how to adapt decompose:

Code: Select all

function [x,y] = decompose(Sys,Exp,Opt)

[x,y_monomer] = pepper(Sys{1},Exp,Opt);
[x,y_trimer] = pepper(Sys{2},Exp,Opt);

data = y_monomer'; save('monomer','data','-ascii');
data = y_trimer'; save('trimer','data','-ascii');

figure(234);
subplot(2,1,1)
plot(x,y_monomer);
subplot(2,1,2)
plot(x,y_trimer);

y = y_monomer + y_trimer;

end

Re: Error "Attempt to reference field of non-structure array

Posted: Wed Jul 12, 2017 11:32 pm
by thanasis
Thanks Stefan,

This works now, so I guess it wasn't a bug but a feature!

Cheers,

Thanasis

Re: Error "Attempt to reference field of non-structure array

Posted: Thu Jul 13, 2017 2:58 pm
by Stefan Stoll
Indeed. It simplifies custom-fitting functions for multi-spin system situations and gives the user more flexibility.

Re: Error "Attempt to reference field of non-structure array

Posted: Thu Jul 13, 2017 4:22 pm
by thanasis
Indeed, it looks more flexible to use.

On this topic I have a related question which I post on this thread.

As I had posted in the past, and believed to have found an answer to my problem (viewtopic.php?f=3&t=332#p1023), I wanted to scale the two subspectra to the sum spectrum and experimental data so that I can plot together. So I invoked esfit like so to extract the calculated sum spectrum:

Code: Select all

[BestSys,BestSpc] = esfit('decompose',spc,{Sys1,Sys2},{Vary1,Vary2},Exp,[],FitOpt);
datafname = [fname,'_fitcurve.txt'];
calcdata = [B(:) BestSpc(:)];
save(datafname,'calcdata','-ascii');
and then I recalculated the sum in my fitting function like you suggested:

Code: Select all

function [x,y] = decompose_v2(Sys,Exp,Opt)

[x,y_monomer] = pepper(Sys{1},Exp,Opt);
[x,y_trimer] = pepper(Sys{2},Exp,Opt);

calc_monomer = y_monomer'; save('Cu7_monomer.txt','calc_monomer','-ascii');
calc_trimer = y_trimer'; save('Cu7_trimer.txt','calc_trimer','-ascii');

figure(234);
plot(x,y_monomer)
drawnow
hold on
plot(x,y_trimer)
drawnow
hold off

y = y_monomer + y_trimer;
calc_total = y'; save('Cu7_total.txt','calc_total','-ascii');

end
I was expecting that Cu7_total.txt = constant * ...fitcurve.txt, and that by multiplying the subspectra with that constant would give me the scaled subspectra.

However, I found that this is not the case: the sum of the subspectra from my fitting function and the calculated spectrum are not exactly the same. Do you have any suggestions as to why that is?
The calculations are from my posted experimental spectra so that you can corroborate, and I confirm the result with the 5.1.8 version.

Thanks,

Thanasis

Re: Error "Attempt to reference field of non-structure array

Posted: Thu Jul 13, 2017 4:31 pm
by Stefan Stoll
The difference is that the calculated spectrum returned by esfit is scaled to the experimental one, using rescale() and the option FitOpt.Scaling.