def black_tophat(input, size=None, footprint=None, structure=None, output=None, mode="reflect", cval=0.0, origin=0): """Multi-dimensional black tophat filter. Either a size or a footprint, or the structure must be provided. An output array can optionally be provided. The origin parameter controls the placement of the filter. The mode parameter determines how the array borders are handled, where cval is the value when mode is equal to 'constant'. """ tmp = grey_dilation(input, size, footprint, structure, None, mode, cval, origin) if isinstance(output, numarray.NumArray): grey_erosion(tmp, size, footprint, structure, output, mode, cval, origin) del tmp return numarray.subtract(output, input, output) else: tmp = grey_erosion(tmp, size, footprint, structure, None, mode, cval, origin) return tmp - input
def _stdev(data): n = len(data[:,0,0]) s = num.zeros(data[0,:,:].shape, num.Float32) # First pass to get the mean. for j in range(n): s += data[j,:,:] ave = s/n var = num.zeros(s.shape, num.Float32) ep = num.zeros(s.shape, num.Float32) for j in range(n): s = data[j,:,:]-ave num.add(ep, s, ep) p = s**2 num.add(var, p, var) # Corrected two-pass formula. num.subtract(var, ep*ep/n, var) num.divide(var, (n-1), var) return num.sqrt(var)
def morphological_laplace(input, size = None, footprint = None, structure = None, output = None, mode = "reflect", cval = 0.0, origin = 0): """Multi-dimensional morphological laplace. Either a size or a footprint, or the structure must be provided. An output array can optionally be provided. The origin parameter controls the placement of the filter. The mode parameter determines how the array borders are handled, where cval is the value when mode is equal to 'constant'. """ tmp1 = grey_dilation(input, size, footprint, structure, None, mode, cval, origin) if isinstance(output, numarray.NumArray): grey_erosion(input, size, footprint, structure, output, mode, cval, origin) numarray.add(tmp1, output, output) del tmp1 numarray.subtract(output, input, output) return numarray.subtract(output, input, output) else: tmp2 = grey_erosion(input, size, footprint, structure, None, mode, cval, origin) numarray.add(tmp1, tmp2, tmp2) del tmp1 numarray.subtract(tmp2, input, tmp2) numarray.subtract(tmp2, input, tmp2) return tmp2
def white_tophat(input, size = None, footprint = None, structure = None, output = None, mode = "reflect", cval = 0.0, origin = 0): """Multi-dimensional white tophat filter. Either a size or a footprint, or the structure must be provided. An output array can optionally be provided. The origin parameter controls the placement of the filter. The mode parameter determines how the array borders are handled, where cval is the value when mode is equal to 'constant'. """ tmp = grey_erosion(input, size, footprint, structure, None, mode, cval, origin) if isinstance(output, numarray.NumArray): grey_dilation(tmp, size, footprint, structure, output, mode, cval, origin) del tmp return numarray.subtract(input, output, output) else: tmp = grey_dilation(tmp, size, footprint, structure, None, mode, cval, origin) return input - tmp
def mad_combine(infileglob, outfilebase): # get list of files to operate on files = glob.glob(infileglob) # check more than one image exists if files < 2: print 'Less than two input files found!' return print 'Operating on images',infileglob # get images images = _get_images(files) lenimages = len(images) print 'Found', lenimages, 'images' # get header of first image hdr = images[0][0].header # get ascard of first image hdrascard = hdr.ascard # get data from images into num (untidy tuple concatenation) data = num.zeros((lenimages,) + images[0][0].data.shape, num.Float32) for i in range(lenimages): data[i,:,:] = images[i][0].data # delete array del images # sort data print 'Sorting... (this may take a while, i.e an hour or so!)' #data_sorted = num.sort(data, axis=0) data_sorted = data # for debugging # find standard deviation of lowest n - n_discard pixels print 'Calculating mad_low...' mad_low = _mad3(data_sorted[:-n_discard,:,:]) # correct for bias to stddev num.multiply(mad_low, corr[`lenimages - n_discard` + ',' + `lenimages`], mad_low) # make median image print 'Calculating median...' if lenimages%2 != 0: # then odd number of images m = (lenimages - 1) / 2 median = data_sorted[m,:,:] else: # even number of images m = lenimages / 2 median = (data_sorted[m,:,:] + data_sorted[m-1,:,:]) / 2 # delete array del data_sorted # get ccd properties from header # these keywords are for FORS2 # - they may need altering for other instruments gain = hdr['OUT1GAIN'] # N_{ADU} = gain * N_{e-} invgain = 1.0 / gain # N_{e-} = invgain * N_{ADU} ron = hdr['OUT1RON'] # read out noise in e- # take only +ve values in median median_pos = num.choose(median < 0.0, (median, 0.0)) # calculate sigma due to ccd noise for each pixel print 'Calculating noise_med...' noise_med = num.sqrt(median_pos * invgain + ron*ron) * gain # delete array del median_pos # find maximum of noise and mad_low # -> sigma to test pixels against to identify cosmics print 'Calculating sigma_test...' sigma_test = num.choose(noise_med < mad_low, (noise_med, mad_low)) # delete arrays del mad_low, noise_med # calculate 'relative residual' for each pixel print 'Calculating rel_res...' rel_res = num.zeros(data.shape, num.Float32) res = num.zeros(data[0].shape, num.Float32) for i in range(lenimages): num.subtract(data[i,:,:], median, res) num.divide(res, sigma_test, rel_res[i,:,:]) # delete arrays del sigma_test, res # now average over all pixels for which rel_res < sigma_limit # first count number included for each pixel # by testing to produce a boolean array, then summing over. print 'Calculating included...' included = num.zeros(rel_res[0].shape, num.Int16) included[:,:] = num.sum(rel_res <= sigma_limit) # put all discarded pixels to zero print 'Calculating combined...' pre_combine = num.choose(rel_res <= sigma_limit, (0.0,data)) # delete array del rel_res # sum all pixels and divide by included to give mean combined = num.sum(pre_combine) # delete array del pre_combine num.divide(combined, included, combined) # Work out errors on this combined image # take only +ve values in combined mean_pos = num.choose(combined < 0.0, (combined, 0.0)) # calculate sigma due to ccd noise for each pixel print 'Calculating noise_mean...' noise_mean = num.sqrt(mean_pos * invgain + ron*ron) * gain # delete array del mean_pos # create standard error image print 'Calculating error...' error = noise_mean / num.sqrt(included) # delete array del noise_mean # write all images to disk print 'Writing images to disk...' _write_images(combined, error, included, hdrascard, outfilebase)