You can write your own software routines (or "procedures") using Igor Pro®'s built-in programming language. These routines are entered as text in "procedure windows":
In addition to the main procedure window named "Procedure" (which is inseparable from the current Igor Pro® "experiment"), additional procedure windows may used to organize your work or to re-use routines previously written by the user or others. Igor ships with about 200 such procedure files written by WaveMetrics programmers.
You can use Igor's built-in programming language to call built-in functions and "operations", of which there are a considerable number (about 550). The Help menu´s Command Help item is a useful guide to these, and contextual help menus provide templates and quick access to documentation.
Procedure windows can also contain text that causes Igor to:
- Load ("include") other procedure files
- Define constants
- Define new user-defined menus or menu items
User-defined Functions
User-defined functions are quite similar to functions written in C, Pascal, or modern Fortran and are compiled for speed.
Parameters and Return Values
Functions have parameters and return values. Parameters can be passed by value or by reference. They can be numbers, strings, structures, or references to arrays ("waves") of data. The parameters can be required or they can be optional.
Here's a simple function that counts the number of data values that exceed a given number:
Local and Global Variables
Like nearly every other procedural language, Igor´s language supports local (or "stack") variables (and strings and structures) that vanish when the routine containing them ceases execution.
In the example above the parameters w and value and the local variables exceed, i, and n exist only while the CountValuesThatExceed function is running. Afterwards only the returned value exists, either in the calling routine or in a global if assigned there. For example:
creates a global variable gCount whose value is the returned exceed value. gCount will continue to exist after the end of command execution, and can be observed in Igor´s Data Browser.
Parameters passed by Reference
In Igor, arrays of data are always global objects: they are always passed into a routine by reference as a local "wave reference" parameter. In the example above, w is such a wave reference parameter.
Other kinds of parameters are passed by value unless specifically declared to be pass-by-reference using a convention borrowed from C++:
Wave 1
Variable &thing1, &thing2
thing1=0; thing2=0
if( ... )
thing1 += 1
endif
if( ... )
thing2 += 1
endif
End
When CountTwoThings is invoked:
CountTwoThings(aWave, loc1, loc2)
the values of loc1 and loc2 in the calling routine are changed by CountTwoThings, in a manner familiar to most Fortran programmers.
Without the & character in CountTwoThings, loc1 and loc2 would be passed by value (copied into CountTwoThings), and remain unaffected by assignment and incrementing inside that routine.
Flow-control Commands
Igor´s language is a go-to-less "structured" procedural language with many of the standard modern flow-control constructs, and a few others. Here are some examples:
do-while
thesum += wave[i];
i += 1;
while( i < n )
for-endfor
thesum += wave[j];
endfor
if-elseif-endif
val = j - i;
elseif( i > j )
val = i - j;
else
val = 0
endif
strswitch-case-endswitch ("string switch")
case "revert": // literal string or string constant
val= 2
break // without this execution "falls through" to val=1
case "okay":
val= 1
break
default:
val= 0
break
endswitch
switch-case-endswitch ("numeric switch")
case 0: // literal number
case kMyConstant: // Constant kMyConstant =<some value>
val= 1
break
default:
val= 2
break
endswitch
try-catch-endtry
// test denominator
if( denominator==0 )
AbortOnRTE // this is like C++´s "throw"
endif
// use denominator
val= numerator / denominator
...
catch
// denominator must have been 0
val=NaN
endtry
Structures
You can define your own structures and pass them between functions. The syntax for using structure members is similar to C. Structures can contain numbers, strings, arrays of characters and substructures. In addition, Igor has some pre-defined structures such as the WMButtonAction in this simple coding example which also demonstrates that Igor´s structures can be converted into and from strings:
// with two buttons named b0 and b1.
Window DemoStructuresPanel() : Panel
PauseUpdate; Silent 1 // building window...
NewPanel /W=(343,91,561,138)
Button b0,pos={26,12},size={50,20},proc=ButtonProc,title="Click"
Button b1,pos={130,12},size={50,20},proc=ButtonProc,title="Click"
EndMacro
// Defines a custom structure
Structure mystruct
Int32 nclicks
double lastTime
EndStructure
// The function which runs when Button b0 or b1 are clicked.
Function ButtonProc(bStruct) : ButtonControl
STRUCT WMButtonAction &bStruct // Igor-defined structure, passed by reference.
if( bStruct.eventCode != 1 )
return 0 // we only handle mouse down (code=1)
endif
STRUCT mystruct s1 // local user-defined structure
if( strlen(bStruct.userdata) == 0 ) // button hasn't had userdata initialized
print "first click on " + bStruct.ctrlName
else
// button has a structure packed into its userdata.
StructGet/S s1,bStruct.userdata // unpack structure from userdata string.
Variable lastTime= s1.lastTime // get a value from the structure.
String ctime= Secs2Date(lastTime, 1 )+" "+Secs2Time(lastTime,1)
printf "button %s clicked %d time(s), last click = %s\r",bStruct.ctrlName,s1.nclicks,ctime
endif
s1.nclicks += 1 // update the structure members
s1.lastTime= datetime // seconds since Jan 1, 1904.
StructPut/S s1,bStruct.userdata // pack structure s1 into string inside struct bStruct.
return 0
End
And this is the resulting user interface:
Vector and Array Arithmetic
Igor´s programming language allows you to write assignment statements that work on an entire data set or on a subset just like you would assign the value to a single variable in a standard programming language:
data = sin(2*pi*p/1000) // assigns to each element of data. p iterates from 0 to 999.
Display data
Here's an example of changing only a portion of the array:
For more examples, see Data Math.
#include
Igor encourages code reuse through its "include" mechanism, which is similar to C.
For example, by simply entering this statement in any procedure window:
Igor adds the Multipeak Fitting package to your Igor experiment:
The package is comprised of multiple pre-written procedure files stored in the WaveMetrics Procedures folder that ships with Igor. The Multipeak Fitting.ipf procedure file itself includes other procedure files that support its functionality:
You can reuse your own procedures this way, though with a slightly different syntax:
which loads the procedure file named "MyProcedureFile.ipf" from your "User Procedures" folder (which is located inside your Documents\WaveMetrics\Igor Pro User Files folder).
Constants
Have you ever looked at program code and wondered why some "magic number" was used?
Sleep/T 60*60*2 // perhaps a little clearer
You can write code that is easier to maintain by using well-named constants:
Constant kSecondsPerMinute=60
Constant kMinutesToWait=2
Sleep/T kTicksPerSecond*kSecondsPerMinute*kMinutesToWait
(Another advantage of using constants is when an identical value must be used in multiple places in the code. If you use a constant name everywhere the value is needed and later need to change the value, you can simply change the definition of the constant to change the value wherever it is used. This is better than combing through the code trying to determine which instances of say, 1, need to change to 2.)
Igor also has string constants, and you can make constant definitions "static" which makes them private to the procedure file they´re defined in:
User-defined Menus
You can add to Igor´s menus by writing menu definitions in procedure windows. For an example, see the "Analysis" menu definition in the Multipeak Fitting.ipf file shown above.
You can also enable or disable Igor´s standard menus using the SetIgorMenuMode command, or show and hide built-in menus with ShowIgorMenus and HideIgorMenus.
You can also programmatically add contextual menus to graph, table, panel, and layout windows using the PopupContextualMenu operation or add menu items to many of Igor's built-in contextual menus.
These features allow you to customize Igor for your applications, and to disable Igor features that users of your customized application do not want to worry about.
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More