The XOP1 Sample XOP

XOP1 is the simplest of all XOPs. It merely adds one to each element of an Igor Pro® wave. XOP1 illustrates the structure of an XOP.

Usually communication between Igor and the XOP is initiated in response to a user action. In the case of XOP1, it is called only when the user invokes the XOP1 operation from Igor's command line or from a procedure (user-defined function or macro). For example, from the Igor command line, the user could execute the following commands:

Make testWave=0        // Make a test data set.
Display testWave       // Display it in a graph
XOP1 testWave          // Add one to the test wave.

In creating an external operation, you start by creating a plain-text template that tells Igor the syntax of your operation. For XOP1 the template is:

XOP1 wave:waveH

This says that the operation name is XOP1 and that it takes one parameter of type wave. waveH is the mnemonic name for the parameter and is used as a structure field name. Igor takes this template and generates starter C code. You fill in the starter code to perform the desired operation and then compile it in your development system.

When your external operation is first invoked, you register it with Igor (by calling the RegisterXOP1 in this case). Each time your external operation is invoked, Igor calls your "execute" operation (called ExecuteXOP1 in this case), passing to it a structure containing the parameters specified by the caller. Your execute operation then performs the requested operation.

// XOP1.cpp -- A sample Igor external operation
#include "XOPStandardHeaders.h"    // Include ANSI headers, Mac headers, IgorXOP.h, XOP.h and XOPSupport.h
#include "XOP1.h"
/*	DoWave(waveHandle)

	Adds 1 to the wave.
static void
DoWave(waveHndl waveH)
	float *fDataPtr;	// Pointer to single-precision floating point wave data.
	double *dDataPtr;	// Pointer to double-precision floating point wave data.
	CountInt numPoints;
	IndexInt point;
	numPoints = WavePoints(waveH);					// Number of points in wave.
	switch (WaveType(waveH)) {
		case NT_FP32:
			fDataPtr = (float*)WaveData(waveH);		// DEREFERENCE - we must not cause heap to scramble.
			for (point = 0; point main1ParamsSet[0] == 0)
		return NOWAV;			// Wave parameter was not specified.
	waveH = p->waveH;
	if (waveH == NULL)
		return NOWAV;			// User specified a non-existent wave.

	// Do the operation.
	result = XOP1(waveH);
	if (result == 0)
		WaveHandleModified(waveH);	// Tell Igor to update wave in graphs/tables.

	return result;

static int
RegisterXOP1(void)		// Called at startup to register this operation with Igor.
	const char* cmdTemplate;
	const char* runtimeNumVarList;
	const char* runtimeStrVarList;

	// NOTE: If you change this template, you must change the XOP1RuntimeParams structure as well.
	cmdTemplate = "XOP1 wave";
	runtimeNumVarList = "";
	runtimeStrVarList = "";
	return RegisterOperation(cmdTemplate, runtimeNumVarList, runtimeStrVarList, sizeof(XOP1RuntimeParams), (void*)ExecuteXOP1, 0);

static int
RegisterOperations(void)	// Register any operations with Igor.
	int result;
	// Register XOP1 operation.
	if (result = RegisterXOP1())
		return result;
	// There are no more operations added by this XOP.
	return 0;

/*	XOPEntry()

	This is the entry point from the host application to the XOP for all
	messages after the INIT message.
extern "C" void
	XOPIORecResult result = 0;
	switch (GetXOPMessage()) {
		// We don't need to handle any messages for this XOP.

/*	XOPMain(ioRecHandle)

	This is the initial entry point through which the Igor calls XOP.
	XOPMain does any necessary initialization and then sets the XOPEntry field of the
	ioRecHandle to the address to be called for future messages.
XOPMain(IORecHandle ioRecHandle)
	int result;
	XOPInit(ioRecHandle);			// Do standard XOP initialization.
	SetXOPEntry(XOPEntry);			// Set entry point for future calls.
	if (igorVersion < 620) {
		return EXIT_FAILURE;

	if (result = RegisterOperations()) {
		return EXIT_FAILURE;




Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More