def real_spec(request): band = request.param wav, flux = load_aces_spectrum([3900, 4.5, 0.0, 0]) wav, flux = wav_selector(wav, flux, *band_limits(band)) flux = flux / snr_constant_band(wav, flux, 100, band) atm = Atmosphere.from_band(band).at(wav) return wav, flux, atm.transmission
def test_band_limits(band): """Test getting limits out of band.""" band_min, band_max = utils.band_limits(band) assert band_min < band_max assert band_min != band_max assert 0 < band_min < 3 assert 0 < band_max < 3
def test_from_band_is_a_constructor(band): """This is testing loading files using from_band method.""" atm = Atmosphere.from_band(band) min_wl, max_wl = band_limits(band) assert isinstance(atm, Atmosphere) assert np.all(atm.wl <= max_wl * 1.01) assert np.all(atm.wl >= min_wl * 0.99)
def test_band_middle(band): """Test band middle is middle of band. Some repeated coding. """ lower, upper = utils.band_limits(band) middle = utils.band_middle(band) assert lower < middle assert middle < upper assert (lower + upper) / 2 == middle
def test_band_selector(band): """Test band selector selects the wav and flux in the given band.""" wav = np.linspace(0.5, 3, 100) flux = wav**2 band_min, band_max = utils.band_limits(band) assert not np.all(wav > band_min) # Assert wav goes outside band assert not np.all(wav < band_max) wav, flux = utils.band_selector(wav, flux, band) assert np.all(wav > band_min) assert np.all(wav < band_max)
def test_snr_constant_band_returns_mid_value_const(band): size = 100 np.random.seed(40) flux = 500 * np.random.rand( size ) # To give a random spectrum (but consistent between tests) lim = utils.band_limits(band) wav = np.linspace(lim[0], lim[1], size) band_const = snrnorm.snr_constant_band(wav, flux, band=band) wav_const = snrnorm.snr_constant_wav(wav, flux, wav_ref=utils.band_middle(band)) assert isinstance(band_const, float) assert isinstance(wav_const, float) assert band_const == wav_const # Since band calls wave at midpoint
def test_valid_snr_get_reference_spectrum(): """Testing getting the reference spectrum.""" ref_band = "J" wav_ref, flux_ref = eniric.obsolete.snr_norm.get_reference_spectrum( "M0-K-1.0-100k", ref_band=ref_band) band_min, band_max = utils.band_limits(ref_band) # Test the wavelength is in the reference band wavelength range assert np.all(wav_ref <= band_max) assert np.all(wav_ref >= band_min) # test properties of output assert len(wav_ref) == len(flux_ref) assert isinstance(wav_ref, np.ndarray) assert isinstance(flux_ref, np.ndarray)
def test_snr_normalization_logic(band): """Testing direct value. snr = sqrt(sum(3 pixels)) const = (snr/ref_snr)**2 if pixel value = 3 then the normalization constant will be 1. """ size = 100 band = "K" lim = utils.band_limits(band) wav = np.linspace(lim[0], lim[1], size) flux = 3 * np.ones(size) band_const = snrnorm.snr_constant_band(wav, flux, snr=3, band=band) wav_const = snrnorm.snr_constant_wav( wav, flux, snr=3, wav_ref=(lim[0] + lim[1]) / 2 ) assert band_const == 1 assert wav_const == 1
def from_band(cls, band: str, bary: bool = False): """Read in atmospheric model for given band. Alternate constructor for Atmosphere. Base on "base" path in config.yaml. Parameters ---------- band: str Name of atmosphere file. bary: bool Barycentric shift the mask. """ extension = "_bary.dat" if bary else ".dat" atmmodel = join( config.pathdir, config.paths["atmmodel"], "{0}_{1}{2}".format(config.atmmodel["base"], band, extension), ) try: # Try find the band file atm = cls.from_file(atmmodel) except IOError: warnings.warn("""Could not find band file for band {0}. It is recommend to create this using `split_atmosphere.py -b {0}` `barycenter_broaden_atmmodel.py -b {0}` Trying to load main atmosphere file for now. (will be slower).""". format(band)) full_model = join( config.pathdir, config.paths["atmmodel"], "{0}.dat".format(config.atmmodel["base"]), ) atm = cls.from_file(full_model) # Shorten to band atm = atm.wave_select(*band_limits(band)) if bary: atm.barycenter_broaden(consecutive_test=True) return atm
def main( model: str = atmmodel, bands: Optional[List[str]] = None, new_name: Optional[str] = None, data_dir: Optional[str] = None, rv_extend: float = 100, cutoff_depth: float = 2.0, ): """Split the large atmospheric model transmission spectra into the separate bands. Keeps wavelength of atmosphere model as nanometers. Parameters ---------- model: str Telluric model file to load. It has columns wavelength, flux, std_flux, mask. bands: list[str] List bands to split model into separate files. new_name: str New file name base. data_dir: Optional[str] Directory for results. Can also be given in config.yaml "paths:atmmodel:"... rv_extend: float (positive) (default 100) Rv amount to extend wavelength range of telluric band. To later apply barycenter shifting. cutoff_depth: float Telluric line depth cutoff. Default = 2%. """ if (bands is None) or ("ALL" in bands): bands_ = eniric.bands["all"] else: bands_ = bands if new_name is None: new_name = model.split(".")[0] if data_dir is None: data_dir_ = eniric.paths["atmmodel"] else: data_dir_ = str(data_dir) model_name = join(data_dir_, model) # If trying to obtain the provided model extract from and it doesn't yet exist # extract from tar.gz file. (Extracted it is 230 MB which is to large for Git) if "Average_TAPAS_2014.dat" == atmmodel: if not os.path.exists(model_name): print("Unpacking Average_TAPAS_2014.dat.tar.gz...") import tarfile with tarfile.open(str(model_name) + ".tar.gz", "r") as tar: tar.extractall(data_dir_) print("Unpacked") print("Loading from_file {0}".format(model_name)) atm = Atmosphere.from_file(model_name) # Return value from saving each band write_status = np.empty_like(bands_, dtype=int) for i, band in enumerate(bands_): print("Starting {0}".format(band)) filename_band = "{0}_{1}.dat".format(new_name, band) band_min, band_max = band_limits(band) # * 1000 to convert into km/s band_min = doppler_shift_wav(band_min, -rv_extend) band_max = doppler_shift_wav(band_max, rv_extend) split_atm = atm.wave_select(band_min, band_max) # Apply telluric line mask atm.mask_transmission(depth=cutoff_depth) # Save the result to file filename = join(data_dir_, filename_band) header = ["# atm_wav(nm)", "atm_flux", "atm_std_flux", "atm_mask"] print("Saving to_file {}".format(filename)) write_status[i] = split_atm.to_file(filename, header=header, fmt="%11.8f") print("Done Splitting") return np.sum(write_status) # If any extracts fail they will turn up here.
def test_band_limits_raises_errors(band, error): """Test it raises the Value and Attribute Errors.""" with pytest.raises(error): utils.band_limits(band)
def band_select(self, band): """Slice Atmosphere to a given Band.""" wl_min, wl_max = band_limits(band) return self.wave_select(wl_min, wl_max)