;+ interpolate flux or counts between two binning vectors ; ; INPUT: oldBins is a list of bin edges. It contains n>=2 unique ; elements sorted in ascending order ; newBins is a list of bin edges. It contains m>=2 unique ; elements sorted in ascending order ; oldVals is a list of n-1 values associated to ; oldBins, the values to interpolate. That is, ; oldVals[i] is associated with the bin having edges ; (oldBins[i], oldBins[i+1]). ; flux set means oldVals are counts/binWidth, not counts ; ; OUTPUT: returns a list of m-1 interpolated values associated to ; newBins ; ; METHOD: traverse both bin lists once. For each old bin ; there are 4 possibilities: ; a) old bin precedes current new bin ; b) new bin precedes the current old bin ; c) old bin overlaps new bin, extends beyond ; d) old bin overlaps new bin, does not extend beyond ; CALLS: none ; ; NOTES: 1. algorithm is simple linear interpolation. ; 2. The interpolated vector might contain less ; information than the input vector. Exchanging oldBins ; and newBins is not an inverse function for brl_rebin(). ; 3. Difference between FLUX=0 and FLUX=1: suppose ; the old and new binning schemes have the same ; total range. Then FLUX=0 preserves the sum of ; oldVals, and would be used when oldVals represents ; counts in each bin, whereas FLUX=1 preserves the dot ; product of oldVals and the (n-1 length) vector of ; differences between successive oldBin entries---used ; when oldVals has counts divided by bin width. ; ; WARNING: since this might be called repeatedly with only ; oldVals changing, error-checking is minimal. The ; calling routine is responsible for error-checking. ; ; REVISION HISTORY: ; works, not much testing mm/Jul 2012 ; 22Oct2012: corrected normalization for flux eq 0 ; 01Jan2013: calculates array lengths n&m automatically (DMS) ;- function brl_rebin,oldVals,oldBins,newBins,FLUX=flux n=n_elements(oldBins) m=n_elements(newBins) if (n lt 2 or m lt 2) then $ message,"length(s) violation: "+strtrim(n)+", "+strtrim(m) result=fltarr(m-1) oldLo=oldBins[0] oldHi=oldBins[1] newLo=newBins[0] newHi=newBins[1] newIndex=0 oldIndex=0 total=0. while (1) do begin ; DEBUG****print,oldIndex,oldLo,oldHi,newIndex,newLo,newHi,total if (oldHi le newLo) then begin oldIndex += 1 if (oldIndex ge n-1) then return,result oldLo=oldHi oldHi=oldBins[oldIndex+1] continue endif if (newHi le oldLo) then begin if keyword_set(flux) then $ result[newIndex]=total/(newHi-newLo) $ else $ result[newIndex]=total/(oldHi-oldLo) total=0. newIndex += 1 if (newIndex ge m-1) then return,result newLo=newHi newHi=newBins[newIndex+1] continue endif if (newHi lt oldHi) then begin total += (newHi-(oldLo>newLo))*oldVals[oldIndex] if keyword_set(flux) then $ result[newIndex]=total/(newHi-newLo) $ else $ result[newIndex]=total/(oldHi-oldLo) total = 0. newIndex += 1 if (newIndex ge m-1) then return,result newLo=newHi newHi=newBins[newIndex+1] continue endif else begin total += (oldHi-(oldLo>newLo))*oldVals[oldIndex] oldIndex += 1 if (oldIndex ge n-1) then begin if keyword_set(flux) then $ result[newIndex]=total/(newHi-newLo) $ else $ result[newIndex]=total/(oldHi-oldLo) return,result endif oldLo=oldHi oldHi=oldBins[oldIndex+1] endelse endwhile end