0
$\begingroup$

This might sound a little silly question but I cannot get my code work. Here is the problem:

I have quite a few lists of data which are basically beam profiles. I am using Manipulate to find a fit for each one of them. Then I extract the fit parameter from Manipulate using Dynamic which gives me a list of numbers. Finally, this is the part where I have problem, I want to use these number in the fitting function and use it somewhere else.

Here is the code:

data={
0.176471, 0.168627, 0.184314, 0.168627, 0.164706, 0.168627, 0.172549, \
0.160784, 0.172549, 0.164706, 0.176471, 0.172549, 0.176471, 0.184314, \
0.164706, 0.180392, 0.176471, 0.176471, 0.188235, 0.184314, 0.184314, \
0.176471, 0.188235, 0.168627, 0.180392, 0.168627, 0.176471, 0.180392, \
0.188235, 0.180392, 0.176471, 0.180392, 0.184314, 0.168627, 0.184314, \
0.203922, 0.192157, 0.192157, 0.184314, 0.188235, 0.184314, 0.176471, \
0.172549, 0.184314, 0.180392, 0.180392, 0.188235, 0.188235, 0.184314, \
0.196078, 0.188235, 0.184314, 0.188235, 0.184314, 0.188235, 0.192157, \
0.211765, 0.192157, 0.192157, 0.188235, 0.192157, 0.203922, 0.203922, \
0.196078, 0.203922, 0.196078, 0.207843, 0.192157, 0.215686, 0.219608, \
0.207843, 0.211765, 0.211765, 0.203922, 0.215686, 0.223529, 0.215686, \
0.219608, 0.223529, 0.219608, 0.223529, 0.231373, 0.231373, 0.235294, \
0.219608, 0.227451, 0.231373, 0.235294, 0.243137, 0.243137, 0.239216, \
0.247059, 0.270588, 0.25098, 0.25098, 0.270588, 0.262745, 0.266667, \
0.270588, 0.258824, 0.286275, 0.290196, 0.294118, 0.282353, 0.294118, \
0.301961, 0.313725, 0.317647, 0.321569, 0.317647, 0.345098, 0.345098, \
0.360784, 0.345098, 0.364706, 0.368627, 0.364706, 0.372549, 0.392157, \
0.372549, 0.384314, 0.411765, 0.431373, 0.403922, 0.4, 0.419608, \
0.431373, 0.447059, 0.45098, 0.439216, 0.427451, 0.431373, 0.447059, \
0.466667, 0.529412, 0.537255, 0.533333, 0.517647, 0.466667, 0.45098, \
0.407843, 0.411765, 0.423529, 0.415686, 0.45098, 0.466667, 0.470588, \
0.466667, 0.498039, 0.498039, 0.45098, 0.462745, 0.466667, 0.47451, \
0.494118, 0.494118, 0.560784, 0.603922, 0.662745, 0.639216, 0.654902, \
0.627451, 0.615686, 0.619608, 0.611765, 0.6, 0.615686, 0.658824, \
0.670588, 0.643137, 0.65098, 0.619608, 0.682353, 0.678431, 0.639216, \
0.619608, 0.647059, 0.67451, 0.631373, 0.654902, 0.678431, 0.631373, \
0.635294, 0.654902, 0.666667, 0.67451, 0.67451, 0.678431, 0.666667, \
0.666667, 0.690196, 0.67451, 0.686275, 0.67451, 0.662745, 0.686275, \
0.658824, 0.666667, 0.662745, 0.654902, 0.678431, 0.662745, 0.666667, \
0.662745, 0.694118, 0.686275, 0.666667, 0.690196, 0.678431, 0.67451, \
0.686275, 0.647059, 0.65098, 0.627451, 0.654902, 0.631373, 0.611765, \
0.619608, 0.611765, 0.588235, 0.596078, 0.576471, 0.596078, 0.584314, \
0.592157, 0.584314, 0.592157, 0.611765, 0.564706, 0.588235, 0.584314, \
0.560784, 0.564706, 0.576471, 0.54902, 0.564706, 0.556863, 0.556863, \
0.537255, 0.537255, 0.533333, 0.517647, 0.494118, 0.490196, 0.498039, \
0.470588, 0.486275, 0.482353, 0.462745, 0.470588, 0.47451, 0.478431, \
0.482353, 0.466667, 0.470588, 0.47451, 0.443137, 0.427451, 0.411765, \
0.4, 0.415686, 0.407843, 0.403922, 0.392157, 0.407843, 0.396078, \
0.392157, 0.376471, 0.376471, 0.360784, 0.368627, 0.376471, 0.364706, \
0.360784, 0.341176, 0.337255, 0.333333, 0.329412, 0.321569, 0.313725, \
0.309804, 0.309804, 0.313725, 0.286275, 0.290196, 0.27451, 0.286275, \
0.266667, 0.282353, 0.298039, 0.282353, 0.262745, 0.266667, 0.278431, \
0.254902, 0.258824, 0.25098, 0.239216, 0.243137, 0.25098, 0.239216, \
0.243137, 0.258824, 0.239216, 0.223529, 0.239216, 0.243137, 0.235294, \
0.227451, 0.223529, 0.231373, 0.227451, 0.215686, 0.215686, 0.219608, \
0.215686, 0.215686, 0.207843, 0.215686, 0.215686, 0.207843, 0.211765, \
0.203922, 0.2, 0.192157, 0.2, 0.188235, 0.196078, 0.188235, 0.192157, \
0.188235, 0.172549, 0.188235, 0.196078, 0.172549, 0.176471, 0.2, \
0.180392, 0.184314, 0.184314, 0.176471, 0.192157, 0.180392, 0.176471, \
0.192157, 0.176471, 0.176471, 0.180392, 0.176471, 0.188235, 0.156863, \
0.184314, 0.172549, 0.164706, 0.176471, 0.188235, 0.172549, 0.168627, \
0.164706, 0.172549, 0.176471, 0.164706, 0.168627, 0.168627, 0.176471, \
0.192157, 0.180392, 0.168627, 0.160784, 0.164706, 0.168627, 0.168627, \
0.172549, 0.180392, 0.172549, 0.172549, 0.164706, 0.172549, 0.168627, \
0.172549, 0.160784, 0.156863, 0.164706, 0.176471, 0.156863, 0.176471, \
0.172549, 0.164706, 0.180392, 0.172549, 0.160784, 0.172549, 0.164706, \
0.168627, 0.164706, 0.164706, 0.168627, 0.164706, 0.168627, 0.164706};

 Manipulate[
 Show[data, global = {a, b, x0, c}; 
  Plot[a + b*Exp[-((x - x0)^2)/(2 c^2)], {x, 0, 700}, 
   ImageSize -> Medium, PlotRange -> All]], {a, 0.01, 0.9, 0.01}, {b, 
  0.01, 0.9, 0.01}, {x0, 300, 600, 1}, {c, 0.01, 100, 0.1}]
Dynamic@global

From here I want to use the values of global in the fit model g[a_, b_, x0_, c_] := a + b*Exp[-((x - x0)^2)/(2 c^2)] and use it to extract the FWHM of the profile. But I can't figure out how to assign the list of values from Dynamic to the fit model

I would welcome any suggestions to improve the code as well since I don't believe it is a good. I apologize if the list is too long.

$\endgroup$
2
$\begingroup$

Perhaps a better approach is to let Mathematica find the best coefficients. Using your data

f[x_] := a + b*Exp[-((x - x0)^2)/(2 c^2)];
fit = FindFit[data, f[x], {a, b, c, {x0, 200}}, x]
{a -> 0.169627, b -> 0.503936, c -> 54.9195, x0 -> 194.807}

Show[ListPlot[data], Plot[f[x] /. fit, {x, 0, 400}]]

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you for the answer. But the thing is that I have 84 profiles which their FWHM changes by a lot. I tried using this idea but it did not turn out to be very efficient. Do you have any suggestions about the problem that I have with Dymanic? $\endgroup$ – saeid Aug 27 at 18:08
  • $\begingroup$ @saeid Could you potentially Map the approach used here onto your 84 profiles, to avoid the dynamic yet not have to do this by hand for each? That could make a nice table of your FWHM parameters for each case. $\endgroup$ – Ghersic Aug 27 at 18:53
  • $\begingroup$ @Ghersic I think I can do that. Thanks for the suggestion. The code that bil has given is very nice and smooth. $\endgroup$ – saeid Aug 29 at 5:52
  • $\begingroup$ @saeid No problem. If you're familiar with pure functions, it would likely be fits = FindFit[#, f[x], {a, b, c, {x0, 200}}, x] & /@ {dataSet1, dataSet2, dataSet3, ...} . That would make a list of all the fits, and then similarly a Map (/@) pure function using code similar to his Show[ListPlot ...] final line to see each with its data. $\endgroup$ – Ghersic Sep 1 at 20:10
  • $\begingroup$ @Ghersic This certainly makes sense. Thanks! $\endgroup$ – saeid Sep 2 at 21:35
2
$\begingroup$

Trying to eyeball a fit to the data, particularly for multiple data sets, would be very time consuming and unlikely to give the best fit.

Use NonlinearModelFit with constraints on the parameters and an initial estimate for x0 taken automatically from the data.

For whatever calculations are to be done on each data set, define a Module to return the desired information. For example,

info[data_List] := Module[
  {nlm, min, max, hmv, hm},
  {model -> (nlm = NonlinearModelFit[data,
        {a + b*Exp[-((x - x0)^2)/(2 c^2)],
         b > 0, c > 0, x0 > 0},
        {a, b, c,
         {x0, Position[data, Max[data]][[1, 1]]}}, x]) // Normal,
   parameters -> nlm["BestFitParameters"],
   minimum -> (min = MinValue[{nlm // Normal, 1 <= x <= Length[data]}, x]),
   maximum -> (max = MaxValue[nlm // Normal, x]),
   halfMax -> (hmv = Mean[{min, max}]),
   halfMaxArg -> (x /. (hm = Solve[{(nlm // Normal) == hmv}, x] // Quiet)),
   fullWidthHalfMax -> Subtract @@ (x /. hm // Reverse)}]

For the data set given

info1 = info[data]

(* {model -> 0.169627 + 0.503936 E^(-0.000165774 (-194.807 + x)^2), 
 parameters -> {a -> 0.169627, b -> 0.503936, c -> 54.9195, x0 -> 194.807}, 
 minimum -> 0.170096, maximum -> 0.673563, halfMax -> 0.42183, 
 halfMaxArg -> {130.188, 259.426}, fullWidthHalfMax -> 129.239} *)

Plot[Tooltip[model /. info1],
 {x, 1, Length@data},
 PlotStyle -> Thick,
 Prolog -> {Red, AbsolutePointSize[3],
   Point[Transpose@{Range@Length@data, data}],
   Green, Tooltip[Line[{#, halfMax /. info1} & /@ (halfMaxArg /. info1)],
    Row[{"FWHM = ", fullWidthHalfMax /. info1}]]}]

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you Bob for the code. I learned a lot from this. I will have to spend some time on figuring out on what you have written here. $\endgroup$ – saeid Aug 29 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.