def rectify(dname, lamdat, A, B, maskname, band, wavoptions, longoptions): header, data = IO.readfits(dname) raw_img = data * Detector.gain / header['TRUITIME'] dlam = Wavelength.grating_results(band) hpp = np.array(Filters.hpp[band]) ll_fid = np.arange(hpp[0], hpp[1], dlam) rectified = np.zeros((2048, len(ll_fid))) from scipy.interpolate import interp1d for i in xrange(2048): ll = lamdat[i, :] ss = raw_img[i, :] ok = np.isfinite(ll) & np.isfinite(ss) & (ll < hpp[1]) & (ll > hpp[0]) if len(np.where(ok)[0]) < 30: continue f = interp1d(ll[ok], ss[ok], bounds_error=False) rectified[i, :] = f(ll_fid) header.update("wat0_001", "system=world") header.update("wat1_001", "wtype=linear") header.update("wat2_001", "wtype=linear") header.update("dispaxis", 1) header.update("dclog1", "Transform") header.update("dc-flag", 0) header.update("ctype1", "AWAV") header.update("cunit1", "Angstrom") header.update("crval1", ll_fid[0]) header.update("crval2", 0) header.update("crpix1", 1) header.update("crpix2", 1) header.update("cdelt1", 1) header.update("cdelt2", 1) header.update("cname1", "angstrom") header.update("cname2", "pixel") header.update("cd1_1", dlam) header.update("cd1_2", 0) header.update("cd2_1", 0) header.update("cd2_2", 1) header.update("object", "rectified [eps]") IO.writefits(rectified, maskname, "rectified_%s" % (dname), wavoptions, header=header, overwrite=True, lossy_compress=True)
def rectify(dname, lamdat, A, B, maskname, band, wavoptions, longoptions): header, data = IO.readfits(dname) raw_img = data * Detector.gain / header['TRUITIME'] dlam = Wavelength.grating_results(band) hpp = np.array(Filters.hpp[band]) ll_fid = np.arange(hpp[0], hpp[1], dlam) rectified = np.zeros((2048, len(ll_fid))) from scipy.interpolate import interp1d for i in xrange(2048): ll = lamdat[i,:] ss = raw_img[i,:] ok = np.isfinite(ll) & np.isfinite(ss) & (ll < hpp[1]) & (ll > hpp[0]) if len(np.where(ok)[0]) < 30: continue f = interp1d(ll[ok], ss[ok], bounds_error=False) rectified[i,:] = f(ll_fid) header.update("wat0_001", "system=world") header.update("wat1_001", "wtype=linear") header.update("wat2_001", "wtype=linear") header.update("dispaxis", 1) header.update("dclog1", "Transform") header.update("dc-flag", 0) header.update("ctype1", "AWAV") header.update("cunit1", "Angstrom") header.update("crval1", ll_fid[0]) header.update("crval2", 0) header.update("crpix1", 1) header.update("crpix2", 1) header.update("cdelt1", 1) header.update("cdelt2", 1) header.update("cname1", "angstrom") header.update("cname2", "pixel") header.update("cd1_1", dlam) header.update("cd1_2", 0) header.update("cd2_1", 0) header.update("cd2_2", 1) header.update("object", "rectified [eps]") IO.writefits(rectified, maskname, "rectified_%s" % (dname), wavoptions, header=header, overwrite=True, lossy_compress=True)
def write_outputs(solutions, itime, header, maskname, band_name, plan, options): sky_sub_out = np.zeros((2048, 2048), dtype=np.float) sky_model_out = np.zeros((2048, 2048), dtype=np.float) p0 = plan[0].replace("'", "p") p1 = plan[1].replace("'", "p") suffix = "%s-%s" % (p0,p1) xroi = slice(0,2048) for sol in solutions: if not sol["ok"]: continue yroi = slice(sol["bottom"], sol["top"]) sky_sub_out[yroi, xroi] = sol["output"] sky_model_out[yroi, xroi] = sol["model"] header['BUNIT'] = 'SECOND' IO.writefits(itime, maskname, "itime_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(data, maskname, "sub_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(sky_sub_out, maskname, "bsub_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True) header['BUNIT'] = 'ELECTRONS' IO.writefits(Var, maskname, "var_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(sky_model_out, maskname, "bmod_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) '''Now create rectified solutions''' dlam = Wavelength.grating_results(band) hpp = np.array(Filters.hpp[band]) ll_fid = np.arange(hpp[0], hpp[1], dlam) nspec = len(ll_fid) rectified = np.zeros((2048, nspec), dtype=np.float32) rectified_var = np.zeros((2048, nspec), dtype=np.float32) rectified_itime = np.zeros((2048, nspec), dtype=np.float32) from scipy.interpolate import interp1d for i in xrange(2048): ll = lam[1][i,:] ss = sky_sub_out[i,:] ok = np.isfinite(ll) & np.isfinite(ss) & (ll < hpp[1]) & (ll > hpp[0]) if len(np.where(ok)[0]) < 100: continue f = interp1d(ll[ok], ss[ok], bounds_error=False) rectified[i,:] = f(ll_fid) f = interp1d(ll, Var[i,:], bounds_error=False) rectified_var[i,:] = f(ll_fid) f = interp1d(ll, itime[i,:], bounds_error=False) rectified_itime[i,:] = f(ll_fid) header["wat0_001"] = "system=world" header["wat1_001"] = "type=linear" header["wat2_001"] = "type=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["type1"] = "AWAV" header["cunit1"] = "Angstrom" header["crval1"] = (ll_fid[0], "Starting wavelength Angstrom") header["crval2"] = 0 header["crpix1"] = 1 header["crpix2"] = 1 header["cdelt1"] = 1 header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = (dlam, "Angstrom/pixel") header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = (1, "pixel/pixel") IO.writefits(rectified_itime, maskname, "%s_rectified_itime_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified, maskname, "%s_rectified_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified_var, maskname, "%s_rectified_var_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified*rectified_itime/np.sqrt(rectified_var), maskname, "%s_rectified_sn_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True)
def handle_rectification(maskname, in_files, wavename, band_pass, barset_file, options, commissioning_shift=3.0): '''Handle slit rectification and coaddition. Args: maskname: The mask name string in_files: List of stacked spectra in electron per second. Will look like ['electrons_Offset_1.5.txt.fits', 'electrons_Offset_-1.5.txt.fits'] wavename: path (relative or full) to the wavelength stack file, string band_pass: Band pass name, string barset_file: Path to a mosfire fits file containing the full set of FITS extensions for the barset. It can be any file in the list of science files. Returns: None Writes files: [maskname]_[band]_[object name]_eps.fits -- The rectified, background subtracted, stacked eps spectrum [maskname]_[band]_[object name]_sig.fits -- Rectified, background subtracted, stacked weight spectrum (STD/itime) [maskname]_[band]_[object_name]_itime.fits Rectified, CRR stacked integration time spectrum [maskname]_[band]_[object_name]_snrs.fits Rectified signal to noise spectrum ''' global edges, dats, vars, itimes, shifts, lambdas, band, fidl, all_shifts band = band_pass dlambda = Wavelength.grating_results(band) hpp = Filters.hpp[band] fidl = np.arange(hpp[0], hpp[1], dlambda) lambdas = IO.readfits(wavename, options) if np.any(lambdas[1].data < 0) or np.any(lambdas[1].data > 29000): print "***********WARNING ***********" print "The file {0} may not be a wavelength file.".format(wavename) print "Check before proceeding." print "***********WARNING ***********" edges, meta = IO.load_edges(maskname, band, options) shifts = [] posnames = [] postoshift = {} for file in in_files: print ":: ", file II = IO.read_drpfits(maskname, file, options) off = np.array((II[0]["decoff"], II[0]["raoff"]),dtype=np.float64) if "yoffset" in II[0]: off = -II[0]["yoffset"] else: # Deal with data taken during commissioning if II[0]["frameid"] == 'A': off = 0.0 else: off = commissioning_shift try: off0 except: off0 = off shift = off - off0 shifts.append(shift) posnames.append(II[0]["frameid"]) postoshift[II[0]['frameid']] = shift print "Position {0} shift: {1:2.2f} as".format(off, shift) plans = Background.guess_plan_from_positions(set(posnames)) all_shifts = [] for plan in plans: to_append = [] for pos in plan: to_append.append(postoshift[pos]) all_shifts.append(to_append) # Reverse the elements in all_shifts to deal with an inversion all_shifts.reverse() theBPM = IO.badpixelmask() all_solutions = [] cntr = 0 for plan in plans: p0 = plan[0].replace("'", "p") p1 = plan[1].replace("'", "p") suffix = "%s-%s" % (p0,p1) print "Handling plan %s" % suffix fname = "bsub_{0}_{1}_{2}.fits".format(maskname,band,suffix) EPS = IO.read_drpfits(maskname, fname, options) EPS[1] = np.ma.masked_array(EPS[1], theBPM, fill_value=0) fname = "var_{0}_{1}_{2}.fits".format(maskname, band, suffix) VAR = IO.read_drpfits(maskname, fname, options) VAR[1] = np.ma.masked_array(VAR[1], theBPM, fill_value=np.inf) fname = "itime_{0}_{1}_{2}.fits".format(maskname, band, suffix) ITIME = IO.read_drpfits(maskname, fname, options) ITIME[1] = np.ma.masked_array(ITIME[1], theBPM, fill_value=0) dats = EPS vars = VAR itimes = ITIME EPS[0]["ORIGFILE"] = fname tock = time.time() sols = range(len(edges)-1,-1,-1) shifts = all_shifts[cntr] cntr += 1 p = Pool() solutions = p.map(handle_rectification_helper, sols) #solutions = map(handle_rectification_helper, [15]) p.close() all_solutions.append(solutions) tick = time.time() print "-----> Mask took %i. Writing to disk." % (tick-tock) output = np.zeros((1, len(fidl))) snrs = np.zeros((1, len(fidl))) sdout= np.zeros((1, len(fidl))) itout= np.zeros((1, len(fidl))) # the barset [bs] is used for determining object position x, x, bs = IO.readmosfits(barset_file, options) for i_slit in xrange(len(solutions)): solution = all_solutions[0][i_slit] header = EPS[0].copy() obj = header['OBJECT'] target_name = bs.ssl[-(i_slit+1)]['Target_Name'] header['OBJECT'] = target_name pixel_dist = np.float(bs.ssl[-(i_slit+1)]['Target_to_center_of_slit_distance'])/0.18 pixel_dist -= solution['offset'] ll = solution["lambda"] header["wat0_001"] = "system=world" header["wat1_001"] = "wtype=linear" header["wat2_001"] = "wtype=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["ctype1"] = "AWAV" header["cunit1"] = "Angstrom" header["crval1"] = ll[0] header["crval2"] = -solution["eps_img"].shape[0]/2 - pixel_dist header["crpix1"] = 1 header["crpix2"] = 1 header["cdelt1"] = 1 header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = ll[1]-ll[0] header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = 1 S = output.shape img = solution["eps_img"] std = solution["sd_img"] tms = solution["itime_img"] for i_solution in xrange(1,len(all_solutions)): print "Combining solution %i" %i_solution solution = all_solutions[i_solution][i_slit] img += solution["eps_img"] std += solution["sd_img"] tms += solution["itime_img"] output = np.append(output, img, 0) output = np.append(output, np.nan*np.zeros((3,S[1])), 0) snrs = np.append(snrs, img*tms/std, 0) snrs = np.append(snrs, np.nan*np.zeros((3,S[1])), 0) sdout = np.append(sdout, std, 0) sdout = np.append(sdout, np.nan*np.zeros((3,S[1])), 0) itout = np.append(itout, tms, 0) itout = np.append(itout, np.nan*np.zeros((3,S[1])), 0) header['bunit'] = ('electron/second', 'electron power') IO.writefits(img, maskname, "{0}_{1}_{2}_eps.fits".format(maskname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('electron/second', 'sigma/itime') IO.writefits(std/tms, maskname, "{0}_{1}_{2}_sig.fits".format(maskname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('second', 'exposure time') IO.writefits(tms, maskname, "{0}_{1}_{2}_itime.fits".format(maskname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('', 'SNR') IO.writefits(img*tms/std, maskname, "{0}_{1}_{2}_snrs.fits".format(maskname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header = EPS[0].copy() header["wat0_001"] = "system=world" header["wat1_001"] = "wtype=linear" header["wat2_001"] = "wtype=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["ctype1"] = "AWAV" header["cunit1"] = ("Angstrom", 'Start wavelength') header["crval1"] = ll[0] header["crval2"] = 1 header["crpix1"] = 1 header["crpix2"] = 1 header["cdelt1"] = 1 header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = (ll[1]-ll[0], 'Angstrom/pixel') header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = 1 header["bunit"] = "ELECTRONS/SECOND" IO.writefits(output, maskname, "{0}_{1}_eps.fits".format(maskname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "" IO.writefits(snrs, maskname, "{0}_{1}_snrs.fits".format(maskname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "ELECTRONS/SECOND" IO.writefits(sdout/itout, maskname, "{0}_{1}_sig.fits".format(maskname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "SECOND" IO.writefits(itout, maskname, "{0}_{1}_itime.fits".format(maskname, band), options, overwrite=True, header=header, lossy_compress=False)
def write_outputs(solutions, itime, header, maskname, band_name, plan, options): sky_sub_out = np.zeros((2048, 2048), dtype=np.float) sky_model_out = np.zeros((2048, 2048), dtype=np.float) p0 = plan[0].replace("'", "p") p1 = plan[1].replace("'", "p") suffix = "%s-%s" % (p0, p1) xroi = slice(0, 2048) for sol in solutions: if not sol["ok"]: continue yroi = slice(sol["bottom"], sol["top"]) sky_sub_out[yroi, xroi] = sol["output"] sky_model_out[yroi, xroi] = sol["model"] header['BUNIT'] = 'SECOND' IO.writefits(itime, maskname, "itime_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(data, maskname, "sub_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(sky_sub_out, maskname, "bsub_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True) header['BUNIT'] = 'ELECTRONS' IO.writefits(Var, maskname, "var_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) header['BUNIT'] = 'ELECTRONS/SECOND' IO.writefits(sky_model_out, maskname, "bmod_%s_%s_%s.fits" % (maskname, band, suffix), options, header=header, overwrite=True, lossy_compress=True) '''Now create rectified solutions''' dlam = Wavelength.grating_results(band) hpp = np.array(Filters.hpp[band]) ll_fid = np.arange(hpp[0], hpp[1], dlam) nspec = len(ll_fid) rectified = np.zeros((2048, nspec), dtype=np.float32) rectified_var = np.zeros((2048, nspec), dtype=np.float32) rectified_itime = np.zeros((2048, nspec), dtype=np.float32) from scipy.interpolate import interp1d for i in xrange(2048): ll = lam[1][i, :] ss = sky_sub_out[i, :] ok = np.isfinite(ll) & np.isfinite(ss) & (ll < hpp[1]) & (ll > hpp[0]) if len(np.where(ok)[0]) < 100: continue f = interp1d(ll[ok], ss[ok], bounds_error=False) rectified[i, :] = f(ll_fid) f = interp1d(ll, Var[i, :], bounds_error=False) rectified_var[i, :] = f(ll_fid) f = interp1d(ll, itime[i, :], bounds_error=False) rectified_itime[i, :] = f(ll_fid) header["wat0_001"] = "system=world" header["wat1_001"] = "type=linear" header["wat2_001"] = "type=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["type1"] = "AWAV" header["cunit1"] = "Angstrom" header["crval1"] = (ll_fid[0], "Starting wavelength Angstrom") header["crval2"] = 0 header["crpix1"] = 1 header["crpix2"] = 1 header["cdelt1"] = 1 header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = (dlam, "Angstrom/pixel") header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = (1, "pixel/pixel") IO.writefits(rectified_itime, maskname, "%s_rectified_itime_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified, maskname, "%s_rectified_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified_var, maskname, "%s_rectified_var_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True) IO.writefits(rectified * rectified_itime / np.sqrt(rectified_var), maskname, "%s_rectified_sn_%s_%s.fits" % (maskname, band_name, suffix), options, header=header, overwrite=True, lossy_compress=True)
def handle_rectification(maskname, in_files, wavename, band_pass, files, options, commissioning_shift=3.0, target='default'): '''Handle slit rectification and coaddition. Args: maskname: The mask name string in_files: List of stacked spectra in electron per second. Will look like ['electrons_Offset_1.5.txt.fits', 'electrons_Offset_-1.5.txt.fits'] wavename: path (relative or full) to the wavelength stack file, string band_pass: Band pass name, string barset_file: Path to a mosfire fits file containing the full set of FITS extensions for the barset. It can be any file in the list of science files. Returns: None Writes files: [maskname]_[band]_[object name]_eps.fits -- The rectified, background subtracted, stacked eps spectrum [maskname]_[band]_[object name]_sig.fits -- Rectified, background subtracted, stacked weight spectrum (STD/itime) [maskname]_[band]_[object_name]_itime.fits Rectified, CRR stacked integration time spectrum [maskname]_[band]_[object_name]_snrs.fits Rectified signal to noise spectrum ''' global edges, dats, vars, itimes, shifts, lambdas, band, fidl, all_shifts band = band_pass dlambda = Wavelength.grating_results(band) hpp = Filters.hpp[band] fidl = np.arange(hpp[0], hpp[1], dlambda) lambdas = IO.readfits(wavename, options) if np.any(lambdas[1].data < 0) or np.any(lambdas[1].data > 29000): info("***********WARNING ***********") info("The file {0} may not be a wavelength file.".format(wavename)) info("Check before proceeding.") info("***********WARNING ***********") edges, meta = IO.load_edges(maskname, band, options) shifts = [] posnames = [] postoshift = {} for file in in_files: info(":: "+str(file)) II = IO.read_drpfits(maskname, file, options) off = np.array((II[0]["decoff"], II[0]["raoff"]),dtype=np.float64) if "yoffset" in II[0]: off = -II[0]["yoffset"] else: # Deal with data taken during commissioning if II[0]["frameid"] == 'A': off = 0.0 else: off = commissioning_shift try: off0 except: off0 = off shift = off - off0 shifts.append(shift) posnames.append(II[0]["frameid"]) postoshift[II[0]['frameid']] = shift info("Position {0} shift: {1:2.2f} as".format(off, shift)) # this is to deal with cases in which we want to rectify one single file if len(set(posnames)) is 1: plans = [['A']] else: plans = Background.guess_plan_from_positions(set(posnames)) all_shifts = [] for plan in plans: to_append = [] for pos in plan: to_append.append(postoshift[pos]) all_shifts.append(to_append) # Reverse the elements in all_shifts to deal with an inversion all_shifts.reverse() theBPM = IO.badpixelmask() all_solutions = [] cntr = 0 if target is 'default': outname = maskname else: outname = target for plan in plans: if len(plan) is 1: p0 = 'A' p1 = 'B' else: p0 = plan[0].replace("'", "p") p1 = plan[1].replace("'", "p") suffix = "%s-%s" % (p0,p1) info("Handling plan %s" % suffix) fname = "bsub_{0}_{1}_{2}.fits".format(outname,band,suffix) EPS = IO.read_drpfits(maskname, fname, options) EPS[1] = np.ma.masked_array(EPS[1], theBPM, fill_value=0) fname = "var_{0}_{1}_{2}.fits".format(outname, band, suffix) VAR = IO.read_drpfits(maskname, fname, options) VAR[1] = np.ma.masked_array(VAR[1], theBPM, fill_value=np.inf) fname = "itime_{0}_{1}_{2}.fits".format(outname, band, suffix) ITIME = IO.read_drpfits(maskname, fname, options) ITIME[1] = np.ma.masked_array(ITIME[1], theBPM, fill_value=0) dats = EPS vars = VAR itimes = ITIME EPS[0]["ORIGFILE"] = fname tock = time.time() sols = range(len(edges)-1,-1,-1) shifts = all_shifts[cntr] cntr += 1 p = Pool() solutions = p.map(handle_rectification_helper, sols) p.close() all_solutions.append(solutions) tick = time.time() info("-----> Mask took %i. Writing to disk." % (tick-tock)) output = np.zeros((1, len(fidl))) snrs = np.zeros((1, len(fidl))) sdout= np.zeros((1, len(fidl))) itout= np.zeros((1, len(fidl))) # the barset [bs] is used for determining object position files = IO.list_file_to_strings(files) info("Using "+str(files[0])+" for slit configuration.") x, x, bs = IO.readmosfits(files[0], options) for i_slit in xrange(len(solutions)): solution = all_solutions[0][i_slit] header = EPS[0].copy() obj = header['OBJECT'] target_name = bs.ssl[-(i_slit+1)]['Target_Name'] header['OBJECT'] = target_name pixel_dist = np.float(bs.ssl[-(i_slit+1)]['Target_to_center_of_slit_distance'])/0.18 pixel_dist -= solution['offset'] ll = solution["lambda"] header["wat0_001"] = "system=world" header["wat1_001"] = "wtype=linear" header["wat2_001"] = "wtype=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["ctype1"] = "AWAV" header["cunit1"] = "Angstrom" header["crval1"] = ll[0] header["crval2"] = -solution["eps_img"].shape[0]/2 - pixel_dist header["crpix1"] = 1 header["crpix2"] = 1 #remove redundant CDELTi due to wavelength issues with ds9 #see: https://github.com/Keck-DataReductionPipelines/MosfireDRP/issues/44 #header["cdelt1"] = 1 #header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = ll[1]-ll[0] header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = 1 try: header["BARYCORR"]= (lambdas[0]['BARYCORR'],lambdas[0].comments['BARYCORR']) except KeyError: warning( "Barycentric corrections not applied to the wavelength solution") pass S = output.shape img = solution["eps_img"] std = solution["sd_img"] tms = solution["itime_img"] for i_solution in xrange(1,len(all_solutions)): info("Combining solution %i" %i_solution) solution = all_solutions[i_solution][i_slit] img += solution["eps_img"] std += solution["sd_img"] tms += solution["itime_img"] #print "adding in quadrature" output = np.append(output, img, 0) output = np.append(output, np.nan*np.zeros((3,S[1])), 0) snrs = np.append(snrs, img*tms/std, 0) snrs = np.append(snrs, np.nan*np.zeros((3,S[1])), 0) sdout = np.append(sdout, std, 0) sdout = np.append(sdout, np.nan*np.zeros((3,S[1])), 0) itout = np.append(itout, tms, 0) itout = np.append(itout, np.nan*np.zeros((3,S[1])), 0) header['bunit'] = ('electron/second', 'electron power') IO.writefits(img, maskname, "{0}_{1}_{2}_eps.fits".format(outname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('electron/second', 'sigma/itime') IO.writefits(std/tms, maskname, "{0}_{1}_{2}_sig.fits".format(outname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('second', 'exposure time') IO.writefits(tms, maskname, "{0}_{1}_{2}_itime.fits".format(outname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header['bunit'] = ('', 'SNR') IO.writefits(img*tms/std, maskname, "{0}_{1}_{2}_snrs.fits".format(outname, band, target_name), options, overwrite=True, header=header, lossy_compress=False) header = EPS[0].copy() header["wat0_001"] = "system=world" header["wat1_001"] = "wtype=linear" header["wat2_001"] = "wtype=linear" header["dispaxis"] = 1 header["dclog1"] = "Transform" header["dc-flag"] = 0 header["ctype1"] = "AWAV" header["cunit1"] = ("Angstrom", 'Start wavelength') header["crval1"] = ll[0] header["crval2"] = 1 header["crpix1"] = 1 header["crpix2"] = 1 #remove redundant CDELTi due to wavelength issues with ds9 #see: https://github.com/Keck-DataReductionPipelines/MosfireDRP/issues/44 #header["cdelt1"] = 1 #header["cdelt2"] = 1 header["cname1"] = "angstrom" header["cname2"] = "pixel" header["cd1_1"] = (ll[1]-ll[0], 'Angstrom/pixel') header["cd1_2"] = 0 header["cd2_1"] = 0 header["cd2_2"] = 1 try: header["BARYCORR"]= (lambdas[0]['BARYCORR'],lambdas[0].comments['BARYCORR']) except KeyError: warning( "Barycentric corrections not applied to the wavelength solution") pass header["bunit"] = "ELECTRONS/SECOND" info("############ Final reduced file: {0}_{1}_eps.fits".format(outname,band)) IO.writefits(output, maskname, "{0}_{1}_eps.fits".format(outname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "" IO.writefits(snrs, maskname, "{0}_{1}_snrs.fits".format(outname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "ELECTRONS/SECOND" IO.writefits(sdout/itout, maskname, "{0}_{1}_sig.fits".format(outname, band), options, overwrite=True, header=header, lossy_compress=False) header["bunit"] = "SECOND" IO.writefits(itout, maskname, "{0}_{1}_itime.fits".format(outname, band), options, overwrite=True, header=header, lossy_compress=False)