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
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
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
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)
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)
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