def extract_stellar_spectra_ascii(root, night, steps=["08", "09", "10"]): """Generate ascii spectra for each of the data reduction steps in steps. Saves ascii spectra in a new folder in the night directory called 'ascii'. Parameters: ----------- root: string The base path to the reduced data (i.e. where the nightly folders are stored.) night: string The night to extract spectra from (in the form 201XYYZZ). steps: list of strings The PyWiFeS data reduction steps to extract and convert to 1D spectra. """ # Sort out directory structures data_dir = os.path.join(root, night) out_dir = os.path.join(data_dir, 'ascii') if not os.path.isdir(out_dir) and not os.path.exists(out_dir): os.mkdir(out_dir) print('Converting to ascii:', data_dir) # Extract all files for path, subdirs, files in os.walk(data_dir): for name in files: fl = os.path.join(path, name) step = fl.split(".")[-2][1:] # Only run on specified data reduction outputs if step in steps and fl.endswith('%s.fits' % step): print(fl) f = fits.open(fl) header = f[0].header objectid = header['OBJNAME'] run = header['RUN'] f.close() # Extract spectrum flux, wave = ps.read_and_find_star_p08(fl) spectrum, sig = ps.weighted_extract_spectrum(flux) # Determine output format depending on spectral arm if 'T2m3wr' in name: filename = '%s_%s_%s_r.dat' % (night, objectid, step) elif 'T2m3wb' in name: filename = '%s_%s_%s_b.dat' % (night, objectid, step) filename = filename.replace(' ', '_') # Save output fln = os.path.join(out_dir, filename) print(fln) np.savetxt(fln, np.transpose([wave, spectrum]))
a.close() a = pyfits.open(fn, mode='update') a[1].header['OBJECT'] = 'UCAC4-' + objname a.close() a = pyfits.open(fn) objname = a[1].header['OBJECT'] if len(objname) == 0: objname = 'object' obsmjd = a[1].header['MJD-OBS'] obsdate = a[1].header['DATE-OBS'].split('T')[0] if args.save_name == None: save_name = objname + '_spectra.eps' else: save_name = args.save_name flux, wave = ps.read_and_find_star_p08(fn) spectrum, sig = ps.weighted_extract_spectrum(flux) median_value = np.median(spectrum) if objname in Objects: obj_data = Objects[objname] if str(obsmjd) not in obj_data[:, 1]: dict_date = np.append(obj_data.T[0], obsdate) dict_mjd = np.append(obj_data.T[1], obsmjd) dict_medians = np.append(obj_data.T[2], median_value) Objects[objname] = np.array([dict_date, dict_mjd, dict_medians]).T else: Objects.update({objname: np.array([[obsdate, obsmjd, median_value]])}) #plot figure plt.clf() plt.plot(wave, spectrum)
slit_temp = [] MJD = [] RV = [] #Get template hdu_p08 = pyfits.open(file_p08) file_temp = files[0] hdu_temp = pyfits.open(file_temp) MJD_obs = hdu_temp[0].header['MJD-OBS'] MJD.append(MJD_obs) #Make templates for slit in range(11): RV.append([0.0]) flux_stamp = np.array([hdu_temp[slit + 1].data[:]]) spectrum, sig = ps.weighted_extract_spectrum(flux_stamp) pix_arr = np.arange(0, len(spectrum), 0.1) spectrum_interp = np.interp(pix_arr, np.arange(0, len(spectrum)), spectrum) if slit == 0: spectrum_temp = spectrum_interp slit_temp.append(spectrum_interp) outfn = 'templates/slit_' + str(slit + 1) + '.fits' pyfits.writeto(outfn, spectrum_interp, clobber=True) print(('saved template:' + outfn)) #import pdb #pdb.set_trace() #Now go through the other files bad_intervals = ([0, 5400], [6700, 7000])
temp_name = Pref_template[ind].split('_')[0] custom_simbad = Simbad() custom_simbad.add_votable_fields("sptype") data = custom_simbad.query_object(temp_name) sptype = data['SP_TYPE'][-1] Temp_sptype[ind] = sptype else: sptype = Temp_sptype[ind] else: templates = glob.glob(templates_dir + '/*.fits') Temp_sptype[ind] = ' ' if args.correct_sky == 'True': #Calculating RV from skylines if args.absorption == 'False': spectrum, sig = ps.weighted_extract_spectrum( sky, var) snr_val = np.max(spectrum) / np.median(spectrum) SNR.append(snr_val) rv_sky, rv_sky_sig, temp_used = ps.calc_rv_template( spectrum, wave, sig, sky_temp, (sky_intervals), heliocentric_correction=0.0) temp_hdu = fits.open('/Users/rajikak/tools/' + temp_used) spectrum_interp = np.interp( wave_template, wave * (1 - (rv_sky) / 2.998e5), spectrum) print("Skyline offset= " + str(rv_sky) + ', ' +
def extract_stellar_spectra_fits( ob, night, steps=["08", "09", "10"], npix=7, manual_click=False, out_dir=None, do_median_subtraction=False, min_slit_i=0, take_uncertainties_from_p08=True, ): """Make a fits data cube of the reduced and extracted stellar spectra, with a different HDU for each data reduction step. Store this new cube in a folder called 'extracted_1D_cubes' in the night folder. By default: - 8: Final (non-fluxed or telluric corrected) - 9: Final (fluxed) -10: Final (fluxed and telluric corrected) Parameters: ----------- ob: string Unique part of the fits filename (i.e. excluding .pXX.fits) night: string The night to extract spectra from (in the form YYYYMMDD). steps: list of strings The PyWiFeS data reduction steps to extract and convert to 1D spectra. npix: int Number of pixels to extract for aperture photometry manual_click: bool, default: True Whether to ask for user input during extraction out_dir: str or None, default None Overriden output directory do_median_subtraction: bool, default: False Whether to do median subtraction on process_stellar plots. min_slit_i: int, default: 0 process_stellar plotting parameter. take_uncertainties_from_p08: boolean, default: True Whether to take uncertainties from p08 spectra (propagated as fractional uncertainty), which is in counts and suited to process_stellar extraction. """ # Get the list of fits files to extract 1D spectra from fits_files = [ob + ".p%s.fits" % step for step in steps] # Get the header information from the first header = fits.getheader(fits_files[0]) obj_id = header['OBJNAME'].replace(" ", "") if "T2m3wb" in ob: arm = "b" elif "T2m3wr" in ob: arm = "r" else: arm = "" fig_fn = os.path.join(out_dir, "extracted_region_{}_{}.pdf".format(arm, obj_id)) # Construct a new fits file hdus = [] hdus.append(fits.PrimaryHDU(header=header)) print("Making cube for %s%s" % (ob, ".pXX.fits")) for fits_file, step in zip(fits_files, steps): # Extract the 1D spectrum print("\tExtracting 1D spectrum for step %s" % step) flux, wave = ps.read_and_find_star_p08( fits_file, npix=npix, manual_click=manual_click, fig_fn=fig_fn, fig_title=obj_id, do_median_subtraction=do_median_subtraction, arm=arm, min_slit_i=min_slit_i, ) spectrum, sig = ps.weighted_extract_spectrum(flux) # Initialise fractional uncertainty vectors if step == "08": sigma_frac = sig / spectrum # Details of extraction do not lend themselves to determining correct # uncertainties from fluxed spectra. As such, the default behaviour is # to propagate the uncertainties from the p08 spectra while it is in # units of counts and Poisson uncertainties make sense. if take_uncertainties_from_p08 and step != "08": sig = spectrum * sigma_frac # Make fits table from numpy record array data = np.array([wave, spectrum, sig]).T.tolist() rec = np.rec.array(data, names=["wave", "spectrum", "sigma"]) hdus.append(fits.BinTableHDU.from_columns(rec)) hdus[-1].header["REDSTEP"] = step # Determine output format depending on spectral arm if 'T2m3wr' in ob: output_filename = '%s_%s_r.fits' % (night, obj_id) elif 'T2m3wb' in ob: output_filename = '%s_%s_b.fits' % (night, obj_id) output_filepath = os.path.join(out_dir, output_filename) # Write the fits file print("Writing cube to %s \n" % output_filename) hdu_list = fits.HDUList(hdus) hdu_list.writeto(output_filepath, overwrite=True)