Viewing contents of file '../idllib/contrib/meron/noise.pro'
Function Noise, dat, poisson = pois, seed = sed
;+
; NAME:
; NOISE
; VERSION:
; 3.0
; PURPOSE:
; Adds Gaussian or Poissonian noise to data.
; CATEGORY:
; Mathematical function.
; CALLING SEQUENCE:
; Result = NOISE( DAT [, keywords])
; INPUTS:
; DAT
; numerical, nonnegative.
; OPTIONAL INPUT PARAMETERS:
; None.
; KEYWORD PARAMETERS:
; /POISSON
; Switch. If set, Poisson noise is generated. The default is gaussian.
; SEED
; Can be used to provide a randomization seed. Optional but highly
; recommended (with an uninitialized variable) when doing repeated calls
; to NOISE. See RESTRICTIONS below.
; OUTPUTS:
; Returns the input data with noise added to it.
; OPTIONAL OUTPUT PARAMETERS:
; None.
; COMMON BLOCKS:
; None.
; SIDE EFFECTS:
; None.
; RESTRICTIONS:
; NOISE relies on the IDL routines RANDOMU and RANDOMN which, in the
; absence of externally provided seed generate one using the system
; time. When consecutive calls to NOISE are made on a fast machine,
; they may occur within a single "clock tick" yielding the same random
; series. This is highly undesirable. The problem can be avoided if
; NOISE is always called with SEED = S when S is an uninitialized
; variable.
; PROCEDURE:
; Generates Gauss-distributed (with sigma = square_root(dat)) random
; numbers for gaussian noise. Uses the rejection method for Poisson
; noise. Calls CAST, DEFAULT and FPU_FIX from MIDL.
; MODIFICATION HISTORY:
; Created 25-JAN-1997 by Mati Meron.
; Modified 10-SEP-1998 by Mati Meron. Underflow filtering added.
;-
on_error, 1
neld = n_elements(dat)
if neld eq 0 then message, 'No data!'
mult = Default(mult,1.,/dtype)
wdat = Cast(dat,3,3) > 0
if keyword_set(pois) then begin
slim = long(2d^31 - 2)
sdat = sqrt(2*wdat)
res = -wdat
a = where(res lt 0, ndo)
while ndo gt 0 do begin
kres = wdat(a) + sdat(a)*tan(!pi*(randomu(sed,ndo) - 0.5))
kres = floor(-slim > kres < slim)
b = where (kres ge 0, ndo)
if ndo gt 0 then begin
ab = a(b)
u = wdat(ab)
su = sdat(ab)
v = kres(b) + 0.5
rat = exp(v*(1 + alog(u/(v - 1./(24*v)))) - u)* $
su/(2*u + 1./6)/atan(su, (v - u)^2 + 2*u - 0.25)
c = where(rat ge randomu(sed,ndo), ndo)
if ndo gt 0 then res(ab(c)) = kres(b(c))
endif
a = where(res lt 0, ndo)
endwhile
endif else res = wdat + round(sqrt(dat)*randomn(sed,neld))
return, FPU_fix(res)
end