#pragma rtGlobals=2 // Use modern global access method. #pragma IgorVersion = 6.0 #pragma version = 2.61 Menu "Graph" "Append Multiple Graphs to a Layout",AppendGraph2LayoutN(NaN,"","") End Menu "Layout" "Append Multiple Graphs to a Layout",AppendGraph2LayoutN(NaN,"","") End // Puts text on the lower right corner showing when the layout was made, and on the lower left showing where it came from Proc Layout_Corner_Labels_Style_() // This is needed to make it show up in the "Layout Macros" menu Add_Corner_Labels_To_Layout() End Proc Add_Corner_Labels_To_Layout() : LayoutStyle PauseUpdate; Silent 1 // modifying window... Textbox/C/N=stamp0/F=0/A=RB/X=0.1/Y=0.1 "\\Z06\\{\"%s %s\",date(), time()}" Textbox/C/N=stamp1/F=0/A=LB/X=0.1/Y=0.1 "\\Z06\\{\"%s\",CornerStamp1_()}"+":"+WinName(0, 1) EndMacro Function/S CornerStamp1_() PathInfo home // creates String s_path return S_path+IgorInfo(1) End // Puts text on the lower right corner showing when the graph was made, and on the lower left showing where it came from Proc Add_Corner_Labels_To_Graph() : GraphStyle AddCornerLabelsToGraph() EndMacro Function AddCornerLabelsToGraph() GetWindow kwTopWin , psize Variable pBottom=V_bottom Variable pheight = V_bottom-V_top GetWindow kwTopWin , gsize Variable gBottom=V_bottom Variable bottom = -floor(100*(gBottom-pBottom)/pheight) Textbox/C/N=stamp0/F=0/A=RB/X=0.2/Y=(bottom)/E=2 "\\Z04\\{\"%s %s\",date(), time()}" Textbox/C/N=stamp1/F=0/A=LB/X=0.2/Y=(bottom)/E=2 "\\Z04\\{\"%s\",CornerStamp1_()}"+":"+WinName(0, 1) End // Put up multigraph layouts. Each time you call this, it adds another graph to the layout Window AppendMultiGraph2LayoutN() : Layout // this is needed to make it appear in the "Layout Macros" menu AppendGraph2LayoutN(NaN,"","") End // Append a graph to a multiple graph layout. This is for making multi-graph layouts Function/S AppendGraph2LayoutN(Nmax,orientation,gName) Variable Nmax // requested maximum number of graphs in the layout, one of Nlist String orientation // this must be "portrait" or "landscape" String gName // name of graph to append, if empty string, DoPrompt String Nlist = "1;2;3;4;6;8;9;12;16;20" // list of allowed values for Nmax if (!stringmatch("portrait",orientation) && !stringmatch("landscape",orientation)) orientation = "" endif if (Nmax<1 || Nmax>99 || numtype(Nmax)) Nmax = -1 // forces a prompt dialog elseif (Nmax>16) Nmax = 20 elseif (Nmax>12) Nmax = 16 elseif (Nmax>9) Nmax = 12 elseif (Nmax>6) Nmax = 9 elseif (Nmax>4) Nmax = 6 elseif (Nmax>3) Nmax = 4 elseif (Nmax>2) Nmax = 3 elseif (Nmax>1) Nmax = 2 endif Variable printIt=0 String lname if (strlen(gName)<1 || Nmax<0) if (Nmax<0) lname = StringFromList(0,WinList("Layout*",";","WIN:4")) // GetWindow $lname ,note // window note in S_Value // Nmax = NumberByKey("Nmax",S_Value,"=") Nmax = NumberByKey("Nmax",GetUserData(lname,"","AppendGraph2Layout"),"=") Nmax = numtype(Nmax) ? -1 : Nmax endif Nmax = Nmax<0 ? 12 : Nmax // 12 is default for absurd inputs Nmax = WhichListItem(num2istr(Nmax),Nlist)+1 Prompt gName, "Graph to add to layout",popup,WinList("*",";","WIN:1") Prompt Nmax,"number of graphs/layout",popup,Nlist DoPrompt "Pick a Graph",gName,Nmax if (V_flag) return "" endif Nmax = str2num(StringFromList(Nmax-1,Nlist)) printIt = 1 endif if (strlen(gName)<1) DoAlert 0, "no graph to add" return "" endif lname = StringFromList(0,WinList("Layout"+num2istr(Nmax)+"_*",";","WIN:4")) // get layout to append to if (strlen(LayoutInfo(lname, gName ))>1) return lname // graph is on layout, all done endif // check if this layout is full Variable i,N,NL = NumberByKey("NUMOBJECTS", LayoutInfo(lname,"Layout")) for (i=0,N=0;i=Nmax) // this layout is full, force creation of a new one lname = "" endif if (strlen(lname)<1) if (strlen(orientation)<1) // orientation was not passed, ask now orientation = SelectString(Nmax==8,"Landscape","Portrait") Prompt orientation, "page orientation",popup,"Portrait;Landscape" DoPrompt "Pick a Graph",orientation if (V_flag) return "" endif printIt = 1 endif lname = UniqueName("Layout"+num2istr(Nmax)+"_",8,0) // need to make a newlayout NewLayout/P=$orientation ModifyLayout mag=0.5, units=0, frame=0 DoWindow/C $lname // SetWindow kwTopWin ,note=ReplaceNumberByKey("Nmax","",Nmax,"=") SetWindow kwTopWin ,userdata(AppendGraph2Layout)=ReplaceNumberByKey("Nmax","",Nmax,"=") endif String page = StringByKey("PAGE", LayoutInfo(lname,"Layout")) // get page size to determing landscape or portrait Variable aspect = (str2num(StringFromList(3,page,","))-str2num(StringFromList(1,page,","))) // aspect = height/width aspect /= (str2num(StringFromList(2,page,","))-str2num(StringFromList(0,page,","))) orientation = SelectString(aspect>1,"landscape","portrait") // String rc = StringByKey(num2istr(Nmax),"1:1,1;2:2,1;3:3,1;4:2,2;6:3,2;9:3,3;12:4,3;16:4,4;20:4,5") String rc = StringByKey(num2istr(Nmax),"1:1,1;2:2,1;3:3,1;4:2,2;6:3,2;8:4,2;9:3,3;12:4,3;16:4,4;20:4,5") Variable rows=str2num(StringFromList(0,rc,",")) Variable columns=str2num(StringFromList(1,rc,",")) if (stringmatch("landscape",orientation)) // swap rows and columns for Landscape orientation Variable swap = rows rows = columns columns = swap endif AppendLayoutObject/F=0/W=$lname graph $gName String cmd sprintf cmd, "Tile /A=(%d,%d)/O=1",rows,columns Execute cmd RemoveLayoutObjects/W=$lname/Z stamp0,stamp1 // make sure that text boxes are written last, so they show Textbox/C/N=stamp0/W=$lname/F=0/A=RB/X=0.1/Y=0.1 "\\Z06\\{\"%s %s\",date(), time()}" Textbox/C/N=stamp1/W=$lname/F=0/A=LB/X=0.1/Y=0.1 "\\Z06\\{\"%s\", CornerStamp1_()}"+":"+WinName(0,1) if (printIt && topOfStack()) printf "\tAppendGraph2LayoutN(%d,\"%s\",\"%s\")\r",Nmax,orientation,gName endif return lname End //Function xxx(Nmax) // a test routine for AppendGraph2LayoutN() // Variable Nmax // Make/N=100/O y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12 // SetScale/I x 0,10,"", y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12 // y0 = 0.2*x -1 // y1 = sin(x/2) ; y2 = sin(x) ; y3 = sin(2*x) ; y4 = sin(3*x) ; y5 = sin(4*x) // y5 = cos(x/2) ; y6 = cos(x) ; y7 = cos(2*x) ; y8 = cos(3*x) ; y9 = cos(4*x) // y10 = exp(x/10)/3 ; y11 = exp(-x/4) ; y12 = 2*exp(-x/2)-1 // Variable i // String win // for (i=0;i<=12;i+=1) // win = "Graph"+num2istr(i) // if (strlen(WinList(win,"","WIN:1"))<1) // Display/K=1 $("y"+num2istr(i)) // DoWindow/C $win // ModifyGraph tick=2, minor=1, standoff=0, mirror=1 // ModifyGraph axOffset(left)=-4.7,axOffset(bottom)=-1.5 // endif // AppendGraph2LayoutN(Nmax,"",win) // endfor //End // ============================================================================ // // ============================== Start of String Ranges ============================== // // This section is for dealing with random or usually non contiguous sequence of integers // i.e. you took data in scans 1-30, but scans 17, and 25 were no good. So the valid range is "1-16,18-24,26-30" // or perhaps you want to combine scans "3,7,9" The following routines handle those situations in a simple fashion. Function NextInRange(range,last) // given a string like "2-5,7,9-12,50" get the next number in this compound range // the range is assumed to be monotonic, it returns NaN if no more values String range // list defining the range Variable last // last number obtained from this range, use -Inf to get start of range, it returns the next // find first item in the list that should use next String item Variable m,i,j Variable first // first value in an item do item = StringFromList(j,range,",") first = str2num(item) // do we need to check for NaN in first? if (numtype(first)) return NaN elseif (last=first, check to see if item is a '2-5' type range m=-1 // remove any leading white space from item do m += 1 while (char2num(item[m])<=32) item = item[m,strlen(item)-1] i = strsearch(item,"-",1) // location of first '-' after the first character if (i<0) // only a single number, not a dash type range, keep looking j += 1 continue endif // check to see if last was in the range of item, but not the last value if (last>=str2num(item) && last0) return NaN End //Function TestNextInRange(range) // String range // range = SelectString(strlen(range) ,"-16,-7--3,-1-2,5,50-54,99",range) // Variable i = -Inf // printf "for range = {%s}, ", range // do // i = NextInRange(range,i) // if (numtype(i)) // break // endif // printf "%d ", i // while (!numtype(i)) // print "" //End Function PointInRange(i,range) // return the ith number in range, first number is i==0 Variable i // index to number in range String range // a string range Variable N=ItemsInRange(range) i = round(i) if (numtype(i) || i<0 || i>=N) // check for valid index return NaN endif Variable j, m=-Inf for (j=0;j<=i;j+=1) // this is not the fastest, but it is simple m = NextInRange(range,m) endfor return m End Function ItemsInRange(range) // given a string like "2-5,7,9-12,50" get the total number of values in the range String range // list defining the range // the range is assumed to be monotonic, it returns NaN on error String item // each of the comma sepated items Variable len=0 // the result, number of values represented Variable m,i,j,N=ItemsInList(range,",") for (j=0;j=0) return Inf endif i = strlen(range)+1 do i -= 1 c = char2num(range[i-1]) while(c>=48 && c<=57 && i>0) // a digit, continue last=str2num(range[i,Inf]) if (c==45) if (i==1) return -last endif c = char2num(range[i-2]) // char preceeding minus sign if (c==45 || c==44) return -last endif endif return last End // Caution expandRange("1-100000",";") will produce a very long string! Use NextInRange() to avoid this problem Function/S expandRange(range,sep) // expand a string like "2-5,7,9-12,50" to "2,3,4,5,7,9,10,11,12,50" String range // series of numberseparated by commas and dashes, white is space igaored String sep // separates final list, usually ";" if (strsearch(range,"Inf",0,2)>=0) // cannot put an infinite number of characters into a string return "" endif if (strlen(sep)<1) // sep defaults to ';' sep = ";" endif Variable i1,i2,i String str,out="" Variable N=ItemsInList(range,",") if (N<1) return "" endif Variable j=0 do str = StringFromList(j, range, ",") Variable m=-1 // remove any leading white space do m += 1 while (char2num(str[m])<=32) str = str[m,strlen(str)-1] // now check str to see if it is a range like "20-23" i1 = str2num(str) i = strsearch(str,"-",strlen(num2str(i1))) // position of "-" after first number if (i>0) i2 = str2num(str[i+1,inf]) i = i1 do out += num2str(i)+sep i += 1 while (i<=i2) else out += num2str(i1)+sep endif j += 1 while (j '%s'\r",range, compressRange(range,";") // range = "1;2;3;4;5;9;10;11" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") // range = "4" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") // range = "4;7" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") // range = "-10;-9;-8;-7;-6;-5;-3;-2;-1;0;1;2;7;9;22" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") // range = "7;6;4;5;2;3" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") // range = "-1;1;0;-3;2;-2" // printf "'%s' ---> '%s'\r",range, compressRange(range,";") //End // =============================== End of String Ranges ============================== // // ============================================================================ // // =================================================================================== // ================================= Start of Progress Panel ================================= Function/T ProgressPanelStart(percentName,[stop,showTime]) // display a progress bar // if the user does a "DoUpdate/W=$wname", then V_flag will be set to 2 if the stop button was pushed String percentName // name of global value to use, if not a global variable then set value to 0 Variable stop // if true, include a stop button Variable showTime // if true, include the ending time on panel stop = ParamIsDefault(stop) ? 0 : stop stop = NumberByKey("IGORVERS",IgorInfo(0))>=6.10 ? stop : 0 // stop feature requires version 6.10 or above showTime = ParamIsDefault(showTime) ? 0 : showTime Variable right = stop ? 695 : 630, bottom = showTime ? 137 : 117 NewPanel/K=1/W=(330,87,right,bottom)/N=Progress String wname = S_name // save the name of the window ValDisplay progressValdisp, win=$wname, pos={5,5},size={288,25},font="Helvetica",fSize=18,format="%d%%" ValDisplay progressValdisp, win=$wname, limits={0,100,0},barmisc={0,50},highColor= (19368,32650,65196) if (exists(percentName)==2) // the global exists, use it NVAR percent = $percentName percent = limit(percent,0,100) ValDisplay progressValdisp,win=$wname, value= #percentName else // no global, just set to zero ValDisplay progressValdisp,win=$wname, value= #"0" endif if (stop) Button stopButton,pos={299,4},size={50,20},title="Stop" endif if (showTime) TitleBox timeTitle,pos={1,29},size={213,16},fSize=12,frame=0,title=" " endif #if NumberByKey("IGORVERS",IgorInfo(0))>=6.10 DoUpdate/W=$wname/E=1 // mark as a progress window #else DoUpdate #endif String str = num2istr(DateTime) SetWindow $wname userdata(startTimeSec)=str SetWindow $wname userdata(lastTimeSec)=str // last time updated SetWindow $wname userdata(showTime)=num2istr(showTime) SetWindow $wname userdata(stop)=num2istr(stop) SetWindow $wname userdata(percent)=num2str(percent) return wname End // Function ProgressPanelUpdate(wname,percent) // update a progress bar String wname // window name Variable percent // percent done (% !!) ValDisplay progressValdisp,win=$wname, value= #num2istr(floor(limit(percent,0,100))) Variable showTime = str2num(GetUserData(wname,"","showTime")) if (showTime && percent>0) Variable start = str2num(GetUserData(wname,"","startTimeSec")) Variable last = str2num(GetUserData(wname,"","lastTimeSec")) Variable now = DateTime if (now-last > 2) Variable remain = (now-start) * (100-percent)/percent String str if (remain < 5*60) // under 10 min sprintf str, "should end in %s, at %s",Secs2Time(remain,5),Secs2Time(now+remain,1) else sprintf str, "should end in %s, at %s",Secs2Time(remain,4),Secs2Time(now+remain,0) endif str += SelectString(remain > 24*3600,""," on "+Secs2Date(now+remain,2)) // more than 1 day TitleBox timeTitle,title=str SetWindow $wname userdata(lastTimeSec)=num2istr(now) // last time updated, is now endif endif Variable done=0 #if NumberByKey("IGORVERS",IgorInfo(0))>=6.10 DoUpdate/W=$wname // update only progress window done = V_Flag == 2 // stop button on progress window was pushed #else DoUpdate // update all windows, no stop button #endif return done End //Function testProgress() // String progressWin = ProgressPanelStart("",stop=1,showTime=1) // display a progress bar // Variable i,N=1e3 // for (i=0;i0) line = line[0,i-1] endif line = ReplaceString("\t",line," ") // change all tabs to spaces line += " " // ensure a space terminator if (strsearch(line,"$filetype ",0)!=0) // does not starts with $filetype, pass back the tag i = strsearch(line," ",0) return line[1,i-1] endif line = line[9,Inf] // strip off the $filetype tag // now get the value for (i=0;i=0 && char2num(line[i])<=32;i-=1) endfor line = line[0,i] line = ReplaceString(",",line,";") // change all commas, and spaces to semi-colons line = ReplaceString(" ",line,";") return line End Function keyInList(key,keyWordList,keySepStr,listSepStr) // returns true if key=value pair is in the keyWordList String key // string with key String keyWordList // list of keyword=value pairs String keySepStr // separates key and value, defaults to colon String listSepStr // separates key value pairs, defaults to semicolon keySepStr = SelectString(strlen(keySepStr),":",keySepStr) // default to colon listSepStr = SelectString(strlen(listSepStr),";",listSepStr) // default to semicolon String find=key+keySepStr // find this if (strsearch(keyWordList,find,0)==0) // check if it is at the start return 1 // found key=value is first pair endif if ( strsearch(keyWordList,listSepStr+find,0)>0) // check if key is after first key=value pair return 1 // found key=value is a later pair endif return 0 // no key=value found End // Merges two key=value lists, if priority=0, then list0 has priority, if priority=1 then list1 Function/S MergeKeywordLists(list0,list1,priority,keySepStr,listSepStr) String list0,list1 Variable priority // 0 or 1 String keySepStr // separates key and value, defaults to colon String listSepStr // separates key value pairs, defaults to semicolon keySepStr = SelectString(strlen(keySepStr),":",keySepStr) // default to colon listSepStr = SelectString(strlen(listSepStr),";",listSepStr) // default to semicolon String item, key,value Variable i,N=ItemsInList(list1) for (i=0;ia[i]) return 0 endif i += 1 while (i=0; i-=1) // find last non-white space endfor return str[0,i] End // do not use num2sexigesmal() anymore, for new code use Secs2Time() directly. Function/S num2sexigesmal(seconds,places) // convert seconds into a hh:mm:ss.sss string Variable seconds Variable places return Secs2Time(seconds,5,places) End // returns 1 if the calling function was invoked from a menu item or command line (otherwise 0) Function topOfStack() return (ItemsInList(GetRTStackInfo(0))<3) End //Function abc() // String cmd, pathStr="\\\"/Users/tischler/data/Sector 34/July 4, 2006/EW5/recon/\\\"" // print PathStr // sprintf cmd, "do shell script \"ls %s\"",pathStr // ExecuteScriptText cmd // print cmd // print S_value[0,72] //End