Coding Conventions
thomas_braun
Coding conventions and best practices for Igor Pro development.
Completely unofficial and authored by us.
Project Details
Project Homepage: | View Homepage |
Project CVS: | https://github.com/byte-physics/igor-pro-coding-conventions |
Current Project Release
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Thomas, thanks for all these useful suggestions. One topic I would like to see discussed further is the use of global variables. Apparently, their use is deprecated, so I would like your opinion on alternatives. I have had many occasions of needing to pass many such defined variables to several subroutines. In one case, using a structure worked well (at the cost of more cumbersome programming). Can you add commentary on other options, and their trade-offs?
January 3, 2023 at 05:50 am - Permalink
Hi,
Since I am not as comfortable (yet) in using structures, I default to a different solution that comes from when I used IP to drive measurement systems which I have built in the past. The basic concept it to use two waves of "engineering constants", one numeric (ECN) and the other string (ECS) and the heavy use of dimension labels. I can reference them easily in functions with the dimension label taking the form of a variable name. ECN[%time_out] for example. One advantage I have found is that since they are standard waves the values can be checked at any time just by editing the waves. Additionally, as the project matures and functionality added editing the wave in a table is easy to create new "variables" and set their values.
I have come to really use dimension labels as extra column especially since I can have a text column (dimension label) with a numeric wave. Sort of a work around data frame.
Andy
January 3, 2023 at 09:19 am - Permalink
Andy, you bring up an interesting option. Ironically, using dimension labels vs indices is a topic that Thomas discusses [spoiler alert: indices execute faster.]
January 3, 2023 at 09:46 am - Permalink
Thanks Stephen and Andy for your input.
> Globals
I would not call it deprecated, but there are in the majority of cases better alternatives. A case where you really have to use globals are background functions. Andy's idea with waves is one alternative. Unfortunately as you've already discovered are dimension labels slow. If you need up most performance, get the index before the calculation with FindDimLabel and use that instead of the name. Alternatively you can introduce numeric constants and use those instead of dimension labels. But that gets a bit messy if you a huge number of waves and constants.
Another are structures. I would actually think that structures are the way to go. So here is a contrived example:
Structure Properties
variable offset, gain
WAVE/D weights
EndStructure
Function [STRUCT Properties s] InitStructure()
s.offset = 0.1
s.gain = 1.2
Make/FREE/N=(NUM_ELEMENTS)/D s.weights = sqrt(p)
End
Function/WAVE DoCalculation(WAVE/D input, STRUCT Properties &s)
Duplicate/FREE/D input, output
output[p] = ((input[p] + s.offset) * s.gain) * s.weights[p]
return output
End
Function RunMe()
Make/FREE/N=(NUM_ELEMENTS)/D input = p^2
[STRUCT Properties props] = InitStructure()
WAVE output = DoCalculation(input, props)
print/D output
End
Especially with multiple-return-value syntax structures are nice to work with as they can be returned. One can treat structures as the data of an object and do some kind of lay-man's OOP.
January 3, 2023 at 01:09 pm - Permalink