Different treatment in data folder path: Window recreation macro vs. Macro

I am now using Igor 8.042.
Recently, I noticed a different (strange) treatment in data folder path for Window Recreation Macro (WRM) and Macro.
It is, at least for me, just annoying and pain since I cannot no longer re-use Graph Recreation Macro (a type of WRM) as Macro to use creating graphs in different data folders with the same wave names.

When I was using Igor 6 and 7, the behavior was different and I could reuse the WRM as Macro by just renaming "window XXXX(): graph" into "Macro XXXX()".

I would like to know why the basic behavior had been changed from Igor 8. It reduces much productivity in data management and mass data processing on Igor.

Here is the detail explanation.

(1) Window Recreation Macro (below) requires setting current data folder.
Without SetDataFolder commnad, the WRM gives error!
WRM examines all paths relative to ROOT FOLDER, which makes reuse the macro in different data folders with similar data folder structure for mass data processing.

Window TEST_G3_corr_N2O_Month_SoilTemp_Full() : Graph	
        PauseUpdate; Silent 1		// building window...	
        String fldrSav0= GetDataFolder(1)	
        SetDataFolder root:TR_01h_Data:ALL_TR_01h_v2:	
        Display /W=(536.25,404,961.5,746.75) N2O_Flux vs SoilTemp_25 as "TEST_G3_corr_N2O_Month_SoilTemp_Full"
	SetDataFolder fldrSav0



EndMacro

(2) Changing window recreation macro to macro
This also fails since all paths to waves are relative to root folder (not relative to current data folder), which fails referring waves which paths are all relative to root folder......

Conclusion: Window Recreation Macro cannot be no longer used as Macro without significant code modification.

Why such basic behavior/path treatment had been changed?
I miss Igor 6 and 7 a lot.

It looks like all the paths are relative to the datafolder of the first wave on the plot.

so if you remove the line with SetDataFolder and navigate to the equivalent folder in another dataset, the recreation macro should execute with substituted waves, right?

In reply to by tony

Hi Tony,

I thought so, too.
But in window recreation macro, two type of paths are mixed (relative to root folder and current data folder) in 2.5D plot.
In 2.5D plot (I mean X, Y, f(z) Color/Size), X and Y waves are all relative to current data folder. They are OK, but the f(z) wave is relative to root folder.
That is the problem.

Folder Structure:
  root
     TR_01h_Data
          ALL_TR_01h_v2
 

The f(z) path: relative to root folder)
     ModifyGraph zmrkSize(N2O_Flux)={:TR_01h_Data:ALL_TR_01h_v2:Month_Meas,3,9,4,4}
     ModifyGraph zColor(N2O_Flux)={:TR_01h_Data:ALL_TR_01h_v2:Month_Meas,3,9,Grays256,1}


 
Window G3_corr_N2O_Month_SoilTemp_Full() : Graph
    PauseUpdate; Silent 1       // building window...
    String fldrSav0= GetDataFolder(1)
    SetDataFolder root:TR_01h_Data:ALL_TR_01h_v2:
    Display /W=(536.25,404,961.5,746.75) N2O_Flux vs SoilTemp_25 as "G3_corr_N2O_Month_SoilTemp_Full"
    SetDataFolder fldrSav0
    ModifyGraph mode=3
    ModifyGraph marker=19
    ModifyGraph msize=3
    ModifyGraph mrkThick=1
    ModifyGraph useMrkStrokeRGB=1
    ModifyGraph zmrkSize(N2O_Flux)={:TR_01h_Data:ALL_TR_01h_v2:Month_Meas,3,9,4,4}
    ModifyGraph zColor(N2O_Flux)={:TR_01h_Data:ALL_TR_01h_v2:Month_Meas,3,9,Grays256,1}
    ModifyGraph tick=2
    ModifyGraph mirror=1
    ModifyGraph fSize=14
    ModifyGraph lblMargin(left)=10,lblMargin(bottom)=3
    ModifyGraph lblLatPos(left)=1,lblLatPos(bottom)=-2
    Label left "N2O_Flux"
    Label bottom "SoilTemp_25"
    SetAxis left 0,5000
    SetAxis bottom 0,35
    ColorScale/C/N=textColorS/F=0/H={0,0,1}/B=1/A=MT/X=-31.85/Y=-0.26 trace=N2O_Flux
    ColorScale/C/N=textColorS vert=0, side=2, width=100, tickLen=2, notation=1
    AppendText "\\Zr150Month_Meas"
EndMacro

For ordinary 2D plot, simply converting Graph Macro into Macro will work OK, but not for 2.5D plot (x, y, f(z)) ...

How about this:

menu "Graph"
    "Duplicate Graph Different Folder"
end

function DuplicateGraphDifferentFolder()
    string recreation = WinRecreation("", 0), sdfr = "root:"
    string fldrSav0 = GetDataFolder(1), cmd = ""
    variable i = strsearch(recreation, "SetDataFolder", 0)
    if(i > -1)
        sdfr=recreation[i+14,strsearch(recreation, "\r", i)-1]
    endif
    CreateBrowser/M Prompt="select folder"
    ModifyBrowser/M showWaves=0, showVars=0, showStrs=0, ShowInfo=0, showPlot=0
    ModifyBrowser/M SetDataFolder="root:"
    ModifyBrowser/M showModalBrowser
    if (V_Flag == 0)
        return 0
    endif
    if (ItemsInList(s_browserlist) != 1)
        DoAlert 0, "select one folder"
        return 0
    endif
    SetDataFolder $StringFromList(0, s_browserlist)
    recreation = ReplaceString(sdfr[4,Inf], recreation, ":")
    for (i=2;i<ItemsInList(recreation, "\r")-1;i++)
        cmd = StringFromList(i,recreation, "\r")
        if (grepstring(cmd, "SetDataFolder|fldrSav0"))
            continue
        endif
        Execute /Z cmd
    endfor
    SetDataFolder fldrSav0
end

 

I have not read this thread closely but this might shed some light:

DisplayHelpTopic "Data Folders and Window Recreation Macros"

As far as I know, this has not changed in decades.

 

I can see the ease in processing that you have lost. I also however see the loss as an opportunity to restructure your approach to a more robust one. In this respect, I believe that the use of functions rather than macros has been advocated as the preferred approach to future programming since perhaps Igor 6 or Igor 7. What is limiting you from creating a general-purpose function that generates a graph from the waves in the data folder that you select using the data browser? Add a menu function at the top, store the procedure as a procedure file in the WaveMetrics Igor Procedures folder, and you will have the function always available in the macros menu (or where-ever else you decide to have it show).

In the meantime, an alternative fix in your current approach is to move the SetDataFolder fldrSav0 to the end of the code block and to remove the ":TR_01h_Data:ALL_TR_01h_v2:" prefixes from the zmrkSize and zColor lines.

 

I don't see any change in Igor 6-9 in that kind of graph's recreation macro.

I generated a simple zColor graph using your data folders and saved the generated window macros in each version of Igor; they're the same:

Window Graph0Igor9() : Graph
    PauseUpdate; Silent 1       // building window...
    String fldrSav0= GetDataFolder(1)
    SetDataFolder root:TR_01h_Data:
    Display /W=(35,45,430,253) N20_Flux vs SoilTemp_25
    SetDataFolder fldrSav0
    ModifyGraph zColor(N20_Flux)={:TR_01h_Data:Month_Meas,*,*,PlanetEarth}
EndMacro

Window Graph0Igor6() : Graph
    PauseUpdate; Silent 1       // building window...
    String fldrSav0= GetDataFolder(1)
    SetDataFolder root:TR_01h_Data:
    Display /W=(35,45,430,253) N20_Flux vs SoilTemp_25
    SetDataFolder fldrSav0
    ModifyGraph zColor(N20_Flux)={:TR_01h_Data:Month_Meas,*,*,PlanetEarth}
EndMacro

Window Graph0Igor7() : Graph
    PauseUpdate; Silent 1       // building window...
    String fldrSav0= GetDataFolder(1)
    SetDataFolder root:TR_01h_Data:
    Display /W=(35,45,430,253) N20_Flux vs SoilTemp_25
    SetDataFolder fldrSav0
    ModifyGraph zColor(N20_Flux)={:TR_01h_Data:Month_Meas,*,*,PlanetEarth}
EndMacro

Window Graph0Igor8() : Graph
    PauseUpdate; Silent 1       // building window...
    String fldrSav0= GetDataFolder(1)
    SetDataFolder root:TR_01h_Data:
    Display /W=(35,45,430,253) N20_Flux vs SoilTemp_25
    SetDataFolder fldrSav0
    ModifyGraph zColor(N20_Flux)={:TR_01h_Data:Month_Meas,*,*,PlanetEarth}
EndMacro

 

Perhaps what changed is the use of a wave that isn't in the root data folder. If you always create your template graph with waves in the root folder, then the waves will be referred to in ways that don't (explicitly) reference a data folder. As the help topic that HRodstein pointed you to says, a window macro implicitly references the root data folder. That macro will behave as you expect.

In case you are wondering, window macros run in root context for backward compatibility with old versions of Igor that didn't have data folders. You can still (mostly) open an experiment file made by Igor v. 2 in Igor v. 9!

> You can still (mostly) open an experiment file made by Igor v. 2 in Igor v. 9!

Will it show the same opening dialog that Igor 2 used to display? Do those opening dialogs still exist in the archives of WaveMetrics? Can we get a historical slide show of them some day? Is there perhaps a superuser Easter-egg command that will show them to us?

Sorry. My mind ran in tangents on this one.

:-)

 

Hi everyone, 
As John suggested, the basic behavior does not change since Igor 6 or 7.
It was my misunderstanding. Sorry.

But the problem remains for 2.5D plot.

Since Display and AppendToGraph are sandwiched by this way, simply converting the Graph Macro into Macro works OK.

    SetDataFolder root:TR_01h_Data:ALL_TR_01h_v2:
        Display /W=(536.25,404,961.5,746.75) N2O_Flux vs SoilTemp_25 as "G3_corr_N2O_Month_SoilTemp_Full"
    SetDataFolder fldrSav0
 

But after this section, in Graph Macro, the macro resumes using path relative to root folder.
Then, it would be a trouble for re-using the Graph Macro as general Macro.

I understand making a function is an ultimate solution, but I would like to have a handy one.
A practical and handy way is to manually change the paths in a way of "relative to current data folder".
I know it, but if possible, I would like to avoid it....

 

If you can tolerate having to set the current data folder to whatever folder holds the waves you want the macro to use, then you should be able to simply remove any SetDataFolder commands. Or my original suggestion: be sure that when you generate the window macro, you are using only waves in root:.

At some point, it may be easier to convert the window macro into a function like this:

Function TEST_G3_corr_N2O_Month_SoilTemp_Full(Wave ywave, Wave xwave) : Graph  
        Display /W=(536.25,404,961.5,746.75) ywave vs xwave as "TEST_G3_corr_N2O_Month_SoilTemp_Full"
EndMacro

Clearly, your example is simplified, and a real example would probably require more complex manipulation. Any ModifyGraph command that references a trace name would need something like

String tname = NameOfWave(ywave)
ModifyGraph marker($tname)=8
... more ModifyGraph commands referencing $tname ...

We had a good reason to do it the way we do it. The question is now, where is the line between what you admit is a "quick and convenient" method, and just doing it the hard way?

This is similar to the conundrum we have all faced- if I do it once, I can use the command line faster than writing code. If I do it 100 times, it is probably faster to write real code. Where is the crossover point? When I have just done it once, how do I know if I will do it 100 times?

So your original question has merit, and WaveMetrics drew the line at a different point than you did.

What is the problem with trace names? Custom trace names are set by the Display command, so provided that works the ModifyGraph commands should work too. How about something like this (there are probably plenty of ways for it to fail, but if the data are organised within distinctively named folders this seems to work):

menu "Graph"
    "Copy Relative Window Macro to Clipboard"
end

function CopyRelativeWindowMacroToClipboard()
    string recreation=WinRecreation("", 0), sdfr="root:"
    recreation = replacestring("Window", recreation, "Macro", 0, 1)
    variable i = strsearch(recreation, "SetDataFolder", 0)
    if (i > -1)
        sdfr=recreation[i+14,strsearch(recreation, "\r", i)-1]
    endif
    // if the data folder path is distinctive this may work
    recreation = ReplaceString(sdfr[4,Inf], recreation, ":")
    // put lines of macro into a free text wave
    wave /t wRec = ListToTextWave(recreation, "\r")
    // grep out the lines we don't want
    Grep /LIST="\r"/Q/E={"(?i)^\s*(String fldrSav0|SetDataFolder)",1} wRec
    if (V_Value)
        PutScrapText S_value
    endif
end

I also edited the "Duplicate Graph Different Folder" snippet in a previous post.

Tony- I was just trying to work the original problem which was stated as a desire to use the recreation macro directly. You have gone the extra mile, as usual!

And yes, custom trace names are a boon to folks who need easy-to-write generic code for ModifyGraph. I didn't address in my response the possibilities for how WaveName() might fail to produce the right trace name!