From 983de7a16ece7b2ec993d423cff8eb4a8db36080 Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Sat, 26 Aug 2017 11:06:19 +0800 Subject: foregrounds.py: Remove foreground components combination * Remove output configs "combine", "combine_prefix", "output_dir" * Remove configuration checker "check_output" --- fg21sim/configs/00-general.conf.spec | 9 --- fg21sim/configs/checkers.py | 15 +---- fg21sim/foregrounds.py | 126 +++++------------------------------ 3 files changed, 19 insertions(+), 131 deletions(-) diff --git a/fg21sim/configs/00-general.conf.spec b/fg21sim/configs/00-general.conf.spec index 9d9847d..49525d6 100644 --- a/fg21sim/configs/00-general.conf.spec +++ b/fg21sim/configs/00-general.conf.spec @@ -103,15 +103,6 @@ checksum = boolean(default=False) # Whether overwrite existing files clobber = boolean(default=False) -# Whether combine all components and output -combine = boolean(default=True) -# Prefix for the combined files -combine_prefix = string(default="fg") -# Output directory to place the combined products -# NOTE: This config is mandatory and should be provided by the user -# if above "combine=True". -output_dir = string(default=None) - # Filename of the simulation products manifest (JSON format), which # records all output products together with their sizes and MD5 hashes. # Do not create such a manifest if this option is not specified. diff --git a/fg21sim/configs/checkers.py b/fg21sim/configs/checkers.py index ffb1e63..698311d 100644 --- a/fg21sim/configs/checkers.py +++ b/fg21sim/configs/checkers.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Weitian LI +# Copyright (c) 2016-2017 Weitian LI # MIT license """ @@ -93,14 +93,6 @@ def check_frequency(configs): return results -def check_output(configs): - """Check the "[output]" section of the configurations.""" - results = {} - if configs.getn("output/combine"): - results.update(_check_missing(configs, "output/output_dir")) - return results - - def check_galactic_synchrotron(configs): """Check the "[galactic][synchrotron]" section of the configurations.""" comp = "galactic/synchrotron" @@ -187,7 +179,6 @@ _CHECKERS = [ check_foregrounds, check_sky, check_frequency, - check_output, check_galactic_synchrotron, check_galactic_freefree, check_galactic_snr, @@ -205,13 +196,13 @@ def check_configs(configs, raise_exception=True, checkers=_CHECKERS): Parameters ---------- - configs : `ConfigManager` instance + configs : `~ConfigManager` An ``ConfigManager`` instance contains both default and user configurations. raise_exception : bool, optional Whether raise a ``ConfigError`` exception if there is any invalid config options? - checkers : list of functions, optional + checkers : list[function], optional List of checker functions through which the configurations will be checked. diff --git a/fg21sim/foregrounds.py b/fg21sim/foregrounds.py index abb829f..2605438 100644 --- a/fg21sim/foregrounds.py +++ b/fg21sim/foregrounds.py @@ -13,22 +13,15 @@ Currently supported foregrounds: - Extragalactic point sources (multiple types) """ -import os import logging -from datetime import datetime, timezone from collections import OrderedDict -import numpy as np -import astropy.units as au -from astropy.io import fits - from .galactic import (Synchrotron as GalacticSynchrotron, FreeFree as GalacticFreeFree, SuperNovaRemnants as GalacticSNR) from .extragalactic import (GalaxyClusters as EGGalaxyClusters, PointSources as EGPointSources) from .products import Products -from .sky import get_sky logger = logging.getLogger(__name__) @@ -38,12 +31,9 @@ class Foregrounds: """ Interface to the simulations of supported foreground components. - All the enabled components are also combined to make the total foreground - map, as controlled by the configurations. - Parameters ---------- - configs : `ConfigManager` + configs : `~ConfigManager` An `ConfigManager` instance containing both the default and user configurations. For more details, see the example configuration specification. @@ -62,8 +52,6 @@ class Foregrounds: instance/object. frequencies : 1D `~numpy.ndarray` List of frequencies where the foreground components are simulated. - freq_unit : `~astropy.units.Unit` - Unit of the frequency """ # All supported foreground components COMPONENTS_ALL = OrderedDict([ @@ -77,6 +65,7 @@ class Foregrounds: def __init__(self, configs): self.configs = configs self._set_configs() + # Initialize the products manifest logger.info("Initialize the products manifest ...") self.manifestfile = self.configs.get_path("output/manifest") @@ -85,6 +74,7 @@ class Foregrounds: else: self.products = None logger.warning("Output products manifest not configured!") + # Initialize enabled components self.components = OrderedDict() for comp in self.components_id: @@ -94,7 +84,9 @@ class Foregrounds: logger.info("Done initialize %d components!" % len(self.components)) def _set_configs(self): - """Load the configs and set the corresponding class attributes.""" + """ + Load the configs and set the corresponding class attributes. + """ self.components_id = self.configs.foregrounds[0] logger.info("All supported simulation components: {0}".format( ", ".join(list(self.COMPONENTS_ALL.keys())))) @@ -102,127 +94,41 @@ class Foregrounds: ", ".join(self.components_id))) # self.frequencies = self.configs.frequencies - self.freq_unit = au.Unit(self.configs.getn("frequency/unit")) logger.info("Simulation frequencies: " - "{min:.2f} - {max:.2f} {unit} (#{num:d})".format( + "{min:.2f} - {max:.2f} [MHz] (#{num:d})".format( min=min(self.frequencies), max=max(self.frequencies), - num=len(self.frequencies), - unit=self.freq_unit)) + num=len(self.frequencies))) # - self.filename_pattern = self.configs.getn("output/filename_pattern") - self.use_float = self.configs.getn("output/use_float") - self.checksum = self.configs.getn("output/checksum") self.clobber = self.configs.getn("output/clobber") - self.combine = self.configs.getn("output/combine") - self.prefix = self.configs.getn("output/combine_prefix") - self.output_dir = self.configs.get_path("output/output_dir") - def _make_filepath(self, **kwargs): - """ - Make the path of output file according to the filename pattern - and output directory loaded from configurations. - """ - data = { - "prefix": self.prefix, - } - data.update(kwargs) - filename = self.filename_pattern.format(**data) - filepath = os.path.join(self.output_dir, filename) - return filepath - - def _make_header(self): - """ - Make the header with detail information (e.g., parameters and - history) for the simulated products. - """ - header = fits.Header() - header["COMP"] = ("Combined foreground", "Emission component") - header.add_comment("COMPONENTS: " + ", ".join(self.components_id)) - header["UNIT"] = ("Kelvin", "Map unit") - header["CREATOR"] = (__name__, "File creator") - # TODO: - history = [] - comments = [] - for hist in history: - header.add_history(hist) - for cmt in comments: - header.add_comment(cmt) - self.header = header - logger.info("Created FITS header") - - def _output(self, skymap, frequency): + def preprocess(self): """ - Write the simulated free-free map to disk with proper header - keywords and history. - - Returns - ------- - outfile : str - The (absolute) path to the output sky map file. + Perform the preparation procedures for the final simulations. """ - outfile = self._make_filepath(frequency=frequency) - if not hasattr(self, "header"): - self._make_header() - header = self.header.copy() - header["FREQ"] = (frequency, "Frequency [ MHz ]") - header["DATE"] = ( - datetime.now(timezone.utc).astimezone().isoformat(), - "File creation date" - ) - if self.use_float: - skymap = skymap.astype(np.float32) - sky = get_sky(configs=self.configs) - sky.data = skymap - sky.header = header - sky.write(outfile, clobber=self.clobber, checksum=self.checksum) - return outfile - - def preprocess(self): - """Perform the preparation procedures for the final simulations.""" if self.products: - self.products.frequencies = (self.frequencies, - str(self.freq_unit)) + self.products.frequencies = (self.frequencies, "MHz") logger.info("Perform preprocessing for all enabled components ...") for comp_obj in self.components.values(): comp_obj.preprocess() def simulate(self): """ - Simulate the enabled components, as well as combine all the - simulated components to make up the total foregrounds. - - This is the *main interface* to the foreground simulations. - - NOTE - ---- - For each requested frequency, all enabled components are simulated, - which are combined to compose the total foreground and save to disk. - In this way, less memory is required, since the number of components - are generally much less than the number of frequency bins. + Simulate the enabled components. """ - sky = get_sky(configs=self.configs) nfreq = len(self.frequencies) for freq_id, freq in enumerate(self.frequencies): logger.info("[#{0}/{1}] ".format(freq_id+1, nfreq) + - "Simulating components at {freq} {unit} ...".format( - freq=freq, unit=self.freq_unit)) - if self.combine: - skymap_comb = np.zeros(shape=sky.shape) + "Simulating components at %.2f [MHz] ..." % freq) for comp_id, comp_obj in self.components.items(): skymap, filepath = comp_obj.simulate_frequency(freq) if filepath and self.products: self.products.add_product(comp_id, freq_id, filepath) - if self.combine: - skymap_comb += skymap - if self.combine: - filepath_comb = self._output(skymap_comb, freq) - if self.products: - self.products.add_product("combined", freq_id, - filepath_comb) def postprocess(self): - """Perform the post-simulation operations before the end.""" + """ + Perform the post-simulation operations before the end. + """ logger.info("Perform postprocessing for all enabled components ...") for comp_obj in self.components.values(): comp_obj.postprocess() -- cgit v1.2.2