def show(self, item, slit=None): """ Show one of the class internals Args: item (str): 'spec' -- Show the fitted points and solution; requires slit 'fit' -- Show fit QA; requires slit slit (int, optional): Returns: """ if item == 'spec': # spec spec = self.wv_calib[str(slit)]['spec'] # tcent tcent = self.wv_calib[str(slit)]['tcent'] yt = np.zeros_like(tcent) for jj, t in enumerate(tcent): it = int(np.round(t)) yt[jj] = np.max(spec[it - 1:it + 1]) # Plot plt.clf() ax = plt.gca() ax.plot(spec, drawstyle='steps-mid') ax.scatter(tcent, yt, color='red', marker='*') ax.set_xlabel('Pixel') ax.set_ylabel('Counts') plt.show() elif item == 'fit': autoid.arc_fit_qa(self.wv_calib[str(slit)])
def build_wv_calib(self, arccen, method, skip_QA=False): """ Main routine to generate the wavelength solutions in a loop over slits Wrapper to arc.simple_calib or arc.calib_with_arclines self.maskslits is updated for slits that fail Args: method : str 'simple' -- arc.simple_calib 'arclines' -- arc.calib_with_arclines 'holy-grail' -- wavecal.autoid.HolyGrail 'reidentify' -- wavecal.auotid.ArchiveReid 'full_template' -- wavecal.auotid.full_template skip_QA (bool, optional) Returns: dict: self.wv_calib """ # Obtain a list of good slits ok_mask = np.where(~self.maskslits)[0] # Obtain calibration for all slits if method == 'simple': lines = self.par['lamps'] line_lists = waveio.load_line_lists(lines) self.wv_calib = arc.simple_calib_driver( self.msarc, line_lists, arccen, ok_mask, nfitpix=self.par['nfitpix'], IDpixels=self.par['IDpixels'], IDwaves=self.par['IDwaves']) elif method == 'semi-brute': # TODO: THIS IS CURRENTLY BROKEN debugger.set_trace() final_fit = {} for slit in ok_mask: # HACKS BY JXP self.par['wv_cen'] = 8670. self.par['disp'] = 1.524 # ToDO remove these hacks and use the parset in semi_brute best_dict, ifinal_fit \ = autoid.semi_brute(arccen[:, slit], self.par['lamps'], self.par['wv_cen'], self.par['disp'], match_toler=self.par['match_toler'], func=self.par['func'], n_first=self.par['n_first'], sigrej_first=self.par['n_first'], n_final=self.par['n_final'], sigrej_final=self.par['sigrej_final'], sigdetect=self.par['sigdetect'], nonlinear_counts= self.nonlinear_counts) final_fit[str(slit)] = ifinal_fit.copy() elif method == 'basic': final_fit = {} for slit in ok_mask: status, ngd_match, match_idx, scores, ifinal_fit = \ autoid.basic(arccen[:, slit], self.par['lamps'], self.par['wv_cen'], self.par['disp'], nonlinear_counts=self.nonlinear_counts) final_fit[str(slit)] = ifinal_fit.copy() if status != 1: self.maskslits[slit] = True elif method == 'holy-grail': # Sometimes works, sometimes fails arcfitter = autoid.HolyGrail(arccen, par=self.par, ok_mask=ok_mask) patt_dict, final_fit = arcfitter.get_results() elif method == 'reidentify': # Now preferred # Slit positions arcfitter = autoid.ArchiveReid(arccen, self.spectrograph, self.par, ok_mask=ok_mask, slit_spat_pos=self.slit_spat_pos) patt_dict, final_fit = arcfitter.get_results() elif method == 'full_template': # Now preferred if self.binspectral is None: msgs.error( "You must specify binspectral for the full_template method!" ) final_fit = autoid.full_template(arccen, self.par, ok_mask, self.det, self.binspectral, nsnippet=self.par['nsnippet']) else: msgs.error( 'Unrecognized wavelength calibration method: {:}'.format( method)) self.wv_calib = final_fit # Remake mask (*mainly for the QA that follows*) self.maskslits = self.make_maskslits(len(self.maskslits)) ok_mask = np.where(~self.maskslits)[0] # QA if not skip_QA: for slit in ok_mask: outfile = qa.set_qa_filename(self.master_key, 'arc_fit_qa', slit=slit, out_dir=self.qa_path) autoid.arc_fit_qa(self.wv_calib[str(slit)], outfile=outfile) # Return self.steps.append(inspect.stack()[0][3]) return self.wv_calib
def build_wv_calib(self, arccen, method, skip_QA=False): """ Main routine to generate the wavelength solutions in a loop over slits Wrapper to arc.simple_calib or arc.calib_with_arclines self.maskslits is updated for slits that fail Args: method : str 'simple' -- arc.simple_calib 'arclines' -- arc.calib_with_arclines 'holy-grail' -- wavecal.autoid.HolyGrail 'reidentify' -- wavecal.auotid.ArchiveReid 'identify' -- wavecal.identify.Identify 'full_template' -- wavecal.auotid.full_template skip_QA (bool, optional) Returns: dict: self.wv_calib """ # Obtain a list of good slits ok_mask = np.where(np.invert(self.maskslits))[0] # Obtain calibration for all slits if method == 'simple': lines = self.par['lamps'] line_lists = waveio.load_line_lists(lines) final_fit = arc.simple_calib_driver( line_lists, arccen, ok_mask, n_final=self.par['n_final'], sigdetect=self.par['sigdetect'], IDpixels=self.par['IDpixels'], IDwaves=self.par['IDwaves']) elif method == 'semi-brute': # TODO: THIS IS CURRENTLY BROKEN embed() final_fit = {} for slit in ok_mask: # HACKS BY JXP self.par['wv_cen'] = 8670. self.par['disp'] = 1.524 # ToDO remove these hacks and use the parset in semi_brute best_dict, ifinal_fit \ = autoid.semi_brute(arccen[:, slit], self.par['lamps'], self.par['wv_cen'], self.par['disp'], match_toler=self.par['match_toler'], func=self.par['func'], n_first=self.par['n_first'], sigrej_first=self.par['n_first'], n_final=self.par['n_final'], sigrej_final=self.par['sigrej_final'], sigdetect=self.par['sigdetect'], nonlinear_counts= self.nonlinear_counts) final_fit[str(slit)] = ifinal_fit.copy() elif method == 'basic': final_fit = {} for slit in ok_mask: status, ngd_match, match_idx, scores, ifinal_fit = \ autoid.basic(arccen[:, slit], self.par['lamps'], self.par['wv_cen'], self.par['disp'], nonlinear_counts=self.nonlinear_counts) final_fit[str(slit)] = ifinal_fit.copy() if status != 1: self.maskslits[slit] = True elif method == 'holy-grail': # Sometimes works, sometimes fails arcfitter = autoid.HolyGrail(arccen, par=self.par, ok_mask=ok_mask) patt_dict, final_fit = arcfitter.get_results() elif method == 'identify': final_fit = {} # Manually identify lines msgs.info("Initializing the wavelength calibration tool") # TODO: Move this loop to the GUI initalise method embed() for slit in ok_mask: arcfitter = gui_identify.initialise(arccen, slit=slit, par=self.par) final_fit[str(slit)] = arcfitter.get_results() if final_fit[str(slit)] is not None: ans = 'y' # ans = '' # while ans != 'y' and ans != 'n': # ans = input("Would you like to store this wavelength solution in the archive? (y/n): ") if ans == 'y' and final_fit[str( slit)]['rms'] < self.par['rms_threshold']: # Store the results in the user reid arxiv specname = self.spectrograph.spectrograph gratname = "UNKNOWN" # input("Please input the grating name: ") dispangl = "UNKNOWN" # input("Please input the dispersion angle: ") templates.pypeit_identify_record( final_fit[str(slit)], self.binspectral, specname, gratname, dispangl) msgs.info("Your wavelength solution has been stored") msgs.info( "Please consider sending your solution to the PYPEIT team!" ) elif method == 'reidentify': # Now preferred # Slit positions arcfitter = autoid.ArchiveReid(arccen, self.spectrograph, self.par, ok_mask=ok_mask, slit_spat_pos=self.slit_spat_pos) patt_dict, final_fit = arcfitter.get_results() elif method == 'full_template': # Now preferred if self.binspectral is None: msgs.error( "You must specify binspectral for the full_template method!" ) final_fit = autoid.full_template(arccen, self.par, ok_mask, self.det, self.binspectral, nsnippet=self.par['nsnippet']) else: msgs.error( 'Unrecognized wavelength calibration method: {:}'.format( method)) self.wv_calib = final_fit # Remake mask (*mainly for the QA that follows*) self.maskslits = self.make_maskslits(len(self.maskslits)) ok_mask = np.where(np.invert(self.maskslits))[0] # QA if not skip_QA: for slit in ok_mask: outfile = qa.set_qa_filename(self.master_key, 'arc_fit_qa', slit=slit, out_dir=self.qa_path) autoid.arc_fit_qa(self.wv_calib[str(slit)], outfile=outfile) # Return self.steps.append(inspect.stack()[0][3]) return self.wv_calib
def main(flg): # Keck LRISb if flg & (2**0): # B300, all lamps binspec = 1 slits = [15] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B300', 'lris_blue_300.sav') outroot = 'keck_lris_blue_300_d680.fits' build_template(xidl_file, slits, None, binspec, outroot, lowredux=True) if flg & (2**1): # B400, all lamps I think) binspec = 2 outroot='keck_lris_blue_400_d560.fits' slits = [19,14] lcut = [5500.] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B400', 'lris_blue_400_d560.sav') build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) if flg & (2**2): # B600, all lamps binspec = 2 outroot='keck_lris_blue_600_d560.fits' slits = [0,7] lcut = [4500.] wfile = os.path.join(template_path, 'Keck_LRIS', 'B600', 'MasterWaveCalib_A_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**3): # B1200, all lamps? binspec = 2 outroot='keck_lris_blue_1200_d460.fits' slits = [19,44] lcut = [3700.] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B1200', 'lris_blue_1200.sav') build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) # Shane Kastb if flg & (2**4): # 452/3306 binspec = 1 slits = [0] xidl_file = os.path.join(template_path, 'Shane_Kast', '452_3306', 'kast_452_3306.sav') outroot = 'shane_kast_blue_452.fits' build_template(xidl_file, slits, None, binspec, outroot, lowredux=True) if flg & (2**5): # 600/4310 binspec = 1 slits = [0,3] lcut = [4550.] xidl_file = os.path.join(template_path, 'Shane_Kast', '600_4310', 'kast_600_4310.sav') outroot = 'shane_kast_blue_600.fits' build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) if flg & (2**6): # 830/3460 binspec = 1 slits = [0] xidl_file = os.path.join(template_path, 'Shane_Kast', '830_3460', 'kast_830_3460.sav') outroot = 'shane_kast_blue_830.fits' build_template(xidl_file, slits, None, binspec, outroot, lowredux=True) # Keck/DEIMOS if flg & (2**7): # 600ZD :: Might not go red enough binspec = 1 slits = [0,1] lcut = [7192.] xidl_file = os.path.join(template_path, 'Keck_DEIMOS', '600ZD', 'deimos_600.sav') outroot = 'keck_deimos_600.fits' build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) if flg & (2**8): # 830G binspec = 1 outroot='keck_deimos_830G.fits' # 3-12 = blue 6508 -- 8410 # 7-24 = blue 8497 -- 9925 (no lines after XeI) ifiles = [0, 0, 1] slits = [12, 14, 24] lcut = [8400., 8480] wfile1 = os.path.join(template_path, 'Keck_DEIMOS', '830G_M_8600', 'MasterWaveCalib_A_1_03.json') wfile2 = os.path.join(template_path, 'Keck_DEIMOS', '830G_M_8600', 'MasterWaveCalib_A_1_07.json') # det_dict det_cut = {} det_cut['dets'] = [[1,2,3,4], [5,6,7,8]] det_cut['wcuts'] = [[0,9000.], [8200,1e9]] # Significant overlap is fine # build_template([wfile1,wfile2], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles, det_cut=det_cut) if flg & (2**9): # 1200 binspec = 1 outroot='keck_deimos_1200G.fits' # 3-3 = blue 6268.23 -- 7540 # 3-14 = red 6508 -- 7730 # 7-3 = blue 7589 -- 8821 # 7-17 = red 8000 - 9230 # 7c-0 = red 9120 -- 9950 ifiles = [0, 0, 1, 1, 2] slits = [3, 14, 3, 17, 0] lcut = [7450., 7730., 8170, 9120] wfile1 = os.path.join(template_path, 'Keck_DEIMOS', '1200G', 'MasterWaveCalib_A_1_03.json') wfile2 = os.path.join(template_path, 'Keck_DEIMOS', '1200G', 'MasterWaveCalib_A_1_07.json') wfile3 = os.path.join(template_path, 'Keck_DEIMOS', '1200G', 'MasterWaveCalib_A_1_07c.json') # det_dict det_cut = None #det_cut = {} #det_cut['dets'] = [[1,2,3,4], [5,6,7,8]] #det_cut['wcuts'] = [[0,9000.], [8200,1e9]] # Significant overlap is fine # build_template([wfile1,wfile2,wfile3], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles, det_cut=det_cut, chk=True) # ###############################################3 # Keck/LRISr if flg & (2**10): # R400 binspec = 2 outroot='keck_lris_red_400.fits' slits = [7] # Quite blue, but not the bluest lcut = [] wfile = os.path.join(template_path, 'Keck_LRIS', 'R400', 'MasterWaveCalib_A_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**11): # R1200 # slits = [2-3] # 7726 -- 9250 # slits = [1-4] # 9250 -- 9925 binspec = 1 outroot='keck_lris_red_1200_9000.fits' ifiles = [0, 1] slits = [3, 7] lcut = [9250.] wfile1 = os.path.join(template_path, 'Keck_LRIS', 'R1200_9000', 'MasterWaveCalib_A_1_02.json') # Original Dev wfile2 = os.path.join(template_path, 'Keck_LRIS', 'R1200_9000', 'MasterWaveCalib_A_1_01.json') # Dev suite 2x1 build_template([wfile1,wfile2], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles) if flg & (2**12): # R600/5000 # slits = [1-4] # 5080 -- 7820 # slits = [1-7] # 7820 -- 9170 binspec = 2 outroot='keck_lris_red_600_5000.fits' slits = [4, 7] lcut = [7820.] wfile = os.path.join(template_path, 'Keck_LRIS', 'R600_5000', 'MasterWaveCalib_B_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**27): # R600/7500 # slits = [1-10] # 5000 -- 7840 # slits = [1-4] # 7840 -- 9230 binspec = 2 outroot='keck_lris_red_600_7500.fits' slits = [10, 4] lcut = [7840.] wfile = os.path.join(template_path, 'Keck_LRIS', 'R600_7500', 'MasterWaveCalib_I_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False, chk=True, normalize=True, subtract_conti=True) # ################################## # Magellan/MagE if flg & (2**13): # Load mase_path = os.path.join(os.getenv('XIDL_DIR'), 'Magellan', 'MAGE', 'mase', 'Calib') sav_file = os.path.join(mase_path, 'MagE_wvguess_jfh.idl') mase_dict = readsav(sav_file) mase_sol = Table(mase_dict['all_arcfit']) # Do it all_wave = np.zeros((2048, 15)) all_flux = np.zeros_like(all_wave) for order in np.arange(15): all_flux[:,order] = mase_dict['sv_aspec'][order] # Build the wavelengths wv_air = cheby_val(mase_sol['FFIT'][order], np.arange(2048), mase_sol['NRM'][order], mase_sol['NORD'][order]) all_wave[:,order] = airtovac(wv_air * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = np.arange(20, 5, -1, dtype=int) tbl.meta['BINSPEC'] = 1 # Write outroot='magellan_mage.fits' outfile = os.path.join(template_path, outroot) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**14): # Magellan/MagE Plots outpath = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'plots') new_mage_file = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv', 'magellan_mage.fits') # Load mage_wave = Table.read(new_mage_file) llist = waveio.load_line_lists(['ThAr_MagE']) # for kk in range(mage_wave['wave'].shape[1]): wv = mage_wave['wave'][:, kk] fx = mage_wave['flux'][:, kk] order = 20 - kk # Reidentify detections, spec_cont_sub, patt_dict = autoid.reidentify(fx, fx, wv, llist, 1) # Fit final_fit = fitting.fit_slit(fx, patt_dict, detections, llist) # Output outfile=os.path.join(outpath, 'MagE_order{:2d}_IDs.pdf'.format(order)) autoid.arc_fit_qa(final_fit, outfile=outfile, ids_only=True) print("Wrote: {}".format(outfile)) autoid.arc_fit_qa(final_fit, outfile=os.path.join(outpath, 'MagE_order{:2d}_full.pdf'.format(order))) if flg & (2**15): # VLT/X-Shooter reid_arxiv # VIS reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') for iroot, iout in zip(['vlt_xshooter_vis1x1.json', 'vlt_xshooter_nir.json'], ['vlt_xshooter_vis1x1.fits', 'vlt_xshooter_nir.fits']): # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk,order in enumerate(orders): all_flux[:,kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:,kk] = odict[str(kk)]['wave_soln'] else: all_wave[:,kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**16): # VLT/X-Shooter line list line_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'lists') old_file = os.path.join(line_path, 'ThAr_XSHOOTER_VIS_air_lines.dat') # Load air_list = waveio.load_line_list(old_file) # Vacuum vac_wv = airtovac(air_list['wave']*units.AA).value vac_list = air_list.copy() vac_list['wave'] = vac_wv # Write new_file = os.path.join(line_path, 'ThAr_XSHOOTER_VIS_lines.dat') vac_list.write(new_file, format='ascii.fixed_width', overwrite=True) print("Wrote: {}".format(new_file)) if flg & (2**17): # NIRES reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'keck_nires.json' iout = 'keck_nires.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk,order in enumerate(orders): all_flux[:,kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:,kk] = odict[str(kk)]['wave_soln'] else: all_wave[:,kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**18): # Gemini/GNIRS reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'gemini_gnirs.json' iout = 'gemini_gnirs.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk,order in enumerate(orders): all_flux[:,kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:,kk] = odict[str(kk)]['wave_soln'] else: all_wave[:,kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) # ############################## if flg & (2**20): # GMOS R400 Hamamatsu binspec = 2 outroot='gemini_gmos_r400_ham.fits' # ifiles = [0, 1, 2, 3, 4] slits = [0, 2, 3, 0, 0] # Be careful with the order.. lcut = [5400., 6620., 8100., 9000.] wfile1 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_01_aa.json') wfile5 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_05_aa.json') # 5190 -- 6679 #wfile2 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_02_aa.json') wfile3 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_04_aa.json') wfile4 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_03_aa.json') wfile6 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_06_aa.json') # build_template([wfile1,wfile5,wfile3,wfile4, wfile6], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles, chk=True, normalize=True, subtract_conti=True) # ############################## if flg & (2**21): # GMOS R400 E2V binspec = 2 outroot='gemini_gmos_r400_e2v.fits' # ifiles = [0, 1, 2] slits = [0, 0, 0] lcut = [6000., 7450] wfile1 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_1_01.json') wfile2 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_1_02.json') wfile3 = os.path.join(template_path, 'GMOS', 'R400', 'MasterWaveCalib_A_1_03.json') # build_template([wfile1,wfile2,wfile3], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles, chk=True, normalize=True) # ############################## if flg & (2**22): # GMOS R400 Hamamatsu binspec = 2 outroot='gemini_gmos_b600_ham.fits' # ifiles = [0, 1, 2, 3, 4] slits = [0, 0, 0, 0, 0] lcut = [4250., 4547., 5250., 5615.] wfile1 = os.path.join(template_path, 'GMOS', 'B600', 'MasterWaveCalib_C_1_01.json') wfile5 = os.path.join(template_path, 'GMOS', 'B600', 'MasterWaveCalib_D_1_01.json') # - 4547 wfile2 = os.path.join(template_path, 'GMOS', 'B600', 'MasterWaveCalib_C_1_02.json') wfile4 = os.path.join(template_path, 'GMOS', 'B600', 'MasterWaveCalib_D_1_02.json') # 4610-5608 wfile3 = os.path.join(template_path, 'GMOS', 'B600', 'MasterWaveCalib_C_1_03.json') # build_template([wfile1,wfile5,wfile2,wfile4,wfile3], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles, chk=True, normalize=True, subtract_conti=True, miny=-100.) if flg & (2**23): # WHT/ISIS iroot = 'wht_isis_blue_1200_4800.json' outroot = 'wht_isis_blue_1200_4800.fits' wfile = os.path.join(template_path, 'WHT_ISIS', '1200B', iroot) binspec = 2 slits = [0] lcut = [3200.] build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**24): # Magellan/FIRE reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'magellan_fire_echelle.json' iout = 'magellan_fire_echelle.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk,order in enumerate(orders): all_flux[:,kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:,kk] = odict[str(kk)]['wave_soln'] else: all_wave[:,kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**25): # FIRE longslit binspec = 1 reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') outroot = 'magellan_fire_long.fits' xidl_file = os.path.join(os.getenv('FIRE_DIR'), 'LowDispersion', 'NeNeAr_archive_fit.fits') spec_file = os.path.join(os.getenv('FIRE_DIR'), 'LowDispersion', 'NeNeAr2.sav') fire_sol = Table.read(xidl_file) wave = cheby_val(fire_sol['FFIT'].data[0], np.arange(2048), fire_sol['NRM'].data[0], fire_sol['NORD'].data[0]) wv_vac = airtovac(wave * units.AA) xidl_dict = readsav(spec_file) flux = xidl_dict['arc1d'] write_template(wv_vac.value, flux, binspec, reid_path, outroot, det_cut=None) # Gemini/Flamingos2 if flg & (2**26): reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = ['Flamingos2_JH_JH.json','Flamingos2_HK_HK.json'] outroot=['Flamingos2_JH_JH.fits','Flamingos2_HK_HK.fits'] binspec = 1 slits = [0] lcut = [] for ii in range(len(iroot)): wfile = os.path.join(reid_path, iroot[ii]) build_template(wfile, slits, lcut, binspec, outroot[ii], lowredux=False) # MDM/OSMOS -- MDM4K if flg & (2 ** 28): # ArI 4159 -- 6800 wfile = os.path.join(template_path, 'MDM_OSMOS', 'MasterWaveCalib_MDM4K_01.json') outroot = 'mdm_osmos_mdm4k.fits' binspec = 1 slits = [0] lcut = [3200.] build_template(wfile, slits, lcut, binspec, outroot, lowredux=False, chk=True, subtract_conti=True)
def build_wv_calib(self, arccen, method, skip_QA=False): """ Main routine to generate the wavelength solutions in a loop over slits Wrapper to arc.simple_calib or arc.calib_with_arclines self.maskslits is updated for slits that fail Args: method : str 'simple' -- arc.simple_calib 'arclines' -- arc.calib_with_arclines 'holy-grail' -- wavecal.autoid.HolyGrail 'reidentify' -- wavecal.auotid.ArchiveReid 'identify' -- wavecal.identify.Identify 'full_template' -- wavecal.auotid.full_template skip_QA (bool, optional) Returns: dict: self.wv_calib """ # Obtain a list of good slits ok_mask_idx = np.where(np.invert(self.wvc_bpm))[0] # Obtain calibration for all slits if method == 'simple': lines = self.par['lamps'] line_lists = waveio.load_line_lists(lines) final_fit = arc.simple_calib_driver( line_lists, arccen, ok_mask_idx, n_final=self.par['n_final'], sigdetect=self.par['sigdetect'], IDpixels=self.par['IDpixels'], IDwaves=self.par['IDwaves']) elif method == 'holy-grail': # Sometimes works, sometimes fails arcfitter = autoid.HolyGrail( arccen, par=self.par, ok_mask=ok_mask_idx, nonlinear_counts=self.nonlinear_counts) patt_dict, final_fit = arcfitter.get_results() elif method == 'identify': final_fit = {} # Manually identify lines msgs.info("Initializing the wavelength calibration tool") embed(header='line 222 wavecalib.py') for slit_idx in ok_mask_idx: arcfitter = Identify.initialise(arccen, self.slits, slit=slit_idx, par=self.par) final_fit[str(slit_idx)] = arcfitter.get_results() arcfitter.store_solution(final_fit[str(slit_idx)], "", self.binspectral, specname=self.spectrograph.name, gratname="UNKNOWN", dispangl="UNKNOWN") elif method == 'reidentify': # Now preferred # Slit positions arcfitter = autoid.ArchiveReid( arccen, self.spectrograph, self.par, ok_mask=ok_mask_idx, #slit_spat_pos=self.spat_coo, orders=self.orders, nonlinear_counts=self.nonlinear_counts) patt_dict, final_fit = arcfitter.get_results() elif method == 'full_template': # Now preferred if self.binspectral is None: msgs.error( "You must specify binspectral for the full_template method!" ) final_fit = autoid.full_template( arccen, self.par, ok_mask_idx, self.det, self.binspectral, nonlinear_counts=self.nonlinear_counts, nsnippet=self.par['nsnippet']) else: msgs.error( 'Unrecognized wavelength calibration method: {:}'.format( method)) # Build the DataContainer # Loop on WaveFit items tmp = [] for idx in range(self.slits.nslits): item = final_fit.pop(str(idx)) if item is None: # Add an empty WaveFit tmp.append(wv_fitting.WaveFit(self.slits.spat_id[idx])) else: # This is for I/O naming item.spat_id = self.slits.spat_id[idx] tmp.append(item) self.wv_calib = WaveCalib( wv_fits=np.asarray(tmp), arc_spectra=arccen, nslits=self.slits.nslits, spat_ids=self.slits.spat_id, PYP_SPEC=self.spectrograph.name, ) # Update mask self.update_wvmask() #TODO For generalized echelle (not hard wired) assign order number here before, i.e. slits.ech_order # QA if not skip_QA: ok_mask_idx = np.where(np.invert(self.wvc_bpm))[0] for slit_idx in ok_mask_idx: outfile = qa.set_qa_filename( self.master_key, 'arc_fit_qa', slit=self.slits.slitord_id[slit_idx], out_dir=self.qa_path) # #autoid.arc_fit_qa(self.wv_calib[str(self.slits.slitord_id[slit_idx])], # outfile=outfile) autoid.arc_fit_qa( self.wv_calib.wv_fits[slit_idx], #str(self.slits.slitord_id[slit_idx]), outfile=outfile) # Return self.steps.append(inspect.stack()[0][3]) return self.wv_calib
def iterative_fitting(spec, tcent, ifit, IDs, llist, disp, match_toler = 2.0, func = 'legendre', n_first=2, sigrej_first=2.0, n_final=4, sigrej_final=3.0, weights=None, plot_fil=None, verbose=False): """ Routine for iteratively fitting wavelength solutions. Parameters ---------- spec : ndarray, shape = (nspec,) arcline spectrum tcent : ndarray Centroids in pixels of lines identified in spec ifit : ndarray Indices of the lines that will be fit IDs: ndarray wavelength IDs of the lines that will be fit (I think?) llist: dict Linelist dictionary disp: float dispersion Optional Parameters ------------------- match_toler: float, default = 3.0 Matching tolerance when searching for new lines. This is the difference in pixels between the wavlength assigned to an arc line by an iteration of the wavelength solution to the wavelength in the line list. func: str, default = 'legendre' Name of function used for the wavelength solution n_first: int, default = 2 Order of first guess to the wavelength solution. sigrej_first: float, default = 2.0 Number of sigma for rejection for the first guess to the wavelength solution. n_final: int, default = 4 Order of the final wavelength solution fit sigrej_final: float, default = 3.0 Number of sigma for rejection for the final fit to the wavelength solution. weights: ndarray Weights to be used? verbose : bool If True, print out more information. plot_fil: Filename for plotting some QA? Returns ------- final_fit: dict Dictionary containing the full fitting results and the final best guess of the line IDs """ #TODO JFH add error checking here to ensure that IDs and ifit have the same size! if weights is None: weights = np.ones(tcent.size) nspec = spec.size xnspecmin1 = float(nspec-1) # Setup for fitting sv_ifit = list(ifit) # Keep the originals all_ids = -999.*np.ones(len(tcent)) all_idsion = np.array(['UNKNWN']*len(tcent)) all_ids[ifit] = IDs # Fit n_order = n_first flg_continue = True flg_penultimate = False fmin, fmax = 0.0, 1.0 # Note the number of parameters is actually n_order and not n_order+1 while flg_continue: if flg_penultimate: flg_continue = False # Fit with rejection xfit, yfit, wfit = tcent[ifit], all_ids[ifit], weights[ifit] mask, fit = utils.robust_polyfit(xfit/xnspecmin1, yfit, n_order, function=func, sigma=sigrej_first, minx=fmin, maxx=fmax, verbose=verbose, weights=wfit) rms_ang = utils.calc_fit_rms(xfit[mask == 0]/xnspecmin1, yfit[mask == 0], fit, func, minx=fmin, maxx=fmax, weights=wfit[mask == 0]) rms_pix = rms_ang/disp if verbose: msgs.info('n_order = {:d}'.format(n_order) + ': RMS = {:g}'.format(rms_pix)) # Reject but keep originals (until final fit) ifit = list(ifit[mask == 0]) + sv_ifit # Find new points (should we allow removal of the originals?) twave = utils.func_val(fit, tcent/xnspecmin1, func, minx=fmin, maxx=fmax) for ss, iwave in enumerate(twave): mn = np.min(np.abs(iwave-llist['wave'])) if mn/disp < match_toler: imn = np.argmin(np.abs(iwave-llist['wave'])) #if verbose: # print('Adding {:g} at {:g}'.format(llist['wave'][imn],tcent[ss])) # Update and append all_ids[ss] = llist['wave'][imn] all_idsion[ss] = llist['ion'][imn] ifit.append(ss) # Keep unique ones ifit = np.unique(np.array(ifit, dtype=int)) # Increment order? if n_order < n_final: n_order += 1 else: flg_penultimate = True # Final fit (originals can now be rejected) #fmin, fmax = 0., 1. #xfit, yfit, wfit = tcent[ifit]/(nspec-1), all_ids[ifit], weights[ifit] xfit, yfit, wfit = tcent[ifit], all_ids[ifit], weights[ifit] mask, fit = utils.robust_polyfit(xfit/xnspecmin1, yfit, n_order, function=func, sigma=sigrej_final, minx=fmin, maxx=fmax, verbose=verbose, weights=wfit)#, debug=True) irej = np.where(mask == 1)[0] if len(irej) > 0: xrej = xfit[irej] yrej = yfit[irej] if verbose: for kk, imask in enumerate(irej): wave = utils.func_val(fit, xrej[kk]/xnspecmin1, func, minx=fmin, maxx=fmax) msgs.info('Rejecting arc line {:g}; {:g}'.format(yfit[imask], wave)) else: xrej = [] yrej = [] #xfit = xfit[mask == 0] #yfit = yfit[mask == 0] #wfit = wfit[mask == 0] ions = all_idsion[ifit] # ions = all_idsion[ifit][mask == 0] # Final RMS rms_ang = utils.calc_fit_rms(xfit[mask==0]/xnspecmin1, yfit[mask==0], fit, func, minx=fmin, maxx=fmax, weights=wfit[mask==0]) # rms_ang = utils.calc_fit_rms(xfit, yfit, fit, func, # minx=fmin, maxx=fmax, weights=wfit) rms_pix = rms_ang/disp # Pack up fit spec_vec = np.arange(nspec) wave_soln = utils.func_val(fit,spec_vec/xnspecmin1, func, minx=fmin, maxx=fmax) cen_wave = utils.func_val(fit, float(nspec)/2/xnspecmin1, func, minx=fmin, maxx=fmax) cen_wave_min1 = utils.func_val(fit, (float(nspec)/2 - 1.0)/xnspecmin1, func, minx=fmin, maxx=fmax) cen_disp = cen_wave - cen_wave_min1 final_fit = dict(fitc=fit, function=func, pixel_fit=xfit, wave_fit=yfit, weights=wfit, ions=ions, fmin=fmin, fmax=fmax, xnorm = xnspecmin1, nspec=nspec, cen_wave = cen_wave, cen_disp = cen_disp, xrej=xrej, yrej=yrej, mask=(mask == 0), spec=spec, wave_soln = wave_soln, nrej=sigrej_final, shift=0., tcent=tcent, rms=rms_pix) # If set to True, this will output a file that can then be included in the tests saveit = False if saveit: from linetools import utils as ltu jdict = ltu.jsonify(final_fit) if plot_fil is None: outname = "temp" print("You should have set the plot_fil directory to save wavelength fits... using 'temp' as a filename") else: outname = plot_fil ltu.savejson(outname + '.json', jdict, easy_to_read=True, overwrite=True) print(" Wrote: {:s}".format(outname + '.json')) # QA if plot_fil is not None: autoid.arc_fit_qa(final_fit, plot_fil) # Return return final_fit
def iterative_fitting(spec, tcent, ifit, IDs, llist, disp, match_toler = 2.0, func = 'legendre', n_first=2, sigrej_first=2.0, n_final=4, sigrej_final=3.0, input_only=False, weights=None, plot_fil=None, verbose=False): """ Routine for iteratively fitting wavelength solutions. Parameters ---------- spec : ndarray, shape = (nspec,) arcline spectrum tcent : ndarray Centroids in pixels of lines identified in spec ifit : ndarray Indices of the lines that will be fit IDs: ndarray wavelength IDs of the lines that will be fit (I think?) llist: dict Linelist dictionary disp: float dispersion Optional Parameters ------------------- match_toler: float, default = 3.0 Matching tolerance when searching for new lines. This is the difference in pixels between the wavlength assigned to an arc line by an iteration of the wavelength solution to the wavelength in the line list. func: str, default = 'legendre' Name of function used for the wavelength solution n_first: int, default = 2 Order of first guess to the wavelength solution. sigrej_first: float, default = 2.0 Number of sigma for rejection for the first guess to the wavelength solution. n_final: int, default = 4 Order of the final wavelength solution fit sigrej_final: float, default = 3.0 Number of sigma for rejection for the final fit to the wavelength solution. input_only: bool If True, the routine will only perform a robust polyfit to the input IDs. If False, the routine will fit the input IDs, and then include additional lines in the linelist that are a satisfactory fit. weights: ndarray Weights to be used? verbose : bool If True, print out more information. plot_fil: Filename for plotting some QA? Returns ------- final_fit: :class:`pypeit.core.wavecal.wv_fitting.WaveFit` """ #TODO JFH add error checking here to ensure that IDs and ifit have the same size! if weights is None: weights = np.ones(tcent.size) nspec = spec.size xnspecmin1 = float(nspec-1) # Setup for fitting sv_ifit = list(ifit) # Keep the originals all_ids = -999.*np.ones(len(tcent)) all_idsion = np.array(['UNKNWN']*len(tcent)) all_ids[ifit] = IDs # Fit n_order = n_first flg_continue = True flg_penultimate = False fmin, fmax = 0.0, 1.0 # Note the number of parameters is actually n_order and not n_order+1 while flg_continue: if flg_penultimate: flg_continue = False # Fit with rejection xfit, yfit, wfit = tcent[ifit], all_ids[ifit], weights[ifit] maxiter = xfit.size - n_order - 2 # if xfit.size == 0: msgs.warn("All points rejected !!") return None # Fit pypeitFit = fitting.robust_fit(xfit/xnspecmin1, yfit, n_order, function=func, maxiter=maxiter, lower=sigrej_first, upper=sigrej_first, maxrej=1, sticky=True, minx=fmin, maxx=fmax, weights=wfit) # Junk fit? if pypeitFit is None: msgs.warn("Bad fit!!") return None rms_ang = pypeitFit.calc_fit_rms(apply_mask=True) rms_pix = rms_ang/disp if verbose: msgs.info('n_order = {:d}'.format(n_order) + ': RMS = {:g}'.format(rms_pix)) # Reject but keep originals (until final fit) ifit = list(ifit[pypeitFit.gpm == 1]) + sv_ifit if not input_only: # Find new points from the linelist (should we allow removal of the originals?) twave = pypeitFit.eval(tcent/xnspecmin1)#, func, minx=fmin, maxx=fmax) for ss, iwave in enumerate(twave): mn = np.min(np.abs(iwave-llist['wave'])) if mn/disp < match_toler: imn = np.argmin(np.abs(iwave-llist['wave'])) #if verbose: # print('Adding {:g} at {:g}'.format(llist['wave'][imn],tcent[ss])) # Update and append all_ids[ss] = llist['wave'][imn] all_idsion[ss] = llist['ion'][imn] ifit.append(ss) # Keep unique ones ifit = np.unique(np.array(ifit, dtype=int)) # Increment order? if n_order < n_final: n_order += 1 else: flg_penultimate = True # Final fit (originals can now be rejected) xfit, yfit, wfit = tcent[ifit], all_ids[ifit], weights[ifit] pypeitFit = fitting.robust_fit(xfit/xnspecmin1, yfit, n_order, function=func, lower=sigrej_final, upper=sigrej_final, maxrej=1, sticky=True, minx=fmin, maxx=fmax, weights=wfit)#, debug=True) irej = np.where(np.logical_not(pypeitFit.bool_gpm))[0] if len(irej) > 0: xrej = xfit[irej] yrej = yfit[irej] if verbose: for kk, imask in enumerate(irej): wave = pypeitFit.eval(xrej[kk]/xnspecmin1)#, func, minx=fmin, maxx=fmax) msgs.info('Rejecting arc line {:g}; {:g}'.format(yfit[imask], wave)) else: xrej = [] yrej = [] ions = all_idsion[ifit] # Final RMS rms_ang = pypeitFit.calc_fit_rms(apply_mask=True) rms_pix = rms_ang/disp # Pack up fit spec_vec = np.arange(nspec) wave_soln = pypeitFit.eval(spec_vec/xnspecmin1) cen_wave = pypeitFit.eval(float(nspec)/2/xnspecmin1) cen_wave_min1 = pypeitFit.eval((float(nspec)/2 - 1.0)/xnspecmin1) cen_disp = cen_wave - cen_wave_min1 # Ions bit ion_bits = np.zeros(len(ions), dtype=WaveFit.bitmask.minimum_dtype()) for kk,ion in enumerate(ions): ion_bits[kk] = WaveFit.bitmask.turn_on(ion_bits[kk], ion.replace(' ', '')) # DataContainer time # spat_id is set to an arbitrary -1 here and is updated in wavecalib.py final_fit = WaveFit(-1, pypeitfit=pypeitFit, pixel_fit=xfit, wave_fit=yfit, ion_bits=ion_bits, xnorm=xnspecmin1, cen_wave=cen_wave, cen_disp=cen_disp, spec=spec, wave_soln = wave_soln, sigrej=sigrej_final, shift=0., tcent=tcent, rms=rms_pix) # QA if plot_fil is not None: autoid.arc_fit_qa(final_fit, plot_fil) # Return return final_fit
def main(flg): # Keck LRISb if flg & (2**0): # B300, all lamps binspec = 1 slits = [15] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B300', 'lris_blue_300.sav') outroot = 'keck_lris_blue_300_d680.fits' build_template(xidl_file, slits, None, binspec, outroot, lowredux=True) if flg & (2**1): # B400, all lamps I think) binspec = 2 outroot = 'keck_lris_blue_400_d560.fits' slits = [19, 14] lcut = [5500.] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B400', 'lris_blue_400_d560.sav') build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) if flg & (2**2): # B600, all lamps binspec = 2 outroot = 'keck_lris_blue_600_d560.fits' slits = [0, 7] lcut = [4500.] wfile = os.path.join(template_path, 'Keck_LRIS', 'B600', 'MasterWaveCalib_A_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**3): # B1200, all lamps? binspec = 2 outroot = 'keck_lris_blue_1200_d460.fits' slits = [19, 44] lcut = [3700.] xidl_file = os.path.join(template_path, 'Keck_LRIS', 'B1200', 'lris_blue_1200.sav') build_template(xidl_file, slits, lcut, binspec, outroot, lowredux=True) # ###############################################3 # Keck/LRISr if flg & (2**10): # R400 binspec = 2 outroot = 'keck_lris_red_400.fits' slits = [7] # Quite blue, but not the bluest lcut = [] wfile = os.path.join(template_path, 'Keck_LRIS', 'R400', 'MasterWaveCalib_A_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**11): # R1200 # slits = [2-3] # 7726 -- 9250 # slits = [1-4] # 9250 -- 9925 binspec = 1 outroot = 'keck_lris_red_1200_9000.fits' ifiles = [0, 1] slits = [3, 7] lcut = [9250.] wfile1 = os.path.join(template_path, 'Keck_LRIS', 'R1200_9000', 'MasterWaveCalib_A_1_02.json') # Original Dev wfile2 = os.path.join(template_path, 'Keck_LRIS', 'R1200_9000', 'MasterWaveCalib_A_1_01.json') # Dev suite 2x1 build_template([wfile1, wfile2], slits, lcut, binspec, outroot, lowredux=False, ifiles=ifiles) if flg & (2**12): # R600/5000 # slits = [1-4] # 5080 -- 7820 # slits = [1-7] # 7820 -- 9170 binspec = 2 outroot = 'keck_lris_red_600_5000.fits' slits = [4, 7] lcut = [7820.] wfile = os.path.join(template_path, 'Keck_LRIS', 'R600_5000', 'MasterWaveCalib_B_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**27): # R600/7500 # slits = [1-10] # 5000 -- 7840 # slits = [1-4] # 7840 -- 9230 binspec = 2 outroot = 'keck_lris_red_600_7500.fits' slits = [10, 4] lcut = [7840.] wfile = os.path.join(template_path, 'Keck_LRIS', 'R600_7500', 'MasterWaveCalib_I_1_01.json') build_template(wfile, slits, lcut, binspec, outroot, lowredux=False, chk=True, normalize=True, subtract_conti=True) # ################################## # Magellan/MagE if flg & (2**13): # Load mase_path = os.path.join(os.getenv('XIDL_DIR'), 'Magellan', 'MAGE', 'mase', 'Calib') sav_file = os.path.join(mase_path, 'MagE_wvguess_jfh.idl') mase_dict = readsav(sav_file) mase_sol = Table(mase_dict['all_arcfit']) # Do it all_wave = np.zeros((2048, 15)) all_flux = np.zeros_like(all_wave) for order in np.arange(15): all_flux[:, order] = mase_dict['sv_aspec'][order] # Build the wavelengths wv_air = cheby_val(mase_sol['FFIT'][order], np.arange(2048), mase_sol['NRM'][order], mase_sol['NORD'][order]) all_wave[:, order] = airtovac(wv_air * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = np.arange(20, 5, -1, dtype=int) tbl.meta['BINSPEC'] = 1 # Write outroot = 'magellan_mage.fits' outfile = os.path.join(template_path, outroot) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**14): # Magellan/MagE Plots outpath = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'plots') new_mage_file = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv', 'magellan_mage.fits') # Load mage_wave = Table.read(new_mage_file) llist = waveio.load_line_lists(['ThAr_MagE']) # for kk in range(mage_wave['wave'].shape[1]): wv = mage_wave['wave'][:, kk] fx = mage_wave['flux'][:, kk] order = 20 - kk # Reidentify detections, spec_cont_sub, patt_dict = autoid.reidentify( fx, fx, wv, llist, 1) # Fit final_fit = wv_fitting.fit_slit(fx, patt_dict, detections, llist) # Output outfile = os.path.join(outpath, 'MagE_order{:2d}_IDs.pdf'.format(order)) autoid.arc_fit_qa(final_fit, outfile=outfile, ids_only=True) print("Wrote: {}".format(outfile)) autoid.arc_fit_qa(final_fit, outfile=os.path.join( outpath, 'MagE_order{:2d}_full.pdf'.format(order))) if flg & (2**15): # VLT/X-Shooter reid_arxiv # VIS reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') for iroot, iout in zip( ['vlt_xshooter_vis1x1.json', 'vlt_xshooter_nir.json'], ['vlt_xshooter_vis1x1.fits', 'vlt_xshooter_nir.fits']): # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk, order in enumerate(orders): all_flux[:, kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:, kk] = odict[str(kk)]['wave_soln'] else: all_wave[:, kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**16): # VLT/X-Shooter line list line_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'lists') old_file = os.path.join(line_path, 'ThAr_XSHOOTER_VIS_air_lines.dat') # Load air_list = waveio.load_line_list(old_file) # Vacuum vac_wv = airtovac(air_list['wave'] * units.AA).value vac_list = air_list.copy() vac_list['wave'] = vac_wv # Write new_file = os.path.join(line_path, 'ThAr_XSHOOTER_VIS_lines.dat') vac_list.write(new_file, format='ascii.fixed_width', overwrite=True) print("Wrote: {}".format(new_file)) if flg & (2**17): # NIRES reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'keck_nires.json' iout = 'keck_nires.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk, order in enumerate(orders): all_flux[:, kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:, kk] = odict[str(kk)]['wave_soln'] else: all_wave[:, kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**18): # Gemini/GNIRS reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'gemini_gnirs.json' iout = 'gemini_gnirs.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk, order in enumerate(orders): all_flux[:, kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:, kk] = odict[str(kk)]['wave_soln'] else: all_wave[:, kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**23): # WHT/ISIS iroot = 'wht_isis_blue_1200_4800.json' outroot = 'wht_isis_blue_1200_4800.fits' wfile = os.path.join(template_path, 'WHT_ISIS', '1200B', iroot) binspec = 2 slits = [0] lcut = [3200.] build_template(wfile, slits, lcut, binspec, outroot, lowredux=False) if flg & (2**24): # Magellan/FIRE reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'magellan_fire_echelle.json' iout = 'magellan_fire_echelle.fits' # Load old_file = os.path.join(reid_path, iroot) odict, par = waveio.load_reid_arxiv(old_file) # Do it orders = odict['fit2d']['orders'][::-1].astype(int) # Flipped all_wave = np.zeros((odict['0']['nspec'], orders.size)) all_flux = np.zeros_like(all_wave) for kk, order in enumerate(orders): all_flux[:, kk] = odict[str(kk)]['spec'] if 'nir' in iroot: all_wave[:, kk] = odict[str(kk)]['wave_soln'] else: all_wave[:, kk] = airtovac(odict[str(kk)]['wave_soln'] * units.AA).value # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile)) if flg & (2**25): # FIRE longslit binspec = 1 reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') outroot = 'magellan_fire_long.fits' xidl_file = os.path.join(os.getenv('FIRE_DIR'), 'LowDispersion', 'NeNeAr_archive_fit.fits') spec_file = os.path.join(os.getenv('FIRE_DIR'), 'LowDispersion', 'NeNeAr2.sav') fire_sol = Table.read(xidl_file) wave = cheby_val(fire_sol['FFIT'].data[0], np.arange(2048), fire_sol['NRM'].data[0], fire_sol['NORD'].data[0]) wv_vac = airtovac(wave * units.AA) xidl_dict = readsav(spec_file) flux = xidl_dict['arc1d'] wvutils.write_template(wv_vac.value, flux, binspec, reid_path, outroot, det_cut=None) # Gemini/Flamingos2 if flg & (2**26): reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = ['Flamingos2_JH_JH.json', 'Flamingos2_HK_HK.json'] outroot = ['Flamingos2_JH_JH.fits', 'Flamingos2_HK_HK.fits'] binspec = 1 slits = [0] lcut = [] for ii in range(len(iroot)): wfile = os.path.join(reid_path, iroot[ii]) build_template(wfile, slits, lcut, binspec, outroot[ii], lowredux=False) # MDM/OSMOS -- MDM4K if flg & (2**28): # ArI 4159 -- 6800 wfile = os.path.join(template_path, 'MDM_OSMOS', 'MasterWaveCalib_MDM4K_01.json') outroot = 'mdm_osmos_mdm4k.fits' binspec = 1 slits = [0] lcut = [3200.] build_template(wfile, slits, lcut, binspec, outroot, lowredux=False, chk=True, subtract_conti=True) # Keck KCWI if flg & (2**29): # FeAr BH2 wfile1 = os.path.join(template_path, 'KCWI', 'BH2', 'Keck_KCWI_BH2_4200.json') outroot = 'keck_kcwi_BH2_4200.fits' binspec = 1 slits = [1015] lcut = [4350.0, 8000.0] build_template([wfile1], slits, lcut, binspec, outroot, lowredux=False, normalize=True) # FeAr BM wfile1 = os.path.join(template_path, 'KCWI', 'BM', 'Keck_KCWI_BM_4060.json') wfile2 = os.path.join(template_path, 'KCWI', 'BM', 'Keck_KCWI_BM_4670.json') outroot = 'keck_kcwi_BM.fits' binspec = 1 slits = [1026, 1021] lcut = [4350.0, 8000.0] build_template([wfile1, wfile2], slits, lcut, binspec, outroot, lowredux=False, normalize=True) # P200 DBSP r if flg & (2**30): # HeNeAr wfile = os.path.join(template_path, 'P200_DBSP', 'R316_7500_D55', 'P200_DBSP_Red.json') outroot = 'p200_dbsp_red_316_7500_d55.fits' binspec = 1 slits = [221] lcut = None # only matters if >1 slit build_template([wfile], slits, lcut, binspec, outroot, lowredux=False, normalize=True) # P200 DBSP b if flg & (2**31): # FeAr wfile = os.path.join(template_path, 'P200_DBSP', 'B600_4000_D55', 'P200_DBSP_Blue.json') outroot = 'p200_dbsp_blue_600_4000_d55.fits' binspec = 1 slits = [231] lcut = None build_template([wfile], slits, lcut, binspec, outroot, lowredux=False, normalize=True) # MMT/MMIRS if flg & (2**32): reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = [ 'mmt_mmirs_HK_zJ.json', 'mmt_mmirs_J_zJ.json', 'mmt_mmirs_K3000_Kspec.json' ] outroot = [ 'mmt_mmirs_HK_zJ.fits', 'mmt_mmirs_J_zJ.fits', 'mmt_mmirs_K3000_Kspec.fits' ] binspec = 1 slits = [1020, 1020, 1020] lcut = [] for ii in range(len(iroot)): wfile = os.path.join(reid_path, iroot[ii]) build_template(wfile, slits, lcut, binspec, outroot[ii], lowredux=False) # LBT/MODS if flg & (2**33): reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = ['lbt_mods1r_red.json', 'lbt_mods2r_red.json'] outroot = ['lbt_mods1r_red.fits', 'lbt_mods2r_red.fits'] binspec = 1 slits = [[1557], [1573]] lcut = [] for ii in range(len(iroot)): wfile = os.path.join(reid_path, iroot[ii]) build_template(wfile, slits[ii], lcut, binspec, outroot[ii], lowredux=False) # P200 Triplespec if flg & (2**34): reid_path = os.path.join(resource_filename('pypeit', 'data'), 'arc_lines', 'reid_arxiv') iroot = 'p200_triplespec_MasterWaveCalib.fits' iout = 'p200_triplespec.fits' # Load old_file = os.path.join(reid_path, iroot) par = io.fits_open(old_file) pyp_spec = par[0].header['PYP_SPEC'] spectrograph = load_spectrograph(pyp_spec) orders = spectrograph.orders # Do it all_wave = np.zeros((par[2].data['spec'].size, orders.size)) all_flux = np.zeros_like(all_wave) for kk, order in enumerate(orders): all_flux[:, kk] = par[2 * kk + 2].data['spec'] all_wave[:, kk] = par[2 * kk + 2].data['wave_soln'] # Write tbl = Table() tbl['wave'] = all_wave.T tbl['flux'] = all_flux.T tbl['order'] = orders tbl.meta['BINSPEC'] = 1 # Write outfile = os.path.join(reid_path, iout) tbl.write(outfile, overwrite=True) print("Wrote: {}".format(outfile))
def build_wv_calib(self, arccen, method, skip_QA=False): """ Main routine to generate the wavelength solutions in a loop over slits Wrapper to arc.simple_calib or arc.calib_with_arclines self.maskslits is updated for slits that fail Args: method : str 'simple' -- arc.simple_calib 'arclines' -- arc.calib_with_arclines 'holy-grail' -- wavecal.autoid.HolyGrail 'reidentify' -- wavecal.auotid.ArchiveReid 'identify' -- wavecal.identify.Identify 'full_template' -- wavecal.auotid.full_template skip_QA (bool, optional) Returns: dict: self.wv_calib """ # Obtain a list of good slits ok_mask_idx = np.where(np.invert(self.wvc_bpm))[0] # Obtain calibration for all slits if method == 'simple': lines = self.par['lamps'] line_lists = waveio.load_line_lists(lines) final_fit = arc.simple_calib_driver( line_lists, arccen, ok_mask_idx, n_final=self.par['n_final'], sigdetect=self.par['sigdetect'], IDpixels=self.par['IDpixels'], IDwaves=self.par['IDwaves']) # elif method == 'basic': # final_fit = {} # for slit in ok_mask: # status, ngd_match, match_idx, scores, ifinal_fit = \ # autoid.basic(arccen[:, slit], self.par['lamps'], self.par['wv_cen'], # self.par['disp'], nonlinear_counts=self.nonlinear_counts) # final_fit[str(slit)] = ifinal_fit.copy() # if status != 1: # self.maskslits[slit] = True elif method == 'holy-grail': # Sometimes works, sometimes fails arcfitter = autoid.HolyGrail( arccen, par=self.par, ok_mask=ok_mask_idx, nonlinear_counts=self.nonlinear_counts) patt_dict, final_fit = arcfitter.get_results() elif method == 'identify': final_fit = {} # Manually identify lines msgs.info("Initializing the wavelength calibration tool") # TODO: Move this loop to the GUI initalise method embed() for slit_idx in ok_mask_idx: arcfitter = gui_identify.initialise(arccen, slit=slit_idx, par=self.par) final_fit[str(slit_idx)] = arcfitter.get_results() if final_fit[str(slit_idx)] is not None: ans = 'y' # ans = '' # while ans != 'y' and ans != 'n': # ans = input("Would you like to store this wavelength solution in the archive? (y/n): ") if ans == 'y' and final_fit[str( slit_idx)]['rms'] < self.par['rms_threshold']: # Store the results in the user reid arxiv specname = self.spectrograph.spectrograph gratname = "UNKNOWN" # input("Please input the grating name: ") dispangl = "UNKNOWN" # input("Please input the dispersion angle: ") templates.pypeit_identify_record( final_fit[str(slit_idx)], self.binspectral, specname, gratname, dispangl) msgs.info("Your wavelength solution has been stored") msgs.info( "Please consider sending your solution to the PYPEIT team!" ) elif method == 'reidentify': # Now preferred # Slit positions arcfitter = autoid.ArchiveReid( arccen, self.spectrograph, self.par, ok_mask=ok_mask_idx, slit_spat_pos=self.spat_coo, nonlinear_counts=self.nonlinear_counts) patt_dict, final_fit = arcfitter.get_results() elif method == 'full_template': # Now preferred if self.binspectral is None: msgs.error( "You must specify binspectral for the full_template method!" ) final_fit = autoid.full_template( arccen, self.par, ok_mask_idx, self.det, self.binspectral, nonlinear_counts=self.nonlinear_counts, nsnippet=self.par['nsnippet']) else: msgs.error( 'Unrecognized wavelength calibration method: {:}'.format( method)) # Convert keys to spatial system self.wv_calib = {} tmp = copy.deepcopy(final_fit) for idx in range(self.slits.nslits): if str(idx) in final_fit.keys(): self.wv_calib[str(self.slits.slitord_id[idx])] = final_fit.pop( str(idx)) # Update mask self.update_wvmask() #TODO For generalized echelle (not hard wired) assign order number here before, i.e. slits.ech_order # QA if not skip_QA: ok_mask_idx = np.where(np.invert(self.wvc_bpm))[0] for slit_idx in ok_mask_idx: outfile = qa.set_qa_filename( self.master_key, 'arc_fit_qa', slit=self.slits.slitord_id[slit_idx], out_dir=self.qa_path) autoid.arc_fit_qa(self.wv_calib[str( self.slits.slitord_id[slit_idx])], outfile=outfile) # Return self.steps.append(inspect.stack()[0][3]) return self.wv_calib