def saltfpevelocity(infile, existfit, xc, yc, rmax, logfile, verbose): """XXX""" # getting paths for filenames pathin = os.path.dirname(infile) basein = os.path.basename(infile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) print pathin, basein # start log now that all parameters are set up with logging(logfile, debug) as log: # Some basic checks, some tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input', infile) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(infile) # if a list is input throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file') # The file contains a list of images, check they exist # format is 4x dummy lines, then a line/lines containing: x,y,wave0,sn,norm,dnorm,filename testfile = open(infile) print testfile for i in range(1, 5): line = testfile.readline() line = 'dummy' infiles = [] while (len(line.strip()) != 0): line = testfile.readline() if (len(line.strip()) > 0): linearray = line.split() infiles.append(linearray[6]) # check input files exist saltsafeio.filesexist(infiles, '', 'r') # convert existfile to a one letter string if existfit == 'yes': existfit == 'y' else: existfit == 'n' # If all looks OK, run the FORTRAN code print infile, 'input filename' print existfit, xc, yc, rmax evelocity_wrapper2.evelocity2(infile, existfit, xc, yc, rmax)
def saltfpeprofile(plottype, infile, logfile, verbose): """Line profile fitting and display""" plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # getting paths for filenames pathin = os.path.dirname(infile) basein = os.path.basename(infile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) print pathin, basein # start log now that all parameters are set up with logging(logfile, debug) as log: # Some basic checks, some tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input', infile) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(infile) # if a list is input throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file') # The file contains a list of images, check they exist # format is 4x dummy lines, then a line/lines containing: x,y,wave0,sn,norm,dnorm,filename testfile = open(infile) print testfile for i in range(1, 5): line = testfile.readline() line = 'dummy' infiles = [] while (len(line.strip()) != 0): line = testfile.readline() if (len(line.strip()) > 0): linearray = line.split() infiles.append(linearray[6]) # check input files exist saltsafeio.filesexist(infiles, '', 'r') # If all looks OK, run the FORTRAN code print 'input filename = ', infile eprofile_wrapper.eprofile(plottype, infile)
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 saltfpcalibrate(plottype, infile, outfile, calibratelogfile, logfile, verbose): """Determines the wavelength calibration of the Fabry-Perot interactively, using the ring measurements from the CALRING program.""" plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input', infile) # The input file in this case is a file, does it exist? if infile[0] != '@': saltsafeio.fileexists(infile) # is the proposed output file specified? saltsafeio.filedefined('Output', outfile) # check whether the proposed output file exists path = os.path.dirname(infile) if len(path) > 0: dir = path + '/' else: dir = './' print dir, ' directory with data' outfile = outfile.strip() if os.path.isfile(outfile): print 'output file exists, appending' # saltsafeio.delete(outfile) # check whether the calibrate logfile is defined saltsafeio.filedefined('Log', calibratelogfile) # Get current working directory as the Fortran code changes dir startdir = os.getcwd() # If all looks OK, run the FORTRAN code calibrate_wrapper.calibrate(plottype, infile, outfile, calibratelogfile) # go back to starting directory os.chdir(startdir)
def saltfpcalibrate(plottype,infile,outfile,calibratelogfile,logfile,verbose): """Determines the wavelength calibration of the Fabry-Perot interactively, using the ring measurements from the CALRING program.""" plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input',infile) # The input file in this case is a file, does it exist? if infile[0] != '@': saltsafeio.fileexists(infile) # is the proposed output file specified? saltsafeio.filedefined('Output',outfile) # check whether the proposed output file exists path = os.path.dirname(infile) if len(path) > 0: dir = path + '/' else: dir = './' print dir, ' directory with data' outfile = outfile.strip() if os.path.isfile(outfile): print 'output file exists, appending' # saltsafeio.delete(outfile) # check whether the calibrate logfile is defined saltsafeio.filedefined('Log',calibratelogfile) # Get current working directory as the Fortran code changes dir startdir = os.getcwd() # If all looks OK, run the FORTRAN code calibrate_wrapper.calibrate(plottype,infile, outfile, calibratelogfile) # go back to starting directory os.chdir(startdir)
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 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 saltfpringfilter(axc,ayc,arad,rxc,ryc,filterfreq,filterwidth,itmax,conv, fitwidth,image,logfile,useconfig,configfile,verbose): """ Determines the center coordinates of a ring, bins the ring radially and computes its power spectrum, and allows the user to select a smoothing filter for the ring. """ # default parameter values are set up in the pyraf .par file. The values used are then changed if a FORTRAN config file exists and the user elects to override the pyraf .par file. # Is the input FORTRAN config file specified? # If it is blank, then it will be ignored. if useconfig: configfile = configfile.strip() if len(configfile) > 0: #check exists saltsafeio.fileexists(configfile) # read updated parameters from the file array=getpfp(configfile,"axc") s=len(array) flag = array[s-1] if flag == 1: axc=float(array[0]) array=getpfp(configfile,"ayc") s=len(array) flag = array[s-1] if flag == 1: ayc=float(array[0]) array=getpfp(configfile,"arad") s=len(array) flag = array[s-1] if flag == 1: arad=float(array[0]) array=getpfp(configfile,"rxc") s=len(array) flag = array[s-1] if flag == 1: rxc=float(array[0]) array=getpfp(configfile,"ryc") s=len(array) flag = array[s-1] if flag == 1: ryc=float(array[0]) array=getpfp(configfile,"calring_filter_width") s=len(array) flag = array[s-1] if flag == 1: filterwidth=int(array[0]) array=getpfp(configfile,"calring_filter_freq") s=len(array) flag = array[s-1] if flag == 1: filterfreq=int(array[0]) array=getpfp(configfile,"calring_itmax") s=len(array) flag = array[s-1] if flag == 1: itmax=int(array[0]) array=getpfp(configfile,"calring_conv") s=len(array) flag = array[s-1] if flag == 1: conv=float(array[0]) array=getpfp(configfile,"calring_fitwidth") s=len(array) flag = array[s-1] if flag == 1: fitwidth=float(array[0]) # getting paths for filenames pathin = os.path.dirname(image) basein = os.path.basename(image) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) # forcing logfiles to be created in the same directory as the input data # (we change to this directory once starting the fortran code) if len(pathin) > 0: logfile = baselog # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input',image) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(image) infile = image # if the input file is a list, throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file' ) # optionally update the FORTRAN config file with new values - not implemented currently # If all looks OK, run the FORTRAN code if len(pathin) > 0: dir = pathin else: dir = './' infile = basein print(dir, infile, 'input directory and input file') # Get current working directory as the Fortran code changes dir startdir = os.getcwd() ringfilter_wrapper.ringfilter(dir,axc, ayc,arad, rxc,ryc,filterfreq,filterwidth,itmax,conv,fitwidth,infile) # go back to starting directory os.chdir(startdir)
def saltfpringfilter(axc, ayc, arad, rxc, ryc, filterfreq, filterwidth, itmax, conv, fitwidth, image, logfile, useconfig, configfile, verbose): """ Determines the center coordinates of a ring, bins the ring radially and computes its power spectrum, and allows the user to select a smoothing filter for the ring. """ # default parameter values are set up in the pyraf .par file. The values used are then changed if a FORTRAN config file exists and the user elects to override the pyraf .par file. # Is the input FORTRAN config file specified? # If it is blank, then it will be ignored. if useconfig: configfile = configfile.strip() if len(configfile) > 0: #check exists saltsafeio.fileexists(configfile) # read updated parameters from the file array = getpfp(configfile, "axc") s = len(array) flag = array[s - 1] if flag == 1: axc = float(array[0]) array = getpfp(configfile, "ayc") s = len(array) flag = array[s - 1] if flag == 1: ayc = float(array[0]) array = getpfp(configfile, "arad") s = len(array) flag = array[s - 1] if flag == 1: arad = float(array[0]) array = getpfp(configfile, "rxc") s = len(array) flag = array[s - 1] if flag == 1: rxc = float(array[0]) array = getpfp(configfile, "ryc") s = len(array) flag = array[s - 1] if flag == 1: ryc = float(array[0]) array = getpfp(configfile, "calring_filter_width") s = len(array) flag = array[s - 1] if flag == 1: filterwidth = int(array[0]) array = getpfp(configfile, "calring_filter_freq") s = len(array) flag = array[s - 1] if flag == 1: filterfreq = int(array[0]) array = getpfp(configfile, "calring_itmax") s = len(array) flag = array[s - 1] if flag == 1: itmax = int(array[0]) array = getpfp(configfile, "calring_conv") s = len(array) flag = array[s - 1] if flag == 1: conv = float(array[0]) array = getpfp(configfile, "calring_fitwidth") s = len(array) flag = array[s - 1] if flag == 1: fitwidth = float(array[0]) # getting paths for filenames pathin = os.path.dirname(image) basein = os.path.basename(image) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) # forcing logfiles to be created in the same directory as the input data # (we change to this directory once starting the fortran code) if len(pathin) > 0: logfile = baselog # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input', image) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(image) infile = image # if the input file is a list, throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file') # optionally update the FORTRAN config file with new values - not implemented currently # If all looks OK, run the FORTRAN code if len(pathin) > 0: dir = pathin else: dir = './' infile = basein print dir, infile, 'input directory and input file' # Get current working directory as the Fortran code changes dir startdir = os.getcwd() ringfilter_wrapper.ringfilter(dir, axc, ayc, arad, rxc, ryc, filterfreq, filterwidth, itmax, conv, fitwidth, infile) # go back to starting directory os.chdir(startdir)
def slotback(images, outfits, extension, imgtype='image', subbacktype='median', sigback=3, mbin=7, sorder=3, niter=5, ampperccd=2, ignorexp=6, clobber=False, logfile='salt.log', verbose=True): with logging(logfile, debug) as log: # set up the variables order = sorder plotfreq = 0.01 ftime = plotfreq # is the input file specified? infiles = saltio.argunpack('Input', images) # is the output file specified? saltio.filedefined('Output', outfits) #open the first file and check its charactistics struct = saltio.openfits(infiles[0]) # how many extensions? nextend = saltkey.get('NEXTEND', struct[0]) if nextend < extension: msg = 'Insufficient number of extensions in %s' % (infile) raise SaltIOError(msg) # how many amplifiers? amplifiers = saltkey.get('NCCDS', struct[0]) amplifiers = int(ampperccd * float(amplifiers)) if ampperccd > 0: nframes = nextend / amplifiers nstep = amplifiers else: nframes = nextend nstep = 1 ntotal = nframes * len(infiles) # image size naxis1 = saltkey.get('NAXIS1', struct[extension]) naxis2 = saltkey.get('NAXIS2', struct[extension]) # CCD binning ccdsum = saltkey.get('CCDSUM', struct[0]) binx = int(ccdsum.split(' ')[0]) biny = int(ccdsum.split(' ')[1]) # If a total file is to written out, create it and update it hdu = 1 # delete the file if clobber is on and the file exists if os.path.isfile(outfits): if clobber: saltio.delete(outfits) else: raise SaltIOError( 'Output fits file ' + writenewfits + 'already exists. Use Clobber=yes to overwrite file') # create the output file 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(outfits) except: raise SaltIOError('Could not create new fits file named ' + writenewfits) # read it back in for updating hduList = saltio.openfits(outfits, mode='update') # set up the completeness tracker if verbose: j = 0 x2 = float(j) / float(ntotal) ctext = 'Percentage Complete: %3.2f' % x2 sys.stdout.write(ctext) sys.stdout.flush() for infile in infiles: struct = saltio.openfits(infile) # Skip through the frames and process each frame individually for i in range(nframes): if not (infile == infiles[0] and i < ignorexp): hdu = extension + i * nstep try: header = struct[hdu].header array = struct[hdu].data array = array * 1.0 except Exception, e: msg = 'Unable to open extension %i in image %s because %s' % ( hdu, infile, e) raise SaltIOError(msg) # start the analysis of each frame # gain and readout noise try: gain = float(header['GAIN']) except: gain = 1 log.warning('Gain not specified in image header') try: rdnoise = float(header['RDNOISE']) except: rdnoise = 0 log.warning('RDNOISE not specified in image header') # background subtraction if not subbacktype == 'none': try: narray = subbackground(array, sigback, mbin, order, niter, subbacktype) except: log.warning('Image ' + infile + ' extention ' + str(i) + ' is blank, skipping') continue # create output array try: if imgtype == 'background': oarray = narray - array else: oarray = narray except: oarray = array # print progress if verbose: x2 = float(j) / float(ntotal) if x2 > ftime: ctext = '\b\b\b\b\b %3.2f' % x2 sys.stdout.write(ctext) sys.stdout.flush() ftime += plotfreq # update the header values with the image name and extension number try: hdue = pyfits.ImageHDU(oarray) hdue.header = header hdue.header.update('ONAME', infile, 'Original image name') hdue.header.update('OEXT', hdu, 'Original extension number') except Exception, e: msg='SALTPHOT--WARNING: Could not update image in newfits file for %s ext %i because %s' \ % (infile, hdu, e) raise SaltIOError(msg) hduList.append(hdue) j += 1 # close FITS file saltio.closefits(struct)
def slotback(images,outfits,extension,imgtype='image',subbacktype='median', sigback=3,mbin=7,sorder=3,niter=5,ampperccd=2,ignorexp=6, clobber=False,logfile='salt.log',verbose=True): with logging(logfile,debug) as log: # set up the variables order=sorder plotfreq=0.01 ftime=plotfreq # is the input file specified? infiles = saltio.argunpack ('Input',images) # is the output file specified? saltio.filedefined('Output',outfits) #open the first file and check its charactistics struct=saltio.openfits(infiles[0]) # how many extensions? nextend=saltkey.get('NEXTEND',struct[0]) if nextend < extension: msg='Insufficient number of extensions in %s' % (infile) raise SaltIOError(msg) # how many amplifiers? amplifiers=saltkey.get('NCCDS',struct[0]) amplifiers = int(ampperccd*float(amplifiers)) if ampperccd>0: nframes = nextend/amplifiers nstep=amplifiers else: nframes = nextend nstep=1 ntotal=nframes*len(infiles) # image size naxis1=saltkey.get('NAXIS1',struct[extension]) naxis2=saltkey.get('NAXIS2',struct[extension]) # CCD binning ccdsum=saltkey.get('CCDSUM',struct[0]) binx=int(ccdsum.split(' ')[0]) biny=int(ccdsum.split(' ')[1]) # If a total file is to written out, create it and update it hdu = 1 # delete the file if clobber is on and the file exists if os.path.isfile(outfits): if clobber: saltio.delete(outfits) else: raise SaltIOError('Output fits file '+writenewfits+'already exists. Use Clobber=yes to overwrite file') # create the output file 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(outfits) except: raise SaltIOError('Could not create new fits file named '+writenewfits) # read it back in for updating hduList = saltio.openfits(outfits,mode='update') # set up the completeness tracker if verbose: j=0 x2=float(j)/float(ntotal) ctext='Percentage Complete: %3.2f' % x2 sys.stdout.write(ctext) sys.stdout.flush() for infile in infiles: struct=saltio.openfits(infile) # Skip through the frames and process each frame individually for i in range(nframes): if not (infile==infiles[0] and i < ignorexp): hdu=extension+i*nstep try: header=struct[hdu].header array=struct[hdu].data array=array*1.0 except Exception as e: msg='Unable to open extension %i in image %s because %s' % (hdu, infile, e) raise SaltIOError(msg) # start the analysis of each frame # gain and readout noise try: gain=float(header['GAIN']) except: gain=1 log.warning('Gain not specified in image header') try: rdnoise=float(header['RDNOISE']) except: rdnoise=0 log.warning('RDNOISE not specified in image header') # background subtraction if not subbacktype=='none': try: narray=subbackground(array, sigback, mbin, order, niter, subbacktype) except: log.warning('Image '+infile+' extention '+str(i)+' is blank, skipping') continue # create output array try: if imgtype=='background': oarray=narray-array else: oarray=narray except: oarray=array # print progress if verbose: x2=float(j)/float(ntotal) if x2 > ftime: ctext='\b\b\b\b\b %3.2f' % x2 sys.stdout.write(ctext) sys.stdout.flush() ftime += plotfreq # update the header values with the image name and extension number try: hdue = pyfits.ImageHDU(oarray) hdue.header=header hdue.header.update('ONAME',infile,'Original image name') hdue.header.update('OEXT',hdu,'Original extension number') except Exception as e: msg='SALTPHOT--WARNING: Could not update image in newfits file for %s ext %i because %s' \ % (infile, hdu, e) raise SaltIOError(msg) hduList.append(hdue) j +=1 # close FITS file saltio.closefits(struct) # close the output fits file: try: # write out the file hduList.flush() hduList.close() except Exception as e: raise SaltIOError('Failed to write %s because %s' % (outfits, e))
def saltfpeprofile(plottype,infile,logfile, verbose): """Line profile fitting and display""" plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # getting paths for filenames pathin = os.path.dirname(infile) basein = os.path.basename(infile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) print pathin, basein # start log now that all parameters are set up with logging(logfile, debug) as log: # Some basic checks, some tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input',infile) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(infile) # if a list is input throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file' ) # The file contains a list of images, check they exist # format is 4x dummy lines, then a line/lines containing: x,y,wave0,sn,norm,dnorm,filename testfile= open(infile) print testfile for i in range(1, 5): line = testfile.readline() line = 'dummy' infiles=[] while (len(line.strip()) != 0): line = testfile.readline() if (len(line.strip()) > 0): linearray = line.split() infiles.append(linearray[6]) # check input files exist saltsafeio.filesexist(infiles,'','r') # If all looks OK, run the FORTRAN code print 'input filename = ', infile eprofile_wrapper.eprofile(plottype,infile)
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 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 saltfpcalprofile(axc,ayc,arad,rxc,ryc,filter, filterfreq,filterwidth,plottype,itmax,conv, fitwidth,rlo,rhi,rfixed,cenfixed,images,outfile,comment,cala, calb, calc, cald, calf,calprofilelogfile,logfile,useconfig,configfile,verbose): """Fits a Voigt profile to a ring in one or more Fabry-Perot calibration ring images""" # default parameter values are set up in the pyraf .par file. The values used are then changed if a FORTRAN config file exists and the user elects to override the pyraf .par file. # Is the input FORTRAN config file specified? # If it is blank, then it will be ignored. if useconfig: configfile = configfile.strip() if len(configfile) > 0: #check exists saltsafeio.fileexists(configfile) # read updated parameters from the file array=getpfp(configfile,"axc") s=len(array) flag = array[s-1] if flag == 1: axc=float(array[0]) array=getpfp(configfile,"ayc") s=len(array) flag = array[s-1] if flag == 1: ayc=float(array[0]) array=getpfp(configfile,"arad") s=len(array) flag = array[s-1] if flag == 1: arad=float(array[0]) array=getpfp(configfile,"rxc") s=len(array) flag = array[s-1] if flag == 1: rxc=float(array[0]) array=getpfp(configfile,"ryc") s=len(array) flag = array[s-1] if flag == 1: ryc=float(array[0]) array=getpfp(configfile,"calring_filter") s=len(array) flag = array[s-1] if flag == 1: filter=str(array[0]) array=getpfp(configfile,"calring_filter_width") s=len(array) flag = array[s-1] if flag == 1: filterwidth=int(array[0]) array=getpfp(configfile,"calring_filter_freq") s=len(array) flag = array[s-1] if flag == 1: filterfreq=int(array[0]) array=getpfp(configfile,"calring_itmax") s=len(array) flag = array[s-1] if flag == 1: itmax=int(array[0]) array=getpfp(configfile,"calring_conv") s=len(array) flag = array[s-1] if flag == 1: conv=float(array[0]) array=getpfp(configfile,"calring_fitwidth") s=len(array) flag = array[s-1] if flag == 1: fitwidth=float(array[0]) array=getpfp(configfile,"calring_rlo") s=len(array) flag = array[s-1] if flag == 1: rlo=float(array[0]) array=getpfp(configfile,"calring_rhi") s=len(array) flag = array[s-1] if flag == 1: rhi=float(array[0]) array=getpfp(configfile,"calring_fixed") s=len(array) flag = array[s-1] if flag == 1: cenfixed=str(array[0]) array=getpfp(configfile,"calibration_a") s=len(array) flag = array[s-1] if flag == 1: cala=float(array[0]) array=getpfp(configfile,"calibration_b") s=len(array) flag = array[s-1] if flag == 1: calb=float(array[0]) array=getpfp(configfile,"calibration_c") s=len(array) flag = array[s-1] if flag == 1: calc=float(array[0]) array=getpfp(configfile,"calibration_d") s=len(array) flag = array[s-1] if flag == 1: cald=float(array[0]) array=getpfp(configfile,"calibration_f") s=len(array) flag = array[s-1] if flag == 1: calf=float(array[0]) cenfixed=str(cenfixed) if cenfixed[0] == 'y' or cenfixed[0] == 'Y': cenfixed = 1 else: cenfixed = 0 cenfixed = bool(cenfixed) filter = str(filter) if filter[0] == 'y' or filter[0] == 'Y': filter = 1 else: filter = 0 filter = bool(filter) plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # getting paths for filenames pathin = os.path.dirname(images) basein = os.path.basename(images) pathout = os.path.dirname(outfile) baseout = os.path.basename(outfile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) pathcalprofilelog = os.path.dirname(calprofilelogfile) basecalprofilelog = os.path.basename(calprofilelogfile) # forcing logfiles to be created in the same directory as the input data # (we change to this directory once starting the fortran code) if len(pathin) > 0: logfile = baselog calprofilelogfile = basecalprofilelog # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input',images) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(images) infile = images # if the input file is a list, does it exist? if basein[0] == '@': infile2 = basein.lstrip('@') if (len(pathin) > 0): infile = pathin + '/' + infile2 else: infile = infile2 saltsafeio.listexists('Input',infile) # parse list of input files infiles=fpsafeio.fplistparse('Raw image',images,'','','') # check input files exist saltsafeio.filesexist(infiles,'','r') # is the proposed output file specified? saltsafeio.filedefined('Output',outfile) # check whether the proposed output file exists path = os.path.dirname(images) if len(path) > 0: dir = path + '/' else: dir = './' # print dir, ' directory with data' outfile = outfile.strip() if os.path.isfile(outfile): print 'output file exists, appending' # saltsafeio.delete(outfile) # optionally update the FORTRAN config file with new values - not implemented currently # If all looks OK, run the FORTRAN code infile = basein if len(pathout) > 0 : if (pathin == pathout): outfile = baseout # absolute path then leave alone elif pathout[0] == '/': outfile = outfile else: # as will move to directory of input data, need to strip this off if its in the path a = pathout.lstrip(pathin) b = a.lstrip('/') outfile = b + '/' + baseout print dir, infile, outfile, 'input directory, input and output files' if basein[0] == '@': print infiles,'infiles' # Get current working directory as the Fortran code changes dir startdir = os.getcwd() calprofile_wrapper.calprofile(dir,calprofilelogfile,outfile,comment, axc, ayc,arad, rxc,ryc,filter,filterfreq,filterwidth,plottype,itmax,conv,fitwidth,rlo,rhi,rfixed, cenfixed,infile, cala, calb, calc, cald, calf) # go back to starting directory os.chdir(startdir)
def saltfpnightring(axc, ayc, arad, rxc, ryc, filter, filterfreq, filterwidth, plot, plottype, itmax, conv, fitwidth, images, outfile, comment, cala, calb, calc, cald, calf, nightringlogfile, logfile, useconfig, configfile, verbose): """Measures the centre coordinates and radius of one or more night-time calibration rings """ # default parameter values are set up in the pyraf .par file. The values used are then changed if a FORTRAN config file exists and the user elects to override the pyraf .par file. # Is the input FORTRAN config file specified? # If it is blank, then it will be ignored. if useconfig: configfile = configfile.strip() if len(configfile) > 0: #check exists saltsafeio.fileexists(configfile) # read updated parameters from the file array = getpfp(configfile, "axc") s = len(array) flag = array[s - 1] if flag == 1: axc = float(array[0]) array = getpfp(configfile, "ayc") s = len(array) flag = array[s - 1] if flag == 1: ayc = float(array[0]) array = getpfp(configfile, "arad") s = len(array) flag = array[s - 1] if flag == 1: arad = float(array[0]) array = getpfp(configfile, "rxc") s = len(array) flag = array[s - 1] if flag == 1: rxc = float(array[0]) array = getpfp(configfile, "ryc") s = len(array) flag = array[s - 1] if flag == 1: ryc = float(array[0]) array = getpfp(configfile, "calring_filter") s = len(array) flag = array[s - 1] if flag == 1: filter = str(array[0]) array = getpfp(configfile, "calring_filter_width") s = len(array) flag = array[s - 1] if flag == 1: filterwidth = int(array[0]) array = getpfp(configfile, "calring_filter_freq") s = len(array) flag = array[s - 1] if flag == 1: filterfreq = int(array[0]) array = getpfp(configfile, "calring_itmax") s = len(array) flag = array[s - 1] if flag == 1: itmax = int(array[0]) array = getpfp(configfile, "calring_conv") s = len(array) flag = array[s - 1] if flag == 1: conv = float(array[0]) array = getpfp(configfile, "calring_fitwidth") s = len(array) flag = array[s - 1] if flag == 1: fitwidth = float(array[0]) array = getpfp(configfile, "calibration_a") s = len(array) flag = array[s - 1] if flag == 1: cala = float(array[0]) array = getpfp(configfile, "calibration_b") s = len(array) flag = array[s - 1] if flag == 1: calb = float(array[0]) array = getpfp(configfile, "calibration_c") s = len(array) flag = array[s - 1] if flag == 1: calc = float(array[0]) array = getpfp(configfile, "calibration_d") s = len(array) flag = array[s - 1] if flag == 1: cald = float(array[0]) array = getpfp(configfile, "calibration_f") s = len(array) flag = array[s - 1] if flag == 1: calf = float(array[0]) filter = str(filter) if filter[0] == 'y' or filter[0] == 'Y': filter = 1 else: filter = 0 filter = bool(filter) plot = str(plot) if plot[0] == 'y' or plot[0] == 'Y': plot = 1 else: plot = 0 plot = bool(plot) plottype = str(plottype) plottype = plottype.strip() if plottype == 'xwindow': plottype = '/xw' else: plottype = '/ps' # additional verbose command as required in the fortran code too. Set this to whatever is input in the epar file. verb = str(verbose) if verb[0] == 'y' or verb[0] == 'Y': verb = 1 else: verb = 0 verb = bool(verb) # getting paths for filenames pathin = os.path.dirname(images) basein = os.path.basename(images) pathout = os.path.dirname(outfile) baseout = os.path.basename(outfile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) pathnightringlog = os.path.dirname(nightringlogfile) basenightringlog = os.path.basename(nightringlogfile) # forcing logfiles to be created in the same directory as the input data # (we change to this directory once starting the fortran code) if len(pathin) > 0: logfile = baselog nightringlogfile = basenightringlog # start log now that all parameter are set up with logging(logfile, debug) as log: # Some basic checks, many tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input', images) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(images) infile = images # if the input file is a list, does it exist? if basein[0] == '@': infile2 = basein.lstrip('@') if (len(pathin) > 0): infile = pathin + '/' + infile2 else: infile = infile2 saltsafeio.listexists('Input', infile) # parse list of input files infiles = fpsafeio.fplistparse('Raw image', images, '', '', '') # check input files exist saltsafeio.filesexist(infiles, '', 'r') # is the proposed output file specified? saltsafeio.filedefined('Output', outfile) # check whether the proposed output file exists path = os.path.dirname(images) if len(path) > 0: dir = path + '/' else: dir = './' # print dir, ' directory with data' outfile = outfile.strip() if os.path.isfile(outfile): print 'output file exists, appending' # saltsafeio.delete(outfile) # optionally update the FORTRAN config file with new values - not implemented currently # If all looks OK, run the FORTRAN code infile = basein if len(pathout) > 0: if (pathin == pathout): outfile = baseout # absolute path then leave alone elif pathout[0] == '/': outfile = outfile else: # as will move to directory of input data, need to strip this off if its in the path a = pathout.lstrip(pathin) b = a.lstrip('/') outfile = b + '/' + baseout print dir, infile, outfile, 'input directory, input and output files' if basein[0] == '@': print infiles, 'infiles' # Get current working directory as the Fortran code changes dir startdir = os.getcwd() nightring_wrapper.nightring(dir, nightringlogfile, outfile, comment, axc, ayc, arad, rxc, ryc, filter, filterfreq, filterwidth, plot, plottype, itmax, conv, fitwidth, infile, cala, calb, calc, cald, calf, verb) # go back to starting directory os.chdir(startdir)
def saltfpevelocity(infile,existfit,xc,yc,rmax,logfile, verbose): """XXX""" # getting paths for filenames pathin = os.path.dirname(infile) basein = os.path.basename(infile) pathlog = os.path.dirname(logfile) baselog = os.path.basename(logfile) print(pathin, basein) # start log now that all parameters are set up with logging(logfile, debug) as log: # Some basic checks, some tests are done in the FORTRAN code itself # is the input file specified? saltsafeio.filedefined('Input',infile) # if the input file is a file, does it exist? if basein[0] != '@': saltsafeio.fileexists(infile) # if a list is input throw an error if basein[0] == '@': raise SaltIOError(basein + ' list input instead of a file' ) # The file contains a list of images, check they exist # format is 4x dummy lines, then a line/lines containing: x,y,wave0,sn,norm,dnorm,filename testfile= open(infile) print(testfile) for i in range(1, 5): line = testfile.readline() line = 'dummy' infiles=[] while (len(line.strip()) != 0): line = testfile.readline() if (len(line.strip()) > 0): linearray = line.split() infiles.append(linearray[6]) # check input files exist saltsafeio.filesexist(infiles,'','r') # convert existfile to a one letter string if existfit == 'yes': existfit == 'y' else: existfit =='n' # If all looks OK, run the FORTRAN code print(infile, 'input filename') print(existfit, xc, yc, rmax) evelocity_wrapper2.evelocity2(infile,existfit,xc,yc,rmax)
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 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.')