Exemple #1
0
    def _loader(self):
        """
        Load a filter from the database

        Returns
        -------
        meta: metadata of the spectra (header)
        lam: wavelengths
        flux: flux
        """

        try:  # it should also try to read it from the file directly
            self.wave_unit = units.validate_unit(self.wave_unit)
        except exceptions.SynphotError:
            self.wave_unit = u.AA

        # make try and except here to catch most problems
        if self.data_type == "fits":
            meta, lam, trans = read_fits_spec(self.filename,
                                              ext=1,
                                              wave_unit=self.wave_unit)
            #      wave_col=self.wave_column_name, flux_col=self.trans_column_name)
        elif self.data_type == "ascii":
            meta, lam, trans = read_ascii_spec(self.filename,
                                               wave_unit=self.wave_unit)
            #          wave_col=self.wave_column_name, flux_col=self.trans_column_name)
            # , flux_unit=self._internal_flux_unit,
        lam = lam.to(u.AA)

        return meta, lam, trans.value
Exemple #2
0
    def _loader(self):
        """
        Load a template from the database

        Returns
        -------
        meta: metadata of the spectra (header)
        lam: wavelengths
        flux: flux
        """
        try:
            self.wave_unit = units.validate_unit(self.wave_unit)
            self.flux_unit = units.validate_unit(self.flux_unit)
        except exceptions.SynphotError:  # Assumes angtroms and FLAM
            self.wave_unit = u.AA
            self.flux_unit = units.FLAM

    #   self.resolution = self.resolution * self.wave_unit

        if self.data_type == "fits":  # make try and except here to catch most problems
            meta, lam, flux = read_fits_spec(self.path,
                                             ext=1,
                                             wave_unit=self.wave_unit,
                                             flux_unit=self.flux_unit,
                                             wave_col=self.wave_column_name,
                                             flux_col=self.flux_column_name)
        else:
            meta, lam, flux = read_ascii_spec(self.path,
                                              wave_unit=self.wave_unit,
                                              flux_unit=self.flux_unit)

        return meta, lam, flux
Exemple #3
0
    def _loader(self):
        """
        Load a filter from the database

        Returns
        -------
        meta: metadata of the spectra (header)
        lam: wavelengths
        flux: flux
        """

        try:  # it should also try to read it from the file directly
            self.wave_unit = units.validate_unit(self.wave_unit)
        except exceptions.SynphotError:
            self.wave_unit = u.AA

        if self.data_type == "fits":
            meta, lam, rvs = read_fits_spec(
                self.filename,
                ext=1,
                wave_unit=self.wave_unit,
                flux_unit=self.extinction_unit,
                # self._internal_flux_unit,
                wave_col=self.wave_column,
                flux_col=self.extinction_column)
        elif self.data_type == "ascii":
            meta, lam, rvs = read_ascii_spec(
                self.filename,
                wave_unit=self.wave_unit,
                flux_unit=self.extinction_unit,
                # self._internal_flux_unit,
                wave_col=self.wave_column,
                flux_col=self.extinction_column)

        return meta, lam, rvs
Exemple #4
0
    def set_bandpass_from_filter(self, filtername):
        """Loads the specified <filtername> from the transmission profile file
        which is mapped via the etc.config.Conf() items.
        Returns a SpectralElement instance for the filter profile
        """

        if len(filtername) == 2 and filtername[1] == 'p':
            filtername = filtername[0]

        filename = conf.mapping.get(filtername, None)
        if filename is None:
            raise ETCError('Filter name {0} is invalid.'.format(filtername))
        if 'LCO_' in filename().upper() and '.csv' in filename().lower():
            file_path = pkg_resources.files('etc.data').joinpath(
                os.path.expandvars(filename()))
            source = "LCO iLab format"
            header, wavelengths, throughput = self._read_lco_filter_csv(
                file_path)
        elif 'http://svo' in filename().lower():
            source = "SVO filter service"
            header, wavelengths, throughput = specio.read_remote_spec(
                filename(), wave_unit=u.AA, flux_unit=units.THROUGHPUT)
        else:
            source = "local file"
            file_path = pkg_resources.files('etc.data').joinpath(
                os.path.expandvars(filename()))
            warnings.simplefilter('ignore', category=AstropyUserWarning)
            header, wavelengths, throughput = specio.read_ascii_spec(
                file_path, wave_unit=u.nm, flux_unit=units.THROUGHPUT)
            if throughput.mean() > 1.0:
                throughput /= 100.0
                header['notes'] = 'Divided by 100.0 to convert from percentage'
        print("Reading from {} for {}".format(source, filtername))

        header['filename'] = filename
        header['descrip'] = filename.description
        meta = {'header': header, 'expr': filtername}

        return SpectralElement(Empirical1D,
                               points=wavelengths,
                               lookup_table=throughput,
                               meta=meta)
Exemple #5
0
    def __init__(self, name=None, camera_type="CCD", **kwargs):
        _cam_types = [
            "CCD",
        ]
        self.camera_type = camera_type.upper() if camera_type.upper(
        ) in _cam_types else "CCD"
        self.name = name if name is not None else self.camera_type + ' camera'

        # Defaults assume no elements per channel on the assumption that it's
        # in the common optics (populated in Instrument())
        self.num_ar_coatings = kwargs.get('num_chan_ar_coatings', 0)
        self.num_lenses = kwargs.get('num_chan_lenses', 0)
        self.num_mirrors = kwargs.get('num_chan_mirrors', 0)

        # Fused silica (common lens material) and fused quartz (common for CCD windows)
        # turn out to have the same transmission...
        self.lens_trans = kwargs.get('chan_lens_trans', 0.93)

        self.mirror_refl = kwargs.get('chan_mirror_refl', 0.9925)
        # Transmission/Reflection values of optical elements coating
        self.ar_coating = kwargs.get('chan_ar_coating_refl', 0.99)

        # Read common components first
        trans_components = kwargs.get('trans_components', None)
        wavelengths = np.arange(300, 1501, 1) * u.nm
        if trans_components:
            print("Computing channel transmission from components")
            trans = len(wavelengths) * [
                1.0,
            ]
            for comp_name in trans_components.split(","):
                print(comp_name)
                element = read_element(comp_name)
                trans *= element(wavelengths)
        else:
            print("Computing channel transmission from elements")
            transmission = self._compute_transmission()
            trans = len(wavelengths) * [
                transmission,
            ]
        header = {}
        self.transmission = SpectralElement(Empirical1D,
                                            points=wavelengths,
                                            lookup_table=trans,
                                            keep_neg=True,
                                            meta={'header': header})

        ccd_qe = kwargs.get('ccd_qe', 0.9)
        if not isinstance(ccd_qe, (u.Quantity, numbers.Number)):
            file_path = os.path.expandvars(ccd_qe)
            if not os.path.exists(file_path):
                file_path = str(
                    pkg_resources.files('etc.data').joinpath(ccd_qe))
            header, wavelengths, throughput = specio.read_ascii_spec(
                file_path, wave_unit=u.nm, flux_unit=units.THROUGHPUT)
            if throughput.mean() > 1.0:
                throughput /= 100.0
                header['notes'] = 'Divided by 100.0 to convert from percentage'
            header['filename'] = ccd_qe
            self.ccd_qe = BaseUnitlessSpectrum(Empirical1D,
                                               points=wavelengths,
                                               lookup_table=throughput,
                                               keep_neg=False,
                                               meta={'header': header})
        else:
            self.ccd_qe = ccd_qe
        self.ccd_gain = kwargs.get('ccd_gain', 1) * (u.electron / u.adu)
        self.ccd_readnoise = kwargs.get('ccd_readnoise',
                                        0) * (u.electron / u.pix)
        ccd_pixsize = kwargs.get('ccd_pixsize', 0)
        try:
            ccd_pixsize_units = u.Unit(
                kwargs.get('ccd_pixsize_units', 'micron'))
        except ValueError:
            ccd_pixsize_units = u.micron
        self.ccd_pixsize = (ccd_pixsize * ccd_pixsize_units).to(u.micron)
        self.ccd_xpixels = kwargs.get('ccd_xpixels', 0)
        self.ccd_ypixels = kwargs.get('ccd_ypixels', 0)
        self.ccd_xbinning = kwargs.get('ccd_xbinning', 1)
        self.ccd_ybinning = kwargs.get('ccd_ybinning', 1)
Exemple #6
0
def read_element(filtername_or_filename,
                 element_type='element',
                 wave_units=u.nm,
                 flux_units=units.THROUGHPUT):
    """Generic reader for optical elements, filters and others.
    The passed <filtername_or_filename> is first looked up in the `Conf` mapping
    dictionary for a match; if there is no match, it is assumed to be a filename
    or location specifier. These can be of 3 types:
    1. LCO Imaging Lab scanned optical element CSV files (contain 'LCO_' and '.csv' in the filename)
    2. SVO filter service references (contain 'http://svo')
    3. Local files (either ASCII or FITS)

    Checking on the read wavelengths is performed for local files:
    * if the first wavelength value is <100nm and the user didn't override the
    units through [wave_units], the wavelengths are assumed to be in, and are
    converted to, microns.
    * if the first wavelength value is >3000nm and the user didn't override the
    units through [wave_units], the wavelengths are assumed to be in, and are
    converted to, angstroms.
    """

    element_type = element_type.lower()
    filename = conf.mapping.get(filtername_or_filename, None)
    if filename is None:
        filename = filtername_or_filename
    else:
        filename = filename()
        element_type = 'spectral_element'
    if 'LCO_' in filename.upper() and '.csv' in filename.lower():
        file_path = pkg_resources.files('etc.data').joinpath(
            os.path.expandvars(filename))
        source = "LCO iLab format"
        header, wavelengths, throughput = read_lco_filter_csv(file_path)
    elif 'http://svo' in filename.lower():
        source = "SVO filter service"
        header, wavelengths, throughput = specio.read_remote_spec(
            filename, wave_unit=u.AA, flux_unit=units.THROUGHPUT)
    else:
        source = "local file"
        file_path = os.path.expandvars(filename)
        if not os.path.exists(file_path):
            file_path = str(pkg_resources.files('etc.data').joinpath(filename))
        warnings.simplefilter('ignore', category=AstropyUserWarning)
        if filename.lower().endswith('fits') or filename.lower().endswith(
                'fit'):
            try:
                header, wavelengths, throughput = specio.read_spec(
                    file_path,
                    wave_col='lam',
                    flux_col='trans',
                    wave_unit=u.nm,
                    flux_unit=u.dimensionless_unscaled)
            except KeyError:
                # ESO-SM01 format; different column name for transmission and micron vs nm
                header, wavelengths, throughput = specio.read_spec(
                    file_path,
                    wave_col='lam',
                    flux_col='flux',
                    wave_unit=u.micron,
                    flux_unit=u.dimensionless_unscaled)
        else:
            header, wavelengths, throughput = specio.read_ascii_spec(
                file_path, wave_unit=wave_units, flux_unit=flux_units)
        if wavelengths[0].value < 100.0 and wave_units == u.nm:
            # Small values seen, Convert to microns
            wavelengths = wavelengths.value * u.micron
        elif wavelengths[0].value > 3000.0 and wave_units == u.nm:
            # Large values seen, Convert to angstroms
            wavelengths = wavelengths.value * u.AA
        if element_type != 'spectrum' and throughput.mean() > 1.5:
            # Test for mean throughput is above 1 to catch case where a throughput
            # fudge may be in the range ~1 to a few e.g. ESO Omegacam optics fudge
            # which goes to 3.2 and averages out to ~1.4
            throughput /= 100.0
            header['notes'] = 'Divided by 100.0 to convert from percentage'
    header['source'] = source
    header['filename'] = filename
    if element_type == 'spectrum':
        # SourceSpectrum can't use the default units.THROUGHPUT so we need to
        # change to an assumed units.PHOTLAM (u.photon / (u.cm**2 * u.s * u.AA))
        # if nothing was passed by the user
        if flux_units == units.THROUGHPUT:
            throughput = throughput.value * units.PHOTLAM
        element = SourceSpectrum(Empirical1D,
                                 points=wavelengths,
                                 lookup_table=throughput,
                                 keep_neg=False,
                                 meta={'header': header})
    elif element_type == 'spectral_element':
        element = SpectralElement(Empirical1D,
                                  points=wavelengths,
                                  lookup_table=throughput,
                                  keep_neg=False,
                                  meta={'header': header})
    else:
        element = BaseUnitlessSpectrum(Empirical1D,
                                       points=wavelengths,
                                       lookup_table=throughput,
                                       keep_neg=False,
                                       meta={'header': header})

    return element