2.12.2 Accessing Metadata
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.
Column Label Rows
Metadata is most visible in a worksheet where column headers may contain information such as Long Name (L), Units (U), Comments(C), Sampling Interval and various Parameter rows, including User-Defined parameters.
The row indices for column label rows are assigned to characters, which are given in the Column Label Row reference table. Examples of use follow.
Read/Write Column Label Rows
At times you may want to capture or set the Column Label RowsColumn Header string from script. Access the label row by using the corresponding label row characters as a row index.
Note: Numeric cell access does not supported to use label row characters.
Here are a few examples of reading and writing column header strings:
Book1_A[L]$ = Time; // Set the Long Name of column A to '''Time'''
Book1_A[U]$ = sec; // Set the Units of column A to '''sec'''
string strC$ = col(2)[C]$; // Read the Comments of column2 into strC$
// Get value from first system parameter row
double syspar1 = %(col(2)[p1]$);
Col(1)[L]$="Temperature"; // set Col(1) long name to "Temperature"
range bb = 2; // declare a range variable for Col(2)
// Set the long name of Col(2) to that of Col(1) with the string " Data"
Note: For Origin 8.0, LabTalk variables took precedence over Column Label Row characters, for example:
int L = 4; // For Origin 8.0 and earlier ...
Col(B)[L]$= // Returns the value in row 4 of Col(B), as a string
But for Origin 8.1, this has been changed so that the column label rows (L, U, C, etc.) will take precedence:
int L = 4; // For Origin 8.1 ...
Col(B)[L]$= // Returns the Long Name of Col(B), as a string
The following example shows how to create and access user parameter rows
// Show the first user parameter row
wks.userParam1 = 1;
// Assign the 1st user parameter row a custom name
wks.userParam1$ = "Temperature";
// Write to a specific user parameter row of a column
col(2)[Temperature]$ = "96.8";
// Get a user-defined parameter row value
double temp = %(col(2)[Temperature]$);
Show/Hide Column Labels
You can set which column header rows are displayed and in what order by wks.labels object method. For the active worksheet, this script specifies the following column header rows (in the order given): Long Name, Unit, the first System-Parameter, the First User-Parameter, and Comments:
range ww = !;
Even Sampling Interval
Origin users can set the sampling interval (X) for a data series (Y) to something other than the corresponding row numbers of the data points (default).
Accessing the Sampling Interval Column Label Row
When this is done, a special header row is created to remind the user of the custom interval (and initial value) applied. To access the text in this header row, simply use the E row-index character. This header is effectively read-only and cannot be set to an arbitrary string, but the properties from which this string is composed may be changed with either column properties (see the wks.col object) or the colint X-Function.
// Read the Sampling Interval header text of Column 1 to a string variable
string sampInt$ = Col(1)[E]$;
// If an initial value of 2 and increment of 0.5 was set for Col(1),
// the output will be:
sampInt$=; // "x0 = 2"
// "dx = 0.5"
To see a Sampling Interval header, you can try the following steps:
- Create a new worksheet and delete the X-column
- Right-click at the top of the remaining column (i.e., B(Y)), such that then entire column is selected, and select Set Sampling Interval from the drop-down menu.
- Set the initial and step values to something other than 1.
- Click OK, and you will see a new header row created which lists the values you specified.
The next example demonstrates how to do this from script, using X-functions.
Also, when you import certain types of data, e.g. *.wav, the sampling interval will show as a header row.
Sampling Interval by X-Function
Sampling Interval is special in that its display is formatted for the user's information. Programmatically, it is accessed as follows
// Use full formal notation of an X-Function
colint rng:=col(1) x0:=68 inc:=.25 units:=Degrees lname:="Temperature";
// which in shorthand notation is
colint 1 68 .25 Degrees "Temperature";
The initial value and increment can be read back using worksheet column properties:
double XInitial = wks.col1.xinit;
double XIncrement = wks.col1.xinc;
string XUnits$ = wks.col1.xunits$;
string XName$ = wks.col1.xname$;
Note: While these properties will show up in a listing of column properties (Enter wks.col1.= in the Script window to display the property names for column 1), unless a sampling interval is established:
- The strings wks.col1.xunits$ and wks.col1.xname$ will have no value.
- The numeric values wks.col1.xinit and wks.col1.xinc will each have a value of 1, corresponding to the initial value and increment of the row numbers.
Trees are a data type supported by LabTalk, and we also consider trees a form of metadata since they give structure to existing data. They were briefly introduced in the section dealing with Data Types and Variables, but appear again because of their importance to X-functions.
Many X-functions input and output data in tree form. And since X-functions are one of the primary tools accessible from LabTalk script, it is important to recognize and use tree variables effectively.
Access Import File Tree Nodes
After importing data into a worksheet, Origin stores metadata in a special tree-like structure (page.info) at the page level. Basic information about the file can be retrieved directly from this structure:
string strName, strPath;
// Get the file name, path and date from the structure
strName$ = page.info.system.import.filename$;
strPath$ = page.info.system.import.filepath$;
dDate = page.info.system.import.filedate;
// Both % and $ substitution methods are used
ty File %(strPath$)%(strName$), dated $(dDate,D10);
// Starting with Origin 2019b, there is easier output of formatted file date.
strDate$ = page.info.SYSTEM.IMPORT.FILEDATE$;
//Generates a date-time string using the D9 date format.
This tree structure includes a tree with additional information about the import. This tree can be extracted as a tree variable using an X-Function:
impinfo ipg:=[Book2] tr:=MyFiles;
MyFiles.=; // Dump the contents of the tree to the script Window
Note: The contents of the impinfo tree will depend on the function used to import.
If you import multiple files into one workbook (using either New Sheets, New Columns or New Rows) then you need to load a particular tree for each file as the Organizer only displays the system metadata from the last import:
// Use the function first to find the number of files
impinfo trInfo:=trFile fcount:=iNumFiles;
// Now loop through all files - these are indexed from 0
for( idx = 0 ; idx < iNumFiles ; idx++ )
// Get the tree for the next file
impinfo findex:=idx trInfo:=trFile;
string strFileName, strLocation;
strFileName$ = trFile.Info.FileName$;
strLocation$ = trFile.Info.DataRange$;
ty File %(strFileName$) was imported into %(strLocation$);
Access Report Page Tree
Analysis Report pages are specially formatted Worksheets based on a tree structure. You can get this structure into a tree variable using the getresults X-Function and extract results.
// Import an Origin Sample file
string fpath$ = "Samples\Curve Fitting\Gaussian.dat";
string fname$ = SYSTEM.PATH.PROGRAM$ + fpath$;
// Run a Gauss fit of the data and create a Report sheet
nlbegin (1,2) gauss;
nlend 1 1;
// An automatically-created string variable, __REPORT$,
// holds the name of the last Report sheet created:
string strLastReport$ = __REPORT$;
// This is the X-Function which gets the Report into a tree
getresults tr:=MyResults iw:=%(strLastReport$);
// So now we can access those results
User Tree in Page Storage
Information can be stored in a workbook, matrixbook or graph page using a tree structure (page.tree). The following example shows how to create a section and add subsections and values to the active page storage area.
// Add values to a treenode;
page.tree.experiment.sample.RunNumber = 45;
page.tree.experiment.sample.Temperature = 273.8;
// Add values to another treenode;
page.tree.experiment.detector.Type$ = "InGaAs";
page.tree.experiment.detector.Cooling$ = "Liquid Nitrogen";
| +---RUNNUMBER = 45
| \---TEMPERATURE = 273.8
+---TYPE = InGaAs
\---COOLING = Liquid Nitrogen
Once the information has been stored, it can be retrieved by simply dumping the storage contents:
// Dump entire contents of page storage
// or programmaticaly accessed
temperature = page.tree.experiment.sample.temperature;
string type$ = page.tree.experiment.detector.Type$;
ty Using %(type$) at $(temperature)K;
You can view such trees in the page Organizer for Workbooks and Matrixbooks.
User Tree in a Worksheet
Trees stored at the Page level in a Workbook can be accessed no matter what Sheet is active. You can also store trees at the sheet level:
// Here we add two trees to the active sheet
// Dynamically create a branch and value
wks.tree.input.Min = 0;
// Add another value
wks.tree.input.max = 1;
// Add second tree
// and two more values
wks.tree.output.min = -100;
wks.tree.output.max = 100;
// Now dump the trees
// or access it
ty Input $(wks.tree.input.min) to $(wks.tree.input.max);
ty Output $(wks.tree.output.min) to $(wks.tree.output.max);
// Access a sheet-level tree using a range
range rs = [Book7]Sheet2!;
You can view such trees in the page Organizer for Workbooks and Matrixbooks.
User Tree in a Worksheet Column
Individual worksheet columns can also contain metadata stored in tree format. Assigning and retrieving tree nodes is very similar to the page-level tree.
// Create a COLUMN tree
// Add a branch
// and two values in the branch
wks.col2.tree.batch.mix.ratio$ = "20:15:2";
// Add branch dynamically and add values
wks.col2.tree.batch.Line.No = 7;
wks.col2.tree.batch.Line.Date$ = 3/15/2010;
// Dump the tree to the Script Window
// Or access the tree
batch = wks.col2.tree.batch.mix.batchno;
string strDate$ = wks.col2.tree.batch.Line.Date$;
ty Batch $(batch) made on %(strDate$) [$(date(%(strDate$)))];
You can view these trees in the Column Properties dialog on the User Tree tab.