if outfile: utc_new=saltsafekey.get('UTC-OBS', struct[i+k], infile) utc_new_sec=slottool.getobstime(struct[i], infile) fout.write('%25s %2i %12s %12s %7.3f %5.4f %4i \n' % (infile, i, utc_list[j], utc_new, utc_new_sec, t_diff[j], nd[j] )) j += 1 # Housekeeping key words if update: history = 'SALTUTCFIX -- ' history += 'images='+infile+' ' saltsafekey.housekeeping(struct[0],'SLOTUTC','UTC has been corrected',history,infile) # update fits file if update: saltsafeio.updatefits(struct) saltsafeio.closefits(struct) # close outfile if outfile: fout.close() # Keep plot window open if plotdata: plt.show() def updateheaders(struct, ext, tdiff, real_expt, utc, infile): # exit if tdiff wasn't updated if tdiff == real_expt: msg='No adequate correction found for frame %i in file %s' % (ext, infile) raise SaltError(msg)
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 as 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 as e: msg='Could not set user dwell time because %s' % e raise SaltError(msg) # If requested, update the UTC times if update or outfile: if verbose: log.message('Updating UTC times') 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.openupdatefits(infile) # 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): for k in range(0,amplifiers): if update: struct[i+k]=updateheaders(struct[i+k],i+k, t_diff[j], real_expt, utc_list[j], infile) if outfile: utc_new=saltsafekey.get('UTC-OBS', struct[i+k], infile) utc_new_sec=slottool.getobstime(struct[i], infile) fout.write('%25s %2i %12s %12s %7.3f %5.4f %4i \n' % (infile, i, utc_list[j], utc_new, utc_new_sec, t_diff[j], nd[j] )) j += 1 # Housekeeping key words if update: history = 'SALTUTCFIX -- ' history += 'images='+infile+' ' saltsafekey.housekeeping(struct[0],'SLOTUTC','UTC has been corrected',history,infile) # update fits file if update: saltsafeio.updatefits(struct) saltsafeio.closefits(struct) # close outfile if outfile: fout.close() # Keep plot window open if plotdata: plt.show()
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()
fout.write('%25s %2i %12s %12s %7.3f %5.4f %4i \n' % (infile, i, utc_list[j], utc_new, utc_new_sec, t_diff[j], nd[j])) j += 1 # Housekeeping key words if update: history = 'SALTUTCFIX -- ' history += 'images=' + infile + ' ' saltsafekey.housekeeping(struct[0], 'SLOTUTC', 'UTC has been corrected', history, infile) # update fits file if update: saltsafeio.updatefits(struct) saltsafeio.closefits(struct) # close outfile if outfile: fout.close() # Keep plot window open if plotdata: plt.show() def updateheaders(struct, ext, tdiff, real_expt, utc, infile): # exit if tdiff wasn't updated if tdiff == real_expt: msg = 'No adequate correction found for frame %i in file %s' % (ext,