#pragma rtGlobals=1 // Use modern global access method. #pragma Version=2.20 #pragma IgorVersion=6.0 ////////////////////////////////////////////// // Igor conversion: 03 FEB 06 SRK // Revision: 03 MAR 06 SRK // // Program uses Lake's iterative technique, J. A. Lake, Acta Cryst. 23 (1967) 191-4. // to DESMEAR Infinite slit smeared USANS DATA. // // TO SEE DESCRIPTION, CHECK COMPUTER SOFTWARE LOGBOOK, P13,41-46, 50 // J. BARKER, August, 2001 // Switches from fast to slow convergence near target chi JGB 2/2003 // // steps are: // load // mask // extrapolate (find the power law of the desmeared set = smeared -1) // smooth (optional) // desmear based on dQv and chi^2 target // save result // ///////// // Waves produced at each step: (Q/I/S with the following extensions) // // Load: Uses -> nothing (Kills old waves) // Produces -> "_exp" and "_exp_orig" // // Mask: Uses -> "_exp" // Produces -> "_msk" // // Extrapolate: Uses -> nothing // Produces -> nothing // // Smooth: Uses -> "_smth" OR "_msk" OR "_exp" (in that order) // Produces -> "_smth" // // Desmear: Uses -> "_smth" OR "_msk" OR "_exp" (in that order) // Produces -> "_dsm" // //////// ///***** TO FIX ******* // - ? power law + background extrapolation (only useful for X-ray data...) // // see commented code lines for Igor 4 or Igor 5 // - there are only a few options and calls that are not Igor 4 compatible. // Igor 4 routines are currently used. //////////////////////////////////////////////////////////////////////// // main entry routine Proc Desmear() String USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder //check for the correct data folder, initialize if necessary // if(DataFolderExists(USANSFolder+":DSM") == 0) Execute "Init_Desmearing()" endif SetDataFolder $(USANSFolder+":DSM") //always initialize these global variables gStr1 = "" gStr2 = "" gIterStr = "" SetDataFolder root: DoWindow/F Desmear_Graph if(V_flag==0) Execute "Desmear_Graph()" endif End Proc Init_Desmearing() String USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder //set up the folder(s) needed NewDataFolder/O $(USANSFolder+":DSM") NewDataFolder/O $(USANSFolder+":myGlobals") //in case it wasn't created elsewhere SetDataFolder $(USANSFolder+":DSM") String/G gCurFile="" Variable/G gMaxFastIter = 100 //max number of iter in Fast convergence Variable/G gMaxSlowIter = 10000 Variable/G gNptsExtrap = 10 //points for high q extrapolation Variable/G gChi2Target = 1 //chi^2 target Variable/G gPowerM = -4 Variable/G gDqv = 0.117 //2005 measured slit height - see John Variable/G gNq = 1 Variable/G gS = 0 // global varaible for Midpnt() Variable/G gSmoothFac=0.03 Variable/G gChi2Final = 0 //chi^2 final Variable/G gIterations = 0 //total number of iterations String/G gStr1 = "" //information strings String/G gStr2 = "" String/G gIterStr = "" Variable/G gChi2Smooth = 0 Variable/G gFreshMask=1 SetDataFolder root: End //////////// Lake desmearing routines // Smears guess Y --> YS using weighting array Function DSM_Smear(Y_wave,Ys,NQ,FW) Wave Y_wave,Ys Variable nq Wave FW Variable ii,jj,summ for(ii=0;ii NN-1 since Igor indexes from 0! (Q_exp[NN] DNE!) FW[ii][NN-1] = -DU(ii,NN-2)*Q_exp[NN-2]/(Q_exp[NN-1]-Q_exp[NN-2]) FW[ii][NN-1] += (1.0/(Q_exp[NN-1]-Q_exp[NN-2]))*IG(ii,NN-2) FW[ii][NN-1] *= (1.0/dqv) FW[ii][NN-1] += R_wave[ii] // Printf "FW[%d][%d] = %g\r",ii,NN-1,FW[ii][NN-1] endfor // // special case: I=J=N FW[NN-1][NN-1] = R_wave[NN-1] // Return (0) End //// Function Integrand_dsm(u,qi,m) Variable u,qi,m Variable integrand Integrand = (u^2+qi^2)^(m/2) return integrand end /// Function DU(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Wave Q_exp = $(USANSFolder+":DSM:Q_exp") Variable DU // Wave DU_save=root:DSM:DU_save If (ii == jj) DU = sqrt(Q_exp[jj+1]^2-Q_exp[ii]^2) Else DU = sqrt(Q_exp[jj+1]^2-Q_exp[ii]^2) - sqrt(Q_exp[jj]^2-Q_exp[ii]^2) EndIf // DU_save[ii][jj] = DU Return DU End Function IG(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Wave Q_exp=$(USANSFolder+":DSM:Q_exp") Variable IG,UL,UU // WAVE IG_save = root:DSM:IG_save If (ii == jj) UL=0.0 Else UL=sqrt(Q_exp[jj]^2-Q_exp[ii]^2) EndIf UU=sqrt(Q_exp[jj+1]^2-Q_exp[ii]^2) //in FORTRAN log = natural log.... IG = UU*Q_exp[jj+1]+Q_exp[ii]^2*ln(UU+Q_exp[jj+1]) IG -= UL*Q_exp[jj] IG -= Q_exp[ii]^2*ln(UL+Q_exp[jj]) IG *= 0.5 // IG_save[ii][jj] = IG Return IG End // Function FF(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Variable FF NVAR dqv = $(USANSFolder+":DSM:gDqv") FF = (1.0/dqv)*(0.5+HH(ii,jj)) Return FF End // Function GG(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Variable GG NVAR dqv = $(USANSFolder+":DSM:gDqv") GG = (1.0/dqv)*(0.5-HH(ii,jj)) Return GG End // Function HH(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Wave Q_exp=$(USANSFolder+":DSM:Q_exp") Variable HH HH = 0.5*(Q_exp[jj+1]+Q_exp[jj])/(Q_exp[jj+1]-Q_exp[jj]) HH -= (1.0/(Q_exp[jj+1]-Q_exp[jj]))*(CC(ii,jj+1)-CC(ii,jj)) return HH End // // Function CC(ii,jj) Variable ii,jj SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder wave Q_exp = $(USANSFolder+":DSM:Q_exp") Variable CC If (ii == jj) CC = 0.0 Else CC = (Q_exp[jj]-Q_exp[ii])^0.5 EndIf Return CC End // QROMO is a gerneric NR routine that takes function arguments // Call Qromo(Integrand,lower,dqv,Q_exp(N),m,SS,Midpnt) // -- here, it is always called with Integrand and Midpnt as the functions // -- so rewrite in a simpler way.... // // SS is the returned value? // H_wave, S_wave (original names H,S) // // modified using c-version in NR (pg 143) Function QROMO(A,B,qi,m) Variable A,B,qi,m SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Variable EPS,JMAX,JMAXP,KM,K EPS=1.E-6 JMAX=14 KM=4 K=KM+1 Make/O/D/N=(JMAX) $(USANSFolder+":DSM:S_wave") Make/O/D/N=(JMAX+1) $(USANSFolder+":DSM:H_wave") wave S_wave=$(USANSFolder+":DSM:S_wave") wave H_wave=$(USANSFolder+":DSM:H_wave") S_wave=0 H_wave=0 H_Wave[0] = 1 variable jj,SS,DSS for(jj=0;jj=KM) //after 1st 5 points calculated POLINT(H_wave,S_wave,jj-KM,KM,0.0,SS,DSS) //ss, dss returned IF (ABS(DSS) < EPS*ABS(SS)) RETURN ss endif ENDIF // S_wave[jj+1]=S_wave[jj] H_wave[jj+1]=H_wave[jj]/9. endfor DoAlert 0,"Too many steps in QROMO" return 1 //error if you get here END // // see NR pg 109 // - Given input arrays xa[1..n] and ya[1..n], and a given value x // return a value y and an error estimate dy. if P(x) is the polynomial of // degree N-1 such that P(xai) = yai, then the returned value y=P(x) // // arrays XA[] and YA[] are passed in with an offset of the index // of where to start the interpolation Function POLINT(XA,YA,offset,N,X,Y,DY) Wave XA,YA Variable offset,N,X,&Y,&DY Variable ii,mm,nmax,ns,dif,den,ho,hp,wi,dift SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder NMAX=10 Make/O/D/N=(NMAX) $(USANSFolder+":DSM:Ci"),$(USANSFolder+":DSM:Di") wave Ci = $(USANSFolder+":DSM:Ci") wave Di = $(USANSFolder+":DSM:Di") NS=1 DIF=ABS(X-XA[0]) for(ii=0;ii -20"} //(set background to zero and hold fixed) CurveFit/H="100" Power kwCWave=P_coef iw[(num-1-nend),(num-1)] /X=qw /W=sw /D extr_hqi=P_coef[0]+P_coef[1]*extr_hqq^P_coef[2] // for the case of data with a background // Make/O/D P_coef={0,1,-4} //input // //(set background to iw[num-1], let it be a free parameter // P_coef[0] = iw[num-1] // CurveFit Power kwCWave=P_coef iw[(num-1-nend),(num-1)] /X=qw /W=sw /D // extr_hqi=P_coef[0]+P_coef[1]*extr_hqq^P_coef[2] Printf "Smeared Power law exponent = %g\r",P_coef[2] Printf "**** For Desmearing, use a Power law exponent of %5.1f\r",P_coef[2]-1 retVal = P_coef[2]-1 SetDataFolder root: return(retVal) End Function DSM_Guinier_Fit(w,x) //: FitFunc Wave w Variable x //fit data to I(q) = A*exp(B*q^2) // (B will be negative) //two parameters Variable a,b,ans a=w[0] b=w[1] ans = a*exp(b*x*x) return(ans) End Proc Desmear_Graph() String USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder PauseUpdate; Silent 1 // building window... Display /W=(5,44,408,558) /K=1 ModifyGraph cbRGB=(51664,44236,58982) DoWindow/C Desmear_Graph ControlBar 160 // break into tabs TabControl DSM_Tab,pos={5,3},size={392,128},proc=DSM_TabProc TabControl DSM_Tab,labelBack=(49151,49152,65535),tabLabel(0)="Load" TabControl DSM_Tab,tabLabel(1)="Mask",tabLabel(2)="Extrapolate" TabControl DSM_Tab,tabLabel(3)="Smooth",tabLabel(4)="Desmear",value= 0 //always visible - revert and save //maybe the wrong place here? Button DSMControlA,pos={225,135},size={80,20},proc=DSM_RevertButtonProc,title="Revert" Button DSMControlA,help={"Revert the smeared data to its original state and start over"} Button DSMControlB,pos={325,135},size={50,20},proc=DSM_SaveButtonProc,title="Save" Button DSMControlB,help={"Save the desmeared data set"} Button DSMControlC,pos={25,135},size={50,20},proc=DSM_HelpButtonProc,title="Help" Button DSMControlC,help={"Show the help file for desmearing"} // add the controls to each tab ---- all names start with "DSMControl_" //tab(0) Load - initially visible Button DSMControl_0a,pos={23,39},size={80,20},proc=DSM_LoadButtonProc,title="Load Data" Button DSMControl_0a,help={"Load slit-smeared USANS data = \".cor\" files"} CheckBox DSMControl_0b,pos={26,74},size={80,14},proc=DSM_LoadCheckProc,title="Log Axes?" CheckBox DSMControl_0b,help={"Toggle Log/Lin Q display"},value= 1 TitleBox DSMControl_0c,pos={120,37},size={104,19},font="Courier",fSize=10 TitleBox DSMControl_0c,variable= $(USANSFolder+":DSM:gStr1") //second message string not used currently // TitleBox DSMControl_0d,pos={120,57},size={104,19},font="Courier",fSize=10 // TitleBox DSMControl_0d,variable= root:DSM:gStr2 //tab(1) Mask Button DSMControl_1a,pos={20,35},size={90,20},proc=DSM_MyMaskProc,title="Mask Point" //bMask Button DSMControl_1a,help={"Toggles the masking of the selected data point"} Button DSMControl_1a,disable=1 Button DSMControl_1b,pos={20,65},size={140,20},proc=DSM_MaskGTCursor,title="Mask Q >= Cursor" //bMask Button DSMControl_1b,help={"Toggles the masking of all q-values GREATER than the current cursor location"} Button DSMControl_1b,disable=1 Button DSMControl_1c,pos={20,95},size={140,20},proc=DSM_MaskLTCursor,title="Mask Q <= Cursor" //bMask Button DSMControl_1c,help={"Toggles the masking of all q-values LESS than the current cursor location"} Button DSMControl_1c,disable=1 Button DSMControl_1d,pos={180,35},size={90,20},proc=DSM_ClearMaskProc,title="Clear Mask" //bMask Button DSMControl_1d,help={"Clears all mask points"} Button DSMControl_1d,disable=1 // Button DSMControl_1b,pos={144,66},size={110,20},proc=DSM_MaskDoneButton,title="Done Masking" // Button DSMControl_1b,disable=1 //tab(2) Extrapolate Button DSMControl_2a,pos={31,42},size={90,20},proc=DSM_ExtrapolateButtonProc,title="Extrapolate" Button DSMControl_2a,help={"Extrapolate the high-q region with a power-law"} Button DSMControl_2a,disable=1 SetVariable DSMControl_2b,pos={31,70},size={100,15},title="# of points" SetVariable DSMControl_2b,help={"Set the number of points for the power-law extrapolation"} SetVariable DSMControl_2b,limits={5,100,1},value= $(USANSFolder+":DSM:gNptsExtrap") SetVariable DSMControl_2b,disable=1 CheckBox DSMControl_2c,pos={157,45},size={105,14},proc=DSM_ExtrapolationCheckProc,title="Show Extrapolation" CheckBox DSMControl_2c,help={"Show or hide the high q extrapolation"},value= 1 CheckBox DSMControl_2c,disable=1 SetVariable DSMControl_2d,pos={31,96},size={150,15},title="Power Law Exponent" SetVariable DSMControl_2d,help={"Power Law exponent from the fit = the DESMEARED slope - override as needed"} SetVariable DSMControl_2d format="%5.2f" SetVariable DSMControl_2d,limits={-inf,inf,0},value= $(USANSFolder+":DSM:gPowerM") SetVariable DSMControl_2d,disable=1 //tab(3) Smooth Button DSMControl_3a,pos={34,97},size={70,20},proc=DSM_SmoothButtonProc,title="Smooth" Button DSMControl_3a,disable=1 //BoxCheck CheckBox DSMControl_3b,pos={34,39},size={35,14},title="Box",value= 1 CheckBox DSMControl_3b,help={"Use a single pass of 3-point box smoothing"} CheckBox DSMControl_3b,disable=1 //SSCheck CheckBox DSMControl_3c,pos={34,60},size={45,14},title="Spline",value= 0 CheckBox DSMControl_3c,help={"Use a single pass of a smoothing spline"} CheckBox DSMControl_3c,disable=1 //extendCheck CheckBox DSMControl_3d,pos={268,60},size={71,14},title="Extend Data" CheckBox DSMControl_3d,help={"extends the data at both low q and high q to avoid end effects in smoothing"} CheckBox DSMControl_3d,value= 0 CheckBox DSMControl_3d,disable=1 Button DSMControl_3e,pos={125,97},size={90,20},proc=DSM_SmoothUndoButtonProc,title="Start Over" Button DSMControl_3e,help={"Start the smoothing over again without needing to re-mask the data set"} Button DSMControl_3e,disable=1 SetVariable DSMControl_3f,pos={94,60},size={150,15},title="Smoothing factor" SetVariable DSMControl_3f,help={"Smoothing factor for the smoothing spline"} SetVariable DSMControl_3f format="%5.4f" SetVariable DSMControl_3f,limits={0.01,2,0.01},value= $(USANSFolder+":DSM:gSmoothFac") SetVariable DSMControl_3f,disable=1 CheckBox DSMControl_3g,pos={268,39},size={90,14},title="Log-scale smoothing?" CheckBox DSMControl_3g,help={"Use log-scaled intensity during smoothing (reverts to linear if negative intensity points found)"} CheckBox DSMControl_3g,value=0 CheckBox DSMControl_3g,disable=1 ValDisplay DSMControl_3h pos={235,97},title="Chi^2",size={80,20},value=root:Packages:NIST:USANS:DSM:gChi2Smooth ValDisplay DSMControl_3h,help={"This is the Chi^2 value for the smoothed data vs experimental data"} ValDisplay DSMControl_3h,disable=1 //tab(4) Desmear Button DSMControl_4a,pos={35,93},size={80,20},proc=DSM_DesmearButtonProc,title="Desmear" Button DSMControl_4a,help={"Do the desmearing - the result is in I_dsm"} Button DSMControl_4a,disable=1 SetVariable DSMControl_4b,pos={35,63},size={120,15},title="Chi^2 target" SetVariable DSMControl_4b,help={"Set the targetchi^2 for convergence (recommend chi^2=1)"} SetVariable DSMControl_4b,limits={0,inf,0.1},value= $(USANSFolder+":DSM:gChi2Target") SetVariable DSMControl_4b,disable=1 SetVariable DSMControl_4c,pos={35,35},size={80,15},title="dQv" SetVariable DSMControl_4c,help={"Slit height as read in from the data file. 0.117 is the NIST value, override if necessary"} SetVariable DSMControl_4c,limits={-inf,inf,0},value= $(USANSFolder+":DSM:gDqv") SetVariable DSMControl_4c,disable=1 TitleBox DSMControl_4d,pos={160,37},size={104,19},font="Courier",fSize=10 TitleBox DSMControl_4d,variable= $(USANSFolder+":DSM:gIterStr") TitleBox DSMControl_4d,disable=1 SetDataFolder root: EndMacro // function to control the drawing of buttons in the TabControl on the main panel // Naming scheme for the buttons MUST be strictly adhered to... else buttons will // appear in odd places... // all buttons are named DSMControl_NA where N is the tab number and A is the letter denoting // the button's position on that particular tab. // in this way, buttons will always be drawn correctly :-) // Function DSM_TabProc(ctrlName,tab) //: TabControl String ctrlName Variable tab String ctrlList = ControlNameList("",";"),item="",nameStr="" Variable num = ItemsinList(ctrlList,";"),ii,onTab for(ii=0;ii= 3.0e-5 (1/A), below this USANS is not reliable. NumBad = RemoveBadQPoints(Q_exp,I_exp,S_exp,0) SVAR str1 = $(USANSFolder+":DSM:gStr1") sprintf str1,"%d negative q-values were removed",numBad // don't trim off any positive q-values // val = 3e-5 //lowest "good" q-value from USANS // NumBad = RemoveBadQPoints(Q_exp,I_exp,S_exp,val-1e-8) // SVAR str2 = root:DSM:gStr2 // sprintf str2,"%d q-values below q = %g were removed",numBad,val Duplicate/O $(USANSFolder+":DSM:Q_exp") $(USANSFolder+":DSM:Q_exp_orig") Duplicate/O $(USANSFolder+":DSM:I_exp") $(USANSFolder+":DSM:I_exp_orig") Duplicate/O $(USANSFolder+":DSM:S_exp") $(USANSFolder+":DSM:S_exp_orig") wave I_exp_orig = $(USANSFolder+":DSM:I_exp_orig") nq = numpnts($(USANSFolder+":DSM:Q_exp")) dQv = NumVarOrDefault("root:"+DFStr+":USANS_dQv", 0.117 ) // if(WaveExists(sigQ)) //try to read dQv //// dqv = -sigQ[0][0] //// DoAlert 0,"Found dQv value of " + num2str(dqv) // else // dqv = 0.117 // // dqv = 0.037 //old value // DoAlert 0,"Could not find dQv in the data file - using " + num2str(dqv) // endif NVAR gDqv = $(USANSFolder+":DSM:gDqv") //needs to be global for Weights_L() NVAR gNq = $(USANSFolder+":DSM:gNq") //reset the globals gDqv = dqv gNq = nq // append the (blank) wave note to the intensity wave Note I_exp,"BOX=0;SPLINE=0;" Note I_exp_orig,"BOX=0;SPLINE=0;" //draw the graph Execute "AppendSmeared()" SetDataFolder root: End // remove any q-values <= val Function RemoveBadQPoints(qw,iw,sw,val) Wave qw,iw,sw Variable val Variable ii,num,numBad,qval num = numpnts(qw) ii=0 numBad=0 do qval = qw[ii] if(qval <= val) numBad += 1 else //keep the points qw[ii-numBad] = qval iw[ii-numBad] = iw[ii] sw[ii-numBad] = sw[ii] endif ii += 1 while(ii 0 //Igor 5 Variable aExists= strlen(CsrWave(A)) > 0 //Igor 4 if(!aExists) return(1) //possibly reverted data, no cursor, no Mask wave endif Duplicate/O $(USANSFolder+":DSM:Q_exp_orig"),$(USANSFolder+":DSM:Q_msk") Duplicate/O $(USANSFolder+":DSM:I_exp_orig"),$(USANSFolder+":DSM:I_msk") Duplicate/O $(USANSFolder+":DSM:S_exp_orig"),$(USANSFolder+":DSM:S_msk") Wave Q_msk=$(USANSFolder+":DSM:Q_msk") Wave I_msk=$(USANSFolder+":DSM:I_msk") Wave S_msk=$(USANSFolder+":DSM:S_msk") //finish up - trim the data sets and reassign the working set Wave MaskData=$(USANSFolder+":DSM:MaskData") RemoveMaskedPoints(MaskData,Q_msk,I_msk,S_msk) //reset the number of points NVAR gNq = $(USANSFolder+":DSM:gNq") gNq = numpnts(Q_msk) Cursor/K A HideInfo return(0) End // not quite the same as revert Function DSM_ClearMaskProc(ctrlName) : ButtonControl String ctrlName SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Wave MaskData=$(USANSFolder+":DSM:MaskData") MaskData = NaN return(0) end // when the mask button is pressed, A must be on the graph // Displays MaskData wave on the graph // Function DSM_MyMaskProc(ctrlName) : ButtonControl String ctrlName SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder Wave data=$(USANSFolder+":DSM:I_exp_orig") // Variable aExists= strlen(CsrInfo(A)) > 0 //Igor 5 Variable aExists= strlen(CsrWave(A)) > 0 //Igor 4 // need to get rid of old smoothed data if data is re-masked Execute "RemoveSmoothed()" SetDataFolder $(USANSFolder+":DSM") Killwaves/Z I_smth,Q_smth,S_smth if(aExists) //mask the selected point // toggle NaN (keep) or Data value (= masked) Wave MaskData MaskData[pcsr(A)] = (numType(MaskData[pcsr(A)])==0) ? NaN : data[pcsr(A)] //if NaN, doesn't plot else Cursor /A=1/H=1/L=1/P/W=Desmear_Graph A I_exp_orig leftx(I_exp_orig) ShowInfo //if the mask wave does not exist, make one if(exists("MaskData") != 1) Duplicate/O Q_exp_orig MaskData MaskData = NaN //use all data endif Execute "AppendMask()" endif SetDataFolder root: return(0) End // when the mask button is pressed, A must be on the graph // Displays MaskData wave on the graph // Function DSM_MaskLTCursor(ctrlName) : ButtonControl String ctrlName SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder // Variable aExists= strlen(CsrInfo(A)) > 0 //Igor 5 Variable aExists= strlen(CsrWave(A)) > 0 //Igor 4 if(!aExists) return(1) endif // need to get rid of old smoothed data if data is re-masked Execute "RemoveSmoothed()" SetDataFolder $(USANSFolder+":DSM") Killwaves/Z I_smth,Q_smth,S_smth Wave data=I_exp_orig Variable pt,ii pt = pcsr(A) for(ii=pt;ii>=0;ii-=1) // toggle NaN (keep) or Data value (= masked) Wave MaskData MaskData[ii] = (numType(MaskData[ii])==0) ? NaN : data[ii] //if NaN, doesn't plot endfor SetDataFolder root: return(0) End // when the mask button is pressed, A must be on the graph // Displays MaskData wave on the graph // Function DSM_MaskGTCursor(ctrlName) : ButtonControl String ctrlName SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder // Variable aExists= strlen(CsrInfo(A)) > 0 //Igor 5 Variable aExists= strlen(CsrWave(A)) > 0 //Igor 4 if(!aExists) return(1) endif // need to get rid of old smoothed data if data is re-masked Execute "RemoveSmoothed()" SetDataFolder $(USANSFolder+":DSM") Killwaves/Z I_smth,Q_smth,S_smth Wave data=I_exp_orig Variable pt,ii,endPt endPt=numpnts(MaskData) pt = pcsr(A) for(ii=pt;ii YS DSM_Smear(I_old,Is_old,NQ,FW) chi2_OLD = chi2(Is_old,I_work,weights,NQ) printf "starting chi^2 = %g\r",chi2_old Print "Starting fast convergence..... " done = 0 //false iter = 0 Do // while not done, use Fast convergence I_dsm = I_work * I_old / Is_old // Calculate corrected guess (no need for do-loop) // Smear iter guess I_dsm --> I_dsm_sm and see how well I_dsm_sm matches experimental data DSM_Smear(I_dsm,I_dsm_sm,NQ,FW) chi2_new = chi2(I_dsm_sm,I_work,weights,NQ) // Stop iteration if fit from new iteration has worse fit... If (chi2_new > chi2_old) Done = 1 Endif // Stop iteration if fit is better than target value... If (chi2_new < chi2_target) Done = 1 Else Iter += 1 Printf "Iteration %d, Chi^2(new) = %g\r", Iter,chi2_new I_old = I_dsm Is_old = I_dsm_sm if(iter>maxFastIter) break endif CHI2_OLD = CHI2_NEW EndIf while( !done ) // append I_dsm,I_exp to the graph Execute "AppendDesmeared()" DoUpdate SetDataFolder $(USANSFolder+":DSM") // step (6) - refine the desmearing using slow convergence Print "Starting slow convergence..... " done = 0 // ! reset flag for slow convergence Do I_dsm = I_old + (I_work - Is_old) // Calculate corrected guess // Smear iter guess Y --> YS DSM_Smear(I_dsm,I_dsm_sm,NQ,FW) chi2_new = chi2(I_dsm_sm,I_work,weights,NQ) // Stop iteration if fit from new iteration has worse fit... If (chi2_new > chi2_old) Done = 1 Endif // Stop iteration if fit is better than target value... If (chi2_new < chi2_target) Done = 1 Else Iter += 1 if(mod(iter, 50 ) ==0 ) Printf "Iteration %d, Chi^2(new) = %g\r", Iter,chi2_new DoUpdate endif I_old = I_dsm Is_old = I_dsm_sm CHI2_OLD = CHI2_NEW EndIf if(iter>maxSlowIter) break endif While ( !done ) Printf "Iteration %d, Chi^2(new) = %g\r", Iter,chi2_new // adjust the error SetDataFolder $(USANSFolder+":DSM") Duplicate/O S_work err S_dsm = abs(err/I_work*I_dsm) //proportional error //John simply keeps the same error as was read in from the smeared data set - is this right? // S_dsm = S_Work NVAR gChi = gChi2Final //chi^2 final NVAR gIter = gIterations //total number of iterations gChi = chi2_new gIter = Iter SVAR str = gIterStr sprintf str,"%d iterations required",iter SetDataFolder root: return(0) End Function DSM_RevertButtonProc(ctrlName) : ButtonControl String ctrlName SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder CleanUpJunk() SetDataFolder $(USANSFolder+":DSM") //reset the working waves to the original wave Q_exp_orig,I_exp_orig,S_exp_orig Duplicate/O Q_exp_orig Q_exp Duplicate/O I_exp_orig I_exp Duplicate/O S_exp_orig S_exp // kill the data folder // re-initialize? SetDataFolder root: return(0) End