def hrsprepare(images, outimages, outpref, clobber=True, logfile='salt.log',verbose=True): """Convert .fit files to .fits files and place HRS data into standard SALT FITS format """ 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #open the file and write out as a fits files in the output directory for img,oimg in zip(infiles, outfiles): hdu=saltio.openfits(img) hdu=prepare(hdu) log.message('Preparing HRS %s to %s' % (img, oimg), with_header=False) saltio.writefits(hdu, oimg, clobber=clobber) return
def saltprepare(images,outimages,outpref,createvar=False, badpixelimage=None, 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # open the badpixel image if saltio.checkfornone(badpixelimage) is None: badpixelstruct=None else: try: badpixelstruct = saltio.openfits(badpixelimage) except saltio.SaltIOError,e: msg='badpixel image must be specificied\n %s' % e raise SaltError(msg) # open each raw image file for img, oimg, in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) #if createvar, throw a warning if it is using slotmode if saltkey.fastmode(saltkey.get('DETMODE', struct[0])) and createvar: msg='Creating variance frames for slotmode data in %s' % img log.warning(msg) # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot = saltkey.instrumid(struct) # has file been prepared already? try: key = struct[0].header[keyprep] message = 'ERROR -- SALTPREPARE: File ' + infile message += ' has already been prepared' raise SaltError(message) except: pass # prepare file struct=prepare(struct,createvar=createvar, badpixelstruct=badpixelstruct) # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0],keyprep, 'File prepared for IRAF', hist) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct) message = 'SALTPREPARE -- %s => %s' % (img, oimg) log.message(message, with_header=False)
def hrsstack(images, outimages, outpref, clobber=True, logfile='salt.log', verbose=True): """Convert MEF HRS data into a single image. If variance frames and BPMs, then convert them to the same format as well. Returns an MEF image but that is combined into a single frame """ 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') #open the file and write out as a fits files in the output directory for img, oimg in zip(infiles, outfiles): hdu = saltio.openfits(img) hdu = stack(hdu) log.message('Stacking HRS %s to %s' % (img, oimg), with_header=False) saltio.writefits(hdu, oimg, clobber=clobber) return
def saltillum(images, outimages, outpref, mbox=11, clobber=False, 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, "") # verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, "Input", "output") # open each raw image file for infile, outfile in zip(infiles, outfiles): struct = saltio.openfits(infile) struct = illum_cor(struct, mbox) # add any header keywords like history fname, hist = history(level=1, wrap=False) saltkey.housekeeping(struct[0], "SILLUM", "File Illumination corrected", hist) # write it out and close it saltio.writefits(struct, outfile, clobber=clobber) saltio.closefits(struct) # output the information log.message("Illumination corrected image %s " % (infile), with_header=False, with_stdout=verbose)
def specselfid(images, outimages, outpref, refimage=None, ystart='middlerow', rstep=3, clobber=False, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # set up the variables infiles = [] outfiles = [] # Check the input images infiles = saltio.argunpack('Input', images) # create list of output files outfiles = saltio.listparse( 'Outimages', outimages, outpref, infiles, '') # set up defaults if saltio.checkfornone(refimage) is not None: rhdu = saltio.openfits(refimage) else: refimage = None # read in rectify each image for img, oimg, in zip(infiles, outfiles): hdu = saltio.openfits(img) log.message( 'Performing self-identification and rectification on %s' % img) for i in range(1, len(hdu)): if hdu[i].name == 'SCI': if refimage is None: sdata = hdu[i].data else: sdata = rhdu[i].data hdu[i].data = selfid( hdu[i].data, sdata, ystart=ystart, rstep=rstep) if saltkey.found('VAREXT', hdu[i]): varext = saltkey.get('VAREXT', hdu[i]) hdu[varext].data = selfid( hdu[varext].data, sdata, ystart=ystart, rstep=rstep) if saltkey.found('BPMEXT', hdu[i]): bpmext = saltkey.get('BPMEXT', hdu[i]) hdu[bpmext].data = selfid( hdu[bpmext].data, sdata, ystart=ystart, rstep=rstep) # write out the oimg saltio.writefits(hdu, oimg, clobber=clobber)
def hrsstack(images, outimages, outpref, clobber=True, logfile='salt.log',verbose=True): """Convert MEF HRS data into a single image. If variance frames and BPMs, then convert them to the same format as well. Returns an MEF image but that is combined into a single frame """ 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #open the file and write out as a fits files in the output directory for img,oimg in zip(infiles, outfiles): hdu=saltio.openfits(img) hdu=stack(hdu) log.message('Stacking HRS %s to %s' % (img, oimg), with_header=False) saltio.writefits(hdu, oimg, clobber=clobber) return
def saltgain(images, outimages, outpref, gaindb=None, usedb=False, mult=True, clobber=True, logfile='salt.log', verbose=True): #start logging 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') # read in the database file if usedb is true if usedb: gaindb = gaindb.strip() dblist = saltio.readgaindb(gaindb) else: dblist = [] for img, oimg in zip(infiles, outfiles): #open the fits file struct = saltio.openfits(img) # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltkey.instrumid( struct) # has file been prepared already? if saltkey.found(keygain, struct[0]): message = 'SALTGAIN: %s has already been gain-corrected' % img raise SaltError(message) # gain correct the data struct = gain(struct, mult=mult, usedb=usedb, dblist=dblist, log=log, verbose=verbose) # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], keygain, 'Images have been gain corrected', hist) # write FITS file saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def saltsurface(images,outimages,outpref, mask=True, order=3, minlevel=0, clobber=False, 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # open each raw image file for infile, outfile in zip(infiles,outfiles): struct = saltio.openfits(infile) struct = surface_fit(struct, order=order, mask=mask, minlevel=minlevel) #add any header keywords like history fname, hist=history(level=1, wrap=False) saltkey.housekeeping(struct[0],'SURFIT', 'File fit by a surface', hist) #write it out and close it saltio.writefits(struct,outfile,clobber=clobber) saltio.closefits(struct) #output the information log.message('Surface fitted image %s ' % (infile), with_header=False, with_stdout=verbose)
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 salt2iraf(images, outimages, outpref, ext=1, 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') for img, oimg in zip(infiles, outfiles): message = "SALT2IRAF--Converting %s to %s" % (img, oimg) log.message(message, with_header=False) try: convertsalt(img, oimg, ext=ext, clobber=clobber) except SaltError, e: log.message('%s' % e)
def saltillum(images,outimages,outpref, mbox=11, clobber=False, \ 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') # open each raw image file for infile, outfile in zip(infiles, outfiles): struct = saltio.openfits(infile) struct = illum_cor(struct, mbox) #add any header keywords like history fname, hist = history(level=1, wrap=False) saltkey.housekeeping(struct[0], 'SILLUM', 'File Illumination corrected', hist) #write it out and close it saltio.writefits(struct, outfile, clobber=clobber) saltio.closefits(struct) #output the information log.message('Illumination corrected image %s ' % (infile), with_header=False, with_stdout=verbose)
def specselfid(images, outimages, outpref, refimage=None, ystart='middlerow', rstep=3, clobber=False, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # set up the variables infiles = [] outfiles = [] # Check the input images infiles = saltio.argunpack('Input', images) # create list of output files outfiles = saltio.listparse('Outimages', outimages, outpref, infiles, '') # set up defaults if saltio.checkfornone(refimage) is not None: rhdu = saltio.openfits(refimage) else: refimage = None # read in rectify each image for img, oimg, in zip(infiles, outfiles): hdu = saltio.openfits(img) log.message( 'Performing self-identification and rectification on %s' % img) for i in range(1, len(hdu)): if hdu[i].name == 'SCI': if refimage is None: sdata = hdu[i].data else: sdata = rhdu[i].data hdu[i].data = selfid(hdu[i].data, sdata, ystart=ystart, rstep=rstep) if saltkey.found('VAREXT', hdu[i]): varext = saltkey.get('VAREXT', hdu[i]) hdu[varext].data = selfid(hdu[varext].data, sdata, ystart=ystart, rstep=rstep) if saltkey.found('BPMEXT', hdu[i]): bpmext = saltkey.get('BPMEXT', hdu[i]) hdu[bpmext].data = selfid(hdu[bpmext].data, sdata, ystart=ystart, rstep=rstep) # write out the oimg saltio.writefits(hdu, oimg, clobber=clobber)
def saltfpskyring( images, outimages, outpref, axc, ayc, arad, rxc, ryc, pmin, pmax, swindow=5, clobber=False, logfile="salt.log", verbose=True, ): """Sky subtracts Fabry-Perot images""" # start log now that all parameter are set up 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, "") # verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, "Input", "output") for img, oimg in zip(infiles, outfiles): # open up the file hdu = saltio.openfits(img) # determine the azimuthally averaged profile rpro, radial_profile = median_radial_profile( hdu[0].data, xc=axc, yc=ayc, rmax=arad, nbins=100, pmin=pmin, pmax=pmax ) if swindow > 1: radial_profile = np.convolve(radial_profile, np.ones(swindow), mode="same") / swindow # calculate the indices from the image y, x = np.indices(hdu[0].data.shape) radius = np.hypot(x - axc, y - ayc) # subtract off the sky data mdata = hdu[0].data - np.interp(radius, rpro, radial_profile) hdu[0].data = mdata # write FITS file saltio.writefits(hdu, oimg, clobber=clobber) saltio.closefits(hdu) message = "SALTFPSKYRING -- Subtracted sky from %s" % (img) log.message(message, with_header=False)
def saltcrclean(images,outimages,outpref,crtype='fast',thresh=5,mbox=3, \ bthresh=3, flux_ratio=0.2, bbox=11, gain=1, rdnoise=5, fthresh=5,\ bfactor=2, gbox=3, maxiter=5, multithread=False, update=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.listparse('Outfile', outimages, outpref,infiles,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #check to see if multithreading is available if mp: pass else: multithread=False log.warning('multiprocessing module is not available. Setting multiththread=False') # Begin processes each file for infile,outfile in zip(infiles,outfiles): #open the infile struct=saltio.openfits(infile) #clean the cosmic rays if multithread and len(struct)>1: struct=multicrclean(struct, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \ gain, rdnoise, bfactor, fthresh, gbox, maxiter, log, verbose=verbose) else: struct=crclean(struct, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \ gain, rdnoise, bfactor, fthresh, gbox, maxiter, update, log, verbose=verbose) #log the call #log.message('Cleaned %i cosmic rays from %s using %s method' % (totcr, infile, crtype), with_header=False) log.message('', with_header=False, with_stdout=verbose) #add house keeping keywords saltkey.put('SAL-TLM',time.asctime(time.localtime()), struct[0]) #add the history keyword fname, hist=history(level=1, wrap=False) saltkey.history(struct[0],hist) #write out the file saltio.writefits(struct, outfile, clobber=clobber) #close the image saltio.closefits(struct)
def saltxtalk(images,outimages,outpref,xtalkfile=None, usedb=False, clobber=True, logfile='salt.log',verbose=True): #start logging 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,'') # are input and output lists the same length? saltio.comparelists(infiles,outfiles,'Input','output') # does crosstalk coefficient data exist if usedb: xtalkfile = xtalkfile.strip() xdict = saltio.readxtalkcoeff(xtalkfile) else: xdict=None for img, oimg in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) #find the best xcoeff for the image if using the db if usedb: obsdate=saltkey.get('DATE-OBS', struct[0]) obsdate=int('%s%s%s' % (obsdate[0:4],obsdate[5:7], obsdate[8:])) xkey=np.array(xdict.keys()) date=xkey[abs(xkey-obsdate).argmin()] xcoeff=xdict[date] else: xcoeff=[] # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot = saltkey.instrumid(struct) # has file been prepared already? if saltkey.found(keyxtalk, struct[0]): message='%s has already been xtalk corrected' % img raise SaltError(message) #apply the cross-talk correction struct = xtalk(struct, xcoeff, log=log, verbose=verbose) # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], 'SXTALK', 'Images have been xtalk corrected', hist) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct)
def saltcrclean(images,outimages,outpref,crtype='fast',thresh=5,mbox=3, \ bthresh=3, flux_ratio=0.2, bbox=11, gain=1, rdnoise=5, fthresh=5,\ bfactor=2, gbox=3, maxiter=5, multithread=False, update=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.listparse('Outfile', outimages, outpref, infiles, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') #check to see if multithreading is available if mp: pass else: multithread = False log.warning( 'multiprocessing module is not available. Setting multiththread=False' ) # Begin processes each file for infile, outfile in zip(infiles, outfiles): #open the infile struct = saltio.openfits(infile) #clean the cosmic rays if multithread and len(struct) > 1: struct=multicrclean(struct, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \ gain, rdnoise, bfactor, fthresh, gbox, maxiter, log, verbose=verbose) else: struct=crclean(struct, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \ gain, rdnoise, bfactor, fthresh, gbox, maxiter, update, log, verbose=verbose) #log the call #log.message('Cleaned %i cosmic rays from %s using %s method' % (totcr, infile, crtype), with_header=False) log.message('', with_header=False, with_stdout=verbose) #add house keeping keywords saltkey.put('SAL-TLM', time.asctime(time.localtime()), struct[0]) #add the history keyword fname, hist = history(level=1, wrap=False) saltkey.history(struct[0], hist) #write out the file saltio.writefits(struct, outfile, clobber=clobber) #close the image saltio.closefits(struct)
def specwavemap( images, outimages, outpref, solfile=None, caltype="line", function="polynomial", order=3, blank=0, nearest=False, clobber=True, logfile="salt.log", verbose=True, ): with logging(logfile, debug) as log: # set up the variables infiles = [] outfiles = [] # Check the input images infiles = saltsafeio.argunpack("Input", images) # create list of output files outfiles = saltsafeio.listparse("Outimages", outimages, outpref, infiles, "") # read in the wavelength solutions and enter them into # there own format if caltype == "line": soldict = sr.entersolution(solfile) else: soldict = None # read in rectify each image for img, oimg in zip(infiles, outfiles): if caltype == "line": msg = "Creating wave map image %s from image %s using files %s" % (oimg, img, solfile) else: msg = "Creating wave map image %s from image %s using RSS Model" % (oimg, img) log.message(msg) hdu = saltsafeio.openfits(img) hdu = wavemap( hdu, soldict, caltype=caltype, function=function, order=order, blank=blank, nearest=nearest, clobber=clobber, log=log, verbose=verbose, ) saltsafeio.writefits(hdu, oimg, clobber=clobber)
def saltslot(images, outimages, outpref, gaindb='', xtalkfile='', usedb=False, clobber=False, logfile='salt.log', verbose=True): #start logging 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, '') # are input and output lists the same length? saltio.comparelists(infiles, outfiles, 'Input', 'output') # does crosstalk coefficient data exist if usedb: dblist = saltio.readgaindb(gaindb) xtalkfile = xtalkfile.strip() xdict = saltio.readxtalkcoeff(xtalkfile) else: dblist = [] xdict = None for img, oimg in zip(infiles, outfiles): #open the fits file struct = saltio.openfits(img) # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltkey.instrumid( struct) # has file been prepared already? if saltkey.found(keygain, struct[0]): message = '%s has already been reduced' % img raise SaltError(message) # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], keyslot, 'Images have been slotmode reduced', hist) # write FITS file saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def specwavemap(images, outimages, outpref, solfile=None, caltype='line', function='polynomial', order=3, blank=0, nearest=False, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # set up the variables infiles = [] outfiles = [] # Check the input images infiles = saltsafeio.argunpack('Input', images) # create list of output files outfiles = saltsafeio.listparse('Outimages', outimages, outpref, infiles, '') # read in the wavelength solutions and enter them into # there own format if caltype == 'line': soldict = sr.entersolution(solfile) else: soldict = None # read in rectify each image for img, oimg, in zip(infiles, outfiles): if caltype == 'line': msg = 'Creating wave map image %s from image %s using files %s' % ( oimg, img, solfile) else: msg = 'Creating wave map image %s from image %s using RSS Model' % ( oimg, img) log.message(msg) hdu = saltsafeio.openfits(img) hdu = wavemap(hdu, soldict, caltype=caltype, function=function, order=order, blank=blank, nearest=nearest, clobber=clobber, log=log, verbose=verbose) saltsafeio.writefits(hdu, oimg, clobber=clobber)
def saltarith(operand1, op, operand2, result, outpref, divzero=0, clobber=False, \ logfile='salt.log',verbose=True): with logging(logfile, debug) as log: # Check the input images infiles = saltio.argunpack('Input', operand1) # create list of output files outfiles = saltio.listparse('Outfile', result, outpref, infiles, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') #let's keep track of whether operand2 is an image or not is_image = False #load in operand2, or, if it's not an image, assume it's a number try: operand2struct = float(operand2) except ValueError: operand2struct = saltio.openfits(operand2) is_image = True #open the input image files for infile, outfile in zip(infiles, outfiles): struct = saltio.openfits(infile) #do some math! outstruct = arith(struct, op, operand2struct, is_image, divzero) try: pass except Exception, e: msg = 'Unable to do math %s because %s' % (infile, e) raise SaltError(msg) #update header stuff fname, hist = history(level=1, wrap=False) saltkey.housekeeping(struct[0], 'SARITH', 'Some arithmatic was performed', hist) #write it. close it. saltio.writefits(outstruct, outfile, clobber=clobber) saltio.closefits(struct) #output the information log.message('imarith: %s %s %s %s' % (infile, op, operand2, outfile), with_header=False, with_stdout=verbose) #close the operand2 image if is_image: saltio.closefits(operand2struct)
def slotpreview(images,outfile,ampperccd=2,ignorexp=6,recenter_radius=5, tgt_col='b',cmp_col='g', tgt_lw=2,cmp_lw=2,cmap='gray', scale='zscale',contrast=0.1,clobber=True,logfile='salt.log', verbose=True): with logging(logfile,debug) as log: # is the input file specified? saltsafeio.filedefined('Input',images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input',images) # parse list of input files imlist=saltsafeio.listparse('Raw image',images,'','','') # check input files exist saltsafeio.filesexist(imlist,'','r') # is the output file specified? saltsafeio.filedefined('Output',outfile) # check output file does not exist, optionally remove it if it does exist if os.path.exists(outfile) and clobber: os.remove(outfile) elif os.path.exists(outfile) and not clobber: raise SaltIOError('File '+outfile+' already exists, use clobber=y') # Get the number of ccds to calculate the number of frames to skip try: nccds=pyfits.getheader(imlist[0])['NCCDS'] except: raise SaltIOError('Could not read NCCDS parameter from header of first fits file.') # Create GUI App = QtGui.QApplication(sys.argv) aw = ApplicationWindow(imlist=imlist, number=ignorexp*ampperccd*nccds+1, config=outfile, target_line_color=tgt_col, comparison_line_color=cmp_col, target_line_width=tgt_lw, comparison_line_width=cmp_lw, distance=recenter_radius, cmap=cmap, scale=scale, contrast=contrast) aw.show() # Start application event loop exit=App.exec_() # Check if GUI was executed succesfully if exit!=0: log.warning('Slotpreview GUI has unexpected exit status'+str(exit))
def slotreadtimefix(images, outimages, outpref, clobber=False, logfile='slot.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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') for img, oimg in zip(infiles, outfiles): #check to see if the out image already exists if not clobber and os.path.isfile(oimg): raise SaltIOError('%s alraedy exists' % oimg) #open the file struct = saltio.openfits(img) #log the message log.message('Updateing times in %s' % img, with_header=False, with_stdout=verbose) #now for each science frame, corrent the readtime #Assumes SALT format and that the first extension #is empty for i in range(1, len(struct)): try: struct[i] = readtimefix(struct[i]) except SaltIOError, e: raise SaltError('%s %s' % (img, e)) #Add history keywords # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], "SLOTREAD", 'READTIME added', hist) #write to the output saltio.writefits(struct, oimg, clobber) return
def saltarith(operand1, op, operand2, result, outpref, divzero=0, clobber=False, \ logfile='salt.log',verbose=True): with logging(logfile,debug) as log: # Check the input images infiles = saltio.argunpack ('Input',operand1) # create list of output files outfiles=saltio.listparse('Outfile', result, outpref, infiles,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #let's keep track of whether operand2 is an image or not is_image = False #load in operand2, or, if it's not an image, assume it's a number try: operand2struct = float(operand2) except ValueError: operand2struct = saltio.openfits(operand2) is_image = True #open the input image files for infile, outfile in zip(infiles,outfiles): struct = saltio.openfits(infile) #do some math! outstruct = arith(struct, op, operand2struct, is_image, divzero) try: pass except Exception as e: msg='Unable to do math %s because %s' % (infile, e) raise SaltError(msg) #update header stuff fname, hist = history(level=1, wrap=False) saltkey.housekeeping(struct[0],'SARITH', 'Some arithmatic was performed',hist) #write it. close it. saltio.writefits(outstruct,outfile,clobber=clobber) saltio.closefits(struct) #output the information log.message('imarith: %s %s %s %s' % (infile, op, operand2, outfile), with_header=False, with_stdout=verbose) #close the operand2 image if is_image: saltio.closefits(operand2struct)
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 saltmosaic(images,outimages,outpref,geomfile,interp='linear',geotran=True, cleanup=True,clobber=False,logfile=None,verbose=True): #Start the logging 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # does CCD geometry definition file exist geomfilefile = geomfile.strip() saltio.fileexists(geomfile) gap = 0 xshift = [0, 0] yshift = [0, 0] rotation = [0, 0] gap, xshift, yshift, rotation=saltio.readccdgeom(geomfile) # open each raw image file and apply the transformation to it for img, oimg in zip(infiles, outfiles): #open the structure struct = saltio.openfits(img) #create the mosaic ostruct=make_mosaic(struct, gap, xshift, yshift, rotation, interp_type=interp, geotran=geotran, cleanup=cleanup, log=log, verbose=verbose) #update the header information # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(ostruct[0], 'SMOSAIC', 'Images have been mosaicked ', hist) #write the image out saltio.writefits(ostruct,oimg, clobber=clobber) #close the files saltio.closefits(struct) saltio.closefits(ostruct)
def saltgain(images,outimages, outpref, gaindb=None,usedb=False, mult=True, clobber=True, logfile='salt.log',verbose=True): #start logging 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # read in the database file if usedb is true if usedb: gaindb = gaindb.strip() dblist= saltio.readgaindb(gaindb) else: dblist=[] for img, oimg in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot = saltkey.instrumid(struct) # has file been prepared already? if saltkey.found(keygain, struct[0]): message='SALTGAIN: %s has already been gain-corrected' % img raise SaltError(message) # gain correct the data struct = gain(struct,mult=mult, usedb=usedb, dblist=dblist, log=log, verbose=verbose) # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0],keygain, 'Images have been gain corrected', hist) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct)
def specrectify(images, outimages, outpref, solfile=None, caltype='line', function='polynomial', order=3, inttype='linear', w1=None, w2=None, dw=None, nw=None, blank=0, conserve=False, nearest=False, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # set up the variables infiles = [] outfiles = [] # Check the input images infiles = saltsafeio.argunpack('Input', images) # create list of output files outfiles = saltsafeio.listparse( 'Outimages', outimages, outpref, infiles, '') # read in the wavelength solutions and enter them into # there own format if caltype == 'line': soldict = entersolution(solfile) else: soldict = None # read in rectify each image for img, oimg, in zip(infiles, outfiles): if caltype == 'line': msg = 'Creating rectified image %s from image %s using files %s' % ( oimg, img, solfile) else: msg = 'Creating rectified image %s from image %s using RSS Model' % ( oimg, img) log.message(msg) hdu = saltsafeio.openfits(img) hdu = rectify(hdu, soldict, caltype=caltype, function=function, order=order, inttype=inttype, w1=w1, w2=w2, dw=dw, nw=nw, pixscale=0.0, blank=blank, conserve=conserve, nearest=nearest, clobber=clobber, log=log, verbose=verbose) # write out the oimg saltsafeio.writefits(hdu, oimg, clobber=clobber)
def saltslot(images,outimages,outpref,gaindb='',xtalkfile='',usedb=False, clobber=False,logfile='salt.log',verbose=True): #start logging 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,'') # are input and output lists the same length? saltio.comparelists(infiles,outfiles,'Input','output') # does crosstalk coefficient data exist if usedb: dblist= saltio.readgaindb(gaindb) xtalkfile = xtalkfile.strip() xdict = saltio.readxtalkcoeff(xtalkfile) else: dblist=[] xdict=None for img, oimg in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot = saltkey.instrumid(struct) # has file been prepared already? if saltkey.found(keygain, struct[0]): message='%s has already been reduced' % img raise SaltError(message) # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0],keyslot, 'Images have been slotmode reduced', hist) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct)
def saltfpmask(images, outimages, outpref, axc,ayc, arad, maskmethod='c', maskvalue=0, \ radi=None,rado=None,clobber=False, logfile='saltfp.log', verbose=True): """Aperture masks Fabry-Perot images""" 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') for img, oimg in zip(infiles, outfiles): #open the image hdu = saltio.openfits(img) #test that the data are in the first try: data = hdu[0].data except Exception, e: message = 'SALTFPMASK--ERROR: Could not access data in Primary exention of %s because %s' % ( img, e) log.message(message) #determine the mask value if it is a region if maskmethod == 'region': maskvalue = calc_maskvalue(data, axc, ayc, radi, rado) #mask the image message = "SALTFPMASK--Masking image %s with a value of %s" % ( img, maskvalue) log.message(message, with_header=False) hdu[0].data = maskimage(data, axc, ayc, arad, maskvalue) try: pass except Exception, e: message = 'SALTFPMASK--ERROR: Could not create mask for %s because %s' % ( img, e) log.message(message) #write out the image saltio.writefits(hdu, oimg, clobber=clobber)
def slotreadtimefix(images,outimages, outpref, clobber=False, logfile='slot.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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') for img, oimg in zip(infiles, outfiles): #check to see if the out image already exists if not clobber and os.path.isfile(oimg): raise SaltIOError('%s alraedy exists' % oimg) #open the file struct=saltio.openfits(img) #log the message log.message('Updateing times in %s' % img, with_header=False, with_stdout=verbose) #now for each science frame, corrent the readtime #Assumes SALT format and that the first extension #is empty for i in range(1,len(struct)): try: struct[i]=readtimefix(struct[i]) except SaltIOError,e : raise SaltError('%s %s' % (img,e)) #Add history keywords # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0],"SLOTREAD", 'READTIME added', hist) #write to the output saltio.writefits(struct, oimg, clobber) return
def saltsurface(images, outimages, outpref, mask=True, order=3, minlevel=0, clobber=False, 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') # open each raw image file for infile, outfile in zip(infiles, outfiles): struct = saltio.openfits(infile) struct = surface_fit(struct, order=order, mask=mask, minlevel=minlevel) #add any header keywords like history fname, hist = history(level=1, wrap=False) saltkey.housekeeping(struct[0], 'SURFIT', 'File fit by a surface', hist) #write it out and close it saltio.writefits(struct, outfile, clobber=clobber) saltio.closefits(struct) #output the information log.message('Surface fitted image %s ' % (infile), with_header=False, with_stdout=verbose)
def saltfpmask(images, outimages, outpref, axc,ayc, arad, maskmethod='c', maskvalue=0, \ radi=None,rado=None,clobber=False, logfile='saltfp.log', verbose=True): """Aperture masks Fabry-Perot images""" 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') for img, oimg in zip(infiles, outfiles): #open the image hdu=saltio.openfits(img) #test that the data are in the first try: data=hdu[0].data except Exception, e: message='SALTFPMASK--ERROR: Could not access data in Primary exention of %s because %s' % (img, e) log.message(message) #determine the mask value if it is a region if maskmethod=='region': maskvalue=calc_maskvalue(data, axc, ayc, radi, rado) #mask the image message="SALTFPMASK--Masking image %s with a value of %s" % (img, maskvalue) log.message(message, with_header=False) hdu[0].data= maskimage(data, axc, ayc, arad, maskvalue) try: pass except Exception, e: message='SALTFPMASK--ERROR: Could not create mask for %s because %s' % (img, e) log.message(message) #write out the image saltio.writefits(hdu, oimg, clobber=clobber)
def saltfpzeropoint(images,outimages, outpref, calfile, fpa, fpb, fpc, fpd, fpe, fpf, clobber=False,logfile='salt.log',verbose=True): """Adds zeropoint information to each image""" with logging(logfile,debug) as log: # Check the input images infiles = saltio.argunpack ('Input',images) # create the output files outfiles=saltio.listparse('Outfile', outimages, outpref,infiles,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #calculate the zeropoint coefficients fpcoef=np.array([fpa,fpb,fpc,fpd,fpe,fpf]) zpcoef,tstart=calc_zpcoef(calfile, fpcoef) # open each image and detect the ring for img, oimg in zip(infiles, outfiles): hdu=saltio.openfits(img) #get the image time t=(get_datetime(hdu)-tstart).seconds #add the header values to the image saltkey.new('FPA',fpa+zpcoef[1]+zpcoef[0]*t,'FPA Coef',hdu[0]) saltkey.new('FPB',fpb,'FPB Coef',hdu[0]) saltkey.new('FPC',fpc,'FPC Coef',hdu[0]) saltkey.new('FPD',fpd,'FPD Coef',hdu[0]) saltkey.new('FPE', 0,'FPE Coef',hdu[0]) saltkey.new('FPF',fpf,'FPF Coef',hdu[0]) #write the file out saltio.writefits(hdu, oimg, clobber) #log the action msg='Updating the FP information in %s' % (img) log.message(msg, with_stdout=verbose, with_header=False)
def specprepare(images,outimages,outpref,badpixelimage='', \ 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # open the badpixel image if saltio.checkfornone(badpixelimage) is None: badpixelstruct=None else: try: badpixelstruct = saltio.openfits(badpixelimage) except saltio.SaltIOError,e: msg='badpixel image must be specificied\n %s' % e raise SALTSpecError(msg) # open each raw image file for img, oimg, in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) # prepare file struct=prepare(struct,badpixelstruct) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct) message = 'SPECPREPARE -- %s => %s' % (img, oimg) log.message(message)
def salt2iraf(images,outimages,outpref,ext=1, 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') for img, oimg in zip(infiles, outfiles): message="SALT2IRAF--Converting %s to %s" % (img, oimg) log.message(message, with_header=False) try: convertsalt(img, oimg, ext=ext, clobber=clobber) except SaltError, e: log.message('%s' % e)
def saltfpprep(images, outimages, outpref, clobber=True, logfile='saltfp.log', verbose=True): """Prepares data for Fabry-Perot reductions""" 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') for img, oimg in zip(infiles, outfiles): message="SALTFPPREP--Preparing image %s" % (img) log.message(message, with_header=False) try: convertsalt(img, oimg, clobber=clobber) except SaltError, e: log.message('%s' %e)
def saltfpprep(images, outimages, outpref, clobber=True, logfile='saltfp.log', verbose=True): """Prepares data for Fabry-Perot reductions""" 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') for img, oimg in zip(infiles, outfiles): message="SALTFPPREP--Preparing image %s" % (img) log.message(message, with_header=False) try: convertsalt(img, oimg, clobber=clobber) except SaltError as e: log.message('%s' %e)
def specprepare(images, outimages, outpref, badpixelimage='', 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, '') # verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') # open the badpixel image if saltio.checkfornone(badpixelimage) is None: badpixelstruct = None else: try: badpixelstruct = saltio.openfits(badpixelimage) except saltio.SaltIOError as e: msg = 'badpixel image must be specificied\n %s' % e raise SALTSpecError(msg) # open each raw image file for img, oimg, in zip(infiles, outfiles): # open the fits file struct = saltio.openfits(img) # prepare file struct = prepare(struct, badpixelstruct) # write FITS file saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct) message = 'SPECPREPARE -- %s => %s' % (img, oimg) log.message(message)
def saltembed(images,outimages,outpref, 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # open each raw image file for img, oimg, in zip(infiles, outfiles): #open the fits file struct=saltio.openfits(img) #get the number of CCDs nccd=saltkey.get('NCCDS', struct[0]) #set the number of amps per CCD--*TODO* Read from header namps=2 #get the number of windows--try to read from header try: nwindows=saltkey.get('NWINDOWS', struct[0]) except: nwindows=len(struct)/(nccd*namps) outstruct=embedimage(struct, nccd, namps, nwindows) saltio.writefits(outstruct, oimg, clobber=clobber) message = 'SALTEMBED -- %s => %s' % (img, oimg) log.message(message, with_header=False)
def saltfpskyring(images, outimages, outpref, axc, ayc, arad, rxc, ryc, pmin, pmax, swindow=5, clobber=False, logfile='salt.log', verbose=True): """Sky subtracts Fabry-Perot images""" # start log now that all parameter are set up 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, '') #verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') for img, oimg in zip(infiles, outfiles): #open up the file hdu = saltio.openfits(img) #determine the azimuthally averaged profile rpro, radial_profile = median_radial_profile(hdu[0].data, xc=axc, yc=ayc, rmax=arad, nbins=100, pmin=pmin, pmax=pmax) if swindow > 1: radial_profile = np.convolve( radial_profile, np.ones(swindow), mode='same') / swindow # calculate the indices from the image y, x = np.indices(hdu[0].data.shape) radius = np.hypot(x - axc, y - ayc) #subtract off the sky data mdata = hdu[0].data - np.interp(radius, rpro, radial_profile) hdu[0].data = mdata # write FITS file saltio.writefits(hdu, oimg, clobber=clobber) saltio.closefits(hdu) message = 'SALTFPSKYRING -- Subtracted sky from %s' % (img) log.message(message, with_header=False)
def saltheadtime(images,timetype,writetoheader,clobber,logfile,verbose,debug): # Start log. with logging(logfile,debug) as log: # is the input file specified? saltsafeio.filedefined('Input',images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input',images) # parse list of input files infiles=saltsafeio.listparse('Raw image',images,'','','') # check input files exist saltsafeio.filesexist(infiles,'','r') # Loop over the input files. for file in infiles: print '---------------------------------------------------------\n\ ' print 'Reading file ', file openfile= saltsafeio.openfits(file) #Get information from header, display it, and close file. headers=openfile[0].header dateTimeString=[] ra=headers['RA'] dec=headers['DEC'] objEpoch=headers['EPOCH'] obsEquinox=headers['EQUINOX'] if headers['DETMODE']=='SLOT': numExtensions=headers['NEXTEND'] print 'Detector mode is slot. Number of extensions in this file is '+str(numExtensions)+'.' for num in range(numExtensions+1): extheader=openfile[num].header dateTimeString.append(extheader['DATE-OBS']+extheader['TIME-OBS']) else: dateTimeString.append(headers['DATE-OBS']+headers['TIME-OBS']) openfile.close() #Convert times. All equations are in library, salttime.py. newTime=[] if timetype=="JD(UTC)": for num in range(len(dateTimeString)): newTime.append(convertUTtoJDUTC(dateTimeString[num])) keyword='JDUT-OBS' comment='Julian Date ref. to UTC.' print 'The date and time from header extension '+ str(num) +' are:', dateTimeString[num], "UTC" print 'Converted time ('+ timetype +') ='+str(newTime[num])+'\n\ ' elif timetype=="JD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoJD(dateTimeString[num])) keyword='JD-OBS' comment='Julian Date ref. to TT (Terrestrial timescale)' print 'The date and time from header extension '+ str(num) +' are:', dateTimeString[num], "UTC" print 'Converted time ('+ timetype +') ='+str(newTime[num])+'\n\ ' elif timetype=="MJD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoMJD(dateTimeString[num])) keyword='MJD-OBS' comment='Modified JD ref. to TT (Terrestrial timescale)' print 'The date and time from header extension '+ str(num) +' are:', dateTimeString[num], "UTC" print 'Converted time ('+ timetype +') ='+str(newTime[num])+'\n\ ' elif timetype=="HJD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoHJD(dateTimeString[num],ra,dec)) keyword='HJD-OBS' comment='Heliocentric JD ref. to TT (Terrestrial timescale)' print 'The date and time from header extension '+ str(num) +' are:', dateTimeString[num], "UTC" print 'Converted time ('+ timetype +') ='+str(newTime[num])+'\n\ ' elif timetype=="BJD(TDB)": for num in range(len(dateTimeString)): newTime.append(convertUTtoBJD(dateTimeString[num],ra,dec)) keyword='BJD-OBS' comment='Barycentric JD ref. to TDB (Barycentric Dynamical Time)' print 'The date and time from header extension '+ str(num) +' are:', dateTimeString[num], "UTC" print 'Converted time ('+ timetype +') ='+str(newTime[num])+'\n\ ' #Open file to write new time to header, if desired. if writetoheader: try: filetowrite=fits.open(file,mode='update') except Exception, e: print e for num in range(len(dateTimeString)): hdr=filetowrite[num].header if hdr.has_key(keyword)==1: if clobber: hdr.update(keyword,newTime[num],comment) print 'Keyword ' +keyword +' has been updated in header extension '+str(num)+' to the following value: '+ str(newTime[num]) else: print 'Keyword '+keyword+' has not been updated.' else: hdr.update(keyword,newTime[num],comment,after='TIME-OBS') print 'Keyword ' + keyword +' has been added to header extension '+str(num)+' as the following value: '+ str(newTime[num]) filetowrite.flush() filetowrite.close()
def saltheadtime(images, timetype, writetoheader, clobber, logfile, verbose, debug): # Start log. with logging(logfile, debug) as log: # is the input file specified? saltsafeio.filedefined('Input', images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input', images) # parse list of input files infiles = saltsafeio.listparse('Raw image', images, '', '', '') # check input files exist saltsafeio.filesexist(infiles, '', 'r') # Loop over the input files. for file in infiles: print '---------------------------------------------------------\n\ ' print 'Reading file ', file openfile = saltsafeio.openfits(file) #Get information from header, display it, and close file. headers = openfile[0].header dateTimeString = [] ra = headers['RA'] dec = headers['DEC'] objEpoch = headers['EPOCH'] obsEquinox = headers['EQUINOX'] if headers['DETMODE'] == 'SLOT': numExtensions = headers['NEXTEND'] print 'Detector mode is slot. Number of extensions in this file is ' + str( numExtensions) + '.' for num in range(numExtensions + 1): extheader = openfile[num].header dateTimeString.append(extheader['DATE-OBS'] + extheader['TIME-OBS']) else: dateTimeString.append(headers['DATE-OBS'] + headers['TIME-OBS']) openfile.close() #Convert times. All equations are in library, salttime.py. newTime = [] if timetype == "JD(UTC)": for num in range(len(dateTimeString)): newTime.append(convertUTtoJDUTC(dateTimeString[num])) keyword = 'JDUT-OBS' comment = 'Julian Date ref. to UTC.' print 'The date and time from header extension ' + str( num) + ' are:', dateTimeString[num], "UTC" print 'Converted time (' + timetype + ') =' + str( newTime[num]) + '\n\ ' elif timetype == "JD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoJD(dateTimeString[num])) keyword = 'JD-OBS' comment = 'Julian Date ref. to TT (Terrestrial timescale)' print 'The date and time from header extension ' + str( num) + ' are:', dateTimeString[num], "UTC" print 'Converted time (' + timetype + ') =' + str( newTime[num]) + '\n\ ' elif timetype == "MJD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoMJD(dateTimeString[num])) keyword = 'MJD-OBS' comment = 'Modified JD ref. to TT (Terrestrial timescale)' print 'The date and time from header extension ' + str( num) + ' are:', dateTimeString[num], "UTC" print 'Converted time (' + timetype + ') =' + str( newTime[num]) + '\n\ ' elif timetype == "HJD(TT)": for num in range(len(dateTimeString)): newTime.append(convertUTtoHJD(dateTimeString[num], ra, dec)) keyword = 'HJD-OBS' comment = 'Heliocentric JD ref. to TT (Terrestrial timescale)' print 'The date and time from header extension ' + str( num) + ' are:', dateTimeString[num], "UTC" print 'Converted time (' + timetype + ') =' + str( newTime[num]) + '\n\ ' elif timetype == "BJD(TDB)": for num in range(len(dateTimeString)): newTime.append(convertUTtoBJD(dateTimeString[num], ra, dec)) keyword = 'BJD-OBS' comment = 'Barycentric JD ref. to TDB (Barycentric Dynamical Time)' print 'The date and time from header extension ' + str( num) + ' are:', dateTimeString[num], "UTC" print 'Converted time (' + timetype + ') =' + str( newTime[num]) + '\n\ ' #Open file to write new time to header, if desired. if writetoheader: try: filetowrite = fits.open(file, mode='update') except Exception, e: print e for num in range(len(dateTimeString)): hdr = filetowrite[num].header if hdr.has_key(keyword) == 1: if clobber: hdr.update(keyword, newTime[num], comment) print 'Keyword ' + keyword + ' has been updated in header extension ' + str( num) + ' to the following value: ' + str( newTime[num]) else: print 'Keyword ' + keyword + ' has not been updated.' else: hdr.update(keyword, newTime[num], comment, after='TIME-OBS') print 'Keyword ' + keyword + ' has been added to header extension ' + str( num) + ' as the following value: ' + str( newTime[num]) filetowrite.flush() filetowrite.close()
def saltmosaic(images, outimages, outpref, geomfile, interp='linear', geotran=True, fill=False, cleanup=True, clobber=False, logfile=None, verbose=True): # Start the logging 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, '') # verify that the input and output lists are the same length saltio.comparelists(infiles, outfiles, 'Input', 'output') # does CCD geometry definition file exist geomfilefile = geomfile.strip() saltio.fileexists(geomfile) gap = 0 xshift = [0, 0] yshift = [0, 0] rotation = [0, 0] gap, xshift, yshift, rotation = saltio.readccdgeom(geomfile) # open each raw image file and apply the transformation to it for img, oimg in zip(infiles, outfiles): # open the structure struct = saltio.openfits(img) # create the mosaic ostruct = make_mosaic(struct, gap, xshift, yshift, rotation, interp_type=interp, geotran=geotran, fill=fill, cleanup=cleanup, log=log, verbose=verbose) # update the header information # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(ostruct[0], 'SMOSAIC', 'Images have been mosaicked', hist) # write the image out ostruct.writeto(oimg, clobber=clobber, output_verify='ignore') # close the files struct.close() ostruct.close()
def saltbias(images, outimages, outpref, subover=True, trim=True, subbias=False, masterbias='bias.fits', median=False, function='polynomial', order=3, rej_lo=3, rej_hi=3, niter=10, plotover=False, turbo=False, clobber=False, logfile='salt.log', verbose=True): status = 0 ifil = 0 ii = 0 mbiasdata = [] bstruct = '' biasgn = '' biassp = '' biasbn = '' biasin = '' filetime = {} biastime = {} for i in range(1, 7): filetime[i] = [] biastime[i] = [] 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, '') # are input and output lists the same length? saltio.comparelists(infiles, outfiles, 'Input', 'output') # Does master bias frame exist? # gain, speed, binning and instrument of master bias frame if subbias: if os.path.isfile(masterbias): bstruct = saltio.openfits(masterbias) else: message = 'Master bias frame %s does not exist' % masterbias raise SaltError(message) else: bstruct = None # open each raw image file for img, oimg in zip(infiles, outfiles): #open the file struct = saltio.openfits(img) #check to see if it has already been bias subtracted instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltkey.instrumid( struct) # has file been biaseded already? try: key = struct[0].header[keybias] message = 'File %s has already been de-biased ' % infile raise SaltError(message) except: pass #compare with the master bias to make sure they are the same if subbias: pass #subtract the bias struct = bias(struct, subover=subover, trim=trim, subbias=subbias, bstruct=bstruct, median=median, function=function, order=order, rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, log=log, verbose=verbose) #write the file out # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], keybias, 'Images have been de-biased', hist) # write FITS file saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def slotmerge(images, outimages, outpref, geomfile, clobber, logfile, verbose): with logging(logfile, debug) as log: # are the arguments defined saltsafeio.argdefined('images', images) saltsafeio.argdefined('geomfile', geomfile) saltsafeio.argdefined('logfile', logfile) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input', images) # parse list of input files infiles = saltsafeio.listparse('Raw image', images, '', '', '') # check input files exist saltsafeio.filesexist(infiles, '', 'r') # load output name list: @list, * and comma separated outimages = outimages.strip() outpref = outpref.strip() if len(outpref) == 0 and len(outimages) == 0: raise SaltIOError('Output file(s) not specified') # test output @filelist exists if len(outimages) > 0 and outimages[0] == '@': saltsafeio.listexists('Output', outimages) # parse list of output files outfiles = saltsafeio.listparse('Output image', outimages, outpref, infiles, '') # are input and output lists the same length? saltsafeio.comparelists(infiles, outfiles, 'Input', 'output') # do the output files already exist? if not clobber: saltsafeio.filesexist(outfiles, '', 'w') # does CCD geometry definition file exist geomfilefile = geomfile.strip() saltsafeio.fileexists(geomfile) # read geometry definition file gap = 0 xshift = [0, 0] yshift = [0, 0] rotation = [0, 0] gap, xshift, yshift, rotation = saltsafeio.readccdgeom(geomfile) for ro in rotation: if ro != 0: log.warning('SLOTMERGE currently ignores CCD rotation') # Begin processes each file for infile, outfile in zip(infiles, outfiles): # determine the name for the output file outpath = outfile.rstrip(os.path.basename(outfile)) if (len(outpath) == 0): outpath = '.' # open each raw image struct = saltsafeio.openfits(infile) # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltsafekey.instrumid( struct, infile) # how many amplifiers? nccds = saltsafekey.get('NCCDS', struct[0], infile) amplifiers = nccds * 2 #if (nccds != 2): # raise SaltError('Can not currently handle more than two CCDs') # CCD geometry coefficients if instrume == 'RSS' or instrume == 'PFIS': xsh = [xshift[0], 0., xshift[1]] ysh = [yshift[0], 0., yshift[1]] rot = [rotation[0], 0., rotation[1]] refid = 1 if instrume == 'SALTICAM': xsh = [xshift[0], 0.] ysh = [yshift[0], 0.] rot = [rotation[0], 0] refid = 1 # how many extensions? nextend = saltsafekey.get('NEXTEND', struct[0], infile) # how many exposures exposures = nextend / amplifiers # CCD on-chip binning xbin, ybin = saltsafekey.ccdbin(struct[0], infile) gp = int(gap / xbin) # create output hdu structure outstruct = [None] * int(exposures + 1) outstruct[0] = struct[0] # iterate over exposures, stitch them to produce file of CCD images for i in range(exposures): # Determine the total size of the image xsize = 0 ysize = 0 for j in range(amplifiers): hdu = i * amplifiers + j + 1 try: xsize += len(struct[hdu].data[0]) if ysize < len(struct[hdu].data): ysize = len(struct[hdu].data) except: msg = 'Unable to access extension %i ' % hdu raise SaltIOError(msg) xsize += gp * (nccds - 1) maxxsh, minxsh = determineshifts(xsh) maxysh, minysh = determineshifts(ysh) xsize += (maxxsh - minxsh) ysize += (maxysh - minysh) # Determine the x and y origins for each frame xdist = 0 ydist = 0 shid = 0 x0 = np.zeros(amplifiers) y0 = np.zeros(amplifiers) for j in range(amplifiers): x0[j] = xdist + xsh[shid] - minxsh y0[j] = ysh[shid] - minysh hdu = i * amplifiers + j + 1 darr = struct[hdu].data xdist += len(darr[0]) if j % 2 == 1: xdist += gp shid += 1 # make the out image outarr = np.zeros((ysize, xsize), np.float64) # Embed each frame into the output array for j in range(amplifiers): hdu = i * amplifiers + j + 1 darr = struct[hdu].data outarr = salttran.embed(darr, x0[j], y0[j], outarr) # Add the outimage to the output structure hdu = i * amplifiers + 1 outhdu = i + 1 outstruct[outhdu] = pyfits.ImageHDU(outarr) outstruct[outhdu].header = struct[hdu].header # Fix the headers in each extension datasec = '[1:%4i,1:%4i]' % (xsize, ysize) saltsafekey.put('DATASEC', datasec, outstruct[outhdu], outfile) saltsafekey.rem('DETSIZE', outstruct[outhdu], outfile) saltsafekey.rem('DETSEC', outstruct[outhdu], outfile) saltsafekey.rem('CCDSEC', outstruct[outhdu], outfile) saltsafekey.rem('AMPSEC', outstruct[outhdu], outfile) # add housekeeping key words outstruct[outhdu] = addhousekeeping(outstruct[outhdu], outhdu, outfile) # close input FITS file saltsafeio.closefits(struct) # housekeeping keywords keymosaic = 'SLOTMERG' fname, hist = history(level=1, wrap=False) saltsafekey.housekeeping(struct[0], keymosaic, 'Amplifiers have been mosaiced', hist) #saltsafekey.history(outstruct[0],hist) # this is added for later use by saltsafekey.put('NCCDS', 0.5, outstruct[0]) saltsafekey.put('NSCIEXT', exposures, outstruct[0]) saltsafekey.put('NEXTEND', exposures, outstruct[0]) # write FITS file of mosaiced image outstruct = pyfits.HDUList(outstruct) saltsafeio.writefits(outstruct, outfile, clobber=clobber)
def specslitnormalize(images, outimages, outpref, response=None, response_output=None, order=2, conv=1e-2, niter=20, startext=0, clobber=False, 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, '') # read in the response function response = saltio.checkfornone(response) if response: log.message('Loading response from %s' % response) response = readresponse(response) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): # open the image hdu = saltio.openfits(img) for i in range(startext, len(hdu)): if hdu[i].name == 'SCI': log.message('Normalizing extension %i in %s' % (i, img)) # things that will change for each slit # set up the data for the source try: data = hdu[i].data except Exception as e: message = \ 'Unable to read in data array in %s because %s' % \ (img, e) raise SALTSpecError(message) if response is None: response = create_response( data, spatial_axis=1, order=order, conv=conv, niter=niter) if response_output: write_response(response, clobber=clobber) else: # add a check that the response is the same shape as # the data if len(response) != data.shape[0]: raise SALTSpecError( 'Length of response function does not equal size of image array') # correct the data data = data / response # correct the variance frame if saltkey.found('VAREXT', hdu[i]): vhdu = saltkey.get('VAREXT', hdu[i]) hdu[vhdu].data = hdu[vhdu].data / response saltio.writefits(hdu, ofile, clobber=clobber)
def salteditkey(images,outimages,outpref, keyfile, recfile=None,clobber=False,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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') #is key file defined saltio.argdefined('keyfile',keyfile) keyfile = keyfile.strip() saltio.fileexists(keyfile) # if the data are the same, set up to use update instead of write openmode='copyonwrite' if (infiles!=outfiles): openmode='copyonwrite' # determine the date of the observations obsdate=saltstring.makeobsdatestr(infiles, 1,9) if len(obsdate)!=8: message = 'Either FITS files from multiple dates exist, ' message += 'or raw FITS files exist with non-standard names.' log.warning(message) # FITS file columns to record keyword changes fitcol = [] keycol = [] oldcol = [] newcol = [] # Set up the rules to change the files keyedits=readkeyfile(keyfile, log=log, verbose=verbose) #now step through the images for img, oimg in zip(infiles, outfiles): #determine the appropriate keyword edits for the image klist=[] for frange in keyedits: if checkfitsfile(img, frange, keyedits[frange]): klist.append(keyedits[frange][3]) if klist: #open up the new files struct = saltio.openfits(img,mode=openmode) struct.verify('fix') for kdict in klist: for keyword in kdict: #record the changes value=kdict[keyword] fitcol.append(img) keycol.append(keyword) newcol.append(value) try: oldcol.append(struct[0].header[keyword].lstrip()) except: oldcol.append('None') #update the keyword if saltkey.found(keyword, struct[0]): try: saltkey.put(keyword,value,struct[0]) message='\tUpdating %s in %s to %s' % (keyword, os.path.basename(img), value) log.message(message, with_header=False, with_stdout=verbose) except Exception, e: message = 'Could not update %s in %s because %s' % (keyword, img, str(e)) raise SaltError(message) else: try: saltkey.new(keyword.strip(),value,'Added Comment',struct[0]) message='\tAdding %s in %s to %s' % (keyword, os.path.basename(img), value) log.message(message, with_header=False, with_stdout=verbose) except Exception,e : message = 'Could not update %s in %s because %s' % (keyword, img, str(e)) raise SaltError(message) #updat the history keywords #fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) #saltkey.housekeeping(struct[0],'SAL-EDT', 'Keywords updated by SALTEDITKEY', hist) #write the file out if openmode=='update': saltio.updatefits(struct) message = 'Updated file ' + os.path.basename(oimg) else: saltio.writefits(struct, oimg, clobber) message = 'Created file ' + os.path.basename(oimg) log.message(message, with_header=False, with_stdout=True) struct.close()
def specslitnormalize(images, outimages, outpref, response=None, response_output=None, order=2, conv=1e-2, niter=20, startext=0, clobber=False, 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, '') # read in the response function response = saltio.checkfornone(response) if response: log.message('Loading response from %s' % response) response = readresponse(response) # Identify the lines in each file for img, ofile in zip(infiles, outfiles): # open the image hdu = saltio.openfits(img) for i in range(startext, len(hdu)): if hdu[i].name == 'SCI': log.message('Normalizing extension %i in %s' % (i, img)) # things that will change for each slit # set up the data for the source try: data = hdu[i].data except Exception as e: message = \ 'Unable to read in data array in %s because %s' % \ (img, e) raise SALTSpecError(message) if response is None: response = create_response(data, spatial_axis=1, order=order, conv=conv, niter=niter) if response_output: write_response(response, clobber=clobber) else: # add a check that the response is the same shape as # the data if len(response) != data.shape[0]: raise SALTSpecError( 'Length of response function does not equal size of image array' ) # correct the data data = data / response # correct the variance frame if saltkey.found('VAREXT', hdu[i]): vhdu = saltkey.get('VAREXT', hdu[i]) hdu[vhdu].data = hdu[vhdu].data / response saltio.writefits(hdu, ofile, clobber=clobber)
def specslit(image, outimage, outpref, exttype='auto', slitfile='', outputslitfile='', regprefix='', sections=3, width=25, sigma=2.2, thres=6, order=3, padding=5, yoffset=0, inter=False, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # check all the input and make sure that all the input needed is provided # by the user # read the image or image list and check if each in the list exist infiles = saltio.argunpack('Input', image) # unpack the outfiles outfiles = saltio.listparse('Outimages', outimage, outpref, infiles, '') # from the extraction type, check whether the input file is specified. # if the slitfile parameter is specified then use the slit files for # the extraction. if the extraction type is auto then use image for the # detection and the slit extraction if exttype == 'rsmt' or exttype == 'fits' or exttype == 'ascii' or exttype == 'ds9': slitfiles = saltio.argunpack('Slitfile', slitfile) if len(slitfiles) == 1: slitfiles = slitfiles * len(infiles) saltio.comparelists(infiles, slitfiles, 'image', 'slitfile') elif exttype == 'auto': slitfiles = infiles log.message( 'Extraction type is AUTO. Slit detection will be done from image' ) # read in if an optional ascii file is requested if len(outputslitfile) > 0: outslitfiles = saltio.argunpack('Outslitfiles', outputslitfile) saltio.comparelists(infiles, outslitfiles, 'image', 'outputslitfile') else: outslitfiles = [''] * len(infiles) # check if the width and sigma parameters were specified. # default is 25 and 2.2 if width < 10.: msg = 'The width parameter needs be a value larger than 10' raise SALTSpecError(msg) if sigma < 0.0: msg = 'Sigma must be greater than zero' raise SaltSpecError(msg) # check the treshold parameter. this needs to be specified by the user if thres <= 0.0: msg = 'Threshold must be greater than zero' raise SaltSpecError(msg) # check to make sure that the sections are greater than the order if sections <= order: msg = 'Number of sections must be greater than the order for the spline fit' raise SaltSpecError(msg) # run through each of the images and extract the slits for img, oimg, sfile, oslit in zip(infiles, outfiles, slitfiles, outslitfiles): log.message('Proccessing image %s' % img) # open the image struct = saltio.openfits(img) ylen, xlen = struct[1].data.shape xbin, ybin = saltkey.ccdbin(struct[0], img) # setup the VARIANCE and BPM frames if saltkey.found('VAREXT', struct[1]): varext = saltkey.get('VAREXT', struct[1]) varlist = [] else: varext = None # setup the BPM frames if saltkey.found('BPMEXT', struct[1]): bpmext = saltkey.get('BPMEXT', struct[1]) bpmlist = [] else: bpmext = None # open the slit definition file or identify the slits in the image slitmask = None ycheck = False if exttype == 'rsmt': log.message('Using slits from %s' % sfile) if yoffset is None: yoffset = 0 ycheck = True slitmask = mt.read_slitmask_from_xml(sfile) xpos = -0.3066 ypos = 0.0117 cx = int(xlen / 2.0) cy = int(ylen / 2.0) + ypos / 0.015 / ybin + yoffset order, slit_positions = mt.convert_slits_from_mask( slitmask, order=1, xbin=xbin, ybin=ybin, pix_scale=0.1267, cx=cx, cy=cy) sections = 1 elif exttype == 'fits': log.message('Using slits from %s' % sfile) order, slit_positions = read_slits_from_fits(sfile) elif exttype == 'ascii': log.message('Using slits from %s' % sfile) order, slit_positions = mt.read_slits_from_ascii(sfile) elif exttype == 'ds9': log.message('Using slits from %s' % sfile) order, slit_positions, slitmask = mt.read_slits_from_ds9( sfile, order=order) slitmask = None sections = 1 elif exttype == 'auto': log.message('Identifying slits in %s' % img) # identify the slits in the image order, slit_positions = identify_slits(struct[1].data, order, sections, width, sigma, thres) # write out the slit identifications if ofile has been supplied if oslit: log.message('Writing slit positions to %s' % oslit) mt.write_outputslitfile(slit_positions, oslit, order) if ycheck: slit_positions, dy = check_ypos(slit_positions, struct[1].data) log.message('Using an offset of {}'.format(dy)) # extract the slits spline_x = mt.divide_image(struct[1].data, sections) spline_x = 0.5 * (np.array(spline_x[:-1]) + np.array(spline_x[1:])) extracted_spectra, spline_positions = mt.extract_slits( slit_positions, spline_x, struct[1].data, order=order, padding=padding) if varext: extracted_var, var_positions = mt.extract_slits( slit_positions, spline_x, struct[varext].data, order=order, padding=padding) if bpmext: extracted_bpm, bpm_positions = mt.extract_slits( slit_positions, spline_x, struct[bpmext].data, order=order, padding=padding) # write out the data to the new array # create the new file hdulist = fits.HDUList([struct[0]]) # log the extracted spectra if needed log.message('', with_stdout=verbose) # setup output ds9 file if regprefix: regout = open( regprefix + os.path.basename(img).strip('.fits') + '.reg', 'w') regout.write('# Region file format: DS9 version 4.1\n') regout.write('# Filename: %s\n' % img) regout.write( '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\nphysical\n' ) # add each imglist = [] nslits = len(spline_positions) for i in range(nslits): y1 = spline_positions[i][0].min() y2 = spline_positions[i][1].max() msg = 'Extracted Spectra %i between %i to %i' % (i + 1, y1, y2) # log.message(msg, with_header=False, with_stdout=verbose) sdu = fits.ImageHDU(extracted_spectra[i], header=struct[1].header) if varext: vdu = fits.ImageHDU(extracted_var[i], header=struct[varext].header) sdu.header['VAREXT'] = i + nslits + 1 varlist.append(vdu) if bpmext: bdu = fits.ImageHDU(extracted_bpm[i], header=struct[bpmext].header) sdu.header['BPMEXT'] = i + 2 * nslits + 1 bpmlist.append(bdu) imglist.append(sdu) # add in some additional keywords imglist[i].header['MINY'] = (y1, 'Lower Y value in original image') imglist[i].header['MAXY'] = (y2, 'Upper Y value in original image') if regprefix: xsize = struct[1].data.shape[1] xsize = int(0.5 * xsize) rtext = '' if slitmask: # rtext='%s, %8.7f, %8.7f, %3.2f' % (slitmask.slitlets.data[i]['name'], slitmask.slitlets.data[i]['targ_ra'], slitmask.slitlets.data[i]['targ_dec'], slitmask.slitlets.data[i]['slit_width']) pass regout.write('box(%i,%i, %i, %i) #text={%s}\n' % (xsize, 0.5 * (y1 + y2), 2 * xsize, y2 - y1, rtext)) # add slit information if slitmask: imglist[i].header['SLITNAME'] = ( slitmask.slitlets.data[i]['name'], 'Slit Name') imglist[i].header['SLIT_RA'] = ( slitmask.slitlets.data[i]['targ_ra'], 'Slit RA') imglist[i].header['SLIT_DEC'] = ( slitmask.slitlets.data[i]['targ_dec'], 'Slit DEC') imglist[i].header['SLIT'] = ( slitmask.slitlets.data[i]['slit_width'], 'Slit Width') # add to the hdulist hdulist += imglist if varext: hdulist += varlist if bpmext: hdulist += bpmlist # write the slit positions to the header # create the binary table HDU that contains the split positions tbhdu = mt.slits_HDUtable(slit_positions, order) bintable_hdr = tbhdu.header # add the extname parameter to the extension tbhdu.header['EXTNAME'] = 'BINTABLE' # add the extname parameter to the extension hdulist[0].header['SLITEXT'] = len(hdulist) hdulist.append(tbhdu) # add addition header information about the mask if slitmask: hdulist[0].header['MASKNAME'] = (slitmask.mask_name, 'SlitMask Name') hdulist[0].header['MASK_RA'] = (slitmask.center_ra, 'SlitMask RA') hdulist[0].header['MASK_DEC'] = (slitmask.center_dec, 'SlitMask DEC') hdulist[0].header['MASK_PA'] = (slitmask.position_angle, 'SlitMask Position Angle') # write out the image saltio.writefits(hdulist, oimg, clobber)
def slotutcfix(images, update, outfile, ampperccd, ignorexp, droplimit, inter, plotdata, logfile, verbose, debug): with logging(logfile, debug) as log: # set up the variables utc_list = [] # is the input file specified? saltsafeio.filedefined('Input', images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input', images) # parse list of input files and place them in order infiles = saltsafeio.listparse('Raw image', images, '', '', '') infiles.sort() # check input files exist saltsafeio.filesexist(infiles, '', 'r') # check to see if the output file exists and if so, clobber it if os.path.isfile(outfile): try: os.remove(outfile) except: raise SaltIOError('File ' + outfile + ' can not be removed') # open the outfile if outfile: try: fout = open(outfile, 'w') except: raise SaltIOError('File ' + outfile + ' can not be opened') # get time of first exposure and basic information about the observations infile = infiles[0] struct = saltsafeio.openfits(infile) # check to make sure slotmode data detmode = saltsafekey.get('DETMODE', struct[0], infile) if detmode != 'Slot Mode': raise SaltIOError('Data are not Slot Mode Observations') # Check to see if SLOTUTCFIX has already been run # and print a warning if they have if saltsafekey.found('SLOTUTC', struct[0]): message = 'Data have already been processed by SLOTUTCFIX' log.warning(message) # check to make sure that it is the right version of the software scamver = saltsafekey.get('DETSWV', struct[0], infile) try: scamver = float(scamver.split('-')[-1]) if 4.42 <= scamver <= 5.00: pass else: raise SaltError( 'cannot currently correct this version of the SCAM software.' ) except: raise SaltError('Not able to read software version') # requested exposure time req_texp = saltsafekey.get('EXPTIME', struct[0], infile) # how many extensions? nextend = saltsafekey.get('NEXTEND', struct[0], infile) # how many amplifiers amplifiers = saltsafekey.get('NCCDS', struct[0], infile) amplifiers = int(ampperccd * float(amplifiers)) if ampperccd > 0: nframes = nextend / amplifiers nstep = amplifiers else: nframes = nextend nstep = 1 # how many total frame and unique times ntotal = nextend * len(infiles) nunique = len(infiles) * nframes - ignorexp + 1 # Create arrays necessary for analysis id_arr = np.arange(nunique) utc_arr = np.zeros(nunique, dtype=float) # Read in each file and make a list of the UTC values if verbose: log.message('Reading in files to create list of UTC values.') j = 0 for n, infile in enumerate(infiles): # Show progress if verbose: percent = 100. * float(n) / float(len(infiles)) ctext = 'Percentage Complete: %.2f\r' % percent sys.stdout.write(ctext) sys.stdout.flush() struct = saltsafeio.openfits(infile) if not len(struct) - 1 == nextend: raise SaltIOError( infile, ' has a different number of extensions from the first file' ) # Skip through the frames and read in the utc istart = 1 if infile == infiles[0]: istart = ignorexp * amplifiers + 1 for i in range(istart, len(struct), amplifiers): try: utc_list.append( saltsafekey.get('UTC-OBS', struct[i], infile)) utc_arr[j] = slottool.getobstime(struct[i], infile) j += 1 except Exception, e: raise SaltIOError( 'Unable to create array of UTC times. Please check the number of extensions in the files' ) # close FITS file saltsafeio.closefits(struct) # set up the other important arrays try: diff_arr = utc_arr.copy() diff_arr[1:] = diff_arr[1:] - utc_arr[:-1] diff_arr[0] = -1 dsec_arr = utc_arr - utc_arr.astype(int) except: raise SaltIOError('Unable to create timing arrays') # calculate the real exposure time if verbose: log.message('Calculating real exposure time.') real_expt, med_expt, t_start, t_arr, ysum_arr = calculate_realexptime( id_arr, utc_arr, dsec_arr, diff_arr, req_texp, utc_list) # plot the results if plotdata: if verbose: log.message('Plotting data.') plt.ion() plt.plot(t_arr, ysum_arr, linewidth=0.5, linestyle='-', marker='', color='b') plt.xlabel('Time (s)') plt.ylabel('Fit') # Calculate the corrrect values if verbose: log.message('Calculating correct values') i_start = abs(utc_arr - t_start).argmin() t_diff = utc_arr * 0.0 + real_expt nd = utc_arr * 0.0 ndrop = 0 for i in range(len(utc_arr)): if utc_arr[i] >= t_start: t_new = t_start + real_expt * (i - i_start + ndrop) t_diff[i] = utc_arr[i] - t_new while (t_diff[i] > real_expt and nd[i] < droplimit): nd[i] += 1 t_new = t_start + real_expt * (i - i_start + ndrop + nd[i]) t_diff[i] = utc_arr[i] - t_new if (nd[i] < droplimit): ndrop += nd[i] else: t_new = t_start + real_expt * (i - i_start) t_diff[i] = utc_arr[i] - t_new while (t_diff[i] > real_expt and nd[i] < droplimit): nd[i] += 1 t_new = t_start + real_expt * (i - i_start - nd[i]) t_diff[i] = utc_arr[i] - t_new # calculate the corrected timestamp by counting 6 record files forward and # 8 recored + unrecorded files back--or just 8*t_exp forward. # if the object is near the end of the run, then just replace it with # the correct value assuming no dropped exposures. # first make the array of new times new_arr = utc_arr - t_diff # Next loop through them to find the corrected time corr_arr = utc_arr * 0.0 for i in range(len(new_arr)): if i + 6 < len(new_arr) - 1: corr_arr[i] = new_arr[i + 6] - 8 * real_expt else: corr_arr[i] = new_arr[i] - 2 * real_expt t_diff = utc_arr - corr_arr # write out the first results msg = "Dwell Time=%5.3f Requested Exposure Time=%5.3f Nobs = %i Dropped = %i" % ( real_expt, req_texp, nunique, ndrop) if verbose: log.message(msg) if outfile: fout.write('#' + msg + '\n') fout.write('#%23s %2s %12s %12s %10s %8s %4s \n' % ('File', 'N', 'UTC_old', 'UTC_new', 'UTC_new(s)', 'Diff', 'drop')) # Give the user a chance to update the value if inter: message = 'Update headers with a dwell time of %5.3f s [y/n]? ' % real_expt update = saltsafeio.yn_ask(message) if not update: message = 'Set Dwell Time manually [y/n]? ' update = saltsafeio.yn_ask(message) if update: message = 'New Dwell Time: ' real_expt = saltsafeio.ask(message) try: real_expt = float(real_expt) except Exception, e: msg = 'Could not set user dwell time because %s' % e raise SaltError(msg)
def slotpreview(images, outfile, ampperccd=2, ignorexp=6, recenter_radius=5, tgt_col='b', cmp_col='g', tgt_lw=2, cmp_lw=2, cmap='gray', scale='zscale', contrast=0.1, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # is the input file specified? saltsafeio.filedefined('Input', images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input', images) # parse list of input files imlist = saltsafeio.listparse('Raw image', images, '', '', '') # check input files exist saltsafeio.filesexist(imlist, '', 'r') # is the output file specified? saltsafeio.filedefined('Output', outfile) # check output file does not exist, optionally remove it if it does exist if os.path.exists(outfile) and clobber: os.remove(outfile) elif os.path.exists(outfile) and not clobber: raise SaltIOError('File ' + outfile + ' already exists, use clobber=y') # Get the number of ccds to calculate the number of frames to skip try: nccds = pyfits.getheader(imlist[0])['NCCDS'] except: raise SaltIOError( 'Could not read NCCDS parameter from header of first fits file.' ) # Create GUI App = QtGui.QApplication(sys.argv) aw = ApplicationWindow(imlist=imlist, number=ignorexp * ampperccd * nccds + 1, config=outfile, target_line_color=tgt_col, comparison_line_color=cmp_col, target_line_width=tgt_lw, comparison_line_width=cmp_lw, distance=recenter_radius, cmap=cmap, scale=scale, contrast=contrast) aw.show() # Start application event loop exit = App.exec_() # Check if GUI was executed succesfully if exit != 0: log.warning('Slotpreview GUI has unexpected exit status' + str(exit))
def slotutcfix(images,update,outfile,ampperccd,ignorexp,droplimit,inter,plotdata,logfile,verbose,debug): with logging(logfile,debug) as log: # set up the variables utc_list = [] # is the input file specified? saltsafeio.filedefined('Input',images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input',images) # parse list of input files and place them in order infiles=saltsafeio.listparse('Raw image',images,'','','') infiles.sort() # check input files exist saltsafeio.filesexist(infiles,'','r') # check to see if the output file exists and if so, clobber it if os.path.isfile(outfile): try: os.remove(outfile) except: raise SaltIOError('File ' + outfile + ' can not be removed') # open the outfile if outfile: try: fout=open(outfile,'w') except: raise SaltIOError('File ' + outfile + ' can not be opened') # get time of first exposure and basic information about the observations infile=infiles[0] struct=saltsafeio.openfits(infile) # check to make sure slotmode data detmode=saltsafekey.get('DETMODE',struct[0], infile) if detmode != 'Slot Mode': raise SaltIOError('Data are not Slot Mode Observations') # Check to see if SLOTUTCFIX has already been run # and print a warning if they have if saltsafekey.found('SLOTUTC', struct[0]): message='Data have already been processed by SLOTUTCFIX' log.warning(message) # check to make sure that it is the right version of the software scamver=saltsafekey.get('DETSWV', struct[0], infile) try: scamver=float(scamver.split('-')[-1]) if 4.42 <= scamver <= 5.00: pass else: raise SaltError('cannot currently correct this version of the SCAM software.') except: raise SaltError('Not able to read software version') # requested exposure time req_texp=saltsafekey.get('EXPTIME',struct[0],infile) # how many extensions? nextend=saltsafekey.get('NEXTEND',struct[0],infile) # how many amplifiers amplifiers=saltsafekey.get('NCCDS',struct[0],infile) amplifiers = int(ampperccd*float(amplifiers)) if ampperccd>0: nframes = nextend/amplifiers nstep=amplifiers else: nframes = nextend nstep=1 # how many total frame and unique times ntotal=nextend*len(infiles) nunique=len(infiles)*nframes-ignorexp+1 # Create arrays necessary for analysis id_arr=np.arange(nunique) utc_arr=np.zeros(nunique,dtype=float) # Read in each file and make a list of the UTC values if verbose: log.message('Reading in files to create list of UTC values.') j=0 for n,infile in enumerate(infiles): # Show progress if verbose: percent=100.*float(n)/float(len(infiles)) ctext='Percentage Complete: %.2f\r' % percent sys.stdout.write(ctext) sys.stdout.flush() struct=saltsafeio.openfits(infile) if not len(struct)-1==nextend: raise SaltIOError(infile,' has a different number of extensions from the first file') # Skip through the frames and read in the utc istart=1 if infile==infiles[0]: istart=ignorexp*amplifiers+1 for i in range(istart,len(struct), amplifiers): try: utc_list.append(saltsafekey.get('UTC-OBS', struct[i], infile)) utc_arr[j]=slottool.getobstime(struct[i], infile) j += 1 except Exception, e: raise SaltIOError('Unable to create array of UTC times. Please check the number of extensions in the files') # close FITS file saltsafeio.closefits(struct) # set up the other important arrays try: diff_arr=utc_arr.copy() diff_arr[1:]=diff_arr[1:]-utc_arr[:-1] diff_arr[0]=-1 dsec_arr=utc_arr-utc_arr.astype(int) except: raise SaltIOError('Unable to create timing arrays') # calculate the real exposure time if verbose: log.message('Calculating real exposure time.') real_expt, med_expt, t_start, t_arr, ysum_arr=calculate_realexptime(id_arr, utc_arr, dsec_arr, diff_arr, req_texp, utc_list) # plot the results if plotdata: if verbose: log.message('Plotting data.') plt.ion() plt.plot(t_arr,ysum_arr,linewidth=0.5,linestyle='-',marker='',color='b') plt.xlabel('Time (s)') plt.ylabel('Fit') # Calculate the corrrect values if verbose: log.message('Calculating correct values') i_start = abs(utc_arr-t_start).argmin() t_diff=utc_arr*0.0+real_expt nd=utc_arr*0.0 ndrop=0 for i in range(len(utc_arr)): if utc_arr[i] >= t_start: t_new=t_start+real_expt*(i-i_start+ndrop) t_diff[i]=utc_arr[i]-t_new while (t_diff[i]>real_expt and nd[i] < droplimit): nd[i]+= 1 t_new=t_start+real_expt*(i-i_start+ndrop+nd[i]) t_diff[i]=utc_arr[i]-t_new if (nd[i]<droplimit): ndrop += nd[i] else: t_new=t_start+real_expt*(i-i_start) t_diff[i]=utc_arr[i]-t_new while (t_diff[i]>real_expt and nd[i] < droplimit): nd[i]+= 1 t_new=t_start+real_expt*(i-i_start-nd[i]) t_diff[i]=utc_arr[i]-t_new # calculate the corrected timestamp by counting 6 record files forward and # 8 recored + unrecorded files back--or just 8*t_exp forward. # if the object is near the end of the run, then just replace it with # the correct value assuming no dropped exposures. # first make the array of new times new_arr=utc_arr-t_diff # Next loop through them to find the corrected time corr_arr=utc_arr*0.0 for i in range(len(new_arr)): if i+6 < len(new_arr)-1: corr_arr[i]=new_arr[i+6]-8*real_expt else: corr_arr[i]=new_arr[i]-2*real_expt t_diff=utc_arr-corr_arr # write out the first results msg="Dwell Time=%5.3f Requested Exposure Time=%5.3f Nobs = %i Dropped = %i" % (real_expt, req_texp, nunique, ndrop) if verbose: log.message(msg) if outfile: fout.write('#'+msg+'\n') fout.write('#%23s %2s %12s %12s %10s %8s %4s \n' % ('File', 'N', 'UTC_old', 'UTC_new', 'UTC_new(s)', 'Diff', 'drop' )) # Give the user a chance to update the value if inter: message='Update headers with a dwell time of %5.3f s [y/n]? ' % real_expt update=saltsafeio.yn_ask(message) if not update: message='Set Dwell Time manually [y/n]? ' update=saltsafeio.yn_ask(message) if update: message='New Dwell Time: ' real_expt=saltsafeio.ask(message) try: real_expt=float(real_expt) except Exception, e: msg='Could not set user dwell time because %s' % e raise SaltError(msg)
def saltxtalk(images, outimages, outpref, xtalkfile=None, usedb=False, clobber=True, logfile='salt.log', verbose=True): #start logging 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, '') # are input and output lists the same length? saltio.comparelists(infiles, outfiles, 'Input', 'output') # does crosstalk coefficient data exist if usedb: xtalkfile = xtalkfile.strip() xdict = saltio.readxtalkcoeff(xtalkfile) else: xdict = None for img, oimg in zip(infiles, outfiles): #open the fits file struct = saltio.openfits(img) #find the best xcoeff for the image if using the db if usedb: obsdate = saltkey.get('DATE-OBS', struct[0]) obsdate = int('%s%s%s' % (obsdate[0:4], obsdate[5:7], obsdate[8:])) xkey = np.array(xdict.keys()) date = xkey[abs(xkey - obsdate).argmin()] xcoeff = xdict[date] else: xcoeff = [] # identify instrument instrume, keyprep, keygain, keybias, keyxtalk, keyslot = saltkey.instrumid( struct) # has file been prepared already? if saltkey.found(keyxtalk, struct[0]): message = '%s has already been xtalk corrected' % img raise SaltError(message) #apply the cross-talk correction struct = xtalk(struct, xcoeff, log=log, verbose=verbose) # housekeeping keywords fname, hist = history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0], 'SXTALK', 'Images have been xtalk corrected', hist) # write FITS file saltio.writefits(struct, oimg, clobber=clobber) saltio.closefits(struct)
def saltflat(images,outimages,outpref, flatimage,minflat=1, allext=False, clobber=False, \ 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,'') #verify that the input and output lists are the same length saltio.comparelists(infiles,outfiles,'Input','output') # check flatfield image exists flaimage= flatimage.strip() saltio.fileexists(flatimage) flatstruct= saltio.openfits(flatimage) # Normalize the flat field image # This requires to go through each science extension and divide it by # mean of the image. Things that have to be checked: # that data exist, that it is a science extension #determine the global mean fmean=0 fcount=0 #replace bad pixels for i in range(len(flatstruct)): if flatstruct[i].data is not None and (flatstruct[i].name=='SCI' or flatstruct[i].name=='PRIMARY'): data = flatstruct[i].data mask = (data > minflat) if (numpy.nan==flatstruct[i].data).sum() or (numpy.inf==flatstruct[i].data).sum(): message = '\nWARNING -- SALTFLAT: %s contains invalid values' % flatimage log.warning(message,with_stdout=verbose) flatstruct[i].data[mask==0] = minflat flatstruct[i].data[flatstruct[i].data==numpy.inf] = minflat #determine the mean mask = (data > minflat) fmean += data[mask].sum() fcount += data[mask].size if fcount>0: fmean=fmean/fcount for i in range(len(flatstruct)): if flatstruct[i].name=='PRIMARY': #is it a flat--if not throw a warning try: key_ccdtype=saltkey.get('CCDTYPE', flatstruct[i]) except: key_ccdtype=None if key_ccdtype!='FLAT': message = '\nWARNING -- SALTFLAT: %s does not have CCDTYPE=FLAT' % flatimage log.warning(message,with_stdout=verbose) #if there are data, normalize it if flatstruct[i].data is not None: flatstruct[i].data=flatnormalize(flatstruct[i].data, minflat) #Noramlize the science extensions if flatstruct[i].name=='SCI': if flatstruct[i].data is not None: if allext is False: fmean=flatstruct[i].data.mean() flatstruct[i].data=flatnormalize(flatstruct[i].data, minflat, fmean) #Apply to the variance frames if saltkey.found('VAREXT', flatstruct[i]): varext=saltkey.get('VAREXT',flatstruct[i]) flatstruct[varext].data=flatstruct[varext].data/fmean**2 # open each raw image file for infile, outfile in zip(infiles,outfiles): struct = saltio.openfits(infile) # flat field correct the image outstruct = flat(struct, flatstruct) try: pass except Exception,e: msg='Unable to flatten %s because %s' % (infile, e) raise SaltError(msg) #add any header keywords like history fname, hist=history(level=1, wrap=False) saltkey.housekeeping(struct[0],'SFLAT', 'File flatfield corrected', hist) #write it out and close it saltio.writefits(outstruct,outfile,clobber=clobber) saltio.closefits(struct) #output the information log.message('Flatfields image %s using %s' % (infile, flatimage), with_header=False, with_stdout=verbose) #clost the flatfield image saltio.closefits(flatstruct)
def specslit(image, outimage, outpref, exttype='auto', slitfile='', outputslitfile='', regprefix='', sections=3, width=25, sigma=2.2, thres=6, order=3, padding=5, yoffset=0, inter=False, clobber=True, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # check all the input and make sure that all the input needed is provided # by the user # read the image or image list and check if each in the list exist infiles = saltio.argunpack('Input', image) # unpack the outfiles outfiles = saltio.listparse( 'Outimages', outimage, outpref, infiles, '') # from the extraction type, check whether the input file is specified. # if the slitfile parameter is specified then use the slit files for # the extraction. if the extraction type is auto then use image for the # detection and the slit extraction if exttype == 'rsmt' or exttype == 'fits' or exttype == 'ascii' or exttype == 'ds9': slitfiles = saltio.argunpack('Slitfile', slitfile) if len(slitfiles) == 1: slitfiles = slitfiles * len(infiles) saltio.comparelists(infiles, slitfiles, 'image', 'slitfile') elif exttype == 'auto': slitfiles = infiles log.message( 'Extraction type is AUTO. Slit detection will be done from image') # read in if an optional ascii file is requested if len(outputslitfile) > 0: outslitfiles = saltio.argunpack('Outslitfiles', outputslitfile) saltio.comparelists( infiles, outslitfiles, 'image', 'outputslitfile') else: outslitfiles = [''] * len(infiles) # check if the width and sigma parameters were specified. # default is 25 and 2.2 if width < 10.: msg = 'The width parameter needs be a value larger than 10' raise SALTSpecError(msg) if sigma < 0.0: msg = 'Sigma must be greater than zero' raise SaltSpecError(msg) # check the treshold parameter. this needs to be specified by the user if thres <= 0.0: msg = 'Threshold must be greater than zero' raise SaltSpecError(msg) # check to make sure that the sections are greater than the order if sections <= order: msg = 'Number of sections must be greater than the order for the spline fit' raise SaltSpecError(msg) # run through each of the images and extract the slits for img, oimg, sfile, oslit in zip( infiles, outfiles, slitfiles, outslitfiles): log.message('Proccessing image %s' % img) # open the image struct = saltio.openfits(img) ylen, xlen = struct[1].data.shape xbin, ybin = saltkey.ccdbin(struct[0], img) # setup the VARIANCE and BPM frames if saltkey.found('VAREXT', struct[1]): varext = saltkey.get('VAREXT', struct[1]) varlist = [] else: varext = None # setup the BPM frames if saltkey.found('BPMEXT', struct[1]): bpmext = saltkey.get('BPMEXT', struct[1]) bpmlist = [] else: bpmext = None # open the slit definition file or identify the slits in the image slitmask = None ycheck = False if exttype == 'rsmt': log.message('Using slits from %s' % sfile) if yoffset is None: yoffset = 0 ycheck = True slitmask = mt.read_slitmask_from_xml(sfile) xpos = -0.3066 ypos = 0.0117 cx = int(xlen / 2.0) cy = int(ylen / 2.0) + ypos / 0.015 / ybin + yoffset order, slit_positions = mt.convert_slits_from_mask( slitmask, order=1, xbin=xbin, ybin=ybin, pix_scale=0.1267, cx=cx, cy=cy) sections = 1 elif exttype == 'fits': log.message('Using slits from %s' % sfile) order, slit_positions = read_slits_from_fits(sfile) elif exttype == 'ascii': log.message('Using slits from %s' % sfile) order, slit_positions = mt.read_slits_from_ascii(sfile) elif exttype == 'ds9': log.message('Using slits from %s' % sfile) order, slit_positions, slitmask = mt.read_slits_from_ds9( sfile, order=order) slitmask = None sections = 1 elif exttype == 'auto': log.message('Identifying slits in %s' % img) # identify the slits in the image order, slit_positions = identify_slits( struct[1].data, order, sections, width, sigma, thres) # write out the slit identifications if ofile has been supplied if oslit: log.message('Writing slit positions to %s' % oslit) mt.write_outputslitfile(slit_positions, oslit, order) if ycheck: slit_positions, dy = check_ypos(slit_positions, struct[1].data) log.message('Using an offset of {}'.format(dy)) # extract the slits spline_x = mt.divide_image(struct[1].data, sections) spline_x = 0.5 * (np.array(spline_x[:-1]) + np.array(spline_x[1:])) extracted_spectra, spline_positions = mt.extract_slits(slit_positions, spline_x, struct[1].data, order=order, padding=padding) if varext: extracted_var, var_positions = mt.extract_slits(slit_positions, spline_x, struct[varext].data, order=order, padding=padding) if bpmext: extracted_bpm, bpm_positions = mt.extract_slits(slit_positions, spline_x, struct[bpmext].data, order=order, padding=padding) # write out the data to the new array # create the new file hdulist = fits.HDUList([struct[0]]) # log the extracted spectra if needed log.message('', with_stdout=verbose) # setup output ds9 file if regprefix: regout = open( regprefix + os.path.basename(img).strip('.fits') + '.reg', 'w') regout.write('# Region file format: DS9 version 4.1\n') regout.write('# Filename: %s\n' % img) regout.write( '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\nphysical\n') # add each imglist = [] nslits = len(spline_positions) for i in range(nslits): y1 = spline_positions[i][0].min() y2 = spline_positions[i][1].max() msg = 'Extracted Spectra %i between %i to %i' % (i + 1, y1, y2) # log.message(msg, with_header=False, with_stdout=verbose) sdu = fits.ImageHDU( extracted_spectra[i], header=struct[1].header) if varext: vdu = fits.ImageHDU( extracted_var[i], header=struct[varext].header) sdu.header['VAREXT'] = i + nslits + 1 varlist.append(vdu) if bpmext: bdu = fits.ImageHDU( extracted_bpm[i], header=struct[bpmext].header) sdu.header['BPMEXT']= i + 2 * nslits + 1 bpmlist.append(bdu) imglist.append(sdu) # add in some additional keywords imglist[i].header['MINY'] = (y1, 'Lower Y value in original image') imglist[i].header['MAXY'] = (y2, 'Upper Y value in original image') if regprefix: xsize = struct[1].data.shape[1] xsize = int(0.5 * xsize) rtext = '' if slitmask: # rtext='%s, %8.7f, %8.7f, %3.2f' % (slitmask.slitlets.data[i]['name'], slitmask.slitlets.data[i]['targ_ra'], slitmask.slitlets.data[i]['targ_dec'], slitmask.slitlets.data[i]['slit_width']) pass regout.write('box(%i,%i, %i, %i) #text={%s}\n' % ( xsize, 0.5 * (y1 + y2), 2 * xsize, y2 - y1, rtext)) # add slit information if slitmask: imglist[i].header['SLITNAME'] = (slitmask.slitlets.data[i]['name'], 'Slit Name') imglist[i].header['SLIT_RA'] = (slitmask.slitlets.data[i]['targ_ra'], 'Slit RA') imglist[i].header['SLIT_DEC'] = (slitmask.slitlets.data[i]['targ_dec'], 'Slit DEC') imglist[i].header['SLIT'] = (slitmask.slitlets.data[i]['slit_width'], 'Slit Width') # add to the hdulist hdulist += imglist if varext: hdulist += varlist if bpmext: hdulist += bpmlist # write the slit positions to the header # create the binary table HDU that contains the split positions tbhdu = mt.slits_HDUtable(slit_positions, order) bintable_hdr = tbhdu.header # add the extname parameter to the extension tbhdu.header['EXTNAME'] = 'BINTABLE' # add the extname parameter to the extension hdulist[0].header['SLITEXT'] = len(hdulist) hdulist.append(tbhdu) # add addition header information about the mask if slitmask: hdulist[0].header['MASKNAME'] = (slitmask.mask_name, 'SlitMask Name') hdulist[0].header['MASK_RA'] = (slitmask.center_ra, 'SlitMask RA') hdulist[0].header['MASK_DEC'] = ( slitmask.center_dec, 'SlitMask DEC') hdulist[0].header['MASK_PA'] = ( slitmask.position_angle, 'SlitMask Position Angle') # write out the image saltio.writefits(hdulist, oimg, clobber)
def saltbias(images,outimages,outpref,subover=True,trim=True,subbias=False, masterbias='bias.fits', median=False, function='polynomial', order=3, rej_lo=3, rej_hi=3, niter=10, plotover=False, turbo=False, clobber=False, logfile='salt.log', verbose=True): status = 0 ifil = 0 ii = 0 mbiasdata = [] bstruct = '' biasgn = '' biassp = '' biasbn = '' biasin = '' filetime = {} biastime = {} for i in range(1,7): filetime[i] = [] biastime[i] = [] 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,'') # are input and output lists the same length? saltio.comparelists(infiles,outfiles,'Input','output') # Does master bias frame exist? # gain, speed, binning and instrument of master bias frame if subbias: if os.path.isfile(masterbias): bstruct = saltio.openfits(masterbias) else: message = 'Master bias frame %s does not exist' % masterbias raise SaltError(message) else: bstruct=None # open each raw image file for img, oimg in zip(infiles, outfiles): #open the file struct = saltio.openfits(img) #check to see if it has already been bias subtracted instrume,keyprep,keygain,keybias,keyxtalk,keyslot = saltkey.instrumid(struct) # has file been biaseded already? try: key = struct[0].header[keybias] message = 'File %s has already been de-biased ' % infile raise SaltError(message) except: pass #compare with the master bias to make sure they are the same if subbias: pass #subtract the bias struct=bias(struct,subover=subover, trim=trim, subbias=subbias, bstruct=bstruct, median=median, function=function, order=order, rej_lo=rej_lo, rej_hi=rej_hi, niter=niter, plotover=plotover, log=log, verbose=verbose) #write the file out # housekeeping keywords fname, hist=history(level=1, wrap=False, exclude=['images', 'outimages', 'outpref']) saltkey.housekeeping(struct[0],keybias, 'Images have been de-biased', hist) # write FITS file saltio.writefits(struct,oimg, clobber=clobber) saltio.closefits(struct)
def slotphot(images,outfile,srcfile,newfits=None,phottype='square', subbacktype='median',sigback=3,mbin=7,sorder=3,niter=5,sigdet=5, contpix=10,ampperccd=2,ignorexp=6,driftlimit=10.,finddrift=True, outtype='ascii',reltime=True,clobber=True,logfile='salt.log', verbose=True): """Perform photometry on listed SALT slotmode *images*.""" with logging(logfile,debug) as log: # set up the variables entries = [] vig_lo = {} vig_hi = {} amp = {} x = {} y = {} x_o = {} y_o = {} r = {} br1 = {} br2 = {} hour = 0 min = 0 sec = 0. time0 = 0. nframes = 0 bin=mbin order=sorder # is the input file specified? saltsafeio.filedefined('Input',images) # if the input file is a list, does it exist? if images[0] == '@': saltsafeio.listexists('Input',images) # parse list of input files infiles=saltsafeio.listparse('Raw image',images,'','','') # check input files exist saltsafeio.filesexist(infiles,'','r') # is the output file specified? saltsafeio.filedefined('Output',outfile) # check output file does not exist, optionally remove it if it does exist if os.path.exists(outfile) and clobber: os.remove(outfile) elif os.path.exists(outfile) and not clobber: raise SaltIOError('File '+outfile+' already exists, use clobber=y') # open output ascii file if outtype=='ascii': try: lc = open(outfile,'a') except: raise SaltIOError('Cannot open ouput file '+outfile) # is the extraction region defintion file specified? saltsafeio.filedefined('Extraction region defintion',srcfile) # check extraction region defintion file exists srcfile = srcfile.strip() saltsafeio.fileexists(srcfile) # read extraction region defintion file amp, x, y, x_o, y_o, r, br1, br2=slottool.readsrcfile(srcfile) # set the writenewfits parameter if not newfits or newfits=='none': writenewfits=False else: writenewfits=newfits # get time of first exposure and basic information about the observations infile=infiles[0] struct=saltsafeio.openfits(infile) # identify instrument instrume,keyprep,keygain,keybias,keyxtalk,keyslot=saltsafekey.instrumid(struct,infile) # how many extensions? nextend=saltsafekey.get('NEXTEND',struct[0],infile) if nextend < amp['comparison']: msg='Insufficient number of extensions in %s' % (infile) raise SaltIOError(msg) # how many amplifiers? amplifiers=saltsafekey.get('NCCDS',struct[0],infile) amplifiers = int(ampperccd*float(amplifiers)) if ampperccd>0: nframes = int(nextend/amplifiers) nstep=amplifiers else: nframes = nextend nstep=1 ntotal=nframes*len(infiles) # image size naxis1=saltsafekey.get('NAXIS1',struct[amp['comparison']],infile) naxis2=saltsafekey.get('NAXIS2',struct[amp['comparison']],infile) # CCD binning ccdsum=saltsafekey.get('CCDSUM',struct[0],infile) binx=int(ccdsum.split(' ')[0]) biny=int(ccdsum.split(' ')[1]) # Identify the time of the observations ext = 1 try: time0=slottool.getobstime(struct[ext], infile+'['+str(ext)+']') dateobs=saltsafekey.get('DATE-OBS',struct[ext],infile) dateobs=dateobs.replace('-','/') except: raise SaltIOError('No time or obsdate in first image') # If a total file is to be written out, create it and update it if writenewfits: if os.path.isfile(writenewfits): if clobber: saltsafeio.delete(writenewfits) else: raise SaltIOError('Newfits file exists, use clobber') try: hdu=pyfits.PrimaryHDU() hdu.header=struct[0].header hdu.header['NCCDS']=1 hdu.header['NSCIEXT']=ntotal-ignorexp hdu.header['NEXTEND']=ntotal-ignorexp hduList=pyfits.HDUList(hdu) hduList.verify() hduList.writeto(writenewfits) except: raise SaltIOError('Could not create newfits file, '+writenewfits) # Close image file saltsafeio.closefits(struct) # Read newfits file back in for updating if writenewfits: try: hduList=pyfits.open(writenewfits,mode='update') except: raise SaltIOError('Cannot open newfits file '+writenewfits+' for updating.') # set up the arrays j=0 time=np.zeros(ntotal ,dtype='float')-1.0 dx=np.zeros(ntotal ,dtype='float') dy=np.zeros(ntotal ,dtype='float') tflux=np.zeros(ntotal ,dtype='float') terr =np.zeros(ntotal ,dtype='float') cflux=np.zeros(ntotal ,dtype='float') cerr =np.zeros(ntotal ,dtype='float') ratio=np.zeros(ntotal ,dtype='float') rerr =np.zeros(ntotal ,dtype='float') tgt_x=np.zeros(ntotal ,dtype='float') tgt_y=np.zeros(ntotal ,dtype='float') cmp_x=np.zeros(ntotal ,dtype='float') cmp_y=np.zeros(ntotal ,dtype='float') p_one=100./ntotal # One percent p_old=-1 # Previous completed percentage p_new=0 # New completed percentage p_n=1 # Counter number for infile in infiles: # Log if verbose: log.message('Starting photometry on file '+infile, with_stdout=False) struct=pyfits.open(infile) # Skip through the frames and process each frame individually for i in range(nframes): # Show progress if verbose: p_new=int(p_n*p_one) p_n+=1 if p_new!=p_old: ctext='Percentage Complete: %d\r' % p_new sys.stdout.write(ctext) sys.stdout.flush() p_old=p_new if not (infile==infiles[0] and i < ignorexp): ext=amp['comparison']+i*nstep try: header=struct[ext].header array=struct[ext].data array=array*1.0 except: msg='Unable to open extension %i in image %s' % (ext, infile) raise SaltIOError(msg) # starti the analysis of each frame # get the time time[j]=slottool.getobstime(struct[ext],infile+'['+str(ext)+']') # gain and readout noise try: gain=float(header['GAIN']) except: gain=1 raise SaltIOError('Gain not specified in image header') try: rdnoise=float(header['RDNOISE']) except: rdnoise=0 raise SaltIOError('RDNOISE not specified in image header') # background subtraction if not subbacktype=='none': try: array=subbackground(array, sigback, bin, order, niter, subbacktype) except SaltError: log.warning('Image '+infile+' extention '+str(ext)+' is blank, skipping') continue # x-y fit to the comparison star and update the x,y values if finddrift: carray, fx,fy=slottool.finddrift(array, x['comparison'], y['comparison'], r['comparison'], naxis1, naxis2, sigdet, contpix, sigback, driftlimit, niter) if fx > -1 and fy > -1: if fx < naxis1 and fy < naxis2: dx[j]=x['comparison']-fx dy[j]=y['comparison']-fy x['comparison']=fx y['comparison']=fy x['target']=x['target']-dx[j] y['target']=y['target']-dy[j] else: dx[j]=0 dy[j]=0 x['comparison']=x_o['comparison'] y['comparison']=y_o['comparison'] x['target']=x_o['target'] y['target']=y_o['target'] else: msg='No comparison object found in image file ' + infile+' on extension %i skipping.' % ext log.warning(msg) pass # do photometry try: tflux[j],terr[j],cflux[j],cerr[j],ratio[j],rerr[j]=slottool.dophot(phottype, array, x, y, r, br1, br2, gain, rdnoise, naxis1, naxis2) except SaltError, e: msg='Could not do photometry on extension %i in image %s because %s skipping.' % (ext, infile, e) log.warning(msg) tgt_x[j]=x['target'] tgt_y[j]=y['target'] cmp_x[j]=x['comparison'] cmp_y[j]=y['comparison'] # record results # TODO! This should be removed in favor of the write all to disk in the end if outtype=='ascii': slottool.writedataout(lc, j+1, time[j], x, y, tflux[j], terr[j], cflux[j],cerr[j],ratio[j],rerr[j],time0, reltime) # write newfits file if writenewfits: # add original name and extension number to header try: hdue=pyfits.ImageHDU(array) hdue.header=header hdue.header.update('ONAME',infile,'Original image name') hdue.header.update('OEXT',ext,'Original extension number') hduList.append(hdue) except: log.warning('Could not update image in newfits '+infile+' '+str(ext)) # increment counter j+=1 # close FITS file saltsafeio.closefits(struct) # close newfits file if writenewfits: try: hduList.flush() hduList.close() except: raise SaltIOError('Cannot close newfits file.') # write to output if outtype=='ascii': # close output ascii file try: lc.close() except: raise SaltIOError('Cannot close ouput file ' + outfile) elif outtype=='fits': print 'writing fits' try: c1=pyfits.Column(name='index',format='D',array=np.arange(ntotal)) if reltime: c2=pyfits.Column(name='time',format='D',array=time-time0) else: c2=pyfits.Column(name='time',format='D',array=time) c3=pyfits.Column(name='tgt_x',format='D',array=tgt_x) c4=pyfits.Column(name='tgt_y',format='D',array=tgt_y) c5=pyfits.Column(name='tgt_flux',format='D',array=tflux) c6=pyfits.Column(name='tgt_err',format='D',array=terr) c7=pyfits.Column(name='cmp_x',format='D',array=cmp_x) c8=pyfits.Column(name='cmp_y',format='D',array=cmp_y) c9=pyfits.Column(name='cmp_flux',format='D',array=cflux) c10=pyfits.Column(name='cmp_err',format='D',array=cerr) c11=pyfits.Column(name='flux_ratio',format='D',array=ratio) c12=pyfits.Column(name='flux_ratio_err',format='D',array=rerr) tbhdu=pyfits.new_table([c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12]) # Add header information tbhdu.header.update('RELTIME',str(reltime),'Time relative to first datapoint or absolute.') tbhdu.writeto(outfile) print 'fits written to ',outfile except: raise SaltIOError('Could not write to fits table.')