def makeObject(self, inObjectFile="mkobject.coo"): """IRAF routine: mkobjects. This places a star in the fits image that is the parent object of this class, at the given ra and dec. It takes as input a file of "ra dec magnitude" for a star type object. 1. Get info from the header files if you want noise 2. Get FWHM for size of the star for the given image 3. Generate the star radius = FWHM / scale, from statistics, scale = 2*sqrt(2*ln(2)) """ # 1. self.loadHeader() INFODICT = { "RON": self.getHeader("RON"), \ "GAIN": self.getHeader("GAIN"), \ "EXPTIME": self.getHeader("EXPTIME"), \ "MAGZP": self._ZPDICT[self.getHeader("FILTER")], \ "POISSON": "no", \ "STAR": "gaussian", \ } # 2. scale = 2*scipy.sqrt(2*scipy.log(2)) self.getMyMedianFWHM() INFODICT["RADIUS"] = self._MEDFWHM / scale # 3. outputname = self._Name.replace(".fits", "_mko.fits") iraf.noao(_doprint=0) iraf.artdata(_doprint=0) iraf.mkobjects(input=self._Name, \ output=outputname, \ # When creating new images #title="",\ #ncols=self.xdim, \ #nlines=self.ydim, \ #header=self.hdrfile, \ #background=0.0, \ # When creating objects objects=inObjectFile, \ xoffset=0.0, \ yoffset=0.0, \ star=INFODICT["STAR"], \ radius=INFODICT["RADIUS"], # this is fwhm/scale (pixels), where scale = 2sqrt(2ln2)\ #beta=2.5, # for star=moffat profile\ ar=1.0, \ pa=0.0, \ distance=1.0, \ exptime=INFODICT["EXPTIME"], \ magzero=INFODICT["MAGZP"], \ # Noise parameters gain=INFODICT["GAIN"], \ rdnoise=INFODICT["RON"], \ poisson=INFODICT["POISSON"], \ seed=1, \ comments=1) return outputname
def _iraf_dqbits_init(_data): """Initialize common IRAF tasks for dqbits tests """ if not HAS_IRAF: return # imports & package loading iraf.stsdas(_doprint=0) iraf.imgtools(_doprint=0) iraf.artdata(_doprint=0) iraf.mstools(_doprint=0) # create two data files as input (dont care if appropriate to mscombine) iraf.imcopy('dev$pix', _data['dqbits']['input1']) iraf.imcopy('dev$pix', _data['dqbits']['input2'])
def mkobjects_iraf(inimage, outimage, objfile, radius, magzero): from pyraf import iraf iraf.noao(_doprint=0) iraf.artdata(_doprint=0) if os.path.exists( outimage) == True: # If the file exists already, IRAF doesn't tell you but just doesn't write the new file os.remove(outimage) print 'Deleted ' + outimage + ' first' iraf.mkobjects(input=inimage, output=outimage, objects=objfile, radius=radius, magzero=magzero) return None
""" import sys, glob, os #import numarray as n import numpy as N import pylab #from math import * from pyraf import iraf #import pyfits import random import mystuff #bcdpath=r13810688/ch1/bcd iraf.images() iraf.images.imutil() iraf.artdata() import spitzergetnoise def findnearest(x1,y1,x2,y2,delta):#x2 is array dmin = 100000000000000000000000000000000000. matchflag=1 nmatch=0 for i in range(len(x2)): d = N.sqrt((x1-x2[i])**2 + (y1-y2[i])**2) if d < delta: nmatch=nmatch+1 if d < dmin: dmin = d imatch = i
def telluric_correction(targetdir,telluricdir,stype): """ Removes telluric lines from 1D spectrum Assumes both science and telluric spectrum have been extracted and wavelength calibrated, i.e. file dimcomb.ms.fits exists in telluric directory. """ print 'Target directory is ' + targetdir if os.path.exists( os.path.join(targetdir,'dimcomb.ms.fits') ): print "Wavelength calibrated target spectrum 'dimcomb.ms.fits' exists" print 'Telluric directory is ' + telluricdir if os.path.exists( os.path.join(telluricdir,'dimcomb.ms.fits') ): print "Wavelength calibrated telluric spectrum 'dimcomb.ms.fits' exists" print 'Generating black-body spectrum...' print 'Telluric star type ' + stype # from this site http://www.gemini.edu/sciops/instruments/nir/photometry/temps_colors.txt if stype == 'A0V': bbtemp = 9480.0 if stype == 'A1V': bbtemp = 9230.0 if stype == 'A2V': bbtemp = 8810.0 if stype == 'A3V': bbtemp = 8270.0 if stype == 'A4V': bbtemp = 8200.0 if stype == 'A5V': bbtemp = 8160.0 print 'Fitting with blackbody, temperature = ' + str(bbtemp) + 'K' iraf.noao(_doprint=0) iraf.artdata (_doprint=0) if os.path.exists( os.path.join(telluricdir,'blackbody.fits') ): os.remove( os.path.join(telluricdir,'blackbody.fits') ) iraf.mk1dspec.setParam('input', os.path.join(telluricdir,'blackbody.fits') ) iraf.mk1dspec.setParam('title','blackbody') iraf.mk1dspec.setParam('ncols',1024) iraf.mk1dspec.setParam('wstart',13900) iraf.mk1dspec.setParam('wend',24000) iraf.mk1dspec.setParam('temperature',bbtemp) iraf.mk1dspec() print 'Generated blackbody spectrum' # Divide telluric star spectrum by black-body if os.path.exists( os.path.join(telluricdir,'tdimcomb.ms.fits') ): os.remove( os.path.join(telluricdir,'tdimcomb.ms.fits') ) iraf.onedspec(_doprint=0) """ To divide by blackbody I want to turn off the cross-correlation - which I think would only work if both spectra had similar features. I don't want to scale the spectrum - which scales the airmass using Beer's Law - or shift it. If the temperature is correct I should be able to simply divide. If not then I should change the temperature """ iraf.telluric.setParam('input',os.path.join(telluricdir,'dimcomb.ms.fits') ) # List of input spectra to correct iraf.telluric.setParam('output',os.path.join(telluricdir,'tdimcomb.ms.fits') ) # List of output corrected spectra iraf.telluric.setParam('cal',os.path.join(telluricdir,'blackbody.fits') ) # List of telluric calibration spectra iraf.telluric.setParam('answer','yes') # Search interactively? iraf.telluric.setParam('xcorr', 'no') # Cross correlate for shift? iraf.telluric.setParam('tweakrms', 'no') # Twak to minise rms? iraf.telluric.setParam('interactive', 'yes') # Interactive? iraf.telluric.setParam('threshold',0.0) # Threshold for calibration iraf.telluric.setParam('offset',1) # Displayed offset between spectra iraf.telluric.setParam('sample','15000:18000,19700:23800') iraf.telluric.setParam('dshift',5.0) iraf.telluric.setParam('smooth',3.0) iraf.telluric() """ When your calibration spectrum has zero or negative intensity values, you have to set the "threshold" parameter accordingly. As explained in the help page for the TELLURIC task, you can think of the "threshold" value as the minimum intensity value TELLURIC will accept from your calibration spectra. Any intensity value lower than the threshold value will be replaced by the threshold. """ """ I've turned cross-correlation off, since I don't really understand it. Tweak is on, but doesn't seem to do that much. Still not sure if it's understanding the airmass """ print 'Now correcting target spectrum...' if os.path.exists( os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ): os.remove( os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ) iraf.telluric.setParam('input',os.path.join(targetdir,'dimcomb+bkgd.ms.fits') ) # List of input spectra to correct iraf.telluric.setParam('output',os.path.join(targetdir,'tdimcomb+bkgd.ms.fits') ) # List of output corrected spectra iraf.telluric.setParam('cal',os.path.join(telluricdir,'tdimcomb.ms.fits') ) # List of telluric calibration spectra iraf.telluric.setParam('answer','yes') # Search interactively? iraf.telluric.setParam('threshold',0.0) iraf.telluric.setParam('xcorr', 'no') # Cross correlate for shift? iraf.telluric.setParam('tweakrms', 'yes') # Tweak to minise rms? iraf.telluric.setParam('interactive', 'yes') # Interactive? iraf.telluric.setParam('offset',6) # Displayed offset between spectra hdulist = fits.open(os.path.join(targetdir,'imcomb.ms.fits')) hdr = hdulist[0].header hdulist.close() iraf.telluric.setParam('airmass',hdr['AIRMASS']) iraf.telluric() return None
def solveField(fullfilename, findstarmethod="astrometry.net"): """ @param: fullfilename entire path to image @type: str @param: findstarmethod (astrometry.net, sex) @type: str Does astrometry to image=fullfilename Uses either astrometry.net or sex(tractor) as its star finder """ pathname, filename = os.path.split(fullfilename) pathname = pathname + "/" basefilename, file_xtn = os.path.splitext(filename) # *** enforce .fits extension if (file_xtn != ".fits"): raise ValueError( "File extension must be .fits it was = %s\n" % file_xtn) # *** check whether the file exists or not if (os.path.exists(fullfilename) == False): raise IOError( "You selected image %s It does not exist\n" % fullfilename) # version 0.23 changed behavior of --overwrite # I need to specify an output filename with -o outfilename = basefilename + "-out" image = Image.fromFile(fullfilename) try: ra = image["CRVAL1"] # expects to see this in image except: raise AstrometryNetException( "Need CRVAL1 and CRVAL2 and CD1_1 on header") try: dec = image["CRVAL2"] except: raise AstrometryNetException( "Need CRVAL1 and CRVAL2 and CD1_1 on header") width = image["NAXIS1"] height = image["NAXIS2"] radius = 5.0 * abs(image["CD1_1"]) * width if findstarmethod == "astrometry.net": line = "solve-field %s -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --ra %f --dec %f --radius %f" % ( fullfilename, outfilename, ra, dec, radius) elif findstarmethod == "sex": sexoutfilename = pathname + outfilename + ".xyls" line = "solve-field %s -d 10,20,30,40,50,60,70,80,90,100 --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f" % ( sexoutfilename, outfilename, width, height, ra, dec, radius) # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d" %(sexoutfilename, outfilename,width, height) # could use --guess-scale for unreliable mounts: # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale" %(sexoutfilename, outfilename, width, height) sex = SExtractor() sex.config['BACK_TYPE'] = "AUTO" sex.config['DETECT_THRESH'] = 3.0 sex.config['DETECT_MINAREA'] = 18.0 sex.config['VERBOSE_TYPE'] = "QUIET" sex.config['CATALOG_TYPE'] = "FITS_1.0" #sex.config['CATALOG_TYPE'] = "ASCII" sex.config['CATALOG_NAME'] = sexoutfilename sex.config['PARAMETERS_LIST'] = ["X_IMAGE", "Y_IMAGE", "MAG_ISO"] sex.run(fullfilename) else: log.error("Unknown option used in astrometry.net") # when there is a solution astrometry.net creates a file with .solved # added as extension. is_solved = pathname + outfilename + ".solved" # if it is already there, make sure to delete it if (os.path.exists(is_solved)): os.remove(is_solved) print "SOLVE", line # *** it would be nice to add a test here to check # whether astrometrynet is running OK, if not raise a new exception # like AstrometryNetInstallProblem solve = Popen(line.split()) # ,env=os.environ) solve.wait() # if solution failed, there will be no file .solved if (os.path.exists(is_solved) == False): raise NoSolutionAstrometryNetException( "Astrometry.net could not find a solution for image: %s %s" % (fullfilename, is_solved)) # wcs_imgname will be the old fits file with the new header # wcs_solution is the solve-field solution file wcs_imgname = pathname + outfilename + "-wcs" + ".fits" wcs_solution = pathname + outfilename + ".wcs" shutil.copyfile(wcs_solution, wcs_solution + ".fits") if (os.path.exists(wcs_imgname) == True): iraf.imdelete(wcs_imgname) # create a separate image with new header iraf.artdata() iraf.imcopy(fullfilename, wcs_imgname) iraf.hedit(wcs_imgname, "CD1_1,CD1_2,CD2_1,CD2_2,CRPIX1,CRPIX2,CRVAL1,CRVAL2,RA,DEC,ALT,AZ", add="no", addonly="no", delete="yes", verify="no", show="no", update="yes") iraf.mkheader(images=wcs_imgname, headers=wcs_solution + ".fits", append="yes", verbose="no", mode="al") return(wcs_imgname)
def model_telluric(): """ Make model telluric spectrum which we will use in 'telluric' Need to fix output from splot for mk1dspec """ def is_number(s): try: float(s) return True except ValueError: return False l = [] with open('splot.log') as f: for line in f.readlines(): if len(line.split()) == 7: if is_number(line.split()[0]): l.append(line.split()) l = np.asarray(l, dtype=np.float) # in mk1dspec peak normalised to continum of one. # use gaussian - voigt seems to overestimate bkgd for some reason # wavelength peak gaussian gfwhm with open('splot_mod.log', 'w') as f: for line in l: f.write(str(line[0]) + ' ' + str(1.0-line[1]+line[4]) + ' gaussian ' + str(line[5]) + '\n') if os.path.exists('model_tell_spec.fits'): os.remove('model_tell_spec.fits') print 'Removing file model_tell_spec.fits' iraf.artdata(_doprint=0) # List of input spectra iraf.mk1dspec.setParam('input','uniform.fits') # List of output spectra iraf.mk1dspec.setParam('output','model_tell_spec.fits') # Title of spectrum iraf.mk1dspec.setParam('title','telluric') # Number of columns iraf.mk1dspec.setParam('ncols',1024) # Starting wavelength (Angstroms) iraf.mk1dspec.setParam('wstart',13986.8488019) # Ending wavelength (Angstroms) iraf.mk1dspec.setParam('wend',23940.4525609) # Continuum at first pixel iraf.mk1dspec.setParam('continuum',0.) # Continuum slope per pixel iraf.mk1dspec.setParam('slope',0.) # Blackbody temperture (Kelvin). 0 = no blackbody iraf.mk1dspec.setParam('temperature',0.) # F-nu or F-lamda? iraf.mk1dspec.setParam('fnu','no') # List of files containing lines iraf.mk1dspec.setParam('lines','splot_mod.log') iraf.mk1dspec() hdulist = fits.open('dimcomb.ms.fits') airmass = hdulist[0].header['airmass'] hdulist = fits.open('model_tell_spec.fits', mode='update') hdulist[0].header['airmass'] = airmass hdulist.flush() return None
def solveField(fullfilename, findstarmethod="astrometry.net"): """ @param: fullfilename entire path to image @type: str @param: findstarmethod (astrometry.net, sex) @type: str Does astrometry to image=fullfilename Uses either astrometry.net or sex(tractor) as its star finder """ pathname, filename = os.path.split(fullfilename) pathname = pathname + "/" basefilename,file_xtn = os.path.splitext(filename) # *** enforce .fits extension if (file_xtn != ".fits"): raise ValueError("File extension must be .fits it was = %s\n" %file_xtn) # *** check whether the file exists or not if ( os.path.exists(fullfilename) == False ): raise IOError("You selected image %s It does not exist\n" %fullfilename) # version 0.23 changed behavior of --overwrite # I need to specify an output filename with -o outfilename = basefilename + "-out" image = Image.fromFile(fullfilename) try: ra = image["CRVAL1"] # expects to see this in image except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") try: dec = image["CRVAL2"] except: raise AstrometryNetException("Need CRVAL1 and CRVAL2 and CD1_1 on header") width = image["NAXIS1"] height = image["NAXIS2"] radius = 5.0 * abs(image["CD1_1"]) * width if findstarmethod == "astrometry.net": #line = "solve-field --guess-scale %s --overwrite -o %s" %(fullfilename, outfilename) line = "solve-field %s --overwrite -o %s --ra %f --dec %f --radius %f" %(fullfilename, outfilename, ra, dec, radius) print line elif findstarmethod == "sex": sexoutfilename = pathname + outfilename + ".xyls" line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --ra %f --dec %f --radius %f" %(sexoutfilename, outfilename, width, height, ra, dec, radius) print "Sextractor command line %s" %line # using --guess-scale # line = "solve-field %s --overwrite -o %s --x-column X_IMAGE --y-column Y_IMAGE --sort-column MAG_ISO --sort-ascending --width %d --height %d --guess-scale" %(sexoutfilename, outfilename, width, height) sex = SExtractor() sex.config['BACK_TYPE'] = "AUTO" sex.config['DETECT_THRESH'] = 3.0 sex.config['DETECT_MINAREA'] = 18.0 sex.config['VERBOSE_TYPE'] = "QUIET" sex.config['CATALOG_TYPE'] = "FITS_1.0" #sex.config['CATALOG_TYPE'] = "ASCII" sex.config['CATALOG_NAME'] = sexoutfilename sex.config['PARAMETERS_LIST'] = ["X_IMAGE","Y_IMAGE","MAG_ISO"] sex.run(fullfilename) else: log.error("Unknown option used in astrometry.net") # when there is a solution astrometry.net creates a file with .solved # added as extension. is_solved = pathname + outfilename + ".solved" # if it is already there, make sure to delete it if ( os.path.exists(is_solved)): os.remove(is_solved) solve = Popen(line.split()) # ,env=os.environ) solve.wait() # if solution failed, there will be no file .solved if ( os.path.exists(is_solved) == False ): raise NoSolutionAstrometryNetException("Astrometry.net could not find a solution for image: %s %s" %(fullfilename, is_solved)) # wcs_imgname will be the old fits file with the new header # wcs_solution is the solve-field solution file wcs_imgname = pathname + outfilename + "-wcs" + ".fits" wcs_solution = pathname + outfilename + ".wcs" shutil.copyfile(wcs_solution,wcs_solution+".fits") if ( os.path.exists(wcs_imgname) == True ): iraf.imdelete(wcs_imgname) # create a separate image with new header iraf.artdata() iraf.imcopy(fullfilename,wcs_imgname) iraf.mkheader(images=wcs_imgname,headers=wcs_solution+".fits", append="no",verbose="no",mode="al") return(wcs_imgname)
from builtins import object import os import time import extras import tableio from astropy.io import fits as pyfits from astropy.modeling.models import Sersic1D, Sersic2D from astropy.modeling.models import Gaussian1D, Gaussian2D import numpy import multiprocessing import traceback import functools from pyraf import iraf from iraf import artdata iraf.noao(_doprint=0) iraf.artdata(_doprint=0) def error(msg, *args): multiprocessing.log_to_stderr() return multiprocessing.get_logger().error(msg, *args) def trace_unhandled_exceptions(func): @functools.wraps(func) def wrapped_func(*args, **kwargs): try: func(*args, **kwargs) except Exception as e: error(traceback.format_exc()) raise