def readShiftFile(self, filename): """ Reads a shift file from disk and populates a dictionary. """ order = [] fshift = open(filename,'r') flines = fshift.readlines() fshift.close() common = [f.strip('#').strip() for f in flines if f.startswith('#')] c=[line.split(': ') for line in common] # Remove any line comments in the shift file - lines starting with '#' # but not part of the common block. for l in c: if l[0] not in ['frame', 'refimage', 'form', 'units']: c.remove(l) for line in c: line[1]=line[1].strip() self.update(c) files = [f.strip().split(' ',1) for f in flines if not (f.startswith('#') or f.strip() == '')] for f in files: order.append(f[0]) self['order'] = order for f in files: # Check to see if filename provided is a full filename that corresponds # to a file on the path. If not, try to convert given rootname into # a valid filename based on available files. This may or may not # define the correct filename, which is why it prints out what it is # doing, so that the user can verify and edit the shiftfile if needed. #NOTE: # Supporting the specification of only rootnames in the shiftfile with this # filename expansion is NOT to be documented, but provided solely as # an undocumented, dangerous and not fully supported helper function for # some backwards compatibility. if not os.path.exists(f[0]): f[0] = fu.buildRootname(f[0]) print 'Defining filename in shiftfile as: ',f[0] f[1] = f[1].split() try: f[1] = [float(s) for s in f[1]] except: msg = 'Cannot read in ', s, ' from shiftfile ', filename, ' as a float number' raise ValueError, msg msg = "At least 2 and at most 4 shift values should be provided in a shiftfile" if len(f[1]) < 2: raise ValueError, msg elif len(f[1]) == 3: f[1].append(1.0) elif len(f[1]) == 2: f[1].extend([0.0, 1.0]) elif len(f[1]) > 4: raise ValueError, msg fdict = dict(files) self.update(fdict)
def __init__(self, inlist=None, output=None, shiftfile=None): """ Parameters =========== `inlist`: a list a python list of filenames `output` a string a user specified output name or 'final' `shiftfile`: a string a name of a shift file, if given, the association table will be updated with the values in the shift file """ if output == None: if len(inlist) == 1: self.output = fu.buildNewRootname(inlist[0]) else: self.output = 'final' else: self.output = fu.buildNewRootname(output) # Ensure that output name does not already contain '_drz' _indx = self.output.find('_drz') if _indx > 0: self.output = self.output[:_indx] self.order = [] if inlist != None: for fn in inlist: if fu.findFile(fu.buildRootname(fn)): self.order.append(fu.buildNewRootname(fn)) else: # This may mean corrupted asn table in which a file is listed as present # when it is missing. raise IOError, 'File %s not found.\n' %fn dict.__init__(self, output=self.output, order=[], members={}) if inlist != None: self.input = [fu.buildRootname(f) for f in inlist] self.shiftfile = shiftfile
def update(self, members=None, shiftfile=None, replace=False): __help_update=""" :Purpose: Update an existing association table Parameters ========== `members`: dictionary a dictionary representing asndict['members'] `shiftfile`: string the name of a shift file If given, shiftfile will replace shifts in an asndict. `replace`: bool False(default) a flag which indicates whether the 'members' item of an association table should be updated or replaced. default: False If True, it's up to the user to replace also asndict['order'] """ if members and isinstance(members, dict): if not replace: self['members'].update(members=members) else: self['members'] = members elif shiftfile: members = {} abshift = False dshift = False row = 0 sdict = ShiftFile(shiftfile) shift_frame = sdict['frame'] shift_units = sdict['units'] refimage = sdict['refimage'] if sdict['form']=='delta': dshift = True else: abshift = True for f in self.order: fullname = fu.buildRootname(f) xshift = sdict[fullname][0] yshift = sdict[fullname][1] rot = sdict[fullname][2] scale = sdict[fullname][3] members[f] = ASNMember(row=row, dshift=dshift, abshift=abshift, rot=rot, xshift=xshift, yshift=yshift, scale=scale, refimage=refimage, shift_frame=shift_frame, shift_units=shift_units) row+=1 self['members'].update(members) else: #print __help_update pass
def buildPrimary(self, fasn, output=None): _prihdr = fits.Header([fits.Card('SIMPLE', True, 'Fits standard'), fits.Card('BITPIX ', 16 ,' Bits per pixel'), fits.Card('NAXIS ', 0 ,' Number of axes'), fits.Card('ORIGIN ', 'NOAO-IRAF FITS Image Kernel July 1999' ,'FITS file originator'), fits.Card('IRAF-TLM', '18:26:13 (27/03/2000)' ,' Time of last modification'), fits.Card('EXTEND ', True ,' File may contain standard extensions'), fits.Card('NEXTEND ', 1 ,' Number of standard extensions'), fits.Card('DATE ', '2001-02-14T20:07:57',' date this file was written (yyyy-mm-dd)'), fits.Card('FILENAME', 'hr_box_asn.fits' ,' name of file'), fits.Card('FILETYPE', 'ASN_TABLE' ,' type of data found in data file'), fits.Card('TELESCOP', 'HST' ,' telescope used to acquire data'), fits.Card('INSTRUME', 'ACS ' ,' identifier for instrument used to acquire data'), fits.Card('EQUINOX ', 2000.0 ,' equinox of celestial coord. system'), fits.Card('ROOTNAME', 'hr_box ' ,' rootname of the observation set'), fits.Card('PRIMESI ', 'ACS ' ,' instrument designated as prime'), fits.Card('TARGNAME', 'SIM-DITHER' ,'proposer\'s target name'), fits.Card('RA_TARG ', 0. ,' right ascension of the target (deg) (J2000)'), fits.Card('DEC_TARG', 0. ,' declination of the target (deg) (J2000)'), fits.Card('DETECTOR', 'HRC ' ,' detector in use: WFC, HRC, or SBC'), fits.Card('ASN_ID ', 'hr_box ' ,' unique identifier assigned to association'), fits.Card('ASN_TAB ', 'hr_box_asn.fits' ,' name of the association table')]) # Format time values for keywords IRAF-TLM, and DATE _ltime = time.localtime(time.time()) tlm_str = time.strftime('%H:%M:%S (%d/%m/%Y)',_ltime) date_str = time.strftime('%Y-%m-%dT%H:%M:%S',_ltime) origin_str = 'FITS Version '+ astropy.__version__ # Build PRIMARY HDU _hdu = fits.PrimaryHDU(header=_prihdr) fasn.append(_hdu) newhdr = fasn['PRIMARY'].header mem0name = self['order'][0] refimg = self['members'][mem0name]['refimage'] shframe = self['members'][mem0name]['shift_frame'] fullname = fu.buildRootname(mem0name,ext=['_flt.fits', '_c0h.fits', '_c0f.fits']) try: # Open img1 to obtain keyword values for updating template fimg1 = fits.open(fullname) except: print 'File %s does not exist' % fullname kws = ['INSTRUME', 'PRIMESI', 'TARGNAME', 'DETECTOR', 'RA_TARG', 'DEC_TARG'] mem0hdr = fimg1['PRIMARY'].header default = 'UNKNOWN' for kw in kws: try: newhdr[kw] = mem0hdr[kw] except: newhdr[kw] = default fimg1.close() if not output: output = self['output'] outfilename = fu.buildNewRootname(output, extn='_asn.fits') newhdr['IRAF-TLM']=tlm_str newhdr['DATE'] = date_str newhdr['ORIGIN'] = origin_str newhdr['ROOTNAME'] = output newhdr['FILENAME'] = outfilename newhdr['ASN_ID'] = output newhdr['ASN_TAB'] = outfilename newhdr['SHFRAME'] = (shframe, "Frame which shifts are measured") newhdr['REFIMAGE'] = (refimg, "Image shifts were measured from")
def parseinput(inputlist,outputname=None, atfile=None): """ Recursively parse user input based upon the irafglob program and construct a list of files that need to be processed. This program addresses the following deficiencies of the irafglob program:: parseinput can extract filenames from association tables Returns ------- This program will return a list of input files that will need to be processed in addition to the name of any outfiles specified in an association table. Parameters ---------- inputlist - string specification of input files using either wild-cards, @-file or comma-separated list of filenames outputname - string desired name for output product to be created from the input files atfile - object function to use in interpreting the @-file columns that gets passed to irafglob Returns ------- files - list of strings names of output files to be processed newoutputname - string name of output file to be created. See Also -------- stsci.tools.irafglob """ # Initalize some variables files = [] # list used to store names of input files newoutputname = outputname # Outputname returned to calling program. # The value of outputname is only changed # if it had a value of 'None' on input. # We can use irafglob to parse the input. If the input wasn't # an association table, it needs to be either a wildcard, '@' file, # or comma seperated list. files = irafglob(inputlist, atfile=atfile) # Now that we have expanded the inputlist into a python list # containing the list of input files, it is necessary to examine # each of the files to make sure none of them are association tables. # # If an association table is found, the entries should be read # Determine if the input is an association table for file in files: if (checkASN(file) == True): # Create a list to store the files extracted from the # association tiable assoclist = [] # The input is an association table try: # Open the association table assocdict = readASNTable(file, None, prodonly=False) except: errorstr = "###################################\n" errorstr += "# #\n" errorstr += "# UNABLE TO READ ASSOCIATION FILE,#\n" errorstr += str(file)+'\n' errorstr += "# DURING FILE PARSING. #\n" errorstr += "# #\n" errorstr += "# Please determine if the file is #\n" errorstr += "# in the current directory and #\n" errorstr += "# that it has been properly #\n" errorstr += "# formatted. #\n" errorstr += "# #\n" errorstr += "# This error message is being #\n" errorstr += "# generated from within the #\n" errorstr += "# parseinput.py module. #\n" errorstr += "# #\n" errorstr += "###################################\n" raise ValueError, errorstr # Extract the output name from the association table if None # was provided on input. if outputname == None: newoutputname = assocdict['output'] # Loop over the association dictionary to extract the input # file names. for f in assocdict['order']: assoclist.append(fileutil.buildRootname(f)) # Remove the name of the association table from the list of files files.remove(file) # Append the list of filenames generated from the association table # to the master list of input files. files.extend(assoclist) # Return the list of the input files and the output name if provided in an association. return files,newoutputname