#pragma rtGlobals=1 // Use modern global access method. #pragma version=2.50 #pragma IgorVersion=6.10 //#pragma ModuleName=BaselineSpline //#pragma hide=1 #include // written by tony withers, withers@umn.edu // 2.50 // log mode to save node positions to file // can load node positions from a file // 2.40 // Added textbox reminder of how to toggle graph mode // renamed procedures for consistency // 2.30 5/16/11 // bug fix - code was choking on non-existant wave in first call to ACW_SplineClear() // added panel to change fitting options // 2.10 // call ACW_SplineClear() from ACW_SplineSubtract() // 2.0 8/6/09 // incorporated suggestions from JJ Weimer that improve functionality and clarity of code // and compatibility with 6.10 // ... and then wrecked his nice programming with my clumsy code. // 1.43b // allow refit function to switch interpolate flag when number of nodes is small to allow linear fit // 1.42 6/8/08 // set y axis to manual range to avoid crazy rescaling if spline shoots out of range. // show subtracted spectrum whilst fitting // 1.41 10/9/07 // for XY data we now interpolate directly into XY baseline // improved guesses for initial node positions for unevenly spaced XY data // 1.40 10/9/07 // fixed bug that occurred with baseline subtraction of XY data // 1.30 7/24/07 // handles XY data // baseline is waveform, but data wave need not be (though it should be reasonably closely spaced). // 1.20 7/3/07 // uses new graphwaveedit flag. now requires version 6.0.1. Static StrConstant thePackage="BaselineSpline" Static StrConstant thePackageFolder="root:Packages:BaselineSpline" Static StrConstant theProcedureFile = "BaselineSpline.ipf" Static Constant thePackageVersion = 2.5 Static Constant hasHelp = 0 // uncomment the next line to use JJ Weimer style menu definitions: //#define Weimerized #ifdef Weimerized Menu "Misc" Submenu "Packages" "Spline Baseline",/Q, ACW_SplineInit() end end Menu "Macros" ACW_SplineToggleFitMenu(),/Q, ACW_SplineToggleFitting() ACW_SplineSubtractMenu(),/Q, ACW_SplineSubtract() ACW_SplineClearMenu(),/Q, ACW_SplineClear() "Spline fit settings...",/Q, ACW_SplineSettings() "Spline fit load saved nodes...",/Q, ACW_SplineLoadNodes() end #else Menu "Analysis" Submenu "Packages" "Spline Baseline",/Q, ACW_SplineInit() end end Menu "Macros" Submenu "Spline Baseline" "Initalise...",/Q, ACW_SplineInit() "Settings...",/Q, ACW_SplineSettings() "Load saved nodes...",/Q, ACW_SplineLoadNodes() // following Macro menus appear when editing is possible ACW_SplineToggleFitMenu(), /Q, ACW_SplineToggleFitting() ACW_SplineSubtractMenu(), /Q , ACW_SplineSubtract() ACW_SplineClearMenu(),/Q, ACW_SplineClear() end end #endif // Macro menus appear when editing is possible Function/S ACW_SplineToggleFitMenu() NVAR V_edit= root:Packages:SplineFit:V_edit if (NVAR_exists(V_edit)) switch(V_edit) case -1: return "" break case 0: return "Adjust Nodes/1" break case 1: return "Adjust Nodes!"+num2char(18)+"/1" break endswitch else return "" endif end // Macro menu appears when spline curve is attached to graph Function/S ACW_SplineSubtractMenu() NVAR V_edit= root:Packages:SplineFit:V_edit if (NVAR_exists(V_edit)) if (V_edit >= 0) // V_edit is set to -1 when we're done with fitting return "Subtract Baseline" else return "" endif else return "" endif end // clear spline line menu Function/S ACW_SplineClearMenu() NVAR V_edit= root:Packages:SplineFit:V_edit if (NVAR_exists(V_edit)) if (V_edit >= 0) return "Clear Spline" else return "" endif else return "" endif end // initialize spline baseline package function ACW_SplineInit() if (strlen(WinList("*",";","WIN:1"))==0) // no graphs doalert 0, "Spline baseline requires a trace plotted in a graph window." return 0 endif // make sure the top graph is visible dowindow /F $WinName(0,1) // clear any package detritus from the last used spline graph ACW_SplineClear() // initialise (or reinitialise) the package data folder ACW_SplineResetPackageFolder() // define the globals SVAR S_Data=root:Packages:SplineFit:S_Data SVAR S_Xwave=root:Packages:SplineFit:S_Xwave SVAR S_GraphName=root:Packages:SplineFit:S_GraphName NVAR V_edit=root:Packages:SplineFit:V_edit wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals wave W_nodesX=root:Packages:SplineFit:W_nodesX wave W_nodesY=root:Packages:SplineFit:W_nodesY wave W_spline_dependency=root:Packages:SplineFit:W_spline_dependency wave W_base=root:Packages:SplineFit:W_base // define some local variables variable i, nthRange, nn=SplineFitGlobals[%nodes]-3 nn=max(1, nn) // just making sure string s_traceName variable p_low, p_high, v1, v2 variable pmin, pmax, delP string s_info variable trace_offset=0 prompt s_traceName, "Data Wave", popup, TraceNameList("",";",1+4) // what does bit 2 do? prompt nn, "Number of Nodes", popup, "4;5;6;7;8;9;10;" DoPrompt "", s_traceName, nn if (V_Flag) return 0 endif SplineFitGlobals[%nodes]=nn+3 if (stringmatch(s_traceName, "_none_")) doalert 0, "No spectra in top graph window. Inititalisation failed." return 0 endif S_Data=s_traceName S_GraphName=WinName(0, 1) string newName="SF_"+S_GraphName if (checkname(newName, 6)!=0) newName=uniquename(newName, 6, 0) endif RenameWindow $S_GraphName $newName S_GraphName=WinName(0, 1) wave data=TraceNametoWaveRef("",s_tracename) duplicate /O data root:Packages:SplineFit:W_base, root:Packages:SplineFit:W_sub wave W_base=root:Packages:SplineFit:W_base wave w_sub= root:Packages:SplineFit:W_sub variable resetNodesX=1 if(dimsize(W_nodesX, 0)==SplineFitGlobals[%nodes] && (SplineFitGlobals[%options]&2^1) ) resetNodesX=0 endif redimension/N=(SplineFitGlobals[%nodes]) W_nodesX, W_nodesY SplineFitGlobals[%isXY]=0 // find out whether data is XY S_Xwave=StringByKey("XWAVE", TraceInfo("",s_tracename,0)) if (strlen(S_Xwave)) wave Xwave=XWaveRefFromTrace("", s_tracename ) S_Xwave[0]=StringByKey("XWAVEDF", TraceInfo("",s_tracename,0)) SplineFitGlobals[%isXY]=1 // check for monotonic X wave Differentiate Xwave /D=root:Packages:SplineFit:W_diff wave W_diff=root:Packages:SplineFit:W_diff Wavestats /Q W_diff killwaves W_diff if (V_max>0 && V_min<0) doalert 0, "X wave is not monatonic!" // remove prepended SF_ from graph name RenameWindow $S_GraphName $(S_GraphName[3,inf]) return 0 endif endif // manually scale y axis getaxis /Q left setAxis left, V_min, V_max // identify trace to be corrected if (SplineFitGlobals[%options]&2^0) ACW_SplineHighlightData(1) endif // determine where to place nodes on the bottom axis if(SplineFitGlobals[%fitWithinGraph]) // keep nodes within window GetAxis/Q bottom if (SplineFitGlobals[%isXY]) findlevel /Q/P Xwave, V_max if (V_flag) v1=numpnts(Xwave) else v1=V_LevelX endif findlevel /Q/P Xwave, V_min if (V_flag) v2=0 else v2=V_LevelX endif pmax=max(v1,v2) pmin=min(v1,v2) else pmax=floor(max( x2pnt(data, V_max), x2pnt(data,V_min) ) ) -1 pmin=ceil (min( x2pnt(data,V_max), x2pnt(data,V_min) ) ) +1 endif else // spead nodes across entire range of wave and autoscale bottom axis pmin=0 pmax=numpnts(data)-1 // autoscale bottom axis before adding spline nodes // baseline is subtracted from entire wave, so show the whole range. getaxis /Q bottom if (v_min>v_max) setaxis /r/a bottom else setaxis /A bottom endif endif delP=(pmax-pmin)/(SplineFitGlobals[%nodes]-1) // initialise node positions. set nodes to follow roughly the data if (SplineFitGlobals[%isXY]) nthRange=(Xwave[pmax]-Xwave[pmin])/(SplineFitGlobals[%nodes]-1) if (resetNodesX) W_nodesX=Xwave[pmin]+p*nthRange endif else nthRange=(pnt2x(data, pmax)-pnt2x(data, pmin))/(SplineFitGlobals[%nodes]-1) if (resetNodesX) W_nodesX=pnt2x(data, pmin)+p*nthRange endif endif for (i=0;i<(SplineFitGlobals[%nodes]);i+=1) if (SplineFitGlobals[%isXY]) // necessary for unevenly spaced data findlevel /Q/P Xwave, W_nodesX[i]-nthRange/24 if (V_flag) p_low=pmin else p_low= V_LevelX endif findlevel /Q/P Xwave, W_nodesX[i]+nthRange/24 if (V_flag) p_high=pmax else p_high= V_LevelX endif else p_low= max(pmin, pmin+i*delP - delP/24 ) p_high= min(pmax, pmin+i*delP + delP/24 ) endif wavestats /Q/M=1/R=[p_low , p_high] /Z data W_nodesY[i]=V_avg // this handles a few NANs endfor // if data are offset, then apply offsets to baseline and nodes s_info=traceinfo("",s_tracename,0) trace_offset=GetNumFromModifyStr(s_info,"offset","{",1) AppendToGraph W_spline_dependency // need to have this on graph to force update while in drawing mode ModifyGraph hideTrace(W_spline_dependency)=1 appendtograph W_nodesY vs W_nodesX ModifyGraph mode(W_nodesY)=3,marker(W_nodesY)=11,rgb(W_nodesY)=(0,39168,0) ModifyGraph offset(W_nodesY)={0,trace_offset} ACW_SplineUpdate(W_nodesX) if (SplineFitGlobals[%isXY]) appendtograph W_base vs Xwave if (SplineFitGlobals[%showSub]) appendtograph W_sub vs Xwave endif else appendtograph W_base if (SplineFitGlobals[%showSub]) appendtograph W_sub endif endif ModifyGraph offset(W_base)={0,trace_offset} ModifyGraph rgb(W_base)=(0,0,52224) modifygraph live(W_base)=1 if (SplineFitGlobals[%showSub]) ModifyGraph rgb(W_sub)=(0,0,0) ModifyGraph zero(left)=1 W_sub=data-W_base endif // set a dependency to trigger interpolation AND update graph when we adjust a node position W_spline_dependency:=ACW_SplineUpdate(root:Packages:SplineFit:W_nodesY) ReorderTraces $"W_nodesY",{$"W_base"} V_edit = 0 ACW_SplineToggleFitting() if(SplineFitGlobals[%options]&2^2) //verbose mode print "Spline fit initialized with data wave "+GetWavesDataFolder(data, 2 ) endif return 0 end // initialise (or reinitialise) the package data folder Function ACW_SplineResetPackageFolder() NewDataFolder /O root:Packages NewDataFolder /O root:Packages:SplineFit string /G root:Packages:SplineFit:S_GraphName="" string /G root:Packages:SplineFit:S_Data="" string /G root:Packages:SplineFit:S_Xwave="" variable /G root:Packages:SplineFit:V_edit=0 wave W_nodesX=root:Packages:SplineFit:W_nodesX if (WaveExists(W_nodesX)==0) make /O/n=(1) root:Packages:SplineFit:W_nodesX, root:Packages:SplineFit:W_nodesY endif make /O/n=1 root:Packages:SplineFit:W_spline_dependency make/O/n=1 root:Packages:SplineFit:W_base // create a wave to store some global variables if (exists("root:Packages:SplineFit:SplineFitGlobals")==1) wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals // for backward compatibility with older versions of this procedure redimension /N=10 SplineFitGlobals setdimlabel 0, 5, isXY, SplineFitGlobals setdimlabel 0, 6, showSub, SplineFitGlobals setdimlabel 0, 7, nodes, SplineFitGlobals setdimlabel 0, 8, fitWithinGraph, SplineFitGlobals setdimlabel 0, 9, options, SplineFitGlobals else make /o/n=10 root:Packages:SplineFit:SplineFitGlobals=nan wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals setdimlabel 0, 0, null, SplineFitGlobals setdimlabel 0, 1, flagE, SplineFitGlobals setdimlabel 0, 2, flagF, SplineFitGlobals setdimlabel 0, 3, flagJ, SplineFitGlobals setdimlabel 0, 4, flagT, SplineFitGlobals setdimlabel 0, 5, isXY, SplineFitGlobals setdimlabel 0, 6, showSub, SplineFitGlobals setdimlabel 0, 7, nodes, SplineFitGlobals setdimlabel 0, 8, fitWithinGraph, SplineFitGlobals setdimlabel 0, 9, options, SplineFitGlobals SplineFitGlobals[%flagE]=2 SplineFitGlobals[%flagF]=1 SplineFitGlobals[%flagJ]=1 SplineFitGlobals[%flagT]=2 SplineFitGlobals[%showSub]=1 SplineFitGlobals[%nodes]=5 SplineFitGlobals[%fitWithinGraph]=1 SplineFitGlobals[%options]=5 endif end // dependency function to define the spline curve function ACW_SplineUpdate(w) wave w wave g=root:Packages:SplineFit:SplineFitGlobals wave W_nodesX=root:Packages:SplineFit:W_nodesX wave W_nodesY=root:Packages:SplineFit:W_nodesY wave W_base=root:Packages:SplineFit:W_base SVAR S_Xwave=root:Packages:SplineFit:S_Xwave // check for small number of points variable SplineType=g[%flagT] if (numpnts(W_nodesX)<4) SplineType=1 endif if (g[%isXY]) Interpolate2 /E=(g[%flagE]) /F=(g[%flagF]) /J=(g[%flagJ]) /T=(SplineType) /I=3 /X=$S_Xwave /Y=W_base W_nodesX, W_nodesY else Interpolate2 /E=(g[%flagE]) /F=(g[%flagF]) /J=(g[%flagJ]) /T=(SplineType) /I=3 /Y=W_base W_nodesX, W_nodesY endif if (g[%showSub]) SVAR s_data=root:Packages:SplineFit:S_Data wave data=TraceNametoWaveRef("",S_Data) wave w_sub= root:Packages:SplineFit:w_sub w_sub=data-w_base endif return nan end // function to subtract the spline curve function ACW_SplineSubtract() SVAR s_data=root:Packages:SplineFit:S_Data NVAR V_edit=root:Packages:SplineFit:V_edit wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals wave W_base=root:Packages:SplineFit:W_base wave data=TraceNametoWaveRef("",S_Data) wave W_nodesX=root:Packages:SplineFit:W_nodesX wave W_nodesY=root:Packages:SplineFit:W_nodesY string strSubtracted, strBaseline, strNodes strSubtracted=CleanupName( nameofwave(data)+"_SplineBLCorrected",0) strBaseline=CleanupName( nameofwave(data)+"_SplineBL",0) strNodes=CleanupName( nameofwave(data)+"_SplineNodes",0) if (exists(strSubtracted)) doalert 1, strSubtracted+" exists. Overwrite?" if(V_flag==2) print "Spline baseline subtraction aborted" return 0 endif endif duplicate /o data $strSubtracted wave nob=$strSubtracted if (exists(strBaseline)) doalert 1, strBaseline+" exists. Overwrite?" if(V_flag==2) print "Spline baseline subtraction aborted" return 0 endif endif duplicate /o W_base $strBaseline if (SplineFitGlobals[%options]&2^3) if (exists(strNodes)) doalert 1, strNodes+" exists. Overwrite?" if(V_flag==2) print "Spline baseline subtraction aborted" return 0 endif endif duplicate /o W_nodesX $strNodes wave nd=$strNodes redimension /N=(-1, 2) nd nd[][0]=W_nodesX[p] nd[][1]=W_nodesY[p] if(SplineFitGlobals[%options]&2^2) //verbose mode print "Spline fit saved node positions in wave "+GetWavesDataFolder(nd, 2 ) endif endif wave bl=$strBaseline nob=data-bl if(SplineFitGlobals[%options]&2^2) //verbose mode print "Spline fit created baseline wave "+GetWavesDataFolder(bl, 2 ) print "Spline fit created baseline subtracted wave "+GetWavesDataFolder(nob, 2 ) endif removefromgraph /Z $strSubtracted, $strBaseline, W_base, W_nodesY, w_sub ACW_SplineClear() // find out whether data is XY string s_Xwave=StringByKey("XWAVE", TraceInfo("",NameOfWave(data),0)) if (strlen(s_Xwave)) // XY data wave Xwave=XWaveRefFromTrace("", NameOfWave(data) ) appendtograph nob, bl vs Xwave else appendtograph nob, bl endif // would be nice to put some of this in the history... ModifyGraph rgb($nameofwave(bl))=(0,65280,0) ModifyGraph rgb($nameofwave(nob))=(0,0,0) V_edit=-1 BuildMenu "macros" return 1 end // function to toggle between normal graph and draw mode function ACW_SplineToggleFitting() NVAR V_edit=root:Packages:SplineFit:V_edit variable isMac=abs(cmpstr(IgorInfo(2)[0], "W")) string msg if (V_edit) GraphNormal ModifyGraph mode(W_nodesY)=2 V_edit=0 else ModifyGraph mode(W_nodesY)=3 GraphWaveEdit /T=1 /M $"W_nodesY" V_edit=1 endif sprintf msg, "\Z14\\K(32768,65280,0)%s-1 to %s node editing", selectstring(isMac, "CTRL", "CMD"), selectstring(V_edit, "resume", "pause") TextBox/C/N=SplineFitTextBox/F=0/B=1/A=LT/X=5.00/Y=5.00 msg buildmenu "macros" return 1 end // function to clear the spline curve function ACW_SplineClear() NVAR /Z V_edit=root:Packages:SplineFit:V_edit SVAR S_GraphName=root:Packages:SplineFit:S_GraphName SVAR /Z S_Data=root:Packages:SplineFit:S_Data wave W_spline_dependency=root:Packages:SplineFit:W_spline_dependency wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals string S_topWin=WinName(0,1) if ( NVAR_Exists(V_edit) ) V_edit = -1 endif if (waveexists(W_spline_dependency)) W_spline_dependency=NaN endif if (SVAR_Exists(S_GraphName)&&strlen(S_GraphName)) doWindow /F $S_GraphName else return 0 endif GraphNormal RemoveFromGraph /Z W_spline_dependency,W_base,W_nodesY, w_sub TextBox/K/N=SplineFitTextBox // undo highlighting of data if (SplineFitGlobals[%options]&2^0) ACW_SplineHighlightData(0) endif // remove prepended SF_ from graph name if (WinType(S_GraphName)) string newName=S_GraphName[3,inf] if (checkname(newName, 6)!=0) // in case another window stole the name newName=uniquename(newName, 6, 0) endif RenameWindow $S_GraphName $newName endif S_Data="" S_GraphName="" DoWindow /F $S_topWin return 1 end Function ACW_SplineCheckboxes(ctrlName,checked) : CheckBoxControl String ctrlName Variable checked wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals SVAR S_Data=root:Packages:SplineFit:S_Data SVAR S_GraphName =root:Packages:SplineFit:S_GraphName strswitch(ctrlName) case "checkGraphWidth": SplineFitGlobals[%fitWithinGraph]=checked return 1 case "checkShowSub": SplineFitGlobals[%showSub]=checked if (SVAR_exists(S_GraphName)) dowindow $S_GraphName if (V_flag==1) if (checked) checkdisplayed /W=$S_GraphName w_sub if (V_flag<1) wave w_sub= root:Packages:SplineFit:W_sub appendtograph /W=$S_GraphName W_sub ModifyGraph /W=$S_GraphName rgb(W_sub)=(0,0,0) ModifyGraph /W=$S_GraphName zero(left)=1 endif else dowindow $S_GraphName if (V_flag==1) removefromgraph /W=$S_GraphName /Z w_sub endif endif endif endif return 1 case "checkHighlightData": SplineFitGlobals[%options]=SplineFitGlobals[%options]%^2^0 // toggle 1st bit ACW_SplineHighlightData(checked) // update graph if neccessary return 1 case "checkRememberNodes": SplineFitGlobals[%options]=SplineFitGlobals[%options]%^2^1 return 1 case "checkVerbose": SplineFitGlobals[%options]=SplineFitGlobals[%options]%^2^2 return 1 case "checkSaveNodes": SplineFitGlobals[%options]=SplineFitGlobals[%options]%^2^3 return 1 endswitch return 0 End Function ACW_SplineButtons(ctrlName) String ctrlName DisplayHelpTopic "interpolate2" End Function ACW_SplinePopMenu(ctrlName,popNum,popStr) String ctrlName Variable popNum String popStr wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals strswitch(ctrlName) case "popE": SplineFitGlobals[%flagE]=popNum return 1 case "popJ": SplineFitGlobals[%flagJ]=popNum-1 return 1 case "popT": SplineFitGlobals[%flagT]=popNum return 1 endswitch return 0 End //Create panel to edit settings Function ACW_SplineSettings() wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals if (waveexists(SplineFitGlobals)==0) ACW_SplineResetPackageFolder() wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals endif DoWindow/K SplineFitPanel NewPanel /N=SplineFitPanel /K=1/W=(549,75,854,300) as "Spline Fit Parameters" ModifyPanel fixedSize=1 SetDrawLayer ProgBack GroupBox groupFlags,pos={20,19},size={247,51},title="Interpolate2 flags" PopupMenu popE,pos={31,42},size={46,21}, title="/E", proc=ACW_SplinePopMenu PopupMenu popE,value="1;2", mode=(SplineFitGlobals[%flagE]), popvalue=num2str(SplineFitGlobals[%flagE]) SetVariable setvarFlagF,pos={90,44},size={45,16},bodyWidth=30,title="/F" SetVariable setvarFlagF,value= SplineFitGlobals[%flagF], limits={0,inf,0.1} PopupMenu popJ,pos={150,42},size={44,21},title="/J", proc=ACW_SplinePopMenu PopupMenu popJ,value="0;1;2", mode=(SplineFitGlobals[%flagJ]+1), popvalue=num2str(SplineFitGlobals[%flagJ]) PopupMenu popT,pos={210,42},size={46,21},title="/T", proc=ACW_SplinePopMenu PopupMenu popT,value="1;2;3", mode=(SplineFitGlobals[%flagT]), popvalue=num2str(SplineFitGlobals[%flagT]) SetVariable setvarNodes,pos={38,82},size={63,16},bodyWidth=30,title="nodes" SetVariable setvarNodes,value= SplineFitGlobals[%nodes] Button buttonHelp,pos={153,79},size={100,20},proc=ACW_SplineButtons,title="Interpolate2 help..." CheckBox checkGraphWidth,pos={153,142},size={89,14},proc=ACW_SplineCheckboxes,title="Fit within graph" CheckBox checkGraphWidth,value= 1 CheckBox checkShowSub,pos={38,111},size={100,14},proc=ACW_SplineCheckboxes,title="Show subtraction" CheckBox checkShowSub,value= SplineFitGlobals[%showSub] CheckBox checkHighlightData,pos={153,111},size={119,14},proc=ACW_SplineCheckboxes,title="Highlight selected data" CheckBox checkHighlightData,value= (SplineFitGlobals[%options]&2^0) CheckBox checkVerbose,pos={38,142},size={88,14},proc=ACW_SplineCheckboxes,title="Write to history" CheckBox checkVerbose,value= SplineFitGlobals[%options]&2^2 CheckBox checkRememberNodes,pos={38,173},size={140,14},proc=ACW_SplineCheckboxes,title="Remember node positions" CheckBox checkRememberNodes,value= SplineFitGlobals[%options]&2^1 CheckBox checkSaveNodes,pos={38,204},size={140,14},proc=ACW_SplineCheckboxes,title="Save node positions" CheckBox checkSaveNodes,value= SplineFitGlobals[%options]&2^3 //pauseforuser SplineFitPanel return 1 End // function to highlight selected data wave in graph window // increases line or marker size by 1 to highlight Function ACW_SplineHighlightData(On) variable On // 1 to highlight, 0 to undo SVAR S_Data=root:Packages:SplineFit:S_Data SVAR S_GraphName =root:Packages:SplineFit:S_GraphName if (!(SVAR_Exists(S_GraphName)&&strlen(S_GraphName))) return 0 endif if (!(SVAR_Exists(S_Data)&&strlen(S_Data))) return 0 endif dowindow $S_GraphName if (V_flag!=1) return 0 endif string S_trace=TraceInfo(S_GraphName, S_Data, 0) variable mode=GetNumFromModifyStr(S_trace,"mode","",0) variable size if (mode==3) //data is plotted with markers size=GetNumFromModifyStr(S_trace,"msize","",0) if (size==0) // don't mess with auto sized markers return 0 endif if (On) ModifyGraph/Z /W=$S_GraphName msize($S_Data)=size+1 else ModifyGraph/Z /W=$S_GraphName msize($S_Data)=size-1 endif else size=GetNumFromModifyStr(S_trace,"lSize","",0) if (On) ModifyGraph/Z /W=$S_GraphName lSize($S_Data)=size+1 else ModifyGraph/Z /W=$S_GraphName lSize($S_Data)=size-1 endif endif return 1 End Function ACW_SplineLoadNodes() wave /Z SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals if (waveexists(SplineFitGlobals)==0) ACW_SplineResetPackageFolder() wave SplineFitGlobals=root:Packages:SplineFit:SplineFitGlobals endif string str_NodeWave variable LoadY prompt str_NodeWave, "Select saved nodes", popup, wavelist("*",";","DIMS:2") prompt LoadY, "", popup, "Load X positions only;Load X and Y positions;" DoPrompt "", str_NodeWave, LoadY if (V_Flag) return 0 endif wave w_nodes=$str_NodeWave loadY-=1 wave W_nodesX=root:Packages:SplineFit:W_nodesX wave W_nodesY=root:Packages:SplineFit:W_nodesY redimension /N=(dimsize(w_nodes, 0)), W_nodesX redimension /N=(dimsize(w_nodes, 0)), W_nodesY W_nodesX=w_nodes[p][0] SplineFitGlobals[%nodes]=numpnts(W_nodesX) if (LoadY) W_nodesY=w_nodes[p][1] return 1 endif SVAR s_data=root:Packages:SplineFit:S_Data wave /Z data=TraceNametoWaveRef("",S_Data) if (waveexists(data)==0) return 0 endif // figure out Y values from data // average data over range 5 points either side of X position variable i, p_low, p_high for (i=0;i<(SplineFitGlobals[%nodes]);i+=1) if (SplineFitGlobals[%isXY]) // necessary for unevenly spaced data SVAR S_Xwave=root:Packages:SplineFit:S_Xwave wave xwave=$S_Xwave findlevel /Q/P Xwave, W_nodesX[i] if (V_flag) return 0 else p_low= V_LevelX-5 p_high= V_LevelX+5 endif else p_low= x2pnt(data, W_nodesX[i])-5 p_high= x2pnt(data, W_nodesX[i])+5 endif wavestats /Q/M=1/R=[p_low , p_high] /Z data W_nodesY[i]=V_avg // this handles a few NANs endfor return 1 end