Commit 4fcb6311 authored by Yannick Roehlly's avatar Yannick Roehlly
Browse files

Use ordered dictionaries for parameters

So that the configuration files and the serialized data have a logical
order.
parent 325f5cd7
...@@ -4,19 +4,20 @@ ...@@ -4,19 +4,20 @@
# Author: Yannick Roehlly <yannick.roehlly@oamp.fr> # Author: Yannick Roehlly <yannick.roehlly@oamp.fr>
from importlib import import_module from importlib import import_module
from collections import OrderedDict
class AnalysisModule(object): class AnalysisModule(object):
"""Abstract class, the pCigale analysis modules are based on. """Abstract class, the pCigale analysis modules are based on.
""" """
# parameter_list is a dictionary containing all the parameters used by the # parameter_list is a ordered dictionary containing all the parameters
# module. Each parameter name is associate to a tuple (variable type, # used by the module. Each parameter name is associate to a tuple
# description [string], default value). Each module must define its # (variable type, description [string], default value). Each module must
# parameter list, unless it does not use any parameter. Using None means # define its parameter list, unless it does not use any parameter. Using
# that there is no description, unit or default value. If None should be # None means that there is no description, unit or default value. If None
# the default value, use the 'None' string instead. # should be the default value, use the 'None' string instead.
parameter_list = {} parameter_list = OrderedDict()
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Instantiate a analysis module """Instantiate a analysis module
......
...@@ -21,6 +21,7 @@ import sys ...@@ -21,6 +21,7 @@ import sys
import atpy import atpy
import json import json
import numpy as np import numpy as np
from collections import OrderedDict
from copy import deepcopy from copy import deepcopy
from scipy import stats from scipy import stats
from progressbar import ProgressBar from progressbar import ProgressBar
...@@ -48,56 +49,56 @@ class Module(common.AnalysisModule): ...@@ -48,56 +49,56 @@ class Module(common.AnalysisModule):
TODO: Description of the PSUM method. TODO: Description of the PSUM method.
""" """
parameter_list = { parameter_list = OrderedDict([
"analysed_variables": ( ("analysed_variables", (
"array of strings", "array of strings",
"List of the variables (in the SEDs info dictionaries) for which " "List of the variables (in the SEDs info dictionaries) for which "
"the statistical analysis will be done.", "the statistical analysis will be done.",
["sfr", "average_sfr"] ["sfr", "average_sfr"]
), )),
"save_best_sed": ( ("save_best_sed", (
"boolean", "boolean",
"If true, save the best SED for each observation to a file.", "If true, save the best SED for each observation to a file.",
False False
), )),
"plot_best_sed": ( ("plot_best_sed", (
"boolean", "boolean",
"If true, for each observation save a plot of the best SED " "If true, for each observation save a plot of the best SED "
"and the observed fluxes.", "and the observed fluxes.",
False False
), )),
"plot_chi2_distribution": ( ("plot_chi2_distribution", (
"boolean", "boolean",
"If true, for each observation and each analysed variable " "If true, for each observation and each analysed variable "
"plot the value vs reduced chi-square distribution.", "plot the value vs reduced chi-square distribution.",
False False
), )),
"save_pdf": ( ("save_pdf", (
"boolean", "boolean",
"If true, for each observation and each analysed variable " "If true, for each observation and each analysed variable "
"save the probability density function.", "save the probability density function.",
False False
), )),
"plot_pdf": ( ("plot_pdf", (
"boolean", "boolean",
"If true, for each observation and each analysed variable " "If true, for each observation and each analysed variable "
"plot the probability density function.", "plot the probability density function.",
False False
), )),
"pdf_max_bin_number": ( ("pdf_max_bin_number", (
"integer", "integer",
"Maximum number of bins used to compute the probability density " "Maximum number of bins used to compute the probability density "
"function. This is only used when saving or printing the PDF. " "function. This is only used when saving or printing the PDF. "
"If there are less values, the probability is given for each " "If there are less values, the probability is given for each "
"one.", "one.",
50 50
), )),
"storage_type": ( ("storage_type", (
"string", "string",
"Type of storage used to cache the generate SED.", "Type of storage used to cache the generate SED.",
"memory" "memory"
) ))
} ])
def process(self, data_file, column_list, sed_modules, def process(self, data_file, column_list, sed_modules,
sed_modules_params, redshift_module_name, sed_modules_params, redshift_module_name,
......
...@@ -14,6 +14,7 @@ The data file is used only to get the list of fluxes to be computed. ...@@ -14,6 +14,7 @@ The data file is used only to get the list of fluxes to be computed.
import os import os
from itertools import product from itertools import product
from collections import OrderedDict
from datetime import datetime from datetime import datetime
from astropy.table import Table from astropy.table import Table
from progressbar import ProgressBar from progressbar import ProgressBar
...@@ -29,24 +30,24 @@ class Module(common.AnalysisModule): ...@@ -29,24 +30,24 @@ class Module(common.AnalysisModule):
""" """
parameter_list = { parameter_list = OrderedDict([
"output_file": ( ("output_file", (
"string", "string",
"Name of the output file.", "Name of the output file.",
"computed_fluxes.xml" "computed_fluxes.xml"
), )),
"output_format": ( ("output_format", (
"string", "string",
"Format of the output file. Any format supported by astropy.table " "Format of the output file. Any format supported by astropy.table "
"e.g. votable or ascii.", "e.g. votable or ascii.",
"votable" "votable"
), )),
"storage_type": ( ("storage_type", (
"string", "string",
"Type of storage used to cache the generate SED.", "Type of storage used to cache the generate SED.",
"memory" "memory"
) ))
} ])
def process(self, data_file, column_list, sed_modules, def process(self, data_file, column_list, sed_modules,
sed_modules_params, redshift_module, sed_modules_params, redshift_module,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
# Author: Yannick Roehlly <yannick.roehlly@oamp.fr> # Author: Yannick Roehlly <yannick.roehlly@oamp.fr>
import numpy as np import numpy as np
from collections import OrderedDict
from . import common from . import common
from ...data import Database from ...data import Database
...@@ -18,40 +19,40 @@ class Module(common.SEDCreationModule): ...@@ -18,40 +19,40 @@ class Module(common.SEDCreationModule):
Bruzual and Charlot (2003) models. Bruzual and Charlot (2003) models.
""" """
parameter_list = { parameter_list = OrderedDict([
"imf": ( ("imf", (
"string", "string",
"Initial mass function: salp (Salpeter) or chab (Chabrier)", "Initial mass function: salp (Salpeter) or chab (Chabrier)",
None None
), )),
"metallicity": ( ("metallicity", (
"float", "float",
"Mettalicity, 0.02 for Solar metallicity.", "Mettalicity, 0.02 for Solar metallicity.",
None None
), )),
"separation_age": ( ("separation_age", (
"integer", "int",
"Age [Myr] of the separation between the young and the old star " "Age [Myr] of the separation between the young and the old star "
"populations. The default value in 10^7 years (10 Myr). Set " "populations. The default value in 10^7 years (10 Myr). Set "
"to 0 not to differentiate ages (only an old population).", "to 0 not to differentiate ages (only an old population).",
10 10
) ))
} ])
out_parameter_list = { out_parameter_list = OrderedDict([
"sfr": "Instantaneous Star Formation Rate in solar mass per year, " ("sfr", "Instantaneous Star Formation Rate in solar mass per year, "
"at the age of the galaxy.", "at the age of the galaxy."),
"average_sfr": "Average SFR in the last 100 Myr (default) of the " ("average_sfr", "Average SFR in the last 100 Myr (default) of the "
"galaxy history.", "galaxy history."),
"m_star": "Total mass in stars in Solar mass.", ("m_star", "Total mass in stars in Solar mass."),
"m_gas": "Mass returned to the ISM by evolved stars in Solar mass.", ("m_gas", "Mass returned to the ISM by evolved stars in Solar mass."),
"n_ly": "rate of H-ionizing photons in s^-1, per Solar mass " ("n_ly", "rate of H-ionizing photons in s^-1, per Solar mass "
"of galaxy.", "of galaxy."),
"b_4000": "Amplitude of 4000 Å break (Bruzual 2003)", ("b_4000", "Amplitude of 4000 Å break (Bruzual 2003)"),
"b4_vn": "Amplitude of 4000 Å narrow break (Balogh et al. 1999)", ("b4_vn", "Amplitude of 4000 Å narrow break (Balogh et al. 1999)"),
"b4_sdss": "Amplitude of 4000 Å break (Stoughton et al. 2002)", ("b4_sdss", "Amplitude of 4000 Å break (Stoughton et al. 2002)"),
"b_912": "Amplitude of Lyman discontinuity" ("b_912", "Amplitude of Lyman discontinuity")
} ])
def _init_code(self): def _init_code(self):
"""Read the SSP from the database.""" """Read the SSP from the database."""
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import numpy as np import numpy as np
import scipy.constants as cst import scipy.constants as cst
from collections import OrderedDict
from . import common from . import common
...@@ -19,35 +20,35 @@ class Module(common.SEDCreationModule): ...@@ -19,35 +20,35 @@ class Module(common.SEDCreationModule):
""" """
parameter_list = { parameter_list = OrderedDict([
"temperature": ( ("temperature", (
"float", "float",
"Temperature of the dust in K.", "Temperature of the dust in K.",
None None
), )),
"beta": ( ("beta", (
"float", "float",
"Emissivity index of the dust.", "Emissivity index of the dust.",
None None
), )),
"alpha": ( ("alpha", (
"float", "float",
"Mid-infrared powerlaw slope.", "Mid-infrared powerlaw slope.",
None None
), )),
"attenuation_value_names": ( ("attenuation_value_names", (
"list of strings", "list of strings",
"List of attenuation value names (in the SED's info dictionary)." "List of attenuation value names (in the SED's info dictionary)."
"A new re-emission contribution will be added for each one.", "A new re-emission contribution will be added for each one.",
None None
) ))
} ])
out_parameter_list = { out_parameter_list = OrderedDict([
"temperature": "Temperature of the dust in K.", ("temperature", "Temperature of the dust in K."),
"beta": "Emissivity index of the dust.", ("beta", "Emissivity index of the dust."),
"alpha": "Mid-infrared powerlaw slope." ("alpha", "Mid-infrared powerlaw slope.")
} ])
def _init_code(self): def _init_code(self):
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
# Author: Yannick Roehlly <yannick.roehlly@oamp.fr> # Author: Yannick Roehlly <yannick.roehlly@oamp.fr>
from importlib import import_module from importlib import import_module
from collections import OrderedDict
def complete_parameters(given_parameters, parameter_list): def complete_parameters(given_parameters, parameter_list):
...@@ -14,36 +15,34 @@ def complete_parameters(given_parameters, parameter_list): ...@@ -14,36 +15,34 @@ def complete_parameters(given_parameters, parameter_list):
have no default value and is not present in given_parameters, raises an have no default value and is not present in given_parameters, raises an
error. If a parameter is present in given_parameters and not in error. If a parameter is present in given_parameters and not in
parameter_list, an exception is also raised. parameter_list, an exception is also raised.
Returns an ordered dictionary with the same key order as the parameter
list.
Parameters Parameters
---------- ----------
given_parameters : dictionary given_parameters : dictionary
Parameter dictionary used to configure the module. Parameter dictionary used to configure the module.
parameter_list : dictionary parameter_list : OrderedDict
Parameter list from the module. Parameter list from the module.
Returns Returns
------- -------
parameters : dictionary parameters : OrderedDict
Dictionary combining the given parameters with the default values for Ordered dictionary combining the given parameters with the default
the missing ones. values for the missing ones.
Raises Raises
------ ------
KeyError when the given parameters are different from the expected ones. KeyError when the given parameters are different from the expected ones.
""" """
# For parameters that are present on the parameter_list with a default # Complete the given parameters with default values when needed.
# value and that are not in the giver_parameters dictionary, we add them
# with their default value.
for key in parameter_list: for key in parameter_list:
if (not key in given_parameters) and ( if (not key in given_parameters) and (
parameter_list[key][2] is not None): parameter_list[key][2] is not None):
given_parameters[key] = parameter_list[key][2] given_parameters[key] = parameter_list[key][2]
# If the keys of the parameters dictionary are different from the one # Check parameter consistency between the parameter list and the given
# of the parameter_list dictionary, we raises a KeyError. That means # parameters.
# that a parameter is missing (and has no default value) or that an
# unexpected one was given.
if not set(given_parameters.keys()) == set(parameter_list.keys()): if not set(given_parameters.keys()) == set(parameter_list.keys()):
missing_parameters = (set(parameter_list.keys()) missing_parameters = (set(parameter_list.keys())
- set(given_parameters.keys())) - set(given_parameters.keys()))
...@@ -61,29 +60,34 @@ def complete_parameters(given_parameters, parameter_list): ...@@ -61,29 +60,34 @@ def complete_parameters(given_parameters, parameter_list):
raise KeyError("The parameters passed are different from the " raise KeyError("The parameters passed are different from the "
"expected one. " + message) "expected one. " + message)
return given_parameters # We want the result to be ordered as the parameter_list of the module is.
result = OrderedDict()
for key in parameter_list.keys():
result[key] = given_parameters[key]
return result
class SEDCreationModule(object): class SEDCreationModule(object):
"""Abstract class, the pCigale SED creation modules are based on. """Abstract class, the pCigale SED creation modules are based on.
""" """
# parameter_list is a dictionary containing all the parameters used by # parameter_list is an ordered dictionary containing all the parameters
# the module. Each parameter name is associate to a tuple (variable type, # used by the module. Each parameter name is associate to a tuple
# description [string], default value). Each module must define its # (variable type, description [string], default value). Each module must
# parameter list, unless it does not use any parameter. Using None means # define its parameter list, unless it does not use any parameter. Using
# that there is no description or default value. If None should be the # None means that there is no description or default value. If None should
# default value, use the 'None' string instead. # be the default value, use the 'None' string instead.
parameter_list = {} parameter_list = OrderedDict()
# out_parameter_list is a dictionary containing all the SED parameters # out_parameter_list is an ordered dictionary containing all the SED
# that are added to the SED info dictionary and for which a statistical # parameters that are added to the SED info dictionary and for which a
# analysis may be done. Each parameter name is associated with its # statistical analysis may be done. Each parameter name is associated with
# description. In the SED info dictionary, the parameter name in prefixed # its description. In the SED info dictionary, the parameter name in
# with the name of the module plus an underscore (to allow several # prefixed with the name of the module plus an underscore (to allow
# modules to add a parameter with the same name, for instance a repeated # several modules to add a parameter with the same name, for instance a
# module.) # repeated module.)
out_parameter_list = {} out_parameter_list = OrderedDict()
# comments is the text that is used to comment the module section in # comments is the text that is used to comment the module section in
# the configuration file. For instance, it can be used to give special # the configuration file. For instance, it can be used to give special
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt # Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt
# Author: Yannick Roehlly <yannick.roehlly@oamp.fr> # Author: Yannick Roehlly <yannick.roehlly@oamp.fr>
from collections import OrderedDict
from . import common from . import common
from ...data import Database from ...data import Database
...@@ -21,21 +22,21 @@ class Module(common.SEDCreationModule): ...@@ -21,21 +22,21 @@ class Module(common.SEDCreationModule):
""" """
parameter_list = { parameter_list = OrderedDict([
'alpha': ( ('alpha', (
'float', 'float',
"Alpha slope.", "Alpha slope.",
None None
), )),
'attenuation_value_names': ( ('attenuation_value_names', (
'array of strings', 'array of strings',
"List of attenuation value names (in the SED's info dictionary). " "List of attenuation value names (in the SED's info dictionary). "
"A new re-emission contribution will be added for each one.", "A new re-emission contribution will be added for each one.",
None None
) ))
} ])
out_parameter_list = {'alpha': 'Alpha slope.'} out_parameter_list = OrderedDict([('alpha', 'Alpha slope.')])
def _init_code(self): def _init_code(self):
"""Get the template set out of the database""" """Get the template set out of the database"""
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
# Author: Médéric Boquien <mederic.boquien@oamp.fr> # Author: Médéric Boquien <mederic.boquien@oamp.fr>
from . import common from . import common
from collections import OrderedDict
import numpy as np import numpy as np
from pcigale.data import Database from pcigale.data import Database
...@@ -22,39 +23,41 @@ class Module(common.SEDCreationModule): ...@@ -22,39 +23,41 @@ class Module(common.SEDCreationModule):
""" """
parameter_list = { parameter_list = OrderedDict([
'qpah': ( ('qpah', (
'float', 'float',
"Mass fraction of PAH", "Mass fraction of PAH",
None None
), )),
'umin': ( ('umin', (
'float', 'float',
"Minimum radiation field", "Minimum radiation field",
None None
), )),
'umax': ( ('umax', (
'float', 'float',
"Maximum radiation field", "Maximum radiation field",
None None
), )),
'gamma': ( ('gamma', (
'float', 'float',
"Fraction illuminated from Umin to Umax", "Fraction illuminated from Umin to Umax",
None None
), )),
'attenuation_value_names': ( ('attenuation_value_names', (
'list of strings', 'list of strings',
"List of attenuation value names (in the SED's info dictionary). " "List of attenuation value names (in the SED's info dictionary). "
"A new re-emission contribution will be added for each one.", "A new re-emission contribution will be added for each one.",