Clone Window

Clone a window, i.e. make an exact copy of a graph, table, etc. with the same axes, traces, etc. The waves in the original and the clone are shared between the two (no data is copied).

Function CloneWindow([win,replace,with,freeze])
    String win // Name of the window to clone.  
    String replace,with // Replace some string in the windows recreation macro with another string.  
    Variable freeze // Make a frozen clone (basically just a picture).  
   
    if(ParamIsDefault(replace) || ParamIsDefault(with))
        replace=""; with=""
    endif
    if(ParamIsDefault(win))
        win=WinName(0,1)
    endif
    String win_rec=WinRecreation(win,0)
    Variable i
    for(i=0;i<ItemsInList(replace);i+=1)
        String one_replace=StringFromList(i,replace)
        String one_with=StringFromList(i,with)
        win_rec=ReplaceString(one_replace,win_rec,one_with)
    endfor
    if(freeze)
        Struct rect coords
        GetWinCoords(win,coords)
        SavePICT /WIN=$win as "Clipboard"
        String newName=UniqueName(win,6,0)
        LoadPICT /O/Q "Clipboard",$newName
        Display /N=$newName /W=(coords.left,coords.top,coords.right,coords.bottom)
        DrawPICT /W=$newName 0,0,1,1,$newName
    else
        Execute /Q win_rec
    endif
End


CloneWindow, but replace all the traces with copies and puts those copies in one data folder. Data is not shared between the original and the clone.
Function CloneWindow2([win,name,times])
    String win
    String name // The new name for the window and data folder.
    Variable times // The number of clones to make.  Clones beyond the first will have _2, _3, etc. appended to their names.  
    if(ParamIsDefault(win))
        win=WinName(0,1)
    endif
    if(ParamIsDefault(name))
        name=UniqueName2(win,"6;11")
    else
        name=CleanupName(name,0)
    endif
    times=ParamIsDefault(times) ? 1 : times
    String curr_folder=GetDataFolder(1)
    NewDataFolder /O/S root:$name
    String traces=TraceNameList(win,";",3)
    Variable i,j
    for(i=0;i<ItemsInList(traces);i+=1)
        String trace=StringFromList(i,traces)
        Wave TraceWave=TraceNameToWaveRef(win,trace)
        Wave /Z TraceXWave=XWaveRefFromTrace(win,trace)
        Duplicate /o TraceWave $NameOfWave(TraceWave)
        if(waveexists(TraceXWave))
            Duplicate /o TraceXWave $NameOfWave(TraceXWave)
        endif
    endfor
    String win_rec=WinRecreation(win,0)
   
    // Copy error bars if they exist.  Won't work with subrange display syntax.  
    for(i=0;i<ItemsInList(win_rec,"\r");i+=1)
        String line=StringFromList(i,win_rec,"\r")
        if(StringMatch(line,"*ErrorBars*"))
            String errorbar_names
            sscanf line,"%*[^=]=(%[^)])",errorbar_names
            for(j=0;j<2;j+=1)
                String errorbar_path=StringFromList(j,errorbar_names,",")
                sscanf errorbar_path,"%[^[])",errorbar_path
                String errorbar_name=StringFromList(ItemsInList(errorbar_path,":")-1,errorbar_path,":")
                Duplicate /o $("root"+errorbar_path) $errorbar_name
            endfor
        endif
    endfor
   
    for(i=1;i<=times;i+=1)
        Execute /Q win_rec
        if(i==1)
            DoWindow /C $name
        else
            DoWindow /C $(name+"_"+num2str(i))
        endif
        ReplaceWave allInCDF
    endfor
    SetDataFolder $curr_folder
End
Thank you for this excellent snippet. One note/question on CloneWindow2: I had to include a colon after "root" when duplicating my error bar waves or they weren't created in the new data folder.

Duplicate /o $("root:"...

Any thoughts on this? Thanks!

CloneWindow2 code is now failing for me. This line:

            sscanf line,"%*[^=]=(%[^)])",errorbar_names

does not work on a graph I have where the line is: "ErrorBars/T=0/L=0 r_TCP_710C_2min_0006_C Y,wave=(:WAXS:TCP_710C_2min_0006_C:s_TCP_710C_2min_0006_C,:WAXS:TCP_710C_2min_0006_C:s_TCP_710C_2min_0006_C)". errorbar_names is empty string after that line. 

This is Igor 8.04. I think the problem are my parameters to Errorbars : /T=0/L=0. Can the syntax be changed to look for the content after the last "=" sign and skip the previous ones, if any are present? 

I think I fixed it, not sure if this will work always, but here is small code change which seems to work for me now: 

    // Copy error bars if they exist.  Won't work with subrange display syntax.  
    for(i=0;i<ItemsInList(win_rec,"\r");i+=1)
        String line=StringFromList(i,win_rec,"\r")
        if(StringMatch(line,"*ErrorBars*"))
            String errorbar_names
            SplitString/E=",.*" line
            sscanf S_value,"%*[^=]=(%[^)])",errorbar_names
            for(j=0;j<2;j+=1)
                String errorbar_path=StringFromList(j,errorbar_names,",")
                sscanf errorbar_path,"%[^[])",errorbar_path
                String errorbar_name=StringFromList(ItemsInList(errorbar_path,":")-1,errorbar_path,":")
                Duplicate /o $("root"+errorbar_path) $errorbar_name
            endfor
        endif
    endfor

Note, I added SplitString which splits the "line" at first "," to remove ErrorBars with flags (which may contain additional "=").

Also, I needed to remove the ":" from "root" in the Duplicate command. 

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More