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
 All Forums
 Origin Forum
 Origin Forum
 Access to worksheet from external DLL fit function

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Anti-Spam Code:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkUpload FileInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Stefan.E.S Posted - 04/23/2010 : 09:11:19 AM
Origin Ver. and Service Release : 8.1G SR2
Operating System: WinXP

In a fit function I need to access data which are contained in an Origin worksheet. The fit function is programmed as using Microsoft Visual C++.

Can I use e.g. lParam1 or LParam2 from the FIT_PARA_LIST below for access to an origin worksheet?


#define FIT_PARA_LIST  short cntrl, DWORD lpProc, short nParam, DWORD lParam1, DWORD lParam2, LPDOUBLE p, LPDOUBLE c, LPDOUBLE x, LPDOUBLE y, LPDOUBLE dy


Furthermore, I would like to use the number (index) of the current x-axis data point in my fit function.

How can this be retrieved in an external DLL fit function?
2   L A T E S T    R E P L I E S    (Newest First)
Stefan.E.S Posted - 04/29/2010 : 04:45:18 AM
I just found out that I simply had to recompile the DLL using the Origin 8.1 header file "OriginLab\Orgin81\ATI\include\ORGDLL.H" instead of "FitFuncDef.H". Now the fitting works.

I suggest to supply documentation for fitting with fit functions from an external DLL using ORGDLL.H. Currently there is only documentation for "FitFuncDef.h".

Below I attach the fdf-file that I use for running the example from my previous post




[General Information]
Function Name = Theofit4
Brief Description = linear combination of theoretical spectra
Function Source = Theofit.1
Function Type = External DLL
Function Form = Expression
Number Of Parameters = 11
Number Of Independent Variables = 1
Number Of Dependent Variables = 1
Analytical Derivatives for User-Defined = 0
FunctionPrev = Theofit4


[Fitting Parameters]
Naming Method = User-Defined
Names = yscale,a0,a1,c1S,c3P0,c3P1,c3P2,es1S,es3P0,es3P1,es3P2
Meanings = xxx,xxx,xxx,xxx
Initial Values = 1.0(F),0.0(F),0.0(F),0.25(V),0.25(V),0.25(V),0.25(V),0(F),0(F),0(F),0(F)
Lower Bounds = 0.0,--,--,0.0,0.0,0.0,0.0,--,--,--,--
Upper Bounds = --,--,--,1.0,1.0,1.0,1.0,--,--,--,--
Number Of Significant Digits = 8,8,8,8,8,8,8,8,8,8,8


[Formula]
formula goes here;


[Constraints]
c1s+c3P0+c3P1+c3P2=1;
es3P1=es3P0;
es3P2=es3P0;


[Constants]


[Parameters Initialization]


[Initializations]


[After Fitting]


[Independent Variables]
x = 


[Dependent Variables]
y = 


[Controls]
General Linear Constraints = 0
Initialization Scripts = 1
Scripts After Fitting = 0
Number Of Duplicates = N/A
Duplicate Offset = N/A
Duplicate Unit = N/A
Generate Curves After Fitting = 1
Curve Point Spacing = Same X as Fitting Data
Generate Peaks After Fitting = 0
Generate Peaks During Fitting = 0
Generate Peaks with Baseline = 0
Paste Parameters to Plot After Fitting = 1
Paste Parameters to Notes Window After Fitting = 1
Generate Residuals After Fitting = 0
Keep Parameters = 1
Enable Parameters Initialization = 0
Compile On Param Change Script = 0


[Compile Function]
Compile = 0
Compile Parameters Initialization = 0
OnParamChangeScriptsEnabled = N/A


[Origin C Function Header]


[Origin C Parameter Initialization Header]


[References]






StSch
Stefan.E.S Posted - 04/29/2010 : 04:03:30 AM
I forgot to mention that access to origin worksheets from external DLL fitting functions was possible with Origin 7.5. I just wonder how this functionality can be used in Origin 8.1. Below a copy of a working orgin 7.5 example. A response from OriginLab would be appreaciated.

Thanks,

Stefan



#include <windows.h>

/* The following entry function
 * related to Windows
 */
#ifndef _WIN32

int FAR PASCAL LibMain(hModule, wDataSeg, cbHeapSize, lpszCmdLine)
HANDLE	hModule;
WORD    wDataSeg;
WORD    cbHeapSize;
LPSTR   lpszCmdLine;
{
    return 1;/* Nothing is done, but it is necessary */
}

//	ANU v4.134 9/30/96 32_BIT_COMPATIBLE
#else  //_WIN32

BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
	 
   // The return value is only used for DLL_PROCESS_ATTACH; all other
   //   conditions are ignored.  
	return TRUE;   // successful DLL_PROCESS_ATTACH
}

#endif
///end 32_BIT_COMPATIBLE


/* Your DLL code starts here */

#include    <math.h>
#include    <stdio.h>
#include    "orgdll.h"

///Function names have to be upper case so that origin can
//recognize the functions.




int FAR  PASCAL THEOFIT(
	HWND			hWnd,	/* Origin's main window */
	double FAR *	lpValue,/* input (x) ,output (y)*/
	short			nParam, /* number of parameters */
	double FAR *	lpParam,/* parameter array */
	LPCALLBK lpfn)
{

/*  Fitting of a weighted sum of theoretical spectra to an experimental spectrum.
    The theoretical spectra are assumed to be contained in a workshhet named "Theory"
	and to have a common, equidistant energy axis that is col. no. 1 in the worksheet.
	The spectra are assumed to be in the subsequent columns. Column names can be arbitrary.
	The number of parameters to be given in the fdf-file is 3 + number of spectra) */


	/* Fit parameters are
	 *     lpParam[0]				   : overall scale factor
	 *     lpParam[1..2]               : linear background (subtracted)
	 *     lpParam[3..nspec+3]		   : individual scale factor for each spectrum
	 *     lpParam[nspec+4..2*nspec+3] : energy shift for each spectrum
	 * nspec, npts and theory[npts][nspec+1] are defined in Theospec.h
	 * with the theoretical energy scale stored in theory[npts][0] 
	 */
    
	double	x = *lpValue;
    if (x<=0) {*lpValue=0;return (0);} 
	/* lpValue point to a temperary location
	 * that contains the X value on input
	 */

    int nspec = (nParam-3)/2;
	
    char TheoryWksName[80], colname[80], cstr[80];

    typedef char SpecName[80];
    
    SpecName Theory_E, *Theory_Spectrum = new SpecName[nspec];	 

	strcpy(TheoryWksName,"Theory");

	// get name of 1st column in theory worksheet (energy)
    lpfn(hWnd,WCB_EXECUTE,"%A=Theory!WKS.COL1.NAME$",0L);
	lpfn(hWnd,WCB_GET_STRING,(LPSTR)colname,0);
	strcpy(Theory_E,TheoryWksName);
	strcat(Theory_E,"_");
	strcat(Theory_E,colname);
    
	int n;

    for (n=1;n<=nspec;n++)
	{
		// get name of n+1st column in theory worksheet (spectra)
		sprintf(cstr,"%%A=Theory!WKS.COL%d.NAME$",n+1);
		lpfn(hWnd,WCB_EXECUTE,cstr,0L);
		lpfn(hWnd,WCB_GET_STRING,(LPSTR)colname,0);
		strcpy(Theory_Spectrum[n-1],TheoryWksName);
		strcat(Theory_Spectrum[n-1],"_");
		strcat(Theory_Spectrum[n-1],colname);
		// output to script window for debugging purposes
		// sprintf(cstr,"type -a $(%d) %s",n,Theory_Spectrum[n-1]);
		// lpfn(hWnd,WCB_EXECUTE,(LPSTR)cstr,0L);
	}

	// variables needed for reading data from worksheets
	long range[4];
	DWORD data_id;
	DATAELEMENT data;

	data.index = 0;
	data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_E, (LPSTR)range);
	lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
	double x0 = data.value;
    long int npts = range[1];

	data.index = 1;
	data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_E, (LPSTR)range);
	lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
	double x1 = data.value;

	double dx = x1-x0;
	double y=0;
   
    int i;
	for (int j=0;j<nspec;j++)
	{
		double eshift = lpParam[3+nspec+j];
    	i = int((x-x0-eshift)/dx);

/*
//      in case of non equidistant x-values use the following instructions
		for (i=npts-1;i>=0;i--)
		    {
			data.index = i;
			data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_E, (LPSTR)range);
			lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
			double xi = data.value+eshift;
			if (x<xi) break;
		}
*/
		if ((i>0) && (i<npts-2))
		{

			data.index = i;
			data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_E, (LPSTR)range);
			lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
			double x1 = data.value+eshift;
			data.index = i;
			data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_Spectrum[j], (LPSTR)range);
			lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
			double y1 = data.value;
			data.index = i+1;
			data_id = lpfn(hWnd, WCB_DATA_GET_ID, (LPSTR)Theory_Spectrum[j], (LPSTR)range);
			lpfn(hWnd, WCB_DATA_GET_VALUE, (LPSTR)data_id, (LPSTR)(&data));
			double y2 = data.value;
    		y += lpParam[j+3]*(y1 + (x-x1)*(y2-y1)/dx);
		}
	}

  y *= lpParam[0]; // overall scale factor
  y -= lpParam[1]+x*lpParam[2]; //  subtract background

  *lpValue = y; // result of the function is stored back to lpValue 
 
  delete[] Theory_Spectrum;

  return(0);
 	/* You must return zero if there is no error
     * otherwise you can return any number other than
	 * zero to signal an error
	 */
}






StSch

The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000