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 Rows or Column 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" 
// appended
bb[L]$=Col(1)[L]$+" 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

Create and Name User Parameter Rows

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 = !;
ww.labels(LUP1D1C);

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:

  1. Create a new worksheet and delete the X-column
  2. 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.
  3. Set the initial and step values to something other than 1.
  4. 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

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;
double dDate;
// 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:

Tree MyFiles;
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:

Tree trFile;
int iNumFiles;
// 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$;
impasc;
// Run a Gauss fit of the data and create a Report sheet
nlbegin (1,2) gauss;
nlfit;
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
ty Variable\tValue\tError;
separator 3;
ty y0\t$(MyResults.Parameters.y0.Value)\t$(MyResults.Parameters.y0.Error);
ty xc\t$(MyResults.Parameters.xc.Value)\t$(MyResults.Parameters.xc.Error);
ty w\t$(MyResults.Parameters.w.Value)\t$(MyResults.Parameters.w.Error);
ty A\t$(MyResults.Parameters.A.Value)\t$(MyResults.Parameters.A.Error);

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";
page.tree.=
/*
Output: 
    EXPERIMENT
         +---SAMPLE
         |    +---RUNNUMBER = 45
         |    \---TEMPERATURE = 273.8
         \---DETECTOR
              +---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
page.tree.=;
// 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
wks.tree.add(Input);
// Dynamically create a branch and value
wks.tree.input.Min = 0;
// Add another value
wks.tree.input.max = 1;
// Add second tree
wks.tree.add(Output);
// and two more values
wks.tree.output.min = -100;
wks.tree.output.max = 100;

// Now dump the trees
wks.tree.=;
// 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!;
rs!wks.tree.=;

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
wks.col2.tree.add(Batch);
// Add a branch
wks.col2.tree.batch.addsection(Mix);
// and two values in the branch
wks.col2.tree.batch.mix.ratio$ = "20:15:2";
wks.col2.tree.batch.mix.BatchNo= 113210;
// 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
wks.col2.tree.=;
// 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.

ROI

If a Region Of Interest (ROI) box is created from SVG, ROI created from brain atlas SVG for example, the metadata can be saved and accessed by binary storage tree roi.info.tree.

Tree Node Description
roi.info.tree.longname$ Assign and retrieve ROI Long Name.

For ROI box craeated from a SVG image, the acronym name will be set as ROI name and the full name is stroed into Long Name, which can also be retrieved by this byte.

roi.info.tree.svg$ Access SVG name. Also accessible by user tree, e.g. layer.info.tree.BrainAtlas.SVG$ in Book Organizer.
roi.info.tree.slice$ Access slice name for the ROI. Also accessible by user tree layer.info.tree.slice$ in Book Organizer.