Data Folders
Ken
I am wondering if it is possible to have the root:'s contents (waves and global variables) copied to a subfolder within root:, without copying other subfolders within root:.
For example, root: contains wave1, wave2, var1, var2, var3, and subfolder root:sub. Root:sub contains wave3, wave4, var4, and var5. Is it possible to create a new subfolder within root: called root:copyfolder which contains copies of wave1, wave2, var1, var2, and var3 so that the original wave1, wave2, var1, var2, and var3 are unaffected?
Also, is it a bad idea to create global variables of the same name, even if they are in separate datafolders?
Thank you.
string TheWaves = Wavelist("*", ";", "")
string CurrentWave
NewDataFolder/O Copies
variable i
do
CurrentWave = StringFromList(i, TheWaves)
if(strlen(CurrentWave)==0) // no more waves
break
endif
wave w= $CurrentWave
duplicate w root:copies:$CurrentWave
i+=1
while(1)
end
for the variables you'll need to implement e.g.
in the above code.
June 28, 2011 at 09:56 am - Permalink
That is really a question of style, and the use you want to make of the global variables. One of the reasons we created Data Folders is to allow you to segregate data that have the same names. We envision waves resulting from multiple experimental runs, where the wave names are all the same but put into data folders with names like Run1, Run2, etc.
I also frequently create a data folder with information about a control panel or graph that is the object of some code. I create a data folder named to refer to the graph, then I can have the same-named variables and waves but which refer to information in the various different graphs.
So that was a really long-winded way to say "No, it's fine".
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 28, 2011 at 04:53 pm - Permalink
Below is my current code.
string Folder_Name, Folder_BaseName = "Data_"
string DFWavesList = Wavelist("*", ";", ""), DFVariablesList = VariableList("*", ";", 4), DFCurrentWave, DFCurrentVariable
variable FolderCount = 1
variable/G Temp
do
Folder_Name = Folder_BaseName + num2str(FolderCount)
if(DataFolderExists(Folder_Name) != 1) // DF does not currently exist
NewDataFolder/O/S $Folder_Name
variable x
// Duplicate waves
do
DFCurrentWave = StringFromList(x, DFWavesList,";")
if(strlen(DFCurrentWave)==0) // No more waves
break
endif
Duplicate/O root:$DFCurrentWave $DFCurrentWave
x+=1
while(1)
// Duplicate variables
x = 0
do
DFCurrentVariable = StringFromList(x, DFVariablesList,";")
if(strlen(DFCurrentVariable)==0) // No more variables
break
endif
NVAR Temp = root:$DFCurrentVariable
variable/G $DFCurrentVariable = Temp
x+=1
while(1)
break
endif
FolderCount += 1
while(1)
SetDataFolder root:
end
The code works as desired. However, this is my first time using the NVAR command, and I am wondering if this is the proper way to use it. If a global variable is already declared, is NVAR variableName the same as variable/G variableName? Also, how come in the above code, I cannot do variable/G $DFCurrentVariable = root:$DFCurrentVariable directly, but must create Temp to hold root:$DFCurrentVariable first?
June 29, 2011 at 12:23 pm - Permalink
If you just want to quickly backup your stuff to a separate folder before doing something with it you can also do it without much programming:
Create a new folder then select the things you want to copy (including variables). Then drag and drop the selection over the new folder while holding 'alt'.
That's how I do it usually. I had a button for copying stuff before I discovered the convenience of 'alt' and 'ctrl+d'.
June 30, 2011 at 04:04 am - Permalink
NVAR, SVAR and WAVE have dual roles. The first is at compile time: they provide a name to refer to an object that may not exist yet, so that the compiler can create the correct code. The second is is run-time: they actually look up the object by its real name and connect that object to the local name, so that you can use the local name as a surrogate for the real name.
You can read more about all this:
DisplayHelpTopic "Local Versus Global Variables"
DisplayHelpTopic "Converting a String into a Reference Using $"
DisplayHelpTopic "Accessing Global Variables And Waves"
The syntax Variable/G name=something is used to initialize the new global variable, so that syntax is already taken up for a different use.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 30, 2011 at 12:41 pm - Permalink
I am still confused why I cannot do variable/G $DFCurrentVariable = root:$DFCurrentVariable though. Through every iteration of the do loop, $DFCurrentVariable changes, so it's not like I am declaring the same variable twice. I have condensed the code into the necessary parts below. The commented out code is what works, while the non-commented out code gives the error, "can't use $ in this way in a function" when trying to compile the code.
string DFVariablesList = VariableList("*", ";", 4)
string DFCurrentVariable
//variable/G Temp
NewDataFolder/O/S DataFolder
variable x
do
DFCurrentVariable = StringFromList(x, DFVariablesList,";")
if(strlen(DFCurrentVariable)==0) // No more variables
break
endif
variable/G $DFCurrentVariable = root:$DFCurrentVariable
//NVAR Temp = root:$DFCurrentVariable
//variable/G $DFCurrentVariable = Temp
x+=1
while(1)
end
By the way, I want to incorporate the duplication action into the code, but it was still interesting to learn that the same can be done using ctrl-d and alt-drag.
July 6, 2011 at 10:00 am - Permalink
If you're trying to duplicate a datafolder, how about using the operation DuplicateDataFolder?
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
July 6, 2011 at 11:13 am - Permalink
Entering DuplicateDataFolder root:,root:New into the command line, for instance, gives the message "cannot move a data folder into itself or into a child data folder."
July 6, 2011 at 11:36 am - Permalink
Regardless of your intentions, this line is problematic in a number of different ways.
It appears that you may not yet fully understand the concept of global variables and references to global variables, and the subtle but important differences between them.
Remember that
variable /G
sets aside some storage somewhere.NVAR
allows you to reference that storage. In order to keep these concepts straight in your mind I recommend that you stick to the following:1) only use
variable /G
when you wish to create a global variable. Don't do any assignments in that line (i.e. don't mix variable /G and '=' in one line).2) always use
NVAR
when you want to read or set the contents of a global variable.Lastly, remember that an
NVAR
really is just a signpost - it is a pointer to something else. That is why it never makes sense to change the name of an NVAR (and Igor will prevent you from doing so). In plain terms: to get a signpost to point to something else, you just change the direction it points to, but you don't change its name (since that is irrelevant anyway - we don't give names to signposts in daily life).July 6, 2011 at 12:24 pm - Permalink
The reason is that it is illegal to reference a global variable from a user-defined function without a NVAR. You can CREATE a global variable (using Variable/G) but you cannot directly reference it, either on the lefthand side or the righthand side of an assignment statement. This is true whether you use $str in the path or not.
In your example, you are directly referencing the global variable on the righthand side.
Some illustrative examples:
SetDataFolder root:
Variable/G globalVar = 987
String name = "globalVar"
// Try to directly reference on lefthand side
root:globalVar = 123 // Illegal
root:$name = 123 // Still illegal
// Try to directly reference on righthand side
Variable localVar
localVar = root:globalVar // Illegal
localVar = root:$name // Still illegal
// Reference through an NVAR
NVAR nv = root:globalVar
nv = 123 // OK
localVar = nv // OK
nv = 123
End
To add a twist, a statement like:
implicitly creates an NVAR so this is legal:
globalVar = 123 // Uses implicit NVAR
The implicit NVAR is created only when the Variable/G statement uses a simple name, not when it uses a path (Variable/G root:globalVar) or a $ constructions (Variable/G $name).
The same is true for String/G and Make. The create an implicit SVAR or WAVE reference only if a simple name is used.
To review these concepts, execute this:
July 6, 2011 at 10:38 pm - Permalink
Actually, that line seems to work fine for me.
July 7, 2011 at 07:02 am - Permalink
It also works for me which I find surprising. I'm not sure why. I think it is an anomaly:
SetDataFolder root:
Variable/G globalVar1 = 987
root:globalVar1 = 123 // This compiles and works though it seems that it should not compile
NewDataFolder/O/S root:TestFolder
Variable/G globalVar2 = 987
root:TestFolder:globalVar2 = 123 // This does not compile
SetDataFolder root:
End
I don't see any reason why the first assignment (root:globalVar=123) should compile while the second (root:TestFolder:globalVar2=123) does not. It seems like both should fail to compile. My understanding is that an NVAR should be required for both.
July 7, 2011 at 09:28 am - Permalink
Right, the second one fails with "no child data folder of that name exists". Whenever I see that error I sense trouble, because I still haven't figured out completely what that error is supposed to signal.
But especially baffling is this: how can this error ever appear at compile time?
July 7, 2011 at 10:59 am - Permalink