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 womvelcho(hop): """select region of spectrum, put onto velocity scale""" import matplotlib.pyplot as plt import numpy as np import logging from tmath.wombat.inputter import inputter from tmath.wombat.womwaverange import womwaverange from tmath.wombat.womget_element import womget_element from tmath.wombat.womscipyrebin import womscipyrebin wave=hop[0].wave.copy() flux=hop[0].flux.copy() var=hop[0].var.copy() nwave,nflux,mode=womwaverange(wave,flux,'none') wavebindex=womget_element(wave,nwave[0]) waverindex=womget_element(wave,nwave[-1]) nvar=var[wavebindex:waverindex+1].copy() binvec=np.arange(len(nwave)) wavelog=np.log(nwave[0])+((np.log(nwave[-1])-np.log(nwave[0]))/len(nwave))*binvec wavelog=np.exp(wavelog) fluxlog=womscipyrebin(nwave,nflux,wavelog) varlog=womscipyrebin(nwave,nvar,wavelog) zp=wavelog[0]-1.0 while (zp < wavelog[0]) or (zp > wavelog[-1]): zp=inputter('Enter the zero point for velocity (in angstroms): ','float',False) indexzp=womget_element(wavelog, zp) print(' ') logging.info('Zero at bin {}'.format(indexzp)) logging.info('with lambda {}'.format(wavelog[indexzp])) print(' ') z=(wavelog - zp)/zp square=(z+1)*(z+1) wavekmsrel=((square-1.)/(square+1.))*299792.458 kmsperbin=np.zeros(len(nwave)) for i in range(1,len(nwave)): kmsperbin[i]=2.0*2.99792458e5*(wavelog[i]-wavelog[i-1])/\ (wavelog[i]+wavelog[i-1]) kmsmean=np.mean(kmsperbin[1:]) logging.info('Average km/s per bin: {}'.format(kmsmean)) logging.info('km/s at bin 1: {}'.format(kmsperbin[1])) logging.info('km/s at bin n: {}'.format(kmsperbin[-1])) print(' ') wavekms=kmsmean*binvec+kmsmean/2.0 indexzp=womget_element(wavekms,zp) wavekms=wavekms-wavekms[indexzp] hop[0].wave=wavekmsrel.copy() hop[0].flux=fluxlog.copy() hop[0].var=varlog.copy() return hop
def mkfluxstar(fluxfile, gratcode): import pdb 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.womscipyrebin import womscipyrebin 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.finalscaler import finalscaler from tmath.pydux.abcalc import abcalc 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('Flux 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) #extinction terms from Allen, 3rd edition extwave= [2400.,2600.,2800.,3000.,3200.,3400.,3600.,3800., \ 4000.,4500.,5000.,5500.,6000.,6500.,7000.,8000., \ 9000.,10000.,12000.,14000.] extvals=[68.0,89.0,36.0,4.5,1.30,0.84,0.68,0.55,0.46,0.31, \ 0.23,0.195,0.170,0.126,0.092,0.062,0.048,0.039, \ 0.028,0.021] fitsfile = fits.open(fluxfile) 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']) head = pacheck(head) if (exptime < 1): exptime = 1. 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 (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 flux 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'): star = rawdata[0, ap_choice, :] else: star = rawdata[1, ap_choice, :] # fix IRAF weirdness where data can go negative in dispcor interpolation star[np.where(star < 0)] = 0.01 wave = wavearr[:, ap_choice] extinction = womscipyrebin(extwave, extvals, wave) extfactor = np.exp(extinction * sitefactor * airmass) star = star * extfactor abcurve = abcalc(wave, objectname) wdata = 10.0**(0.4 * abcurve) fstar = star * wdata / exptime print('Now 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(fstar), (airmass > airlimit), fig) splineresult = 10**(splineresult) plt.cla() plt.plot(wave, splineresult, drawstyle='steps-mid') plt.pause(0.01) 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 head.set('CRPIX1', 1) head.set('CRVAL1', wave[0]) head.set('CDELT1', wave[1] - wave[0]) head.set('CTYPE1', 'LINEAR') head.set('FLUXFILE', fluxfile) outfile = 'fluxstar' + gratcode + '.fits' print('Writing data to {}'.format(outfile)) outhdu = fits.PrimaryHDU(splineresult) hdul = fits.HDUList([outhdu]) hdul[0].header = head.copy() hdul.writeto(outfile, overwrite=True) print('mkfluxstar') print(fluxfile, gratcode) return
def calibrate(objectlist, gratcode, secondord, gratcode2): from astropy.io import fits import numpy as np from tmath.wombat.getmswave import getmswave from tmath.wombat.womscipyrebin import womscipyrebin from tmath.pydux.obs_extinction import obs_extinction #extinction terms from Allen, 3rd edition extwave= [2400.,2600.,2800.,3000.,3200.,3400.,3600.,3800., \ 4000.,4500.,5000.,5500.,6000.,6500.,7000.,8000., \ 9000.,10000.,12000.,14000.] extvals=[68.0,89.0,36.0,4.5,1.30,0.84,0.68,0.55,0.46,0.31, \ 0.23,0.195,0.170,0.126,0.092,0.062,0.048,0.039, \ 0.028,0.021] fluxfits = fits.open('fluxstar' + gratcode + '.fits') fluxstar = fluxfits[0].data fluxhead = fluxfits[0].header fluxwavezero = float(fluxhead['CRVAL1']) fluxwavedelt = float(fluxhead['CDELT1']) fluxwave = np.arange(len(fluxstar)) * fluxwavedelt + fluxwavezero fluxairmass = float(fluxhead['AIRMASS']) fluxname = fluxhead['OBJECT'] try: fluxnum = int(fluxhead['OBSNUM']) except KeyError: fluxnum = 0 if (secondord): fluxfits2 = fits.open('fluxstar' + gratcode2 + '.fits') fluxstar2 = fluxfits[0].data fluxhead2 = fluxfits[0].header fluxwavezero2 = float(fluxhead2['CRVAL1']) fluxwavedelt2 = float(fluxhead2['CDELT1']) fluxwave2 = np.arange(len(fluxstar2)) * fluxwavedelt2 + fluxwavezero2 fluxairmass2 = float(fluxhead2['AIRMASS']) fluxname2 = fluxhead2['OBJECT'] try: fluxnum2 = int(fluxhead2['OBSNUM']) except KeyError: fluxnum2 = 0 observat = fluxhead['OBSERVAT'].strip().lower() sitefactor = obs_extinction(observat) infile = open(objectlist, 'r') for msfile in infile: msfile = msfile.strip() if ('.fits' not in msfile): msfile = msfile + '.fits' multifits = fits.open(msfile) multispec = multifits[0].data mshead = multifits[0].header objectname = mshead['OBJECT'] print('The object is: {}'.format(objectname)) airmass = float(mshead['AIRMASS']) exptime = float(mshead['EXPTIME']) if (exptime < 1): exptime = 1.0 num_apertures = multispec.shape[1] num_bands = multispec.shape[0] wavearr = np.zeros((multispec.shape[2], multispec.shape[1])) if (secondord): multispec2 = multispec.copy() mshead2 = mshead.copy() for i in range(0, num_apertures): print('\nAperture {}:'.format(i + 1)) wave = getmswave(mshead, i) extinction = womscipyrebin(extwave, extvals, wave) extfactor = np.exp(extinction * sitefactor * airmass) fluxstartmp = womscipyrebin(fluxwave, fluxstar, wave) wdelt = wave[1] - wave[0] for j in range(0, num_bands): multispec[j, i, :] = multispec[j, i, :] * extfactor #extinction multispec[j, i, :] = multispec[j, i, :] / fluxstartmp #flux multispec[j, i, :] = multispec[j, i, :] / exptime #adjust to time multispec[j, i, :] = multispec[j, i, :] * 10**(-19.44) #AB->fnu multispec[j, i, :] = multispec[ j, i, :] * 2.99792458e18 / wave / wave #fnu->flm if (secondord): fluxstartmp2 = womscipyrebin(fluxwave2, fluxstar2, wave) for j in range(0, num_bands): multispec2[ j, i, :] = multispec2[j, i, :] * extfactor #extinction multispec2[j, i, :] = multispec2[j, i, :] / fluxstartmp #flux multispec2[ j, i, :] = multispec2[j, i, :] / exptime #adjust to time multispec2[j, i, :] = multispec2[j, i, :] * 10**( -19.44) #AB->fnu multispec2[j, i, :] = multispec2[ j, i, :] * 2.99792458e18 / wave / wave #fnu->flm msfile = 'c' + gratcode + msfile mshead.set('FLUX_Z', fluxairmass, 'airmass of flux standard') mshead.set('FLUX_NUM', fluxnum, 'obsnum of flux standard') mshead.set('FLUX_OBJ', fluxname, 'id of flux standard') outhdu = fits.PrimaryHDU(multispec) hdul = fits.HDUList([outhdu]) hdul[0].header = mshead.copy() hdul.writeto(msfile, overwrite=True) hdul.close() if (secondord): msfile = 'c' + gratcode2 + msfile mshead2.set('FLX2_Z', fluxairmass, 'airmass of flux second ord. standard') mshead2.set('FLX2_NUM', fluxnum, 'obsnum of flux second ord. standard') mshead2.set('FLX2_OBJ', fluxname, 'id of flux second ord. standard') outhdu = fits.PrimaryHDU(multispec2) hdul = fits.HDUList([outhdu]) hdul[0].header = mshead2.copy() hdul.writeto(msfile2, overwrite=True) hdul.close() infile.close() fluxfits.close() if (secondord): fluxfits2.close() print('calibrate') print(objectlist, gratcode, secondord, gratcode2) return
def abcalc(wave, objectname): # creates ab curve to flux standard stars # TM 11/21/98 # EVALUATES AB(NU) MAGNITUDES FOR THE FLUX STAR SPECIFIED BY IDNO. # # IDNO = 1 FOR HD 19445 # 2 FOR HD 84937 # 3 FOR BD +26 2606 # 4 FOR BD +17 4708 # 5 FOR HD 140283 # 6 FOR GD-248 # 7 FOR G158-100 # 8 FOR LTT 1788 # 9 FOR LTT 377 # 10 FOR HZ 4 # 11 FOR HZ 7 # 12 FOR ROSS 627 # 13 FOR LDS 235B # 14 FOR G99-37 # 15 FOR LB 227 # 16 FOR L745-46A # 17 FOR FEIGE 24 # 18 FOR G60-54 # 19 FOR G24-9 # 20 FOR BD+28 4211 # 21 FOR G191B2B # 22 FOR G157-34 # 23 FOR G138-31 # 24 FOR HZ 44 # 25 FOR LTT 9491 # 26 FOR FEIGE 100 # 27 FOR FEIGE 34 # 28 FOR LTT 1020 # 29 FOR LTT 9239 # 30 FOR HILTNER 600 (APPROXIMATE) # 31 FOR BD+25 3941 (APPROXIMATE) # 32 FOR BD+33 2642 (APPROXIMATE) # 33 FOR FEIGE 56 (APPROXIMATE) # 34 FOR G193-74 # 35 FOR eg145 # 36 for FEIGE 25 # 37 for PG0823+546 # 38 for HD 217086 # 39 for HZ 14 # 40 for FEIGE 66 # # NUMBERS 25--29 WERE ADDED ON 2 AUGUST 1987# NUMBER 8 WAS # MODIFIED SLIGHTLY (UP TO 0.11 MAG) NEAR THE H-K BREAK. # # NUMBERS 30 AND 31 WERE ADDED ON 24 JANUARY 1988# NUMBERS # ARE ONLY APPROXIMATE NEAR THE BALMER LIMIT, LONGWARD OF # 8100 A, AND SHORTWARD OF 3300 A. DITTO FOR NUMBER 32, # WHI#H WAS ADDED ON 2 MAY 1988. DITTO FOR NUMBER 33, WHICH # WAS ADDED ON 25 AUGUST 1991. # THERE ARE 41 WAVELENGTHS. # INTERPOLATION IN THIS TABLE SHOULD APPROXIMATE THE MONOCHROMATIC # CONTINUUM FLUX DISTRIBUTION OF THE MCSP STANDARD STARS. # SYSTEMATIC ERRORS AS LARGE AS 5% MAY OCCUR NEAR THE CONVERGENCE # OF THE BALMER SERIES, WHERE THE CONTINUUM IS NOT WELL DEFINED. # NO ATTEMPT IS MADE TO FOLLOW THE WINGS OF THE BALMER LINES, # A PROCEDURE WHICH SEEMS DANGEROUS AT BEST. # # NOTE THAT ALEX FILIPPENKO HAS MODIFIED ALL AB MAGNITUDES SO # THAT ABSORPTION LINES ARE INTERPOLATED OVER SMOOTHLY. THIS # MEANS THAT MCSP STANDARDS AND OTHERS CANNOT BE USED IN THE # MANNER USED BEFORE (THAT IS, SUMMING ALL COUNTS IN 40-ANG # BANDPASSES AND COMPARING WITH TABULATED VALUES). # import numpy as np from tmath.wombat.inputter import inputter from tmath.wombat.womscipyrebin import womscipyrebin idstar = 0 while (idstar < 1) or (idstar > 56): print('The object is {}'.format(objectname)) print(' ') print(' WHICH STANDARD STAR IS THIS ?') print(' ORIGINAL MCSP FLUX STANDARDS (AB79 SCALE): ') print(' (1) HD 19445 (2) HD 84937 (3) BD+262606') print(' (4) BD+17 4708 (5) HD 140283 (SOMEWHAT OBSOLETE)') print(' OTHERS (AB69, AB79, STONE, OR BALDWIN/STONE SCALE): ') print(' (6) GD-248 (AB79) (7) G158-100 (AB79)') print(' (8) LTT 1788 (B/S) (9) LTT 377 (B/S)') print(' (10) HZ 4 (~AB79) (11) HZ 7 (~AB79)') print(' (12) ROSS 627 (~AB79) (13) LDS 235B (~AB79)') print(' (14) G99-37 (~AB79) (15) LB 227 (~AB79)') print(' (16) L745-46A (~AB79) (17) FEIGE 24 (~AB79)') print(' (18) G60-54 (~AB79) (19) G24-9 (AB79)') print(' (20) BD+28 4211 (STONE) (21) G191B2B (~AB79)') print(' (22) G157-34 (AB79) (23) G138-31 (AB79)') print(' (24) HZ 44 (~AB79) (25) LTT 9491 (B/S)') print(' (26) FEIGE 110 (STONE) (27) FEIGE 34 (STONE)') print(' (28) LTT 1020 (B/S) (29) LTT 9239 (B/S)') print(' (30) HILTNER 600 (STONE) (31) BD+25 3941 (STONE)') print(' (32) BD+33 2642 (STONE) (33) FEIGE 56 (STONE)') print(' (34) G193-74 (AB79) (35) EG145 (OKE,74) ') print(' (36) FEIGE 25 (STONE) (37) PG0823+546 ') print(' (38) HD 217086 (39) HZ 14 ') print(' (40) FEIGE 66 (41) Feige 67 (Groot special) ') print(' (42) LTT 377 (43) LTT 2415 ') print(' (44) LTT 4364 (45) Feige 15') print(' (46) Hiltner 102 (lousy) (47) LTT 3864 ') print(' (48) LTT 3218 (49) CYG OB2 ') print(' (50) VMa 2 (51) GD 71 ') print(' (52) HZ 43 (53) LTT 7379') print(' (54) LTT 7987 (55) GD 153 ') print(' (56) CD32D9927 ') idstar = inputter('Star number? ', 'int', False) # All numbers from lolita's abcalc.f, we trust that they are ok waveab = [3080.0, 3160.0, 3240.0, 3320.0, 3400.0, 3480.0, 3560.0, \ 3640.0, 3680.0, 3720.0, 3760.0, 3780.0, 3820.0, 3860.0, \ 4020.0, 4200.0, 4400.0, 4560.0, 4760.0, 5000.0, 5120.0, \ 5240.0, 5400.0, 5560.0, 5760.0, 6020.0, 6420.0, 6780.0, \ 7100.0, 7460.0, 7780.0, 8100.0, 8380.0, 8780.0, 9300.0, \ 9700.0, 9940.0,10260.0,10820.0,11140.0,12000.0] ab = np.zeros((41, 57)) ab[:, 1] = [9.476, 9.391, 9.310, 9.232, 9.168, 9.103, 9.039, \ 8.979, 8.945, 8.919, 8.849, 8.814, 8.762, 8.695, \ 8.483, 8.385, 8.293, 8.235, 8.180, 8.118, 8.081, \ 8.048, 8.014, 7.982, 7.948, 7.908, 7.862, 7.837, \ 7.812, 7.790, 7.776, 7.760, 7.759, 7.755, 7.752, \ 7.752, 7.752, 7.752, 7.760, 7.760, 7.763] ab[:, 2] = [9.677, 9.610, 9.542, 9.480, 9.422, 9.370, 9.310, \ 9.269, 9.243, 9.205, 9.099, 9.018, 8.926, 8.850, \ 8.650, 8.548, 8.496, 8.448, 8.400, 8.351, 8.332, \ 8.315, 8.290, 8.266, 8.237, 8.202, 8.174, 8.150, \ 8.133, 8.125, 8.123, 8.112, 8.111, 8.115, 8.119, \ 8.123, 8.130, 8.137, 8.150, 8.160, 8.180] ab[:, 3] = [11.155, 11.072, 10.998, 10.935, 10.866, 10.806, \ 10.750, 10.698, 10.670, 10.651, 10.540, 10.480, \ 10.400, 10.320, 10.120, 10.021, 9.955, 9.908, 9.843, \ 9.768, 9.741, 9.719, 9.693, 9.660, 9.630, 9.594, \ 9.552, 9.527, 9.502, 9.485, 9.474, 9.463, 9.457, \ 9.457, 9.458, 9.458, 9.461, 9.462, 9.468, 9.473, \ 9.488] ab[:, 4] = [10.955, 10.872, 10.798, 10.718, 10.663, 10.601, \ 10.536, 10.487, 10.452, 10.426, 10.307, 10.268, \ 10.190, 10.110, 9.880, 9.765, 9.690, 9.637, 9.573, \ 9.520, 9.491, 9.465, 9.434, 9.405, 9.374, 9.337, \ 9.294, 9.262, 9.233, 9.216, 9.211, 9.200, 9.194, \ 9.194, 9.195, 9.195, 9.198, 9.199, 9.205, 9.210, \ 9.225] ab[:, 5] = [9.050, 8.820, 8.630, 8.520, 8.430, 8.360, 8.300, \ 8.230, 8.200, 8.160, 8.050, 7.990, 7.915, 7.870, \ 7.680, 7.560, 7.470, 7.420, 7.340, 7.260, 7.230, \ 7.210, 7.170, 7.120, 7.080, 7.040, 6.975, 6.930, \ 6.890, 6.860, 6.840, 6.830, 6.810, 6.800, 6.810, \ 6.840, 6.860, 6.880, 6.890, 6.900, 6.910] ab[:, 6] = [15.295, 15.262, 15.229, 15.200, 15.178, 15.163, \ 15.150, 15.138, 15.133, 15.127, 15.122, 15.119, \ 15.113, 15.108, 15.090, 15.071, 15.058, 15.052, \ 15.050, 15.056, 15.063, 15.070, 15.081, 15.093, \ 15.110, 15.133, 15.175, 15.212, 15.245, 15.283, \ 15.318, 15.353, 15.384, 15.427, 15.484, 15.528, \ 15.554, 15.592, 15.652, 15.688, 15.775] ab[:, 7] = [16.725, 16.665, 16.591, 16.502, 16.400, 16.292, \ 16.183, 16.082, 16.034, 15.986, 15.938, 15.914, \ 15.868, 15.824, 15.651, 15.490, 15.346, 15.246, \ 15.139, 15.027, 14.979, 14.932, 14.872, 14.824, \ 14.768, 14.696, 14.609, 14.537, 14.485, 14.430, \ 14.393, 14.361, 14.338, 14.310, 14.281, 14.261, \ 14.248, 14.233, 14.209, 14.199, 14.178] ab[:, 8] = [14.785, 14.637, 14.492, 14.348, 14.214, 14.113, \ 14.025, 13.946, 13.911, 13.880, 13.840, 13.818, \ 13.780, 13.737, 13.626, 13.524, 13.440, 13.380, \ 13.310, 13.237, 13.195, 13.166, 13.136, 13.100, \ 13.062, 13.020, 12.976, 12.949, 12.925, 12.898, \ 12.874, 12.850, 12.833, 12.815, 12.809, 12.808, \ 12.804, 12.800, 12.794, 12.790, 12.781] ab[:, 9] = [13.180, 13.030, 12.890, 12.660, 12.610, 12.580, \ 12.530, 12.460, 12.375, 12.300, 12.230, 12.200, \ 12.130, 12.020, 11.775, 11.630, 11.570, 11.500, \ 11.390, 11.360, 11.325, 11.285, 11.235, 11.190, \ 11.170, 11.150, 11.085, 11.060, 11.040, 11.035, \ 11.020, 10.985, 10.980, 10.970, 10.965, 10.960, \ 10.960, 10.960, 10.960, 10.960, 10.960] ab[:, 10] = [14.660, 14.670, 14.680, 14.690, 14.710, 14.730, \ 14.750, 14.780, 14.800, 14.820, 14.800, 14.770, \ 14.770, 14.720, 14.470, 14.360, 14.310, 14.330, \ 14.380, 14.430, 14.450, 14.480, 14.520, 14.550, \ 14.590, 14.640, 14.740, 14.840, 14.900, 15.000, \ 15.080, 15.170, 15.170, 15.170, 15.170, 15.170, \ 15.170, 15.170, 15.170, 15.170, 15.170] ab[:, 11] = [13.910, 13.930, 13.940, 13.960, 13.990, 14.010, \ 14.035, 14.060, 14.080, 14.100, 14.090, 14.080, \ 14.080, 14.060, 13.880, 13.850, 13.900, 13.970, \ 14.040, 14.100, 14.135, 14.170, 14.210, 14.280, \ 14.340, 14.400, 14.530, 14.630, 14.710, 14.800, \ 14.880, 14.970, 14.970, 14.970, 14.970, 14.970, \ 14.970, 14.970, 14.970, 14.970, 14.970] ab[:, 12] = [15.080, 14.970, 14.880, 14.825, 14.760, 14.710, \ 14.652, 14.640, 14.620, 14.600, 14.570, 14.550, \ 14.540, 14.530, 14.440, 14.350, 14.280, 14.250, \ 14.220, 14.170, 14.138, 14.120, 14.100, 14.070, \ 14.045, 14.020, 14.010, 14.005, 13.995, 13.993, \ 13.991, 13.990, 13.990, 13.990, 13.990, 13.990, \ 13.990, 13.990, 13.990, 13.990, 13.990] ab[:, 13] = [15.410, 15.400, 15.390, 15.390, 15.380, 15.380, \ 15.390, 15.410, 15.420, 15.430, 15.430, 15.420, \ 15.410, 15.400, 15.390, 15.415, 15.440, 15.460, \ 15.500, 15.540, 15.560, 15.570, 15.600, 15.610, \ 15.630, 15.680, 15.760, 15.850, 15.910, 15.980, \ 16.060, 16.140, 16.210, 16.310, 16.390, 16.540, \ 16.620, 16.620, 16.620, 16.620, 16.620] ab[:, 14] = [15.795, 15.710, 15.580, 15.490, 15.390, 15.310, \ 15.220, 15.185, 15.162, 15.140, 15.110, 15.080, \ 15.050, 15.030, 14.900, 14.810, 14.710, 14.670, \ 14.610, 14.520, 14.488, 14.460, 14.440, 14.400, \ 14.360, 14.320, 14.300, 14.290, 14.285, 14.285, \ 14.290, 14.300, 14.310, 14.320, 14.330, 14.360, \ 14.380, 14.380, 14.380, 14.380, 14.380] ab[:, 15] = [15.270, 15.295, 15.310, 15.320, 15.360, 15.400, \ 15.415, 15.460, 15.483, 15.490, 15.500, 15.515, \ 15.530, 15.530, 15.200, 15.050, 15.000, 15.020, \ 15.090, 15.154, 15.177, 15.215, 15.260, 15.300, \ 15.355, 15.410, 15.530, 15.630, 15.700, 15.807, \ 15.910, 16.010, 16.010, 16.010, 16.010, 16.010, \ 16.010, 16.010, 16.010, 16.010, 16.010] ab[:, 16] = [13.820, 13.730, 13.600, 13.520, 13.420, 13.350, \ 13.300, 13.280, 13.270, 13.265, 13.250, 13.230, \ 13.210, 13.190, 13.130, 13.070, 13.010, 13.005, \ 12.985, 12.940, 12.922, 12.920, 12.895, 12.880, \ 12.860, 12.843, 12.850, 12.870, 12.880, 12.900, \ 12.920, 12.940, 12.960, 12.990, 13.020, 13.060, \ 13.090, 13.090, 13.090, 13.090, 13.090] ab[:, 17] = [11.540, 11.565, 11.580, 11.640, 11.680, 11.730, \ 11.760, 11.830, 11.870, 11.890, 11.920, 11.930, \ 11.950, 11.970, 11.990, 12.010, 12.076, 12.135, \ 12.210, 12.290, 12.345, 12.338, 12.380, 12.393, \ 12.415, 12.450, 12.435, 12.414, 12.375, 12.330, \ 12.310, 12.280, 12.255, 12.210, 12.160, 12.115, \ 12.100, 12.070, 12.070, 12.070, 12.070] ab[:, 18] = [17.749, 17.659, 17.562, 17.460, 17.359, 17.250, \ 17.146, 17.049, 17.006, 16.945, 16.902, 16.881, \ 16.828, 16.785, 16.610, 16.436, 16.285, 16.173, \ 16.068, 15.960, 15.900, 15.860, 15.800, 15.740, \ 15.680, 15.620, 15.550, 15.508, 15.480, 15.460, \ 15.450, 15.440, 15.435, 15.430, 15.427, 15.423, \ 15.425, 15.430, 15.435, 15.440, 15.456] ab[:, 19] = [16.780, 16.740, 16.692, 16.634, 16.570, 16.502, \ 16.431, 16.363, 16.330, 16.300, 16.271, 16.256, \ 16.229, 16.202, 16.105, 16.020, 15.940, 15.887, \ 15.829, 15.776, 15.757, 15.740, 15.718, 15.700, \ 15.681, 15.659, 15.632, 15.615, 15.604, 15.594, \ 15.586, 15.582, 15.581, 15.586, 15.598, 15.609, \ 15.617, 15.628, 15.649, 15.662, 15.695] ab[:, 20] = [9.500, 9.510, 9.530, 9.560, 9.600, 9.649, 9.695, \ 9.736, 9.758, 9.772, 9.791, 9.800, 9.820, 9.833, \ 9.920, 10.011, 10.107, 10.186, 10.261, 10.363, \ 10.406, 10.449, 10.518, 10.582, 10.660, 10.730, \ 10.850, 10.937, 11.023, 11.110, 11.165, 11.216, \ 11.268, 11.310, 11.360, 11.400, 11.427, 11.450, \ 11.485, 11.500, 11.530] ab[:, 21] = [10.750, 10.790, 10.839, 10.883, 10.925, 10.966, \ 11.011, 11.052, 11.069, 11.089, 11.106, 11.111, \ 11.129, 11.143, 11.206, 11.283, 11.369, 11.429, \ 11.508, 11.600, 11.642, 11.686, 11.750, 11.815, \ 11.888, 11.980, 12.114, 12.225, 12.312, 12.408, \ 12.488, 12.562, 12.634, 12.726, 12.842, 12.915, \ 12.955, 12.998, 13.061, 13.090, 13.148] ab[:, 22] = [15.889, 15.853, 15.808, 15.766, 15.728, 15.698, \ 15.670, 15.643, 15.630, 15.618, 15.605, 15.599, \ 15.586, 15.573, 15.524, 15.478, 15.437, 15.415, \ 15.393, 15.372, 15.365, 15.358, 15.351, 15.349, \ 15.350, 15.354, 15.364, 15.373, 15.383, 15.397, \ 15.413, 15.434, 15.455, 15.487, 15.530, 15.566, \ 15.587, 15.617, 15.673, 15.705, 15.785] ab[:, 23] = [17.252, 17.190, 17.124, 17.060, 17.000, 16.950, \ 16.891, 16.841, 16.817, 16.793, 16.769, 16.757, \ 16.732, 16.706, 16.609, 16.515, 16.423, 16.359, \ 16.288, 16.220, 16.194, 16.170, 16.141, 16.119, \ 16.099, 16.078, 16.055, 16.041, 16.031, 16.024, \ 16.023, 16.025, 16.028, 16.033, 16.041, 16.047, \ 16.051, 16.058, 16.070, 16.078, 16.095] ab[:, 24] = [10.737, 10.773, 10.804, 10.830, 10.868, 10.897, \ 10.930, 10.959, 10.978, 10.989, 11.002, 11.010, \ 11.029, 11.045, 11.107, 11.163, 11.233, 11.290, \ 11.359, 11.442, 11.478, 11.516, 11.566, 11.616, \ 11.680, 11.773, 11.905, 12.023, 12.120, 12.235, \ 12.321, 12.400, 12.468, 12.540, 12.637, 12.709, \ 12.760, 12.819, 12.909, 12.954, 13.061] ab[:, 25] = [14.156, 14.137, 14.118, 14.099, 14.080, 14.062, \ 14.045, 14.030, 14.023, 14.017, 14.012, 14.009, \ 14.005, 14.002, 13.996, 13.997, 14.003, 14.011, \ 14.026, 14.053, 14.066, 14.079, 14.096, 14.113, \ 14.139, 14.173, 14.212, 14.261, 14.321, 14.380, \ 14.412, 14.436, 14.450, 14.462, 14.467, 14.469, \ 14.471, 14.475, 14.481, 14.485, 14.496] ab[:, 26] = [10.883, 10.922, 10.960, 10.998, 11.031, 11.065, \ 11.102, 11.138, 11.154, 11.171, 11.187, 11.195, \ 11.210, 11.226, 11.283, 11.350, 11.438, 11.505, \ 11.588, 11.681, 11.723, 11.764, 11.822, 11.879, \ 11.937, 12.014, 12.146, 12.236, 12.321, 12.415, \ 12.487, 12.539, 12.585, 12.650, 12.735, 12.800, \ 12.839, 12.892, 12.983, 13.035, 13.176] ab[:, 27] = [10.126, 10.165, 10.204, 10.242, 10.283, 10.324, \ 10.367, 10.409, 10.428, 10.446, 10.463, 10.471, \ 10.487, 10.502, 10.568, 10.653, 10.750, 10.824, \ 10.920, 11.024, 11.070, 11.116, 11.179, 11.241, \ 11.311, 11.406, 11.551, 11.653, 11.721, 11.796, \ 11.852, 11.892, 11.920, 11.960, 12.011, 12.051, \ 12.075, 12.106, 12.162, 12.194, 12.279] ab[:, 28] = [13.481, 13.272, 13.063, 12.872, 12.730, 12.617, \ 12.528, 12.461, 12.430, 12.399, 12.365, 12.348, \ 12.313, 12.276, 12.131, 11.991, 11.858, 11.775, \ 11.700, 11.626, 11.594, 11.564, 11.522, 11.477, \ 11.428, 11.379, 11.304, 11.260, 11.233, 11.192, \ 11.158, 11.133, 11.113, 11.082, 11.061, 11.056, \ 11.056, 11.057, 11.058, 11.058, 11.059] ab[:, 29] = [14.338, 14.094, 13.850, 13.625, 13.455, 13.330, \ 13.225, 13.134, 13.093, 13.053, 13.016, 12.997, \ 12.962, 12.926, 12.772, 12.605, 12.460, 12.364, \ 12.264, 12.179, 12.140, 12.101, 12.051, 12.008, \ 11.964, 11.913, 11.839, 11.784, 11.740, 11.696, \ 11.675, 11.646, 11.631, 11.599, 11.566, 11.553, \ 11.549, 11.548, 11.547, 11.546, 11.544] ab[:, 30] = [11.010, 10.970, 10.930, 10.850, 10.830, 10.810, \ 10.800, 10.790, 10.780, 10.750, 10.720, 10.680, \ 10.580, 10.500, 10.470, 10.460, 10.460, 10.450, \ 10.450, 10.440, 10.430, 10.430, 10.420, 10.420, \ 10.430, 10.440, 10.480, 10.500, 10.520, 10.550, \ 10.570, 10.590, 10.610, 10.640, 10.670, 10.700, \ 10.720, 10.740, 10.780, 10.800, 10.860] ab[:, 31] = [12.190, 12.110, 12.060, 11.950, 11.850, 11.790, \ 11.740, 11.660, 11.630, 11.580, 11.500, 11.450, \ 11.350, 11.260, 11.160, 11.070, 10.990, 10.870, \ 10.790, 10.690, 10.590, 10.500, 10.410, 10.360, \ 10.320, 10.280, 10.210, 10.130, 10.070, 10.020, \ 9.980, 9.960, 9.970, 9.980, 9.990, 10.000, 10.010, \ 10.020, 10.030, 10.040, 10.050] ab[:, 32] = [10.780, 10.730, 10.670, 10.628, 10.641, 10.663, \ 10.688, 10.700, 10.687, 10.656, 10.585, 10.546, \ 10.483, 10.434, 10.456, 10.516, 10.573, 10.617, \ 10.672, 10.746, 10.777, 10.802, 10.840, 10.882, \ 10.930, 10.991, 11.080, 11.132, 11.169, 11.219, \ 11.249, 11.312, 11.415, 11.511, 11.623, 11.730, \ 11.799, 11.890, 12.028, 12.098, 12.283] ab[:, 33] = [11.510, 11.450, 11.332, 11.290, 11.270, 11.270, \ 11.288, 11.290, 11.290, 11.250, 11.125, 11.020, \ 10.900, 10.830, 10.700, 10.764, 10.820, 10.845, \ 10.902, 10.980, 11.010, 11.035, 11.070, 11.110, \ 11.144, 11.205, 11.307, 11.375, 11.430, 11.518, \ 11.593, 11.648, 11.690, 11.750, 11.890, 11.960, \ 12.015, 12.090, 12.210, 12.280, 12.420] ab[:, 34] = [16.350, 16.300, 16.263, 16.195, 16.160, 16.100, \ 16.070, 16.025, 16.010, 15.980, 15.960, 15.958, \ 15.930, 15.890, 15.858, 15.807, 15.737, 15.732, \ 15.702, 15.670, 15.648, 15.635, 15.624, 15.613, \ 15.600, 15.587, 15.582, 15.583, 15.589, 15.602, \ 15.619, 15.633, 15.649, 15.682, 15.752, 15.825, \ 15.860, 15.940, 16.020, 16.080, 16.250] ab[:, 35] = [14.50, 14.50, 14.41, 14.45, 14.42, 14.45, 14.44, \ 14.49, 14.46, 14.49, 14.47, 14.53, 14.60, 14.58, \ 14.55, 14.49, 14.53, 14.53, 14.56, 14.66, 14.67, \ 14.63, 14.68, 14.70, 14.77, 14.83, 14.86, 14.97, \ 14.99, 15.07, 15.12, 15.16, 15.20, 15.27, 15.35, \ 15.44, 15.38, 15.36, 15.35, 15.34, 15.30] ab[:, 36] = [12.590, 12.590, 12.598, 12.556, 12.540, 12.494, \ 12.515, 12.509, 12.497, 12.427, 12.270, 12.192, \ 12.035, 11.878, 11.752, 11.768, 11.815, 11.830, \ 11.883, 11.950, 11.959, 11.968, 11.989, 12.010, \ 12.024, 12.080, 12.189, 12.209, 12.240, 12.288, \ 12.340, 12.361, 12.400, 12.400, 12.400, 12.400, \ 12.400, 12.400, 12.400, 12.400, 12.400] ab[:, 37] = [13.5600, 13.5600, 13.4400, 13.4600, 13.5800, 13.5760, \ 13.5480, 13.6440, 13.6780, 13.6900, 13.7000, 13.7200, \ 13.7480, 13.7680, 13.8420, 13.9500, 14.0000, 14.1100, \ 14.1540, 14.2500, 14.3040, 14.3260, 14.3900, 14.3660, \ 14.4340, 14.5520, 14.6627, 14.7020, 14.7900, 14.8200, \ 14.8780, 14.9218, 14.9320, 14.8800, 14.9777, 15.0173, \ 15.0647, 15.1137, 15.1137, 15.1137, 15.1137] ab[:, 38] = [8.95000, 8.95000, 8.87000, 8.73600, 8.65000, 8.62000, \ 8.52800, 8.49600, 8.47800, 8.46200, 8.43400, 8.40200, \ 8.35400, 8.32600, 8.22000, 8.15000, 8.08000, 7.96400, \ 7.88800, 7.79000, 7.70800, 7.61600, 7.58000, 7.48000, \ 7.45400, 7.39600, 7.34200, 7.23422, 7.20000, 7.15864, \ 7.11746, 7.09000, 7.09000, 7.09000, 7.09000, 7.09000, \ 7.09000, 7.09000, 7.09000, 7.09000, 7.09000] ab[:, 39] = [13.3800, 13.3800, 13.3912, 13.3576, 13.3700, 13.3724, \ 13.3819, 13.3912, 13.3959, 13.4007, 13.4054, 13.4077, \ 13.4123, 13.4170, 13.4360, 13.4600, 13.5064, 13.5620, \ 13.6630, 13.7901, 13.8228, 13.8848, 13.9700, 14.0092, \ 14.1128, 14.1708, 14.3481, 14.4030, 14.5000, 14.5856, \ 14.5978, 14.6716, 14.6716, 14.6716, 14.6716, 14.6716, \ 14.6716, 14.6716, 14.6716, 14.6716, 14.6716] ab[:,40]= [9.71000, 9.71000, 9.69960, 9.71940, 9.75000, 9.78720, \ 9.80216, 9.81480, 9.82124, 9.82851, 9.83550, 9.83918, \ 9.84723, 9.85676, 9.89451, 9.96000, 10.0500, 10.1132, \ 10.2140, 10.3200, 10.3714, 10.4180, 10.4700, 10.5340, \ 10.6116, 10.7332, 10.9026, 10.9693, 11.0300, 11.1424, \ 11.2164, 11.2752, 11.3143, 11.2954, 11.4150, 11.5300, \ 11.6312, 11.7700, 11.7700, 11.7700, 11.7700] ab[:, 41] = [10.7060, 10.7060, 10.7070, 10.8412, 10.8751, 10.9346, \ 10.9988, 11.0508, 11.0876, 11.1117, 11.1198, 11.1309, \ 11.1536, 11.1253, 11.1920, 11.2856, 11.3744, 11.4628, \ 11.5659, 11.6423, 11.6924, 11.7352, 11.8133, 11.8565, \ 11.9284, 12.0111, 12.1394, 12.2520, 12.3412, 12.4391, \ 12.5198, 12.5946, 12.6563, 12.7585, 12.8850, 12.8850, \ 12.8850, 12.8850, 12.8850, 12.8850, 12.8850] ab[:, 42] = [12.6650, 12.6650, 12.6650, 12.6689, 12.6060, 12.5745, \ 12.4804, 12.3900, 12.3252, 12.2909, 12.2230, 12.1593, \ 12.0765, 12.0277, 11.7515, 11.6150, 11.5000, 11.4408, \ 11.3709, 11.3090, 11.2841, 11.2483, 11.2300, 11.1848, \ 11.1531, 11.1270, 11.0906, 11.0527, 11.0500, 11.0405, \ 11.0333, 11.0334, 11.0415, 11.0607, 11.0660, 11.0623, \ 11.0590, 11.0628, 11.1040, 11.1040, 11.1040] ab[:, 43] = [13.4480, 13.4480, 13.4480, 13.4304, 13.3760, 13.3201, \ 13.2367, 13.1485, 13.1038, 13.0542, 12.9668, 12.9094, \ 12.8061, 12.7308, 12.5630, 12.4730, 12.4300, 12.3768, \ 12.3296, 12.2690, 12.2535, 12.2343, 12.2000, 12.1752, \ 12.1656, 12.1231, 12.0979, 12.0637, 12.0610, 12.0447, \ 12.0358, 12.0350, 12.0426, 12.0589, 12.0848, 12.0996, \ 12.1069, 12.1220, 12.1220, 12.1220, 12.1220] ab[:, 44] = [11.9290, 11.9290, 11.9290, 11.9046, 11.8710, 11.8479, \ 11.8000, 11.7477, 11.7263, 11.7090, 11.6945, 11.6854, \ 11.6673, 11.6534, 11.6223, 11.5960, 11.5740, 11.5590, \ 11.5371, 11.5154, 11.5068, 11.5009, 11.5000, 11.5009, \ 11.5019, 11.5053, 11.5110, 11.5168, 11.5520, 11.5775, \ 11.5920, 11.6202, 11.6513, 11.6907, 11.7590, 11.8070, \ 11.8338, 11.8690, 11.8690, 11.8690, 11.8690] ab[:, 45] = [11.7000, 11.7000, 11.6640, 11.5452, 11.5300, 11.5080, \ 11.4916, 11.3878, 10.6773, 10.2642, 10.2610, 10.2566, \ 10.2443, 10.2311, 10.1995, 10.2156, 10.2294, 10.2487, \ 10.2753, 10.3380, 10.3431, 10.3561, 10.3827, 10.4104, \ 10.4257, 10.4725, 10.5476, 10.5986, 10.6300, 10.6840, \ 10.7300, 10.7407, 10.7600, 10.7600, 10.7600, 10.7600, \ 10.7600, 10.7600, 10.7600, 10.7600, 10.7600] ab[:, 46] = [11.9800, 11.9800, 11.9368, 11.7878, 11.7300, 11.6804, \ 11.6335, 11.5881, 11.5662, 11.5266, 11.4671, 11.4369, \ 11.3756, 11.3132, 11.2430, 11.1481, 11.0673, 10.9546, \ 10.8776, 10.7300, 10.6385, 10.5474, 10.4362, 10.3487, \ 10.2950, 10.2300, 10.1340, 10.0134, 9.93000, 9.87329, \ 9.81000, 9.73858, 9.72000, 9.72000, 9.72000, 9.72000, \ 9.72000, 9.72000, 9.72000, 9.72000, 9.72000] ab[:, 47] = [13.7300, 13.7300, 13.6836, 13.5524, 13.3700, 13.3659, \ 13.2409, 13.0914, 13.0160, 12.9800, 12.9800, 12.9800, \ 12.9312, 12.8542, 12.6721, 12.5692, 12.4777, 12.4015, \ 12.3132, 12.2700, 12.2428, 12.1974, 12.1997, 12.1187, \ 12.0558, 12.0370, 11.9921, 11.9808, 11.9500, 11.9355, \ 11.9100, 11.8901, 11.8895, 11.8679, 11.8612, 11.8664, \ 11.8605, 11.8813, 11.9400, 11.9400, 11.9400] ab[:, 48] = [12.4400, 12.4400, 12.3899, 12.3234, 12.3017, 12.2882, \ 12.2779, 12.2677, 12.2625, 12.2733, 12.2800, 12.2691, \ 12.1489, 11.9884, 11.9632, 11.8777, 11.8386, 11.8197, \ 11.8198, 11.8300, 11.8369, 11.8437, 11.8516, 11.8599, \ 11.8679, 11.8826, 11.9407, 11.9594, 11.9600, 12.0066, \ 12.0400, 12.0421, 12.1004, 12.1041, 12.1510, 12.2075, \ 12.2522, 12.3002, 12.3000, 12.3000, 12.3000] ab[:, 49] = [15.1000, 15.1000, 15.0400, 14.9527, 14.8300, 14.5632, \ 14.3972, 14.2112, 14.1330, 14.0266, 13.9064, 13.8616, \ 13.7702, 13.6812, 13.4022, 13.0700, 12.7400, 12.3942, \ 12.1244, 11.7000, 11.4582, 11.2224, 11.0100, 10.6924, \ 10.4476, 10.1932, 9.86280, 9.46970, 9.21000, 9.01880, \ 8.80220, 8.55000, 8.55000, 8.55000, 8.55000, 8.55000, \ 8.55000, 8.55000, 8.55000, 8.55000, 8.55000] ab[:, 50] = [14.1000, 14.1000, 14.1000, 13.9600, 13.7600, 13.5200, \ 13.4500, 13.3600, 13.2671, 13.2056, 13.1505, 13.1267, \ 13.0874, 13.0555, 12.9277, 12.8200, 12.6900, 12.5800, \ 12.5000, 12.4500, 12.4100, 12.4200, 12.4100, 12.3600, \ 12.3556, 12.3556, 12.3100, 12.3000, 12.2756, 12.2987, \ 12.3100, 12.2544, 12.2514, 12.3034, 12.2867, 12.2867, \ 12.3830, 12.3622, 12.3500, 12.3500, 12.3500] ab[:,51] = [12.194600, 12.228300, 12.270300, 12.321600, 12.354300, \ 12.393000, 12.426700, 12.465400, 12.479000, 12.496700, \ 12.515500, 12.523100, 12.534000, 12.538500, 12.523600, \ 12.551700, 12.626000, 12.682800, 12.769200, 12.860300, \ 12.903400, 12.945100, 12.996200, 13.052800, 13.126000, \ 13.209800, 13.338300, 13.440400, 13.530800, 13.625200, \ 13.706700, 13.789400, 13.856400, 13.955600, 14.046900, \ 14.128700, 14.173900, 14.244800, 14.352100, 14.404500, \ 14.556200] ab[:,52]= [11.890830, 11.953902, 12.001304, 12.038769, 12.068400, \ 12.117474, 12.158472, 12.193123, 12.204728, 12.247052, \ 12.256253, 12.264238, 12.288051, 12.299415, 12.346685, \ 12.400056, 12.476015, 12.550985, 12.628268, 12.718414, \ 12.767287, 12.800667, 12.874192, 12.927598, 13.002908, \ 13.089129, 13.226055, 13.322492, 13.418968, 13.513610, \ 13.603105, 13.685889, 13.728714, 13.841738, 13.964003, \ 14.030111, 14.105518, 14.132800, 14.132800, 14.132800, \ 14.132800] ab[:,53]=[ 11.850000, 11.850000, 11.850000, 11.862280, 11.753000, \ 11.710168, 11.583240, 11.455560, 11.391720, 11.327880, \ 11.264040, 11.232120, 11.168280, 11.104440, 10.878012, \ 10.764100, 10.590400, 10.528520, 10.427080, 10.354000, \ 10.322270, 10.293700, 10.238000, 10.182120, 10.128600, \ 10.090520, 10.032000, 9.9762198, 9.9617100, 9.9360398, \ 9.9185802, 9.9072905, 9.9031467, 9.9140937, 9.9183197, \ 9.9221601, 9.9244636, 9.9169998, 9.9169998, 9.9169998, \ 9.9169998] ab[:,54]=[12.373000, 12.373000, 12.373000, 12.356440, 12.367000, \ 12.397760, 12.395280, 12.386800, 12.403720, 12.419600, \ 12.422360, 12.421640, 12.412320, 12.403216, 12.223200, \ 11.962500, 11.955000, 11.989480, 12.050820, 12.113800, \ 12.140126, 12.165320, 12.207000, 12.247120, 12.309800, \ 12.370320, 12.459800, 12.549230, 12.609700, 12.681920, \ 12.752000, 12.815400, 12.880920, 12.958500, 13.082100, \ 13.161000, 13.220040, 13.175000, 13.175000, 13.175000, \ 13.175000] ab[:,55] = [12.431100, 12.467100, 12.510300, 12.547300, 12.601100, \ 12.643000, 12.672900, 12.715400, 12.725200, 12.746000, \ 12.767500, 12.777500, 12.793400, 12.797200, 12.814100, \ 12.861100, 12.933300, 12.994100, 13.078300, 13.172600, \ 13.212700, 13.258900, 13.314200, 13.377200, 13.450300, \ 13.528800, 13.662500, 13.764600, 13.859700, 13.955800, \ 14.044400, 14.125700, 14.184500, 14.283600, 14.377200, \ 14.483600, 14.542900, 14.592500, 14.699500, 14.761600, \ 14.911200] ab[:,56]=[12.024000, 12.024000, 12.024000, 12.010360, 11.966999, \ 11.948019, 11.845119, 11.752359, 11.703140, 11.617559, \ 11.453240, 11.356260, 11.181759, 11.091120, 10.767380, \ 10.643000, 10.570000, 10.488140, 10.471140, 10.456500, \ 10.454224, 10.448364, 10.446000, 10.416080, 10.418639, \ 10.420500, 10.441330, 10.444580, 10.465000, 10.494888, \ 10.510241, 10.525400, 10.539100, 10.558599, 10.585599, \ 10.609200, 10.623360, 10.631999, 10.631999, 10.631999, \ 10.631999] # use scipy interp here as the very non-linear wavelength scale # precludes the use of womashrebin --- this is going finer anyway abcurve = womscipyrebin(waveab, ab[:, idstar], wave) return abcurve
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
def calibrate(objectlist, gratcode, secondord, gratcode2, answer_flux='y'): from astropy.io import fits import numpy as np import matplotlib.pyplot as plt import inspect from tmath.pydux.xcor import xcor from tmath.pydux.envelope import envelope from tmath.pydux.congrid import congrid from tmath.wombat.getmswave import getmswave from tmath.wombat.womscipyrebin import womscipyrebin from tmath.pydux.scipyrebinsky import scipyrebinsky from tmath.pydux.obs_extinction import obs_extinction from tmath.wombat.yesno import yesno from tmath.wombat.inputter import inputter from tmath.wombat.womget_element import womget_element from tmath.wombat.get_screen_size import get_screen_size #extinction terms from Allen, 3rd edition extwave= [2400.,2600.,2800.,3000.,3200.,3400.,3600.,3800., \ 4000.,4500.,5000.,5500.,6000.,6500.,7000.,8000., \ 9000.,10000.,12000.,14000.] extvals=[68.0,89.0,36.0,4.5,1.30,0.84,0.68,0.55,0.46,0.31, \ 0.23,0.195,0.170,0.126,0.092,0.062,0.048,0.039, \ 0.028,0.021] fluxfits = fits.open('fluxstar' + gratcode + '.fits') fluxstar = fluxfits[0].data fluxhead = fluxfits[0].header fluxwavezero = float(fluxhead['CRVAL1']) fluxwavedelt = float(fluxhead['CDELT1']) fluxwave = np.arange(len(fluxstar)) * fluxwavedelt + fluxwavezero fluxairmass = float(fluxhead['AIRMASS']) fluxname = fluxhead['OBJECT'] try: fluxnum = int(fluxhead['OBSNUM']) except KeyError: fluxnum = 0 if (secondord): fluxfits2 = fits.open('fluxstar' + gratcode2 + '.fits') fluxstar2 = fluxfits[0].data fluxhead2 = fluxfits[0].header fluxwavezero2 = float(fluxhead2['CRVAL1']) fluxwavedelt2 = float(fluxhead2['CDELT1']) fluxwave2 = np.arange(len(fluxstar2)) * fluxwavedelt2 + fluxwavezero2 fluxairmass2 = float(fluxhead2['AIRMASS']) fluxname2 = fluxhead2['OBJECT'] try: fluxnum2 = int(fluxhead2['OBSNUM']) except KeyError: fluxnum2 = 0 observat = fluxhead['OBSERVAT'].strip().lower() sitefactor = obs_extinction(observat) infile = open(objectlist, 'r') for msfile in infile: msfile = msfile.strip() if ('.fits' not in msfile): msfile = msfile + '.fits' multifits = fits.open(msfile) multispec = multifits[0].data mshead = multifits[0].header objectname = mshead['OBJECT'] print('The object is: {}'.format(objectname)) airmass = float(mshead['AIRMASS']) exptime = float(mshead['EXPTIME']) if (exptime < 1): exptime = 1.0 num_apertures = multispec.shape[1] num_bands = multispec.shape[0] wavearr = np.zeros((multispec.shape[2], multispec.shape[1])) if (secondord): multispec2 = multispec.copy() mshead2 = mshead.copy() for i in range(0, num_apertures): print('\nAperture {}:'.format(i + 1)) wave = getmswave(mshead, i) extinction = womscipyrebin(extwave, extvals, wave) extfactor = np.exp(extinction * sitefactor * airmass) fluxstartmp = womscipyrebin(fluxwave, fluxstar, wave) wdelt = wave[1] - wave[0] #TESTING applying shift before flux cal 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 PRELIMINARY master sky'.format( mskyfile.split('/')[-1])) 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 num_bands = multispec.shape[0] skyband = 2 if (num_bands == 2): skyband = 1 sky = multispec[skyband, i, :] envelope_size = 25 mx, mn = envelope(sky, envelope_size) skycont = congrid(mn, (len(sky), ), minusone=True) 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 # shift=xcor(msky[50:-50],sky[50:-50],xfactor,maxlag) if 'kast' in fluxhead.get('VERSION', ''): shift = xcor(msky[50:-50], sky[50:-50], xfactor, maxlag) else: shift = xcor(msky, sky, xfactor, maxlag) angshift = shift * wdelt print( 'Potential preliminary shift of {} angstroms'.format(angshift)) print('Obj wave without shift: ', wave[0]) #The following code applies the calculated shift prior to fitting the flux star #If the target is an object then the object is shifted prior to applying the flux star # answer_flux = input('Is this a master standard star? y/[n]: ') or 'n' # if answer_flux == 'y': # fluxwave=fluxwave+angshift # wave = wave+angshift # #Testing only for standard star # skyshiftdone=False # while (not skyshiftdone): # print('Is this ok?') # answer=yesno('y') # if (answer == 'n'): # #undo shifts # if answer_flux == 'y': # fluxwave=fluxwave-angshift # wave = wave-angshift # angshift=inputter('Enter desired shift in Angstroms: ','float',False) # if answer_flux == 'y': # fluxwave=fluxwave+angshift # wave = wave+angshift # else: # skyshiftdone = True ## # skyshiftdone=False # npixsky2=len(sky)//2 # 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) # fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id) # msky_max = np.max(msky[npixsky2-1:]) # sky_max = np.max(sky[npixsky2-1:]) # scale = sky_max/msky_max # while (not skyshiftdone): # plt.clf() # axarr=fig.subplots(2) # # fig.subplots_adjust(hspace=0) # waveplus=wave-angshift # 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'): # if answer_flux == 'y': # fluxwave=fluxwave-angshift # wave=wave- angshift # angshift=inputter('Enter desired shift in Angstroms: ','float',False) # if answer_flux == 'y': # fluxwave=fluxwave+angshift # wave=wave+angshift # else: # skyshiftdone = True # plt.close() # print ('Obj wave with shift: ', wave[0]) # mshead.set('CRVAL1', wave[0]) # mshead.set('CDELT1', wave[1] - wave[0]) # print ('Fluxwave start', fluxwave[0]) if answer_flux == 'y': print('Changing Flux Star Wavelength') fluxhead.set('CRVAL1', fluxwave[0]) fluxhead.set('CDELT1', fluxwave[1] - fluxwave[0]) outfile = 'fluxstar' + gratcode + '.fits' print('Updating wavelength data to {}'.format(outfile)) outhdu = fits.PrimaryHDU(fluxstar) hdul = fits.HDUList([outhdu]) hdul[0].header = fluxhead.copy() hdul.writeto(outfile, overwrite=True) # fluxfits=fits.open(outfile) # fluxstar=fluxfits[0].data # fluxhead=fluxfits[0].header # fluxwavezero=float(fluxhead['CRVAL1']) # print (fluxwavezero) fluxstartmp = womscipyrebin(fluxwave, fluxstar, wave) ######################################## #testing # mx1=womget_element(wave,5500) # mx2=womget_element(wave,6050) # fx1=womget_element(fluxwave,5500) # fx2=womget_element(fluxwave,5050) mx1 = 0 mx2 = 300 fx1 = 0 fx2 = 300 # mx1=-1000 # mx2=-50 # fx1=-1000 # fx2=-50 test = extfactor[mx1:mx2] * multispec[0, i, :][mx1:mx2] scale1 = 1. / np.median(test) scale2 = 1. / np.median(fluxstartmp[fx1:fx2]) # print (xcor(scale1*multispec[0,i,:][mx1:mx2],scale2*fluxstar[fx1:fx2],10,200)) fig = plt.figure() plt.clf() plt.plot(wave[mx1:mx2], scale1 * test, drawstyle='steps-mid', color='r') plt.plot(fluxwave[fx1:fx2], scale2 * fluxstar[fx1:fx2], drawstyle='steps-mid', color='k') plt.pause(0.01) check = inputter('Check plot [enter when done]: ', 'string', False) plt.close() # for j in range(0, num_bands): multispec[j, i, :] = multispec[j, i, :] * extfactor #extinction multispec[j, i, :] = multispec[j, i, :] / fluxstartmp #flux multispec[j, i, :] = multispec[j, i, :] / exptime #adjust to time multispec[j, i, :] = multispec[j, i, :] * 10**(-19.44) #AB->fnu multispec[j, i, :] = multispec[ j, i, :] * 2.99792458e18 / wave / wave #fnu->flm if (secondord): fluxstartmp2 = womscipyrebin(fluxwave2, fluxstar2, wave) for j in range(0, num_bands): multispec2[ j, i, :] = multispec2[j, i, :] * extfactor #extinction multispec2[j, i, :] = multispec2[j, i, :] / fluxstartmp #flux multispec2[ j, i, :] = multispec2[j, i, :] / exptime #adjust to time multispec2[j, i, :] = multispec2[j, i, :] * 10**( -19.44) #AB->fnu multispec2[j, i, :] = multispec2[ j, i, :] * 2.99792458e18 / wave / wave #fnu->flm msfile = 'c' + gratcode + msfile mshead.set('FLUX_Z', fluxairmass, 'airmass of flux standard') mshead.set('FLUX_NUM', fluxnum, 'obsnum of flux standard') mshead.set('FLUX_OBJ', fluxname, 'id of flux standard') outhdu = fits.PrimaryHDU(multispec) hdul = fits.HDUList([outhdu]) hdul[0].header = mshead.copy() hdul.writeto(msfile, overwrite=True) hdul.close() if (secondord): msfile = 'c' + gratcode2 + msfile mshead2.set('FLX2_Z', fluxairmass, 'airmass of flux second ord. standard') mshead2.set('FLX2_NUM', fluxnum, 'obsnum of flux second ord. standard') mshead2.set('FLX2_OBJ', fluxname, 'id of flux second ord. standard') outhdu = fits.PrimaryHDU(multispec2) hdul = fits.HDUList([outhdu]) hdul[0].header = mshead2.copy() hdul.writeto(msfile2, overwrite=True) hdul.close() infile.close() fluxfits.close() if (secondord): fluxfits2.close() print('calibrate') print(objectlist, gratcode, secondord, gratcode2) return