// TN020-INFO: Continuing the Peak Fit (more iterations) // Revised 8/18/92, James Prouty // // This code extends TN020 Peak Measurement and Fitting to cause // the fitting of peaks to proceed after Igor gives up trying to fit. // Sometimes this results in a successful fit in very difficult situations. // Often, though, if Igor hasn't converged after its usual 40 iterations, // the data just doesn't fit very well. // // The enclosed macro text should inserted into your COPY of // the Peak Measurement experiment. Before inserting this text, // delete the existing Menu and FitPeaksAndBaseline macros so that there // will be room. // // Then either select "Insert Text..." from the File menu to select this // file, or copy the new text to the clipboard and paste it into the // procedure window. You don't need to keep the comments at the start. // // These macros do not provide you with more iterations of // FitBaselineAtRegions. // Continue changes for Peak Measurement Experiment V1.2 // Replace Menu and FitPeaksAndBaseline, add ContinuePeakFit Macro Menu "Macros" m_mp m_so "-" Submenu m_b m_bi m_ba m_bd m_bf m_s m_bs End Submenu m_a m_ai m_aa m_ah m_ala End Submenu m_f m_ii m_ia m_id m_iap "-" m_ff "Continue Peak Fit" "-" m_fr m_fs m_fh m_s End "-" m_cug m_cw End //This macro requires changes to FitPeaksAndBaseline() in order to work Macro ContinuePeakFit() Silent 1 Variable pks=$pdcw[0]-1,s=$pdcw[1],en=$pdcw[2] String/G cf_opts,cf_hold,cf_w,cf_wb,cf_ow Variable/G cf_ok if(pks<1) Abort "no peaks" else Print "Fitting ",pks," peaks" endif if(!cf_ok) Abort "Run FitPeaks First" endif DoWindow/F PeakFitGraph Dup(pdcw,"W_PM") String cmd="FuncFit/H=cf_hold PolyMorph $pcw,$cf_w[s,en]"+cf_opts ResumeUpdate Execute cmd // FuncFitI ("singular matrixI" usually means normalize x values!) if(exists(cf_wb)==1) $cf_ow[s,en]+=$cf_wb[p] endif End // This fits peak equations and a baseline equation or wave to the data. // If the baseline is removed, a constant baseline + peaks will be fit to the data. Macro FitPeaksAndBaseline(w,wx,extent,wb,pktype,wts) String w=g_w,wx=g_wx,wb=fpks_b,wts=fpks_weights Variable extent=fpks_extent ,pktype=fpks_pktype Prompt w,p_w,popup, WaveList("*",";","") Prompt wx,p_wx,popup,calc+WaveList("*X", ";","") Prompt extent,"extent of peak wave to fit",popup,"entire wave, all peaks;wave & peaks within cursors" Prompt wb,p_b,popup, none+S_funcs+"_From Fit Baseline_;"+WaveList("*base*",";","") Prompt pktype,"type of peak fit",popup, S_funcs[70,89] // lor 4,gauss 4 Prompt wts,"weighting wave",popup, none+WaveList("*",";","") Silent 1;PauseUpdate g_w=w;g_wx=wx;SBs(wb);fpks_pktype=pktype fpks_extent=extent;fpks_weights=wts ChkLen(w,wx);ChkLen(w,wb);ChkLen(w,wts) ChkLen(ctrsX,ampsY);ChkLen(ctrsX,widsX) Variable s=0,en=numpnts($w)-1 if(extent==2) CheckTwoCursors(w) s=V_start en=V_theEnd endif String tmpw="W_tmp",ow="W_PeakFit" Mk(pcw,5);Mk(pdcw,5) Dup(w,ow);$ow=NaN Variable terms=0,pkTyp=0,lim=1,baseTyp = floor(strsearch(S_funcs,wb,0)/10) String cmd,opts=" /D="+ow WaveStats/Q/R=[s,en] $w Variable/D bsgs=V_avg,xdiff=pnt2x($w,en)-pnt2x($w,s) if(bsgs==0) bsgs=V_tol endif if(exists(wx)==1) opts+=" /X="+wx xdiff=$wx[en]-$wx[s] endif if(exists(wts)==1) opts+="/W="+wts endif AppWv(ow,wx,"") // initial baseline guesses String hold Variable/G cf_ok=0 if(baseTyp>=0)// function selected (expect "_poly 1", "_dblexp 5", etc) terms=str2num(wb[7,8])-1 // exclude K0 cmd="CurveFit/Q/O "+wb[1,7]+", "+w+"[s,en] "+opts Execute cmd $pcw={NaN,K0,K1,K2,K3,K4} $pdcw={1,s,en,baseTyp,terms} hold="100000"[0,terms+1] afp_b="_From Fit Peaks_" else if(exists(wb)==1) // remove base before fit Dup(w,tmpw);w=tmpw;$w-=$wb terms=0;$pcw={NaN,0};$pdcw={1,s,en,0,0} hold="11";bsgs=0 // K0 not varied else afp_b="_From Fit Peaks_" if(cmpstr(wb,"_From Fit Baseline_")==0) // Use base fit to start Dup(bcw,pcw);Dup(bdcw,pdcw) terms=$pdcw[4] $pdcw[1]=s;$pdcw[2]=en hold="100000"[0,terms+1] else // _None_ terms=0 $pcw={NaN,bsgs} $pdcw={1,s,en,0,0} hold="10" // K0 varied endif endif endif // prevent singular matrix w/ poly base if($pdcw[3]<4) $pcw[1,1+terms]=$pcw[p]*($pcw[p]!=0)+($pcw[p]==0)*bsgs/(xdiff^(p-1)) endif WaveStats/Q $ctrsX Variable npks=V_npnts if(npks<1) Abort "no peaks in peak center wave "+ctrsX endif Variable/D st=2+terms,dst,sz=3,dsz=2,pks=0,kk0 Redimension/N=(5+npks*2) $pdcw iterate (npks) if(($ctrsP[i]>=s) %& ($ctrsP[i]<=en)) dst=3+2*$pdcw[0] Redimension/N=(st+sz) $pcw if(pktype==2) // gauss $pcw[st]=$ampsY[i] // K1 $pcw[st+1]=$ctrsX[i] // K2 $pcw[st+2]=$widsX[i]/2/sqrt(ln(2)) // K3 pkTyp=8 else // lor $pcw[st+2]=$widsX[i]^2 / 4 // K3 $pcw[st]=$ampsY[i]*($widsX[i]^2)/4 // K1 $pcw[st+1]=$ctrsX[i] // K2 pkTyp=7 endif $pdcw[dst]=pkTyp $pdcw[dst+1]=3 hold+= "000" st+=sz dst+=dsz $pdcw[0]+=1 pks+=1 endif loop if(pks<1) Abort "no peaks in between cursors" else Print "Fitting ",pks," peaks" endif // Fit peaks using initial guesses for coefficients Dup(pdcw,"W_PM") cmd="FuncFit/H=hold PolyMorph $pcw,$w[s,en]"+opts String/G cf_opts,cf_hold,cf_w,cf_wb,cf_ow cf_opts=opts;cf_hold=hold;cf_w=w;cf_wb=wb;cf_ow=ow;cf_ok=1 ResumeUpdate Execute cmd // FuncFitI ("singular matrixI" means normalize x values!) KillWv(tmpw) if(exists(wb)==1) $ow[s,en]+=$wb[p] endif ar_wfit=ow ar_ex=extent End //--------- end of text to copy to procedure window -------------