The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Using data only partly
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

t.n.vader

Netherlands
Posts

Posted - 08/25/2010 :  10:56:01 PM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Although this is probably is a simple question, I could not find the solution in the manual. I have to fit many datasets with a simple guassian (y=0) peak. However, only a part of the signal is useable for this. So, I ask the user to estimate the beginning and end of the useable part and also to estimate the center. Then, I loop through all the worksheets and try to fit the data in it.

How can I use only the points that satisfy startx < x < stopx ?


//	Retrieve estimates from user
double startx = InputBox(1.0, "Left limit.");
double stopx = InputBox(10.0, "Right limit.");
double peakx = InputBox((startx+stopx)/2,"Peak location.");

//	Let's fill the start fitting parameters
//	@todo Make sure y0 is fixed
vector vParams(4);
vParams[0] = 0;			//	y0
vParams[1] = peakx;		//	xc
vParams[2] = (stopx-startx)/2;	//	w
vParams[3] = 1;			//	A

//	Start the FitSession
NLFitSession FitSession;
if( !FitSession.SetFunction("Gauss")) {
	out_str("invalid fit function");
	return;
}

//	Initialize aggregate vectors
int sheets = book.Layers.Count();
vector xx, xcResults, wResults, y0Results, AResults;
xx.SetSize( sheets );		//	The part we are varying per measurement
xcResults.SetSize( sheets );	//	xc's from fits
wResults.SetSize( sheets );	//	w's from fits
y0Results.SetSize( sheets );	//	y0's from fits
AResults.SetSize( sheets );	//	A's from fits

//	Initialize some working variables
vector vParamValues, vErrors;
int index = 0, location, nOutcome;
string desc;

//	Loop through all worksheets in the workbook
foreach ( Layer layer in book.Layers ) {

	Worksheet worksheet = layer;
	desc = worksheet.GetName();
	
	//	Acquire data ranges
	vector vX = worksheet.Columns(1).GetDataObject();
	vector vY = worksheet.Columns(2).GetDataObject();
	if( !FitSession.SetData(vY, vX)) {
		out_str("fail to set data");
		return;
	}

	//	Set the parameters to start values
	if( !FitSession.ParamsInitValues()) {
		out_str("fail to initialize parameter");
		return;
	}
	if( 0 != FitSession.SetParamValues( vParams ) ) {
		out_str("fail to set parameters");
		return;
	}	
	FitSession.GetChiSqr();
	
	//	Now, we fit!
	if( !FitSession.Fit(&nOutcome) ) {
		printf("Fail to do fitting for %s\n", desc);
		continue;
	}
	printf("Fitted %s Succesfully\n", desc);
	FitSession.GetFitResultsParams(vParamValues, vErrors);
	
	//	The xx value is in the name of the sheet
	location = desc.ReverseFind(' ');
	xx[index] = atof(desc.Mid( location + 1));
	
	//	We obtained y0, xc, w, A (in that order)
	y0Results[index] = vParamValues[0];
	xcResults[index] = vParamValues[1];
	wResults[index] = vParamValues[2];
	AResults[index] = vParamValues[3];

	index++;

}

//	Create a new workbook
WorksheetPage bookFitResults;
bookFitResults.Create( NULL, CREATE_VISIBLE | CREATE_EMPTY );
bookFitResults.SetName( "FitResult" );
bookFitResults.SetLongName( "Fit results" );

//	Create a new worksheet
Worksheet fitSheet;
fitSheet = bookFitResults.Layers.Item( bookFitResults.AddLayer( "FitResults" ) );
fitSheet.SetSize( sheets, 5 );

//	Save
//	@todo This part isn't correct yet
fitSheet.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
fitSheet.Columns(1).SetType(OKDATAOBJ_DESIGNATION_Y);
fitSheet.Columns(2).SetType(OKDATAOBJ_DESIGNATION_Y);
fitSheet.Columns(3).SetType(OKDATAOBJ_DESIGNATION_Y);
fitSheet.Columns(4).SetType(OKDATAOBJ_DESIGNATION_Y);
fitSheet.Columns(0).SetName("xx");
fitSheet.Columns(1).SetName("y0");
fitSheet.Columns(2).SetName("xc");
fitSheet.Columns(3).SetName("w");
fitSheet.Columns(4).SetName("A");
fitSheet.Columns(0).SetLongName("XX");
fitSheet.Columns(1).SetLongName("Amplitude");
fitSheet.Columns(2).SetLongName("Center location");
fitSheet.Columns(3).SetLongName("Width");
fitSheet.Columns(4).SetLongName("Area");
//	@todo Cannot use more than 3 parameters per datarange?
//	@todo Order is incorrect and depends on first parameter?
DataRange rangeOutput1;
rangeOutput1.Add("Z", fitSheet, 0, 0, -1, 0);
rangeOutput1.Add("X", fitSheet, 0, 1, -1, 1);
rangeOutput1.Add("Y", fitSheet, 0, 2, -1, 2);
rangeOutput1.SetData(&xx, &y0Results, &xcResults );
DataRange rangeOutput2;
rangeOutput2.Add(NULL, fitSheet, 0, 3, -1, 3);
rangeOutput2.Add(NULL, fitSheet, 0, 4, -1, 4);
rangeOutput2.SetData(&wResults, &AResults);

Penn

China
644 Posts

Posted - 08/25/2010 :  11:50:36 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

When getting the data vector from a column, you can use the Vectorbase::GetSubVector method to get a subvector by specifying the indices of startx and stopx. Then use the subvectors of X and Y to set the fitting data. Simply like below:

vector vX = worksheet.Columns(1).GetDataObject();
vector vY = worksheet.Columns(2).GetDataObject();
vector vSubX, vSubY;
vX.GetSubVector(vSubX, startx, stopx);  // startx and stopx are indices
vY.GetSubVector(vSubY, startx, stopx);



Penn
Go to Top of Page

t.n.vader

Netherlands
Posts

Posted - 08/26/2010 :  12:01:34 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hey penn,

Thank you for your quick reply. Is there any better way to find the indices than to loop through the x-vectors?

To clarify: The x and y vectors contain data points, which have no regular interval between the x's. It's therefore non-trivial to retrieve the indices. The x values are in ascending order, though.
Go to Top of Page

Penn

China
644 Posts

Posted - 08/26/2010 :  01:00:53 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

Try the vectorbase::Find method.

Penn
Go to Top of Page

t.n.vader

Netherlands
Posts

Posted - 08/26/2010 :  01:42:58 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Thanks you, that was indeed what I was looking for. Program seems to be working perfectly now!
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000