Use Wavelist to programmatically declare and use waves
Hi--
The goal of this function is average one second data to some other value, say one minute. I want to use Wavelist or some other method, to determine the wave names in the selected folder, and then average them, plot them, etc.. The problem I'm currently having is I cant get the function to compile because the call for declaration is incorrect. Once I figure out how to be able to work with the waves that Wavelist has identified as being in the directory I can move on. For instance let's say I want to next graph ListoWaves[0] vs Timewave then I can move on. See inserted code. As usual thanks in advance for any help.
ssmith
String ListoWaves = Wavelist("*",";","DP:1") //"DP:1" selects only dbl precision float waves to be averaged, eliminates text waves String Timewave = Wavelist("*time*",";","DP:1") //Identifies the time wave // Print ListoWaves // Print Timewave Variable NumWaves = ItemsinList(ListoWaves) //finds the number of items in wavelist // Print Numwaves Wave/T WL = ListToTextWave(Listowaves,";") FOR(e=0;e<(NumWaves);e+=1) Wave WaveDeclare = $WL[e] ENDFOR
If I put your code in a function, the compiler complains that your variable e is not declared. If I add this before the for loop, it then compiles:
Note that I would suggest not using "e" as the name of a variable since it's also the name of a built-in function and that could be confusing, but it's allowed.
October 29, 2025 at 02:29 pm - Permalink
Note that since Igor 9 you can also do a range-based loop, which would get rid of the variable e and would collapse the latter half of your code into a convenient expression:
Also note that with your current method of creating the lists, Timewave is contained within ListoWaves. Maybe you want that, but if not you either want to use:
String ListoWaves = Wavelist("!*time*",";","DP:1")or run RemoveFromList() later.
October 29, 2025 at 07:08 pm - Permalink
Thank you all so much for the help.
November 3, 2025 at 08:30 am - Permalink
Hi All--
This code doesn't compile. It fails at the first print statement. See the attached file. Again I'm trying to declare all of the waves in the current folder so I don't have to list/declare them individually in addition to making it versatile. This way it can be used to create averages for different wave names. It also doesn't compile if I switch the FOR loops. My guess is that I'm trying to use waves (Extinction_Blue_cat, IgorTime_Cat) before they are declared. Any help is greatly appreciated. Thanks.
ssmith
November 4, 2025 at 05:33 am - Permalink
The declaration
WAVE WaveDeclare = $currassociates the local wave name "WaveDeclare" with the wave whose name is in the string variable. Therefore it doesn't make sense to repeat such a declaration in a loop: at the end WaveDeclare will be associated with the last wave in the list. You need different local names for different waves.
You may try a function like:
and then :
etc.
but the following will work too (without local name):
print name2wave("Extinction_Blue_cat")[0] // will quit here if blue cats don't existNovember 4, 2025 at 07:57 am - Permalink
I think that I may not be making myself clear here, sorry about that. I have loaded a file that has created a series of waves seen in the data browser in the attached image. The wave names correspond to the variables the instruments save. In order to manipulate the waves they need to be declared using the "Wave wavename" statement. Depending on which instrument the data comes from the waves names will be different. I'm trying to programmatically declare the wave names without listing each actual wave name. Perhaps ListToTextWave is not correct maybe ListToWaveRefWave is a better way to go?
November 4, 2025 at 10:20 am - Permalink
Yes, in this case ListToWaveRefWave is indeed the function you need to get a wave containing a list of wave references from a list of wave names. It is basically equivalent to calling "name2wave" in a loop, assigning a wave reference to each string of the list.
November 4, 2025 at 10:44 am - Permalink
Thanks. Using the Igor help for the function I've been trying to get this to compile but I'm not having any luck. I'm sure the syntax is wrong but I'm not good enough to see it. Can you help?
November 4, 2025 at 10:49 am - Permalink
Look at my just updated answer. The function ListToWaverefWave already performs the loop you are trying to do in the following lines (for f=0 etc.), just drop this for loop. After the instruction
Wave/Wave WL = ListToWaveRefWave(Listowaves,0)WL[0] will be the reference to the first wave of the list, e.g. WL[0][0] is the value of the first element of the first wave etc.
WL[1] will be the reference to the second wave of the list, e.g. WL[1][0] is the value of the first element of the second wave etc.
etc.
still curious where are those blue cats...
November 4, 2025 at 11:01 am - Permalink
For each iteration of your for loop, the wave that the wave reference variable (WL) points to changes.
If you know there will be a wave named "Extinction_Blue_cat" in the current data folder and you need to reference that specific wave, you should just declare a wave reference variable for that wave. You might need to create a lot of wave references if you have a lot of waves you need to reference by name.
November 4, 2025 at 11:12 am - Permalink
Yes, I was hoping to declare them programmatically, so I would not have to make 25 wave declarations, and then in later functions call them by their actual wave name. Is that possible or do I have to associate the actual name with the reference? It sounds like I just have to declare each of the waves by name so I can manipulate them using the actual wave name?
November 4, 2025 at 11:30 am - Permalink
Consider the following code:
You can execute these functions like this:
Inside the for loop of SumAllPoints, I am declaring a wave reference each iteration through the loop so I can then access that wave to call the sum function. This works for any number of waves named "wave*" in the current data folder.
NOTE: What I wrote above is not the most efficient way to do what I did, I'm just trying to make an example of how to programmatically create a wave reference.
If you will always have a wave named timewave in the current data folder, just reference it like this:
WAVE timewaveIf the name of the wave you want to use for that purpose might change, you can do something like:
WAVE timewave = $("timewave" + num2str(someVariable))I'm not sure what you're actually trying to do so I can't give you code to do exactly that.
November 4, 2025 at 11:45 am - Permalink
I'm not sure I understand your question but I will repeat:
The function name2wave I proposed assigns a name to a wave reference and returns this reference. The Igor function ListToWaveRefWave does the same for a list of wavenames. Now if you want to select some specific names based on common prefixes, suffixes etc. you can use string manipulation functions like cmpstr, ListMatch or similar. You now have all the tools you asked for. If you still don't know how to code your app it's not a question of Igor syntax, it's a question of how to organize a code to make an app (more difficult and demanding more experience). Maybe if you tell us with more details where the blue cats are we might think how to help you to organize your app :)
November 4, 2025 at 12:00 pm - Permalink
I was pulled away for a few days. I would like to get back to this. What I want to do is create a generic averaging routine that can be used on any data. I deal with a number of instruments that collect one second data. I would like to average this data using the requested averaging time and the time wave. After the averaging is complete end up with wave names that have variprefix as the prefix for the real wave names so if some of the waves that I load are "Red_signal", "green_signal" and I average for 2 minutes the resulting wave names would be "Min2_avg_Red_Signal," "Min2_avg_Green_Signal". Then I would need to declare the existing wave names so that they can be plotted with something like "Display Min2_avg_Green_signal vs Min2_avg_Igortime" I hope this makes sense and clear things up. Thanks for any help that you provide.
November 13, 2025 at 07:37 am - Permalink
I think it might help if you read some of the documentation about how to process lists of waves. To bring it up, execute:
DisplayHelpTopic "Processing Lists of Waves"November 13, 2025 at 07:54 am - Permalink
I read the
"Processing Lists of Waves" text an I think that what I'm trying to do is not possible. I'm trying to avoid writing these types of lines of code for each instrument and any new wave groups that I load into an experiment:and so on for 10-15 groups of wave names for each instrument. These group names vary depending on the instrument that generates them. So I guess i can create the wave lists one time and use a CASE statement or some other method to make these calls. Thanks for the help.
Scott
November 13, 2025 at 10:21 am - Permalink
> What I want to do is create a generic averaging routine that can be used on any data.
The above aim is framed too vaguely. You appear to want the following:
I have collected a set of N waves, each with npts points, into one data folder. I want to choose a specific set of M waves from those N waves. I want to choose the M waves using wild-card criteria to select by specific patterns in the wave names. I want to average each of my chosen waves over a defined step increment Delta. I want the averaging process to create a new wave with a name using a prefix that is generated using the increment Delta and the name of the wave that was averaged. The newly created wave will typically be npts/Delta in length.
First, create a function to average one input wave into a new wave.
Test this function on various waves in a data folder using the command line input. Go to the next step only after you have the above completed. For example, calling on the command line should give the desired result wave.
ave_aspecificwave("Extinction_Blue_cat",20) --> ave20_Extinction_Blue_catSecond, create a function to return a list of waves in a data folder selected using a wild-card input. You may find some insights using the example in the link below.
https://www.wavemetrics.com/forum/general/example-return-string-list-wa…
Third, create a function that loops through the wave names in the generated list, passing each wave name to the averaging function created in the first step.
When all this is done, you can use the wild-card input to average all blue waves by 20
ave_asetofwaves("*_blue*", 20) --> generates averages over all "blue" wavesIn summary, you are trying to build multiple steps in one function. Create functions to do only one specific step, then assemble the individual functions appropriately.
> I think that what I'm trying to do is not possible.
What you are trying to do is entirely possible. How you are trying to do it appears to be impossibly confounding.
November 13, 2025 at 05:23 pm - Permalink
Oops, sorry, the double brackets in WL[1][1] won't work here because the compiler thinks it's a 2D wave (I was probably working on my C course when I wrote it :( ).
Here is a working version:
If you mainly work with references but sometimes need to get back to the name you can use the functions nameofwave and GetWavesDataFolder:
November 14, 2025 at 07:09 am - Permalink
Hi--
Thanks you all for the programming tip and suggestions. We have veered off of my original question, which was: how can I programmatically declare waves so they can be called in the rest of my function. I've written the logic in the past to average 3 or 4 waves. So I just called them like in the example below one wave at a time. See the snippet below. I want to develop a loop to make the call " Wave wavename0, wavename1, wavename2
I just don't to do this for a lot of waves if I can do it using a for loop.
Thanks for the help
ssmith911
November 14, 2025 at 09:00 am - Permalink
I think the problem is that you don't actually want to do what you think you want to do, because it doesn't make much sense to want to do that in Igor.
However we all seem to have a problem understanding what you actually want to accomplish in the end, and we we've not been able to help you get there. You are stuck on asking to do something that doesn't make sense, and the rest of us are stuck trying to understand why you want to do that.
I recommend that you create a small example that shows how to create some waves and possibly other objects that have the same organization your actual data has, but with limited complexity. Then, using only the command line, do the type of analysis that you want to do on those waves, including making the graphs to display the end result.
Then describe what parts of this you want to make more flexible. For example, your example waves might be named "wave1_green", "wave2_green", etc. If you want to do a similar analysis for other colors, you might say something like "I want to separately calculate the average of all waves with the "_green", "_blue", and "_red" suffixes.
November 14, 2025 at 09:29 am - Permalink
String ListoWaves = Wavelist("*",";","DP:1") //"DP:1" selects only dbl precision float waves to be averaged, eliminates text waves String Timewave = Wavelist("*time*",";","DP:1") //Identifies the time waveI don't understand the philosophy here. It seems you have a well defined protocol for naming waves. You should use your naming protocol, I don't see any reason for using generic wildcards "*" here and it makes the whole code much more complicated.
For example, I recently worked on a code to make fits of different datasets using different models. The wave names would be something like this (simplified here):
string nydata=datasetprefix+"_ydata"; wave ydata=$nydata
string nxdata=datasetprefix+"_xdata"; wave xdata=$nxdata
string nfitydata="fit_"+modelprefix+"_"+ nydata
etc.
I don't need any wildcards in the app.
Now if you want to process data from different datasets, first make a function to take the list of dataset names from a text wave. You can edit manually such a text wave (can be practical for cases when you don't want to include all existing data). Once tested, you can write another function that will create such a list given some criterions (the only function needing search with wildcards, and you can test this function independently).
November 14, 2025 at 10:27 am - Permalink
I try to give this a shot as well. Maybe your confusion comes from thinking that the external wave name and the 'internal' declaration inside a function needs to be the same, which is not at all the case. So something like this:
Wave IgorTime_catis implicitly the same as this:
Wave IgorTime_cat = theCurrentDF:IgorTime_catHere the internal name inside the function is IgorTime_cat, which refers to a wave with name IgorTime_cat inside some folder. But the internal name can be anything and can also be reassigned as often as you like / need.
Here is a start, which for now simply displays all waves vs your time wave:
You see that 'yWave' successively gets reassigned and reused in the following expression. So you never need a ton of Wave assignments if you can reasonably construct a string list or wave-reference wave with the contents you want to process as input for a loop or similar construct.
November 16, 2025 at 02:27 am - Permalink
Pawel et al.--
Perhaps you are right. I may be making this more difficult that it needs to be. On top of that my attempts at explaining what I'm trying to accomplish is muddying the water for you guys...I apologize for that. Allow me to try one more time to be more specific:
When declaring waves for future use in a function if there are only 6 or 7 waves then this is fine:
Now if there are 30 waves, or more, that need to be declared and may change depending on the instrument the amount of typing becomes excessive not to mention the possible typos that would occur (LOL). So what I'm trying to code is a generic way to declare all of the waves in the current datafolder, so they can be used, by the actual wavename. This way I can move this snippet of code to other functions for the wave declaration part of the new function. Now there may not be an easy way to do this. If not thats fine. I'll just have to create specific wave declarations for each function I create. I am using this as a way to learn how to code in Igor and make the code a littIe simplier in the future. I hope this clears it up. Thank you so much for your patience and help.
November 16, 2025 at 09:02 am - Permalink
> So what I'm trying to code is a generic way to declare all of the waves in the current datafolder, so they can be used, by the actual wavename.
OK. You cannot hard-code a generic function to define a wave reference to any random wave in any random data folder exactly by the actual name of the (randomly) chosen wave. (*) Since you cannot do what you want for one wave, you cannot do what you want for a set of waves.
What you can do is assign a specifically pre-named wave reference to a string that is a (randomly chosen) wave name. So,
Hope this finally clears up your question.
* You may be able to achieve you desire by generating a text file with all the required WAVE my_funkywaveN = my_funkywaveN assignments, reading back the text file via an INPUT + INCLUDE method, and forcing a re-compile of the Igor Pro procedure. But I bet even the experts would not want to phuzt around giving you further advice for such an approach.
November 16, 2025 at 02:30 pm - Permalink
Hello ssmith911,
Did you have a look at my example above? This goes in the same direction as the answer by jj. There should never ever be a need to hard-code names into functions. The Wave assignment is precisely there for declaring 'links' to arbitrary waves for use inside a function. So instead of:
you can simply write something like:
Which can ultimately be exchanged for a string assignment:
Why would you want to use the actual wave name for this if the name can change depending on what you load in?
November 16, 2025 at 10:31 pm - Permalink
Hello,
Based on other suggestions and my previous thoughts here is an example of how such a code might be structured. Note that I separated processing and display: processing is easier to group by data types "Signal" etc, but I see you want to make graphs assembling different colors so doing both at the same time isn't practical. The functions compile but have to be completed with the averaging code. You will also notice that I removed "WaveList" entirely so you have to supply a list of colors to the function (eg. edit a text wave in a table). I think that for an unexperienced programmer this is a much easier starting point , rather than scanning the folder and trying to sort through everything that can be found there, it is also much more flexible (you can select which instruments are to include). Later you can try to write a function that scans a given folder to prepare lists of colors, animals etc. for a more automated processing.
Edit: I have updated the code to include absolute paths for the data waves.
November 17, 2025 at 04:04 am - Permalink
It seems that you want all the waves to be declared in your code, but you don't want to write out the declarations in your code.
Since you want to work with hard-coded waves, you may as well have the waves declared in the code.
How about this to generate the declarations, without typos, (at the time of writing the code):
note that this code needs to be compiled to work, best to keep it in an independent module.
If the names of the waves are not static, there's no point in hard-coding.
if you want to set up wave references in a separate function, then you could perhaps use a structure:
You could also use StructFill with static wave names:
November 17, 2025 at 05:42 am - Permalink
Ok, thanks. I'll have a look at these options. I really appreciate the help from all of you.
ssmith911
November 17, 2025 at 05:48 am - Permalink
Hi Tony,
Nice hacking ! But probably pointless for his application. And you are destroying my educational work :)
November 17, 2025 at 05:51 am - Permalink
Sorry, Pawel, I couldn't resist muddying the waters.
ssmith did say that he wants to create wave references in a separate function, and the only way that I know of to do that is with structures.
November 17, 2025 at 06:01 am - Permalink
I might mention right here that I once shipped a WaveMetrics procedure with a simple function code generator. It wrote a notebook file that could be #included as a procedure window. It used the various Execute/P commands to #include it automatically and compile it. It was such a disaster that I pulled it out of our releases on a point release, not even a major release. It's extraordinarily difficult to make such code generators work reliably.
November 17, 2025 at 10:56 am - Permalink
@ssmith911, I may not have completely understood what you want to do and may have missed details (it's a long thread), but depending on the nature of your data set, there may be another way to work on it that doesn't need explicit declaration of the source waves. Say you have the following waves in the current data folder:
Make/O Extinction_Blue_cat,Extinction_green_cat,Extinction_red_cat,LastBaseLine_Blue_cat,LastBaseLine_green_cat,LastBaseLine_red_catyou can work on the "extinction" set simply by something like:
Then call:
processData("extinction")This assumes that all waves are 1D and have the same length.
November 17, 2025 at 11:36 pm - Permalink