Origin C Programming Guide E
Origin C Programming Guide E
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form
or by any means without the written permission of OriginLab Corporation.
OriginLab, Origin, and LabTalk are either registered trademarks or trademarks of OriginLab
Corporation. Other product and company names mentioned herein may be the trademarks of their
respective owners.
OriginLab Corporation
One Roundhouse Plaza
Northampton, MA 01060
USA
(413) 586-2013
(800) 969-7720
Fax (413) 585-0126
www.OriginLab.com
Table of Contents
Table of Contents .....................................................................................................................iii
1 Basic Features.................................................................................................................... 1
1.1 Hello World Tutorial ....................................................................................................................... 1
2 Language Fundamentals ................................................................................................... 5
2.1 Language Fundamentals .............................................................................................................. 5
2.2 Data Types and Variables ............................................................................................................. 5
2.3 Operators ...................................................................................................................................... 7
2.4 Statement Flow Control ............................................................................................................... 10
2.5 Functions ..................................................................................................................................... 13
2.6 Classes ........................................................................................................................................ 14
2.7 Error and Exception Handling ..................................................................................................... 15
3 Predefined Classes ...........................................................................................................17
3.1 Predefined Classes ..................................................................................................................... 17
3.2 Analysis Class ............................................................................................................................. 17
3.3 Application Communication Class .............................................................................................. 18
3.4 Composite Data Types Class...................................................................................................... 18
3.5 Internal Origin Objects Class ...................................................................................................... 20
3.6 System Class .............................................................................................................................. 27
3.7 User Interface Controls Class ..................................................................................................... 28
3.8 Utility Class.................................................................................................................................. 30
4 Creating and Using Origin C Code ...................................................................................33
4.1 Creating and Using Origin C Code ............................................................................................. 33
4.2 Create and Edit an Origin C File ................................................................................................. 33
4.3 Compiling, Linking and Loading .................................................................................................. 39
4.4 Debugging ................................................................................................................................... 43
4.5 Using Compiled Functions .......................................................................................................... 43
4.6 Distributing Origin C Code .......................................................................................................... 47
5 Matrix Books Matrix Sheets and Matrix Objects .............................................................51
5.1 Matrix Books Matrix Sheets and Matrix Objects ......................................................................... 51
5.2 Base Matrix Book Operation ....................................................................................................... 51
5.3 Matrix Sheets .............................................................................................................................. 54
5.4 Matrix Objects ............................................................................................................................. 61
6 Workbooks Worksheets and Worksheet Columns .........................................................69
6.1 Workbooks Worksheets and Worksheet Columns...................................................................... 69
6.2 Workbooks .................................................................................................................................. 69
6.3 Worksheet Columns .................................................................................................................... 73
6.4 Worksheets ................................................................................................................................. 79
7 Graphs ...............................................................................................................................99
7.1 Graphs ......................................................................................................................................... 99
7.2 Creating and Customizing Graph .............................................................................................. 100
7.3 Adding Data Plots ..................................................................................................................... 104
7.4 Customizing Data Plots ............................................................................................................. 108
7.5 Managing Layers ....................................................................................................................... 116
7.6 Creating and Accessing Graphical Objects .............................................................................. 120
8 Working with Data ...........................................................................................................125
8.1 Working with Data ..................................................................................................................... 125
8.2 Numeric Data ............................................................................................................................ 125
8.3 String Data ................................................................................................................................ 130
8.4 Date and Time Data .................................................................................................................. 132
9 Projects ............................................................................................................................133
iii
Origin C Programming Guide
iv
Table of Contents
19 Reference ....................................................................................................................255
19.1 Reference .................................................................................................................................. 255
19.2 Class Hierarchy ......................................................................................................................... 255
19.3 Collections ................................................................................................................................. 258
v
1 Basic Features
Origin C is a high level programming language closely based on the ANSI C programming language.
In addition, Origin C supports a number of C++ features including classes, mid-stream variable
declarations, overloaded functions, references, and default function arguments. Origin C also
supports collections, and the foreach and using statements from the C# programming language.
Origin C programs are developed in Origin's Integrated Development Environment (IDE) named
Code Builder. Code Builder includes a source code editor with syntax highlighting, a workspace
window, compiler, linker, and a debugger. Refer to Help: Programming: Code Builder for more
information about Code Builder.
Using Origin C allows developers to take full advantage of Origin's data import and handling,
graphing, analysis, image export capabilities, and much more. Applications created with Origin C
execute much faster than those created with Origin's LabTalk scripting language.
2. In Code Builder, click the New button on Code Builder's Standard toolbar to open the New
File dialog.
1
Origin C Programming Guide
3. Select C File from the list box of the dialog, and then type HelloWorld in the File Name text
box.
4. Click OK and the new file will be opened in Code Builder's Multiple Document Interface (MDI).
5. Copy or type the following Origin C code beneath the line that reads // Start your functions
here.
int test()
6. Click the Build button on Code Builder's Standard toolbar to compile and link the
HelloWorld.C source file. The Output window of Code Builder should display as
2
Basic Features
7. Now you can use this function in Origin. For example, you can call this function in Origin's
Script Window. If the Script Window is not open, select the Window: Script Window menu
8. Type the function name test in the Script Window and then press the ENTER key to execute
the command. The Origin C function will be executed and hello, world will be displayed in the
3
Origin C Programming Guide
next line.
9. Besides the Script Window, the function can also be called from the LabTalk Console
Window in Code Builder. Select View:LabTalk Console in Code Builder if this console window
is not open.
Once an Origin C file has been successfully compiled and linked, all functions defined
in the file can be called as script commands from anywhere in Origin that supports
LabTalk script during the current Origin session. The function parameters and return
value need to meet certain criteria for the function to be accessible from script and
there are techniques to make such functions always avaliable. To learn more, please
refer to the LabTalk Programming: LabTalk Guide: Calling X-Functions and
Origin C Functions: Origin C Functions chapter of the LabTalk help file. This help
file is accessible from the Help: Programming: LabTalk main menu in Origin.
4
2 Language Fundamentals
Operators
Functions
Classes
5
Origin C Programming Guide
// NOTE: The double data type is implied when a data type is not
// specified in the declaration of vector and matrix variables.
Another useful class provided by Origin C is the complex class. The complex class supports numeric
data containing both a real and an imaginary component.
2.2.3 Color
Colors in Origin C are represented with a DWORD value. These values can be an index into Origin's
internal color palette or an actual color composed of red, green, and blue components.
0 SYSCOLOR_BLACK 12 SYSCOLOR_DKCYAN
1 SYSCOLOR_RED 13 SYSCOLOR_ROYAL
2 SYSCOLOR_GREEN 14 SYSCOLOR_ORANGE
3 SYSCOLOR_BLUE 15 SYSCOLOR_VIOLET
4 SYSCOLOR_CYAN 16 SYSCOLOR_PINK
5 SYSCOLOR_MAGENTA 17 SYSCOLOR_WHITE
6 SYSCOLOR_YELLOW 18 SYSCOLOR_LTGRAY
7 SYSCOLOR_DKYELLOW 19 SYSCOLOR_GRAY
6
Language Fundamentals
8 SYSCOLOR_NAVY 20 SYSCOLOR_LTYELLOW
9 SYSCOLOR_PURPLE 21 SYSCOLOR_LTCYAN
10 SYSCOLOR_WINE 22 SYSCOLOR_LTMAGENTA
11 SYSCOLOR_OLIVE 23 SYSCOLOR_DKGRAY
2.2.3.3 RGB
An Origin color value can also represent an RGB value. RGB values are made up of 8-bit red, green,
and blue components. These values can easily be made using the RGB macro}.
DWORD brown = RGB(139,69,19); // saddle brown
The values returned from the RGB macro cannot be directly used as Origin color values. You will
need to use the RGB2OCOLOR macro to convert the RGB values to Origin color values.
DWORD brown = RGB2OCOLOR(RGB(139,69,19)); // saddle brown
If you ever need to know whether an Origin color value represents an RGB value or an index into a
palette then you can use the OCOLOR_IS_RGB macro. This macro returns true if the value
represents an RGB value and returns false otherwise.
if( OCOLOR_IS_RGB(ocolor) )
out_str("color value represents an RGB color");
else
out_str("color value represents a color index");
Once you determine that an Origin color value represents an RGB value, then you can use the
GET_CRF_FROM_RGBOCOLOR macro to extract the RGB value from the Origin color value.
if( OCOLOR_IS_RGB(ocolor) )
{
DWORD rgb = GET_CRF_FROM_RGBOCOLOR(ocolor);
printf("red = %d, green = %d, blue = %d\n",
GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
}
2.3 Operators
Operators support the same arithmetic, logical, comparative, and bitwise operators as ANSI C. The
following sections list the four types of operators and show their usage.
7
Origin C Programming Guide
* multiplication
/ division
% modulus (remainder)
+ addition
- subtraction
exponentiate
^
See note below.
Note: Origin C, by default, treats the caret character(^) as an exponentiate operator. This is done to
be consistent with LabTalk. ANSI C uses the caret character as the exclusive OR operator. You can
force Origin C to treat the caret character as the exclusive OR operator by using a special pragma
statement before your code.
Dividing an integer by another integer will give an integer result by default. Use the pragma statement
below before codes to make Origin C compiler to treat all numeric literals as double type.
The modulus operator calculates the remainder of the left operand divided by the right operand. This
operator can only be applied to integral operands.
8
Language Fundamentals
== equal to
!= not equal to
if( aa >= 0 )
out_str("aa is greater than or equal to zero");
if( 12 == aa )
out_str("aa is equal to twelve");
if( aa < 99 )
out_str("aa is less than 99");
! NOT
&& AND
|| OR
Consider the following two examples:
expr2 will not be evaluated if expr1A evaluates to false or expr1B evaluates to true. This behavior is
to the programmer's advantage and allows efficient code to be written. The following demonstrates
the importance of ordering more clearly.
In the above example the entire 'if' expression will evaluate to false if ptr is equal to NULL. If ptr is
NULL then it is very important that the dataValue not be compared to the upperLimit because reading
the dataValue member from a NULL pointer can cause an application to end abruptly.
~ complement
9
Origin C Programming Guide
& AND
exclusive OR (XOR)
^
See note below.
| inclusive (normal) OR
Note: Origin C, by default, treats the caret character as an exponentiate operator. This is done to be
consistent with LabTalk. ANSI C uses the caret character as the exclusive OR operator. You can
force Origin C to treat the caret character as the exclusive OR operator by using a special pragma
statement before your code.
int nn = 5;
if( nn ) // integer type, 0 = false, non-zero = true
{
out_str("nn not 0");
}
10
Language Fundamentals
The following is a simple if-else block in Origin C. Note that the if-block and the else-block are
enclosed in separate sets of curly braces, {}.
if( bRet )
{
out_str("Valid input"); // when bRet is true
}
else
{
out_str("INVALID input"); // when bRet is false
}
The curly braces are optional if the block contains only one statement. This means the above code
can also be written without the braces.
if( bRet )
out_str("Valid input"); // when bRet is true
else
out_str("INVALID input"); // when bRet is false
case 3:
out_str("Case 3");
// no break keyword here, so fall through to case 4
case 4:
out_str("Case 4");
break;
default:
out_str("Other cases");
break;
}
11
Origin C Programming Guide
{
printf("char at %2d is %c\n", index, str[index]);
}
int count = 0;
while( count < 10 ) // execute statements if condition is true
{
out_int("count = ", count);
count++;
}
int count = 0;
do
{
out_int("count = ", count);
count++;
} while( count < 10 ); // execute statements if condition is true
2.4.5.1 break
2.4.5.2 continue
printf("%d\n", index);
}
2.4.5.3 goto
out_str("Begin");
goto Mark1;
12
Language Fundamentals
out_str("Skipped statement");
Mark1:
out_str("First statement after Mark1");
foreach(PageBase pg in Project.Pages)
{
printf("%s is of type %d\n", pg.GetName(), pg.GetType());
}
Refer to the Collections section for a list of all the Collection based classes in Origin C.
2.5 Functions
2.5.1 Global Functions
Origin C provides many global functions for performing a variety of tasks. These global functions fall
into twenty-six categories.
1. Basic IO
3. COM
4. Communications
5. Curve
6. Data Conversion
7. Data Range
8. Date Time
9. File IO
11. Fitting
13
Origin C Programming Guide
17. Mathematics
20. NAG
22. Spectroscopy
23. Statistics
24. System
25. Tree
Please refer to the Global Functions section for a complete list of functions with examples.
The following code snippet shows how to call the above function.
2.6 Classes
14
Language Fundamentals
Origin C supports many built-in classes, but also allows users to create their own.
class Book
{
public:
string GetName()
{
return m_strName;
}
And below is a simple example using the class and method definitions above to declare an instance
of the Book class, give it a name using SetName, and then output the name using GetName.
void test_class()
{
Book OneBook; // Declare a Book object
// Call public function to Set/Get name for the Book object
OneBook.SetName("ABC");
out_str(OneBook.GetName());
}
The above example is very simple. If you want to know more class features, for example,
constructors and destructors, or virtual methods, please view the EasyLR.c, EasyLR.h and EasyFit.h
files in this zip file, under the \Origin C Examples\Programming Guide\Extending Origin C .
15
Origin C Programming Guide
The try block consists of the try keyword followed by one or more statements enclosed in braces.
Immediately after the try block is the catch handler. Origin C supports only a single catch handler that
accepts an integer argument. After the catch keyword comes one or more statements enclosed in
braces.
try
{
LPSTR lpdest = NULL; // NULL pointer on purpose
strcpy(lpdest, "Test"); // copy to NULL pointer to cause error
}
catch(int nErr)
{
out_int("Error = ", nErr);
}
The try-catch works by executing the statements in the try block. If an error occurs, the execution will
jump to the catch block. If no error occurs then the catch block is ignored.
The throw keyword is optional and is used to trigger an error and cause execution to jump to the
catch block.
void TryCatchThrowEx()
{
try
{
DoSomeWork(4); // pass a valid number to show success
DoSomeWork(-1); // pass an invalid number to cause error
}
catch(int iErr)
{
printf("Error code = %d\n", iErr);
}
}
void DoSomeWork(double num)
{
if( num < 0 )
throw 100; // Force error
if( 0 == num )
throw 101; // Force error
16
3 Predefined Classes
Analysis Class
System Class
Utility Class
This class provides a method for accessing the information of the fitting
NLFitContext function, as well as the current evaluation state that is generated by
implementing the fitting function in Origin C.
This class is the higher level Origin class. It wraps the NLFit class with a
friendly interface to aid in implementing the fitting evaluation procedure. It is
NLFitSession the kernel of the NLFit dialog. This class is recommended for coding in
Origin C, because it takes care of all the complexities that arise from the
process of interfacing to Origin.
17
Origin C Programming Guide
complex This class is used to handle number data of complex type. It contains
both the Real part and Imaginary part of the complex number.
This class, which is derived from the vectorbase class, from which it
inherits methods and properties, is an abstract base class and is
curvebase used to handle the classes of Curve type, polymorphically. So
objects of curvebase type cannot be constructed, and a derived
class, such as Curve, should be used instead.
This class is derived from the vector and vectorbase classes, and it
inherits their methods and properties. A Dataset is an array, which is
allocated and sized dynamically. It can be tied or not tied to an
Dataset internal Origin data set. By default, the Dataset is of type double, but
it can also be of any basic data type, including char, byte, short,
word, int, uint and complex (but not string). The syntax
Dataset<type> can be used to construct these types of Dataset.
18
Predefined Classes
This class is derived from the matrix and matrixbase classes, from
which it inherits methods and properties. A Matrix (upper case M) is a
two-dimensional array, which is allocated and sized dynamically, and
tied to an internal Origin matrix window. The default type of a Matrix
is double, but any basic data type is allowed as well, including char,
byte, short, word, int, uint and complex (but not string). The syntax
Matrix<type> is used to construct these types of Matrix.
Matrix This class is used to access the data in the internal Origin matrix,
while the MatrixObject class is used to control the style of the matrix.
That is to say, the relationship between the MatrixObject and Matrix
classes is the same as the one between the Column and Dataset
classes.
The data values displayed in the cells of the Origin matrix
(referenced by a Matrix object) are typically referred to, in the
worksheet, as Z values, whose associated X and Y values are
linearly mapped to the columns and rows of the matrix, respectively.
This class is derived from the matrixbase class, from which it inherits
methods and properties. A matrix (lower case m) is a two-
dimensional array, which is allocated and sized dynamically, and is
matrix not tied to any internal Origin matrix window, which provides more
flexibility. The default type of a matrix is double, but any basic data
type can be used as well, including char, byte, short, word, int, uint
and complex (but not string). The syntax matrix<type> is used to
construct these types of matrix.
This class is an abstract base class for handling the matrix and
matrixbase Matrix class types polymorphically. Thus, objects of matrixbase type
cannot be constructed, and objects of its derived classes, such as
matrix and Matrix, should be used instead.
This class is only used for including the properties of different data
PropertyNode types, such as Bool, int, float, double, string, vector, matrix, and
picture, etc.
Tree This class is used to save Origin C trees as XML files, as well as to
load XML files to Origin C trees.
TreeNode This class provides several methods for constructing multilevel trees,
traversing trees and accessing the attributes of tree nodes.
TreeNodeCollection This class is used to get a collection of child tree nodes with an
enumerative name prefix.
vectorbase This class is an abstract base class used for handling objects of
19
Origin C Programming Guide
This class is derived from the vectorbase class, from which it inherits
methods and properties. A vector is an array, which is allocated and
sized dynamically, and not tied to any internal Origin data set, which
vector allows for more flexibility. The default type of vector is double, but
other basic data types are also allowed, including char, byte, short,
word, int, uint, complex, and string. The syntax vector<type> can be
used to construct these types of vector.
20
Predefined Classes
DatasetObject This class is used to access non-numeric data sets, which are
usually members of Column objects.
21
Origin C Programming Guide
GetGraphPoints This class is used to get the position (x, y) of a screen point or
data point from an Origin graph window.
22
Predefined Classes
GraphPageBase This class is the base class for GraphPage and LayoutPage.
23
Origin C Programming Guide
24
Predefined Classes
This class is the Origin C base class for all Origin objects.
OriginObject Member functions and data members are provided in this
class for all Origin objects.
25
Origin C Programming Guide
Origin allows for saving binary type (TreeNode type) and INI
type (INIFile type) information in Origin objects, which can be
storage any Origin C objects derived from the OriginObject class,
such as a WorksheetPage, Column, Folder, GraphPage,
GraphLayer, DataPlot, Project, etc.
26
Predefined Classes
This class is used to control the permission to read/write the binary files by using
file unbuffered io (accessing immediate disk). It is similar to the MFC CFile class.
Please also refer to the stdioFile class, which is for buffered stream io to text
27
Origin C Programming Guide
files.
INIFile This class is used to access the data stored in the initialization file.
Registry The methods in this class are used to access Windows registry.
This class is derived from the file class, from which it inherits methods and
properties. This class is used to control the permission to read/write the text and
stdioFile binary files by using buffered stream io. However, this class does not support
stream io to stdin, stdout, and stderr. Please also refer to the file class, which is
for unbuffered io to binary files.
*BitmapRadioButton This class provides the functionality of bitmap radio button controls.
*CodeEdit This class is derived from the RichEdit class. It is used to display the
redefined color for key words in coding text.
*ColorText This class is only available in Origin packages that have the
DeveloperKit installed.
28
Predefined Classes
*Dialog This class is the base class for displaying dialog boxes on the
screen.
*DialogBar This class is used to create a Dockable control bar with a child Origin
C-driven dialog.
*ListBox This class is used to define list boxes. A list box shows a list of string
items for viewing and selecting.
*OriginControls This class is the base class for displaying the Origin window on
dialog.
*PictureControl This class is used to paint a PictureHolder object within the control
on dialog.
29
Origin C Programming Guide
This class provides methods for formatting text. A rich edit control is
*RichEdit a window, in which text can be written and edited. The text can be in
character and paragraph formatting.
A slider control is a window with a slider and optional ticks. When the
*Slider slider is moved by the mouse or the directional keys on the
keyboard, the control will send a notification message to implement
the change.
A wait cursor is a visual sign for indicating that the software is busy
waitCursor processing data. This class provides methods and properties for
opening and controlling wait cursors.
*Window This class is the base class of all window classes. It is similar to the
MFC CWnd class.
*WndContainer This class is the base class of the derived control classes.
30
Predefined Classes
For more details about the following classes, please refer to the Origin C: Origin C Reference:
Classes: Utility chapter in the help document of OriginC.
Class Brief Description
This class is a collection of almost all data types and objects. When
Array Array::IsOwner is TRUE, the array will be the owner of the memories that are
allocated to the objects. And the objects will be destroyed when the array is
resized or destructed.
BitsHex This class is used to compress byte vectors (1 and 0) to hexadecimal strings, and
decompress hexadecimal strings to byte vectors.
Profiler This class can be used to measure the call times of various functions to find out
the slower ones.
31
4 Creating and Using Origin C Code
Debugging
4.2.1 Overview
Code Builder is an Integrated Development Environment (IDE) for Origin C and LabTalk
programming. Code Builder provides tools for writing/editing, compiling, linking, debugging, and
executing your Origin C code. Although Origin C code can be written in any text editor, it must be
added to Code Builder's Workspace to be compiled and linked.
33
Origin C Programming Guide
34
Creating and Using Origin C Code
The build process happens much faster than with source files
The system variables that allow you to produce either object (OCB) or preprocessed (OP) files are
@OCS, @OCSB, and @OCSE. You can change their values in the Script Window or in the Code
Builder LabTalk Console. For example, in the Script Window, enter:
@OCS
The default value of this variable is 1, which allows you to create an OCB file or OP file. If @OCS=0,
the compiler will not create an OCB file or an OP file.
@OCSB
The default value of @OCSB=1; this generates an object file at compile time. To generate an OP file,
set @OCSB=0, after which OP files will be generated at compile time. The OP file will be saved in the
same folder as its source file and have the same file name, but with the OP extension. Note that if
@OCS=0, this variable is meaningless.
@OCSE
This variable is only available in OriginPro. Its default value is 1. By default the compiler will generate
an encrypted OP file, which will hide implementation details. The encrypted OP file can be loaded
and linked by either Origin or OriginPro versions. Note: this variable is only meaningful when
@OCSB=0.
Notes:
1. The generated OP and OCB have 32 bit and 64 bit versions. For example, the op
file generated from abc.c file on a 32 bit version will be named as abc_32.OP.
2. Since Origin 9.0, the generated 32 bit or 64 bit version file works only in its
corresponding version (32 bit or 64 bit) of Origin.
35
Origin C Programming Guide
2. Project
3. System
4. Temporary
5. User [AutoLoad]
6. User
4.2.3.1 Apps
This folder is used to manage packages. This folder contains only folders, and each folder represents
a disk folder in User Files Folder. A special folder named Common is used for holding files that are
shared between all packages. Each package folder contains a subfolder named "User Files", which
contains files that are in the User Files Folder.
Context menu of "Apps" folder
When you right click on the Apps folder, there is a context menu with two items:
1. Add Existing Folder...
36
Creating and Using Origin C Code
2. New
The first is for choosing a folder that already exists in the User Files Folder, and the second is for
creating a new folder named Untitled which also creates a new disk folder named Untitled in User
Files Folder. Repeating New will create enumerated Untitled folders.
Context menus of each package folder except Common.
1. Add Files
This is used to add files to the folder. Each package folder represent a disk folder in User
Files Folder. If an added file is from your User Files Folder, then the file is placed in the
"User Files" subfolder to indicate where it will be installed. If selected files are not already
in the User Files Folder and not in User Files Folder\packageFolder\, they will be copied
to User Files Folder\packageFolder\ folder.
2. Show Full Path
Show or hide the full path of the files.
3. Rename
Rename the package folder.
4. Delete
Delete the package folder. If a disk folder exists, you will be asked if you want to delete
the disk folder and files also.
5. Duplicate
Duplicate the package folder and its files.
6. Generate
Launch the Package Manager and add the files from the package folder. If an OPX in the
User Files Folder with the same name exists, that OPX will be loaded and all files
removed before adding all the files from the package folder.
7. Generate with Common
Same as Generate, but the files in the Common folder are also added.
Note: Because Common is not a package, its Context menu has only the first two items. This is also
true for User Files folder found in each package.
4.2.3.2 Project
Files in the Project folder are saved within the current Origin project file (*.OPJ). They are added to
the Project folder of the Code Builder workspace when you open an Origin project file containing
them. They are automatically compiled and linked upon opening the project file.
4.2.3.3 System
Files in the System folder are externally saved in Windows folders (usually in the Origin C folder or
one of its subfolders). They are automatically added to the System folder of the Code Builder
workspace, compiled, and linked whenever Origin starts.
4.2.3.4 Temporary
37
Origin C Programming Guide
All files that are not listed in the Project, System, or User folders, and get loaded and compiled when
using Origin, will appear in the Temporary folder. For example, if you export a graph then all the files
used for handling a graph export will appear in the Temporary folder.
4.2.3.6 User
Files in the User folder are externally saved in Windows folders and are manually added to the User
folder of the Code Builder workspace, compiled, and linked by the user in Code Builder.
Notes:
The contents of the Apps and User [AutoLoad] folders persist across all Origin
sessions, while the contents of the Project folder are unique to each Project file
(OPJ).
button .
2. Create a new source code file by pressing Ctrl-N or by clicking the New toolbar button. When
the New File dialog appears enter a name for your source code file and then press Enter or
3. An editor window will open. Go to the end of the last line in the editor window and press enter
void HelloWorld()
}
4. Before we can call this function we need to compile and link the code. You can do this by
38
Creating and Using Origin C Code
5. The Output window will show the compiling and linking progress. If any errors appear, then
double check your function and fix the errors. When no errors appear, the function is ready to
be called.
6. Click in the top part of the Command & Results window. Type the name of your function and
press Enter. In the bottom part of the Command & Results window you should see a repeat of
your function's name, and the line you entered, followed by a line with your function's output.
While these steps are sufficient to get you going with Code Builder, there are many more details that
will help you write, debug and execute your Origin C files effectively. These are covered in the
sections that follow.
Before you can access your Origin C functions, you will need to compile and link them (a process
known as building) using Code Builder.
Once your functions compile and link without error, they are loaded automatically, and you will be
able to access them from the current Origin session. To access your functions in future sessions of
Origin you will need to ensure that they are reloaded and linked; a process that is fast and can be
automated.
This chapter covers the manual and automated build process for Origin C source files and
preprocessed files.
Link the file to all dependents, compiling dependents where necessary, and load the object files
The act of compiling and linking all the files is referred to as building.
After adding the file to the workspace, it needs to be compiled (by clicking the Compile button) to
generate the object file, which will have the same name as the source/preprocessed file, but with the
OCB file extension. In Origin versions 8.1 and later, the object file will be saved in the Application
Data folder. In older versions the file was saved to the User Files\OCTemp folder.
39
Origin C Programming Guide
To build the active file and all its dependents, select the Build button, or select the Rebuild All
button to build all files in the workspace. The object file that is created will be automatically loaded
into memory and linked so that the functions defined in the file are executable within Origin.
Once the object file is generated, subsequent build processes will be much faster. If there are no
changes to the built source/preprocessed file, Code Builder will load and link the object file directly,
but not rebuild the file.
Build: All of the files in a given folder are compiled and linked when that folder is the active window in
the Code Builder (or a dependent of the active window) and the Build toolbar button is clicked.
Build All: files in all Code Builder folders are compiled and linked when the Code Builder Rebuild All
toolbar button is clicked.
Add files to Code Builder's System folder, and they will be built automatically each time Origin
starts. Files in the System folder are also rebuilt each time an Origin project or a Code Builder
The Build on Startup option will build the most recently opened Code Builder workspace upon
Origin startup.
Drag a file from another Workspace folder and drop it on the Project folder.
Drag a file from another Workspace folder and drop it on the System folder.
40
Creating and Using Origin C Code
Closing Code Builder Edits the OriginCSystem section in the Origin.ini file to include your file when
Origin starts so your functions are always ready.
If the Workspace view is not visible then choose Workspace on the View menu.
The next time you start Origin it will check the files in the User folder and try to compile and link any
changed files.
"%Y="<Enter> in the Script or Command window to locate your User File Folder). If you do not
2. In the [Config] section, uncomment (remove the leading ";") OgsN = OEvents. N here can be
3. Open OEvents.ogs under the Origin installation folder. Find the [AfterCompileSystem] section
run.LoadOC(Originlab\AscImpOptions, 16);
4. Save and close this file.
5. Restart Origin and open Code Builder. In the Temporary folder, there are 3 files.
along with the two files. For more details please search run.LoadOC in your Labtalk
documentation.
Alternatively, starting with Origin 2015, Origin supports the User [AutoLoad] folder in Workspace.
Files added in the folder will be automatically loaded on Origin startup.
Right-click on the User [AutoLoad] folder and choose Add files.
41
Origin C Programming Guide
Drag a file from another Workspace folder and drop it on the User [AutoLoad] folder.
empty now.
2. Run the following script in the Command Window... the dragNdrop.c file together with its
dependent files all are loaded into the Temporary folder and compiled.
if(run.LoadOC(OriginLab\dragNdrop.c, 16) != 0)
return 0;
42
Creating and Using Origin C Code
4.4 Debugging
A convenient debugging technique is to define an output macro and then place that macro throughout
your code as shown below.
void DebugStatements()
{
int ii;
DBG_OUT("ii at t0 = ", ii)
ii++;
DBG_OUT("ii at t1 = ", ii)
ii++;
DBG_OUT("ii at t2 = ", ii)
ii++;
DBG_OUT("ii at t3 = ", ii)
printf("Finished running DebugMacros.");
}
During the development cycle the body of the macro can remain defined as above causing the
desired debug messages to be shown on the message box. However, once development is complete
(or at least stable) the macro can be redefined as below causing the debug statements to disappear.
Commenting out the body of the DBG_OUT macro (and rebuilding) causes the debug statements to
disappear without having to remove the many possible instances of its use, saving them for possible
reuse in the future. Should the code ever need to be modified or debugged again the body of the
macro can simply be uncommented.
43
Origin C Programming Guide
Once Origin C functions have been compiled, linked and loaded, they are ready to be used in Origin.
This means calling the function by its name and providing the necessary arguments from any location
in Origin that accepts LabTalk script commands. Common locations include the script window, the
command window, or a custom button in the Origin GUI. Running Scripts chapter of the LabTalk
Scripting Guide details all of the locations in Origin from which script, and therefore Origin C
functions, can be used.
The above code prevents foo0 from being called from LabTalk, allows foo1 to be called from LabTalk,
and allows foo2 to be called from LabTalk using the run -oc command. If you were to comment out
the second pragma, then both foo0 and foo1 would be prevented from being called from LabTalk.
This is because a single pragma statement applies to all functions after the pragma and up to the
next pragma or the end of the file.
There is also a LabTalk system variable that controls LabTalk access to all Origin C functions. The
variable is @OC, and it defaults to 1, which enables access. Setting the variable to 0 disables
access.
44
Creating and Using Origin C Code
Note that setting @OC=0 will make Origin C functions effectively invisible to LabTalk, such that the
list f command will give no result.
bool int No
vector<complex> dataset No
As the table above indicates, arguments of Origin C functions of type string, int, and double may be
passed by value or by reference from LabTalk. Note, however, that the Origin C function must be
written for the type of pass being performed.
Passing by Value
Below are examples of passing arguments by value from LabTalk to Origin C. The format for each
example is to give the Origin C function declaration line, and then the LabTalk code used to call it.
The Origin C function body is left out since it is unimportant for demonstrating variable passing.
The simple case of a function accepts an argument of type double and returns a double.
Here, an Origin C function that takes a vector argument and returns a vector, is called by LabTalk
using data set variables, or ranges that are assigned to data types.
45
Origin C Programming Guide
Passing by Reference
For the Origin C function below, note the ampersand & character in the argument declaration,
indicating that the argument will be passed by reference.
The following example demonstrates some arguments being passed by reference and others being
passed by value.
//Or use a data set from a column; be sure to put data in Col(A)
get_min_max_double_arr(Col(A), dMin, dMax);
The following example shows passing a LabTalk matrix range variable by reference to an Origin C
function.
2. Origin C Function
Thus, LabTalk functions like Normal and Data (which return a range of values and are thus used in
46
Creating and Using Origin C Code
vector notation) would have higher precedence than Origin C functions of the same name. In all other
cases, the Origin C function is called.
#pragma labtalk(1,Math)
double add2num(double a, double b)
{
return a + b;
}
#pragma labtalk(1,Statistics)
double mean2num(double a, double b)
{
return (a + b)/2;
}
In this way, many functions can be defined in a single source file and, upon building, be immediately
available in the desired locations of the F(x) menu.
Functions to be added to the F(x) menu must conform to the following additional restrictions:
The return type of the function cannot be void
The function should not have reference or pointer (&) for argument type
When an encrypted OCZ file is open in Origin session, since Origin 2016 SR0 user
can choose to re-save the *.ocz file as not encrypted *.c or *.cpp by selecting menu
File: Save As and choose a file type in Save as type drop-down list.
47
Origin C Programming Guide
file named MyButton.c, copy the following code to it and save it to the User File Folder\OriginC\
subfolder.
void OnButtonClick()
DataRange dr;
dr.Add(wks, 0, "X");
dr.Add(wks, 1, "Y");
GraphPage gp;
gp.Create();
GraphLayer gl = gp.Layers(0);
int nn = gl.AddPlot(dr);
gl.Rescale();
}
2. Create an OGS file named MyButton.ogs to load the Origin C source file and call function.
48
Creating and Using Origin C Code
[Main]
if(0 == Run.LoadOC(%Y\OriginC\MyButton.c))
OnButtonClick;
}
3. In the Origin menu, choose View: Toolbars. In the Customize Toolbar dialog, choose the
Button Groups tab, and click New button to open the Create Button Group dialog. Set
MyButton as the Group Name, keep Number of Buttons as 1, choose the Userdef.bmp file
from the User File Folder as Bitmap, and click the OK button. In the ensuing Save As dialog,
click the Save button to save the MyButton.ini file to the default path.
4. In the Customize Tool dialog, select MyButton item from Groups list, and click to choose the
button from Buttons panel, then click Settings button from Button group to open a Button
Settings dialog. Choose MyButton.ogs as the File Name, type "Main" in for Section Name,
then make sure the following check-boxes are unchecked: Matrix, Excel, Graph, Layout and
5. Click Export to open the Export Button Group dialog, then click Add File and choose the
49
Origin C Programming Guide
6. Click Export button, then in the Save As dialog click Save to save the MyButton.OPX file to the
specified folder.
7. Choose menu Tools: Package Manager, and in the dialog that opens, choose File: Open to
Run.LoadOC(%Y\OriginC\MyButton.c);
8. into LabTalk Script: After Installation in gird view to load the Origin C source file. This script
will be run when you drop OPX into Origin to install this application.
50
5 Matrix Books Matrix Sheets and Matrix Objects
The Origin C MatrixPage class is for working with Origin matrix books. Each matrix book contains a
collection of MatrixLayers and each matrix layer contains a collection of MatrixObjects.
Matrix Sheets
Matrix Objects
51
Origin C Programming Guide
Both matrix book and workbook are windows, and they share lots of similar operations, and the Basic
Workbook Operation chapter can be referred to.
1. Create New Matrix Book
MatrixPage matPg;
The difference to open a matrix book by Open method is that the extension of a matrix book is
ogm.
There are multiple ways to access an existing matrix book and the methods used are the same
as workbooks. The Project class contains a collection of all the matrix books in the project. The
matPg = Project.MatrixPages.Item(2);
The methods SaveToFile will be used for saving matrix book as *.ogm file.
MatrixPage matPg("MBook1");
52
Matrix Books Matrix Sheets and Matrix Objects
This is the same as workbook's show and hide by using the Show property derived from
OriginObject class.
To activate a workbook, the method SetShow can be used by passing parameter of value
MatrixPage matPg("MBook1");
The Destroy method can also be used to destroy (delete) a matrix book.
MatrixPage matPg;
MatrixPage matPage("MBook1");
To handle with matrix book's short name, Long Name and Comments, Origin C provides the
same ways as handling workbook's, including the inherited methods SetName, SetLongName,
53
Origin C Programming Guide
MatrixPage mp("tangent");
mp.ShowImageThumbnails(true); // Pass true to make thumbnail visible
54
Matrix Books Matrix Sheets and Matrix Objects
MatrixLayer ly = Project.ActiveLayer();
if( ly ) // If the active layer is a matrix sheet
ly.Destroy(); // Delete the matrix sheet
MatrixLayer matLy1(strFullName);
matLy2.Attach(strFullName);
2. A matrix book constains a collection of matrix layers. Loop through all matrix layers in a
MatrixPage matPage("MBook1");
foreach(Layer ly in matPage.Layers)
out_str(ly.GetName());
3. Access a specified matrix sheet by its name or index.
// Assume there are at least two matrix sheets on the page MBook1,
MatrixPage matPage("MBook1");
55
Origin C Programming Guide
In Origin, all matrix objects in matrix sheet share the same dimension (the same number of columns
and rows).
1. To get number of rows and columns in a matrix sheet, you can get the first matrix object of a
matrix sheet, and then use the methods (GetNumCols and GetNumRows) in MatrixObject
class.
please note, even this method is defined in MatrixObject, what it changes is the matrix sheet's
dimension, because all matrix objects in the same matrix sheet have the same dimensions.
56
Matrix Books Matrix Sheets and Matrix Objects
values. You can use the SetXY method to set the XY mapping coordinates. Note: this method
is available by matrix object, however, the XY mapping is shared by all matrix objects in the
mo.SetXY(-10, 20, -2.3, 12.4); // Set X from -10 to 20, and Y from
-2.3 to 12.4
A matrix label includes a Long Name, Units, and Comments for X, Y, Z. The labels of X and Y are for
all matrix objects in the matrix sheet, the label of Z is for each matrix object. The following code
shows how to get and set the labels.
1. Set XY Labels
MatrixPage mp("MBook1");
Tree tr;
57
Origin C Programming Guide
if( 0 == ml.UpdateThemeIDs(tr.Root) )
MatrixPage mp("MBook1");
Tree tr;
if( !trX.LongName.IsEmpty() )
if( !trX.Unit.IsEmpty() )
if( !trX.Comment.IsEmpty() )
if( !trY.LongName.IsEmpty() )
if( !trY.Unit.IsEmpty() )
58
Matrix Books Matrix Sheets and Matrix Objects
if( !trY.Comment.IsEmpty() )
MatrixPage mp("MBook1");
Tree tr;
MatrixPage mp("MBook1");
MatrixObject mo = ml.MatrixObjects(0);
Tree tr;
59
Origin C Programming Guide
if( !tr.Root.Unit.IsEmpty() )
if( !tr.Root.Comment.IsEmpty() )
MatrixLayer ml = Project.ActiveLayer();
Tree tr;
tr.Root.CommonStyle.Fill.FillColor.nVal = SYSCOLOR_BLUE;
tr.Root.CommonStyle.Color.nVal = SYSCOLOR_LTMAGENTA;
DataRange dr;
dr.Add(NULL, ml, 2, 2, 5, 3); // first row, col, last row, col
if( 0 == dr.UpdateThemeIDs(tr.Root) )
dr.ApplyFormat(tr, TRUE, TRUE);
The next example shows how to get and set the text color of a cell.
60
Matrix Books Matrix Sheets and Matrix Objects
return false;
vector<uint> vTextColor;
if( !grid.GetCellTextColors(vTextColor, col, row, row) )
return false;
color = vTextColor[0];
return true;
}
uint color;
getCellTextColor(ml, row, col, color);
printf("color == %d\n", color);
}
MatrixLayer mlMerge;
mlMerge.Create("Origin"); // Create a new sheet for merging
MatrixObject mo1 = ml1.MatrixObjects(0); // Matrix object in 2nd sheet
MatrixObject mo2 = ml2.MatrixObjects(0); // Matrix object in 3rd sheet
MatrixObject mo3 = ml3.MatrixObjects(0); // Matrix object in 4th sheet
matobj_move(mo1, mlMerge); // Move the matrix object to the end of the
sheet
matobj_move(mo2, mlMerge);
matobj_move(mo3, mlMerge);
61
Origin C Programming Guide
The method MatrixLayer::Insert will insert a specified number of matrix objects before the current
matrix object.
MatrixLayer ml = Project.ActiveLayer();
ml.SetActive(2); // Set 3rd (index is 0-based) matrix object active
62
Matrix Books Matrix Sheets and Matrix Objects
// The data type of matrix object must keep consistent with the matrix
window
if( FSI_SHORT == mo.GetInternalDataType() )
{
matrix<short>& mat = mo.GetDataObject();
}
int nImgIndex = 0;
MatrixObject mo = ml.MatrixObjects(nImgIndex);
if( !mo.IsImageView() )
{
BOOL bAllObjs = FALSE;
ml.SetViewImage(TRUE, bAllObjs, nImgIndex); // FALSE for data view
}
63
Origin C Programming Guide
Matrix object's internal data types include double, real, short, long, char, text, mixed, byte, ushort,
ulong, and complex, etc. And Origin C provides the GetInternalDataType and SetInternalDataType
methods in MatrixObject class to get and set matrix object internal data type respectively.
The MatrixObject::GetFormat and MatrixObject::SetFormat are provided for getting and setting the
data format of a matrix object respectively.
64
Matrix Books Matrix Sheets and Matrix Objects
// multiply 10 for each data in matrix, this change also effect on window
mat = mat * 10;
// Get matrix object from matrix sheet by index, name is not allowed.
MatrixObject mo1 = matLayer1.MatrixObjects(0);
MatrixObject mo2 = matLayer2.MatrixObjects(0);
65
Origin C Programming Guide
// To vector
MatrixLayer ml = Project.ActiveLayer(); // Active matrix sheet
MatrixObject mo = ml.MatrixObjects(0); // The 1st matrix object
matrixbase &mb = mo.GetDataObject(); // Get data from matrix object
vector vb;
mb.GetAsVector(vb); // Convert the matrix data into vector
// From vector
MatrixLayer ml1;
ml1.Create("Origin"); // Create a matrix sheet
MatrixObject mo1 = ml1.MatrixObjects(0); // Get matrix object
matrixbase &mb1 = mo1.GetDataObject(); // Get data object
mb1.SetSize(2, 3); // Set size 2 rows x 3 columns
vector v = {1, 2, 3, 4, 5, 6}; // Vector data
// Set vector data to matrix object
// First row: 1, 2, 3
// Second row: 4, 5, 6
int iRet = mb1.SetByVector(v);
void MatrixObject_Complex_EX()
{
// Original data for real
matrix mR =
{
{2, 2, 2, 0},
{0, 1, 99, 99}
};
// Original data for imaginary
matrix mI =
{
{3, -3, 0, 3},
{0, 99, 1, 99}
};
matrix<complex> mC;
// Create a complex data
int iRet = mC.MakeComplex(mR, mI);
if(iRet == 0)
66
Matrix Books Matrix Sheets and Matrix Objects
{
// Create a new matrix sheet for complex data
MatrixLayer ml;
ml.Create("Origin");
MatrixObject mo = ml.MatrixObjects(0);
ml.SetInternalData(FSI_COMPLEX);
matrixbase &mb = mo.GetDataObject();
mb = mC;
MatrixLayer ml = Project.ActiveLayer();
MatrixObject mo = ml.MatrixObjects(0);
matrixbase &mb = mo.GetDataObject();
67
Origin C Programming Guide
// Convert the active matrix object's data into a newly created worksheet
directly,
// without tranposing, and with setting the column type the same as matrix
MatrixLayer ml = Project.ActiveLayer(); // Active matrix sheet
MatrixObject mo = ml.MatrixObjects(0); // Get the first matrix object
matrixbase &mb = mo.GetDataObject(); // Get the data from matrix object
Worksheet wks;
wks.Create("Origin"); // Create a new worksheet
mb.CopyTo(wks, 0, 0, -1, -1, 0, 0, FALSE, TRUE); // Convert the data to
worksheet
68
6 Workbooks Worksheets and Worksheet Columns
The Origin C WorksheetPage class is for working with Origin workbooks. Each workbook contains a
collection of Worksheets and each worksheet contains a collection of Columns.
Workbooks
Worksheet Columns
Worksheets
6.2 Workbooks
6.2.1 Workbooks
The Origin C WorksheetPage class provides methods and properties common to Origin workbooks.
This class is derived from Page class, from which it inherits its methods and properties.
69
Origin C Programming Guide
Workbook Manipulation
You can also access a workbook by passing its index to the Item method of the Collection class.
WorksheetPage wksPg;
wksPg = Project.WorksheetPages.Item(2);
if(wksPg) // if there is a 3rd workbook
out_str(wksPg.GetName()); // output workbook name
If the workbook name is known, this workbook can be accessed by passing its name to the class
constructor.
WorksheetPage wksPg("Book1");
if(wksPg) // if there is a workbook named "Book1"
wksPg.SetName("MyBook1"); // rename the workbook
70
Workbooks Worksheets and Worksheet Columns
Origin allows you to save a workbook with data to a file (*.ogw), or as a template without data (*.otw),
and for the workbook with analysis, it is able to be saved as an analysis template (*.ogw). And
methods SaveToFile and SaveTemplate are used for saving workbook as *.ogw and *.otw files
respectively.
WorksheetPage wksPg("Book1");
// Save workbook as OGW file
bool bRet1 = wksPg.SaveToFile("D:\\" + wksPg.GetName() + ".ogw");
// Save workbook as OTW template
bool bRet2 = wksPg.SaveTemplate("D:\\" + wksPg.GetName() + ".otw");
WorksheetPage wksPg("Book1");
wksPg.Show = false; // Hide the workbook. If true, show the workbook
WorksheetPage wksPg("Book1");
wksPg.SetShow(PAGE_ACTIVATE); // Activate the workbook
// More operations can be done by passing different values, such as
// wksPg.SetShow(PAGE_HIDDEN); // Hide the workbook
// wksPg.SetShow(PAGE_MINIMIZED); // Minimize the workbook
// wksPg.SetShow(PAGE_MAXIMIZED); // Maximize the workbook
WorksheetPage wksPg;
wksPg = Project.WorksheetPages.Item(0); // get first workbook in project
if( wksPg ) // if there is a workbook
wksPg.Destroy(); // delete the workbook
71
Origin C Programming Guide
For a workbook, there will be short name, Long Name, and Comments. The inherited methods,
SetName, SetLongName, SetComments, which are defined in OriginObject class, can be used to
control workbook's name (both short name and Long Name) and comments.
WorksheetPage wksPg("Book1");
if(wksPg)
{
wksPg.SetName("MyBook"); // Rename workbook
wksPg.SetLongName("This is Long Name", false); // Set Long Name
wksPg.SetComments("Comments"); // Set Comments
}
Also, Label property is provided for changing Long Name. And TitleShow property is for how to show
short name and Long Name on the workbook's title.
WorksheetPage wksPg1("Book2");
if(wksPg1)
{
wksPg1.Label = "My Label"; // Set Label (also called Long Name)
// Show only Label on workbook's title
wksPg1.TitleShow = WIN_TITLE_SHOW_LABEL;
// Show only short name on workbook's title
// wksPg1.TitleShow = WIN_TITLE_SHOW_NAME;
// Show both short name and Label on workbook's title
// wksPg1.TitleShow = WIN_TITLE_SHOW_BOTH;
}
WorksheetPage wksPgTarget;
wksPgTarget.Create("Origin"); // Create the target workbook
Folder fld = Project.ActiveFolder(); // Get the active/current folder
foreach(PageBase pb in fld.Pages)
{ // Loop all Pages in folder
WorksheetPage wksPgSource = pb; // Convert the Page to
WorksheetPage
// If convert failed, that is to say the Page is not WorksheetPage
if(!wksPgSource)
{
continue; // Next Page
}
// Skip the target workbook
if(wksPgTarget.GetName() == wksPgSource.GetName())
{
continue;
72
Workbooks Worksheets and Worksheet Columns
}
// Loop all worksheet in workbook for merging
foreach(Layer lay in wksPgSource.Layers)
{
Worksheet wks = lay; // Get the worksheet
// Add the worksheet to target workbook
wksPgTarget.AddLayer(wks, 0, false);
}
// If not to keep the source workbook, destroy it
wksPgSource.Destroy();
}
73
Origin C Programming Guide
To add a column to the end of the worksheet, the AddCol method in Worksheet class is available,
and also the InsertCol for inserting a column before a specified position.
Worksheet column labels support Long Name, Units, Comments, Parameters and User-Defined
labels. We can use Origin C code to show/hide labels or to add text to the specified column label.
Worksheet wks;
wks.Create();
Grid gg;
gg.Attach(wks);
wks.Columns(0).SetLongName("X Data");
wks.Columns(1).SetLongName("Y Data");
wks.Columns(0).SetComments("This is a test");
74
Workbooks Worksheets and Worksheet Columns
wks.Columns(0).SetUnits("AA");
wks.Columns(1).SetUnits("BB");
75
Origin C Programming Guide
// 1: None
// 2: Y Error
// 3: X
// 4: L
// 5: Z
// 6: X Error
int nType = col.GetType();
out_int("Type: ", nType);
// Set column type. See more define OKDATAOBJ_DESIGNATION_* in oc_const.h
col.SetType(OKDATAOBJ_DESIGNATION_Z);
76
Workbooks Worksheets and Worksheet Columns
Worksheet wks;
wks.Create("origin", CREATE_VISIBLE);
wks.AddCol();
77
Origin C Programming Guide
{
return;
}
Column col1 = wks.Columns(0); // 1st column
vectorbase &v1 = col1.GetDataObject(); // Get data object
vector<uint> vnIndices; // vector for reverse indices
vnIndices.Data(v1.GetSize() - 1, 0, -1); // Reverse indices
v1.Reorder(vnIndices); // Reverse the data
// Attach to the first column, make sure the format of the column is
// Text & Numeric(default) or Numeric.
Column col(wks, 0);
Or we can use a Dataset object to get and set numeric data for a column. For example:
If the column's format is Date or Time, the data you get from this column will be Julian date/time
data, but not the display-date-time-format string.
78
Workbooks Worksheets and Worksheet Columns
6.4 Worksheets
6.4.1 Worksheets
Origin C provides the Worksheet class for working with the worksheets in a WorksheetPage. While a
workbook contains a collection of worksheets, a worksheet contains a collection of Columns. The
Worksheet class is derived from the Layer class.
Virtual Matrix
79
Origin C Programming Guide
// If book and sheet name are known, the string can be constructed
manually.
string strFullName = okutil_make_book_sheet_string("Book5", "Sheet1");
With the full layer name we can now access the worksheet.
A workbook contains a collection of worksheets. You can loop through all the worksheets in a
specified workbook using the foreach statement.
WorksheetPage wksPage("Book1");
foreach(Layer wks in wksPage.Layers)
out_str(wks.GetName());
80
Workbooks Worksheets and Worksheet Columns
if(wbSource.GetName() == wksPageDest.GetName())
continue;//skip our destination book
81
Origin C Programming Guide
Tree tr;
tr = wks.GetFormat(FPB_ALL, FOB_ALL, TRUE, TRUE);
out_tree(tr); // Output tree to Script window
Or, you may construct a theme tree as in the following three steps. First, create a worksheet and
insert some data:
// Create worksheet
Worksheet wks;
wks.Create("Origin");
wks.SetCell(0, 0, "abc"); // Put text to (0, 0) cell
Second, construct the tree using the range information and provide values for desired properties:
Tree tr;
// Setup the range that the format want to apply
tr.Root.RangeStyles.RangeStyle1.Left.nVal = c1 + 1;
tr.Root.RangeStyles.RangeStyle1.Top.nVal = r1 + 1;
tr.Root.RangeStyles.RangeStyle1.Right.nVal = c2 + 1;
tr.Root.RangeStyles.RangeStyle1.Bottom.nVal = r2 + 1;
// Fill color
tr.Root.RangeStyles.RangeStyle1.Style.Fill.FillColor.nVal =
SYSCOLOR_LTCYAN;
82
Workbooks Worksheets and Worksheet Columns
Worksheet wks;
wks.Create("Origin");
if( bRet )
printf("Successfully merged cells in %s!\n", wks.GetName());
else
printf("Failed to merge cells in %s!\n", wks.GetName());
Tree tr;
tr = wks.GetFormat(FPB_ALL, FOB_ALL, true, true); // Get theme tree of
worksheet
// Start to get the specific tree node from the theme tree
// to set the read-only format for the data cells
string strName = "ogData"; // Use to get the node with the desired format
TreeNode trGrid, trNameStyles;
trGrid = tr.Root.Grid; // Get Grid node
if(!trGrid.IsValid())
return;
TreeNode trNameStyle;
bool bRet = false;
// Loop all children nodes to find out the desired tree node
foreach(trNameStyle in trNameStyles.Children)
{
83
Origin C Programming Guide
// Start to get/create the specific tree node from the theme tree
// to cancel the read-only format for the specified data cell
TreeNode trRangeStyles;
trRangeStyles = trGrid.RangeStyles; // Get RangeStyles node from Grid
node
TreeNode trRangeStyle;
if(!trRangeStyles.IsValid()) // If RangeStyles node does not exist yet
{
// Create RangeStyles node
trRangeStyles = trGrid.AddNode("RangeStyles");
// And create a sub node named RangeStyle1
trRangeStyle = trRangeStyles.AddNode("RangeStyle1");
}
else // If RangeStyles node already exist
{
// Find how many children nodes
int tagNum = trRangeStyles.Children.Count();
// And create a sub node name RangeStyle#, # = tagNum+1
trRangeStyle = trRangeStyles.AddNode("RangeStyle"+(tagNum+1));
}
// Define the range for setting, here range is just one cell
// Left cell of the range, start from 1
trRangeStyle.Left.nVal = 1;
// Top cell of the range, start from 5, including label rows
// there are 4 label rows, then 5 means the first data cell
trRangeStyle.Top.nVal = 5;
// Just one cell, so right of the range is the same with left
trRangeStyle.Right.nVal = 1;
// Just one cell, so bottom of the range is the same with top
trRangeStyle.Bottom.nVal = 5;
trRangeStyle.Style.ReadOnly.nVal = 0; // Set read-only to 0 to cancel it
84
Workbooks Worksheets and Worksheet Columns
It is also able to set the Read-Only format for the cells in label rows. We can just make some simple
changes on the code above. For example, we are going to make the Comments row to be read-only
except the one in column 2, then the corresponding changes are like below.
85
Origin C Programming Guide
If you want to set a display range in a Worksheet, you can use Worksheet::SetBounds, and it is the
same as using the Set As Begin/End menu.
The following code shows how to set a beginning and end for all columns in the current worksheet
window.
Set the size on an empty worksheet, meaning no columns and rows, since otherwise Origin will
need to check the short names of the existing columns to avoid duplicate names when adding
new columns, and this could cost you lots of time. You can use while( wks.DeleteCol(0) ); to
Keep Code Builder closed when running functions to improve the speed of execution.
int nElementSize;
uint nNum;
LPVOID pData = col.GetInternalDataBuffer(&nElementSize, &nNum);
short* psBuff = (short*)pData;
86
Workbooks Worksheets and Worksheet Columns
// OC loop is still slow, but you might pass this pointer to your DLL
// for much faster manipulation, here we just show that the pointer
works
for(int ii = 0; ii < rows; ii++, psBuff++)
{
*psBuff = (ii+1) * (col.GetIndex()+1);
}
col.ReleaseBuffer(); // do NOT forget to call this
}
GraphPage gp;
gp.Create("Origin");
Worksheet wks;
wks.Create();
GraphPage gp;
gp = wks.EmbeddedPages(0); // Get embedded graph page by index
// Sort column
// Before running, please keep active worksheet with two columns fill with
data.
// For example, import \Samples\Mathematics\Sine Curve.dat to worksheet.
Worksheet wks = Project.ActiveLayer();
Column colY(wks, 1); // Y column
87
Origin C Programming Guide
// Sort worksheet
// Before running, please keep active worksheet with two columns fill with
data.
// For example, import \Samples\Mathematics\Sine Curve.dat to worksheet.
Worksheet wks = Project.ActiveLayer();
int nCol = 1; // Ascending sort all worksheet data on the second column
BOOL bIsAscending = true;
BOOL bMissingValuesSmall = TRUE; // Treat missing value as smallest
int r1 = 0, c1 = 0, r2 = -1, c2 = -1; // -1 means end for r2 and c2
int nCol = 1;
Worksheet wks = Project.ActiveLayer();
Column col(wks, nCol);
vector vData = col.GetDataObject();
// to find all less than and equal 0 and return row index
vector<uint> vnRowIndex;
vData.Find(MATREPL_TEST_LESSTHAN | MATREPL_TEST_EQUAL, 0, vnRowIndex);
// Set the number of rows and columns, and data will be kept.
// If want to add a lots of columns and rows at once time, better use
SetSize
int nNumRows = 100;
int nNumCols = 20;
wks.SetSize(nNumRows, nNumCols);
// If want to change the number of rows but keep the number of columns,
// can use -1 replace. For example:
wks.SetSize(nNumRows, -1);
// The same usage also used to change column number and keep row number.
88
Workbooks Worksheets and Worksheet Columns
There are two ways to highlight the selection. The first is to highlight the selected indices.
89
Origin C Programming Guide
Grid gg;
if( gg.Attach(wks) )
{
// convert uint type vector to int type vector
vector<int> vnRows;
vnRows = vnRowIndices;
gg.SetSelection(vnRows);
}
The second method of highlighting a data selection is to prescribe a fill color for the selected rows.
Tree tr;
tr.Root.CommonStyle.Fill.FillColor.nVal = SYSCOLOR_BLUE; // fill color =
blue
tr.Root.CommonStyle.Color.nVal = SYSCOLOR_WHITE; // font color = white
Another way to perform a similar operation is to copy the data from each worksheet into a vector, and
compare the size of the vectors.
90
Workbooks Worksheets and Worksheet Columns
To compare data elements themselves, use the ocmath_compare_data function on the vectors in the
example above.
1. Run the following command in the Command Window to compile the nag_utils.c file and add it
Run.LoadOC(Originlab\nag_utils.c, 16);
2. Include header files in the Origin C file.
#include <wks2mat.h>
#include <Nag_utils.h>
3. Get XYZ data from the active worksheet XYZ columns.
91
Origin C Programming Guide
XYZRange rng;
rng.Add(wks, 0, "X");
rng.Add(wks, 1, "Y");
rng.Add(wks, 2, "Z");
UINT nVar;
if( !is_equal(ystep, 0) )
if( !is_equal(xstep, 0) )
92
Workbooks Worksheets and Worksheet Columns
}
6. Prepare the result matrix window.
MatrixPage mp;
int iRet;
switch(nMethod)
case 0: // Regular
break;
case 1: // Sparse
93
Origin C Programming Guide
break;
break;
default: // Error.
94
Workbooks Worksheets and Worksheet Columns
return;
}
MatrixPage matPg;
matPg.Create("Origin");
MatrixLayer matLy = matPg.Layers(0);
Matrix mat(matLy);
matrix<double> mat1;
if(!mat1.CopyFromWks(wks, 1, -1, 1, -1))
{
out_str("Error: CopyFromWks failed!");
return;
}
mat = mat1;
When your worksheet data is organized in XYZ column form, you should use Gridding to convert
such data into a matrix. Many gridding methods are available, which will interpolate your source data
and generate a uniformly spaced array of values with the X and Y dimensions specified by you.
The following example converts XYZ worksheet data by Renka-Cline gridding method.
95
Origin C Programming Guide
vector vX = dsX;
vector vY = dsY;
vector vZ = dsZ;
ocmath_RenkaCline_Struct comm;
ocmath_renka_cline_interpolation(nPoints, vX, vY, vZ, &comm);
// before running, make sure there is active worksheet window with data.
// For example, new a worksheet window, import XYZ Random Gaussian.dat
from
// Origin folder Samples\Matrix Conversion and Gridding subfolder to
worksheet.
Worksheet wks = Project.ActiveLayer();
// construct a data range object only with Z data, X and Y data will be
auto
// assigned.
DataRange dr;
dr.Add("Z", wks, r1, c1, r2, c2);
96
Workbooks Worksheets and Worksheet Columns
MatrixObject mo;
mo.Attach(dr);
GraphPage gp;
gp.Create("CONTOUR");
GraphLayer gl = gp.Layers(0);
gl.AddPlot(mo, IDM_PLOT_CONTOUR);
gl.Rescale();
mo.Detach();
If you want to assign X and Y data then the data should be monotone. The following example shows
how to construct a virtual matrix with an XYZ data range.
MatrixObject mo;
mo.Attach(dr);
97
7 Graphs
7.1 Graphs
The GraphPage class is for working with a graph window. There is a GraphPage object for each
graph window. A GraphPage object contains a collection of layers. Each of these layers is a
GraphLayer object.
Accessing an Existing Graph
There are multiple ways to access an existing graph. The methods used are the same as those used
for workbooks and matrix books.
You can access a graph by passing its name to the class constructor.
GraphPage grPg("Graph1");
if( grPg ) // if there is a graph named "Graph1"
grPg.SetName("MyGraph1"); // rename the graph
The Project class contains a collection of all the graphs in the project. The following example shows
how to loop through the collection and output the name of each graph.
You can access a graph by passing its zero-based index to the Item method of the Collection class.
GraphPage grPg;
grPg = Project.GraphPages.Item(2);
if( grPg ) // if there is a 3rd graph
out_str(grPg.GetName()); // output graph name
Deleting a Graph
All Origin C's internal classes are derived from the OriginObject class. This class has a Destroy
method that is used to destroy the object. Calling this method on a graph will destroy the graph, all
the layers in the graph, and all the graph objects on each layer.
GraphPage grPg;
grPg = Project.GraphPages.Item(0); // get first graph in project
if( grPg ) // if there is a graph
grPg.Destroy(); // delete the graph
99
Origin C Programming Guide
Managing Layers
GraphPage gp;
gp.Create("3D"); // create a graph using the 3D template
Tree tr;
tr.Root.Background.BaseColor.nVal = SYSCOLOR_RED;
tr.Root.Background.GradientControl.nVal = 1;
tr.Root.Background.GradientColor.nVal = SYSCOLOR_BLUE;
GraphPage gp("Graph1");
if(0 == gp.UpdateThemeIDs(tr.Root) )
gp.ApplyFormat(tr, true, true);
Tree tr;
tr = gl.GetFormat(FPB_ALL, FOB_ALL, true, true);
out_tree(tr);
100
Graphs
GraphLayer gl = Project.ActiveLayer();
Tree tr;
tr.Root.Background.Border.Color.nVal = SYSCOLOR_BLACK;
tr.Root.Background.Border.Width.nVal = 1;
tr.Root.Background.Fill.Color.nVal = SYSCOLOR_WHITE;
if( 0 == gl.UpdateThemeIDs(tr.Root) )
gl.ApplyFormat(tr, true, true);
GraphLayer gl = Project.ActiveLayer();
Axis axesX = gl.XAxis;
GraphLayer gl = Project.ActiveLayer();
Axis axisY = gl.YAxis;
Tree tr;
if(0 == axisY.UpdateThemeIDs(tr.Root) )
{
bool bRet = axisY.ApplyFormat(tr, true, true);
}
101
Origin C Programming Guide
GraphLayer gl = Project.ActiveLayer();
Axis axesX = gl.XAxis;
axesX.Scale.From.dVal = 0;
axesX.Scale.To.dVal = 1;
axesX.Scale.IncrementBy.nVal = 0; // 0=increment by value; 1=number of
major ticks
axesX.Scale.Value.dVal = 0.2; // Increment value
axesX.Scale.Type.nVal = 0;// Linear
axesX.Scale.Rescale.nVal = 0; // Rescake type
axesX.Scale.RescaleMargin.dVal = 8; // precent 8
This example shows how to set scale major ticks number for Y axis.
GraphLayer gl = Project.ActiveLayer();
Axis axesY = gl.YAxis;
Now that we have access to the axis labels we can change their values. The following code sets the
X axis label directly and sets the Y axis label indirectly by linking it to a LabTalk string variable.
Linking to a LabTalk variable requires the label's Programming Control option "Link to variables" to be
turned on. This option is on by default.
To make sure the label changes appear, it may be necessary to refresh the graph page. With our
GraphLayer object we can refresh the page with the following code.
102
Graphs
gl.GetPage().Refresh();
GraphLayer gl = Project.ActiveLayer();
Axis axesX = gl.XAxis;
if(0 == axesX.UpdateThemeIDs(tr.Root) )
{
bool bRet = axesX.ApplyFormat(tr, true, true);
}
GraphLayer gl = Project.ActiveLayer();
Axis axesX = gl.XAxis;
Tree tr;// Set ticks color as Auto, depend on the color of data plot
tr.Root.Ticks.BottomTicks.Color.nVal = INDEX_COLOR_AUTOMATIC;
tr.Root.Ticks.BottomTicks.Width.dVal = 3;
tr.Root.Ticks.BottomTicks.Major.nVal = 0; // 0: In and Out
tr.Root.Ticks.BottomTicks.Minor.nVal = 2; // 2: Out
tr.Root.Ticks.BottomTicks.Style.nVal = 0; // Solid
if(0 == axesX.UpdateThemeIDs(tr.Root) )
bool bRet = axesX.ApplyFormat(tr, true, true);
GraphLayer gl = Project.ActiveLayer();
Axis axesX = gl.XAxis;
Tree tr;
// Show axes begin and end as scale value
tr.Root.Labels.BottomLabels.Custom.Begin.Type.nVal = 2;
tr.Root.Labels.BottomLabels.Custom.End.Type.nVal = 2;
// Set special point as Manual type with the special value and text.
tr.Root.Labels.BottomLabels.Custom.Special.Type.nVal = 3;
103
Origin C Programming Guide
tr.Root.Labels.BottomLabels.Custom.Special.Label.strVal = "Mid";
tr.Root.Labels.BottomLabels.Custom.Special.Value.dVal = 12;
if(0 == axesX.UpdateThemeIDs(tr.Root) )
{
bool bRet = axesX.ApplyFormat(tr, true, true);
}
Plots or Data plots are representations of your data within a graph layer. Each graph layer may
contain one or more plots.
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(-1); // Get active data plot
104
Graphs
GraphPage gp;
gp.Create("BAR"); // Create graph with the specified template
GraphLayer gl = gp.Layers(-1); // Get active graph layer
7.3.2 3D Plot
Plot a 3D surface from a matrix on a graph window.
// Plot 3D surface
int nPlotIndex = gl.AddPlot(mo, IDM_PLOT_SURFACE_COLORMAP);
if(0 == nPlotIndex)
{
gl.Rescale();
printf("3D Surface plotted successfully\n");
}
105
Origin C Programming Guide
// Before running, make sure there are XYZ columns with data in the active
// worksheet window. Or you can import \Samples\Matrix Conversion and
Gridding\
// XYZ Random Gaussian.dat into worksheet.
Worksheet wks = Project.ActiveLayer();
DataRange dr;
dr.Add(wks, 0, "X");
dr.Add(wks, 1, "Y");
dr.Add(wks, 2, "Z");
MatrixLayer ml = Project.ActiveLayer();
MatrixObject mo = ml.MatrixObjects(0);
106
Graphs
7.3.5 Multi-Axes
The following example code shows how to show/hide and set format on the four axes - left, bottom,
right, and top in one graph layer.
// Set the major tick and minor tick of all axes as IN format
// See other TICK_* items in graph_utils.h.
vector<int> vnMajorTicks(4), vnMinorTicks(4);
vnMajorTicks[AXIS_BOTTOM] = TICK_IN;
vnMajorTicks[AXIS_LEFT] = TICK_IN;
vnMajorTicks[AXIS_TOP] = TICK_IN;
vnMajorTicks[AXIS_RIGHT] = TICK_IN;
vnMinorTicks = vnMajorTicks;
run.LoadOC(Originlab\graph_utils.c, 16);
Compile the following Origin C code. Before running, make sure there is a workbook named Book1,
and it has one X column and at least two Y columns.
107
Origin C Programming Guide
// Add more layers with right Axis and link to the 1st layer
GraphPage gp;
gp.Create("Origin");
while ( gp.Layers.Count() < nNumYs )
{
page_add_layer(gp, false, false, false, true,
ADD_LAYER_INIT_SIZE_POS_MOVE_OFFSET, false, 0,
LINK_STRAIGHT);
}
// Loop and add plot from each XY data range to graph layer
foreach(GraphLayer gl in gp.Layers)
{
int nLayerIndex = gl.GetIndex();
gl.YAxis.AxisObjects(AXISOBJPOS_AXIS_SECOND).RightTicks.Color.nVal =
gl.YAxis.AxisObjects(AXISOBJPOS_LABEL_SECOND).RightLabels.Color.nVal
= INDEX_COLOR_AUTOMATIC;
gl.Rescale();
}
}
108
Graphs
The following code shows how to add two data markers to the active graph window.
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots();
The code below shows how to change the position of the present data marker.
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots();
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(0);
109
Origin C Programming Guide
There are two ways to see the format tree structure via the following code.
Set a break point on the GetFormat line in the following code, activate one data plot, run the
code, press F10 (Step Over) to execute the GetFormat line, and see the details of the format
tree in the Code Builder Local Variables Window tr variable. (press Alt+4 to open/hide the
Use the last line, out_tree(tr);, to print out the format tree.
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(-1); // Get the active data plot
if( 0 == dp.UpdateThemeIDs(tr.Root) )
{
bool bRet = dp.ApplyFormat(tr, true, true);
}
Tree tr;
110
Graphs
// Load plot settings from a theme file to a tree, and apply format from
// tree to data plot object.
GraphPage gpDest("Graph2");
GraphLayer glDest = gpDest.Layers(0);
DataPlot dpDest = glDest.DataPlots(0);
Tree tr2;
tr2.Load(strTheme);
dpDest.ApplyFormat(tr2, true, true);
GraphPage gpSource("Graph1");
GraphLayer glSource = gpSource.Layers(0);
DataPlot dpSource = glSource.DataPlots(0);
GraphPage gpDest("Graph2");
GraphLayer glDest = gpDest.Layers(0);
DataPlot dpDest = glDest.DataPlots(0);
if( 0 == dp.UpdateThemeIDs(tr.Root) )
{
111
Origin C Programming Guide
GraphLayer gl = Project.ActiveLayer();
GroupPlot gplot = gl.Groups(0); // Get the first group in layer
// the Nester is an array of types of objects to do nested cycling in the
group
// four types of setting to do nested cycling in the group
vector<int> vNester(3);
vNester[0] = 0; // cycling line color in the group
vNester[1] = 3; // cycling symbol type in the group
vNester[2] = 8; // cycling symbol interior in the group
gplot.Increment.Nester.nVals = vNester; // set Nester of the grouped plot
Tree tr;
tr.Root.Increment.LineColor.nVals = vLineColor; // set line color to
theme tree
tr.Root.Increment.Shape.nVals = vSymbolShape; // set symbol shape to
theme tree
// set symbol interior to theme tree
tr.Root.Increment.SymbolInterior.nVals = vSymbolInterior;
if(0 == gplot.UpdateThemeIDs(tr.Root) )
{
bool bb = gplot.ApplyFormat(tr, true, true); // apply theme tree
}
to set Z level and scale type (log type or not). The values in vz argument are Z values.
GraphLayer gl = Project.ActiveLayer();
112
Graphs
DataPlot dp = gl.DataPlots(0);
dp.SetColormap(vZs);
The following example shows how to set up colormap Z levels with log10 scale type.
113
Origin C Programming Guide
vector vLevels;
vLevels.SetSize(nNewLevels);
vLevels.Data(log10(min), log10(max), step);
vLevels = 10^vLevels;
Tree tr;
tr.ColorMap.Details.Levels.dVals = vLevels;
tr.ColorMap.ScaleType.nVal = 1; // 1 for log10
tr.ColorMap.Min.dVal = min;
tr.ColorMap.Max.dVal = max;
DataPlot dp = glay.DataPlots(nPlot);
bool bRet = dp.SetColormap(tr);
if( !bRet )
{
out_str("fail to set colormap");
return false;
}
return true;
}
Call the above plot_matrix function with coutour template and IDM_PLOT_CONTOUR plot id to plot
contour graph and then set colormap on it.
Call the above plot_matrix function with image template and IDM_PLOT_MATRIX_IMAGE plot id to
plot image graph and then set colormap on it.
The following example shows how to remove fill color, and set up line color, style, width and text
labels on a Contour graph.
114
Graphs
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(0);
Tree tr;
dp.GetColormap(tr);
This example shows how to set the format(i.e. color, size, bold, italic) of the text labels on a Contour
graph.
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(0);
// Get all properties of the related objects of the colormap data plot
Tree tr;
tr = dp.GetFormat(FPB_ALL, FOB_ALL, true, true);
115
Origin C Programming Guide
tr.Root.NumericFormats.Prefix.strVal = "_";
tr.Root.NumericFormats.Suffix.strVal = "Label";
tr.Root.NumericFormats.MinArea.nVal = 5; // Labeling Criteria - Min
Area(%)
if(0 == dp.UpdateThemeIDs(tr.Root) )
dp.ApplyFormat(tr, true, true);
GraphPage gp;
gp.Create("Origin");
while(gp.Layers.Count() < 6)
{
gp.AddLayer();
}
graph_arrange_layers(gp, 3, 2);
116
Graphs
wks.ImportASCII(strDataFile, ai);
}
index++;
}
GraphLayer gl = Project.ActiveLayer();
GraphPage gp = gl.GetPage();
foreach(GraphLayer gl in gp.Layers)
{
if( gl.GetIndex() != glActive.GetIndex() )
gl.Show(false);
}
}
117
Origin C Programming Guide
The following example will arrange the existing layers on the active graph into two rows by three
columns. If the active graph does not already have 6 layers, it will not add any new layers. It arranges
only the layers that exist.
GraphLayer gl = Project.ActiveLayer();
GraphPage gp = gl.GetPage();
GraphLayer gl = Project.ActiveLayer();
GraphPage gp = gl.GetPage();
stLayersGridFormat stFormat;
stFormat.nXGap = 0; // the X direction gap of layers
stFormat.nYGap = 5; // the Y direction gap of layers
stFormat.nLeftMg = 15; // left margin
stFormat.nRightMg = 10;
stFormat.nTopMg = 10;
stFormat.nBottomMg = 10;
// resize layer
dWidth /= 2;
dHeight /= 2;
layer_set_size(gl, dWidth, dHeight);
118
Graphs
Before compiling the following codes, you need to add graph_utils.c to your current workspace. Run
Labtalk command "Run.LoadOC(Originlab\graph_utils.c)" to do this.
layer_swap_position(gl1, gl2);
The following example will swap the position on the page of layers named Layer1 and Layer2.
GraphPage gp("Graph1");
GraphLayer gl1 = gp.Layers("Layer1");
GraphLayer gl2 = gp.Layers("Layer2");
layer_swap_position(gl1, gl2);
119
Origin C Programming Guide
GraphLayer gl = Project.ActiveLayer();
string strName = "MyRect";
GraphObject goRect = gl.CreateGraphObject(GROT_RECT, strName);
GraphLayer gl = Project.ActiveLayer();
GraphObject go = gl.CreateGraphObject(GROT_TEXT, "MyText");
go.Text = "This is a test";
The example below shows how to add an arrow to a graph. The object type of an arrow is
GROT_LINE, the same type as a line. And for both lines and arrows, the number of data points
required is 2.
GraphPage gp;
gp.Create();
GraphLayer gl = gp.Layers();
Tree tr;
tr.Root.Dimension.Units.nVal = 5; // Set unit as Scale
120
Graphs
tr.Root.Arrow.Begin.Style.nVal = 0;
tr.Root.Arrow.End.Style.nVal = 1;
if( 0 == go.UpdateThemeIDs(tr.Root) )
{
go.ApplyFormat(tr, true, true);
}
The example below shows how to add a curved arrow to a graph. For a curved arrow, the number of
data points required is 4.
GraphPage gp;
gp.Create();
GraphLayer gl = gp.Layers();
Tree tr;
tr.Root.Dimension.Units.nVal = 5; // Set unit as Scale
tr.Root.Arrow.Begin.Style.nVal = 0;
tr.Root.Arrow.End.Style.nVal = 1;
if( 0 == go.UpdateThemeIDs(tr.Root) )
{
go.ApplyFormat(tr, true, true);
}
Tree tr;
121
Origin C Programming Guide
if( 0 == goText.UpdateThemeIDs(tr.Root) )
{
bool bRet = goText.ApplyFormat(tr, true, true);
}
if( 0 == go.UpdateThemeIDs(tr.Root) )
{
bool bRet = go.ApplyFormat(tr, true, true);
}
122
Graphs
if( 0 == go.UpdateThemeIDs(tr.Root) )
{
go.ApplyFormat(tr, true, true);
}
if( 0 == go.UpdateThemeIDs(trEvent.Root) )
{
go.ApplyFormat(trEvent, true, true);
}
123
Origin C Programming Guide
wks.SetCell(1, 0, "2");
wks.SetCell(1, 1, "Layer 2");
wks.SetCell(2, 0, "3");
wks.SetCell(2, 1, "Layer 3");
124
8 Working with Data
Numeric Data
String Data
This section gives examples of working with numeric data in Origin C. Numeric data can be stored in
variables of the following data types:
1. double
2. integer
3. vector
4. matrix
Numeric data and strings can be stored in the nodes of a tree, provided the nodes have one of the
data types above.
Note:Values such as 0.0, NANUM (missing value) and values between -1.0E-290 to 1.0E-290 will be
evaluated to be False in logic statement.
double d = NANUM;
if( NANUM == d )
out_str("The value is a missing value.");
Origin C also provides the is_missing_value function for testing if a value is a missing value.
if( is_missing_value(d) )
125
Origin C Programming Guide
int nn = 0;
str = nn;
out_str(str);
8.2.4 Vector
// One-Dimensional array with basic data type, for example, double, int,
string,
// complex.
vector vx, vy;
126
Working with Data
8.2.5 Matrix
// Two-Dimensional array with basic data type, for example, double, int,
complex,
// but not string.
matrix mat(5, 6);
8.2.6 TreeNode
The Origin C TreeNode class provides several methods for constructing multi-level trees, traversing
trees and accessing the value/attributes of tree nodes.
Tree tr;
tr.UserID.nVal = 10;
127
Origin C Programming Guide
8.2.7 Complex
complex cc(1.5, 2.2);
8.2.8 DataRange
The DataRange class is a versatile mechanism to get and put data in a Worksheet, Matrix or Graph
window.
// Construct a data range on the active worksheet, all columns and rows
// from 1st row to 5th row.
Worksheet wks = Project.ActiveLayer();
int r1 = 0, c1 = 0, r2 = 4, c2 = -1;
DataRange dr;
// range name should be make sense, for example, "X", "Y",
// "ED"(Y error), "Z". If the data range is not belong to dependent
// or independent type, default can be "X".
dr.Add("X", wks, r1, c1, r2, c2);
Get data from data range to vector. DataRange::GetData supports multiple overloaded methods. For
example:
128
Working with Data
vector vData;
int index = 0; // range index
dr.GetData(&vData, index);
MatrixLayer ml = Project.ActiveLayer();
DataRange dr;
int nMatrixObjectIndex = 0;
dr.Add(ml, nMatrixObjectIndex, "X");
matrix mat;
dr.GetData(mat);
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(); // Get active data plot
DataRange dr;
int i1 = 0; // from the first data point
int i2 = -1; // to the last data point
dp.GetDataRange(dr, i1, i2);
#include <GetNBox.h>
// Open a dialog to choose a range from one graph data plot.
// And construct a data range object by this selection.
GETN_TREE(tr)
GETN_INTERACTIVE(Range1, "Select Range", "")
if( GetNBox(tr) ) // returns true if click OK button
{
DataRange dr;
dr.Add("Range1", tr.Range1.strVal);
vector vData;
int index = 0; // range index
129
Origin C Programming Guide
130
Working with Data
out_str(str);
int end = str.Find('!', begin); // Find and return the index of '!'
end--; // Move the previous character of !
// Get the sub string with the begin index and substring length
int nLength = end - begin + 1;
string strSheetName = str.Mid(begin, nLength);
out_str(strSheetName);// Should output "Sheet1"
131
Origin C Programming Guide
// Converts a time value and corrects for the local time zone
TM tmLocal;
convert_time_to_local(&aclock , &tmLocal);
double dJulianDate;
SystemTimeToJulianDate(&dJulianDate, &st); // Convert to Julian date
132
9 Projects
9.1 Projects
The Origin C Project class is used for accessing the various high level objects contained in an Origin
project. This includes workbooks, matrixbooks, graphs, notes, folders, and more.
Managing Projects
Managing Folders
Accessing Pages
Accessing Metadata
Accessing Operations
Origin C provides the Project class for opening, saving, and appending projects and for accessing the
various objects contained in a project. The Project class contains collections for all the page types
and loose data sets. There are methods to get the active objects such as the active curve, layer, and
folder.
133
Origin C Programming Guide
Project.Open("c:\\abc.opj", OPJ_OPEN_APPEND);
if( Project.IsModified() )
{
// Set the active project as not modified. We do this when we know
// we do not want to save the changes and want to prevent Origin
// from prompting the user about unsaved changes.
Project.ClearModified();
// Start a new project, knowing the user will not be prompted about
// unsaved changes in the active project.
Project.Open();
}
Pages in an Origin project (workbooks, matrix books, and graphs) can be organized in a hierarchical
folder structure, visible in Origin's Project Explorer. The Origin C Folder class allows you to create,
activate, select, and arrange folders.
134
Projects
fldRoot.Activate();
135
Origin C Programming Guide
Metadata is information which refers to other data. Examples include the time at which data was
originally collected, the operator of the instrument collecting the data and the temperature of a sample
being investigated. Metadata can be stored in Projects, Pages, Layers and Columns.
136
Projects
In the Command Window or Script Window you can use the LabTalk command list r to list all the
DataRange objects in the current project.
Add Tree
This code declares a variable of type tree, assigns some data to nodes of the tree, and adds the tree
to the current project.
Tree tr;
tr.FileInfo.name.strVal = "Test.XML";
tr.FileInfo.size.nVal = 255;
Get Tree
Likewise, a similar code extracts data stored in an existing tree variable named Test and puts it into
a new tree variable named trTest:
The Project::GetTreeNames method gets the names of all LabTalk tree variables in the project.
Here, the names are assigned to a string vector; the number of strings assigned is returned as an
integer.
vector<string> vsTreeNames;
137
Origin C Programming Guide
Add Tree
Keep an active worksheet window in the current project, to run the example code below. After
running the code to add a user tree, right click on the title of the worksheet window, choose Show
Organizer, and you will see the added user tree show up in the panel on the right.
Get Tree
The OriginObject::GetBinaryStorage method is used to get a tree from an Origin object by name.
138
Projects
out_str(vsNames[nn]);
}
Add Tree
Tree tr;
tr.test.strVal = "This is a column";
tr.value.dVal = 0.15;
col.PutBinaryStorage("colTree", tr);
Get Tree
Tree tr;
if( col.GetBinaryStorage("colTree", tr) )
out_tree(tr);
storage st;
st = wksPage.GetStorage("system");
Tree tr;
tr = st;
139
Origin C Programming Guide
Tree trReport;
uint uid; // to receive the UID of the report range
// true to translate the escaped operation strings(ex. ?$OP:A=1)
// to real dataset name in the returned tree
bool bTranslate = true;
if( wks.GetReportTree(trReport, &uid, 0, GRT_TYPE_RESULTS, true) )
{
out_tree(trReport);
}
OperationManager opManager;
opManager = Project.Operations;
140
Projects
Tree trResult;
wks.GetReportTree(trResult);
The following code shows how to get the needed results from the report tree, convert them to a cell
linking format string, and put it into a newly created worksheet.
string strCellPrefix;
strCellPrefix.Format("cell://%s!", wks.GetName());
// Statistics
vsLabels.Add(strCellPrefix + "RegStats.DOF.row_label");
vsValues.Add(strCellPrefix + "RegStats.C1.DOF");
vsLabels.Add(strCellPrefix + "RegStats.SSR.row_label");
vsValues.Add(strCellPrefix + "RegStats.C1.SSR");
// put to columns
Column colLabel(wksSummary, 0);
Column colValue(wksSummary, 1);
colLabel.PutStringArray(vsLabels);
colValue.PutStringArray(vsValues);
141
10 Importing
10.1 Importing
One of the huge benefits of Origin is the ability to import data of different formats into a worksheet or
a matrix sheet. Origin C provides this ability to import ASCII and binary data files, image files, video
files, and data from a database. The following sections will show you how to import data into a
worksheet or matrix sheet.
Importing Data
Importing Images
Importing Videos
The Worksheet and MatrixLayer classes are derived from the Datasheet class. The Datasheet class
has a method named ImportASCII. The ImportASCII method is used for importing ASCII data files.
There are also ImportExcel and ImportSPC methods for importing Microsoft Excel and spectroscopic
data files, respectively.
143
Origin C Programming Guide
The next example will also import an ASCII data file into a worksheet but it will also obtain additional
information about each column from the file, and set up the worksheet columns.
ASCIMP ai;
if( 0 == AscImpReadFileStruct(strFile, &ai) )
{
ai.iAutoSubHeaderLines = 0; // Disable auto detect sub header
// 1, LongName
// 2. Units
// 3. Expanded Description(User defined)
// 4. Type Indication(User defined)
ai.iSubHeaderLines = 4;
144
Importing
}
}
run.LoadOC(Originlab\FileImport.c, 16);
// Option 16 ensures that all dependent Origin C files are loaded,
// by scanning for the corresponding .h in FileImport.c
#include <..\Originlab\FileImport.h>
void import_with_filter_file()
{
Page pg = Project.Pages(); // Active Page
Sometimes the existing filter might need to be modified to meet the requirements of the data format,
so you need to load the filter from the file and configure it. See the following case:
145
Origin C Programming Guide
#include <..\Originlab\FileImport.h>
void config_filter_tree()
{
string strFile = GetAppPath(1) + "Samples\\Curve Fitting\\Step01.dat";
if( !strFile.IsFile() )
return;
defined in your filter or on the Source page of the Import Wizard, as the target window.
trFilter: A reference to a TreeNode object that holds all the filter settings from your filter file, or
lpcszFile: The full path and name of the file that is being imported.
nFile: The file index number in an ordered sequence of imported files (e.g. If you import n files,
your function gets called n times, and nFile is the file count for the file being processed).
146
Importing
Or
int YourFunctionName(Layer& lyTarget, TreeNode& trFilter, LPCSTR lpcszFile, int nFile)
where:
lyTarget: A reference to a Layer object of type worksheet or Matrix. This would be what you
defined in your filter or on the Source page of the Import Wizard, as the target window.
trFilter: A reference to a TreeNode object that holds all the filter settings from your filter file, or
lpcszFile: The full path and name of the file that is being imported.
nFile: The file index number in an ordered sequence of imported files (e.g. If you import n files,
your function gets called n times, and nFile is the file count for the file being processed).
See an example in the \Samples\Import and Export\User Defined folder, found in the Origin
installation folder.
Note: The target window template named on the first page of the Import Wizard (Source page)
is only used when creating new windows (as would happen under some conditions during drag-
and-drop importing). When choosing File: Import, if your active window is consistent with your
import filter's Target Window specification, no new window is created and a reference to the
page object for the active window is passed to your function. If the active window is of a different
type, a new window is created using the specified template, and the page reference to this new
window is passed.
saVarValues: An string array where the user should put the variable values.
saHdrLines: A reference to an string array that contains the header lines. Note that the Origin
C function does not need to read the data file because the header lines are automatically
trFilter: A reference to a TreeNode object that holds all the filter settings from your filter file, or
147
Origin C Programming Guide
Origin allows you to import images into a matrix or a worksheet cell, and onto a graph. The following
sections will show you how to import images in your Origin C applications.
bool import_image_to_matrix_data(
LPCSTR lpcszMatrixName, // matrix book name
LPCSTR lpcszFileName, // image file name
int nGrayDepth) // import as 8-bit or 16-bit gray
{
// Get the target matrix object
MatrixObject mo(lpcszMatrixName);
if( !mo.IsValid() )
return false;
148
Importing
The following example will embed a JPEG image from a file into a worksheet cell. This is
accomplished using the AttachPicture method of the Worksheet class.
#include <image_utils.h>
149
Origin C Programming Guide
In this example, time is used as the metric by which we seek and import with time skips..
150
11 Exporting
11.1 Exporting
Exporting Worksheets
Exporting Graphs
Exporting Matrices
Exporting Videos
wks.ExportASCII(strFileName,
WKS_EXPORT_ALL|WKS_EXPORT_MISSING_AS_BLANK);
The next example will save all the data in a worksheet to a file, with a comma as the delimiter and
blanks for missing values. In addition the column labels are also saved.
wks.ExportASCII(strFileName,
WKS_EXPORT_ALL|WKS_EXPORT_LABELS|WKS_EXPORT_MISSING_AS_BLANK,
',');
The final example will save the first two columns of data in a worksheet to a file, using a comma as
the delimiter and blanks for missing values. In addition, the column labels are also saved. Row and
column indices start with zero. The end row and column indices can also be -1 to indicate the last row
or last column, respectively.
wks.ExportASCII(strFileName,
WKS_EXPORT_ALL|WKS_EXPORT_LABELS|WKS_EXPORT_MISSING_AS_BLANK,
151
Origin C Programming Guide
'\t',
0, 0, // start with first row, first column
-1, 1); // end with last row, second column
string strFileName;
foreach(GraphPage gp in Project.GraphPages)
{
strFileName.Format("c:\\%s.emf", gp.GetName());
export_page(gp, strFileName, "EMF");
}
The next example will export the active graph to an 800x600 JPEG file. The JPEG file name will be
the name of the graph and will be located in the root of drive C.
GraphPage gp;
gp = Project.ActiveLayer().GetPage();
if( gp ) // if active page is a graph
{
string strFileName;
strFileName.Format("c:\\%s.emf", gp.GetName());
export_page_to_image(strFileName, "JPG", gp, 800, 600, 8);
}
file ff;
if ( !ff.Open("C:\\ExpMatData.txt", file::modeCreate|file::modeWrite) )
return; //fail to open file for write
string strRange;
MatrixLayer ml = Project.ActiveLayer();
ml.GetRangeString(strRange);
152
Exporting
run.LoadOC(Originlab\image_utils.c);
MatrixLayer ml = Project.ActiveLayer();
MatrixObject mo = ml.MatrixObjects();
export_Matrix_to_image("c:\\matrixImg.jpg", "jpg", mo);
return err;
The following example shows how to individually write a graph page into video and define the number
of frames of this graph page in the video.
153
Origin C Programming Guide
GraphPage gp("Graph1");
vw.WriteFrame(gp, nNumFrames);
154
12 Analysis and Applications
Mathematics
Statistics
Curve Fitting
Signal Processing
12.2 Mathematics
12.2.1 Normalize
The following example shows how to pick a point in a data plot (curve) and then normalize all curves
in the layer to the same value at that point. This snippet of code assumes a graph layer with multiple
curves is active and all curves share the same X values. This assumption is typical in spectroscopy.
GraphLayer gl = Project.ActiveLayer();
if( !gl )
return;
// Allow user to click and select one particular point of one particular
curve
GetGraphPoints mypts;
mypts.SetFollowData(true);
mypts.GetPoints(1, gl);
155
Origin C Programming Guide
12.2.2 Interpolation/Extrapolation
The ocmath_interpolate function is used to do interpolation/extrapolation with modes of Linear,
Spline and B-Spline.
DataRange drSource;
drSource.Add(wks, 0, "X"); // 1st column - source x data
drSource.Add(wks, 1, "Y"); // 2nd column - source y data
DataRange drOut;
drOut.Add(wks, 2, "X"); // 3rd column - input x data
drOut.Add(wks, 3, "Y"); // 4th column - interpolated y data
156
Analysis and Applications
double dSmoothingFactor = 1;
int iRet = ocmath_interpolate(vOutx, vOuty, nOutSize, vSrcx, vSrcy,
nSrcSize,
nMode, dSmoothingFactor);
drOut.SetData(&vOuty, &vOutx);
12.2.3 Integration
Origin C provides access to NAG's integral routines to perform integration. With Origin C and NAG
you can do integration on a normal integrand, an integrand with parameters, an integrand with
oscillation, an infinite integral, higher dimension integration, and more. The following examples show
how to do integration with NAG.
Your Origin C code will need to include the NAG header file at least once before your code calls any
NAG functions.
Nag_QuadProgress qp;
NagError fail;
// For the error other than the following three errors which are due
to
// bad input parameters or allocation failure. You will need to free
157
Origin C Programming Guide
printf("%g\n", result);
}
Now, we set parameter values for the function and define the additional parameters necessary to
perform the integration. The integration is then performed by a single function call, passing the
parameters as arguments.
void nag_d01sjc_ex()
{
double a = 0.0;
double b = 2.0; // integration interval
158
Analysis and Applications
Nag_User comm;
comm.p = (Pointer)¶m;
// Perform integration
// There are 3 kinds of infinite boundary types you can use in Nag
infinite
// integrator Nag_LowerSemiInfinite, Nag_UpperSemiInfinite,
Nag_Infinite
/*
d01smc(f_callback, Nag_LowerSemiInfinite, b, epsabs, epsrel,
max_num_subint,
&result, &abserr, &qp, &comm, &fail);
*/
d01sjc(f_callback, a, b, epsabs, epsrel, max_num_subint,
&result, &abserr, &qp, &comm, &fail);
// For errors other than the following three errors which are due to
// bad input parameters, or allocation failure,
// you will need to free the memory allocation before calling the
// integration routine again to avoid memory leakage.
if (fail.code != NE_INT_ARG_LT && fail.code != NE_BAD_PARAM
&& fail.code != NE_ALLOC_FAIL)
{
NAG_FREE(qp.sub_int_beg_pts);
NAG_FREE(qp.sub_int_end_pts);
NAG_FREE(qp.sub_int_result);
NAG_FREE(qp.sub_int_error);
}
printf("%g\n", result);
}
159
Origin C Programming Guide
Main function:
void nag_d01wcc_ex()
{
// Input variables
int ndim = NDIM; // the integral dimension
double a[4], b[4];
for(int ii=0; ii < 4; ++ii) // integration interval
{
a[ii] = 0.0;
b[ii] = 1.0;
}
int minpts = 0;
int maxpts = MAXPTS; // maximum number of function evaluation
double eps = 0.0001; // set the precision
// Output variable
double finval, acc;
Nag_User comm;
NagError fail;
if (fail.code != NE_NOERROR)
printf("%s\n", fail.message);
12.2.4 Differentiation
The ocmath_derivative function is used to do simple derivative calculations without smoothing. The
function is declared in ocmath.h as shown below.
int ocmath_derivative(
160
Analysis and Applications
const double* pXData, double* pYData, uint nSize, DWORD dwCntrl = 0);
The function ignores all missing values and computes the derivative by taking the average of the two
slopes between the point and each of its neighboring data points. If the dwCntrl argument uses the
default value of 0, the function fills in the average when data changes direction.
If dwCntrl is set to DERV_PEAK_AS_ZERO, the function fills in zero if data changes direction.
12.3 Statistics
Often we want to do statistics on the selected data in a worksheet, i.e. one column, one row, or an
entire worksheet. The Working with Data: Numeric Data: DataRange chapter shows how to
construct a data range object by column/row index, then get the raw data into a vector.
int N;
double Mean, SE;
ocmath_basic_summary_stats(vData.GetSize(), vData, &N, &Mean, NULL, &SE);
printf("N=%d\nMean=%g\nSE=%g\n", N, Mean, SE);
vector vBinCenters(nBinSize);
vector vAbsoluteCounts(nBinSize);
vector vCumulativeCounts(nBinSize);
161
Origin C Programming Guide
In addition, there are two functions to calculate frequency count for discrete/categorical data. One is
ocu_discrete_frequencies for text data, and the other is ocmath_discrete_frequencies for numeric
data. Also, there are two functions to calculate frequency count on 2 dimensions:
ocmath_2d_binning_stats and ocmath_2d_binning.
NormTestResults SWRes;
if( STATS_NO_ERROR == ocmath_shapiro_wilk_test(vTestData.GetSize(),
vTestData,
&SWRes, 1) )
{
printf("DOF=%d, TestStat=%g, Prob=%g\n", SWRes.DOF, SWRes.TestStat,
SWRes.Prob);
162
Analysis and Applications
Linear Fitting
Polynomial Fitting
Multiple Regression
Non-linear Fitting
Find XY
void linearfit()
163
Origin C Programming Guide
2. Get the data from the worksheet for linear fit. Both independent and dependent are using vector
variables.
if(!wks)
WorksheetPage wp = wks.GetPage();
DataRange dr;
vector vX;
vector vY;
these options.
GETN_TREE(trGUI)
GETN_ID_BRANCH(IDST_LR_OPTIONS) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
GETN_ID(IDE_LR_FIX_INTCPT)
164
Analysis and Applications
GETN_ID(IDE_LR_FIX_INTCPT_AT)
GETN_ID(IDE_LR_FIX_SLOPE)
GETN_ID(IDE_LR_FIX_SLOPE_AT)
GETN_CHECK(UseReducedChiSq,
STR_FITTING_CHECKBOX_USE_RED_CHI_SQR, 1)
GETN_ID(IDE_FIT_REDUCED_CHISQR)
GETN_END_BRANCH(Fit)
if( !GetNBox(trGUI) )
LROptions stLROptions;
// Do linear fit with the above input dataset and fit option
settings
165
Origin C Programming Guide
if(nRet != STATS_NO_ERROR)
out_str("Error");
return;
string strResult;
tree_to_str(trResult, strResult); // convert tree to string
166
Analysis and Applications
{
// prepare report tree
int nID = 100; // Each node must have node ID and node ID must be
unique
Tree tr;
tr.Report.ID = nID++;
TreeNode trReport = tr.Report;
trReport.SetAttribute(TREE_Table, GETNBRANCH_TRANSPOSE);
// column 1
trReport.P1.ID = nID++;
trReport.P1.SetAttribute(STR_LABEL_ATTRIB, "Parameter"); // column
label
trReport.P1.SetAttribute(STR_COL_DESIGNATION_ATTRIB,
OKDATAOBJ_DESIGNATION_X);
// column 2
trReport.P2.ID = nID++;
trReport.P2.SetAttribute(STR_LABEL_ATTRIB, "Value"); // column label
trReport.P2.SetAttribute(STR_COL_DESIGNATION_ATTRIB,
OKDATAOBJ_DESIGNATION_Y);
// column 3
trReport.P3.ID = nID++;
trReport.P3.SetAttribute(STR_LABEL_ATTRIB, "Prob>|t|"); // column
label
trReport.P3.SetAttribute(STR_COL_DESIGNATION_ATTRIB,
OKDATAOBJ_DESIGNATION_Y);
167
Origin C Programming Guide
168
Analysis and Applications
DataRange dr;
dr.Add("X", wks, 0, 0, -1, 0); // x column
dr.Add("Y", wks, 0, 1, -1, 1); // y column
2. Define the structure variables and other data types as parameters for passing to the function. It
also can initialize some fitting settings.
3. Pass the desired arguments and perform polynomial fitting on the data.
// check error
if(nRet!=STATS_NO_ERROR)
169
Origin C Programming Guide
{
out_str("Error");
return;
}
DataRange dr;
dr.Add("X", wks, 0, 0, -1, 2); // first three columns
dr.Add("Y", wks, 0, 3, -1, 3); // the fourth column
matrix mX;
dr.GetData(mX, 0, 0); // get data of first three columns to matrix
vector vY;
dr.GetData(&vY, 1); // get data of the fourth column
2. Declare and initialize the parameters that will be passed to the function.
170
Analysis and Applications
3. Pass the prepared parameters to the function and perform multiple linear regression.
Run.LoadOC(Originlab\nlsf_utils.c, 16)
// Set Function
NLFitSession nlfSession;
171
Origin C Programming Guide
if ( !nlfSession.SetFunction("Gauss") )
{
out_str("Fail to set function!");
return;
}
Set two XY datasets with DATA_MODE_GLOBAL mode, to perform global fitting with sharing of
parameters:
int nNumData = 2;
// Set the first dataset
if ( !nlfSession.SetData(vY1, vX1, NULL, 0, nNumData) )
{
out_str("Fail to set data for the first dataset!");
return;
}
// Parameter initialization
if ( !nlfSession.ParamsInitValues() )
{
out_str("Fail to init parameters values!");
return;
}
vector vParams(nNumParamsInFunction*nNumData);
// set parameter value for the first dataset
vParams[0] = 5.5; // y0
vParams[1] = 26; // A
vParams[2] = 8; // xc
vParams[3] = 976; // w
172
Analysis and Applications
return;
// Do fit
int nFitOutcome;
nlfSession.Fit(&nFitOutcome);
int nDataIndex = 0;
RegStats fitStats;
NLSFFitInfo fitInfo;
nlfSession.GetFitResultsStats(&fitStats, &fitInfo, false, nDataIndex);
printf("# Iterations=%d, Reduced Chisqr=%g\n", fitInfo.Iterations,
fitStats.ReducedChiSq);
173
Origin C Programming Guide
12.4.6 Find XY
The following procedure will show how to use the specified parameter values to get the value of the
dependent variable from the independent variable or get the value of the independent variable from
the dependent variable.
12.4.6.1 Linear
The formula of getting Y from X:
y = a + x * b;
x = (y - a) / b;
12.4.6.2 Non-linear
For non-linear function, we use NumericFunction class to get y from x and use ocmath_find_xs
function to get x from y.
Get Y from X
#include <ONLSF.h>
#include <..\Originlab\nlsf_utils.h>
void _findy_from_x()
{
// Please use the proper function from the related category in
// Fitting Function Organizer dialog. Press F9 to open this dialog.
// The Poly function below under Polynomial category.
string strFuncFileName = "Poly";
Tree trFF;
if( !nlsf_load_fdf_tree(trFF, strFuncFileName) )
{
out_str("Fail to load function file to tree");
return;
}
NumericFunction func;
if (!func.SetTree(trFF))
174
Analysis and Applications
{
out_str("NumericFunction object init failed");
return;
}
int nNumParamsInFunc =
trFF.GeneralInformation.NumberOfParameters.nVal;
vector vParams(nNumParamsInFunc);
vParams = NANUM;
vParams[0] = 1;
vParams[1] = 2;
vParams[2] = 3;
Get X from Y
The following function shows how to get two X values from the specified Y value. Before running,
please import Samples\Curve Fitting\Gaussian.dat to Worksheet and keep the Worksheet active.
#include <...\originlab\nlsf_utils.h>
#include <FDFTree.h>
void _findx_from_y()
{
double y = 20; // assign 20 as Y value to find X value
175
Origin C Programming Guide
PFN_STR_INT_DOUBLE_DOUBLE_DOUBLEP pFunc =
Project.FindFunction("compute_y_by_x", strFile, true);
string strFuncFileName = "Gauss";
vector vParams(4);
vParams[0] = 5.58333; // y0
vParams[1] = 26; // xc
vParams[2] = 8.66585; // w
vParams[3] = 976.41667; // A
Origin C provides a collection of global functions and NAG functions for signal processing, ranging
from smoothing noisy data to Fourier Transform (FFT), Short-time FFT(STFT), Convolution and
Correlation, FFT Filtering, and Wavelet analysis.
The Origin C functions are under the Origin C help -> Origin C Reference -> Global Functions ->
Signal Processing category.
12.5.1 Smoothing
The ocmath_smooth function support 3 methods: median filter, Savitzky-Golay smoothing and
adjacent averaging smoothing.
12.5.2 FFT
Before using fft_* functions, you need to include fft_utils.h.
#include <fft_utils.h>
12.5.2.1 FFT
fft_real performs a discrete Fourier transform(FFT_FORWARD) or inverse Fourier
transform(FFT_BACKWARD).
176
Analysis and Applications
12.5.2.3 IFFT
12.5.2.4 STFT
The stft_real function is used to perform a Short-Time-Fourier-Transform on 1d signal real data. The
stft_complex function is used to perform a Short-Time-Fourier-Transform on 1d signal complex data.
The following is an example for real data.
int nWinSize = 4;
vector win(nWinSize);
get_window_data(RECTANGLE_WIN, nWinSize, win);
matrix stft;
double stime, sfreq;
vector sig = {0, 0, 0, 1, 1, 0, 0, 0};
stft_real(sig, win, 0.1, 1, 4, stft, stime, sfreq);
#include <..\OriginLab\wavelet_utils.h>
int n = vX.GetSize();
177
Origin C Programming Guide
int ns = vScales.GetSize();
matrix mCoefs(ns, n);
NagError fail;
nag_cwt_real(Nag_Morlet, 5, n, vX, ns, vScales, mCoefs, &fail);
178
Analysis and Applications
if(OE_NOERROR == nRet)
{
printf("Peak Num=%d\n", nDataSize);
vxPeaks.SetSize(nDataSize);
vyPeaks.SetSize(nDataSize);
}
179
Origin C Programming Guide
vyData.GetMinMax(dMin, dMax);
// Get the bigger value from the highest point or the lowest point.
// And multiply 20% to get the peak minimum height.
double dTotalHeight = max(abs(dMax), abs(dMin));
double dPeakMinHeight = dTotalHeight * 20 / 100;
int i1 = 51, i2 = 134; // From/to index to set the sub range of one peak
IntegrationResult IntResult; // Output, integration result
vector vIntegral(i2+1); // Output, integral data
180
Analysis and Applications
If you don't need to know whether the call is successful or not, the error structure declaration is not
needed. And the NAGERR_DEFAULT macro can be passed instead. This macro is a NULL pointer.
To ensure compatibility with future versions of NAG functions, it will be better to use this macro if you
can work without error structure.
When calling the NAG function d01ajc, myFunc (defined above) can be passed as the first argument.
181
Origin C Programming Guide
From the definition, we know that both the return type and the only argument type are double. So we
define the callback function as follows:
The following code shows how to call the c05adc function by passing the myC05ADCfunc callback
function.
12.7.4.1 Dataset
A Dataset object can be passed to a NAG function as long as the Dataset is of the data type
expected by the NAG function. The data type of an Origin worksheet column is Text & Numeric by
default. For most, but not all, NAG functions, this data type is not allowed to be passed, because
NAG functions expect floating or integer pointers.
If you make sure that the Dataset is of the type expected by the NAG function, the following code can
be used to pass a Dataset object to a NAG function.
12.7.4.2 DataRange
The DataRange class provides the GetData method for getting data from a worksheet into a vector,
even if the worksheet columns are of the Text & Numeric data type. The GetData method can also
ignore the rows with missing values easily, which is very important when passing data to NAG
functions.
Using DataRange to pass data from Origin to NAG functions is much safer, and is recommended.
The following example demonstrates how to do that.
void call_NAG_example()
182
Analysis and Applications
{
int i, numPoints = 5;
// Get access to the active worksheet and add two more columns.
Worksheet wks = Project.ActiveLayer();
// Add X2 column
i = wks.AddCol();
Column col(wks, i);
col.SetType(OKDATAOBJ_DESIGNATION_X);
// Add Y2 column
wks.AddCol();
183
Origin C Programming Guide
vX2.Add(xarg);
vY2.Add(fit);
}
}
dsY.Attach(wks, 3);
dsY = vY2;
}
#include <OC_nag.h>
void text_e04ccc()
{
double objf;
double x[2];
Integer n;
n = 2;
x[0] = 0.4;
x[1] = -0.8;
try
{
// call the NAG function, e04cccc = nag_opt_simplex
nag_opt_simplex(n, funct, x, &objf, &opt, NAGCOMM_NULL,
&fail);
}
catch(int err)
{
184
Analysis and Applications
185
13 Output Objects
Results Log
Script Window
Notes Window
Report Sheet
187
Origin C Programming Guide
Note note;
note.Create(); // Create the target Note window
if( note )
{
note.Text = "Hello Note window.";
note.Text += "\nAnother line of text."
}
The next example will use Type.Redirection and Type.Notes$ to redirect Origin C output to a Note
window.
Note note;
note.Create(); // Create the target Note window
LT_set_str("type.notes$", note.GetName());
LT_set_var("type.redirection", 2); // 2 for Note window
188
14 Accessing Database
Object ocora;
try
{
ocora = CreateObject("ADODB.Recordset");
}
catch(int nError)
{
out_str("Failed to create ADODB.Recordset");
return FALSE;
}
189
Origin C Programming Guide
ocora.CursorLocation = adUseClient;
try
{
ocora.open(strQuery, strConn, 1, 3);
}
catch(int nError)
{
out_str("Failed to open Oracle database");
return FALSE;
}
Worksheet wks;
wks.Create();
"Lintilla".
2. Create a table named "FittingSummary" with 9 fields, set the data type of the first two fields as
3. Open OriginExe\Samples\Curve Fitting\autofit.ogw, and fill the columns on the "Data" layer with
data.
4. After recalculating, activate the "Summary" layer, and run the following code to export the result
to a database.
//user should modify connect and query string according to their database
settings.
//such as value of Server, Database, UID, PWD etc.
#define STR_DB_CONN "Driver={MySQL ODBC
3.51 Driver}; \
Server=Lintilla;Port=3306;Option=4;Database=Analysis;UID=test;PWD=te
st;"
#define STR_QUERY "Select * from
FittingSummary"
bool write_wks_to_db()
{
Worksheet wks = Project.ActiveLayer();
190
Accessing Database
if ( wks )
return false;
Object oConn;
oConn = CreateObject("ADODB.Connection");
if ( !oConn )
return error_report("Fail to create ADODB.Connection
object!");
oConn.Open(strConn);
Object oRecordset;
oRecordset = CreateObject("ADODB.Recordset");
if ( !oRecordset )
return error_report("Fail to create ADODB.Recordset
object!");
//open recordset
oRecordset.CursorLocation = 3; //adUseClient, please refer to MSDN
for details
oRecordset.Open(strQuery, oConn, 1, 3); //adOpenKeyset,
adLockOptimistic
191
Origin C Programming Guide
//CREATE TABLE OriginLab(ID INTEGER NOT NULL, NUMBER INTEGER NOT NULL,
SALARY INTE
//GER NOT NULL, Data BLOB NOT NULL);
#include <..\Originlab\oSQLite.h> //required header file
#define STR_DATABASE_FILE "E:\\DataSet1.1.db"
#define STR_QUERY_STRING "select * from Originlab limit 80"
void test_OSQLite()
{
OSQLite sqlObj(STR_DATABASE_FILE);
LPCSTR lpSQL = STR_QUERY_STRING;
sqlObj.Select(lpSQL);
Worksheet wks;
wks.Create("Origin");
sqlObj.Import(wks);
//after modify the data, may use the following code to export data
//sqlObj.Export("OriginLab", wks);
}
192
15 Accessing LabTalk
double dOriginVer;
LT_get_var("@V", &dOriginVer);
printf("Running Origin version %f\n", dOriginVer);
This is how to set the minimum font size used in the Data Display window.
LT_set_var("System.DataDisplay.MinFontSize", 12);
There are times when you will want to temporarily set a LabTalk variable, do some work, and then
restore the LabTalk variable to its original value. There are mainly two ways to do this. The first way
is the long way to do it using LT_get_var and LT_set_var.
double dProgressBar;
LT_get_var("@NPO", &dProgressBar); // get starting value
LT_set_var("@NPO", 0); // set new value
//
// do some work
//
LT_set_var("@NPO", dProgressBar); // restore starting value
193
Origin C Programming Guide
The next way is the simple way using the LTVarTempChange class. To use the class you simply
pass the variable name and the temporary value. The constructor saves the starting value into a data
member and sets the variable to the temporary value. The destructor will restore the variable to its
starting value.
{
LTVarTempChange progressBar("@NPO", 0);
//
// do some work
//
}
char szCustomDateFmt[200];
LT_get_str("System.Date.CustomFormat1$", szCustomDateFmt, 200);
printf("Custom Date Format 1: %s\n", szCustomDateFmt);
This is how to set the font used in the Data Display window.
LT_set_str("System.DataDisplay.Font$", "Courier");
LT_set_str("wks.name$", "MySheet");
string strScript;
string strBook = "Book1";
int iColStart = 2, iColEnd = 5;
strScript.Format("win -a %s;plotxy %u:%u;", strBook, iColStart, iColEnd);
LT_execute(strScript);
The next example calls the LT_execute method of the Layer class instead of the global LT_execute
function. When calling the global LT_execute function, the script runs and will operate on the active
layer when no layer is specified by the script code. When calling the LT_execute method of the Layer
class, the script runs and will operate on the layer instance instead of the active layer.
WorksheetPage wksPg("Book1");
Worksheet wks = wksPg.Layers(0);
WorksheetPage wksPgActive;
wksPgActive.Create("Origin"); // This page is now active
194
Accessing LabTalk
char szFileName[MAX_PATH];
LT_get_str("%A", szFileName, MAX_PATH);
printf("File Name: %s\n", szFileName);
195
16 Accessing X-Function
Origin has many built-in X-Functions for handling a variety of tasks. X-Functions can be called from
both LabTalk and Origin C. This Section will show you how to call X-Functions from Origin C by using
Origin C's XFBase class. This mechanism also can be used in calling one X-Function in another X-
Function.
The XFBase class is declared in the XFBase.h header file located in the Origin C System folder. The
XFBase.h header file is not included in the Origin.h header file so it has to be included separately in
any Origin C file for the use of XFBase class.
#include <XFBase.h>
2. Assign arguments using the SetArg options from the X-Function object
3. Execute the X-Function using the Evaluate method of the X-Function object
The following Origin C code defines a general function for importing files into Origin. The function has
two arguments: data file name and import filter file name. Additional arguments of the impFile X-
Function will use their default values.
return true;
}
The following Origin C code shows how to call the call_impFile_XF function defined above and use it
to import an image file.
197
Origin C Programming Guide
Note:
1. For more example on accessing X-Function, see Help: Programming > Origin C >
198
17 User Interface
Dialog
Wait Cursors
17.2 Dialog
17.2.1 Dialog
A graphic user interface(GUI) is one important part of your customized application in Origin. Creating
GUI is associated with generating dialog in the Origin environment. This section demonstrates
several ways to bring up dialog in Origin:
The simplest dialog can be generated using the Built-in dialog boxes function in Origin C
(OC). the method supports several basic functionalities such as showing messages, opening
If you need more controls of the dialog elements and also have some experience with OC,
GetN Macros and GetNBox function in OC would be the right choice. More or less like C++,
this method grants the access to each element in dialog to which you can add your own
application script.
A more automatic way to build dialog is probably using X-function builder. With this method,
Origin generates dialog automatically for you and your task is merely defining the inputs and
199
Origin C Programming Guide
Python is embedded in Origin since Origin 2015. By calling Python in Origin, interactive dialog
A even more sophisticated way would be to use Microsoft Visual C++ generated resource DLL
for building floating tools, dialog boxes, and wizards in Origin. All elements in Origin, e.g.
Lastly, starting from Origin 2017, we add support for dialogs using HTML and Java Script which
GetN Dialog
X-Function
Python Dialog
Dialog Builder
HTML Dialog
// enter string
string strName = InputBox("Please enter your name", "");
printf("Name is %s.\n", strName);
// enter numeric
double dVal = InputBox(0, "Please enter a value");
200
User Interface
The next example shows an OK-Cancel message box with an exclamation icon to warn the user that
they will not be able to undo an action. This gives the user a choice to proceed or to cancel their
action.
The next example shows a Yes-No message box with a question mark icon. This is being used to ask
the user if they want to continue with their action.
201
Origin C Programming Guide
StringArray saFiletypes(3);
saFiletypes[0]="[Project (*.OPJ)] *.OPJ";
saFiletypes[1]="[Old version (*.ORG)] *.ORG";
saFiletypes[2]="[Worksheets (*.OGW)] *.OGW";
StringArray saFilePaths;
StringArray saFileTypes(3);
saFileTypes[0]="[Project (*.OPJ)] *.OPJ";
saFileTypes[1]="[Old version (*.ORG)] *.ORG";
saFileTypes[2]="[Worksheets (*.OGW)] *.OGW";
string strPath =
GetSaveAsBox(nFDLogUseGroup,GetAppPath(false),strDefaultFilename);
out_str( strPath );
202
User Interface
#include <GetNbox.h>
void simple_dialog()
{
GETN_BOX(trRoot) // define a Tree variable named "trRoot"
// radio button
GETN_RADIO_INDEX_EX(Operator, "Operator", 0, "Add|Subtract")
// list box
GETN_LIST(type, "Operand", 0, "Constant|Reference Data")
// bring up dialog
GetNBox(trRoot );
}
17.2.3.2 Controls
The following table lists the commonly used controls. For more controls and style setup, please refer
to Origin C Reference: Macros: GetN.
Picture Name
GETN_RADIO_INDEX
203
Origin C Programming Guide
GETN_RADIO_INDEX_EX
GETN_CHECK
GETN_LISTBOX
GETN_MULTISEL_LISTBOX
GETN_BUTTON_GROUP
GETN_BUTTON
GETN_COMBO(for numeric)
selection)
text)
GETN_STR_GROUP(multiple selections)
GETN_COMBO_BUTTON
GETN_RANGE
GETN_STR(for string)
GETN_NUM(for numeric)
204
User Interface
GETN_SPINNOR_DOUBLE
GETN_SLIDER
GETN_SLIDEREDIT(editable)
GETN_COLOR
GETN_SYMBOL
GETN_SEPARATOR_LINE
GETN_DATE
GETN_TIME
GETN_PASSWORD
GETN_XYRANGE
GETN_XYRANGE_COMPLEX
GETN_XYZRANGE
GETN_INTERACTIVE
GetNBox(trRoot);
205
Origin C Programming Guide
to
GetNBox(trRoot, node_event);
#include <GetNbox.h>
void GETN_Apply_ex1()
{
GETN_TREE(tr)
GETN_COLOR(LineColor, "Color", 3)
// the option to set color list to contain custom panel
GETN_COLOR_CHOICE_OPTIONS(COLORLIST_CUSTOM | COLORLIST_SINGLE)
206
User Interface
Wizard Dialog
Splitter Dialog
1. Start Visual C++ 6.0, select File->New to open the New dialog. On the Projects tab, choose
Origin Dialog AppWizard, set Project name to "ODialog", choose a Location and click OK.
3. Keep Origin C selected and click Finish, then click OK. The resource file with one simple dialog
and the related source file and header file will be generated.
207
Origin C Programming Guide
6. Go to the file location specified above. Copy the DLL file to outside the Debug or Release
folder, to keep the path of the DLL file the same as that of the ODialog.cpp file.
7. Open the ODialog.cpp file in Origin C Code Builder, compile, and run the DoMyDialog function
This section describes how to create a Resource-only DLL in Visual C++ 6.0.
1. Start Visual C++ 6.0, select File->New to open the New dialog. On the Projects tab, choose
Win32 Dynamic-Link Library as the project template, set the Project name as ODialog, choose
a Location and click OK. In the dialog that appears, select a simple DLL project and click
Finish.
2. Select Project->Settings to open the Project Settings dialog. On the Resources tab, set the
Resource file name, like ODialog.res, and select the Language according to your software
3. Select Insert->Resource to insert resources into the project. For a Dialog and controls on it, set
dialog ID to IDD_OC_DIALOG.
4. Choose File->Save As to save the Resource Script file as ODialog.rc. Choose Project->Add To
5. If the Language is not English, please do this step. In the Workspace view Resource tab, open
the list tree, right click on IDD_OC_DIALOG, choose Properties, and then in the dialog choose
6. Build the whole project with Debug or Release configuration. The resulting DLL file is generated
This article describes in detail the general process of creating a Resource-only DLL in Visual Studio
2008. The following steps show how to build a Resource-only DLL with VS2008 that is accessible in
Origin using Origin C.
1. Start Microsoft Visual Studio 2008.
208
User Interface
3. In the New Project dialog, choose Visual C++ as the programming language and Win32 Project
as the template, type in the project name as "Welcome", select its location, like in the following
209
Origin C Programming Guide
4. In the Win32 Application Wizard dialog, set Application type as DLL and click Finish.
5. Switch to the Resource View of the project, right click on the project name to add resources,
210
User Interface
6. Remember to set the Language property of the resource according to the environment in which
your software will be installed; say English(United States) if your software is in English.
7. Add more controls as required, configure the project as Debug or Release, and save the
project. Then select Build>Build Solution or Rebuild Solution to build the project. You can now
find a folder named "Debug" or "Release" generated under the solution folder, which contains
211
Origin C Programming Guide
This section describes how to use the Resource-only DLL created in the section above.
1. Copy the DLL file to outside the Debug or Release folder, to keep the path of the DLL file the
3. Create a new Origin C file named testODialog.c under the path of the DLL file. Add it to the
current Workspace, and write testing code like the following. Run the OpenDlg function to open
the dialog.
#include <Dialog.h>
public:
// Not specify path, means the DLL file under the same path of
this
// Origin C file.
};
212
User Interface
void OpenDlg()
MyDialog odlg;
odlg.DoModal();
Now that we have defined our class based on PropertyPage we can define a class for handling each
page in the wizard. These next classes will be derived from our page class defined above.
The next class to be defined is the place holder class. This class is derived from the WizardSheet
class which in turn is derived from the PropertySheet class. This class will hold the instances of all
our pages as data members.
213
Origin C Programming Guide
WizPage1 m_WizPage1;
WizPage2 m_WizPage2;
WizPage3 m_WizPage3;
};
With the definitions of all the pages and sheet classes completed we can now define our dialog class.
We first need a dialog resource containing a static control, in which the preview graph will nest. Here
we will use a built-in resource, IDD_SAMPLE_SPLITTER_DLG, in OriginC\Originlab\ODlg8.dll.
In Code Builder, click New button , type file name, and set Location as the same path of the above
dialog resource dll oDlg8.dll - Origin install path OriginC\Originlab subfolder.
class MyPreviewCtrl
{
public:
MyPreviewCtrl(){}
~MyPreviewCtrl()
{
//destroy temporary books when dialog closed.
214
User Interface
if ( m_wksPreview.IsValid() )
m_wksPreview.Destroy();
}
GraphPageControl gpCtrl;
gpCtrl.Create(gCtrl, PREVIEW_NOCLICK_BITS, PREVIEW_TEMPLATE);
GraphPage gpPreview;
gpPreview = gpCtrl.GetPage();
gpPreview.Rename("MyPreview");
m_glPreview = gpPreview.Layers(0); //first layer
if ( !m_wksPreview )
{
//temporary worksheet to hold preview data.
m_wksPreview.Create("Origin", CREATE_TEMP);
m_wksPreview.SetSize(-1, 2); //two columns
//prepare datarange
DataRange drPrev;
drPrev.Add(m_wksPreview, 0, "X");
drPrev.Add(m_wksPreview, 1, "Y");
215
Origin C Programming Guide
private:
//preview graph on dialog
GraphLayer m_glPreview;
~MyGraphPreviewDlg()
{
}
protected:
EVENTS_BEGIN
ON_INIT(OnInitDialog)
ON_BN_CLICKED(IDC_LOAD, OnDraw)
EVENTS_END
private:
//member stands for the preview control
MyPreviewCtrl m_Preview;
};
BOOL MyGraphPreviewDlg::OnInitDialog()
{
m_Preview.Init(IDC_FB_BOX, *this);
Button btn = GetItem(IDC_LOAD);
if( btn )
btn.Text = "Draw";
216
User Interface
return true;
}
m_Preview.Update(vecX, vecY);
return true;
}
void open_preview_dlg()
{
MyGraphPreviewDlg dlg;
dlg.DoModalEx(GetWindow());
return;
}
Execute the function above, and click the Draw button. You will notice the preview be updated.
To create this dialog, you first must prepare a dialog resource with a Static control and two Button
controls. Here we just use the existing resource IDD_SAMPLE_SPLITTER_DLG in the built-in
OriginC\Originlab\ODlg8.dll file to simplify this example.
217
Origin C Programming Guide
In Code Builder, click New button , type file name, and set Location as the same path of the above
dialog resource dll oDlg8.dll - Origin install path OriginC\Originlab subfolder.
The following header files will be used in the example. Copy the following to the above created
source file.
#include <..\Originlab\DialogEx.h>
#include <..\Originlab\SplitterControl.h>
#include <..\Originlab\DynaSplitter.h>
We can derive a class from TreeDynaSplitter. Most dialog initialization and other event functions'
code are done in a base class and make our splitter class a light class.
private:
BOOL constructSettings();
BOOL initSystemInfo(TreeNode& trSys);//show system information
BOOL initUserInfo(TreeNode& trUser);//to collect user settings.
private:
GridTreeControl m_List; //grid control on left panel
Tree m_trSettings;//splitter tree on right panel
bool m_bIsInit;//indicate whether it is from init event
};
218
User Interface
BOOL MySplitter::OnInitSplitter()
{
TreeDynaSplitter::OnInitSplitter(&m_List);
constructSettings(); //construct tree settings
InitSettings(); //tree settings to splitter GUI
SetReady();
return TRUE;
}
BOOL MySplitter::constructSettings()
{
TreeNode trSys = m_trSettings.AddNode("System");
trSys.SetAttribute(STR_LABEL_ATTRIB, "System Information");
219
Origin C Programming Guide
initSystemInfo(trSys);
char szUser[LIC_USERINFO_NAME_COMPANY_MAXLEN];
char szCompany[LIC_USERINFO_NAME_COMPANY_MAXLEN];
char szSerial[LIC_OTHER_INFO_MAXLEN];
char szRegCode[LIC_OTHER_INFO_MAXLEN];
DWORD dwProd = GetLicenseInfo(szUser, szCompany, szSerial,
szRegCode);
string strProduct;
switch( dwProd & 0x000000FF )
{
case ORGPRODUCTTYPE_EVALUATION:
strProduct = "Evaluation";
break;
case ORGPRODUCTTYPE_STUDENT:
strProduct = "Student";
break;
case ORGPRODUCTTYPE_REGULAR:
strProduct = "Regular";
break;
case ORGPRODUCTTYPE_PRO:
strProduct = "Professional";
break;
default:
strProduct = "Unknown";
break;
}
GETN_USE(trSys)
GETN_STR(UserName, "User Name", szUser)
GETN_READ_ONLY_EX(2)
GETN_STR(Company, "Company Name", szCompany)
GETN_READ_ONLY_EX(2)
GETN_STR(SeriNum, "Serial Number", szSerial)
GETN_READ_ONLY_EX(2)
GETN_STR(RegCode, "Register Code", szRegCode)
GETN_READ_ONLY_EX(2)
GETN_STR(Product, "Product Version", strProduct)
GETN_READ_ONLY_EX(2)
return TRUE;
}
220
User Interface
{
if ( !trUser )
return FALSE;
GETN_USE(trUser)
GETN_STRLIST(Language, "Language", "English", "|English|German")
GETN_STR(UserID, "User ID", "")
GETN_PASSWORD(Password, "Password", "")
GETN_STR(Email, "Email", "[email protected]")
return TRUE;
}
The splitter dialog contains a splitter control object, so the dialog can initialize the splitter control and
post messages to it on the proper events.
};
221
Origin C Programming Guide
BOOL MySplitterDlg::OnInitDialog()
{
//rename buttons title to meaningful text
GetDlgItem(IDC_LOAD).Text = "Output";
GetDlgItem(IDCANCEL).Text = "Close";
m_Splitter.Init(IDC_FB_BOX, *this, STR_DLG_NAME);
return TRUE;
}
BOOL MySplitterDlg::OnReady()
{
//update dialog
UpdateDlgShow();
SetInitReady();
//set splittercontrol ready as to init the position and size
m_Splitter.OnReady();
return TRUE;
}
Open Dialog
After the steps above, save all the code and build it, then execute the following function to open the
splitter dialog.
void test_MySplitterDlg()
{
MySplitterDlg dlg;
dlg.DoModalEx(GetWindow());
}
void myTimeConsumingFunction()
{
waitCursor wc; // declare and show the wait cursor
for( int i = 0; i < 10000; i++ )
222
User Interface
{
if( 0 == (i % 100) )
printf("i == %d\n", i);
}
}
The next example is similar to the above example, but adds the ability to exit the function before it
finishes its time consuming task. The exiting early ability is accomplished by calling the wait cursor's
CheckEsc method. This method returns true if the user has pressed the Esc key, otherwise it returns
false.
void myEscapableTimeConsumingFunction()
{
waitCursor wc; // declare and show the wait cursor
for( int i = 0; i < 10000; i++ )
{
if( 0 == (i % 100) )
printf("i == %d\n", i);
if( wc.CheckEsc() )
break; // end loop early
}
}
GetGraphPoints mypts;
// Set as true , the cursor moves along the DataPlot and picks points from
// the curve.
// Set as false, the cursor does not move along the DataPlot, and picks
// points from the screen.
mypts.SetFollowData(true, dp.GetIndex());
// Get the x/y data and indices from the picked points
vector vx, vy;
vector<int> vnPtsIndices, vnPlotIndices;
if( mypts.GetData(vx, vy, vnPtsIndices, vnPlotIndices) == nPts )
{
for(int ii = 0; ii < vx.GetSize(); ii++)
{
printf("point %d: index = %d, x = %g, y = %g, on plot %d\n",
ii+1, vnPtsIndices[ii], vx[ii], vy[ii],
vnPlotIndices[ii]+1);
}
}
223
Origin C Programming Guide
#include <..\Originlab\DialogEx.h>
// OC_REGISTERED key word must allow the PageBase::SetSplitters method
// to find this class.
class OC_REGISTERED MyGraphPolarBar : public Dialog
{
public:
// IDD_POLAR_CONTROL is dialog resource ID
// Odlg8 is the name of dialog resource DLL file, if not specified
path,
//default path is \OriginC\Originlab.
MyGraphPolarBar()
:Dialog(IDD_POLAR_CONTROL, "Odlg8")
{
}
if( bShow )
{
int nPercent = 30;
string strDlgClass = "MyGraphPolarBar"; // the above dialog
class
string strConfig;
switch(nPos)
{
case 0: // Bottom
strConfig.Format("r{%s}r[%s]", (string)nPercent+"%",
strDlgClass);
break;
case 1: // Right
224
User Interface
strConfig.Format("c{%s}c[%s]", (string)nPercent+"%",
strDlgClass);
break;
case 2: // Top
strConfig.Format("r[%s]{%d}r", strDlgClass,
nPercent);
break;
case 3: // Left
strConfig.Format("c[%s]{%d}c", strDlgClass,
nPercent);
break;
}
pg.SetSplitters(strConfig);
}
else
pg.SetSplitters(NULL); // remove dialog bar from page
225
18 Accessing External Resources
The Origin C compiler supports three calling conventions: __cdecl(default), __stdcall and __fastcall.
These calling conventions determine the order in which arguments are passed to the stack as well as
whether the calling function or the called external function cleans the arguments from the stack.
Notes: you don't need to include the .dll extension in the file name. And all function declarations after
the pragma directive will be considered external and from the specified DLL. This assumption is
made until a second #pragma dll(filename) directive appears, or the end of the file is reached.
227
Origin C Programming Guide
#ifdef _OWIN64
#pragma dll(UserFunc_64, header)
#else
#pragma dll(UserFunc, header)
#endif //_OWIN64
18.2.1.4 Examples
A good and complete example of how to access an external DLL is Accessing SQLite Database.
There are other Origin sample projects demonstrating how to call a function from a C dll, a Matlab dll
or a Fortran dll in Origin C. They can be found the Calling Fortran, Calling MATLAB DLL and Calling
C DLL subfolders in this zip file under \Origin C Examples\Programming Guide folder.
This article demonstrate how to use GSL in Origin C. First you need the GSL dll, you can check here
to see how to build GSL dlls, or you can just download them(dlls) from
http://gnuwin32.sourceforge.net/packages/gsl.htm. You need just two dlls (libgsl.dll and
libgslcblas.dll), and you can put them into the same folder where you are going to keep your Origin C
files. For example, in a folder called c:\oc\. When using the downloaded dlls, please pay attention to
the version issues.
libgsl.dll
This is the main gsl dll
libgslcblas.dll
This dll is needed by libgsl.dll
To use libgsl.dll in Origin C, you will need a header file that provides the prototypes of the gsl
functions. You can copy and translate(if needed) the necessary prototype/definition from GSL header
files, for example, call it ocgsl.h, and create in the c:\oc\ folder.
ocgsl.h
228
Accessing External Resources
// you can directly search and copy gsl function prototypes here
GSL_EXPORT double gsl_sf_zeta_int (const int n);
The following is a simple OC file to show how to call gsl_sf_zeta_int and gsl_fit_linear
test_gsl.c
#include <Origin.h>
#include "ocgsl.h"
229
Origin C Programming Guide
Origin C doesn't support external functions that return a struct type variable, so those functions return
this kind of data can not be used in Origin C, e.g.
typedef struct
{
double dat[2];
}gsl_complex;
This charpter will introduce how to access the DLL created by C++(.Net) or C# in Origin C.
230
Accessing External Resources
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace temp
[Guid("4A5BFDFA-7D41-49d1-BB57-C6816E9EDC87")]
231
Origin C Programming Guide
double GetCelsius();
double GetFahrenheit();
namespace temp
[Guid("2AE913C6-795F-49cc-B8DF-FAF7FBA49538")]
public NET_Temperature()
232
Accessing External Resources
return celsius;
return fahrenheit;
233
Origin C Programming Guide
sum += arr[nn];
return sum;
}
3. Choose menu Tools -> Create GUID, in opening dialog select Registry Format radio button,
click New GUID button and then click Copy button. Paste this GUID to replace that one in
[Guid("...")] in the above codes. Reproduce this action again to replace the second GUID in
code.
4. Right click on the project and select Properties to open the property page. Go to Application
tab, and click Assembly Information button, then check the check-box of Make assembly COM-
Visible. If for 32 bit version, go to the Build tab, and select the check-box of Register for COM
interop. If for 64 bit version, go to Build Events tab, and then copy and paste the following
command line to the Post-build event command line text box. Press F6 to build solution.
"%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm"
"$(TargetPath)" /CodeBase
5. Start Origin, open Code Builder, new a c file, then copy the following Origin C code to c file.
void access_DLL()
obj.Fahrenheit = 300;
234
Accessing External Resources
out_double("", obj.GetCelsius());
vector vec;
vec.Data(1,10,1);
out_double("", obj.Sum(var));
235
Origin C Programming Guide
2. Copy the following codes to UserControl.cs file to add a protected override function to set
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SampleControl
[Guid("A31FE123-FD5C-41a1-9102-D25EBD5FDFAF"),
ComSourceInterfaces(typeof(UserEvents)),
ClassInterface(ClassInterfaceType.None),]
public UserControl1()
InitializeComponent();
236
Accessing External Resources
pe.Graphics.FillRectangle(brush, ClientRectangle);
BorderStyle.None;
Refresh();
[Guid("CCBD6133-813D-4dbb-BB91-16E3EFAE66B0")]
}
3. Select Tools -> Create GUID to open Create GUID dialog, choose Registry Format radio
button, click New GUID and Copy button to copy the newly created GUID. Use the new GUID
237
Origin C Programming Guide
4. Choose UserControl1.cs[Design] tab, in Properties window, click Events button , drag scroll
bar to choose MouseClick and double click it to add mouse click event function into
UserControl.cs file. Use the same method to add mouse double click event.
if (OnUserClick != null)
OnUserClick(e.X, e.Y);
if (OnUserDbClick != null)
OnUserDbClick(e.X, e.Y);
238
Accessing External Resources
}
7. Outside UserControl1 class, add the following interface.
[Guid("DA090A6F-FFAC-4a39-ACD3-351FA509CA86"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[DispIdAttribute(0x60020001)]
[DispIdAttribute(0x60020002)]
}
8. Create a resource-only DLL in Visual Studio 2008 as explained in Dialog Builder: Simple Hello
9. Use an ActiveX control in a dialog and show dialog by Origin C. In Origin Code Builder, create
239
Origin C Programming Guide
VTS_I4)
public:
CDotNetComInteropDlg();
EVENTS_BEGIN
ON_INIT(OnInitDialog)
ON_INTEROP_CLICK(IDC_DOTNET, OnClick)
ON_INTEROP_DBLCLICK(IDC_DOTNET, OnDblClick)
EVENTS_END
return true;
240
Accessing External Resources
return true;
BOOL OnInitDialog();
Control m_ctrlDotNet;
};
// Do not specify DLL file path here. Assume the dll file under the
same
CDotNetComInteropDlg::CDotNetComInteropDlg()
: Dialog(IDD_DIALOG1, "DialogBuilder.dll")
InitMsgMap();
BOOL CDotNetComInteropDlg::OnInitDialog()
241
Origin C Programming Guide
//[Guid("A31FE123-FD5C-41a1-9102-D25EBD5FDFAF")]
if(m_ctrlDotNet.CreateActiveXControl(guid,
WS_CHILD|WS_VISIBLE,
ctrlObj.SetBorder(true);
return TRUE;
void Launch_CDotNetComInteropDlg()
CDotNetComInteropDlg dlgDotNet;
dlgDotNet.DoModal();
242
Accessing External Resources
Notes: From Origin 2015, we can run python in Origin (support both command line and .py file), and
use a PyOrigin module to access Origin from Python. view Python.chm for more details.
def SayHello():
print("Welcome to use Python in your Origin C programs!") #actually
this string will not show in Origin C
return 12345
1. First of all, go to the Python installed directory, then create a Python file under this directory,
say "myLib.py". Then open this newly created file using a text editor, Notepad for example, and
2. Start Windows Console (cmd.exe), and then switch the current path to the directory where
Python installed.
3. Run the following command to compile the Python file created just now.
python -m py_compile myLib.py
4. If successfully, there will be a pyc file (myLib.cpython-33.pyc, or something similar with
"myLib") under this folder <Python Installation Directory>/__pycache__/ by default.
243
Origin C Programming Guide
1. Start Visual Studio 2012, and create a new Win32 Project, named OPython.
2. Click OK, and select the Application type to be DLL, and click Finish to create the project.
3. Set the Solution Configurations to be Release. Right click on the project, and choose Property
Note: Here the 32-bit DLL will be created, and that will be used in 32-bit version of Origin.
4. In the Property dialog, from the left panel, activate Configuration Properties: VC++
Directories, and then in the right panel, add the Python header file path and library path to
244
Accessing External Resources
5. From the left panel, activate Configuration Properties: Linker: Input, and then in the right
panel, add the Python library to Additional Dependencies, here is python33.lib. Apply all the
6. Add a header file, named OPython.h, to the project, and put the following code to it.
245
Origin C Programming Guide
#ifndef _OPYTHON_H_
#define _OPYTHON_H_
#ifdef _OPYTHON_CPP_
#else
#define OP_API
//use in OC
#endif
#endif //_OPYTHON_H_
7. Open the OPython.cpp, which is created automatically when creating the project (If no such file,
246
Accessing External Resources
#include "stdafx.h"
#include "OPython.h"
#include <Python.h>
class PythonManager
public:
};
PythonManager::PythonManager()
Py_Initialize();
PythonManager::~PythonManager()
Py_Finalize();
247
Origin C Programming Guide
PythonManager pm;
PyObject* pModule;
PyObject* pFunc;
int nRet = 0;
pModule = PyImport_ImportModule("myLib");
if ( NULL == pModule )
return nRet;
if ( pFunc )
return nRet;
PythonManager pm;
248
Accessing External Resources
PyObject* pModule;
PyObject* pFunc;
float fRet = 0;
pModule = PyImport_ImportModule("myLib");
if ( NULL == pModule )
return fRet;
if ( pFunc )
return fRet;
249
Origin C Programming Guide
}
8. Add a Module-Definition File, named OPython.def, to the project, and replace the original code
250
Accessing External Resources
LIBRARY "OPython"
EXPORTS
;Functions to export
PY_SayHello
PY_Add
PY_Sub
PY_Mult
PY_Div
PY_Mod
9. Build the solution to generate the DLL, OPython.dll, by default
installed.
2. Copy the header file created above (OPython.h) to this folder: <User Files Folder>/OriginC/.
3. Start 32-bit version of Origin and launch Code Builder. Create a new C file and replace with the
#include <Origin.h>
int test_Python()
251
Origin C Programming Guide
return 0;
}
4. Compile the above code in Code Builder, and then run the following line in LabTalk Console
test_Python;
18.2.4.5 Remarks
The example shown in this page is only to create a simple DLL that can reuse the functions written in
Python. If to process a large amount of data in Python, and transfer the data between Origin and
Python, a buffer will be recommended. With buffer, when transfer data from Origin's Column, the
vector, which contains data, can be passed from Origin C to a DLL function, which receive a pointer
(maybe double *pBuffer) as parameter. And any change based on this buffer will take effect
immediately on the vector in Origin C.
The Microsoft Component Object Model (COM) is a software architecture that allows applications to
be built from a binary software component, and it makes the development of software much easier
and more effective.
Origin provides the capability for COM client programming, and it is supported only in OriginPro. This
mechanism uses Object type to represent all COM (automation server) objects. All COM objects can
be initialized in two ways:
Origin C also provides a class to access Matlab, which enables communication between Origin and
Matlab.
#include <Origin.h>
#include <externApps.h> //required header for the MATLAB class
252
Accessing External Resources
void test_Matlab()
{
Matlab matlabObj(true);
if(!matlabObj)
{
out_str("No MATLAB found");
return;
}
COM client programming in Origin C can be used to programmatically exchange data with MS Office
applications. There is a comprehensive example demonstrating how to read data from Excel
worksheets, plot a graph in Origin, and place it in a Word document. This example can be found in
the \Samples\COM Server and Client\MS Office\Client subfolder in Origin.
(Origin C COM programming can also be used to communicate with databases by accessing an
ActiveX Data Object (ADO), and there is a sample file demonstrating that SQL and Access databases
can be imported to a worksheet, and subsequent data modifications returned to the database. For
more information, see the file ADOSample.c in the Samples\COM Server and Client\ADO\Client
subfolder of Origin.
253
19 Reference
19.1 Reference
Class Hierarchy
Collections
255
Origin C Programming Guide
256
Reference
257
Origin C Programming Guide
19.3 Collections
The Collection class provides a template for holding multiple objects of the same type. In Origin C, an
instance of a Collection is read-only. You cannot add items to, or delete items from, a collection.
There are a number of Origin C classes that contain data members which are instances of a
Collection. For example, the Project class contains a data member named WorksheetPages. The
WorksheetPages data member is a collection of all the existing WorksheetPage objects in the project.
The table below lists each of the Origin C Collections, along with the class that contains the collection
and the item types in the collection.
258
Reference
foreach(GraphPage gp in Project.GraphPages)
{
out_str(gp.GetName());
}
259
Origin C Programming Guide
{
out_str(wksPage.GetName());
}
GraphLayer gl = Project.ActiveLayer();
foreach(DataPlot dp in gl.DataPlots)
{
string strRange;
dp.GetRangeString(strRange, NTYPE_BOOKSHEET_XY_RANGE);
260