Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading mflike to v0.8.4 in LAT_MFLike #133

Merged
merged 18 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/foreground.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Foreground
Foreground computation
----------------------

.. autoclass:: soliket.Foreground
.. automodule:: soliket.foreground
:members:
:show-inheritance:
:private-members:


1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The pages here describe how to install and run SOLikeT, and document the functio
workflow
documentation


* :ref:`genindex`
* :ref:`search`

Expand Down
5 changes: 4 additions & 1 deletion docs/mflike.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ Multi Frequency Likelihood
.. autoclass:: soliket.mflike.MFLike
:exclude-members: initialize
:members:
:show-inheritance:
:private-members:
:show-inheritance:

Application of foregrounds and systematics
------------------------------------------

.. automodule:: soliket.mflike.theoryforge_MFLike

Expand Down
88 changes: 88 additions & 0 deletions docs/theory-component-guidelines.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
Contributor Guidelines
======================

How to add your theory component in soliket
-------------------------------------------

Basic ingredients
^^^^^^^^^^^^^^^^^
Your theory calculator must inherit from the cobaya theory class. It must have 3 main blocks of functions:

inizialization (``inizialize``);

requirements (``get_requirement``, ``must_provide``);

calculations (``get_X``, ``calculate``).

In what follows, we will use the structure of ``mflike`` as a concrete example of how to build these 3 blocks. The new version of ``mflike`` in SOLikeT splits the original mflike in 4 blocks: one cobaya-likelihood component (``mflike``); three cobaya-theory components.

The 3 theory components are:
1. ``TheoryForge``: this is where raw theory (CMB spectra) is mixed and modified with instrumental and non-cosmological effects
2. ``Foreground``: this is where the foreground (fg) spectra are computed
3. ``BandPass``: this is where bandpasses are built (either analytically or read from file)


Initialization
^^^^^^^^^^^^^^
You can either assign params in inizialize or do that via a dedicated yaml. You can in general do all the calculations that need to be done once for all.

Requirements
^^^^^^^^^^^^
Here you need to write what external elements are needed by your theory block to perform its duties. These external elements will be computed and provided by some other external module (e.g., another Theory class).
In our case, ``mflike`` must tell us that it needs a dictionary of cmb+fg spectra. This is done by letting the get_requirement function return a dictionary which has the name of the needed element as a key. For example, if the cmb+fg spectra dict is called ``cmbfg_dict``, the get_requirement function should

::

return {"cmbfg_dict":{}}

The key is a dict itself. It can be empty, if no params need to be passed to the external Theory in charge of computing cmbfg_dict.
It might be possible that, in order to compute ``cmbfg_dict``, we should pass to the specific Theory component some params known by ``mflike`` (e.g., frequency channel). This is done by filling the above empty dict:

::

{"cmbfg_dict": {"param1": param1_value, "param2": param2_value, etc}}

If this happens, then the external Theory block (in this example, ``TheoryForge``) must have a ``must_provide`` function.
``must_provide`` tells the code
1. what values should be assigned to the parameters needed to compute the element required from the Theory block. The required elements are stored in the ``**requirements`` dictionary which is the input of ``must_provide``.
In our example, ``TheoryForge`` will assign to ``param1`` the ``param1_value`` passed from ``mflike`` via the ``get_requirement`` in ``mflike`` (and so on). For example:
::

must_provide(self, **requirements):
if "cmbfg_dict" in requirements:
self.param1 = requirements["cmbfg_dict"]["param1"]

if this is the only job of ``must_provide``, then the function will not return anything


2. if needed, what external elements are needed by this specific theory block to perform its duties. In this case, the function will return a dictionary of (empty or not) dictionaries which are the requirements of the specific theory block. Note this can be also done via ``get_requirement``. However, if you need to pass some params read from the block above to the new requirements, this can only be done with ``must_provide``. For example, ``TheoryForge`` needs ``Foreground`` to compute the fg spectra, which we store in a dict called ``fg_dict``. We also want ``TheoryForge`` to pass to ``Foreground`` ``self.param1``. This is done as follows:
::

must_provide(self, **requirements):
if “cmbfg_dict” etc etc
...
return {“fg_dict”: {“param1_fg”: self.param1}}

Of course, ``Foreground`` will have a similar call to ``must_provide``, where we assign to ``self.param1_fg`` the value passed from ``TheoryForge`` to ``Foreground``.

Calculation
^^^^^^^^^^^
In each Theory class, you need at least 2 functions:

1.
::

get_X(self, any_other_param):
return self.current_state[“X”]

where "X" is the name of the requirement computed by that class (in our case, it is ``cmbfg_dict`` in ``TheoryForge``, ``fg_dict`` in ``Foreground``).
"any_other_param" is an optional param that you may want to apply to ``current_state["X"]`` before returning it. E.g., it could be a rescaling amplitude.
This function is called by the Likelihood or Theory class that has "X" as its requirement, via the ``self.provider.get_X(any_other_param)`` call.

2.
::

calculate(self, **state, want_derived=False/True, **params_values_dict):
do actual calculations, that could involve the use of some of the **params_value_dict, and might also compute derived params (if want_derived=True)

state[“X”] = result of above calculations
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ install_requires =
syslibrary

[options.package_data]
soliket = *.yaml,*.bibtex,clusters/data/*,clusters/data/selFn_equD56/*,lensing/data/*.txt,lensing/data/*.fits,mflike/*.yaml,tests/*.yaml,data/xcorr_simulated/*.txt,data/CosmoPower/CP_paper/CMB/*.pkl
soliket = *.yaml,*.bibtex,clusters/data/*,clusters/data/selFn_equD56/*,lensing/data/*.txt,lensing/data/*.fits,mflike/*.yaml,tests/*.yaml,data/xcorr_simulated/*.txt,data/CosmoPower/CP_paper/CMB/*.pkl,tests/data/test_bandpass/*
testpaths = "soliket"
text_file_format = rst

Expand Down
56 changes: 45 additions & 11 deletions soliket/BandPass.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,51 @@
data_folder: MFLike/v0.6
data_folder: MFLike/v0.8

band_integration:
external_bandpass: False
nsteps: 1
bandwidth: 0
# Three options for passband construction (top_hat_band, external_bandpass,
# read_from_sacc). Fill the corresponding dictionary to select one of the
# options. The other dictionaries have to be left empty. Default is
# read_from_sacc.

sgiardie marked this conversation as resolved.
Show resolved Hide resolved
# Parameters to build a top-hat band:
# - nsteps sets the number of frequencies used in the band integration
# - bandwidth sets the relative width of the band wrt the central frequency
# the central frequency of each band is set from the bands stored in the sacc file
# - with nstep: 1, bandwidth must be 0
# Dirac delta bandpass, no band integration
# useful if you don't want to do band integration
# when the bandpasses in the sacc file are multifrequency
# the freq used is the effective frequency from the bandpass
# - if nstep > 1, bandwidth must be > 0
# bandwidth can be a list if you want a different width for each band
# e.g. bandwidth: [0.3,0.2,0.3] for 3 bands
# when top_hat_band is a null dict: no top-hat band is built and
# bandpasses read from external path. Band integration is performed accordingly
# (if bandpass in the file is a single freq, no band integration)
# Bandpass has to be divided by nu**2 if measured with respect to a RJ source
top_hat_band:
# nsteps: 1
# bandwidth: 0


# If passband read from an external file, provide the field
# "path" with the directory path under the data_folder
# this directory would store several subdirectories with the
# name of experiment/array and the frequency
external_bandpass:
#path: path


# The mflike default is to read passbands from the sacc file
# storing the data. If you are not using mflike, make this
# dictionary empty and fill one of the other two dictionaries
read_from_sacc: True

params:
bandint_shift_93:
bandint_shift_LAT_93:
value: 0
latex: \Delta_{\rm band}^{93}
bandint_shift_145:
latex: \Delta_{\rm LAT}^{93}
bandint_shift_LAT_145:
value: 0
latex: \Delta_{\rm band}^{145}
bandint_shift_225:
latex: \Delta_{\rm LAT}^{145}
bandint_shift_LAT_225:
value: 0
latex: \Delta_{\rm band}^{225}
latex: \Delta_{\rm LAT}^{225}
3 changes: 2 additions & 1 deletion soliket/Foreground.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ spectra:
polarizations: ["tt", "te", "ee"]
lmin: 2
lmax: 9000
frequencies: [150]
exp_ch: ["LAT_150"]
eff_freqs: [150.]

foregrounds:
normalisation:
Expand Down
Loading