def womrebindriver(hop, mode): """input info to call womrebin functions""" import matplotlib.pyplot as plt import numpy as np from tmath.wombat.inputter import inputter from tmath.wombat.waveparse import waveparse from tmath.wombat.yesno import yesno from tmath.wombat.womashrebin import womashrebin from tmath.wombat.womscipyrebin import womscipyrebin print('Current A/pix is {}'.format(hop[0].wave[1] - hop[0].wave[0])) print('Wavelength rage: {} to {}'.format(hop[0].wave[0], hop[0].wave[-1])) plt.cla() plt.plot(hop[0].wave, hop[0].flux, drawstyle='steps-mid') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) done = False while (not done): newdelt=inputter('Rebin to how many Angstroms per pixel? ', \ 'float',False) waveb, waver = waveparse() if (waveb > waver): waveb, waver = waver, waveb if (newdelt > 0): newbin = (waver - waveb) / newdelt + 1.0 frac, whole = np.modf(newbin) if (frac > 0.000001): print('NON-INTEGER number of bins') testwave = newdelt * whole + waveb print('Closest match is: {} to {}'.format(waveb, testwave)) print('Would you like this wavelength range?') answer = yesno('y') if (answer == 'y'): waver = testwave done = True else: print('Rebinning to {} A/pix, {} to {}'.format(newdelt,waveb,\ waver)) print('Is this OK?') answer = yesno('y') if (answer == 'y'): done = True nwave = np.arange(0, whole) * newdelt + waveb if (mode == 'ash'): nflux = womashrebin(hop[0].wave, hop[0].flux, nwave) nvar = womashrebin(hop[0].wave, hop[0].var, nwave) else: nflux = womscipyrebin(hop[0].wave, hop[0].flux, nwave) nvar = womscipyrebin(hop[0].wave, hop[0].var, nwave) print('Overplotting rebinned spectrum') plt.cla() plt.plot(hop[0].wave, hop[0].flux, drawstyle='steps-mid') plt.plot(nwave, nflux, drawstyle='steps-mid') #FIX header hop[0].wave = nwave.copy() hop[0].flux = nflux.copy() hop[0].var = nvar.copy() return hop
def womblueshift(hop): """add redshift to spectrum""" import numpy as np from tmath.wombat.yesno import yesno from tmath.wombat.inputter_single import inputter_single from tmath.wombat.inputter import inputter from tmath.wombat.womrebindriver import womrebindriver light_speed = 2.99792458e5 print('Current A/pix is {}'.format(hop[0].wave[1] - hop[0].wave[0])) print('\nWavelength range: {} to {}\n'.format(hop[0].wave[0], hop[0].wave[-1])) answer = inputter_single('Remove redshift in (z) or (k)m/s? (z/k) ', 'zk') z = inputter('Enter the desired blueshift (positive is away from us): ', 'float', False) if (answer == 'k'): z = np.sqrt((1.0 + z / c) / (1.0 - z / c)) - 1.0 hop[0].wave = hop[0].wave * (1.0 + z) print('\nNew wavelength range: {} to {}\n'.format(hop[0].wave[0], hop[0].wave[-1])) print('Rebin spectrum?') rebin = yesno('n') if (rebin == 'y'): hop = womrebindriver(hop, 'scipy') else: pass #FIX header return hop
def womreddening(hop): """redden or deredden with various reddening laws""" import matplotlib.pyplot as plt import extinction from tmath.wombat.inputter_single import inputter_single from tmath.wombat.inputter import inputter from tmath.wombat.yesno import yesno r_v=3.1 print('Redden or deredden a spectrum') plt.cla() plt.plot(hop[0].wave,hop[0].flux,drawstyle='steps-mid',color='k') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) flux=hop[0].flux.copy() action=inputter_single('(r)edden or (d)eredden the spectrum? (r/d) ', 'rd') print(' ') type=inputter_single('Do you want to enter the (c)olor excess, or (v)isual extinction? ','cv') print(' ') if (type == 'v'): av=inputter('Enter A_V in magnitudes: ','float',False) else: ebv=inputter('Enter E(B-V) in magnitudes: ','float',False) av=r_v*ebv print(' ') print('Do you want to use: ') print('(c)ardelli, Clayton, Mathis 1989') print("(o)'donnell 1994") print('(f)itzpatrick 1999\n') method=inputter_single('(c/o/f) ','cof') if (action == 'r'): if (method == 'c'): newflux=extinction.apply(extinction.ccm89(hop[0].wave,av,r_v),flux) elif (method == 'o'): newflux=extinction.apply(extinction.odonnell94(hop[0].wave,av,r_v),flux) else: newflux=extinction.apply(extinction.fitzpatrick99(hop[0].wave,av,r_v),flux) else: if (method == 'c'): ext=extinction.ccm89(hop[0].wave,av,r_v) elif (method == 'o'): ext=extinction.odonnell94(hop[0].wave,av,r_v) else: ext=extinction.fitzpatrick99(hop[0].wave,av,r_v) newflux=flux*10**(0.4*ext) plt.plot(hop[0].wave,newflux,drawstyle='steps-mid',color='r') print('\nOriginal spectrum in black, red/dered in red\n') print('Is this OK?\n') answer=yesno('y') if (answer == 'y'): hop[0].flux=newflux.copy() print('\nActive spectrum now changed') else: print('\nSorry to disappoint you, active spectrum unchanged') return hop
def womplot(hop): import matplotlib.pyplot as plt from tmath.wombat.yesno import yesno from tmath.wombat.wshow import wshow plt.cla() plt.plot(hop[0].wave, hop[0].flux, drawstyle='steps-mid') plt.xlabel('Wavelength') if (hop[0].wave[0] < 0): plt.xlabel('Velocity') plt.ylabel('Flux') plt.title(hop[0].obname) plt.pause(0.01) wshow() print('Change scale?') answer = yesno('n') if (answer == 'y'): xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() done = False while (not done): print('Click corners of box to change plot scale') newlims = plt.ginput(2, timeout=-1) xmin = newlims[0][0] ymin = newlims[0][1] xmax = newlims[1][0] ymax = newlims[1][1] plt.cla() plt.plot(hop[0].wave, hop[0].flux, drawstyle='steps-mid') plt.xlabel('Wavelength') if (hop[0].wave[0] < 0): plt.xlabel('Velocity') plt.ylabel('Flux') plt.title(hop[0].obname) plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) print('Is this OK?') loopanswer = yesno('y') if (loopanswer == 'y'): done = True return hop
def womwaverange(wave, flux, mode): import matplotlib.pyplot as plt from tmath.wombat.waveparse import waveparse from tmath.wombat.womget_element import womget_element from tmath.wombat.inputter_single import inputter_single from tmath.wombat.yesno import yesno from tmath.wombat.wshow import wshow if (mode == 'none'): print('Enter method to select wavelength range') mode = inputter_single( 'Enter (w)avelengths or mark with the (m)ouse? (w/m) ', 'wm') print(mode) print('Spectrum runs from {} to {}.'.format(wave[0], wave[-1])) plt.cla() plt.plot(wave, flux, drawstyle='steps-mid') plt.ylabel('Flux') plt.xlabel('Wavelength') wshow() done = False while (not done): if (mode == 'w'): waveb, waver = waveparse() else: pickpoints = plt.ginput(2, timeout=-1) waveb = pickpoints[0][0] waver = pickpoints[1][0] if (waveb > waver): waveb, waver = waver, waveb indexblue = womget_element(wave, waveb) indexred = womget_element(wave, waver) print('Range selected: {} to {}'.format(wave[indexblue], wave[indexred])) plt.plot(wave[indexblue:indexred+1],flux[indexblue:indexred+1], \ drawstyle='steps-mid',color='r') plt.pause(0.01) print('Is this range correct?') answer = yesno('y') if (answer == 'n'): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid') plt.ylabel('Flux') plt.xlabel('Wavelength') wshow() else: done = True return wave[indexblue:indexred + 1], flux[indexblue:indexred + 1], mode
def womexam(hop): """print spectrum bin values""" from tmath.wombat.womwaverange import womwaverange from tmath.wombat.womget_element import womget_element from tmath.wombat.yesno import yesno done = False while (not done): answer = 'y' wave, flux, mode = womwaverange(hop[0].wave, hop[0].flux, 'none') indexblue = womget_element(hop[0].wave, wave[0]) indexred = womget_element(hop[0].wave, wave[-1]) var = hop[0].var[indexblue:indexred + 1] if (len(wave) > 30): print('This will print out {} values'.format(len(wave))) print('Do you really want to do that?') answer = yesno('n') if (answer == 'y'): done = True print('\nWave Flux') for i, _ in enumerate(wave): print('{} {} {}'.format(wave[i], flux[i], var[i])) return hop
def final(objectlist, gratcode, secondord, gratcode2, user): import matplotlib.pyplot as plt from matplotlib import gridspec import numpy as np from datetime import datetime import os, pdb import inspect import glob import math from astropy.io import fits from astropy import units as u from astropy.coordinates import SkyCoord # from astropy.time import Time from tmath.wombat.get_screen_size import get_screen_size from tmath.wombat.getmswave import getmswave from tmath.wombat.inputter_single import inputter_single from tmath.wombat.inputter import inputter from tmath.wombat.womcatfinal import womcatfinal from tmath.pydux.scipyrebinsky import scipyrebinsky from tmath.wombat.yesno import yesno from tmath.wombat.womashrebin import womashrebin from tmath.wombat.wominterpofluxconserving import interpo_flux_conserving from tmath.wombat.womspectres import spectres from tmath.pydux.getfitsfile import getfitsfile from tmath.pydux.pacheck import pacheck from tmath.pydux.jdcnv import jdcnv from tmath.pydux.baryvel import baryvel from tmath.pydux.finalscaler import finalscaler from tmath.pydux.envelope import envelope from tmath.pydux.congrid import congrid from tmath.pydux.xcor import xcor from tmath.pydux.telluric_remove import telluric_remove from tmath.pydux.waveparse import waveparse from tmath.pydux.parsehourangle import parsehourangle from tmath.pydux import RADEG plt.ion() screen_width, screen_height = get_screen_size() screenpos = '+{}+{}'.format(int(screen_width * 0.2), int(screen_height * 0.05)) fig = plt.figure() fig.canvas.manager.window.wm_geometry(screenpos) fig.canvas.set_window_title('Final Reductions') fig.set_size_inches(8, 5) # turns off key stroke interaction fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id) # this should bring the window to the top, but it doesn't # wm=plt.get_current_fig_manager() #fig.canvas.manager.window.attributes('-topmost', 1) # blah=wm.window.attributes('-topmost', 1) #plt.pause(0.2) #fig.canvas.manager.window.attributes('-topmost', 0) # blah=wm.window.attributes('-topmost', 0) bstarfits = fits.open('bstar' + gratcode + '.fits') bstarstar = bstarfits[0].data bstarhead = bstarfits[0].header bstarwavezero = float(bstarhead['CRVAL1']) bstarwavedelt = float(bstarhead['CDELT1']) bstarwave = np.arange(len(bstarstar)) * bstarwavedelt + bstarwavezero bstarairmass = float(bstarhead['AIRMASS']) bstarname = bstarhead['OBJECT'] try: bstarnum = int(bstarhead['OBSNUM']) except KeyError: bstarnum = 0 if (secondord): bstarfits2 = fits.open('bstarstar' + gratcode2 + '.fits') bstarstar2 = bstarfits[0].data bstarhead2 = bstarfits[0].header bstarwavezero2 = float(bstarhead2['CRVAL1']) bstarwavedelt2 = float(bstarhead2['CDELT1']) bstarwave2 = np.arange( len(bstarstar2)) * bstarwavedelt2 + bstarwavezero2 bstarairmass2 = float(bstarhead2['AIRMASS']) bstarname2 = bstarhead2['OBJECT'] try: bstarnum2 = int(bstarhead2['OBSNUM']) except KeyError: bstarnum2 = 0 observat = bstarhead['OBSERVAT'].strip().lower() #reduxdir=os.environ['PY_REDUX'] reduxdir = inspect.getfile(xcor) reduxdir = reduxdir.rsplit('/', 1)[0] + '/' kecksky=['keck','gemini-north','gemini-n','gemini-south','gemini-s', \ 'soar','ctio','vlt','lco','lco-imacs','lapalma'] licksky = ['lick', 'kpno', 'flwo', 'mmto', 'sso'] if (observat in kecksky): mskyfile = reduxdir + 'kecksky.fits' elif (observat in licksky): mskyfile = reduxdir + 'licksky.fits' else: print('\nCannot find mastersky file and observatory unknown\n') mskyfile = getfitsfile('master sky', '.fits') print('Using {} as master sky'.format(mskyfile)) mskyfits = fits.open(mskyfile) mskydata = mskyfits[0].data mskyhead = mskyfits[0].header mskywavezero = float(mskyhead['CRVAL1']) mskywavedelt = float(mskyhead['CDELT1']) mskywave = np.arange(len(mskydata)) * mskywavedelt + mskywavezero if (np.abs(np.mean(mskydata)) < 1e-7): mskydata = mskydata * 1e15 print('\nHello {}\n'.format(user)) lat_dict = { 'keck': 19.8283, 'gemini-north': 19.8238, 'gemini-south': -30.228, 'gemini-n': 19.8238, 'gemini-s': -30.228, 'soar': -30.228, 'kpno': 31.9633, 'lick': 37.3414, 'palomar': 33.35611, 'mcdonald': 30.6717, 'flwo': 31.681, 'mmto': 31.688, 'sso': -31.2734, 'vlt': -24.6254, 'lco': -29.01, 'lco-imacs': -29.01, 'lapalma': 28.75833, 'ctio': -30.16894 } infile = open(objectlist, 'r') objname = '' secondtime = False seconddone = False for inputfile in infile: inputfile = inputfile.strip() if ('.fits' not in inputfile): inputfile = inputfile + '.fits' multifits = fits.open('c' + gratcode + inputfile) multispec = multifits[0].data mshead = multifits[0].header num_apertures = multispec.shape[1] num_bands = multispec.shape[0] wavearr = np.zeros((multispec.shape[2], multispec.shape[1])) if (secondord): multifits2 = fits.open('c' + gratcode2 + inputfile) multispec2 = multifits2[0].data mshead2 = multifits2[0].header pacheck(mshead) objectname = mshead['OBJECT'] print('The object is: {}'.format(objectname)) observat = mshead['OBSERVAT'].strip().lower() airmass = float(mshead['AIRMASS']) if (airmass < 1): airmass = 1.0 stringra = mshead['RA'] stringdec = mshead['DEC'] geminilist = ['gemini-north', 'gemini-south', 'gemini-n', 'gemini-s'] if (observat) in geminilist: ra = float(stringra) dec = float(stringdec) else: coords = SkyCoord(stringra, stringdec, unit=(u.hourangle, u.deg)) ra = coords.ra.deg dec = coords.dec.deg ra = ra / RADEG dec = dec / RADEG haheader = mshead['HA'] ha = parsehourangle(haheader) ha = ha * (360. / 24.) / RADEG if (observat in lat_dict): latitude = lat_dict[observat] else: print('Observatory Unknown!!!!!!!') latitude = 0.0 latitude = latitude / RADEG # Get Julian date and Earth's velocity #epoch=float(mshead['EPOCH']) date = mshead['DATE-OBS'].strip() # get year,month,day from ISO Y2K format YYYY-MM-DDThh:mm:ss.ssss # the time following T is optional, so we get T from UTMIDDLE if (date[4] == '-'): year = int(date.split('-')[0]) month = int(date.split('-')[1]) day = int(date.split('-')[2].split('T')[0]) printdate = '{}{:02d}{:02d}'.format(year, month, day) else: # Old date format DD/MM/YY year = int(date[6:8]) month = int(date[3:5]) day = int(date[0:2]) # try to catch old format written after 2000 # good until 2050, by which time no one should # be doing this if (year > 50): year = year + 1900 else: year = year + 2000 printdate = '{}{:02d}{:02d}'.format(year, month, day) try: ut = mshead['UTMIDDLE'].strip() except KeyError: ut = mshead['UT'].strip() if ('T' in ut): ut = ut.split('T')[1] # some UT/UTMIDDLE values are ISO format hour = int(ut.split(':')[0]) minute = int(ut.split(':')[1]) second = float(ut.split(':')[2]) julian = jdcnv(year, month, day, (hour + (minute / 60.) + (second / 3600.))) vh, vb = baryvel(julian) # Earth's velocity toward object v=vb[0]*np.cos(dec)*np.cos(ra) + vb[1]*np.cos(dec)*np.sin(ra) \ + vb[2]*np.sin(dec) # Correct for earth's rotation. # Note that this isn't strictly correct because ha is set to # the beginning of the observation, while it really should be # the middle. But this is a small difference and doesn't affect # the results in any way that we would notice... v = v - (0.4651 * np.cos(latitude) * np.sin(ha) * np.cos(dec)) print( '\nThe velocity of the Earth toward the target is {} km/s'.format( v)) print('\nThere are {} apertures in the spectrum.\n'.format( num_apertures)) # clean up header """ delkeylist=['WAT0_001', 'WAT1_001', 'WAT2_001', 'WAT0_002', \ 'WAT1_002', 'WAT2_002', 'WAT3_001', 'WAT2_003', \ 'CTYPE1', 'CTYPE2', 'CTYPE3', 'CD1_1', 'CD2_2', \ 'CD3_3', 'LTM1_1', 'LTM2_2', 'LTM3_3', 'WCSDIM'] for k in delkeylist: try: mshead.remove(k) except KeyError: pass """ waveb = None waver = None bshift = None for i in range(0, num_apertures): # plt.close() # fig=plt.figure() # plt.plot(multispec[0,i,:], drawstyle='steps-mid',color='r') # plt.plot(multispec[1,i,:], drawstyle='steps-mid',color='k') # plt.xlim(1750,1900) # plt.pause(0.01) # print('Check plot') # answer=yesno('y') print('\nAperture {}:'.format(i + 1)) wave = getmswave(mshead, i) print(wave[0], wave[-1]) wdelt = wave[1] - wave[0] mean = np.mean(multispec[0, i, :]) ymin, ymax = finalscaler(multispec[0, i, :]) # plt.clf() gs = gridspec.GridSpec(2, 1, height_ratios=[4, 1]) ax0 = plt.subplot(gs[0]) ax1 = plt.subplot(gs[1]) fig.subplots_adjust(hspace=0) ax0.plot(wave, multispec[1, i, :], drawstyle='steps-mid', color='r') ax0.plot(wave, multispec[0, i, :], drawstyle='steps-mid', color='k') # ax0.plot(multispec[0,i,:],multispec[2,i,:],drawstyle='steps-mid',color='r') # ax0.plot(multispec[0,i,:],multispec[1,i,:],drawstyle='steps-mid',color='k') plt.pause(0.01) ax0.set_ylim((ymin, ymax)) ax1.semilogy(wave,np.abs(multispec[1,i,:]-multispec[0,i,:])/mean, \ drawstyle='steps-mid',color='k') ax0.set_ylabel('Flux') ax1.set_ylabel('Log of fractional residuals') ax1.set_xlabel('Wavelength') plt.pause(0.01) print('\nPlotting optimal as black, normal as red\n') extract = inputter_single( 'Do you want to use the (n)ormal or the (o)ptimal extraction? ', 'no') if (extract == 'o'): object = multispec[0, i, :] extractcode = 'optimal' if (secondord): object2 = multispec2[0, i, :] else: object = multispec[1, i, :] extractcode = 'normal' if (secondord): object2 = multispec2[1, i, :] skyband = 2 if (num_bands == 2): skyband = 1 if (num_bands > 3): sigma = multispec[3, i, :] else: sigma = np.sqrt(multispec[skyband, i, :]) if (np.abs(np.mean(object)) < 1e-7): print('\nScaling data up by 10^15\n') object = object * 1.e15 sigma = sigma * 1.e15 if (secondord): if (num_bands > 3): sigma2 = multispec2[3, i, :] else: sigma2 = np.sqrt(multispec2[skyband, i, :]) if (np.abs(np.mean(object)) < 1e-7): object2 = object2 * 1.e15 sigma2 = sigma2 * 1.e15 nandslist = ['gemini-n', 'gemini-s', 'lco-imacs'] if (observat in nandslist): skyfile = inputfile.replace('tot', 'sky') skyfits = fits.open(skyfile) sky = skyfits[0].data[2, 0, :] else: sky = multispec[skyband, i, :] envelope_size = 25 mx, mn = envelope(sky, envelope_size) skycont = congrid(mn, (len(sky), ), minusone=True) test_sky = sky sky = sky - skycont if (np.abs(np.mean(sky)) < 1.e-7): sky = sky * 1.e15 print(len(mskywave), len(mskydata)) msky = scipyrebinsky(mskywave, mskydata, wave) xfactor = 10 maxlag = 200 if 'kast' in mshead.get('VERSION', ''): shift = xcor(msky[50:-50], sky[50:-50], xfactor, maxlag) else: shift = xcor(msky, sky, xfactor, maxlag) angshift = shift * wdelt print('wdeltf', wdelt) print('The x-cor shift in Angstroms is {}'.format(angshift)) wave = wave + angshift #check to make sure signs are right skyshiftdone = False npixsky2 = len(sky) // 2 msky_max = np.max(msky[npixsky2 - 1:]) sky_max = np.max(sky[npixsky2 - 1:]) scale = sky_max / msky_max plt.close() fig = plt.figure(figsize=[8, 5]) fig.subplots_adjust(hspace=0) while (not skyshiftdone): axarr = fig.subplots(2) waveplus = wave - angshift if not secondtime: axarr[0].plot(waveplus[0:npixsky2],scale*msky[0:npixsky2], \ drawstyle='steps-mid',color='k') axarr[0].plot(wave[0:npixsky2],sky[0:npixsky2], \ drawstyle='steps-mid',color='r') axarr[1].plot(waveplus[npixsky2-1:],scale*msky[npixsky2-1:], \ drawstyle='steps-mid',color='k') axarr[1].plot(wave[npixsky2-1:],sky[npixsky2-1:], \ drawstyle='steps-mid',color='r') plt.pause(0.01) print('\nBlack spectrum = master sky') print( 'Red spectrum = object sky shifted to match master sky' ) print('Is this ok?') answer = yesno('y') if (answer == 'n'): wave = wave - angshift angshift = inputter( 'Enter desired shift in Angstroms: ', 'float', False) wave = wave + angshift else: skyshiftdone = True else: wave = wave + angshift skyshiftdone = True plt.close() # B star removal bstarpass = bstarstar bobj, bsig, bangshift=telluric_remove(bstarwave,bstarpass, bstarairmass, wave, \ object, airmass, sigma, object, shift=bshift) # bobj, bsig, bangshift=telluric_remove(bstarwave,bstarpass, bstarairmass, wave, \ # test_sky, airmass, sigma, object) bshift = bangshift if (secondord): bobj2, bsig2, bangshift2 =telluric_remove(bstarwave2,bstarpass2, bstarairmass2, \ wave, object2, airmass, sigma2) print('\nRemoving redshift due to motion of Earth...') z = -1 * v / 2.99792458e5 wave = wave / (1 + z) # rebin fig = plt.figure() axarr = fig.subplots(1, 2) ymin, ymax = finalscaler(bobj[0:100]) axarr[0].plot(wave[0:100], bobj[0:100], drawstyle='steps-mid') axarr[0].set_xlabel('Wavelength') axarr[0].set_ylabel('Flux') #axarr[0].set_ylim((ymin,ymax)) if (secondtime): axarr[0].plot([wavesave0, wavesave0], [ymin, ymax], color='r') plt.pause(0.01) ymin, ymax = finalscaler(bobj[-100:]) axarr[1].plot(wave[-100:], bobj[-100:], drawstyle='steps-mid') axarr[1].set_xlabel('Wavelength') axarr[1].set_ylabel('Flux') try: axarr[1].set_ylim((ymin, ymax)) except ValueError: bobj_median = np.nanmedian(bobj) axarr[1].set_ylim((bobj_median / 10., bobj_median * 10.)) if (secondtime): axarr[1].plot([wavesaven, wavesaven], [ymin, ymax], color='r') newdelt = 0.0 plt.pause(0.01) print('\nCurrent A/pix is {}'.format(wave[1] - wave[0])) if (secondtime): print('\nPrevious resolution choice: {}'.format(deltsave)) else: deltsave = 0.0 newdelt = wave[1] - wave[0] # while (newdelt <= 0) or (newdelt > wave[-1]): # print('Rebin to how many Angstroms per pixel? ') # newdelt=inputter(' <CR> selects previous choice: ','float',True,deltsave) # if (newdelt <= 0) or (newdelt > wave[-1]): # print('Need positive resoution and smaller than the') # print('entire spectrum. Try again') print('\nCurrent range: {} {}'.format(wave[0], wave[-1])) if (secondtime): print('\nPrevious selection was {} {} (marked in red on plot)'. format(wavesave0, wavesaven)) print('\n<CR> selects previous choice\n') else: wavesave0 = 0.0 wavesaven = 0.0 print('Enter the new wavelength range desired: ') waveb, waver = waveparse(wave, wavesave0, wavesaven) newbin = (waver - waveb) / newdelt + 1.0 #should stay the same now # frac,whole=np.modf(newbin) # if (frac > 0.000001): # testwave=newdelt*whole+waveb # print('Closest match is: {} to {}'.format(waveb,testwave)) # print('Would you like this wavelength range?') # answer=yesno('y') # if (answer == 'y'): # waver=testwave wave_locs = np.where((wave > waveb) & (wave < waver)) # deltsave=newdelt wavesave0 = waveb wavesaven = waver waverange = str(waveb) + ' ' + str(waver) secondtime = True # nwave=np.arange(0,whole)*newdelt + waveb # vartmp=bsig*bsig # olddeltvec=wave-np.roll(wave,1) # olddelt=np.mean(olddeltvec) # nwave = wave # finalobj = bobj # finalvar = bsig**2. # finalsig = bsig #NOT TESTED!!! nwave = wave[wave_locs] print(nwave[0], nwave[-1]) finalobj = bobj[wave_locs] finalvar = bsig[wave_locs]**2. finalsig = bsig[wave_locs] # finalobj=womashrebin(wave,bobj,nwave) # finalvar=womashrebin(wave,vartmp,nwave) # finalsig=np.sqrt(finalvar)*np.sqrt(olddelt/newdelt) #Matt's interpolation algorithm. womashrebin is an unreadable monstrosity. # interp_data = interpo_flux_conserving(wave, bobj, 1./vartmp, waveb, waver, dw=newdelt, testing=False) # interp_wave = np.arange(math.ceil(wave[0])+1., math.floor(wave[-1])-1., dtype=float, step=newdelt) # spectres_data = spectres(interp_wave, wave, bobj, spec_errs=bsig) # trim_range = (interp_data[0] > waveb) & (interp_data[0] < waver) # nwave = interp_data[0][trim_range] # finalobj = interp_data[1][trim_range] # finalvar = 1./interp_data[2][trim_range] # finalsig = np.sqrt(finalvar) suffixes = {} suffixes['ap' + str(i + 1)] = '' if os.path.isfile('../HOST_AP_DATA.txt'): with open('../HOST_AP_DATA.txt') as host_ap_data: h_lines = host_ap_data.readlines() for l in h_lines: suffixes[l.split()[0]] = '_' + l.split()[1] #gonna ignore the second order stuff for now if (secondord): vartmp2 = bsig2 * bsig2 finalobj2 = womashrebin(wave, bobj2, nwave) finalvar2 = womashrebin(wave, vartmp2, nwave) finalsig2 = np.sqrt(finalvar2) * np.sqrt(olddelt / newdelt) if (secondord and not seconddone): finalobj, finalsig, wavebeg, waveend, brscale = secondcat( nwave, finalobj, finalobj2, finalsig, finalsig2, secondtime, wavebeg, waveend, brscale) seconddone = True ymin, ymax = finalscaler(finalobj) plt.close() fig = plt.figure() plt.plot(nwave, finalobj, drawstyle='steps-mid') # plt.plot(spectres_data[0],spectres_data[1],drawstyle='steps-mid', color='green') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(objectname) plt.savefig(objectname + '-' + gratcode + '_ap' + str(i + 1) + suffixes['ap' + str(i + 1)] + '.png') plt.show() outputdone = False while (not outputdone): print('\nThe file is: {}'.format(inputfile)) print('The object is: {}'.format(objectname)) print('The DATE-OBS is: {}'.format(date)) print('The aperture is: {}'.format(i + 1)) print('The previous name was: {}'.format(objname)) print('\nEnter the object name for the final fits file: ') # objname=inputter('(UT date and .fits will be added): ','string',False) objname = objectname + '-' + gratcode fname = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '.fits' sname = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '-sigma.fits' outputdone = True if (os.path.isfile(fname)): print('{} already exists!!!!'.format(fname)) print('Do you wish to overwrite it? ') answer = yesno('y') if (answer == 'y'): outputdone = True else: outputdone = True # add to header new_mshead = mshead.copy() new_mshead.set('CRPIX1', 1) new_mshead.set('CRVAL1', nwave[0]) new_mshead.set('CDELT1', nwave[1] - nwave[0]) new_mshead.set('CTYPE1', 'LINEAR') new_mshead.set('W_RANGE', waverange) new_mshead.set('BSTAR_Z', bstarairmass) new_mshead.set('BSTARNUM', bstarnum) new_mshead.set('BSTAROBJ', bstarname) new_mshead.set('BARYVEL', v) new_mshead.set('SKYSHIFT', angshift) new_mshead.set('ATMSHIFT', bangshift) new_mshead.set('EXTRACT', extractcode) new_mshead.set('REDUCER', user) new_mshead.set('RED_DATE', str(datetime.now()).split()[0], 'EPOCH OF REDUCTION') new_mshead.set('OBJECT', objectname) # if (secondord): # new_mshead.set('SECOND', 'yes', 'Second order correction attempted') # new_mshead.set('COMBRANGE',combrange) # new_mshead.set('BSTAR_Z2',bstarairmass2) # new_mshead.set('BSTARNU2', bstarnum2) # new_mshead.set('BSTAROB2', bstarname2) # fluxairmass2=mshead2['FLX2_Z'] # fluxnum2=mshead2['FLX2_NUM'] # fluxname2=mshead2['FLX2_OBJ'] # new_mshead.set('FLX2_Z',fluxairmass2) # new_mshead.set('FLX2_NUM', fluxnum2) # new_mshead.set('FLX2_OBJ', fluxname2) outdata = np.zeros((len(finalobj), 2)) outdata[:, 0] = finalobj.copy() outdata[:, 1] = finalsig.copy() outhdu = fits.PrimaryHDU(outdata) hdul = fits.HDUList([outhdu]) mshead.set('NAXIS2', 2) hdul[0].header = new_mshead.copy() hdul.writeto(fname, overwrite=True) spectxt = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '.flm' spectxt = spectxt.strip() np.savetxt(spectxt, np.transpose([nwave, finalobj.copy(), finalsig.copy()])) hdul.close() print('Do you wish to combine with another spectrum? ') answer = yesno('y') fname_comb = None if (answer == 'y'): plt.close() done = False while (not done): files = glob.glob(objname.split('-')[0] + '*.fits') print(files) for f in files: if objname not in f and ('red' in f or 'blue' in f ) and '_ap' + str(i + 1) in f: inputfile = f inputfile = input( 'Name of fits file to be combined? [{}]: '.format( inputfile)) or inputfile print(inputfile) inputfile = inputfile.strip() if (inputfile == ''): return hop if ('.fits' not in inputfile): inputfile = inputfile + '.fits' try: fitsdata = fits.open(inputfile) except OSError: print('File {} cannot be opened.'.format(inputfile)) else: done = True crval1 = fitsdata[0].header['CRVAL1'] try: wdelt = fitsdata[0].header['CDELT1'] except KeyError: wdelt = 0.0000001 if (wdelt < 0.000001): wdelt = fitsdata[0].header['CD1_1'] try: objectname = fitsdata[0].header['OBJECT'] if (not isinstance(objectname, str)): objectname = inputfile except KeyError: objectname = inputfile data_new = fitsdata[0].data wave_new = np.arange(1, len(data_new) + 1) * wdelt + crval1 if (len(data_new.shape) == 2): var_new = data_new[:, 1] var_new = var_new.astype(float) var_new = var_new * var_new flux_new = data_new[:, 0] flux_new = flux_new.astype(float) else: flux_new = data_new.astype(float) var_new = np.ones(data_new.shape) if 'red' in inputfile: wavecomb, fluxcomb, varcomb = womcatfinal( [nwave, finalobj, finalvar], [wave_new, flux_new, var_new]) nwave = wavecomb finalobj = fluxcomb finalsig = np.sqrt(varcomb) elif 'blue' in inputfile: wavecomb, fluxcomb, varcomb = womcatfinal( [wave_new, flux_new, var_new], [nwave, finalobj, finalvar]) nwave = wavecomb finalobj = fluxcomb finalsig = np.sqrt(varcomb) else: print( "Please include 'blue' or 'red' in filename of spectrum to combine" ) plt.clf() plt.plot(nwave, finalobj, drawstyle='steps-mid') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(objectname) plt.savefig(objectname + '_combined_ap' + str(i + 1) + suffixes['ap' + str(i + 1)] + '.png') outputdone = False while (not outputdone): print('\nThe file is: {}'.format(inputfile)) print('The object is: {}'.format(objectname)) print('The DATE-OBS is: {}'.format(date)) print('The aperture is: {}'.format(i + 1)) print('The previous name was: {}'.format(objname)) print('\nEnter the object name for the final fits file: ') # objname=inputter('(UT date and .fits will be added): ','string',False) objname = objectname + '-combined' fname_comb = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '.fits' sname_comb = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '-sigma.fits' outputdone = True if (os.path.isfile(fname)): print('{} already exists!!!!'.format(fname)) print('Do you wish to overwrite it? ') answer = yesno('y') if (answer == 'y'): outputdone = True else: outputdone = True # add to header mshead_combined = new_mshead.copy() mshead_combined.set('CRPIX1', 1) mshead_combined.set('CRVAL1', nwave[0]) mshead_combined.set('CDELT1', nwave[1] - nwave[0]) mshead_combined.set('CTYPE1', 'LINEAR') mshead_combined.set('W_RANGE', waverange) mshead_combined.set('BSTAR_Z', bstarairmass) mshead_combined.set('BSTARNUM', bstarnum) mshead_combined.set('BSTAROBJ', bstarname) mshead_combined.set('BARYVEL', v) mshead_combined.set('SKYSHIFT', angshift) mshead_combined.set('ATMSHIFT', bangshift) mshead_combined.set('EXTRACT', extractcode) mshead_combined.set('REDUCER', user) mshead_combined.set( 'RED_DATE', datetime.now().strftime("%Y-%M-%d %I:%M%p"), 'EPOCH OF REDUCTION') mshead_combined.set('OBJECT', objectname) if (secondord): #not implemented mshead_combined.set('SECOND', 'yes', 'Second order correction attempted') mshead_combined.set('COMBRANGE', combrange) mshead_combined.set('BSTAR_Z2', bstarairmass2) mshead_combined.set('BSTARNU2', bstarnum2) mshead_combined.set('BSTAROB2', bstarname2) fluxairmass2 = mshead2['FLX2_Z'] fluxnum2 = mshead2['FLX2_NUM'] fluxname2 = mshead2['FLX2_OBJ'] mshead_combined.set('FLX2_Z', fluxairmass2) mshead_combined.set('FLX2_NUM', fluxnum2) mshead_combined.set('FLX2_OBJ', fluxname2) outdata = np.zeros((len(finalobj), 2)) outdata[:, 0] = finalobj.copy() outdata[:, 1] = finalsig.copy() outhdu = fits.PrimaryHDU(outdata) hdul = fits.HDUList([outhdu]) mshead_combined.set('NAXIS2', 2) hdul[0].header = mshead_combined.copy() hdul.writeto(fname_comb, overwrite=True) hdul.close() spectxt = objname + '-' + printdate + '_ap' + str( i + 1) + suffixes['ap' + str(i + 1)] + '.flm' spectxt = spectxt.strip() np.savetxt( spectxt, np.transpose([nwave, finalobj.copy(), finalsig.copy()])) is_final = input('Is this a final reduction? [y]/n: ') or 'y' if is_final: if not os.path.isdir('../../final_reductions/'): os.mkdir('../../final_reductions/') os.system('cp ' + fname + ' ' + '../../final_reductions/' + fname) if fname_comb: os.system('cp ' + fname_comb + ' ' + '../../final_reductions/' + fname_comb) print('final') print(objectlist, gratcode, secondord, gratcode2) plt.close() return
def womblo(hop, fig): """blotch out bad data""" import logging import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import splrep, splev from tmath.wombat.inputter_single import inputter_single from tmath.wombat.waveparse import waveparse from tmath.wombat.womwaverange import womwaverange from tmath.wombat.womget_element import womget_element from tmath.wombat.yesno import yesno global nsplinepoints, tmpsplptsx, tmpsplptsy, pflag print('Select regions to blotch') wave = hop[0].wave.copy() flux = hop[0].flux.copy() done = False while (not done): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) wavesub, fluxsub, mode = womwaverange(wave, flux, 'none') wavebind = womget_element(wave, wavesub[0]) waverind = womget_element(wave, wavesub[-1]) plt.cla() plt.plot(wave[wavebind:waverind+1],flux[wavebind:waverind+1], \ drawstyle='steps-mid') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) plt.pause(0.01) print('Do you want to enter blotch wavelengths by hand (w),') print('mark points (m), fit a spline (s), or quit (q)?') choice = inputter_single('(w/m/s/q): ', 'wmsq') if (choice == 'w') or (choice == 'm'): blotchgood = False while (not blotchgood): wavechoicedone = False while (not wavechoicedone): if (choice == 'w'): waveselb, waveselr = waveparse() else: print('Mark the two endpoints of the blotch region') endpoints = plt.ginput(2, timeout=-1) waveselb = endpoints[0][0] waveselr = endpoints[1][0] if (waveselb > waveselr): waveselb, waveselr = waveselr, waveselb waveselbind = womget_element(wave, waveselb) waveselrind = womget_element(wave, waveselr) print(waveselb, waveselr, waveselbind, waveselrind) if (waveselbind == 0) or (waveselrind == (len(wave) - 1)): print('Wavelengths incorrect--too close to endpoints') else: wavechoicedone = True contblue = flux[waveselbind - 1] contred = flux[waveselrind + 1] delta = (contred - contblue) / (waveselrind - waveselbind + 1) fluxcor = flux.copy() for i in range(waveselbind, waveselrind + 1): fluxcor[i] = contblue + (i - waveselbind + 1) * delta plt.plot(wave[wavebind:waverind+1],fluxcor[wavebind:waverind+1], \ drawstyle='steps-mid') plt.pause(0.01) print('Is this acceptable') answer = yesno('y') if (answer == 'y'): flux = fluxcor.copy() blotchgood = True logging.info('File {} blotched from {} to {}'.format( hop[0].obname, wave[waveselbind], wave[waveselrind])) elif (choice == 's'): xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) nsplinepoints = 0 tmpsplptsx = [] tmpsplptsy = [] spldone = False while (not spldone): plt.cla() plt.plot(wave[wavebind:waverind+1],flux[wavebind:waverind+1], \ drawstyle='steps-mid') if (len(tmpsplptsx) > 0): plt.plot(tmpsplptsx, tmpsplptsy, 'ro') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) cid = fig.canvas.mpl_connect('button_press_event', onclick) print('\nClick on continuum points for spline fit.') print( 'Spline will replace values between first and last point') print('Left button = add point') print('Middle button = delete point') print('Right button = done\n') pflag = '' while (pflag != 'done'): plt.pause(0.01) fig.canvas.mpl_disconnect(cid) splptsy = [z for _, z in sorted(zip(tmpsplptsx, tmpsplptsy))] splptsx = sorted(tmpsplptsx) spline = splrep(splptsx, splptsy, k=3) splblueindex = womget_element(wave, splptsx[0]) splredindex = womget_element(wave, splptsx[-1]) splwave = wave[splblueindex:splredindex + 1].copy() splineresult = splev(splwave, spline) fluxcor = flux.copy() fluxcor[splblueindex:splredindex + 1] = splineresult.copy() plt.plot(splwave, splineresult, drawstyle='steps-mid') print('Is this acceptable') answer = yesno('y') if (answer == 'y'): flux = fluxcor.copy() spldone = True logging.info( 'File {} blotched with spline from {} to {}'.format( hop[0].obname, wave[splblueindex], wave[splredindex])) else: done = True print('Do another region?') another = yesno('n') if (another == 'n'): done = True hop[0].flux = flux.copy() return hop
def mkbstar(bfile, gratcode): import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Cursor from astropy.io import fits from tmath.wombat.get_screen_size import get_screen_size from tmath.wombat.getmswave import getmswave from tmath.wombat.inputter_single import inputter_single from tmath.wombat.inputter import inputter from tmath.wombat.yesno import yesno from tmath.pydux.obs_extinction import obs_extinction from tmath.pydux.wave_telluric import wave_telluric from tmath.pydux.fitspl import fitspl from tmath.pydux.bblo import bblo from tmath.pydux.finalscaler import finalscaler from tmath.pydux.pacheck import pacheck screen_width, screen_height = get_screen_size() plt.ion() screenpos = '+{}+{}'.format(int(screen_width * 0.2), int(screen_height * 0.05)) fig = plt.figure() fig.canvas.manager.window.wm_geometry(screenpos) fig.canvas.set_window_title('B Star') fig.set_size_inches(18, 12) # turns off key stroke interaction fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id) # this should bring the window to the top, but it doesn't wm = plt.get_current_fig_manager() #fig.canvas.manager.window.attributes('-topmost', 1) blah = wm.window.attributes('-topmost', 1) #plt.pause(0.2) #fig.canvas.manager.window.attributes('-topmost', 0) blah = wm.window.attributes('-topmost', 0) fitsfile = fits.open(bfile) rawdata = fitsfile[0].data head = fitsfile[0].header num_apertures = rawdata.shape[1] wavearr = np.zeros((rawdata.shape[2], rawdata.shape[1])) objectname = head['OBJECT'] airmass = float(head['AIRMASS']) exptime = float(head['EXPTIME']) if (exptime < 1): exptime = 1. head = pacheck(head) observat = head['OBSERVAT'].strip().lower() sitefactor = obs_extinction(observat) for i in range(0, num_apertures): wavearr[:, i] = getmswave(head, i) if (wavearr[-1, 0] < 3000): print('************************************************') print('Spectrum not wavelength calibrated---bailing out') print('************************************************') sys.exit(1) ap_choice = -1 if (np.mean(rawdata[0, 0, :]) < 1e-7): rawdata = rawdata * 1e15 # scale to rational numbers for fit (rational as in sane, # not opposed to irrational) if (num_apertures != 1): axarr = fig.subplots(num_apertures, sharex=True) fig.subplots_adjust(hspace=0) for i in range(0, num_apertures): x = wavearr[:, i] y = rawdata[0, i, :] axarr[i].clear() plt.pause(0.01) axarr[i].plot(x, y, drawstyle='steps-mid') axarr[i].set_ylabel('Aperture {}'.format(i)) plt.pause(0.01) while (ap_choice < 0) or (ap_choice > num_apertures - 1): ap_choice = inputter( 'Which aperture do you want to use for the B star? ', 'int', False) fig.clf() else: ap_choice = 0 ymin, ymax = finalscaler(rawdata[0, ap_choice, :]) fig.clf() x1 = wavearr[:, ap_choice] y1 = rawdata[1, ap_choice, :] y0 = rawdata[0, ap_choice, :] plt.plot(x1, y1, drawstyle='steps-mid', color='r') plt.plot(x1, y0, drawstyle='steps-mid', color='k') plt.pause(0.01) plt.ylim([ymin, ymax]) plt.pause(0.01) print('\nPlotting optimal as black, normal as red') extract = inputter_single( 'Do you want to use (n)ormal or (o)ptimal extraction? ', 'no') if (extract == 'o'): bstar = rawdata[0, ap_choice, :] else: bstar = rawdata[1, ap_choice, :] # fix IRAF weirdness where data can go negative in dispcor interpolation bstar[np.where(bstar < 0)] = 0.01 wave = wavearr[:, ap_choice] print('\nAirmass: {}\n'.format(airmass)) airlimit = 0.5 while (airlimit < 1.0) or (airlimit > 10.): airlimit = inputter('Above what airmass is considered high? ', 'float', False) print('\nNow fit the continuum manually\n') plt.clf() ax = fig.add_subplot(111) cursor = Cursor(ax, useblit=True, color='k', linewidth=1) airlimit = 1.5 splineresult = fitspl(wave, np.log10(bstar), (airmass > airlimit), fig) splineresult = 10**(splineresult) plt.cla() plt.plot(wave, splineresult, drawstyle='steps-mid') plt.pause(0.01) bstar = bstar / splineresult if (airmass > airlimit): loc = wave_telluric(wave, 'high') else: loc = wave_telluric(wave, 'low') #invert loc and convert all good sections to np.nan so they won't plot loc = np.invert(loc) bstar[loc] = 1.0 bstar[np.where(bstar > 1.)] = 1.0 bstar[np.where(bstar <= 0.)] = 0.01 plt.cla() plt.plot(wave, bstar, drawstyle='steps-mid') plt.pause(0.01) print('\nDo you want to blotch the B-star?') blotch = yesno('n') if (blotch == 'y'): bstar = bblo(wave, bstar, (airmass > airlimit), fig) delkeylist=['WAT0_001', 'WAT1_001', 'WAT2_001', 'WAT0_002', \ 'WAT1_002', 'WAT2_002', 'WAT3_001', 'WAT2_003', \ 'CTYPE1', 'CTYPE2', 'CTYPE3', 'CD1_1', 'CD2_2', \ 'CD3_3', 'LTM1_1', 'LTM2_2', 'LTM3_3', 'WCSDIM'] for k in delkeylist: try: head.remove(k) except KeyError: pass plt.cla() plt.plot(wave, bstar, drawstyle='steps-mid') plt.pause(0.01) head.set('CRPIX1', 1) head.set('CRVAL1', wave[0]) head.set('CDELT1', wave[1] - wave[0]) head.set('CTYPE1', 'LINEAR') outfile = 'bstar' + gratcode + '.fits' print('Writing data to {}'.format(outfile)) outhdu = fits.PrimaryHDU(bstar) hdul = fits.HDUList([outhdu]) hdul[0].header = head.copy() hdul.writeto(outfile, overwrite=True) print('mkbstar') print(bfile, gratcode) return
def fitspl(wave, flux, airlimit, fig, cal=None): """fit spline to spectrum""" import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import splrep, splev import tmath.wombat.womconfig as womconfig from tmath.wombat.womget_element import womget_element from tmath.pydux.wave_telluric import wave_telluric from tmath.wombat.yesno import yesno from tmath.wombat.onclick import onclick from tmath.wombat.onkeypress import onkeypress import glob # global nsplinepoints, tmpsplptsx, tmpsplptsy, pflag # starting points for spline bandpts = np.array([3000, 3050, 3090, 3200, 3430, 3450, 3500, 3550, 3600, \ 3650, 3700, 3767, 3863, 3945, 4025, 4144, 4200, 4250, \ 4280, 4390, 4450, 4500, 4600, 4655, 4717, 4750, 4908, \ 4950, 5000, 5050, 5100, 5150, 5200, 5250, 5280, 5350, \ 5387, 5439, 5500, 5550, 6100, 6150, 6400, 6430, 6650, \ 6700, 6750, 6800, 7450, 7500, 7550, 8420, 8460, 8520, \ 8570, 8600, 8725, 8770, 9910, 10000, 10200, 10300, \ 10400, 10500, 10600, 10700]) locsinrange = np.logical_and((bandpts > wave[10]), (bandpts < wave[-10])) useband = bandpts[locsinrange] for i, _ in enumerate(useband): index = womget_element(wave, useband[i]) useband[i] = index # useband now has indices of wavelength positions if (min(flux) < 0): flux[np.where(flux < 0)] = 0.0 plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) if (airlimit): loc = wave_telluric(wave, 'high') else: loc = wave_telluric(wave, 'low') #invert loc and convert all good sections to np.nan so they won't plot loc = np.invert(loc) wavetell = wave.copy() fluxtell = flux.copy() wavetell[loc] = np.nan fluxtell[loc] = np.nan plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if '../../master_files/' + cal + '_splpts_master.txt' not in glob.glob( '../../master_files/*'): womconfig.nsplinepoints = len(useband) womconfig.tmpsplptsx = wave[useband].copy().tolist() womconfig.tmpsplptsy = [] for i, _ in enumerate(useband): womconfig.tmpsplptsy.append( np.median(flux[useband[i] - 2:useband[i] + 3])) spline = splrep(womconfig.tmpsplptsx, womconfig.tmpsplptsy, k=3) else: masterx, mastery = np.genfromtxt('../../master_files/' + cal + '_splpts_master.txt') womconfig.nsplinepoints = len(masterx) womconfig.tmpsplptsx = masterx womconfig.tmpsplptsy = mastery spline = splrep(womconfig.tmpsplptsx, womconfig.tmpsplptsy, k=3) splineresult = splev(wave, spline) plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plt.pause(0.01) done = False print('Is this OK? ') answer = yesno('n') if (answer == 'y'): done = True splptsy = [ z for _, z in sorted(zip(womconfig.tmpsplptsx, womconfig.tmpsplptsy)) ] splptsx = sorted(womconfig.tmpsplptsx) while (not done): plotdone = False while (not plotdone): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plt.pause(0.01) print('Change scale? ') answer = yesno('n') if (answer == 'y'): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') print('Click corners of box to change plot scale') newlims = plt.ginput(2, timeout=-1) xmin = newlims[0][0] ymin = newlims[0][1] xmax = newlims[1][0] ymax = newlims[1][1] plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plotdone = True else: plotdone = True cid = fig.canvas.mpl_connect('button_press_event', onclick) cid2 = fig.canvas.mpl_connect('key_press_event', onkeypress) print('\nClick on continuum points for spline fit.') print('Left button or (a) = add point') print('Middle button or (s) = delete point') print('Right button or (d) = done\n') womconfig.pflag = '' while (womconfig.pflag != 'done'): plt.pause(0.01) fig.canvas.mpl_disconnect(cid) fig.canvas.mpl_disconnect(cid2) splptsy = [ z for _, z in sorted(zip(womconfig.tmpsplptsx, womconfig.tmpsplptsy)) ] splptsx = sorted(womconfig.tmpsplptsx) spline = splrep(splptsx, splptsy, k=3) splineresult = splev(wave, spline) plt.plot(wave, splineresult, drawstyle='steps-mid', color='g') plt.pause(0.01) print('Is this fit OK? ') answer = yesno('y') if (answer == 'y'): done = True if cal != None: np.savetxt('../../master_files/' + cal + '_splpts_master.txt', [splptsx, splptsy]) return splineresult
def secondcat(wave, obj1, obj2, sig1, sig2, secondtimeflag, wavebeg, waveend, brscale): import numpy as np import matplotlib.pyplot as plt from tmath.wombat.womget_element import womget_element from tmath.wombat.inputter_single import inputter_single from tmath.wombat.yesno import yesno print('\nCombining two calibrated spectra for second-order correction') waveblue = wave wavered = wave fluxblue = obj1 fluxred = obj2 fluxtemp = fluxred if (not secondtimeflag): print('Plotting blue side as blue, red side as red') indexblue = womget_element(waveblue, wavered[0]) indexred = womget_element(wavered, waveblue[-1]) meanblue = np.mean(fluxblue[indexblue:]) meanred = np.mean(fluxred[0:indexred]) if ((meanblue / meanred) > 1.2) or (meanblue / meanred < 0.8): print('Averages very different, scaling red to blue for plot') scale = meanblue / meanred print('Red multiplied by {}'.format(scale)) fluxtemp = fluxred * scale plt.clf() plt.plot(waveblue[indexblue:], fluxblue[indexblue:], drawstyle='steps-mid', color='b') plt.plot(wavered[0:indexred], fluxred[:indexred], drawstyle='steps-mid', color='r') plt.xlabel('Wavelength') plt.ylabel('Flux') donescale = False while (not donescale): print('Change y-scale?') answer = yesno('n') if (answer == 'y'): ymin, ymax = scaleparse() plt.ylim([ymin, ymax]) plt.pause(0.01) print('Do again?') answer = yesno('n') if (answer == 'n'): donescale = True regiondone = False while (not regiondone): print( '\nOK, mark the two end points of the region to compute average' ) endpoints = plt.ginput(2, timeout=-1) element1 = endpoints[0][0] element2 = endpoints[1][0] plt.plot(endpoints, 'ro') if (element1 > element2): element1, element2 = element2, element1 binend = womget_element(waveblue, element2) binbeg = womget_element(waveblue, element1) if (binend > len(waveblue) - 1): binend = len(waveblue) - 1 if (binbeg < indexblue): binbeg = indexblue print('\nAre these points OK?') answer = yesno('y') if (answer == 'y'): regiondone = False else: plt.plot(endpoints, 'wo') wavebeg = waveblue[binbeg] waveend = waveblue[binend] binbegred = womget_element(wavered, wavebeg) binendred = womget_element(wavered, waveend) meanblue = np.mean(fluxblue[binbeg:binend + 1]) meanred = np.mean(fluxred[binbegred:binendred + 1]) print('Average for {}:{}'.format(wavebeg, waveend)) print('Blue side: {}'.format(meanblue)) print('Red side: {}'.format(meanred)) brscale = inputter_single('Scale to blue or red? (b/r) ', 'br') if (brscale == 'b'): print('Scaling to blue by {}'.format(meanblue / meanred)) fluxred = fluxred * meanblue / meanred else: print('Scaling to red by {}'.format(meanred / meanblue)) fluxblue = fluxblue * meanred / meanblue print('\nPlotting blue side as blue, red side as red') plt.clf() plt.plot(waveblue[binbeg:binend + 1], fluxblue[binbeg:binend + 1], drawstyle='steps-mid', color='b') plt.plot(wavered[binbegred:binendred + 1], fluxred[binbegred:binendred + 1], drawstyle='steps-mid', color='r') plt.xlabel('Wavelength') plt.ylabel('Flux') donescale = False while (not donescale): print('Change y-scale?') answer = yesno('n') if (answer == 'y'): ymin, ymax = scaleparse() plt.ylim([ymin, ymax]) plt.pause(0.01) print('Do again?') answer = yesno('n') if (answer == 'n'): donescale = True regiondone = False while (not regiondone): print('\nOK, mark the two end points of the region to combine') endpoints = plt.ginput(2, timeout=-1) element1 = endpoints[0][0] element2 = endpoints[1][0] plt.plot(endpoints, 'ro') if (element1 > element2): element1, element2 = element2, element1 binend = womget_element(waveblue, element2) binbeg = womget_element(waveblue, element1) if (binend > len(waveblue) - 1): binend = len(waveblue) - 1 if (binbeg < indexblue): binbeg = indexblue print('\nAre these points OK?') answer = yesno('y') if (answer == 'y'): regiondone = False else: plt.plot(endpoints, 'wo') wavebeg = waveblue[binbeg] waveend = waveblue[binend] binbegred = womget_element(wavered, wavebeg) binendred = womget_element(wavered, waveend) else: binbeg = womget_element(waveblue, wavebeg) binend = womget_element(waveblue, waveend) binbegred = womget_element(wavered, wavebeg) binendred = womget_element(wavered, waveend) meanblue = np.mean(fluxblue[binbeg:binend + 1]) meanred = np.mean(fluxred[binbegred:binendred + 1]) if (brscale == 'b'): scale = meanblue / meanred fluxred = fluxred * scale sig2 = sig2 * scale else: scale = meanred / meanblue fluxblue = fluxblue * scale sig1 = sig1 * scale overflux = (fluxblue[binbeg:binend + 1] + fluxred[binbegred:binendred + 1]) / 2.0 oversig = np.sqrt(sig1[binbeg:binend + 1]**2 + sig2[binbegred:binendred + 1]**2) newwave = waveblue.copy() newflux = fluxblue.copy() newsig = sig1.copy() newsig[binbeg:binend + 1] = oversig newsig[binend + 1:] = sig2[binendred + 1:] newflux[binbeg:binend + 1] = overflux newflux[binend + 1:] = fluxred[binendred + 1:] plt.clf() plt.pause(0.01) axarr = fig.subplots(2, sharex=True) fig.subplots_adjust(hspace=0) axarr[0].plot(waveblue[binbeg:binend + 1], fluxblue[binbeg:binend + 1], drawstyle='steps-mid', color='b') axarr[0].plot(wavered[binbegred:binendred + 1], fluxred[binbegred:binendred + 1], drawstyle='steps-mid', color='r') axarr[0].plot(waveblue[binbeg:binend + 1], overflux, drawstyle='steps-mid', color='k') axarr[0].set_title('Overlap region--with average') axarr[0].set_ylabel('Flux') plt.pause(0.01) axarr[1].plot(newwave, newflux, drawstyle='steps-mid', color='k') axarr[1].plot(newwave[binbeg:binend + 1], newflux[binbeg:binend + 1], drawstyle='steps-mid', color='r') axarr[1].set_xlabel('Wavelength') axarr[1].set_ylabel('Flux') plt.pause(0.01) return newflux, newsig, wavebeg, waveend, brscale
def womcat(hop): """concatenate data with overlapping wavelength regions""" import numpy as np import logging import matplotlib.pyplot as plt from tmath.wombat.inputter import inputter from tmath.wombat.inputter_single import inputter_single from tmath.wombat.womget_element import womget_element from tmath.wombat.yesno import yesno from tmath.wombat.get_screen_size import get_screen_size from tmath.wombat.womwaverange2 import womwaverange2 from tmath.wombat import HOPSIZE from matplotlib.widgets import Cursor plt.ion() screen_width, screen_height = get_screen_size() screenpos = '+{}+{}'.format(int(screen_width * 0.2), int(screen_height * 0.05)) fig = plt.figure() ax = fig.add_subplot(111) cursor = Cursor(ax, useblit=True, color='k', linewidth=1) fig.canvas.manager.window.wm_geometry(screenpos) fig.canvas.set_window_title('Cat') fig.set_size_inches(9, 6) # turns off key stroke interaction fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id) print("\nThis will combine blue and red pieces from two hoppers\n") hopnum1 = 0 hopnum2 = 0 while (hopnum1 < 1) or (hopnum1 > HOPSIZE): hopnum1 = inputter('Enter first hopper: ', 'int', False) while (hopnum2 < 1) or (hopnum2 > HOPSIZE): hopnum2 = inputter('Enter second hopper: ', 'int', False) if (hop[hopnum1].wave[0] > hop[hopnum2].wave[0]): hopnum1, hopnum2 = hopnum2, hopnum1 wdelt1 = hop[hopnum1].wave[1] - hop[hopnum1].wave[0] wdelt2 = hop[hopnum2].wave[1] - hop[hopnum2].wave[0] # check if wavelength dispersion same if (abs(wdelt1 - wdelt2) > 0.00001): print('Spectra do not have same Angstrom/pixel') print('Blue side: {}'.format(wdelt1)) print('Red side: {}'.format(wdelt2)) return hop if hop[hopnum1].wave[-1] < hop[hopnum2].wave[0]: print('Spectra do not overlap\n') return hop print("\nOverlap range is {} to {}".format(hop[hopnum2].wave[0], hop[hopnum1].wave[-1])) print("\nPlotting blue side as blue, red side as red\n") waveblue = hop[hopnum1].wave.copy() fluxblue = hop[hopnum1].flux.copy() varblue = hop[hopnum1].var.copy() wavered = hop[hopnum2].wave.copy() fluxred = hop[hopnum2].flux.copy() varred = hop[hopnum2].var.copy() indexblue = womget_element(waveblue, wavered[0]) indexred = womget_element(wavered, waveblue[-1]) fluxcor = 1.0 blue_mean = np.mean(fluxblue[indexblue:]) red_mean = np.mean(fluxred[0:indexred + 1]) if (blue_mean / red_mean < 0.8) or (blue_mean / red_mean > 1.2): fluxcor = blue_mean / red_mean print("Averages very different, scaling red to blue for plot") print("Red multiplied by {}".format(fluxcor)) plt.cla() plt.plot(waveblue[indexblue:], fluxblue[indexblue:], drawstyle='steps-mid', color='b') plt.plot(wavered[0:indexred], fluxred[0:indexred] * fluxcor, drawstyle='steps-mid', color='r') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.pause(0.01) print('Change scale?') answer = yesno('n') if (answer == 'y'): xmin_old, xmax_old = plt.xlim() ymin_old, ymax_old = plt.ylim() done = False while (not done): plt.xlim([xmin_old, xmax_old]) plt.ylim([ymin_old, ymax_old]) print('Click corners of box to change plot scale') newlims = plt.ginput(2, timeout=-1) xmin = newlims[0][0] ymin = newlims[0][1] xmax = newlims[1][0] ymax = newlims[1][1] plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) print('Is this OK?') loopanswer = yesno('y') if (loopanswer == 'y'): done = True print('\nEnter method to select wavelength ranges\n') mode = inputter_single( 'Enter (w)avelengths or mark with the (m)ouse? (w/m) ', 'wm') print('\nChoose end points of region to compute average\n') waveb, waver, mode = womwaverange2(waveblue[indexblue:], fluxblue[indexblue:], wavered[0:indexred], fluxred[0:indexred] * fluxcor, mode) indexblueb = womget_element(waveblue, waveb) indexbluer = womget_element(waveblue, waver) indexredb = womget_element(wavered, waveb) indexredr = womget_element(wavered, waver) mean_blue = np.mean(fluxblue[indexblueb:indexbluer + 1]) mean_red = np.mean(fluxred[indexredb:indexredr + 1]) print("\nAverage for {}:{}".format(waveb, waver)) print("Blue side: {}".format(mean_blue)) print("Red side: {}\n".format(mean_red)) brscale = inputter_single('Scale to blue or red (b/r)? ', 'br') if (brscale == 'b'): brscalefac = mean_blue / mean_red logging.info('Cat scaling to blue by {}'.format(brscalefac)) fluxred = fluxred * brscalefac varred = varred * brscalefac**2 else: brscalefac = mean_red / mean_blue logging.info('Cat scaling to red by {}'.format(brscalefac)) fluxblue = fluxblue * brscalefac varblue = varblue * brscalefac**2 # print("\nPlotting blue side as blue, red side as red\n") # plt.cla() # plt.plot(waveblue[indexblueb:indexbluer+1],fluxblue[indexblueb:indexbluer+1],drawstyle='steps-mid',color='b') # plt.plot(wavered[indexredb:indexredr+1],fluxred[indexredb:indexredr+1],drawstyle='steps-mid',color='r') # plt.xlabel('Wavelength') # plt.ylabel('Flux') # plt.pause(0.01) # print('Change scale?') # answer=yesno('n') # if (answer == 'y'): # xmin_old,xmax_old=plt.xlim() # ymin_old,ymax_old=plt.ylim() # done=False # while (not done): # plt.xlim([xmin_old,xmax_old]) # plt.ylim([ymin_old,ymax_old]) # print('Click corners of box to change plot scale') # newlims=plt.ginput(2,timeout=-1) # xmin=newlims[0][0] # ymin=newlims[0][1] # xmax=newlims[1][0] # ymax=newlims[1][1] # plt.xlim([xmin,xmax]) # plt.ylim([ymin,ymax]) # print('Is this OK?') # loopanswer=yesno('y') # if (loopanswer == 'y'): # done=True # print('\nChoose end points of region to compute average\n') # waveb,waver,mode=womwaverange2(waveblue[indexblueb:indexbluer+1], # fluxblue[indexblueb:indexbluer+1], # wavered[indexredb:indexredr+1], # fluxred[indexredb:indexredr+1],mode) # indexblueb=womget_element(waveblue,waveb) # indexbluer=womget_element(waveblue,waver) # indexredb=womget_element(wavered,waveb) # indexredr=womget_element(wavered,waver) # ewadd=inputter_single('Add overlap region (e)qually or with (w)eights (e/w)?','ew') # if (ewadd == 'e'): # overflux=(fluxblue[indexblueb:indexbluer+1]+fluxred[indexredb:indexredr+1])/2. # overvar=(varblue[indexblueb:indexbluer+1]+varred[indexredb:indexredr+1]) #replacing with inverse variance weighted average overflux = np.average([ fluxblue[indexblueb:indexbluer + 1], fluxred[indexredb:indexredr + 1] ], weights=[ 1. / varblue[indexblueb:indexbluer + 1], 1. / varred[indexredb:indexredr + 1] ], axis=0) overvar = np.sum( [varblue[indexblueb:indexbluer + 1], varred[indexredb:indexredr + 1]], axis=0) logging.info('Cat combined sides with inverse variance weighted average') # else: # wei_done = False # while (not wei_done): # weiblue=inputter('Enter fractional weight for blue side: ','float',False) # weired=inputter('Enter fractional weight for red side: ','float',False) # if (np.abs((weiblue+weired)-1.0) > 0.000001): # print('Weights do not add to 1.0') # else: # wei_done = True # overflux=(fluxblue[indexblueb:indexbluer+1]*weiblue+ # fluxred[indexredb:indexredr+1]*weired) # overvar=(varblue[indexblueb:indexbluer+1]*weiblue**2+ # varred[indexredb:indexredr+1]*weired**2) # logging.info('Cat adds blue side with weight {} and red side with weight {}'.format(weiblue, weired)) newbluewave = waveblue[:indexblueb] newblueflux = fluxblue[:indexblueb] newbluevar = varblue[:indexblueb] overwave = waveblue[indexblueb:indexbluer + 1] newredwave = wavered[indexredr + 1:] newredflux = fluxred[indexredr + 1:] newredvar = varred[indexredr + 1:] newwave = np.concatenate([newbluewave, overwave, newredwave]) newflux = np.concatenate([newblueflux, overflux, newredflux]) newvar = np.concatenate([newbluevar, overvar, newredvar]) logging.info('File {} and'.format(hop[hopnum1].obname)) logging.info('File {} concatenated'.format(hop[hopnum2].obname)) logging.info('over wavelength range {} to {}'.format( waveblue[indexblueb], waveblue[indexbluer])) plt.clf() axarr = fig.subplots(2) axarr[0].plot(overwave, overflux, drawstyle='steps-mid', color='k') axarr[0].plot(waveblue[indexblueb:indexbluer + 1], fluxblue[indexblueb:indexbluer + 1], drawstyle='steps-mid', color='b') axarr[0].plot(wavered[indexredb:indexredr + 1], fluxred[indexredb:indexredr + 1], drawstyle='steps-mid', color='r') axarr[0].set_title('Overlap region, with inputs and combination') axarr[1].set_ylabel('Flux') axarr[1].plot(newwave, newflux, drawstyle='steps-mid', color='k') axarr[1].plot(newwave[indexblueb:indexbluer + 1], newflux[indexblueb:indexbluer + 1], drawstyle='steps-mid', color='r') plt.pause(0.01) hopout = 0 while (hopout < 1) or (hopout > HOPSIZE): hopout = inputter('Enter hopper to store combined spectrum: ', 'int', False) hop[hopout].wave = newwave hop[hopout].flux = newflux hop[hopout].var = newvar hop[hopout].obname = hop[hopnum1].obname hop[hopout].header = hop[hopnum1].header plt.close() #fig.clf() #plt.cla() return hop
def main(): secondord = False gratcode2 = '' # logging straight from docs.python.org cookbook page # INFO level to screen and cal.log # DEBUG level only to cal.log logging.getLogger('matplotlib').setLevel(logging.WARNING) logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename='cal.log', filemode='a') # define a Handler which writes INFO messages or higher to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.INFO) # set a format which is simpler for console use formatter = logging.Formatter('%(message)s') # tell the handler to use this format console.setFormatter(formatter) # add the handler to the root logger logging.getLogger('').addHandler(console) user = getpass.getuser() print('Hello, {} \n'.format(user)) logging.debug('CAL starts') logging.debug('{} running things'.format(user)) print(' ') print('This program is a driver for the calibration routines.') print('It expects files that have been dispersion calibrated,') print('usually through IRAF (you know, with a -d- in front).') print('(In other words, include the d in your file names.)') print(' ') print('Do you want to use second-order correction?\n') answer = yesno('n') if (answer == 'y'): secondord = True #axarr=fig.subplots(2,sharex=True) #fig.subplots_adjust(hspace=0) print('\nWe now need a grating code, such as opt or ir2.') print('This will be used to keep track of the fluxstar and') print('bstar as in fluxstaropt.fits or bstarir2.fits\n') gratcode = inputter('Enter the grating code: ', 'string', False) print(' ') if (secondord): gratcode2 = inputter('Enter the second-order grating code: ', 'string', False) print(' ') print('Enter the file containing the list of objects') print('(should be dispersion-corrected)\n') done = False while (not done): # objectlist = inputter('Object list file: ', 'string', False) dfiles=glob.glob('d*.fits') for d in dfiles: if gratcode in d: listfile= open(d.split('_ex.fits')[0],"w+") listfile.write(d) listfile.close() objectlist = listfile.name if (os.path.isfile(objectlist)): done = True else: print('No such file') print('\nDo you want to fit a flux star?\n') answer = yesno('y') if (answer == 'y'): plt.close() fluxfile = getfitsfile('flux star', '.fits') pydux.mkfluxstar(fluxfile, gratcode) if (secondord): print(' ') fluxfile2 = getfitsfile('second flux star', '.fits') pydux.mkfluxstar(fluxfile2, gratcode2) else: try: fluxfits = fits.open('fluxstar'+gratcode+'.fits') fluxfile = fluxfits[0].header['FLUXFILE'] fluxfits.close() # except FileNotFoundError: except KeyError: fluxfile = 'Unknown' if (secondord): try: fluxfits2 = fits.open('fluxstar'+gratcode2+'.fits') fluxfile2 = fluxfits2[0].header['FLUXFILE'] fluxfits2.close() # except FileNotFoundError: except KeyError: fluxfile2 = 'Unknown' print('\nDo you want to apply the flux star(s) to the data?\n') answer = yesno('y') if (answer == 'y'): pydux.calibrate(objectlist, gratcode, secondord, gratcode2) print('\nDo you want to fit a b-star?\n') answer = yesno('y') if (answer == 'y'): plt.close() print('\nDo you want to use the flux star {}'.format(fluxfile)) print('as the b-star?\n') same = yesno('y') print(' ') if (same == 'n'): bfile = getfitsfile('b-star', '.fits') else: bfile = fluxfile bfile = 'c'+gratcode+bfile pydux.mkbstar(bfile, gratcode) if (secondord): print('\nDo you want to use the flux star {}'.format(fluxfile2)) print('as the b-star?\n') same = yesno('y') if (same == 'n'): bfile2 = getfitsfile('b-star', '.fits') else: bfile2 = fluxfile2 bfile2 = 'c'+gratcode+bfile2 pydux.mkbstar(bfile2, gratcode2) print('\nFinal calibration (atmos. removal, sky line wave. adjust, etc.)?') answer = yesno('y') if (answer == 'y'): plt.close() pydux.final(objectlist, gratcode, secondord, gratcode2, user) print('\nThere, was that so hard?')
def womirfilters(hop): """calculate photometric values from spectra""" import numpy as np import logging from tmath.wombat.filtermag import filtermag from tmath.wombat.yesno import yesno from tmath.wombat.inputter import inputter from tmath.wombat.inputter_single import inputter_single print('NOTE: The routine expects an f_lambda spectrum') print(' I will try to guess if the spectrum') print(' has been scaled by 1E15') print(' ') print(' Check this before believing fluxes') print(' ') print('NOTE Also: These are the 2MASS filter curves') print(' ') flux = hop[0].flux.copy() if (np.mean(flux) > 0.00001): flux = flux * 1.e-15 filtwave = np.zeros((109, 3)) filttran = np.zeros((109, 3)) filtwave[:,0]=[1.050, 1.051, 1.062, 1.066, 1.070, 1.075, 1.078, 1.082, \ 1.084, 1.087, 1.089, 1.093, 1.096, 1.102, 1.105, 1.107, 1.109, 1.112, \ 1.116, 1.117, 1.120, 1.123, 1.128, 1.129, 1.132, 1.134, 1.138, 1.140, \ 1.143, 1.147, 1.154, 1.159, 1.164, 1.167, 1.170, 1.173, 1.175, 1.179, \ 1.182, 1.186, 1.188, 1.192, 1.195, 1.199, 1.202, 1.209, 1.216, 1.221, \ 1.227, 1.231, 1.236, 1.240, 1.244, 1.247, 1.253, 1.255, 1.258, 1.260, \ 1.265, 1.270, 1.275, 1.279, 1.286, 1.292, 1.297, 1.302, 1.305, 1.307, \ 1.310, 1.313, 1.316, 1.319, 1.323, 1.326, 1.330, 1.333, 1.334, 1.336, \ 1.339, 1.343, 1.346, 1.349, 1.353, 1.355, 1.360, 1.363, 1.370, 1.373, \ 1.377, 1.383, 1.388, 1.392, 1.395, 1.396, 1.397, 1.398, 1.400, 1.401, \ 1.402, 1.404, 1.406, 1.407, 1.410, 1.412, 1.416, 1.421, 1.426, 1.442, \ 1.450] filttran[:,0]=[0.0000, 0.0000, 0.0000, 0.0023, 0.0087, 0.0150, 0.0309, 0.0690, \ 0.1136, 0.1709, 0.2282, 0.2886, 0.3491, 0.4255, 0.4668, 0.5209, \ 0.5687, 0.6228, 0.6546, 0.6864, 0.7150, 0.7437, 0.7595, 0.7595, \ 0.7435, 0.7276, 0.6861, 0.6575, 0.6224, 0.5873, 0.5649, 0.5840, \ 0.6157, 0.6571, 0.6857, 0.7271, 0.7685, 0.8162, 0.8416, 0.8511, \ 0.8447, 0.8256, 0.7937, 0.7554, 0.7172, 0.6757, 0.6629, 0.6883, \ 0.7391, 0.7869, 0.8505, 0.8823, 0.8950, 0.8854, 0.8471, 0.8184, \ 0.7802, 0.7324, 0.6845, 0.6239, 0.5889, 0.5729, 0.5728, 0.5918, \ 0.6172, 0.6681, 0.6968, 0.7286, 0.7667, 0.7954, 0.8431, 0.8813, \ 0.9194, 0.9353, 0.9257, 0.9225, 0.9129, 0.8906, 0.8524, 0.8141, \ 0.7854, 0.7599, 0.7439, 0.7375, 0.7247, 0.7183, 0.7087, 0.7023, \ 0.7022, 0.7181, 0.7339, 0.7147, 0.6829, 0.6446, 0.6160, 0.5873, \ 0.5172, 0.4662, 0.3770, 0.2305, 0.1350, 0.1126, 0.0712, 0.0362, \ 0.0170, 0.0042, 0.0009, 0.0007, 0.0000] filtwave[0:57,1]=[1.315, 1.341, 1.368, 1.397, 1.418, 1.440, 1.462, 1.478, \ 1.486, 1.493, 1.504, 1.515, 1.528, 1.539, 1.546, 1.551, 1.556, 1.565, \ 1.572, 1.577, 1.583, 1.592, 1.597, 1.602, 1.613, 1.619, 1.628, 1.633, \ 1.642, 1.648, 1.657, 1.659, 1.671, 1.684, 1.701, 1.715, 1.727, 1.739, \ 1.746, 1.751, 1.753, 1.756, 1.764, 1.775, 1.785, 1.790, 1.796, 1.803, \ 1.810, 1.813, 1.818, 1.828, 1.835, 1.850, 1.871, 1.893, 1.914] filttran[0:57,1]=[0.0014, 0.0014, 0.0000, 0.0000, 0.0014, 0.0028, 0.0070, \ 0.0252, 0.0700, 0.1807, 0.3529, 0.4972, 0.6527, 0.7591, 0.8109, \ 0.8319, 0.8403, 0.8389, 0.8305, 0.8235, 0.8193, 0.8277, 0.8347, \ 0.8375, 0.8319, 0.8193, 0.8081, 0.8053, 0.8095, 0.8165, 0.8263, \ 0.8305, 0.8375, 0.8431, 0.8501, 0.8529, 0.8543, 0.8529, 0.8445, \ 0.8305, 0.8151, 0.7927, 0.7255, 0.6275, 0.5084, 0.4258, 0.3291, \ 0.2101, 0.1275, 0.0882, 0.0560, 0.0294, 0.0154, 0.0070, 0.0028, \ 0.0014, 0.0000] filtwave[0:76,2]=[1.900, 1.915, 1.927, 1.934, 1.939, 1.948, 1.957, 1.962, \ 1.969, 1.976, 1.981, 1.989, 1.990, 1.998, 2.008, 2.014, 2.019, 2.028, \ 2.037, 2.045, 2.061, 2.072, 2.075, 2.082, 2.089, 2.099, 2.106, 2.113, \ 2.120, 2.124, 2.138, 2.145, 2.155, 2.169, 2.176, 2.185, 2.197, 2.208, \ 2.213, 2.218, 2.232, 2.237, 2.248, 2.256, 2.260, 2.263, 2.265, 2.270, \ 2.272, 2.276, 2.277, 2.281, 2.284, 2.286, 2.291, 2.293, 2.295, 2.297, \ 2.299, 2.306, 2.311, 2.316, 2.320, 2.325, 2.328, 2.335, 2.339, 2.344, \ 2.346, 2.352, 2.361, 2.363, 2.370, 2.375, 2.384, 2.399] filttran[0:76,2]=[0.0000, 0.0013, 0.0027, 0.0040, 0.0082, 0.0153, 0.0293, \ 0.0462, 0.0743, 0.1222, 0.1714, 0.2672, 0.3517, 0.4263, 0.6262, \ 0.6797, 0.7487, 0.7853, 0.8120, 0.8303, 0.8485, 0.8513, 0.8583, \ 0.8597, 0.8667, 0.8751, 0.8765, 0.8835, 0.8891, 0.8863, 0.8848, \ 0.8819, 0.8805, 0.8748, 0.8804, 0.8818, 0.8902, 0.8986, 0.9014, \ 0.8999, 0.8999, 0.8956, 0.8913, 0.8969, 0.8997, 0.8997, 0.9053, \ 0.9109, 0.9166, 0.9109, 0.9025, 0.8870, 0.8686, 0.8433, 0.7714, \ 0.7292, 0.6650, 0.5950, 0.5333, 0.4094, 0.3108, 0.2234, 0.1544, \ 0.1234, 0.0896, 0.0599, 0.0416, 0.0320, 0.0300, 0.0162, 0.0063, \ 0.0007, 0.0034, 0.0020, 0.0006, 0.0000] filtwave = filtwave * 10000.0 filtsize = [109, 57, 76] # Holds the filter zero-points as determined from # Vega model by Dreiling & Bell (ApJ, 241,736, 1980) # # B 6.268e-9 erg cm-2 s-1 A-1 # V 3.604e-9 # R 2.161e-9 # I 1.126e-9 # # The following zero-points are from Lamla # (Landolt-Boernstein Vol. 2b, eds. K. Schaifer & # H.H. Voigt, Berlin: Springer, p. 73, 1982 QC61.L332) # # U 4.22e-9 erg cm-2 s-1 A-1 # # J 3.1e-10 # H 1.2e-10 # K 3.9e-11 # # U B V R I zeropoint = [3.1e-10, 1.2e-10, 3.9e-11] mag = np.zeros(3) filtflux = mag.copy() coverage = mag.copy() efflambda = mag.copy() totflux = mag.copy() filtername = ['J', 'H', 'K'] for i, _ in enumerate(filtername): filtw = filtwave[0:filtsize[i], i] filtt = filttran[0:filtsize[i], i] mag[i], filtflux[i], coverage[i], efflambda[i], totflux[i]= \ filtermag(hop[0].wave,flux, filtw, filtt, \ zeropoint[i]) logging.info('For object {}'.format(hop[0].obname)) logging.info( 'Filter magnitude Flux(erg/s/cm^2/A) Flux(erg/s/cm^2) Coverage(%) Eff. Lambda' ) for i in range(0, 3): if (mag[i] > 99): logging.info( ' {:1s} FILTER AND SPECTRUM DO NOT OVERLAP'.format( filtername[i])) else: logging.info( ' {:1s} {:6.3f} {:10.4e} {:10.4e} {:5.1f} {:7.1f}' .format(filtername[i], mag[i], filtflux[i], totflux[i], coverage[i] * 100., efflambda[i])) print(' ') logging.info('Colors') colortab = [[0, 1], [1, 2]] for i in range(0, 2): if (mag[colortab[i][0]] > 99) or (mag[colortab[i][1]] > 99): logging.info( '{}-{} ONE OR BOTH FILTERS DO NOT OVERLAP SPECTRUM'.format( filtername[colortab[i][0]], filtername[colortab[i][1]])) else: logging.info('{:1s}-{:1s} {:12.4f}'.format( filtername[colortab[i][0]], filtername[colortab[i][1]], mag[colortab[i][0]] - mag[colortab[i][1]])) print('\nWould you like to scale the spectrum to match photometry?\n') answer = yesno('n') if (answer == 'y'): print('\nWhich filter do you have?') scalefilt = inputter_single_mix('J/H/K: ', 'JHK') filtindex = filtername.index(scalefilt) scalemag = inputter( 'Enter your value for filter {}: '.format(filtername[filtindex]), 'float', False) print(' ') logging.info('Scaling {} from {}={:6.3f} to {}={}'.format( hop[0].obname, filtername[filtindex], mag[filtindex], filtername[filtindex], scalemag)) logging.info('Multiplying by {:.3f}'.format( 10**(0.4 * (mag[filtindex] - scalemag)))) hop[0].flux = hop[0].flux * 10**(0.4 * (mag[filtindex] - scalemag)) return hop
def womfilters(hop): """calculate photometric values from spectra""" import numpy as np import logging from tmath.wombat.filtermag import filtermag from tmath.wombat.yesno import yesno from tmath.wombat.inputter import inputter from tmath.wombat.inputter_single import inputter_single print('NOTE: The routine expects an f_lambda spectrum') print(' I will try to guess if the spectrum') print(' has been scaled by 1E15') print(' ') print(' Check this before believing fluxes') print(' ') flux=hop[0].flux.copy() if (np.mean(flux) > 0.00001): flux = flux *1.e-15 filtwave=np.zeros((141,10)) filttran=np.zeros((141,10)) filtwave[0:21, 1] = [3600.00, 3700.00, 3800.00, 3900.00, \ 4000.00, 4100.00, 4200.00, 4300.00, \ 4400.00, 4500.00, 4600.00, 4700.00, \ 4800.00, 4900.00, 5000.00, 5100.00, \ 5200.00, 5300.00, 5400.00, 5500.00, \ 5600.00] filttran[0:21, 1] = [0.00000, 0.03000, 0.13400, 0.56700, \ 0.92000, 0.97800, 1.00000, 0.97800, \ 0.93500, 0.85300, 0.74000, 0.64000, \ 0.53600, 0.42400, 0.32500, 0.23500, \ 0.15000, 0.09500, 0.04300, 0.00900, \ 0.00000] filtwave[0:24, 2] = [4700.00, 4800.00, 4900.00, 5000.00, \ 5100.00, 5200.00, 5300.00, 5400.00, \ 5500.00, 5600.00, 5700.00, 5800.00, \ 5900.00, 6000.00, 6100.00, 6200.00, \ 6300.00, 6400.00, 6500.00, 6600.00, \ 6700.00, 6800.00, 6900.00, 7000.00] filttran[0:24:, 2] = [0.00000, 0.03000, 0.16300, 0.45800, \ 0.78000, 0.96700, 1.00000, 0.97300, \ 0.89800, 0.79200, 0.68400, 0.57400, \ 0.46100, 0.35900, 0.27000, 0.19700, \ 0.13500, 0.08100, 0.04500, 0.02500, \ 0.01700, 0.01300, 0.00900, 0.00000] filtwave[0:24, 3] = [5500.00, 5600.00, 5700.00, 5800.00, \ 5900.00, 6000.00, 6100.00, 6200.00, \ 6300.00, 6400.00, 6500.00, 6600.00, \ 6700.00, 6800.00, 6900.00, 7000.00, \ 7100.00, 7200.00, 7300.00, 7400.00, \ 7500.00, 8000.00, 8500.00, 9000.00] filttran[0:24:, 3] = [0.00000, 0.23000, 0.74000, 0.91000, \ 0.98000, 1.00000, 0.98000, 0.96000, \ 0.93000, 0.90000, 0.86000, 0.81000, \ 0.78000, 0.72000, 0.67000, 0.61000, \ 0.56000, 0.51000, 0.46000, 0.40000, \ 0.35000, 0.14000, 0.03000, 0.00000] filtwave[0:23, 4] = [7000.00, 7100.00, 7200.00, 7300.00, \ 7400.00, 7500.00, 7600.00, 7700.00, \ 7800.00, 7900.00, 8000.00, 8100.00, \ 8200.00, 8300.00, 8400.00, 8500.00, \ 8600.00, 8700.00, 8800.00, 8900.00, \ 9000.00, 9100.00, 9200.00] filttran[0:23, 4] = [0.00000, 0.02400, 0.23200, 0.55500, \ 0.78500, 0.91000, 0.96500, 0.98500, \ 0.99000, 0.99500, 1.00000, 1.00000, \ 0.99000, 0.98000, 0.95000, 0.91000, \ 0.86000, 0.75000, 0.56000, 0.33000, \ 0.15000, 0.03000, 0.00000] filtwave[0:24, 0] = [3050.00, 3100.00, 3150.00, 3200.00, \ 3250.00, 3300.00, 3350.00, 3400.00, \ 3450.00, 3500.00, 3550.00, 3600.00, \ 3650.00, 3700.00, 3750.00, 3800.00, \ 3850.00, 3900.00, 3950.00, 4000.00, \ 4050.00, 4100.00, 4150.00, 4200.00] filttran[0:24, 0] = [0.00000, 0.02000, 0.07700, 0.13500, \ 0.20400, 0.28200, 0.38500, 0.49300, \ 0.60000, 0.70500, 0.82000, 0.90000, \ 0.95900, 0.99300, 1.00000, 0.97500, \ 0.85000, 0.64500, 0.40000, 0.22300, \ 0.12500, 0.05700, 0.00500, 0.00000] filtwave[0:47,5]=[2980., 3005., 3030., 3055., 3080., 3105., 3130., \ 3155., 3180.,3205., 3230., 3255., 3280., 3305., \ 3330., 3355., 3380., 3405., 3430., 3455., 3480., \ 3505., 3530., 3555., 3580., 3605., 3630., 3655., \ 3680., 3705., 3730., 3755., 3780., 3805., 3830., \ 3855., 3880., 3905., 3930., 3955., 3980., 4005., \ 4030., 4055., 4080., 4105., 4130.] filttran[0:47,5]=[0. , 0.0014, 0.0071, 0.0127, 0.0198, 0.0314, \ 0.0464, 0.0629, 0.0794, 0.0949, 0.1093, 0.1229, \ 0.1352, 0.1458, 0.1545, 0.1617, 0.1679, 0.1737, \ 0.1786, 0.1819, 0.1842, 0.186 , 0.187 , 0.1868, \ 0.1862, 0.1858, 0.1853, 0.1841, 0.1812, 0.1754, \ 0.1669, 0.1558, 0.1419, 0.1247, 0.1054, 0.0851, \ 0.0634, 0.0405, 0.0216, 0.011 , 0.0062, 0.0032, \ 0.0015, 0.0008, 0.0006, 0.0003, 0. ] filtwave[0:89,6]=[3630., 3655., 3680., 3705., 3730., 3755., 3780., \ 3805., 3830., 3855., 3880., 3905., 3930., 3955., \ 3980., 4005., 4030., 4055., 4080., 4105., 4130., \ 4155., 4180., 4205., 4230., 4255., 4280., 4305., \ 4330., 4355., 4380., 4405., 4430., 4455., 4480., \ 4505., 4530., 4555., 4580., 4605., 4630., 4655., \ 4680., 4705., 4730., 4755., 4780., 4805., 4830., \ 4855., 4880., 4905., 4930., 4955., 4980., 5005., \ 5030., 5055., 5080., 5105., 5130., 5155., 5180., \ 5205., 5230., 5255., 5280., 5305., 5330., 5355., \ 5380., 5405., 5430., 5455., 5480., 5505., 5530., \ 5555., 5580., 5605., 5630., 5655., 5680., 5705., \ 5730., 5755., 5780., 5805., 5830.] filttran[0:89,6]=[0.000e+00, 5.000e-04, 1.300e-03, 2.200e-03, \ 3.000e-03, 3.900e-03, 5.500e-03, 8.700e-03, \ 1.620e-02, 3.010e-02, 5.000e-02, 7.450e-02, \ 1.024e-01, 1.324e-01, 1.629e-01, 1.924e-01, \ 2.191e-01, 2.419e-01,2.609e-01, 2.767e-01, \ 2.899e-01, 3.010e-01, 3.105e-01, 3.186e-01, \ 3.258e-01, 3.324e-01, 3.385e-01, 3.442e-01, \ 3.496e-01, 3.548e-01, 3.596e-01, 3.640e-01, \ 3.678e-01, 3.709e-01, 3.736e-01, 3.763e-01, \ 3.792e-01, 3.827e-01, 3.863e-01, 3.899e-01, \ 3.931e-01, 3.955e-01, 3.973e-01, 3.986e-01, \ 3.997e-01, 4.008e-01, 4.019e-01, 4.030e-01, \ 4.043e-01, 4.057e-01, 4.073e-01, 4.091e-01, \ 4.110e-01, 4.129e-01, 4.147e-01, 4.165e-01, \ 4.181e-01, 4.194e-01, 4.201e-01, 4.201e-01, \ 4.191e-01, 4.169e-01, 4.147e-01, 4.115e-01, \ 3.988e-01, 3.684e-01, 3.233e-01, 2.690e-01, \ 2.112e-01, 1.550e-01, 1.043e-01, 6.270e-02, \ 3.370e-02, 1.900e-02, 1.280e-02, 8.700e-03, \ 5.700e-03, 3.700e-03, 2.400e-03, 1.700e-03, \ 1.400e-03, 1.200e-03, 1.000e-03, 9.000e-04, \ 7.000e-04, 5.000e-04, 3.000e-04, 1.000e-04, 0.000e+00] filtwave[0:75,7]=[5380., 5405., 5430., 5455., 5480., 5505., 5530., \ 5555., 5580., 5605., 5630., 5655., 5680., 5705., \ 5730., 5755., 5780., 5805., 5830., 5855., 5880., \ 5905., 5930., 5955., 5980., 6005., 6030., 6055., \ 6080., 6105., 6130., 6155., 6180., 6205., 6230., \ 6255., 6280., 6305., 6330., 6355., 6380., 6405., \ 6430., 6455., 6480., 6505., 6530., 6555., 6580., \ 6605., 6630., 6655., 6680., 6705., 6730., 6755., \ 6780., 6805., 6830., 6855., 6880., 6905., 6930., \ 6955., 6980., 7005., 7030., 7055., 7080., 7105., \ 7130., 7155., 7180., 7205., 7230.] filttran[0:75,7]=[0.000e+00, 1.600e-03, 1.130e-02, 2.970e-02, \ 5.680e-02, 9.230e-02, 1.356e-01, 1.856e-01, \ 2.390e-01, 2.917e-01, 3.395e-01, 3.794e-01, \ 4.116e-01, 4.371e-01, 4.570e-01, 4.723e-01, \ 4.839e-01, 4.925e-01, 4.990e-01, 5.040e-01, \ 5.080e-01, 5.112e-01, 5.141e-01, 5.169e-01, \ 5.194e-01, 5.213e-01, 5.222e-01, 5.220e-01, \ 5.212e-01, 5.202e-01, 5.197e-01, 5.202e-01, \ 5.215e-01, 5.233e-01, 5.254e-01, 5.275e-01, \ 5.294e-01, 5.310e-01, 5.319e-01, 5.320e-01, \ 5.316e-01, 5.310e-01, 5.305e-01, 5.302e-01, \ 5.299e-01, 5.290e-01, 5.271e-01, 5.241e-01, \ 5.211e-01, 5.176e-01, 5.057e-01, 4.775e-01, \ 4.341e-01, 3.792e-01, 3.162e-01, 2.488e-01, \ 1.824e-01, 1.225e-01, 7.470e-02, 4.300e-02, \ 2.470e-02, 1.550e-02, 1.120e-02, 8.300e-03, \ 5.900e-03, 4.100e-03, 2.900e-03, 2.100e-03, \ 1.600e-03, 1.300e-03, 1.000e-03, 8.000e-04, \ 5.000e-04, 2.000e-04, 0.000e+00] filtwave[0:89,8]=[6430., 6455., 6480., 6505., 6530., 6555., 6580., \ 6605., 6630., 6655., 6680., 6705., 6730., 6755., \ 6780., 6805., 6830., 6855., 6880., 6905., 6930., \ 6955., 6980., 7005., 7030., 7055., 7080., 7105., \ 7130., 7155., 7180., 7205., 7230., 7255., 7280., \ 7305., 7330., 7355., 7380., 7405., 7430., 7455., \ 7480., 7505., 7530., 7555., 7580., 7605., 7630., \ 7655., 7680., 7705., 7730., 7755., 7780., 7805., \ 7830., 7855., 7880., 7905., 7930., 7955., 7980., \ 8005., 8030., 8055., 8080., 8105., 8130., 8155., \ 8180., 8205., 8230., 8255., 8280., 8305., 8330., \ 8355., 8380., 8405., 8430., 8455., 8480., 8505., \ 8530., 8555., 8580., 8605., 8630.] filttran[0:89,8]=[0.000e+00, 1.000e-04, 3.000e-04, 4.000e-04, 5.000e-04, \ 4.000e-04, 3.000e-04, 5.000e-04, 1.000e-03, 2.100e-03, \ 3.600e-03, 6.000e-03, 1.110e-02, 2.080e-02, 3.660e-02, \ 5.970e-02, 9.130e-02, 1.317e-01, 1.779e-01, 2.260e-01, \ 2.719e-01, 3.125e-01, 3.470e-01, 3.755e-01, 3.978e-01, \ 4.142e-01, 4.256e-01, 4.331e-01, 4.377e-01, 4.405e-01, \ 4.416e-01, 4.411e-01, 4.392e-01, 4.358e-01, 4.315e-01, \ 4.265e-01, 4.214e-01, 4.165e-01, 4.119e-01, 4.077e-01, \ 4.039e-01, 4.006e-01, 3.975e-01, 3.943e-01, 3.906e-01, \ 3.862e-01, 3.812e-01, 3.757e-01, 3.700e-01, 3.641e-01, \ 3.583e-01, 3.526e-01, 3.473e-01, 3.424e-01, 3.379e-01, \ 3.337e-01, 3.297e-01, 3.259e-01, 3.224e-01, 3.194e-01, \ 3.169e-01, 3.150e-01, 3.132e-01, 3.111e-01, 3.081e-01, \ 3.039e-01, 2.996e-01, 2.945e-01, 2.803e-01, 2.493e-01, \ 2.060e-01, 1.578e-01, 1.118e-01, 7.430e-02, 4.580e-02, \ 2.570e-02, 1.340e-02, 7.700e-03, 5.500e-03, 3.700e-03, \ 2.300e-03, 1.500e-03, 1.100e-03, 1.100e-03, 1.100e-03, \ 9.000e-04, 6.000e-04, 3.000e-04, 0.000e+00] filtwave[0:141,9]=[ 7730., 7755., 7780., 7805., 7830., 7855., 7880., \ 7905., 7930., 7955., 7980., 8005., 8030., 8055., \ 8080., 8105., 8130., 8155., 8180., 8205., 8230., \ 8255., 8280., 8305., 8330., 8355., 8380., 8405., \ 8430., 8455., 8480., 8505., 8530., 8555., 8580., \ 8605., 8630., 8655., 8680., 8705., 8730., 8755., \ 8780., 8805., 8830., 8855., 8880., 8905., 8930., \ 8955., 8980., 9005., 9030., 9055., 9080., 9105.,\ 9130., 9155., 9180., 9205., 9230., 9255., 9280.,\ 9305., 9330., 9355., 9380., 9405., 9430., 9455., \ 9480., 9505., 9530., 9555., 9580., 9605., 9630., \ 9655., 9680., 9705., 9730., 9755., 9780., 9805., \ 9830., 9855., 9880., 9905., 9930., 9955., 9980., \ 10005., 10030., 10055., 10080., 10105., 10130., 10155.,\ 10180., 10205., 10230., 10255., 10280., 10305., 10330.,\ 10355., 10380., 10405., 10430., 10455., 10480., 10505.,\ 10530., 10555., 10580., 10605., 10630., 10655., 10680.,\ 10705., 10730., 10755., 10780., 10805., 10830., 10855.,\ 10880., 10905., 10930., 10955., 10980., 11005., 11030.,\ 11055., 11080., 11105., 11130., 11155., 11180., 11205.,\ 11230.] filttran[0:141,9]=[0.00e+00, 0.00e+00, 1.00e-04, 1.00e-04, 1.00e-04, \ 2.00e-04, 2.00e-04, 3.00e-04, 5.00e-04, 7.00e-04, \ 1.10e-03, 1.70e-03, 2.70e-03, 4.00e-03, 5.80e-03, \ 8.20e-03, 1.14e-02, 1.55e-02, 2.02e-02, 2.55e-02, \ 3.11e-02, 3.69e-02, 4.28e-02, 4.84e-02, 5.36e-02, \ 5.83e-02, 6.25e-02, 6.61e-02, 6.93e-02, 7.20e-02, \ 7.44e-02, 7.63e-02, 7.79e-02, 7.92e-02, 8.01e-02, \ 8.08e-02, 8.12e-02, 8.13e-02, 8.12e-02, 8.07e-02, \ 8.01e-02, 7.91e-02, 7.79e-02, 7.66e-02, 7.50e-02, \ 7.34e-02, 7.16e-02, 6.98e-02, 6.79e-02, 6.61e-02, \ 6.42e-02, 6.24e-02, 6.07e-02, 5.90e-02, 5.74e-02, \ 5.59e-02, 5.46e-02, 5.35e-02, 5.24e-02, 5.15e-02, \ 5.05e-02, 4.96e-02, 4.85e-02, 4.74e-02, 4.62e-02, \ 4.50e-02, 4.38e-02, 4.26e-02, 4.15e-02, 4.04e-02, \ 3.93e-02, 3.83e-02, 3.73e-02, 3.63e-02, 3.53e-02, \ 3.42e-02, 3.31e-02, 3.19e-02, 3.07e-02, 2.94e-02, \ 2.80e-02, 2.67e-02, 2.53e-02, 2.40e-02, 2.27e-02, \ 2.13e-02, 2.01e-02, 1.88e-02, 1.76e-02, 1.65e-02, \ 1.53e-02, 1.43e-02, 1.32e-02, 1.22e-02, 1.12e-02, \ 1.03e-02, 9.40e-03, 8.60e-03, 7.80e-03, 7.10e-03, \ 6.40e-03, 5.80e-03, 5.20e-03, 4.70e-03, 4.20e-03, \ 3.80e-03, 3.50e-03, 3.10e-03, 2.80e-03, 2.60e-03, \ 2.40e-03, 2.20e-03, 2.00e-03, 1.90e-03, 1.80e-03, \ 1.60e-03, 1.50e-03, 1.40e-03, 1.30e-03, 1.20e-03, \ 1.10e-03, 1.00e-03, 9.00e-04, 8.00e-04, 8.00e-04, \ 7.00e-04, 7.00e-04, 6.00e-04, 6.00e-04, 5.00e-04, \ 5.00e-04, 4.00e-04, 4.00e-04, 3.00e-04, 3.00e-04, \ 2.00e-04, 2.00e-04, 1.00e-04, 1.00e-04, 0.00e+00, \ 0.00e+00] filtsize = [24, 21, 24, 24, 23, 47, 89, 75, 89, 141] # Holds the filter zero-points as determined from # Vega model by Dreiling & Bell (ApJ, 241,736, 1980) # # B 6.268e-9 erg cm-2 s-1 A-1 # V 3.604e-9 # R 2.161e-9 # I 1.126e-9 # # The following zero-points are from Lamla # (Landolt-Boernstein Vol. 2b, eds. K. Schaifer & # H.H. Voigt, Berlin: Springer, p. 73, 1982 QC61.L332) # # U 4.22e-9 erg cm-2 s-1 A-1 # # J 3.1e-10 # H 1.2e-10 # K 3.9e-11 # # U B V R I zp_johnson = np.array([4.22e-9, 6.268e-9, 3.604e-9, 2.161e-9, 1.126e-9]) leff_sloan=np.array([3560., 4830., 6260., 7670., 9100]) zp_sloan=3.631e-20*2.99792458e18/(leff_sloan*leff_sloan) zeropoint=np.concatenate([zp_johnson,zp_sloan]) mag=np.zeros(10) filtflux=mag.copy() coverage=mag.copy() efflambda=mag.copy() totflux=mag.copy() filtername = ['U', 'B', 'V', 'R', 'I','u','g','r','i','z'] for i,_ in enumerate(filtername): filtw=filtwave[0:filtsize[i],i] filtt=filttran[0:filtsize[i],i] mag[i], filtflux[i], coverage[i], efflambda[i], totflux[i]= \ filtermag(hop[0].wave,flux, filtw, filtt, \ zeropoint[i]) logging.info('For object {}'.format(hop[0].obname)) logging.info('Filter magnitude Flux(erg/s/cm^2/A) Flux(erg/s/cm^2) Coverage(%) Eff. Lambda') for i in range(0,5): if (mag[i] > 99): logging.info(' {:1s} FILTER AND SPECTRUM DO NOT OVERLAP'.format(filtername[i])) else: logging.info(' {:1s} {:6.3f} {:10.4e} {:10.4e} {:5.1f} {:6.1f}'.format(filtername[i],mag[i],filtflux[i],totflux[i],coverage[i]*100.,efflambda[i])) for i in range(5,10): if (mag[i] > 99): logging.info(' {:1s} FILTER AND SPECTRUM DO NOT OVERLAP'.format(filtername[i])) else: logging.info(' {:1s} {:6.3f} {:10.4e} {:10.4e} {:5.1f} {:6.1f}'.format(filtername[i],mag[i],filtflux[i],totflux[i],coverage[i]*100.,efflambda[i])) print(' ') logging.info('Colors') colortab=[[0,1],[1,2],[2,3],[2,4],[5,6],[6,7],[7,8],[8,9]] for i in range(0,4): if (mag[colortab[i][0]] > 99) or (mag[colortab[i][1]] > 99): logging.info('{}-{} ONE OR BOTH FILTERS DO NOT OVERLAP SPECTRUM'.format(filtername[colortab[i][0]],filtername[colortab[i][1]])) else: logging.info('{:1s}-{:1s} {:12.4f}'.format(filtername[colortab[i][0]],filtername[colortab[i][1]],mag[colortab[i][0]]-mag[colortab[i][1]])) for i in range(4,8): if (mag[colortab[i][0]] > 99) or (mag[colortab[i][1]] > 99): logging.info('{}-{} ONE OR BOTH FILTERS DO NOT OVERLAP SPECTRUM'.format(filtername[colortab[i][0]],filtername[colortab[i][1]])) else: logging.info('{:1s}-{:1s} {:12.4f}'.format(filtername[colortab[i][0]],filtername[colortab[i][1]],mag[colortab[i][0]]-mag[colortab[i][1]])) print('\nWould you like to scale the spectrum to match photometry?\n') answer=yesno('n') if (answer == 'y'): print('\nWhich filter do you have?') scalefilt=inputter_single_mix('U/B/V/R/I/u/g/r/i/z: ','UBVRIugriz') filtindex=filtername.index(scalefilt) scalemag=inputter('Enter your value for filter {}: '.format(filtername[filtindex]),'float',False) print(' ') logging.info('Scaling {} from {}={:6.3f} to {}={}'.format(hop[0].obname,filtername[filtindex],mag[filtindex],filtername[filtindex],scalemag)) logging.info('Multiplying by {:.3f}'.format(10**(0.4*(mag[filtindex]-scalemag)))) hop[0].flux=hop[0].flux*10**(0.4*(mag[filtindex]-scalemag)) return hop
def fitspl_dev(wave, flux, airlimit, fig, cal=None): import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import splrep, splev import tmath.wombat.womconfig as womconfig from tmath.wombat.womget_element import womget_element from tmath.pydux.wave_telluric import wave_telluric from tmath.wombat.yesno import yesno from tmath.wombat.onclick import onclick from tmath.wombat.onkeypress import onkeypress import glob """fit spline to spectrum""" # starting points for spline # bandpts = np.array([3000, 3050, 3090, 3200, 3430, 3450, 3500, 3550, 3600, \ # 3650, 3700, 3767, 3863, 3945, 4025, 4144, 4200, 4250, \ # 4280, 4390, 4450, 4500, 4600, 4655, 4717, 4750, 4908, \ # 4950, 5000, 5050, 5100, 5150, 5200, 5250, 5280, 5350, \ # 5387, 5439, 5500, 5550, 6100, 6150, 6400, 6430, 6650, \ # 6700, 6750, 6800, 7450, 7500, 7550, 8420, 8460, 8520, \ # 8570, 8600, 8725, 8770, 9910, 10000, 10200, 10300, \ # 10400, 10500, 10600, 10700]) binWidth = 60 bandpts = np.arange(3000, 11000, binWidth) locsinrange = np.logical_and((bandpts > wave[10]), (bandpts < wave[-10])) #useband=bandpts[locsinrange] # now mask based on spectral features # you can add mask features here, and the feature name can # be anything, they aren't used explicitly featureMask = {} # empirical masks from Dimitriadis featureMask['feature1'] = [3722.56 - 10.0 / 2., 3722.56 + 10.0 / 2.] featureMask['feature2'] = [3736.90 - 15.0 / 2., 3736.90 + 15.0 / 2.] featureMask['feature3'] = [3752.00 - 15.0 / 2., 3752.00 + 15.0 / 2.] featureMask['feature4'] = [3772.00 - 17.0 / 2., 3772.00 + 17.0 / 2.] featureMask['feature5'] = [3800.00 - 18.0 / 2., 3800.00 + 18.0 / 2.] featureMask['feature6'] = [3835.38 - 20.0 / 2., 3835.38 + 20.0 / 2.] featureMask['feature7'] = [3889.05 - 24.0 / 2., 3889.05 + 24.0 / 2.] featureMask['feature8'] = [3933.66 - 16.0 / 2., 3933.66 + 16.0 / 2.] featureMask['feature9'] = [3970.07 - 18.0 / 2., 3970.07 + 18.0 / 2.] featureMask['feature10'] = [4101.74 - 28.0 / 2., 4101.74 + 28.0 / 2.] featureMask['feature11'] = [4340.46 - 30.0 / 2., 4340.46 + 30.0 / 2.] featureMask['feature12'] = [4471.48 - 20.0 / 2., 4471.48 + 20.0 / 2.] featureMask['feature13'] = [4685.70 - 30.0 / 2., 4685.70 + 30.0 / 2.] featureMask['feature14'] = [4861.36 - 35.0 / 2., 4861.36 + 35.0 / 2.] featureMask['feature15'] = [5411.52 - 35.0 / 2., 5411.52 + 35.0 / 2.] featureMask['feature16'] = [5889.95 - 32.0 / 2., 5889.95 + 32.0 / 2.] featureMask['feature17'] = [6562.85 - 40.0 / 2., 6562.85 + 40.0 / 2.] featureMask['feature18'] = [8498.02 - 25.0 / 2., 8498.02 + 25.0 / 2.] featureMask['feature19'] = [8542.09 - 25.0 / 2., 8542.09 + 25.0 / 2.] featureMask['feature20'] = [8662.14 - 25.0 / 2., 8662.14 + 25.0 / 2.] featureMask['feature21'] = [8763.96 - 20.0 / 2., 8763.96 + 20.0 / 2.] featureMask['feature22'] = [8865.75 - 25.0 / 2., 8865.75 + 25.0 / 2.] featureMask['feature23'] = [9010.00 - 28.0 / 2., 9010.00 + 28.0 / 2.] featureMask['feature24'] = [9213.90 - 30.0 / 2., 9213.90 + 30.0 / 2.] featureMask['feature25'] = [9545.97 - 34.0 / 2., 9545.97 + 34.0 / 2.] featureMask['telluric1'] = [3216.0 - binWidth / 2., 3420.0 + binWidth / 2.] #featureMask['telluric2'] = [5600.0-binWidth/2., 6050.0+binWidth/2.] featureMask['telluric3'] = [6250.0 - binWidth / 2., 6360.0 + binWidth / 2.] featureMask['telluric4'] = [6450.0 - binWidth / 2., 6530.0 + binWidth / 2.] featureMask['telluric5'] = [6840.0 - binWidth / 2., 7410.0 + binWidth / 2.] featureMask['telluric6'] = [7560.0 - binWidth / 2., 8410.0 + binWidth / 2.] featureMask['telluric7'] = [8925.0 - binWidth / 2., 9900.0 + binWidth / 2.] # inital testing masks from XIDL # featureMask['balmer1'] = [3714.0-binWidth/2., 3723.0+binWidth/2.] # featureMask['balmer2'] = [3650.0-binWidth/2., 3820.0+binWidth/2.] # featureMask['balmer3'] = [3725.0-binWidth/2., 3735.0+binWidth/2.] # featureMask['balmer4'] = [3740.0-binWidth/2., 3755.0+binWidth/2.] # featureMask['balmer5'] = [3760.0-binWidth/2., 3775.0+binWidth/2.] # featureMask['balmer6'] = [3785.0-binWidth/2., 3806.0+binWidth/2.] # featureMask['balmer7'] = [3810.0-binWidth/2., 3820.0+binWidth/2.] # featureMask['balmer8'] = [3824.0-binWidth/2., 3841.0+binWidth/2.] # featureMask['balmer9'] = [3880.0-binWidth/2., 3895.0+binWidth/2.] # featureMask['balmer10'] = [3957.0-binWidth/2., 3979.0+binWidth/2.] # featureMask['balmer11'] = [4000.0-binWidth/2., 4030.0+binWidth/2.] # featureMask['balmer12'] = [4087.0-binWidth/2., 4120.0+binWidth/2.] # featureMask['balmer13'] = [4135.0-binWidth/2., 4145.0+binWidth/2.] # featureMask['balmer14'] = [4328.0-binWidth/2., 4355.0+binWidth/2.] # featureMask['balmer15'] = [4677.0-binWidth/2., 4692.0+binWidth/2.] # featureMask['balmer16'] = [4830.0-binWidth/2., 4931.0+binWidth/2.] # featureMask['balmer17'] = [5402.0-binWidth/2., 5417.0+binWidth/2.] # featureMask['balmer18'] = [6535.0-binWidth/2., 6590.0+binWidth/2.] # featureMask['telluric1'] = [3216.0-binWidth/2., 3420.0+binWidth/2.] # #featureMask['telluric2'] = [5600.0-binWidth/2., 6050.0+binWidth/2.] # featureMask['telluric3'] = [6250.0-binWidth/2., 6360.0+binWidth/2.] # featureMask['telluric4'] = [6450.0-binWidth/2., 6530.0+binWidth/2.] # featureMask['telluric5'] = [6840.0-binWidth/2., 7410.0+binWidth/2.] # featureMask['telluric6'] = [7560.0-binWidth/2., 8410.0+binWidth/2.] # featureMask['telluric7'] = [8925.0-binWidth/2., 9900.0+binWidth/2.] # generate a mask via a boolean array that excludes regions in stellar features maskInds = np.full(len(bandpts), True, dtype=bool) for i, key in enumerate(featureMask.keys()): featureMaskInds = np.logical_or((bandpts < featureMask[key][0]), (bandpts > featureMask[key][1])) maskInds *= featureMaskInds fullMask = locsinrange * maskInds # apply the mask useband = bandpts[fullMask] for i, _ in enumerate(useband): index = womget_element(wave, useband[i]) useband[i] = index # useband now has indices of wavelength positions if (min(flux) < 0): flux[np.where(flux < 0)] = 0.0 plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) if (airlimit): loc = wave_telluric(wave, 'high') else: loc = wave_telluric(wave, 'low') #invert loc and convert all good sections to np.nan so they won't plot loc = np.invert(loc) wavetell = wave.copy() fluxtell = flux.copy() wavetell[loc] = np.nan fluxtell[loc] = np.nan plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if '../../master_files/' + cal + '_splpts_master.txt' not in glob.glob( '../../master_files/*'): womconfig.nsplinepoints = len(useband) womconfig.tmpsplptsx = wave[useband].copy().tolist() womconfig.tmpsplptsy = [] for i, _ in enumerate(useband): womconfig.tmpsplptsy.append( np.median(flux[useband[i] - 2:useband[i] + 3])) spline = splrep(womconfig.tmpsplptsx, womconfig.tmpsplptsy, k=3) else: masterx, mastery = np.genfromtxt('../../master_files/' + cal + '_splpts_master.txt') womconfig.nsplinepoints = len(masterx) womconfig.tmpsplptsx = list(masterx) womconfig.tmpsplptsy = list(mastery) # print (type(womconfig.tmpsplptsx)) spline = splrep(womconfig.tmpsplptsx, womconfig.tmpsplptsy, k=3) splineresult = splev(wave, spline) plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plt.pause(0.01) done = False print('Is this OK? ') answer = yesno('n') if (answer == 'y'): done = True splptsy = [ z for _, z in sorted(zip(womconfig.tmpsplptsx, womconfig.tmpsplptsy)) ] splptsx = sorted(womconfig.tmpsplptsx) while (not done): plotdone = False while (not plotdone): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plt.pause(0.01) print('Change scale? ') answer = yesno('n') if (answer == 'y'): plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') print('Click corners of box to change plot scale') newlims = plt.ginput(2, timeout=-1) xmin = newlims[0][0] ymin = newlims[0][1] xmax = newlims[1][0] ymax = newlims[1][1] plt.cla() plt.plot(wave, flux, drawstyle='steps-mid', color='k') plt.plot(wavetell, fluxtell, drawstyle='steps-mid', color='violet') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.plot(wave, splineresult, color='g') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) plotdone = True else: plotdone = True cid = fig.canvas.mpl_connect('button_press_event', onclick) cid2 = fig.canvas.mpl_connect('key_press_event', onkeypress) print('\nClick on continuum points for spline fit.') print('Left button or (a) = add point') print('Middle button or (s) = delete point') print('Right button or (d) = done\n') womconfig.pflag = '' while (womconfig.pflag != 'done'): plt.pause(0.01) fig.canvas.mpl_disconnect(cid) fig.canvas.mpl_disconnect(cid2) splptsy = [ z for _, z in sorted(zip(womconfig.tmpsplptsx, womconfig.tmpsplptsy)) ] splptsx = sorted(womconfig.tmpsplptsx) spline = splrep(splptsx, splptsy, k=3) splineresult = splev(wave, spline) plt.plot(wave, splineresult, drawstyle='steps-mid', color='g') plt.pause(0.01) print('Is this fit OK? ') answer = yesno('y') if (answer == 'y'): done = True if cal != None: np.savetxt('../../master_files/' + cal + '_splpts_master.txt', [splptsx, splptsy]) return splineresult
def womgau(hop): """fit gaussian to line""" import numpy as np import logging import matplotlib.pyplot as plt from scipy.optimize import curve_fit from tmath.wombat.womwaverange import womwaverange from tmath.wombat.womget_element import womget_element from tmath.wombat.inputter import inputter from tmath.wombat.inputter_single import inputter_single from tmath.wombat.gauss import gauss from tmath.wombat.gauss_cont import gauss_cont from tmath.wombat.yesno import yesno print(' ') logging.info('Object is {}'.format(hop[0].obname)) print(' ') print('Spectrum runs from {} to {}'.format(hop[0].wave[0], hop[0].wave[-1])) print(' ') print('This routine expects the spectrum to be in flambda units.') print('It also expects a linear wavelength scale.') print(' ') print('Choose general region of spectrum\n') nwave, nflux, mode = womwaverange(hop[0].wave, hop[0].flux, 'none') print('\nNow pick the exact range for the fit') waveint, fluxint, mode = womwaverange(nwave, nflux, mode) indexblue = womget_element(nwave, waveint[0]) indexred = womget_element(nwave, waveint[-1]) if (mode == 'w'): done = False while (not done): print(' ') wavecenter = inputter('Enter approximate center of Gaussian : ', 'float', False) indexcenter = womget_element(waveint, wavecenter) if (indexcenter <= 0) or (wavecenter > waveint[-1]): print('Bad central wavelength, try again') else: done = True else: done = False while (not done): print('Mark the approximate center of the Gaussian') pickcent = plt.ginput(1, timeout=-1) indexcenter = womget_element(waveint, pickcent[0][0]) print('\nApproximate center at {}'.format(waveint[indexcenter])) print('\nIs this OK?') answer = yesno('y') if (answer == 'y'): done = True weights = np.sqrt(hop[0].var[indexblue:indexred + 1]) print(' ') continuum = inputter_single( 'Do you want to fit gaussian with (c)ontinuum, or (n)o continuum? ', 'cn') if (continuum == 'c'): p = [fluxint[indexcenter], waveint[indexcenter], 3.0, 1.0, waveint[0]] result = curve_fit(gauss_cont, waveint, fluxint, sigma=weights, p0=p, absolute_sigma=True, full_output=True) else: p = [fluxint[indexcenter], waveint[indexcenter], 3.0] result = curve_fit(gauss, waveint, fluxint, sigma=weights, p0=p, absolute_sigma=True, full_output=True) coefferr = np.sqrt(np.diag(result[1])) coeff = result[0] # make 'finer-grained' version of fit, 0.2A/pix for calculations wavecalc = np.arange(2 * 5 * 50 * abs( coeff[2])) * 0.2 + coeff[1] - 0.2 * 5 * 50 * abs(coeff[2]) calccenter = womget_element(wavecalc, coeff[1]) if (continuum == 'c'): fluxcalc = gauss_cont(wavecalc, *coeff) fluxcont = wavecalc * coeff[3] + coeff[4] fluxgaussian = fluxcalc - fluxcont linecont = fluxcont[calccenter] else: fluxcalc = gauss(wavecalc, *coeff) deltafit = wavecalc[1] - wavecalc[0] calcindexblue = womget_element(wavecalc, waveint[0]) calcindexred = womget_element(wavecalc, waveint[-1]) sumfluxcalc = np.sum(fluxcalc[calcindexblue:calcindexred + 1] * deltafit) sumallfluxcalc = np.sum(fluxcalc * deltafit) chi = (result[2]['fvec']**2).sum() redchi = chi / (len(waveint) - len(coeff)) if (continuum == 'c'): sumfluxgaussian = np.sum(fluxgaussian[calcindexblue:calcindexred + 1] * deltafit) sumallfluxgaussian = np.sum(fluxgaussian * deltafit) sumfluxcont = np.sum(fluxcont[calcindexblue:calcindexred + 1] * deltafit) sumallfluxcont = np.sum(fluxcont * deltafit) # propagate uncertainty (from old version) not sure this is correct height_pct = coefferr[0] / coeff[0] sigma_pct = coefferr[2] / coeff[2] flux_pct = np.sqrt(height_pct**2 + sigma_pct**2) sumfluxgaussiansig = sumfluxgaussian * flux_pct sumallfluxgaussiansig = sumallfluxgaussian * flux_pct plt.cla() plt.plot(nwave, nflux, drawstyle='steps-mid', color='k') plt.ylabel('Flux') plt.xlabel('Wavelength') xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() plt.plot(wavecalc, fluxcalc, drawstyle='steps-mid', color='b') if (continuum == 'c'): plt.plot(wavecalc, fluxgaussian, drawstyle='steps-mid', color='r') plt.plot(wavecalc, fluxcont, drawstyle='steps-mid', color='g') plt.plot([waveint[0], waveint[0]], [ymin, ymax], color='k', linestyle='--') plt.plot([waveint[-1], waveint[-1]], [ymin, ymax], color='k', linestyle='--') plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) logging.info('For object {} Gaussian fit'.format(hop[0].obname)) if (continuum == 'c'): print( '\nData = Black, Fit = Blue, Continuum = Green, Fit-Continuum = Red\n' ) else: print('\nData = Black, Fit = Blue\n') logging.info('Height {:16.8f}+/-{:16.8f}'.format( coeff[0], coefferr[0])) logging.info('Center {:16.8f}+/-{:16.8f}'.format( coeff[1], coefferr[1])) logging.info('Sigma {:16.8f}+/-{:16.8f}'.format( coeff[2], coefferr[2])) if (continuum == 'c'): logging.info('Slope {:16.8f}+/-{:16.8f}'.format( coeff[3], coefferr[3])) logging.info('Y-intercept {:16.8f}+/-{:16.8f}'.format( coeff[4], coefferr[4])) logging.info('FWHM {:16.8f}+/-{:16.8f}'.format( 2.35482 * np.abs(coeff[2]), 2.35482 * coefferr[2])) logging.info( 'Flux between dotted lines (Gaussian): {:16.8f}+/-{:16.8f}'.format( sumfluxgaussian, sumfluxgaussiansig)) logging.info('EW between dotted lines (Gaussian): {:16.8f}'.format( sumfluxgaussian / linecont)) logging.info('Flux for full (Gaussian): {:16.8f}+/-{:16.8f}'.format( sumallfluxgaussian, sumallfluxgaussiansig)) logging.info('EW for full (Gaussian): {:16.8f}'.format( sumallfluxgaussian / linecont)) logging.info( 'Continuum flux at line center: {:16.8f}'.format(linecont)) logging.info('Chi^2: {}'.format(chi)) logging.info('Reduced chi^2: {}'.format(redchi)) logging.info('All fluxes might need to be scaled by 1e-15') print(' ') return hop
def womspl(hop, fig): """fit spline to spectrum""" import matplotlib.pyplot as plt import numpy as np import copy from tmath.wombat.womplot import womplot from tmath.wombat.onclick import onclick from scipy.interpolate import splrep, splev from tmath.wombat.inputter import inputter from tmath.wombat.yesno import yesno from tmath.wombat import HOPSIZE import tmath.wombat.womconfig as womconfig # global nsplinepoints, tmpsplptsx, tmpsplptsy, pflag print('\nObject is {}\n'.format(hop[0].obname)) womplot(hop) xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) womconfig.nsplinepoints = 0 womconfig.tmpsplptsx = [] womconfig.tmpsplptsy = [] done = False while (not done): plt.cla() plt.plot(hop[0].wave, hop[0].flux, drawstyle='steps-mid') if (len(womconfig.tmpsplptsx) > 0): plt.plot(womconfig.tmpsplptsx, womconfig.tmpsplptsy, 'ro') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) plt.xlim([xmin, xmax]) plt.ylim([ymin, ymax]) cid = fig.canvas.mpl_connect('button_press_event', onclick) print('\nClick on continuum points for spline fit.') print('Left button = add point') print('Middle button = delete point') print('Right button = done\n') womconfig.pflag = '' while (womconfig.pflag != 'done'): plt.pause(0.01) fig.canvas.mpl_disconnect(cid) splptsy = [ z for _, z in sorted(zip(womconfig.tmpsplptsx, womconfig.tmpsplptsy)) ] splptsx = sorted(womconfig.tmpsplptsx) spline = splrep(splptsx, splptsy, k=3) splineresult = splev(hop[0].wave, spline) plt.plot(hop[0].wave, splineresult, drawstyle='steps-mid') plt.pause(0.01) print('Is this fit OK? ') answer = yesno('y') if (answer == 'y'): done = True print('\nSubtract spline fit from flux?\n') sub = yesno('n') if (sub == 'y'): hop[0].flux = hop[0].flux - splineresult print('\nStore spline in hopper?\n') store = yesno('y') if (store == 'y'): hopnum = 0 while (hopnum < 1) or (hopnum > HOPSIZE): hopnum = inputter('Store in which hopper: ', 'int', False) hop[hopnum] = copy.deepcopy(hop[0]) hop[hopnum].flux = splineresult.copy() hop[hopnum].obname = hop[hopnum].obname + 'spline' hop[hopnum].var = np.zeros(len(hop[0].wave)) return hop
def womzap(hop): """routine to zap outliers (CRs)""" import numpy as np import matplotlib.pyplot as plt import logging from tmath.wombat.inputter import inputter from tmath.wombat.inputter_single import inputter_single from tmath.wombat.yesno import yesno from tmath.wombat.wshow import wshow plt.cla() plt.plot(hop[0].wave,hop[0].flux,drawstyle='steps-mid') plt.xlabel('Wavelength') plt.ylabel('Flux') plt.title(hop[0].obname) wshow() print('\nRoutine to zap outliers\n') done = False while (not done): nsig=inputter('Enter zapping threshold in sigmas (0=replace all with median): ','float',False) print(' ') boxsize=inputter('Enter box size for computing statistics: (odd integer < 45) ','int',False) if (boxsize < 3) or (boxsize > 45) or (nsig < 0): print('Invalid boxsize or sigma') else: done = True if (boxsize % 2 == 0): boxsize=boxsize+1 half=int(boxsize/2.) newflux=hop[0].flux.copy() if (nsig > 0): mode=inputter_single('Use inter(q)uartile or (m)edian variance (q/m)? ','qm') if (mode == 'm'): for i in range(half,len(newflux)-half): sample=newflux[i-half:i+half+1] medval=np.median(sample) varpix=(sample[half]-medval)**2 sum=-1.0*varpix for k in range(0,boxsize): diff=sample[k]-medval sum=sum+diff*diff sum=sum/(boxsize-1) if (varpix > nsig*nsig*sum): newflux[i]=medval if (mode == 'q'): for i in range(half,len(newflux)-half): sample=newflux[i-half:i+half+1] medval=np.median(sample) q25=np.percentile(sample,25.) q75=np.percentile(sample,75.) qsig=0.7414272*(q75-q25) diff=abs(sample[half]-medval) if (diff > nsig*qsig): newflux[i]=medval if (nsig == 0): from scipy.ndimage.filters import median_filter newflux=median_filter(newflux,boxsize) plt.plot(hop[0].wave,newflux,drawstyle='steps-mid') print('Does this zapping look good?') good=yesno('y') if (good == 'y'): hop[0].flux=newflux.copy() logging.debug('File {} zapped with sigma {} and boxsize {}'.format\ (hop[0].obname,nsig,boxsize)) else: print('OK, active spectrum unchanged') #FIX var return hop
def telluric_remove(bstarwave, bstar, bairmass, wave, object, airmass, variance, spectrum, shift=None): import numpy as np import pdb import matplotlib.pyplot as plt from tmath.wombat.inputter import inputter from tmath.wombat.yesno import yesno from tmath.wombat.womscipyrebin import womscipyrebin from tmath.wombat.womget_element import womget_element from tmath.pydux.xcor import xcor from tmath.pydux.finalscaler import finalscaler bstartmp = womscipyrebin(bstarwave, bstar, wave) # plt.cla() # plt.plot(bstarwave,bstartmp) # plt.pause(0.01) # answer=yesno('y') print('\nThe ratio of airmasses (object/B-star) is {}'.format(airmass / bairmass)) if (airmass / bairmass > 3.0) or (airmass / bairmass < 0.33): print('\nWARNING: OBJECT AND B-STAR HAVE WILDLY DIFFERENT') print('AIRMASSES: ATMOSPHERIC BAND DIVISION MAY BE LOUSY\n') wmin = wave[0] wmax = wave[-1] npix = len(object) wdelt = wave[1] - wave[0] print('wdelt', wdelt) lag = np.zeros(3) lagflag = [False] * 3 xfactor = 10 maxlag = 200 if not shift: print('\nCross-correlating object with B-star spectrum\n') fig = plt.figure() axarr = fig.subplots(2, 1) if (wmin < 6200) and (wmax > 6400) and (wmax < 6900): indblue = womget_element(wave, 6200) indred = womget_element(wave, 6400) lag[0] = xcor(object[indblue:indred + 1], bstartmp[indblue:indred + 1], xfactor, maxlag) lagflag[0] = True print('The shift at the 6250A band is {} angstroms'.format(lag[0] * wdelt)) if (wmin < 6800) and (wmax > 6500): indblue = womget_element(wave, 6800) indred = womget_element(wave, 6950) scale = 1. / np.max(object[indblue:indred + 1]) obb = scale * object[indblue:indred + 1] bb = bstartmp[indblue:indred + 1] lag[1] = xcor(obb, bb, xfactor, maxlag) lagflag[1] = True print('The shift at the B band is {} angstroms'.format(lag[1] * wdelt)) plt.cla() # ymin,ymax=finalscaler(object) # plt.plot(wave,object,drawstyle='steps-mid',color='r') # plt.plot(wave,newobject,drawstyle='steps-mid',color='k') ymin, ymax = finalscaler(bstartmp[indblue:indred + 1]) axarr[0].plot(wave[indblue:indred + 1], scale * object[indblue:indred + 1], drawstyle='steps-mid', color='r') axarr[0].plot(wave[indblue:indred + 1], bstartmp[indblue:indred + 1], drawstyle='steps-mid', color='k') axarr[0].plot(wave[indblue:indred + 1] + lag[1] * wdelt, bstartmp[indblue:indred + 1], drawstyle='steps-mid', color='g') plt.pause(0.01) if (wmin < 7500) and (wmax > 8000): indblue = womget_element(wave, 7500) indred = womget_element(wave, 8000) scale = 1. / np.max(object[indblue:indred + 1]) lag[2] = xcor(scale * object[indblue:indred + 1], bstartmp[indblue:indred + 1], xfactor, maxlag) print('The shift at the A band is {} angstroms'.format(lag[2] * wdelt)) lagflag[2] = True # ymin,ymax=finalscaler(object) # plt.plot(wave,object,drawstyle='steps-mid',color='r') # plt.plot(wave,newobject,drawstyle='steps-mid',color='k') ymin, ymax = finalscaler(bstartmp[indblue:indred + 1]) axarr[1].plot(wave[indblue:indred + 1], scale * object[indblue:indred + 1], drawstyle='steps-mid', color='r') axarr[1].plot(wave[indblue:indred + 1], bstartmp[indblue:indred + 1], drawstyle='steps-mid', color='k') axarr[1].plot(wave[indblue:indred + 1] + lag[2] * wdelt, bstartmp[indblue:indred + 1], drawstyle='steps-mid', color='g') plt.pause(0.01) check = inputter('Check plot [enter when done]: ', 'string', False) if (sum(lagflag) > 0): avglag = np.sum(lag) / sum(lagflag) angshift = avglag * wdelt print('The mean shift is {} Angstroms'.format(angshift)) else: angshift = 0.0 plt.close() else: angshift = shift fig = plt.figure(figsize=[9, 5]) telluric_done = False bstartmpcopy = bstartmp.copy() while (not telluric_done): print('Applying a shift of {} Angstroms'.format(angshift)) bstartmp = bstartmpcopy.copy() tmp = womscipyrebin(wave + angshift, bstartmp, wave) bstartmp = tmp.copy() bstartmp = bstartmp**((airmass / bairmass)**0.55) # newobject=object/bstartmp newobject = spectrum / bstartmp bvar = variance / bstartmp print('\nPlotting before and after atmospheric band correction\n') plt.cla() # ymin,ymax=finalscaler(object) # plt.plot(wave,object,drawstyle='steps-mid',color='r') # plt.plot(wave,newobject,drawstyle='steps-mid',color='k') ymin, ymax = finalscaler(spectrum) plt.plot(wave, spectrum, drawstyle='steps-mid', color='r') plt.plot(wave, newobject, drawstyle='steps-mid', color='k') plt.ylim([ymin, ymax]) plt.pause(0.01) if not shift: print('Is this OK?') answer = yesno('y') if (answer == 'n'): angshift = inputter('Enter B-star shift in Angstroms: ', 'float', False) else: telluric_done = True else: check = inputter('Check plot [enter when done]: ', 'string', False) telluric_done = True plt.close() return newobject, bvar, angshift