def subbackground(image, sig, nbin, order, iter, type): """Calculate and subtract a global background from an image using a number of different methods. This is assuming that slotmode data is being used. return data array """ # return the same image if no background subtraction is required if type=='none': return image # calculate the image statistics if np.size(image)>0: mean, median, stddev=saltstat.iterstat(image,sig,iter) if stddev==0: raise SaltError('Standard deviation = 0') # Create a row median image. This will be useful for a number of purposes image_mrow=med_row_image(image) # Replace bright objects in the frame with the median value of that row mask=((image-mean) < sig*stddev)*(image-mean > -sig*stddev) image_sig=image*mask+(1-mask)*image_mrow if type == 'median-row': image_back=image*0.0+image_mrow # Median smooth the image if type == 'median': image_back=median_image(image_sig,nbin) # Make a fit to the surface if type=='surf': image_back=image.copy() if type=='both': image_surf=image.copy() for x in range(len(image[0])): y=np.arange(len(image)) my=((image[:,x]-mean) < sig*stddev)*(image[:,x] -mean > -sig*stddev) cy=np.compress(my,y) cim=np.compress(my,image_med[:,x]) coef=np.polyfit(cy,cim,order) image_surf[:,x]=np.polyval(coef,y) # subtract the fit image=image-image_back # return the image return image
def cleancosmicrays(arr, crtype='fast', thresh=5, mbox=3, bbox=5, bthresh=5, flux_ratio=0.2, gain=1, \ rdnoise=5, b_factor=2, fthresh=3, gbin=0, max_iter=1): """Clean the cosmic rays from an input array using three different types of methods """ niter = 0 npix = 1 onpix = 0 #makesure the data array is in floating point try: arr = arr * 1.0 except: message = 'Array cannot be convert to the correct data type' raise SaltError(message) #measure the mean values for the image--leaving this outside #because it doesn't need to be done on each iter loop if crtype == 'fast': mean, midpt, bsigma = saltstat.iterstat(arr, bthresh, max_iter) #set up the array crarr = arr * 0.0 while niter < max_iter and npix > onpix: #apply the correct function to idenitfy cosmic rays if crtype == 'median': crarr += crmedian(arr, thresh, mbox, bbox) elif crtype == 'fast': crarr += crfast(arr, mean, bsigma, thresh, mbox, flux_ratio) elif crtype == 'edge': crarr += credge(arr, thresh, gain, rdnoise, b_factor, fthresh) else: message = 'CRTYPE %s is not a valid value' % crtype raise SaltError(message) #update the array mask = (crarr > 0) arr[mask] = crarr[mask] #count the number of cosmic rays identified onpix = npix npix = crarr.sum() niter += 1 #grow the result if gbin > 0: crarr = crgrow(crarr, grad=gbin) return crarr
def bias(struct, subover=True, trim=True, subbias=False, bstruct=None, median=False, function='polynomial', order=3, rej_lo=3, rej_hi=3, niter=10, plotover=False, log=None, verbose=True): """Bias subtracts the bias levels from a frame. It will fit and subtract the overscan region, trim the images, and subtract a master bias if required. struct--image structure subover--subtract the overscan region trim--trim the image subbias--subtract master bias bstruct--master bias image structure median--use the median instead of mean in image statistics function--form to fit to the overscan region order--order for the function rej_lo--sigma of low points to reject in the fit rej_hi--sigma of high points to reject in the fit niter--number of iterations log--saltio log for recording information verbose--whether to print to stdout """ infile = saltkey.getimagename(struct[0]) # how many extensions? nsciext = saltkey.get('NSCIEXT', struct[0]) nextend = saltkey.get('NEXTEND', struct[0]) nccd = saltkey.get('NCCDS', struct[0]) # how many amplifiers?--this is hard wired amplifiers = 2 * nccd #log the process if subover and log: message = '%28s %7s %5s %4s %6s' % \ ('HDU','Overscan','Order','RMS','Niter') log.message( '\n --------------------------------------------------', with_header=False, with_stdout=verbose) log.message(message, with_header=False, with_stdout=verbose) log.message(' --------------------------------------------------', with_header=False, with_stdout=verbose) if (plotover): plt.figure(1) plt.axes([0.1, 0.1, 0.8, 0.8]) plt.xlabel('CCD Column') plt.ylabel('Pixel Counts (e-)') plt.ion() #loop through the extensions and subtract the bias for i in range(1, nsciext + 1): if struct[i].name == 'SCI': #get the bias section biassec = saltkey.get('BIASSEC', struct[i]) y1, y2, x1, x2 = saltio.getSection(biassec, iraf_format=True) #get the data section datasec = saltkey.get('DATASEC', struct[i]) dy1, dy2, dx1, dx2 = saltio.getSection(datasec, iraf_format=True) #setup the overscan region if subover: yarr = np.arange(y1, y2, dtype=float) data = struct[i].data odata = struct[i].data[y1:y2, x1:x2] if median: odata = np.median((struct[i].data[y1:y2, x1:x2]), axis=1) olevel = np.median((struct[i].data[y1:y2, x1:x2])) saltkey.new('OVERSCAN', '%f' % (olevel), 'Overscan median value', struct[i]) else: odata = np.mean((struct[i].data[y1:y2, x1:x2]), axis=1) olevel = np.mean((struct[i].data[y1:y2, x1:x2])) saltkey.new('OVERSCAN', '%f' % (olevel), 'Overscan mean value', struct[i]) #fit the overscan region ifit=saltfit.interfit(yarr, odata, function=function, \ order=order, thresh=rej_hi, niter=niter) try: ifit.interfit() coeffs = ifit.coef ofit = ifit(yarr) omean, omed, osigma = saltstat.iterstat((odata - ofit), sig=3, niter=5) except ValueError: #catch the error if it is a zero array ofit = np.array(yarr) * 0.0 osigma = 0.0 except TypeError: #catch the error if it is a zero array ofit = np.array(yarr) * 0.0 osigma = 0.0 #if it hasn't been already, convert image to #double format struct[i].data = 1.0 * struct[i].data try: struct[i].header.remove('BZERO') struct[i].header.remove('BSCALE') except: pass #subtract the overscan region for j in range(len(struct[i].data[0])): struct[i].data[y1:y2, j] -= ofit #report the information if log: message = '%25s[%1d] %8.2f %3d %7.2f %3d' % \ (infile, i, olevel, order, osigma, niter) log.message(message, with_stdout=verbose, with_header=False) #add the statistics to the image header saltkey.new('OVERRMS', '%f' % (osigma), 'Overscan RMS value', struct[i]) #update the variance frame if saltkey.found('VAREXT', struct[i]): vhdu = saltkey.get('VAREXT', struct[i]) try: vdata = struct[vhdu].data #The bias level should not be included in the noise from the signal for j in range(len(struct[i].data[0])): vdata[y1:y2, j] -= ofit #add a bit to make sure that the minimum error is the rednoise rdnoise = saltkey.get('RDNOISE', struct[i]) vdata[vdata < rdnoise**2] = rdnoise**2 struct[vhdu].data = vdata + osigma**2 except Exception, e: msg = 'Cannot update the variance frame in %s[%i] because %s' % ( infile, vhdu, e) raise SaltError(msg) #plot the overscan region if plotover: plt.plot(yarr, odata) plt.plot(yarr, ofit) #trim the data and update the headers if trim: struct[i].data = struct[i].data[dy1:dy2, dx1:dx2] datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 - dy1) + ']' saltkey.put('DATASEC', datasec, struct[i]) #update the variance frame if saltkey.found('VAREXT', struct[i]): vhdu = saltkey.get('VAREXT', struct[i]) struct[vhdu].data = struct[vhdu].data[dy1:dy2, dx1:dx2] datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 - dy1) + ']' saltkey.put('DATASEC', datasec, struct[vhdu]) #update the BPM frame if saltkey.found('BPMEXT', struct[i]): bhdu = saltkey.get('BPMEXT', struct[i]) struct[bhdu].data = struct[bhdu].data[dy1:dy2, dx1:dx2] datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 - dy1) + ']' saltkey.put('DATASEC', datasec, struct[bhdu]) #subtract the master bias if necessary if subbias and bstruct: struct[i].data -= bstruct[i].data #update the variance frame if saltkey.found('VAREXT', struct[i]): vhdu = saltkey.get('VAREXT', struct[i]) try: vdata = struct[vhdu].data struct[vhdu].data = vdata + bstruct[vhdu].data except Exception, e: msg = 'Cannot update the variance frame in %s[%i] because %s' % ( infile, vhdu, e) raise SaltError(msg)
def saltfpringfind(images, method=None, section=None, thresh=5, minsize=10, niter=5, conv=0.05, displayimage=True, clobber=False, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) #check the method method = saltio.checkfornone(method) # read in the section section = saltio.checkfornone(section) if section is None: pass else: section = saltio.getSection(section) # open each raw image file for img in infiles: #open the fits file struct = saltio.openfits(img) data = struct[0].data #determine the background value for the image if section is None: #if section is none, just use all pixels greater than zero bdata = data[data > 0] else: y1, y2, x1, x2 = section bdata = data[y1:y2, x1:x2] bmean, bmedian, bstd = iterstat(bdata, sig=thresh, niter=niter, verbose=False) message="Image Background Statistics\n%30s %6s %8s %8s\n%30s %5.4f %5.4f %5.4f\n" % \ ('Image', 'Mean', 'Median', 'Std',img, bmean, bmedian, bstd) log.message(message, with_stdout=verbose) mdata = data * (data - bmean > thresh * bstd) #prepare the first guess for the image ring_list = findrings(data, thresh=thresh, niter=niter, minsize=minsize) #if specified, find the center of the ring if method is not None: for i in range(len(ring_list)): ring_list[i] = findcenter(data, ring_list[i], method, niter=niter, conv=conv) #if one peak: no rings. If two peaks: one ring, if two peaks: four rings if len(ring_list) == 1: msg = "One ring dected in image" else: msg = "%i rings found in image" % len(ring_list) log.message(message, with_stdout=verbose) if displayimage: regfile = img.replace('.fits', '.reg') if clobber and os.path.isfile(regfile): fout = saltio.delete(regfile) fout = open(regfile, 'w') fout.write("""# Region file format: DS9 version 4.1 # Filename: %s global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical """ % img) for ring in ring_list: fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad)) fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad - 3 * ring.sigma)) fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad + 3 * ring.sigma)) fout.close() display(img, catname=regfile, rformat='reg') message = 'Ring Parameters\n%30s %6s %6s %6s\n' % ('Image', 'XC', 'YC', 'Radius') log.message(message, with_stdout=verbose) for ring in ring_list: msg = '%30s %6.2f %6.2f %6.2f\n' % (img, ring.xc, ring.yc, ring.prad) log.message(msg, with_header=False, with_stdout=verbose)
def saltfpringfit(images, outfile, section=None, bthresh=5, niter=5, displayimage=True, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) # read in the section if section is None: section = saltio.getSection(section) msg = 'This mode is not supported yet' raise SaltError(msg) else: section = saltio.getSection(section) print section # open each raw image file for img in infiles: #open the fits file struct = saltio.openfits(img) data = struct[0].data #only keep the bright pixels y1, y2, x1, x2 = section bmean, bmedian, bstd = iterstat(data[y1:y2, x1:x2], sig=bthresh, niter=niter, verbose=False) message="Image Background Statistics\n%30s %6s %8s %8s\n%30s %5.4f %5.4f %5.4f\n" % \ ('Image', 'Mean', 'Median', 'Std',img, bmean, bmedian, bstd) log.message(message, with_stdout=verbose) mdata = data * (data - bmean > bthresh * bstd) #prepare the first guess for the image ring_list = findrings(data, thresh=5, niter=5, minsize=10) if displayimage: regfile = img.replace('.fits', '.reg') print regfile if clobber and os.path.isfile(regfile): fout = saltio.delete(regfile) fout = open(regfile, 'w') fout.write("""# Region file format: DS9 version 4.1 # Filename: %s global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 physical """ % img) for ring in ring_list: print ring fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad)) fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad - 5 * ring.sigma)) fout.write('circle(%f, %f, %f)\n' % (ring.xc, ring.yc, ring.prad + 5 * ring.sigma)) fout.close() display(img, catname=regfile, rformat='reg') #write out the result for viewing struct[0].data = mdata saltio.writefits(struct, 'out.fits', clobber=True) message = 'Ring Parameters' log.message(message)