foreground – Application of foregrounds with bandpass#

The Foreground class calculates foreground spectra , using \(\ell\) ranges, array of frequencies,etc. The inherited BandpowerForeground adds integration over bandpowers, using the bandpass transmissions.

If one wants to use this class as standalone, the bands dictionary is filled when initializing BandpowerForeground.

The default values of the systematic parameters are set in the TTTEEE/TEEE/TT/EE/TE/etc.yaml files. They have to be named as cal/calT/calE/alpha + _ + experiment_channel string (e.g. LAT_93/dr6_pa4_f150). The default values of the foreground parameters are set in the fg_TT/TE/EE.yaml files. If you want to set different parameters settings, do that in the params block of the yaml file you will use for running (see the examples/mflike_example.yaml).

Note

Note that when you set different foregrounds/systematics parameters in the params block of your running yaml, Cobaya will use the new parameters settings you indicated. If you don’t change a parameter setting in the params block, Cobaya will use its default stored in the files mentioned above. Note that, in the .updated.yaml file generated by Cobaya, the mflike.BandpowerForeground theory block will have a params block with all the foreground parameters default settings which may be different from what you are defining in the general params block.

The bandpass shifts are applied within the _bandpass_construction function. There are two possibilities:

  • reading the passband \(\tau(\nu)\) stored in a sacc file (which is the default now)

  • building the passbands \(\tau(\nu)\), either as Dirac delta or as top-hat

For the first option, it is necessary to leave the top_hat_band key empty under mflike.BandpowerForeground:

theory:
  mflike.BandpowerForeground:
    top_hat_band: null

For the second option, the top_hat_band dictionary under the mflike.BandpowerForeground theory block has to be filled with two keys:

  • nsteps: setting the number of frequencies used in the band integration (either 1 for a Dirac delta or > 1)

  • bandwidth: setting the relative width \(\delta\) of the band with respect to the central frequency, such that the frequency extremes are \(\nu_{\rm{low/high}} = \nu_{\rm{center}}(1 \mp \delta/2) + \Delta^{\nu}_{\rm band}\) (with \(\Delta^{\nu}_{\rm band}\) being the possible bandpass shift). bandwidth has to be 0 if nstep = 1, > 0 otherwise. 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.

The effective frequencies, used as central frequencies to build the bandpasses, are read from the bands dictionary as before. To build a Dirac delta, use:

theory:
  mflike.BandpowerForeground:
    top_hat_band:
      nsteps: 1
      bandwidth: 0

If we don’t want to include the beam chromaticity effect, just leave the beam_profile key empty:

theory:
  mflike.BandpowerForeground:
    beam_profile:

If we want to consider it, we have several options on how to compute/read the beam profiles. Notice that we need arrays(freqs, ells+2) (computed from \(\ell = 0\)), since we want a beam window function for each freq in the bandpasses. We should use this block under mflike.BandpowerForeground:

theory:
  mflike.BandpowerForeground:
    beam_profile:
      beam_from_file: filename/False/null
There are two options:
  • reading the beams from the sacc file (beam_from_file: False/null). The beams have to be stored in the sacc.tracers[exp].beam tracer

  • reading the beams from an external yaml file (beam_from_file: filename).

filename has to be the absolute path for the file, with the .yaml/.yml extension. The yaml file has to be a dictionary {"{exp}_s0": {"nu": nu, "beams": array(freqs, ells+2)}, "{exp}_s2": {"nu": nu, "beams": array(freqs, ells+2)},...}

Once computed/read, the beam profiles are saved in

self.beams = {"{exp}_s0": {"nu": nu, "beams": array(freqs, ells+2)}, "{exp}_s2":
{"nu": nu, "beams": array(freqs, ells+2)},...}.

The beams are appropriately normalized, then we select the \(\ell\) range used in the rest of the code.

In case of bandpass shifts \(\Delta \nu \neq 0\), you can decide whether to propagate the bandpass shift effect to \(b_{\ell}(\nu)\) or not. If you want to leave \(b_{\ell}(\nu)\) unchanged even if \(\Delta \nu \neq 0\) (assuming this modification is a second order effect), you just need to leave the beam_profile block as it is, i.e. Bandpass_shifted_beams: null.

In case you want to propagate this effect, the chromatic beams are derived as: : math:b^{T/P}_{ell}(nu + Delta nu) = b^{T/P}_{ell (nu / nu_0)^{-alpha / 2}} (nu_0 + Delta nu), starting from a monochromatic beam \(b^{T/P}_{\ell}(\nu_0 + \Delta \nu)\). This monochromatic beam is derived from measurements of the planet beam and assuming a certain bandpass shift \(\Delta \nu\). So we need a dictionary of these \(b^{T/P}_{\ell}(\nu_0 + \Delta \nu)\) for the several values of \(\Delta \nu\) that could be sampled in the MCMC. To apply the scaling \(b^{T/ P}_{\ell (\nu / \nu_0)^{-\alpha / 2}}(\nu_0 + \Delta \nu)\) we also need \(\nu_0\) and \(\alpha\) for each experiment/array. The array of frequencies \(\nu\) for each experiment/array is derived from the corresponding bandpass file.

This means that, to propagate the bandpass shifts to \(b_{\ell}(\nu)\), we need to provide a yaml file under the key Bandpass_shifted_beams:

beam_profile:
  Bandpass_shifted_beams: bandpass_shifted_beams
  beam_from_file: filename/False/null

where the bandpass_shifted_beams.yaml file is structured as:

LAT_93_s0:
  beams: {..., '-2.0': b_ell(nu_0 -2),
                 '-1.0': b_ell(nu_0 -1),
                 ...
                 '5.0': b_ell(nu_0 + 5),
            ...}
  nu_0: ...
  alpha: ...
LAT_93_s2:
  beams: {'-10.0': b_ell(nu_0 - 10), ...}
  nu_0: ...
  alpha: ...
LAT_145_s0:
  beams: ...
  nu_0: ...
  alpha: ...
...

bandpass_shifted_beams has to be an absolute path, with the .yaml/.yml extension, which is added by the code.

It is important the keys of beam_profile["Bandpass_shifted_beams"]["{exp}_s0/2"] ["beams"] are strings of floats representing the value of \(\Delta \nu\) (if they are strings of int the code to read the associated beams would not work).

Foreground class content#

class mflike.Foreground(info: Mapping[str, Any] = mappingproxy({}), name: str | None = None, timing: bool | None = None, packages_path: str | None = None, initialize=True, standalone=True)[source]#

Bases: Theory

classmethod get_modified_defaults(defaults: dict, input_options: dict = mappingproxy({})) dict[source]#

Adds the appropriate foreground parameters based on the requested_cls

_get_foreground_model_arrays(fg_params: dict, ell: ndarray | None = None) dict[source]#

Gets the foreground power spectra for each component computed by fgspectra. Integration over frequency is performed using bandint_freqs.

Parameters:
  • fg_params – parameters of the foreground components

  • ell – ell range. If None the default range set in mflike.ells is used

Returns:

the foreground dictionary of arrays

get_foreground_model(ell: ndarray | None = None, freqs_order: list[str] | None = None, **fg_params) dict[source]#

Gets the foreground power spectra for each component computed by fgspectra. Integration over frequency is performed using bandint_freqs. This function is not used by Cobaya, but can be used to get the individual foreground components and total as a dictionary when accessing the class separately.

Parameters:
  • ell – ell range. If None the default range set in ells is used

  • freqs_order – list of the effective frequencies for each channel used to compute the foreground components. Useful when this class is called outside of mflike, used in place of self.experiments

  • fg_params – parameters of the foreground components

Returns:

the foreground dictionary

calculate(state, want_derived=False, **params_values_dict)[source]#

Fills the state dictionary of the Foreground Theory class with the foreground spectra, computed using the bandpass transmissions the sampled foreground parameters.

Parameters:
  • statestate dictionary to be filled with computed foreground spectra

  • want_derived – if derived wanted (none here)

  • params_values_dict – dictionary of parameters from the sampler

get_foreground_model_totals(requested_cl=(), **params_values_dict)[source]#

Get total foregrounds for each cl type and frequency channel.

Parameters:
  • requested_cl – optional list of cl types to compute (tt, ee, te)

  • params_values_dict – foreground parameters

Returns:

list of arrays for each requested_cl

get_fg_totals() dict[source]#

Returns the state dictionary of foreground spectra, when used with Cobaya. Should only be called after the model is calculated by Cobaya.

must_provide(**requirements)[source]#

Function called by Cobaya with the actual products that this component needs to compute (i.e. the things this component can provide that are actually used by other components). The function can return conditional requirements that this component needs from other components in order to compute those things.

The requirements argument is a requirement name with any optional parameters. This function may be called more than once with different requirements.

Returns:

optional dictionary (or list of requirement name, option tuples) of conditional requirements for the ones requested.

class mflike.BandpowerForeground(info: Mapping[str, Any] = mappingproxy({}), name: str | None = None, timing: bool | None = None, packages_path: str | None = None, initialize=True, standalone=True)[source]#

Bases: Foreground

must_provide(**requirements)[source]#

Function called by Cobaya with the actual products that this component needs to compute (i.e. the things this component can provide that are actually used by other components). The function can return conditional requirements that this component needs from other components in order to compute those things.

The requirements argument is a requirement name with any optional parameters. This function may be called more than once with different requirements.

Returns:

optional dictionary (or list of requirement name, option tuples) of conditional requirements for the ones requested.

get_can_support_params() list[str][source]#

Get a list of parameters supported by this component, can be used to support parameters that don’t explicitly appear in the .yaml or class params attribute or are otherwise explicitly supported (e.g. via requirements)

Returns:

iterable of names of parameters

_get_foreground_model_arrays(fg_params: dict, ell: ndarray | None = None) dict[source]#

Gets the foreground power spectra for each component computed by fgspectra. The computation assumes the bandpass transmissions computed in _bandpass_construction and integration in frequency is performed if the passbands are not Dirac delta.

Parameters:
  • fg_params – parameters of the foreground components

  • ell – ell range. If None the default range set in self.ells is used

Returns:

the foreground dictionary of arrays

_bandpass_construction(_initialize: bool = False, **params)[source]#

Builds the bandpass transmission with or without beam. When chromatic beam is not considered, we compute: \(\frac{\frac{\partial B_{\nu+\Delta \nu}}{\partial T} \tau(\nu+\Delta \nu)}{\int d\nu \frac{\partial B_{\nu+\Delta \nu}}{\partial T} \tau(\nu+\Delta \nu)}\) using passbands \(\tau(\nu)\) (divided by \(\nu^2\) if measured with respect to a RJ source, not read from a txt file) and bandpass shift \(\Delta \nu\). As a default, \(\tau(\nu)\) is read from the sacc file. If use_top_hat_band, \(\tau(\nu)\) is built as a top-hat with width bandint_width and number of samples nsteps, read from the MFLike.yaml. If nstep = 1 and bandint_width = 0, the passband is a Dirac delta centered at \(\nu+\Delta \nu\).

When the chromatic beam is considered, we compute \(r_{\ell}^T(\nu+\Delta \nu) = \frac{\frac{\partial B_{\nu+\Delta \nu}}{\partial T} \tau(\nu+\Delta \nu) b^T_{\ell}(\nu)} {\int d\nu \frac{\partial B_{\nu+\Delta \nu}}{\partial T} \tau(\nu+\Delta \nu) b^T_{\ell}(\nu)}\) for the temperature field, and a corresponding expression for the polarization field, replacing the temperature beam with the polarization one \(b^P_{\ell}(\nu)\). If we want to propagate the bandpass shifts to the beam, we compute instead \(r_{\ell}^T(\nu+\Delta \nu) = \frac{\frac{\partial B_{\nu+\Delta \nu}}{ \partial T} \tau(\nu+\Delta \nu) b^T_{\ell}(\nu + \Delta \nu)} {\int d\nu \frac{\partial B_{\nu+\Delta \nu}}{\partial T} \tau(\nu+\Delta \nu) b^T_{\ell}(\nu + \Delta \nu)}\).

Parameters:

**params – dictionary of nuisance parameters

Returns:

the list of [nu, transmission] in the multifrequency case or just an array of frequencies in the single frequency one. We distinguish between T and pol transmission when a chromatic beam is included

_init_beam_from_file()[source]#

Reads the beam profile from an external file or the sacc file. It has to be a dictionary {"{exp}_s0": {"nu": nu, "beams": array(freqs, ells+2)}, "{exp}_s2": {"nu": nu, "beams": array(freqs, ells+2)},...} including temperature and polarization beams.

beam_interpolation(b_ell_template: ndarray, f_ell: ndarray, ells: ndarray, freqs: ndarray, freq_ref: float, alpha: float) ndarray[source]#

Computing \(b_{\ell}(\nu)\) from monochromatic beam \(b_{\ell}\) using the frequency scaling: \((b \cdot f)_{\ell \cdot (\nu / \nu_0)^{-\alpha / 2}}\)

Parameters:
  • b_ell_template – (nell array) Template for \(b_{\ell}\), should be 1 at ell=0.

  • f_ell – (nell array) Multiplicate correction to the \(b_{\ell}\) template. Should be 1 at ell=0.

  • ells – (nell array) ell array

  • freqs – (nfreq array) Frequency for that experiment/array

  • freq_ref – (float) Reference frequency.

  • alpha – (float) Power law index.

Returns:

a (nfreq, nell) array: \(b_{\ell}(\nu)\) at each input frequency.

return_beams(exp: str, nu: ndarray, dnu: float) tuple[ndarray, ndarray][source]#

Returns the temperature and polarization beams, properly normalized and from \(\ell = 2\) (same ell range as self.ells). We compute them from \(\ell = 0\) to normalize them in the correct way (temperature beam = 1 for \(\ell = 0\)). The polarization beam is normalized by the temperature one (as in hp.gauss_beam).

If we want to propagate bandpass shifts to the beams, we have to select the monochromatic beam \(b_{\ell}\) computed from the planet beam assuming that bandpass shift. This has to be present in the self.bandpass_shifted_beams dictionary. From each of these \(b_{\ell}\), the chromatic beam is computed with the scaling \(b_{\ell (\nu / \nu_0)^{-\alpha / 2}}\), where \(\nu_0\) and \(\alpha\) are also found in the same dictionary.

Parameters:
  • nu – the frequency array in GHz (for now, the math:nu array is the same between bandpass file and beam file for the same experiment/array. It is passed from the _bandpass_construction function for consistency.)

  • dnu – the bandpass shift \(\Delta \nu\)

Returns:

The temperature and polarization chromatic beams