#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma version=1.0 // Arc Hull is a baseline approximation for spectral data. // A concave-upward arc is defined by a circle centered at the // midpoint of the spectrum. The depth of the arc is adjustable. // The arc is added to the spectrum, and the lower portion of a // convex hull is calculated for the resultant spectrum. // The baseline consists of the sum of the arc and the convex hull. // Setting arc depth to zero creates a convex hull (a.k.a. 'rubber band') // type baseline. // the arc depth SetVar increments by 10% of its value. Menu "Analysis" Submenu "Packages" "Arc Hull",/Q, CCH_init() end end Menu "Macros" "Arc Hull",/Q, CCH_init() end function CCH_clear() GetWindow /Z CCH_panel activeSW string s_graph=parseFilepath(0, s_value, "#", 0, 0) KillWindow /Z CCH_panel if (strlen(winlist(s_graph,";",""))) removefromgraph /W=$s_graph /Z Arc_Hull_Base, Arc_Hull_Sub endif end function CCH_init() if (strlen(WinList("*",";","WIN:1"))==0) // no graphs doalert 0, "Arc hull baseline requires a trace plotted in a graph window." return 0 endif // make sure the top graph is visible string s_graph=WinName(0,1) dowindow /F $s_graph // clear any package detritus from the last used arc hull graph CCH_clear() // initialize (or reinitialize) the package data folder NewDataFolder /O root:Packages NewDataFolder /O root:Packages:CCHbaseline // Create a data folder reference variable DFREF dfr = root:Packages:CCHbaseline // make panel NewPanel /K=1/N=CCH_panel/W=(200,0,0,0)/HOST=$s_graph/EXT=1 as "Arc Hull Controls" ModifyPanel /W=$s_graph#CCH_panel, noEdit=1 string s_trace=stringfromlist(0, CCH_traces()) wave w=TraceNameToWaveRef(s_graph, s_trace) variable depth=(wavemax(w)-wavemin(w))*.15 // store values internally in these controls PopupMenu popTrace, mode=1, Value=CCH_traces(), title="",pos={50,50},size={130,20} PopupMenu popTrace, help={"select data wave" }, proc=CCH_popup SetVariable setvarDepth,pos={50,100},size={130,16},title="Arc depth" SetVariable setvarDepth,limits={-inf,inf,depth/10},value=_NUM:depth SetVariable setvarDepth,help={"depth of arc"}, fsize=14, proc=CCH_SetVar Button CCH_sub,pos={50,150},size={100,20},title="Subtract", proc=CCH_buttons Button CCH_sub,help={"subtract arc hull baseline"} Button CCH_all,pos={50,200},size={100,20},title="All in one", proc=CCH_buttons Button CCH_all,help={"subtract arc hull baseline from all traces"} // set hook to intercept killing of panel SetWindow $s_graph#CCH_panel, hook(CCH_Hook) = CCH_PanelHook if (strlen(s_trace)==0) return 0 endif // do fit to create baseline CCH_doFit(s_trace) wave /SDFR=dfr w_base, w_sub wave w_x=XWaveRefFromTrace(s_graph, s_trace) removefromgraph /W=$s_graph /Z Arc_Hull_Base, Arc_Hull_Sub if(waveexists(w_x)) appendtograph /W=$s_graph w_base/TN=Arc_Hull_Base vs w_x appendtograph /W=$s_graph w_sub/TN=Arc_Hull_Sub vs w_x else AppendToGraph /W=$s_graph w_base/TN=Arc_Hull_Base, w_sub/TN=Arc_Hull_Sub endif end Function CCH_SetVar(s) : SetVariableControl STRUCT WMSetVariableAction &s SetVariable setvarDepth win=$s.win,limits={-inf,inf,s.dval/10} controlinfo /W= $s.win popTrace string s_graph=parseFilepath(0, s.win, "#", 0, 0) CCH_doFit(s_value) return 0 End Function CCH_popup(s) STRUCT WMPopupAction &s string s_graph=parseFilepath(0, s.win, "#", 0, 0) wave w=TraceNameToWaveRef(s_graph, s.popStr) if (waveexists(w)==0) return 0 endif // set default depth each time a trace is selected variable depth=(wavemax(w)-wavemin(w))*0.15 SetVariable setvarDepth,win=$s.win,limits={0,inf,depth/10},value=_NUM:depth CCH_doFit(s.popStr) DFREF dfr = root:Packages:CCHbaseline wave /SDFR=dfr w_base, w_sub removefromgraph /W=$s_graph /Z Arc_Hull_Base, Arc_Hull_Sub wave w_x=XWaveRefFromTrace(s_graph, s.popstr) if(waveexists(w_x)) appendtograph /W=$s_graph w_base/TN=Arc_Hull_Base vs w_x appendtograph /W=$s_graph w_sub/TN=Arc_Hull_Sub vs w_x else AppendToGraph /W=$s_graph w_base/TN=Arc_Hull_Base, w_sub/TN=Arc_Hull_Sub endif return 0 End Function CCH_buttons(s) : ButtonControl STRUCT WMButtonAction &s if(s.eventCode!=2) return 0 endif string s_graph=parseFilepath(0, s.win, "#", 0, 0) string s_trace strswitch(s.ctrlName) case "CCH_sub": controlinfo /W=$s.win popTrace wave w=TraceNameToWaveRef(s_graph, s_value) if (waveexists(w)==0) return 0 endif CCH_subtract(w) break case "CCH_all": string msg="subtract arc hull baseline from all traces using current arc depth?\r" msg+="existing baselines will be overwritten!" doalert 1, msg if(v_flag==2) return 0 endif string s_list=CCH_traces() variable i for(i=0;i=0) reverse /P w_XHull, w_YHull endif wavestats /q w_XHull rotate -v_minloc, w_XHull, w_YHull setscale /p x, 0, 1, w_XHull, w_YHull wavestats /q w_XHull deletepoints v_maxloc+1, numpnts(w_XHull)-v_maxloc-1, w_XHull, w_YHull if(useXwave) Interpolate2/T=1/Y=w_base/X=w_x/I=3 W_XHull,W_YHull else Interpolate2 /T=1/Y=w_base/I=3 W_XHull,W_YHull endif w-=w_base // negative peaks will extend down from zero end Function CCH_PanelHook(s) STRUCT WMWinHookStruct &s strswitch (s.eventName) case "kill": string s_graph=parseFilepath(0, s.winName, "#", 0, 0) removefromgraph /W=$s_graph /Z Arc_Hull_Base, Arc_Hull_Sub return 1 endswitch return 0 end function CCH_subtract(w [,overwrite]) wave w variable overwrite if (paramisdefault(overwrite)) overwrite=0 endif GetWindow /Z CCH_panel activeSW string s_graph=parseFilepath(0, s_value, "#", 0, 0) DFREF dfr = root:Packages:CCHbaseline wave /SDFR=dfr w_sub, w_base // save a copy of the baseline string strNewName=CleanupName(nameofwave(w)+"_base",0) if (overwrite==0 && exists(strNewName)) doalert 1, strNewName+" exists. Overwrite?" if(V_flag==2) return 0 endif endif duplicate /o w $strNewName wave newbase= $strNewName newbase=w_base // subtract baseline strNewName=CleanupName(nameofwave(w)+"_sub",0) if (overwrite==0 && exists(strNewName)) doalert 1, strNewName+" exists. Overwrite?" if(V_flag==2) return 0 endif endif duplicate /o w $strNewName wave subtracted= $strNewName subtracted=w_sub note subtracted, note(w_base) // append note from baseline wave to output wave note note newbase, note(w_base) string s_list=WaveList("*", ";", "WIN:"+s_graph) wave w_x=XWaveRefFromTrace(s_graph, nameofwave(w)) if(WhichListItem(nameofwave(newbase),s_list)==-1) if(waveexists(w_x)) appendtograph /W=$s_graph newbase vs w_x else appendtograph /W=$s_graph newbase endif endif if(WhichListItem(nameofwave(subtracted),s_list)==-1) if(waveexists(w_x)) appendtograph /W=$s_graph subtracted vs w_x else appendtograph /W=$s_graph subtracted endif endif end