示例#1
0
def test_load_specobjs():
    spec_file = data_path(
        'spec1d_r153-J0025-0312_KASTr_2015Jan23T025323.850.fits')
    specobjs, head0 = load.load_specobjs(spec_file)
    # Test
    assert isinstance(specobjs, SpecObjs)
    assert len(specobjs[0].boxcar['COUNTS']) == 1200
示例#2
0
def test_gen_sensfunc():

    kastb = load_spectrograph('shane_kast_blue')

    # Load a random spectrum for the sensitivity function
    sfile = data_path('spec1d_r153-J0025-0312_KASTr_2015Jan23T025323.850.fits')
    specobjs = load.load_specobjs(sfile)
    #    telescope = telescopes.ShaneTelescopePar()
    fitstbl = dummy_fitstbl()
    RA = '05:06:36.6'
    DEC = '52:52:01.0'

    # Get the sensitivity function
    sens_dict = flux.generate_sensfunc(specobjs[0][0].boxcar['WAVE'],
                                       specobjs[0][0].boxcar['COUNTS'],
                                       specobjs[0][0].boxcar['COUNTS_IVAR'],
                                       fitstbl['airmass'][4],
                                       fitstbl['exptime'][4],
                                       kastb.telescope['longitude'],
                                       kastb.telescope['latitude'],
                                       ra=RA,
                                       dec=DEC)

    # Test
    assert isinstance(sens_dict, dict)
    assert isinstance(sens_dict['wave_min'], units.Quantity)
示例#3
0
    def load_objs(self, spec1d_file, std=True):
        """
        Load specobjs and heade from an input spec1d_file

        Args:
            spec1d_file: str
            std: bool, optional
              If True, load up standard star file and header
              If False, load up science file and header

        Returns:
            Loads up self.std_specobjs or self.sci_specobjs

        """
        specobjs, header = load.load_specobjs(spec1d_file)
        if std:
            self.std_specobjs, self.std_header = specobjs, header
            msgs.info(
                'Loaded {0} spectra from the spec1d standard star file: {1}'.
                format(len(self.std_specobjs), spec1d_file))
            self.std_ra = self.std_header['RA']
            self.std_dec = self.std_header['DEC']
            self.std_file = self.std_header['FILENAME']
        else:
            self.sci_specobjs, self.sci_header = specobjs, header
            msgs.info(
                'Loaded {0} spectra from the spec1d science file: {1}'.format(
                    len(self.sci_specobjs), spec1d_file))
        # Check instrument
        spectro = header['INSTRUME']
        assert spectro == self.spectrograph.spectrograph
        return specobjs, header
示例#4
0
def apply_sens_tell(fnames, sensfile, extinct_correct=True, tell_correct=False, debug=False, show=False):

    sens_meta = Table.read(sensfile, 1)
    sens_table = Table.read(sensfile, 2)

    nexp = np.size(fnames)
    for iexp in range(nexp):
        spec1dfile = fnames[iexp]
        outfile = spec1dfile[:-5] + '_flux.fits'
        sobjs, head = load.load_specobjs(spec1dfile)
        instrument = head['INSTRUME']
        spectrograph = load_spectrograph(instrument)
        airmass, exptime = head['AIRMASS'], head['EXPTIME']
        longitude, latitude = head['LON-OBS'], head['LAT-OBS']

        apply_sens_tell_specobjs(sobjs, sens_meta, sens_table, airmass, exptime, extinct_correct=extinct_correct,
                                tell_correct=tell_correct, longitude=longitude, latitude=latitude,
                                debug=debug, show=show)
        save.save_1d_spectra_fits(sobjs, head, spectrograph, outfile, helio_dict=None, overwrite=True)
示例#5
0
    def get_std_trace(self, std_redux, det, std_outfile):
        """
        Returns the trace of the standard if it is applicable to the current reduction

        Args:
            std_redux (bool): If False, proceed
            det (int): Detector index
            std_outfile (str): Filename for the standard star spec1d file

        Returns:
            ndarray: Trace of the standard star on input detector

        """
        if std_redux is False and std_outfile is not None:
            sobjs, hdr_std = load.load_specobjs(std_outfile)
            # Does the detector match?
            # TODO Instrument specific logic here could be implemented with the parset. For example LRIS-B or LRIS-R we
            # we would use the standard from another detector
            this_det = sobjs.det == det
            if np.any(this_det):
                sobjs_det = sobjs[this_det]
                sobjs_std = sobjs_det.get_std()
                std_trace = sobjs_std.trace_spat
                # flatten the array if this multislit
                if 'MultiSlit' in self.spectrograph.pypeline:
                    std_trace = std_trace.flatten()
                elif 'Echelle' in self.spectrograph.pypeline:
                    std_trace = std_trace.T
                else:
                    msgs.error('Unrecognized pypeline')
            else:
                std_trace = None
        else:
            std_trace = None

        return std_trace
示例#6
0
def load_coadd2d_stacks(spec2d_files, det):
    """

    Args:
        spec2d_files: list
           List of spec2d filenames
        det: int
           detector in question

    Returns:
        stack_dict: dict
           Dictionary containing all the images and keys required for perfomring 2d coadds.

    """

    # Get the detector string
    sdet = parse.get_dnum(det, prefix=False)

    # Get the master dir
    head0 = fits.getheader(spec2d_files[0])
    master_dir = os.path.basename(head0['PYPMFDIR'])
    redux_path =  os.getcwd()
    master_path = os.path.join(redux_path, master_dir)

    # Grab the files
    head2d_list=[]
    tracefiles = []
    waveimgfiles = []
    tiltfiles = []
    spec1d_files = []
    for f in spec2d_files:
        head = fits.getheader(f)
        trace_key = '{0}_{1:02d}'.format(head['TRACMKEY'], det)
        wave_key = '{0}_{1:02d}'.format(head['ARCMKEY'], det)

        head2d_list.append(head)
        spec1d_files.append(f.replace('spec2d', 'spec1d'))
        tracefiles.append(os.path.join(master_path,
                                       MasterFrame.construct_file_name('Trace', trace_key)))
        waveimgfiles.append(os.path.join(master_path,
                                         MasterFrame.construct_file_name('Wave', wave_key)))
        tiltfiles.append(os.path.join(master_path,
                                      MasterFrame.construct_file_name('Tilts', wave_key)))

    nfiles = len(spec2d_files)

    specobjs_list = []
    head1d_list=[]
    # TODO Sort this out with the correct detector extensions etc.
    # Read in the image stacks
    for ifile in range(nfiles):
        waveimg = WaveImage.load_from_file(waveimgfiles[ifile])
        tilts = WaveTilts.load_from_file(tiltfiles[ifile])
        hdu = fits.open(spec2d_files[ifile])
        # One detector, sky sub for now
        names = [hdu[i].name for i in range(len(hdu))]
        # science image
        try:
            exten = names.index('DET{:s}-PROCESSED'.format(sdet))
        except:  # Backwards compatability
            det_error_msg(exten, sdet)
        sciimg = hdu[exten].data
        # skymodel
        try:
            exten = names.index('DET{:s}-SKY'.format(sdet))
        except:  # Backwards compatability
            det_error_msg(exten, sdet)
        skymodel = hdu[exten].data
        # Inverse variance model
        try:
            exten = names.index('DET{:s}-IVARMODEL'.format(sdet))
        except ValueError:  # Backwards compatability
            det_error_msg(exten, sdet)
        sciivar = hdu[exten].data
        # Mask
        try:
            exten = names.index('DET{:s}-MASK'.format(sdet))
        except ValueError:  # Backwards compatability
            det_error_msg(exten, sdet)
        mask = hdu[exten].data
        if ifile == 0:
            # the two shapes accomodate the possibility that waveimg and tilts are binned differently
            shape_wave = (nfiles,waveimg.shape[0],waveimg.shape[1])
            shape_sci = (nfiles,sciimg.shape[0],sciimg.shape[1])
            waveimg_stack = np.zeros(shape_wave,dtype=float)
            tilts_stack = np.zeros(shape_wave,dtype=float)
            sciimg_stack = np.zeros(shape_sci,dtype=float)
            skymodel_stack = np.zeros(shape_sci,dtype=float)
            sciivar_stack = np.zeros(shape_sci,dtype=float)
            mask_stack = np.zeros(shape_sci,dtype=float)

        waveimg_stack[ifile,:,:] = waveimg
        tilts_stack[ifile,:,:] = tilts['tilts']
        sciimg_stack[ifile,:,:] = sciimg
        sciivar_stack[ifile,:,:] = sciivar
        mask_stack[ifile,:,:] = mask
        skymodel_stack[ifile,:,:] = skymodel

        sobjs, head = load.load_specobjs(spec1d_files[ifile])
        head1d_list.append(head)
        specobjs_list.append(sobjs)

    # Right now we assume there is a single tslits_dict for all images and read in the first one
    # TODO this needs to become a tslits_dict for each file to accomodate slits defined by flats taken on different
    # nights
    tslits_dict, _ = TraceSlits.load_from_file(tracefiles[0])
    spectrograph = util.load_spectrograph(tslits_dict['spectrograph'])
    slitmask = pixels.tslits2mask(tslits_dict)
    slitmask_stack = np.einsum('i,jk->ijk', np.ones(nfiles), slitmask)

    # Fill the master key dict
    head2d = head2d_list[0]
    master_key_dict = {}
    master_key_dict['frame'] = head2d['FRAMMKEY']  + '_{:02d}'.format(det)
    master_key_dict['bpm']   = head2d['BPMMKEY']   + '_{:02d}'.format(det)
    master_key_dict['bias']  = head2d['BIASMKEY']  + '_{:02d}'.format(det)
    master_key_dict['arc']   = head2d['ARCMKEY']   + '_{:02d}'.format(det)
    master_key_dict['trace'] = head2d['TRACMKEY']  + '_{:02d}'.format(det)
    master_key_dict['flat']  = head2d['FLATMKEY']  + '_{:02d}'.format(det)
    stack_dict = dict(specobjs_list=specobjs_list, tslits_dict=tslits_dict,
                      slitmask_stack=slitmask_stack,
                      sciimg_stack=sciimg_stack, sciivar_stack=sciivar_stack,
                      skymodel_stack=skymodel_stack, mask_stack=mask_stack,
                      tilts_stack=tilts_stack, waveimg_stack=waveimg_stack,
                      head1d_list = head1d_list, head2d_list=head2d_list,
                      redux_path=redux_path, master_path=master_path, master_dir=master_dir,
                      master_key_dict=master_key_dict,
                      spectrograph = tslits_dict['spectrograph'])

    return stack_dict
示例#7
0
    def generate_sensfunc(self):
        """
        Generate the senstivity function

        Wrapper to flux.generate_sensfunc
          Requires self.std has been set

        Returns
        -------
        self.sensfunc : dict

        """

        # Check internals
        if self.std is None:
            msgs.warn('First identify the star first (with find_standard).')
            return None
        if self.std_header is None:
            msgs.warn(
                'First set std_header with a dict-like object holding RA, DEC, '
                'AIRMASS, EXPTIME.')
            return None

        ext_final = fits.getheader(self.par['std_file'], -1)
        norder = ext_final['ECHORDER'] + 1

        self.sens_dict = {}
        for iord in range(norder):
            std_specobjs, std_header = load.load_specobjs(self.par['std_file'],
                                                          order=iord)
            std_idx = flux.find_standard(std_specobjs)
            std = std_specobjs[std_idx]
            try:
                wavemask = std.optimal['WAVE_GRID'] > 0.0  #*units.AA
            except KeyError:
                wavemask = std.optimal['WAVE'] > 1000.0 * units.AA
                this_wave = std.optimal['WAVE'][wavemask]
            else:
                this_wave = std.optimal['WAVE_GRID'][wavemask]

            counts, ivar = std.optimal['COUNTS'][wavemask], std.optimal[
                'COUNTS_IVAR'][wavemask]
            sens_dict_iord = flux.generate_sensfunc(
                this_wave,
                counts,
                ivar,
                float(self.std_header['AIRMASS']),
                self.std_header['EXPTIME'],
                self.spectrograph.telescope['longitude'],
                self.spectrograph.telescope['latitude'],
                star_type=self.star_type,
                star_mag=self.star_mag,
                telluric=self.telluric,
                ra=self.std_ra,
                dec=self.std_dec,
                resolution=self.resolution,
                BALM_MASK_WID=self.BALM_MASK_WID,
                std_file=self.std_file,
                poly_norder=self.poly_norder,
                polycorrect=self.polycorrect,
                debug=self.debug)
            sens_dict_iord['ech_orderindx'] = iord
            self.sens_dict[str(iord)] = sens_dict_iord
        ## add some keys to be saved into primary header in masterframe
        for key in [
                'wave_max', 'exptime', 'airmass', 'std_file', 'std_ra',
                'std_dec', 'std_name', 'cal_file'
        ]:
            try:
                self.sens_dict[key] = sens_dict_iord[key]
            except:
                pass
        self.sens_dict['meta'] = {}
        self.sens_dict['meta']['nslits'] = norder
        self.sens_dict['wave_min'] = self.sens_dict['0']['wave_min']

        # Step
        self.steps.append(inspect.stack()[0][3])
        # Return
        return self.sens_dict