T O P I C R E V I E W |
physicus13 |
Posted - 01/22/2018 : 09:02:45 AM Origin Ver. and Service Release (Select Help-->About Origin): OriginPro 2018, b9.5.1.195 Operating System: Win10
Hi everyone,
Even though I am a long-time user I only recently got into scripting in Origin simply because of the volume of my data (hundreds of curves) and would really appreciate some help.
So I'm trying to get a linear fit on every curve in a workbook without the need to manually set the limits for each curve individually. They are stress-strain curves and are all rising mostly linear until they reach a maximum and then fail. I need to know the slope of all of those and then do some statistics. The issue is that the beginning and end (just before the maximum) of the curve areas is not very uniform (clamping and breaking artifacts). Hence I would like to set the fit area (on x axis) to about 10 percent after start to about 10 percent before the maximum.
My initial idea was to normalize the y values and then try to reference back from the row number of those new cells at 0.1 and 0.9. No idea how to do that though. I also wouldn't mind if the rest of the data is masked or whatever - I just need the slope from 10-90% in reference to the individual maximum.
Any ideas would be more than welcome.
Thanks
Phys
|
5 L A T E S T R E P L I E S (Newest First) |
physicus13 |
Posted - 01/24/2018 : 07:59:53 AM Thank you very much to both of you, that solves my issue 
Hideo - I like your script, as it gives me the possibility to adjust the fits individually (to not only linear fits for example). Problem is I need it for separate workbooks only (not the whole document - should be a simple change though, just can't wrap my head around it at the moment), and I also need it for every X in the workbook (every 1,3,5 etc column). This script is definitely useful though, thank you.
James - Brilliant, thank you, your method gives me all the results I need right away in a readily processable output. I figured out how to add additional values to the output based on your script (see https://www.originlab.com/doc/X-Function/ref/fitLR), so your method works perfectly now for me!
Anyway, this has been incredibly helpful, thanks again!
Regards
Phys |
YimingChen |
Posted - 01/23/2018 : 12:18:51 PM Dear Gordon, Please activate your worksheet and run the following Labtalk script. The idea is for each xy data, find the row index (id_max) of maximum y value, then get the range of data [A:B] for fitting where A = 0.1* id_max and B = 0.9* id_max. This script will save the slope and intercept of linear fitting in the FitResult sheet. You can add more statistics into worksheet as desired.
string mybk$ = %H; // Save the active workbook name
newsheet name:=FitResults outname:=FitRst$ cols:=1; // Add new sheet to hold fit lines
range aa = 1!; // 1st sheet, assume we start with just one data sheet
range bb = %(FitRst$); // The newly added sheet, name is stored in FitLines$ variable
nn = aa.nCols/2;
bb.nCols = 2; // Add new columns in newly added sheet
dataset slopes, intercepts; // To hold fitting result parameters
slopes.SetSize(nn); // Number of Ys in the data worksheet
intercepts.SetSize(nn); // Not needed for now, but maybe want this later
loop(ii, 1, nn) {
range ry = 1!($(ii*2));
idmax = list(max(ry), ry);
int idstart = idmax*0.1;
int idend = idmax*0.9;
range dd = 1!($(ii*2-1), $(ii*2))[idstart:idend];
fitlr iy:=dd;
slopes[ii] = fitlr.b; // ii-1 because loop from 2
intercepts[ii] = fitlr.a;
}
range raa = %(FitRst$)!1;
raa = slopes;
range rbb = %(FitRst$)!2;
rbb = intercepts;
Hope this helps, thank you! Sincerely, James Chen |
Hideo Fujii |
Posted - 01/23/2018 : 10:37:36 AM Hi Phys and others,
Until Shirley takes a look at your specific case, the following snippet masks the X cells (first column) outside of the thresholds (thus their Y's are also excluded in the following linear regression) in general simple situation:
/////////////////////////////////////////////
doc -e LB { //Repeat over all sheets in all books
//type Book:%H Sheet:%(layer.name$);
range rr=[%H]%(layer.name$)!col(1); //col(1) in each worksheet
rrmax=max(rr); //Max
rrmin=min(rr); //Min
rrmax90=rrmax-0.1*(rrmax-rrmin); //Max threshold
rrmin10=rrmin+0.1*(rrmax-rrmin); //Min threshold
rrsize=rr.getSize(); //Datset size
for(ii=1; ii<=rrsize; ii++) { //Repeat over all rows
if(rrmin10>=rr[ii] || rr[ii]>=rrmax90) rr<ii>=1; //Mask X if out of threshold
}
}
///////////////////////////////////////////// |
physicus13 |
Posted - 01/23/2018 : 07:46:16 AM Hi Shirley,
Thanks for your response. I'll submit some exemplary data shortly. In the mean time, more generally - imagine 2 columns x and y:
0 -0.5 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 9.8 11 8
Obviously rows 1-9 show a steady trend, the other ones don't. I now want to limit the linear fit to this range. Of course in the real data, the set is made of more than 1000 data points and different maxima values etc.
My "normalization" idea would be to create a new column z, which normalizes y. In z I can easily identify >=0.1 and <=0.9. If there would be a way to reference the respective cells at the same row in column x or y and set them as fit or masking limits, respectively, that would solve the problem.
Thanks
Phys |
Shirley_GZ |
Posted - 01/23/2018 : 04:34:47 AM Hi Phys,
Sorry, I don't think the normalization is appropriate here. As the normalization will break the relatioship of the X and Y data, then the actual slopes will be changed into other values.
About "the fit area (on x axis) to about 10 percent after start to about 10 percent before the maximum", do you mean sort the XY data and then get the 10% ~ 90% of the number of data points?
To let us learn more about your case, would you please send us some sample data to let us do some testing here, via tech@originlab.com?
Thanks, Shirley
Originlab Technical Service Team |
|
|