def specsky(images,outimages,outpref, method='normal', section=None, function='polynomial', order=2, clobber=True,logfile='salt.log',verbose=True): with logging(logfile,debug) as log: # Check the input images infiles = saltio.argunpack ('Input',images) # create list of output files outfiles=saltio.listparse('Outfile', outimages, outpref,infiles,'') if method not in ['normal', 'fit']: msg='%s mode is not supported yet' % method raise SALTSpecError(msg) if section is None: section=saltio.getSection(section) msg='This mode is not supported yet' raise SALTSpecError(msg) else: section=saltio.getSection(section) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): log.message('Subtracting sky spectrum in image %s into %s' % (img, ofile)) #open the images hdu=saltio.openfits(img) #sky subtract the array hdu=skysubtract(hdu, method=method, section=section, funct=function, order=order) #write out the image if clobber and os.path.isfile(ofile): saltio.delete(ofile) hdu.writeto(ofile)
def specsky(images, outimages, outpref, method='normal', section=None, function='polynomial', order=2, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) # create list of output files outfiles = saltio.listparse('Outfile', outimages, outpref, infiles, '') if method not in ['normal', 'fit']: msg = '%s mode is not supported yet' % method raise SALTSpecError(msg) if section is None: section = saltio.getSection(section) msg = 'This mode is not supported yet' raise SALTSpecError(msg) else: section = saltio.getSection(section) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): log.message('Subtracting sky spectrum in image %s into %s' % (img, ofile)) # open the images hdu = saltio.openfits(img) # sky subtract the array hdu = skysubtract(hdu, method=method, section=section, funct=function, order=order) # write out the image if clobber and os.path.isfile(ofile): saltio.delete(ofile) hdu.writeto(ofile)
def saltcombine(images,outimage, method='average', reject=None, mask=True, \ weight=True, blank=0, scale=None, statsec=None, lthresh=3, \ hthresh=3, clobber=False, logfile='salt.log',verbose=True): with logging(logfile,debug) as log: # Check the input images infiles = saltio.argunpack ('Input',images) #set reject as None reject=saltio.checkfornone(reject) if reject is not None: reject=reject.lower() #set scale scale=saltio.checkfornone(scale) if scale is not None: scale=scale.lower() #set statsec statsec=saltio.checkfornone(statsec) statsec=saltio.getSection(statsec, iraf_format=True) #Fast combine the images outstruct=imcombine(infiles, method=method, reject=reject, mask=mask, \ weight=weight, blank=blank, scale=scale, \ statsec=statsec, lthresh=lthresh, hthresh=hthresh) # housekeeping keywords fname, hist=history(level=1, wrap=False) saltkey.housekeeping(outstruct[0],'SCOMBINE', 'File Combined by SALTCOMBINE', hist) # write FITS file saltio.writefits(outstruct, outimage)
def saltcombine(images,outimage, method='average', reject=None, mask=True, \ weight=True, blank=0, scale=None, statsec=None, lthresh=3, \ hthresh=3, clobber=False, logfile='salt.log',verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) #set reject as None reject = saltio.checkfornone(reject) if reject is not None: reject = reject.lower() #set scale scale = saltio.checkfornone(scale) if scale is not None: scale = scale.lower() #set statsec statsec = saltio.checkfornone(statsec) statsec = saltio.getSection(statsec, iraf_format=True) #Fast combine the images outstruct=imcombine(infiles, method=method, reject=reject, mask=mask, \ weight=weight, blank=blank, scale=scale, \ statsec=statsec, lthresh=lthresh, hthresh=hthresh) # housekeeping keywords fname, hist = history(level=1, wrap=False) saltkey.housekeeping(outstruct[0], 'SCOMBINE', 'File Combined by SALTCOMBINE', hist) # write FITS file saltio.writefits(outstruct, outimage)
def specextract(images, outfile, method='normal', section=None, thresh=3.0, minsize=3.0, outformat='ascii', ext=1, convert=True, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) # create list of output files outfiles = saltio.argunpack('outfile', outfile) if method is 'weighted': msg = 'This mode is not supported yet' raise SALTSpecError(msg) section = saltio.checkfornone(section) if section is not None: sections = saltio.getSection(section, iraf_format=False) section = [] for i in range(0, len(sections), 2): section.append((sections[i], sections[i + 1])) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): log.message('\nExtracting spectrum in image %s to %s' % (img, ofile), with_header=False, with_stdout=verbose) # open the images hdu = saltio.openfits(img) ap_list = extract(hdu, ext=ext, method=method, section=section, minsize=minsize, thresh=thresh, convert=convert) # write the spectra out if ap_list: write_extract(ofile.strip(), ap_list, outformat=outformat, clobber=clobber) log.message('', with_header=False, with_stdout=verbose)
def specextract( images, outfile, method="normal", section=None, thresh=3.0, minsize=3.0, outformat="ascii", ext=1, convert=True, clobber=True, logfile="salt.log", verbose=True, ): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack("Input", images) # create list of output files outfiles = saltio.argunpack("outfile", outfile) if method is "weighted": msg = "This mode is not supported yet" raise SALTSpecError(msg) section = saltio.checkfornone(section) if section is not None: sections = saltio.getSection(section, iraf_format=False) section = [] for i in range(0, len(sections), 2): section.append((sections[i], sections[i + 1])) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): log.message( "\nExtracting spectrum in image %s to %s" % (img, ofile), with_header=False, with_stdout=verbose ) # open the images hdu = saltio.openfits(img) ap_list = extract( hdu, ext=ext, method=method, section=section, minsize=minsize, thresh=thresh, convert=convert ) # write the spectra out if ap_list: write_extract(ofile.strip(), ap_list, outformat=outformat, clobber=clobber) log.message("", with_header=False, with_stdout=verbose)
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 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)
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 embedimage(struct, nccd=2, namps=2, nwindows=1): """For given number of windows in struct, create an embeded image. struct: an image structure nccd: number of ccds namps: number of amplifiers per ccd nwindows: number of windows """ #create the output structure outstruct=pyfits.HDUList(struct[0]) #get the total size of the section decsect=saltio.getSection(saltkey.get('DETSIZE', struct[0]), iraf_format=True) xbin,ybin=saltkey.get('CCDSUM', struct[0]).strip().split() xbin=int(xbin) ybin=int(ybin) #determine the data size--this assumes that the CCDs are in the x direction and #all of the CCDs are the same size xsize=decsect[3]/xbin/(nccd*namps) ysize=decsect[1]/ybin edata=np.zeros((ysize,xsize)) #loop through the number of extensions for i in range(1,nccd*namps+1): #create the total size for the extension extdata=edata.copy() #loop throug each window and add it to the extension xmax=0 for j in range(nwindows): winsect=saltio.getSection(saltkey.get('AMPSEC', struct[i+6*j]), iraf_format=True) y1=(winsect[0]-1)/ybin #y2=(winsect[1])/ybin+1 y2=y1+len(struct[i+6*j].data) x1=(winsect[2]-1)/xbin x2=len(struct[i+6*j].data[0]) #x2=(winsect[3])/xbin extdata[y1:y2,x1:x2]=struct[i+6*j].data xmax=max(xmax, x2) #add the correct header information *TODO* #append to the hdu list exthdu=pyfits.ImageHDU(extdata[:,0:xmax]) outstruct.append(exthdu) #return the new extension return outstruct
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 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)
def specreduce(images, badpixelimage=None, caltype='rss', function='polynomial', order=3, skysub=True, skysection=None, findobj=False, objsection=None, thresh=3.0, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', images) # open the badpixelstruct if saltio.checkfornone(badpixelimage): badpixelstruct = saltio.openfits(badpixelimage) else: badpixelstruct = None # set up the section for sky estimate if skysection is not None: skysection = makesection(skysection) else: skysub = False # set up the section for sky estimate section = saltio.checkfornone(objsection) if section is not None: sections = saltio.getSection(section, iraf_format=False) objsection = [] for i in range(0, len(sections), 2): objsection.append((sections[i], sections[i + 1])) # determine the wavelength solutions if caltype == 'line': calc_wavesol(infiles) # correct the images for img in infiles: # open the fits file struct = saltio.openfits(img) # prepare filep log.message('Preparing %s' % img) struct = prepare(struct, badpixelstruct) # rectify the spectrum log.message('Rectifying %s using %s' % (img, caltype)) struct = rectify( struct, None, caltype=caltype, function=function, order=order) # sky subtract the spectrum # assumes the data is long slit and in the middle of the field if skysub: log.message('Subtracting the sky from %s' % img) struct = skysubtract( struct, method='normal', section=skysection) # extract the spectrum log.message('Extracting the spectrum from %s' % img) print objsection aplist = extract( struct, method='normal', section=objsection, thresh=thresh) oimg = os.path.dirname( os.path.abspath(img)) + '/s' + os.path.basename(img.strip()) ofile = oimg[:-5] + '.txt' write_extract(ofile, aplist, clobber=clobber) # write FITS file log.message('Writing 2-D corrected image as %s' % oimg) saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def specreduce( images, badpixelimage=None, caltype="rss", function="polynomial", order=3, skysub=True, skysection=None, findobj=False, objsection=None, thresh=3.0, clobber=True, logfile="salt.log", verbose=True, ): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack("Input", images) # open the badpixelstruct if saltio.checkfornone(badpixelimage): badpixelstruct = saltio.openfits(badpixelimage) else: badpixelstruct = None # set up the section for sky estimate if skysection is not None: skysection = makesection(skysection) else: skysub = False # set up the section for sky estimate section = saltio.checkfornone(objsection) if section is not None: sections = saltio.getSection(section, iraf_format=False) objsection = [] for i in range(0, len(sections), 2): objsection.append((sections[i], sections[i + 1])) # determine the wavelength solutions if caltype == "line": calc_wavesol(infiles) # correct the images for img in infiles: # open the fits file struct = saltio.openfits(img) # prepare filep log.message("Preparing %s" % img) struct = prepare(struct, badpixelstruct) # rectify the spectrum log.message("Rectifying %s using %s" % (img, caltype)) struct = rectify(struct, None, caltype=caltype, function=function, order=order) # sky subtract the spectrum # assumes the data is long slit and in the middle of the field if skysub: log.message("Subtracting the sky from %s" % img) struct = skysubtract(struct, method="normal", section=skysection) # extract the spectrum log.message("Extracting the spectrum from %s" % img) print objsection aplist = extract(struct, method="normal", section=objsection, thresh=thresh) oimg = os.path.dirname(os.path.abspath(img)) + "/s" + os.path.basename(img.strip()) ofile = oimg[:-5] + ".txt" write_extract(ofile, aplist, clobber=clobber) # write FITS file log.message("Writing 2-D corrected image as %s" % oimg) saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def embedimage(struct, nccd=2, namps=2, nwindows=1): """For given number of windows in struct, create an embeded image. struct: an image structure nccd: number of ccds namps: number of amplifiers per ccd nwindows: number of windows """ #create the output structure outstruct=fits.HDUList(struct[0]) #get the total size of the section decsect=saltio.getSection(saltkey.get('DETSIZE', struct[0]), iraf_format=True) xbin,ybin=saltkey.get('CCDSUM', struct[0]).strip().split() xbin=int(xbin) ybin=int(ybin) #determine the data size--this assumes that the CCDs are in the x direction and #all of the CCDs are the same size xsize=decsect[3]/xbin/(nccd*namps) ysize=decsect[1]/ybin edata=np.zeros((ysize,xsize)) #loop through the number of extensions for i in range(1,nccd*namps+1): #create the total size for the extension extdata=edata.copy() #loop throug each window and add it to the extension xmax=0 for j in range(nwindows): winsect=saltio.getSection(saltkey.get('AMPSEC', struct[i+6*j]), iraf_format=True) y1=(winsect[0]-1)/ybin #y2=(winsect[1])/ybin+1 y2=y1+len(struct[i+6*j].data) x1=(winsect[2]-1)/xbin x2=len(struct[i+6*j].data[0]) #x2=(winsect[3])/xbin extdata[y1:y2,x1:x2]=struct[i+6*j].data xmax=max(xmax, x2) #add the correct header information *TODO* #append to the hdu list exthdu=yfits.ImageHDU(extdata[:,0:xmax]) outstruct.append(exthdu) #return the new extension return outstruct