Skip to content

Photometric Likelihoods

These classes implement Gaussian likelihoods for Euclid photometric primary probes, covering both angular power spectra (Cls) and real-space two-point correlation functions (2PCF).


Base

Shared by both Cls and 2PCF likelihoods.

PhotoLikelihoodProtocol

cloelike.EuclidLikelihood_photo_base.PhotoLikelihoodProtocol

Bases: Protocol

Protocol for photo-z likelihood classes.

This protocol defines the required interface for photometric likelihood implementations, specifying initialization, required attributes, and methods for computing data vectors, theory vectors, covariance matrices, and log-likelihoods.

Attributes: data (dict): Observational data dictionary. settings (dict): Configuration settings dictionary. Background (Background): Cosmological background instance. LinPerturbations (Perturbations): Linear perturbations instance. NonLinPerturbations (Perturbations): Non-linear perturbations instance. derived (dict): Dictionary for derived quantities. mode (str): Mode of operation (e.g., "coupled").

Methods: init(data, settings, Background, LinPerturbations, NonLinPerturbations, mode): Initializes the likelihood protocol. get_data_vector_full() -> np.ndarray: Returns the full data vector. get_data_vector_masked() -> np.ndarray: Returns the masked data vector. get_theory_vector_full(parameters: dict) -> np.ndarray: Returns the full theory vector for given parameters. get_theory_vector_masked(parameters: dict) -> np.ndarray: Returns the masked theory vector for given parameters. get_covariance_matrix_full() -> np.ndarray: Returns the full covariance matrix. get_covariance_matrix_masked_inv() -> np.ndarray: Returns the inverse of the masked covariance matrix. loglike(parameters: dict) -> float: Computes the log-likelihood for the given parameters.

Source code in cloelike/EuclidLikelihood_photo_base.py
@runtime_checkable
class PhotoLikelihoodProtocol(Protocol):
    """
    Protocol for photo-z likelihood classes.

    This protocol defines the required interface for photometric likelihood implementations,
    specifying initialization, required attributes, and methods for computing data vectors,
    theory vectors, covariance matrices, and log-likelihoods.

    Attributes:
        data (dict): Observational data dictionary.
        settings (dict): Configuration settings dictionary.
        Background (Background): Cosmological background instance.
        LinPerturbations (Perturbations): Linear perturbations instance.
        NonLinPerturbations (Perturbations): Non-linear perturbations instance.
        derived (dict): Dictionary for derived quantities.
        mode (str): Mode of operation (e.g., "coupled").

    Methods:
        __init__(data, settings, Background, LinPerturbations, NonLinPerturbations, mode):
            Initializes the likelihood protocol.
        get_data_vector_full() -> np.ndarray:
            Returns the full data vector.
        get_data_vector_masked() -> np.ndarray:
            Returns the masked data vector.
        get_theory_vector_full(parameters: dict) -> np.ndarray:
            Returns the full theory vector for given parameters.
        get_theory_vector_masked(parameters: dict) -> np.ndarray:
            Returns the masked theory vector for given parameters.
        get_covariance_matrix_full() -> np.ndarray:
            Returns the full covariance matrix.
        get_covariance_matrix_masked_inv() -> np.ndarray:
            Returns the inverse of the masked covariance matrix.
        loglike(parameters: dict) -> float:
            Computes the log-likelihood for the given parameters.
    """

    def __init__(
        self,
        data: dict,
        settings: dict,
        Background: Background,
        LinPerturbations: Perturbations,
        NonLinPerturbations: Perturbations,
    ) -> None: ...

    data: dict
    settings: dict
    Background: Background
    LinPerturbations: Perturbations
    NonLinPerturbations: Perturbations
    derived: dict

    def get_data_vector_full(self) -> np.ndarray: ...
    def get_data_vector_masked(self) -> np.ndarray: ...
    def get_theory_vector_full(self, parameters: dict) -> np.ndarray: ...
    def get_theory_vector_masked(self, parameters: dict) -> np.ndarray: ...
    def get_covariance_matrix_full(self) -> np.ndarray: ...
    def get_covariance_matrix_masked_inv(self) -> np.ndarray: ...
    def loglike(self, parameters: dict) -> float: ...

options: show_source: true

PhotoLikelihoodBase

cloelike.EuclidLikelihood_photo_base.PhotoLikelihoodBase

Base class for photometric likelihood calculations using angular correlation functions. This class provides methods for preparing, binning, and masking data, as well as computing likelihoods based on theoretical predictions and observed data vectors. Args: data (dict): Dictionary containing observational data, including '2pcf', 'theta', 'z_arr', and 'cov'. settings (dict): Configuration settings. Besides the required 'scale_cuts', the theory model is selected with the optional keys:

    - 'ia_model': None, "NLA" (default) or "TATT". NLA reads AIA, EtaIA, CIA;
      TATT reads AIA, A2IA, bTA and optionally EtaIA, Eta2IA, CIA, z0IA.
    - 'galaxy_bias_model': "poly" (default, b1_photo_poly0..3), "per_bin" or
      "per_bin_int" (b1_photo_bin{i}, i = 0..n_pos_bins-1), or "nonlinear"
      (b1_photo_nl_bin{i}, and optionally b2_, bs2_, b3nl_, bk2_photo_nl_bin{i}).
    - 'include_rsd': bool, default False.
    - 'nonlinear_param_keys': names of sampled parameters passed as keyword
      arguments to NonLinPerturbations, default ("log10TAGN",). Use () for
      backends without baryonic feedback (e.g. EE2).
    - 'baryon_param_keys': names of sampled parameters passed as
      `baryon_kwargs` to NonLinPerturbations, for classes built with
      `cloelib.cosmology.cosmology.with_baryon_boost`. Default ().
    - 'nonlinear_kwargs': fixed keyword arguments for NonLinPerturbations
      (e.g. {"nonlinear_model": "mead2020"}). Default {}.
    - 'tatt_loop_computer', 'nl_bias_loop_computer': factories called with
      the linear perturbations to build the one-loop kernels for TATT and
      the nonlinear galaxy bias. Default to cloelib's FAST-PT computers.
Background: Object representing background cosmology.
LinPerturbations: Object representing linear perturbations.
NonLinPerturbations: Object representing non-linear perturbations.
mode (str, optional): Mode of operation, default is "coupled".

Attributes: data (dict): Observational data. settings (dict): Configuration settings. derived (dict): Dictionary for storing derived quantities. Background: Background cosmology object. LinPerturbations: Linear perturbations object. NonLinPerturbations: Non-linear perturbations object. scale_cuts: Scale cuts from settings. zs: Redshift array from data. mixmat: Mixing matrix, possibly rebinned. weight_mat: Weight matrix used for binning. masking_vector: Boolean mask for selecting data vector elements. Methods: _masking(arr, interval): Returns a boolean mask for elements within the specified interval. get_covariance_matrix_full(): Returns the full covariance matrix from the data. get_data_vector_masked(): Returns the masked data vector. get_covariance_matrix_masked_inv(): Returns the inverse of the masked covariance matrix. get_theory_vector_full(parameters): Returns the full theoretical prediction vector for given parameters. get_theory_vector_masked(parameters): Returns the masked theoretical prediction vector for given parameters. loglike(parameters): Computes the log-likelihood for the given parameters using the masked data and theory vectors.

Source code in cloelike/EuclidLikelihood_photo_base.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
class PhotoLikelihoodBase:
    """
    Base class for photometric likelihood calculations using angular correlation functions.
    This class provides methods for preparing, binning, and masking data, as well as computing
    likelihoods based on theoretical predictions and observed data vectors.
    Args:
        data (dict): Dictionary containing observational data, including '2pcf', 'theta', 'z_arr', and 'cov'.
        settings (dict): Configuration settings. Besides the required 'scale_cuts',
            the theory model is selected with the optional keys:

            - 'ia_model': None, "NLA" (default) or "TATT". NLA reads AIA, EtaIA, CIA;
              TATT reads AIA, A2IA, bTA and optionally EtaIA, Eta2IA, CIA, z0IA.
            - 'galaxy_bias_model': "poly" (default, b1_photo_poly0..3), "per_bin" or
              "per_bin_int" (b1_photo_bin{i}, i = 0..n_pos_bins-1), or "nonlinear"
              (b1_photo_nl_bin{i}, and optionally b2_, bs2_, b3nl_, bk2_photo_nl_bin{i}).
            - 'include_rsd': bool, default False.
            - 'nonlinear_param_keys': names of sampled parameters passed as keyword
              arguments to NonLinPerturbations, default ("log10TAGN",). Use () for
              backends without baryonic feedback (e.g. EE2).
            - 'baryon_param_keys': names of sampled parameters passed as
              `baryon_kwargs` to NonLinPerturbations, for classes built with
              `cloelib.cosmology.cosmology.with_baryon_boost`. Default ().
            - 'nonlinear_kwargs': fixed keyword arguments for NonLinPerturbations
              (e.g. {"nonlinear_model": "mead2020"}). Default {}.
            - 'tatt_loop_computer', 'nl_bias_loop_computer': factories called with
              the linear perturbations to build the one-loop kernels for TATT and
              the nonlinear galaxy bias. Default to cloelib's FAST-PT computers.
        Background: Object representing background cosmology.
        LinPerturbations: Object representing linear perturbations.
        NonLinPerturbations: Object representing non-linear perturbations.
        mode (str, optional): Mode of operation, default is "coupled".
    Attributes:
        data (dict): Observational data.
        settings (dict): Configuration settings.
        derived (dict): Dictionary for storing derived quantities.
        Background: Background cosmology object.
        LinPerturbations: Linear perturbations object.
        NonLinPerturbations: Non-linear perturbations object.
        scale_cuts: Scale cuts from settings.
        zs: Redshift array from data.
        mixmat: Mixing matrix, possibly rebinned.
        weight_mat: Weight matrix used for binning.
        masking_vector: Boolean mask for selecting data vector elements.
    Methods:
        _masking(arr, interval):
            Returns a boolean mask for elements within the specified interval.
        get_covariance_matrix_full():
            Returns the full covariance matrix from the data.
        get_data_vector_masked():
            Returns the masked data vector.
        get_covariance_matrix_masked_inv():
            Returns the inverse of the masked covariance matrix.
        get_theory_vector_full(parameters):
            Returns the full theoretical prediction vector for given parameters.
        get_theory_vector_masked(parameters):
            Returns the masked theoretical prediction vector for given parameters.
        loglike(parameters):
            Computes the log-likelihood for the given parameters using the masked data and theory vectors.
    """

    def __init__(
        self,
        data,
        settings,
        Background,
        LinPerturbations,
        NonLinPerturbations,
        ells_integration=None,
        mode="coupled",
    ):
        self.data = data
        self.settings = settings
        self.derived = {}
        self.Background = Background
        self.LinPerturbations = LinPerturbations
        self.NonLinPerturbations = NonLinPerturbations
        self.theory_prediction = {}
        self.mode = mode
        if "cosebis" in data:
            # For COSEBIs the scale cuts are set by the W_ell kernels
            if settings.get("scale_cuts") is not None:
                warnings.warn(
                    "For COSEBIs the scale cuts are applied via the w_ells; "
                    "settings['scale_cuts'] is ignored."
                )
            self.scale_cuts = None
        else:
            self.scale_cuts = settings["scale_cuts"]
        self.ia_model = settings.get("ia_model", "NLA")
        if self.ia_model not in IA_MODEL_KEYS:
            raise ValueError(
                f"Unknown ia_model {self.ia_model!r}; "
                f"choose one of {list(IA_MODEL_KEYS)}."
            )
        self.galaxy_bias_model = settings.get("galaxy_bias_model", "poly")
        if self.galaxy_bias_model not in GALAXY_BIAS_MODELS:
            raise ValueError(
                f"Unknown galaxy_bias_model {self.galaxy_bias_model!r}; "
                f"choose one of {list(GALAXY_BIAS_MODELS)}."
            )
        if self.galaxy_bias_model == "nonlinear" and settings.get("include_rsd", False):
            # Fail here rather than at the first loglike call.
            raise ValueError(
                "galaxy_bias_model='nonlinear' does not support include_rsd=True "
                "yet: cloelib's generalized Cl engine has no RSD term."
            )
        self.nonlinear_param_keys = tuple(
            settings.get("nonlinear_param_keys", ("log10TAGN",))
        )
        self.baryon_param_keys = tuple(settings.get("baryon_param_keys", ()))
        self.rebin = False
        self.zs = data["z_arr"]
        if self.mode == "coupled":
            self.mixmat = deepcopy(data.get("mixmat", {}))
        else:
            self.mixmat = None

        if (ells_integration is None) and ("2pcf" in data):
            self.ells_integration = np.arange(2, 40000)

        else:
            self.ells_integration = ells_integration

        if ("cells" in data) and ("n_ell_bins" in settings):
            self._prepare()

    def _prepare(self):
        """Perform rebinning if required by settings."""
        if self.settings["n_ell_bins"] < len(self.data["ells"]):
            self.rebin = True
            self.data["cells_unbin"] = self.data["cells"]
            self.data["ells_unbin"] = self.data["ells"]
            self._bin_data(
                self.data["cells"], self.data["ells"], self.settings["n_ell_bins"]
            )
            self._bin_mixmat()

    def _bin_data(self, cells_data, ells, n_bins):
        """Geometric rebinning of data vectors."""
        bin_edges = np.geomspace(10, ells[-1], n_bins + 1)
        mask_bins = [
            (ells >= bin_edges[i]) & (ells < bin_edges[i + 1]) for i in range(n_bins)
        ]
        self.weight_mat = np.asarray(mask_bins, dtype=float)
        self.weight_mat /= np.sum(self.weight_mat, axis=1)[:, None]
        self.data["ells"] = np.array([np.mean(ells[mb]) for mb in mask_bins])
        for k in cells_data.keys():
            self.data["cells"][k] = cells_data[k] @ self.weight_mat.T

    def _bin_mixmat(self):
        """Apply the same binning to the mixing matrix."""
        for k in self.mixmat.keys():
            new_array = np.tensordot(self.weight_mat, self.mixmat[k], axes=([1], [-2]))
            if k[:2] == ("SHE", "SHE"):
                new_array = np.transpose(new_array, axes=(1, 0, 2))
            self.mixmat[k] = new_array

    def _masking(self, arr, interval):
        return (arr >= interval[0]) & (arr <= interval[1])

    # Parameters passed to Background(...). Parameters consumed only by
    # NonLinPerturbations (e.g. log10TAGN) are set per instance through
    # settings["nonlinear_param_keys"] and settings["baryon_param_keys"].
    _BACKGROUND_PARAM_KEYS = (
        "H0",
        "Omega_cdm0",
        "Omega_b0",
        "Omega_k0",
        "w0",
        "wa",
        "ns",
        "As",
        "mnu",
        "gamma_MG",
        "N_mnu",
        "alpha_s",
    )

    def _init_she_keys(self):
        """Shear nuisance parameters required by the selected IA model."""
        n = self.data["dndz_she"].shape[0]
        ia_required, ia_optional = IA_MODEL_KEYS[self.ia_model]
        self.full_she_keys = (
            list(ia_required)
            + [f"multiplicative_bias_{i}" for i in range(1, n + 1)]
            + [f"dz_shear_{i}" for i in range(1, n + 1)]
            + [f"width_shear_{i}" for i in range(1, n + 1)]
        )
        self.optional_she_keys = list(ia_optional)

    def _init_pos_keys(self):
        """Position nuisance parameters required by the selected bias model."""
        n = self.data["dndz_pos"].shape[0]
        if self.galaxy_bias_model == "poly":
            bias_keys = [f"b1_photo_poly{i}" for i in range(4)]
            optional = []
        elif self.galaxy_bias_model == "nonlinear":
            # Higher-order terms are optional: cloelib drops a term whose
            # coefficient is absent.
            bias_keys = [f"b1_photo_nl_bin{i}" for i in range(n)]
            optional = [
                f"{p}_photo_nl_bin{i}"
                for p in ("b2", "bs2", "b3nl", "bk2")
                for i in range(n)
            ]
        else:
            bias_keys = [f"b1_photo_bin{i}" for i in range(n)]
            optional = []
        self.full_pos_keys = (
            bias_keys
            + [f"magnification_bias_{i}" for i in range(1, n + 1)]
            + [f"dz_pos_{i}" for i in range(1, n + 1)]
            + [f"width_pos_{i}" for i in range(1, n + 1)]
        )
        self.optional_pos_keys = optional

    @staticmethod
    def _select(parameters, required, optional=()):
        """Subset of `parameters`: all `required` keys, plus the `optional`
        ones that are present."""
        selected = {k: parameters[k] for k in required}
        selected.update({k: parameters[k] for k in optional if k in parameters})
        return selected

    def _get_perturbations(self, parameters):
        """Build (and cache) Background/LinPerturbations/NonLinPerturbations for
        the given parameters.

        Combined likelihoods (e.g. 3x2pt) mix several probe-specific mixins in
        one MRO chain, each of which needs the perturbations. Caching here
        (instead of rebuilding in every mixin's get_theory_vector_full) avoids
        recomputing the same cosmology multiple times per call. The cache is
        keyed on the cosmology-relevant subset of `parameters` so a change in
        any of those values rebuilds it, while repeated calls with an unchanged
        cosmology (e.g. only nuisance parameters varying) reuse it.
        """
        key = self._cosmo_key(parameters)
        cached = getattr(self, "_perturbations_cache", None)
        if cached is not None and cached[0] == key:
            return cached[1]
        background = self.Background(
            **{k: parameters[k] for k in self._BACKGROUND_PARAM_KEYS}
        )
        lp = self.LinPerturbations(background=background, redshifts=self.zs)
        nl_kwargs = dict(self.settings.get("nonlinear_kwargs", {}))
        nl_kwargs.update({k: parameters[k] for k in self.nonlinear_param_keys})
        if self.baryon_param_keys:
            nl_kwargs["baryon_kwargs"] = {
                k: parameters[k] for k in self.baryon_param_keys
            }
        nlp = self.NonLinPerturbations(
            background=background,
            linearperturbations=lp,
            redshifts=self.zs,
            **nl_kwargs,
        )
        # sigma8_0() self-memoizes by overwriting `nlp.sigma8_0` with its
        # result on first call, so it must be called exactly once per nlp
        # instance -- here, rather than in each mixin (which would fail on
        # the second mixin to see this shared, cached nlp).
        self.derived["sigma8_0"] = nlp.sigma8_0()
        result = (background, lp, nlp)
        self._perturbations_cache = (key, result)
        # Loop computers depend only on the cosmology; drop the old ones.
        self._loop_computers = {}
        return result

    def _cosmo_key(self, parameters):
        """The same cache key used by `_get_perturbations`, exposed so tracer
        caching below can be keyed on values rather than on `nlp`'s object
        identity (which could in principle be reused after garbage collection)."""
        keys = (
            self._BACKGROUND_PARAM_KEYS
            + self.nonlinear_param_keys
            + self.baryon_param_keys
        )
        return tuple(parameters[k] for k in keys)

    def _get_loop_computer(self, name, default_factory, parameters):
        """One-loop kernel computer for TATT ("tatt") or the nonlinear galaxy
        bias ("nl_bias"), built once per cosmology so the FAST-PT kernels are
        shared between tracers and nuisance-only steps.

        It is built from the linear perturbations: the one-loop integrals need
        the linear power spectrum, which not every nonlinear backend exposes.
        """
        _, lp, _ = self._get_perturbations(parameters)
        if name not in self._loop_computers:
            factory = self.settings.get(f"{name}_loop_computer", default_factory)
            self._loop_computers[name] = factory(lp)
        return self._loop_computers[name]

    def _get_pos_tracer(self, parameters, nlp):
        """Build (and cache) the PositionsTracer for the given parameters/nlp,
        so GCph and GGL do not each rebuild it within the same call."""
        nuisance = self._select(parameters, self.full_pos_keys, self.optional_pos_keys)
        key = self._cosmo_key(parameters) + tuple(sorted(nuisance.items()))
        cached = getattr(self, "_pos_tracer_cache", None)
        if cached is not None and cached[0] == key:
            return cached[1]
        # The nonlinear bias options are only passed when selected, so the linear
        # bias models also work with cloelib versions without the nonlinear bias.
        nl_bias_kwargs = {}
        if self.galaxy_bias_model == "nonlinear":
            nl_bias_kwargs["nl_bias_loop_computer"] = self._get_loop_computer(
                "nl_bias", _nonlinear_bias_loop_computer, parameters
            )
        tracer = PositionsTracer(
            nlp,
            self.data["dndz_pos"],
            self.zs,
            nuisance_params=nuisance,
            galaxy_bias_model=self.galaxy_bias_model,
            include_rsd=self.settings.get("include_rsd", False),
            **nl_bias_kwargs,
        )
        self._pos_tracer_cache = (key, tracer)
        return tracer

    def _get_she_tracer(self, parameters, nlp):
        """Build (and cache) the ShearTracer for the given parameters/nlp, so
        WL and GGL do not each rebuild it within the same call."""
        nuisance = self._select(parameters, self.full_she_keys, self.optional_she_keys)
        key = self._cosmo_key(parameters) + tuple(sorted(nuisance.items()))
        cached = getattr(self, "_she_tracer_cache", None)
        if cached is not None and cached[0] == key:
            return cached[1]
        if self.ia_model == "TATT":
            loop_computer = self._get_loop_computer(
                "tatt", PBJTATTLoopComputer, parameters
            )
        else:
            loop_computer = None
        tracer = ShearTracer(
            nlp,
            self.data["dndz_she"],
            self.zs,
            nuisance_params=nuisance,
            ia_model=self.ia_model,
            tatt_loop_computer=loop_computer,
        )
        self._she_tracer_cache = (key, tracer)
        return tracer

    def get_masking_vector(self):
        return np.array([], dtype=bool)

    def get_covariance_matrix_full(self):
        return self.data["cov"]

    def get_data_vector_full(self):
        return np.array([])

    @lru_cache(maxsize=None)
    def get_masking_vector_cached(self):
        """Compute (once) and cache the combined boolean mask."""
        return self.get_masking_vector()

    @lru_cache(maxsize=None)
    def get_data_vector_masked(self):
        mask = self.get_masking_vector_cached()
        return self.get_data_vector_full()[mask]

    @lru_cache(maxsize=None)
    def get_covariance_matrix_masked_inv(self):
        """Compute (once) and cache inverse masked covariance matrix."""
        cov = self.get_covariance_matrix_full()
        mask = self.get_masking_vector_cached()
        cov_masked = cov[mask][:, mask]
        return np.linalg.inv(cov_masked)

    def get_theory_vector_full(self, parameters):
        return np.array([])

    def get_theory_vector_masked(self, parameters):
        mask = self.get_masking_vector_cached()
        return self.get_theory_vector_full(parameters)[mask]

    def loglike(self, parameters):
        diff = self.get_theory_vector_masked(parameters) - self.get_data_vector_masked()
        inv_cov = self.get_covariance_matrix_masked_inv()
        return -0.5 * diff @ inv_cov @ diff

Methods:

get_masking_vector_cached cached

get_masking_vector_cached()

Compute (once) and cache the combined boolean mask.

Source code in cloelike/EuclidLikelihood_photo_base.py
@lru_cache(maxsize=None)
def get_masking_vector_cached(self):
    """Compute (once) and cache the combined boolean mask."""
    return self.get_masking_vector()

get_covariance_matrix_masked_inv cached

get_covariance_matrix_masked_inv()

Compute (once) and cache inverse masked covariance matrix.

Source code in cloelike/EuclidLikelihood_photo_base.py
@lru_cache(maxsize=None)
def get_covariance_matrix_masked_inv(self):
    """Compute (once) and cache inverse masked covariance matrix."""
    cov = self.get_covariance_matrix_full()
    mask = self.get_masking_vector_cached()
    cov_masked = cov[mask][:, mask]
    return np.linalg.inv(cov_masked)

options: show_source: true


Angular Power Spectra (Cls)

Classes from cloelike.EuclidLikelihood_photo_Cls.

Mixins — composable building blocks for Cls likelihoods:

WLMixin

cloelike.EuclidLikelihood_photo_Cls.WLMixin

Mixin class providing weak lensing (WL) specific functionality for photometric likelihoods. This mixin extends the base photometric likelihood class to include methods and attributes necessary for handling weak lensing data, such as initializing shear bins, constructing masking vectors, and computing data and theory vectors specific to weak lensing.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
class WLMixin:
    """
    Mixin class providing weak lensing (WL) specific functionality for photometric likelihoods.
    This mixin extends the base photometric likelihood class to include methods and attributes
    necessary for handling weak lensing data, such as initializing shear bins, constructing
    masking vectors, and computing data and theory vectors specific to weak lensing.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # Call the next class in the MRO
        self._init_wl()

    def _init_wl(self):
        self.n_she_bins = self.data["dndz_she"].shape[0]
        self._init_she_keys()
        self.WL_keys = [
            ("SHE", "SHE", i, j)
            for i in range(1, self.n_she_bins + 1)
            for j in range(i, self.n_she_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                self._masking(self.data["ells"], self.scale_cuts[key])
                for key in self.WL_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.array(
            [self.data["cells"][key][0, 0] for key in self.WL_keys]
        ).flatten()
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        she = self._get_she_tracer(parameters, nlp)
        if self.mode == "coupled":
            cell_all_th = AngularTwoPoint(she, she).get_pseudo_Cl(0, nlp.k, self.mixmat)
            vec = np.array([cell_all_th[key][0, 0] for key in self.WL_keys]).flatten()
        else:
            cell_all_th = AngularTwoPoint(she, she).get_Cl(self.data["ells"], 0, nlp.k)
            vec = np.array([cell_all_th[key][0, 0] for key in self.WL_keys]).flatten()
        self.theory_prediction.update(cell_all_th)
        return np.concatenate([v, vec])

options: show_source: true

GCphMixin

cloelike.EuclidLikelihood_photo_Cls.GCphMixin

Mixin class providing photometric angular galaxy clustering specific functionality for photometric likelihoods. This mixin extends the base photometric likelihood class to include methods and attributes necessary for handling weak lensing data, such as initializing shear bins, constructing masking vectors, and computing data and theory vectors specific to weak lensing.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
class GCphMixin:
    """
    Mixin class providing photometric angular galaxy clustering specific functionality for photometric likelihoods.
    This mixin extends the base photometric likelihood class to include methods and attributes
    necessary for handling weak lensing data, such as initializing shear bins, constructing
    masking vectors, and computing data and theory vectors specific to weak lensing.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._init_gcph()

    def _init_gcph(self):
        self.n_pos_bins = self.data["dndz_pos"].shape[0]
        self._init_pos_keys()
        self.GG_keys = [
            ("POS", "POS", i, j)
            for i in range(1, self.n_pos_bins + 1)
            for j in range(i, self.n_pos_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                self._masking(self.data["ells"], self.scale_cuts[key])
                for key in self.GG_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.array([self.data["cells"][key] for key in self.GG_keys]).flatten()
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        pos = self._get_pos_tracer(parameters, nlp)
        if self.mode == "coupled":
            cell_all_th = AngularTwoPoint(pos, pos).get_pseudo_Cl(0, nlp.k, self.mixmat)
            vec = np.array([cell_all_th[key] for key in self.GG_keys]).flatten()
        else:
            cell_all_th = AngularTwoPoint(pos, pos).get_Cl(self.data["ells"], 0, nlp.k)
            vec = np.array([cell_all_th[key] for key in self.GG_keys]).flatten()
        self.theory_prediction.update(cell_all_th)
        return np.concatenate([v, vec])

options: show_source: true

GGLMixin

cloelike.EuclidLikelihood_photo_Cls.GGLMixin

Mixin class providing galaxy-galaxy lensing specific functionality for photometric likelihoods. This mixin extends the base photometric likelihood class to include methods and attributes necessary for handling weak lensing data, such as initializing shear bins, constructing masking vectors, and computing data and theory vectors specific to weak lensing.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
class GGLMixin:
    """
    Mixin class providing galaxy-galaxy lensing specific functionality for photometric likelihoods.
    This mixin extends the base photometric likelihood class to include methods and attributes
    necessary for handling weak lensing data, such as initializing shear bins, constructing
    masking vectors, and computing data and theory vectors specific to weak lensing.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._init_ggl()

    def _init_ggl(self):
        self.n_pos_bins = self.data["dndz_pos"].shape[0]
        self.n_she_bins = self.data["dndz_she"].shape[0]
        self._init_pos_keys()
        self._init_she_keys()
        self.GGL_keys = [
            ("POS", "SHE", i, j)
            for i in range(1, self.n_pos_bins + 1)
            for j in range(1, self.n_she_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                self._masking(self.data["ells"], self.scale_cuts[key])
                for key in self.GGL_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.array([self.data["cells"][key][0] for key in self.GGL_keys]).flatten()
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        pos = self._get_pos_tracer(parameters, nlp)
        she = self._get_she_tracer(parameters, nlp)
        if self.mode == "coupled":
            cell_all_th = AngularTwoPoint(pos, she).get_pseudo_Cl(0, nlp.k, self.mixmat)
            vec = np.array([cell_all_th[key][0] for key in self.GGL_keys]).flatten()
        else:
            cell_all_th = AngularTwoPoint(pos, she).get_Cl(self.data["ells"], 0, nlp.k)
            vec = np.array([cell_all_th[key][0] for key in self.GGL_keys]).flatten()
        self.theory_prediction.update(cell_all_th)
        return np.concatenate([v, vec])

options: show_source: true

BNTMixin

cloelike.EuclidLikelihood_photo_Cls.BNTMixin

Mixin that applies a BNT transform to shear-related blocks (WL and GGL) in the photometric likelihood.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
class BNTMixin:
    """
    Mixin that applies a BNT transform to shear-related blocks (WL and GGL)
    in the photometric likelihood.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # test to make sure n(z) is in data
        if "dndz_she" not in self.data:
            raise ValueError(
                "BNTMixin requires 'dndz_she' in self.data to determine "
                "the number of shear bins. This is needed to validate the "
                "shape of the provided BNT matrix."
            )

        n_she_bins = self.data["dndz_she"].shape[0]

        # check to make sure BNT matrix is present.
        if "BNT_matrix" not in self.data:
            raise ValueError(
                "BNTMixin requires a precomputed BNT matrix to be provided in "
                "data['BNT_matrix']. Please compute the BNT matrix "
                "(shape [n_she_bins, n_she_bins]) elsewhere and store it "
                "in the data dict before constructing the likelihood."
            )

        # check to make sure BNT matrix is valid.
        T = np.asarray(self.data["BNT_matrix"])
        if T.ndim != 2 or T.shape[0] != T.shape[1]:
            raise ValueError(
                f"BNT_matrix must be a square 2D array, got shape {T.shape}."
            )
        if T.shape[0] != n_she_bins:
            raise ValueError(
                f"BNT_matrix shape {T.shape} is inconsistent with the number of "
                f"shear bins inferred from data['dndz_she'] "
                f"({n_she_bins} bins)."
            )

        self.BNT_matrix = T

        #  Build projection matrix P and precompute transformed data/cov
        self._P = self._build_full_projection_matrix(T)

        base_data = super().get_data_vector_full()
        base_cov = super().get_covariance_matrix_full()

        self._data_vec_full_BNT = self._P @ base_data
        self._cov_full_BNT = self._P @ base_cov @ self._P.T

    def _build_full_projection_matrix(self, T: np.ndarray) -> np.ndarray:
        """
        Build the full projection matrix P given a BNT matrix T acting on WL
        and on the shear leg of GGL.

        P acts on the concatenated data/theory vector:

            [ WL ; GGL ; GCph ]

        which is the order in which the mixins append their blocks, where some
        blocks may be absent depending on the specific likelihood class (WL only,
        GGL+GCph, or full 3x2pt).
        """
        base_vec = super().get_data_vector_full()
        dim_total = base_vec.size
        n_ell = len(self.data["ells"])
        n_she = self.data["dndz_she"].shape[0]

        # How many pairs in each block?
        n_GC_pairs = len(self.GG_keys) if hasattr(self, "GG_keys") else 0
        n_GGL_pairs = len(self.GGL_keys) if hasattr(self, "GGL_keys") else 0
        n_WL_pairs = len(self.WL_keys) if hasattr(self, "WL_keys") else 0

        dim_GC = n_GC_pairs * n_ell
        dim_GGL = n_GGL_pairs * n_ell
        dim_WL = n_WL_pairs * n_ell

        if dim_GC + dim_GGL + dim_WL != dim_total:
            raise RuntimeError(
                "Inconsistent data-vector dimensions when building BNT "
                f"projection: dim_total={dim_total}, "
                f"GC={dim_GC}, GGL={dim_GGL}, WL={dim_WL}."
            )

        # Start with identity.
        P = np.eye(dim_total)

        # Offsets in the full vector.
        start_WL = 0
        end_WL = start_WL + dim_WL
        start_GGL = end_WL
        end_GGL = start_GGL + dim_GGL

        # GGL block: transform shear index only.
        if dim_GGL > 0:
            P_GGL = self._build_GGL_projection(T, n_ell)
            P[start_GGL:end_GGL, start_GGL:end_GGL] = P_GGL

        # WL block: transform both shear indices.
        if dim_WL > 0:
            P_WL = self._build_WL_projection(T, n_ell, n_she)
            P[start_WL:end_WL, start_WL:end_WL] = P_WL

        # GCph block is left as identity (no transform).
        return P

    def _build_WL_projection(self, T: np.ndarray, n_ell: int, n_she: int) -> np.ndarray:
        """
        Build the WL subspace projection matrix P_WL.

        WL block layout (from WLMixin):
        - WL_keys:
            [("SHE","SHE", i, j) for i in 1..n_she for j in i..n_she]
        - for each key, we take cells[key][0,0], a 1D array over ell
        - final WL vector is flattened in (pair, ell) order.

        For each ell, we implement:
            C'_{ab}(ell) = sum_{i,j} T_{ai} T_{bj} C_{ij}(ell)
        using symmetry C_{ij} = C_{ji}.
        """
        if not hasattr(self, "WL_keys"):
            raise RuntimeError(
                "BNTMixin: WL projection requested but 'WL_keys' is missing. "
                "Make sure WLMixin is in the MRO."
            )

        # Use the WL pair ordering used to build the data vector
        pairs = [(key[2], key[3]) for key in self.WL_keys]
        n_pairs = len(pairs)

        # Sanity check: consistent with number of shear bins
        expected_pairs = n_she * (n_she + 1) // 2
        if n_pairs != expected_pairs:
            raise RuntimeError(
                f"BNTMixin: WL_keys length ({n_pairs}) is inconsistent with "
                f"n_she={n_she} (expected {expected_pairs} pairs)."
            )

        pair_to_idx = {pair: idx for idx, pair in enumerate(pairs)}

        # Build pair-level transformation L_pairs (n_pairs x n_pairs).
        L_pairs = np.zeros((n_pairs, n_pairs))

        for a in range(1, n_she + 1):
            for b in range(a, n_she + 1):
                out_pair = (a, b)
                out_idx = pair_to_idx[out_pair]
                row = L_pairs[out_idx]

                for i in range(1, n_she + 1):
                    for j in range(1, n_she + 1):
                        coeff = T[a - 1, i - 1] * T[b - 1, j - 1]
                        if coeff == 0.0:
                            continue
                        # Symmetry C_{ij} = C_{ji}
                        in_pair = (i, j) if i <= j else (j, i)
                        idx_in = pair_to_idx[in_pair]
                        row[idx_in] += coeff

        # Lift L_pairs to include ell: WL vector has shape (n_pairs * n_ell,).
        dim = n_pairs * n_ell
        P_WL = np.zeros((dim, dim))

        for p_out in range(n_pairs):
            for p_in in range(n_pairs):
                c = L_pairs[p_out, p_in]
                if c == 0.0:
                    continue
                for ell in range(n_ell):
                    out_idx = p_out * n_ell + ell
                    in_idx = p_in * n_ell + ell
                    P_WL[out_idx, in_idx] = c

        return P_WL

    def _build_GGL_projection(self, T: np.ndarray, n_ell: int) -> np.ndarray:
        """
        Build the GGL subspace projection matrix P_GGL.

        GGL block layout (from GGLMixin):
        - GGL_keys:
            [("POS","SHE", i, j)
             for i in 1..n_pos_bins
             for j in 1..n_she_bins]
        - for each key, we take cells[key][0], a 1D array over ell
        - final GGL vector is flattened in (pair, ell) order, where
          'pair' is (pos_bin, she_bin).

        For each ell and each position bin p, we implement:
            C'_{p,a}(ell) = sum_{j} T_{a j} C_{p,j}(ell)
        i.e. a BNT transform on the shear index only.
        """
        if "dndz_pos" not in self.data:
            raise RuntimeError(
                "GGL projection requested but 'dndz_pos' is missing in data."
            )
        if not hasattr(self, "GGL_keys"):
            raise RuntimeError(
                "BNTMixin: GGL projection requested but 'GGL_keys' is missing. "
                "Make sure GGLMixin is in the MRO."
            )

        n_pos = self.data["dndz_pos"].shape[0]
        n_she = self.data["dndz_she"].shape[0]

        # Use the GGL pair ordering used to build the data vector.
        pairs = [(key[2], key[3]) for key in self.GGL_keys]
        n_pairs = len(pairs)

        expected_pairs = n_pos * n_she
        if n_pairs != expected_pairs:
            raise RuntimeError(
                f"BNTMixin: GGL_keys length ({n_pairs}) is inconsistent with "
                f"n_pos={n_pos}, n_she={n_she} (expected {expected_pairs} pairs)."
            )

        pair_to_idx = {pair: idx for idx, pair in enumerate(pairs)}

        # Build pair-level transformation L_GGL (n_pairs x n_pairs).
        L_GGL = np.zeros((n_pairs, n_pairs))

        for p in range(1, n_pos + 1):
            for a in range(1, n_she + 1):
                out_pair = (p, a)
                out_idx = pair_to_idx[out_pair]
                row = L_GGL[out_idx]

                for j in range(1, n_she + 1):
                    in_pair = (p, j)
                    in_idx = pair_to_idx[in_pair]
                    row[in_idx] += T[a - 1, j - 1]

        # Lift L_GGL to include ell: GGL vector has shape (n_pairs * n_ell,).
        dim = n_pairs * n_ell
        P_GGL = np.zeros((dim, dim))

        for p_out in range(n_pairs):
            for p_in in range(n_pairs):
                c = L_GGL[p_out, p_in]
                if c == 0.0:
                    continue
                for ell in range(n_ell):
                    out_idx = p_out * n_ell + ell
                    in_idx = p_in * n_ell + ell
                    P_GGL[out_idx, in_idx] = c

        return P_GGL

    #  Overrides of base interface.
    def get_data_vector_full(self) -> np.ndarray:
        """Return BNT-transformed full data vector."""
        return self._data_vec_full_BNT

    def get_covariance_matrix_full(self) -> np.ndarray:
        """Return BNT-transformed full covariance matrix."""
        return self._cov_full_BNT

    def get_theory_vector_full(self, parameters: dict) -> np.ndarray:
        """
        Return BNT-transformed theory vector.

        Theory is recomputed for each parameter set using the base class,
        then transformed by the precomputed projection matrix `_P`.
        """
        base_theory = super().get_theory_vector_full(parameters)
        return self._P @ base_theory

Methods:

get_data_vector_full

get_data_vector_full() -> np.ndarray

Return BNT-transformed full data vector.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
def get_data_vector_full(self) -> np.ndarray:
    """Return BNT-transformed full data vector."""
    return self._data_vec_full_BNT

get_covariance_matrix_full

get_covariance_matrix_full() -> np.ndarray

Return BNT-transformed full covariance matrix.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
def get_covariance_matrix_full(self) -> np.ndarray:
    """Return BNT-transformed full covariance matrix."""
    return self._cov_full_BNT

get_theory_vector_full

get_theory_vector_full(parameters: dict) -> np.ndarray

Return BNT-transformed theory vector.

Theory is recomputed for each parameter set using the base class, then transformed by the precomputed projection matrix _P.

Source code in cloelike/EuclidLikelihood_photo_Cls.py
def get_theory_vector_full(self, parameters: dict) -> np.ndarray:
    """
    Return BNT-transformed theory vector.

    Theory is recomputed for each parameter set using the base class,
    then transformed by the precomputed projection matrix `_P`.
    """
    base_theory = super().get_theory_vector_full(parameters)
    return self._P @ base_theory

options: show_source: true

Concrete likelihoods:

EuclidLikelihood_WL

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_WL

Bases: WLMixin, PhotoLikelihoodBase

EuclidLikelihood_WL computes the weak lensing (WL) likelihood for photometric surveys using Euclid data.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. WLMixin: Mixin providing weak lensing specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_WL(WLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_WL computes the weak lensing (WL) likelihood for photometric surveys using Euclid data.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        WLMixin: Mixin providing weak lensing specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_GCph

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_GCph

Bases: GCphMixin, PhotoLikelihoodBase

EuclidLikelihood_GCph computes the likelihood for galaxy clustering photometric (GCph) data using the Euclid survey specifications.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. GCphMixin: Mixin providing GCph-specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_GCph(GCphMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_GCph computes the likelihood for galaxy clustering photometric (GCph) data
    using the Euclid survey specifications.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        GCphMixin: Mixin providing GCph-specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_GGL

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_GGL

Bases: GGLMixin, PhotoLikelihoodBase

EuclidLikelihood_GGL class for galaxy-galaxy lensing likelihood computation.

This class combines the functionalities of PhotoLikelihoodBase and GGLMixin to compute the likelihood for galaxy-galaxy lensing (GGL) using photometric data. It initializes the necessary components and constructs a masking vector based on scale cuts for each GGL key.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. GGLMixin: Mixin providing GGL-specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_GGL(GGLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_GGL class for galaxy-galaxy lensing likelihood computation.

    This class combines the functionalities of PhotoLikelihoodBase and GGLMixin to compute
    the likelihood for galaxy-galaxy lensing (GGL) using photometric data. It initializes
    the necessary components and constructs a masking vector based on scale cuts for each
    GGL key.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        GGLMixin: Mixin providing GGL-specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_3x2pt

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_3x2pt

Bases: GCphMixin, GGLMixin, WLMixin, PhotoLikelihoodBase

EuclidLikelihood_3x2pt combines weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL) likelihoods for photometric cosmological analyses, supporting scale cuts and masking.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. GCphMixin: Mixin providing galaxy clustering specific functionality. GGLMixin: Mixin providing galaxy-galaxy lensing specific functionality. WLMixin: Mixin providing weak lensing specific functionality.

Note: The order of inheritance matters due to the method resolution order (MRO) in Python and how mixins extend the base class functionality. Each mixin appends its block after the blocks of the mixins that follow it in the MRO, so the data vector, and therefore the covariance matrix blocks, are ordered WL, GGL and GCph.

Parameters:

Name Type Description Default
data dict

Dictionary containing observational data vectors and related metadata.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance providing background cosmology calculations.

required
LinPerturbations object

Instance for linear perturbation theory calculations.

required
NonLinPerturbations object

Instance for non-linear perturbation theory calculations.

required
mode str

Mode for likelihood calculation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_3x2pt(GCphMixin, GGLMixin, WLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_3x2pt combines weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL)
    likelihoods for photometric cosmological analyses, supporting scale cuts and masking.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        GCphMixin: Mixin providing galaxy clustering specific functionality.
        GGLMixin: Mixin providing galaxy-galaxy lensing specific functionality.
        WLMixin: Mixin providing weak lensing specific functionality.

    Note: The order of inheritance matters due to the method resolution order (MRO) in Python
    and how mixins extend the base class functionality. Each mixin appends its block after
    the blocks of the mixins that follow it in the MRO, so the data vector, and therefore
    the covariance matrix blocks, are ordered WL, GGL and GCph.

    Parameters
    ----------
    data : dict
        Dictionary containing observational data vectors and related metadata.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance providing background cosmology calculations.
    LinPerturbations : object
        Instance for linear perturbation theory calculations.
    NonLinPerturbations : object
        Instance for non-linear perturbation theory calculations.
    mode : str, optional
        Mode for likelihood calculation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_2x2pt

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_2x2pt

Bases: GCphMixin, GGLMixin, PhotoLikelihoodBase

Likelihood class for Euclid 2x2pt photometric clustering and galaxy-galaxy lensing analysis.

This class combines galaxy clustering (GCph) and galaxy-galaxy lensing (GGL) likelihoods, providing methods to compute the full data and theory vectors for both probes.

Note: The order of inheritance matters due to the method resolution order (MRO) in Python and how mixins extend the base class functionality. Each mixin appends its block after the blocks of the mixins that follow it in the MRO, so the data vector, and therefore the covariance matrix blocks, are ordered GGL and GCph.

Parameters:

Name Type Description Default
data dict

Input data dictionary containing observed power spectra and related quantities.

required
settings dict

Configuration settings for the likelihood analysis.

required
Background object

Cosmological background model instance.

required
LinPerturbations object

Linear perturbations model instance.

required
NonLinPerturbations object

Non-linear perturbations model instance.

required
mode str

Mode for likelihood computation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_2x2pt(GCphMixin, GGLMixin, PhotoLikelihoodBase):
    """
    Likelihood class for Euclid 2x2pt photometric clustering and galaxy-galaxy lensing analysis.

    This class combines galaxy clustering (GCph) and galaxy-galaxy lensing (GGL) likelihoods,
    providing methods to compute the full data and theory vectors for both probes.

    Note: The order of inheritance matters due to the method resolution order (MRO) in Python
    and how mixins extend the base class functionality. Each mixin appends its block after
    the blocks of the mixins that follow it in the MRO, so the data vector, and therefore
    the covariance matrix blocks, are ordered GGL and GCph.

    Parameters
    ----------
    data : dict
        Input data dictionary containing observed power spectra and related quantities.
    settings : dict
        Configuration settings for the likelihood analysis.
    Background : object
        Cosmological background model instance.
    LinPerturbations : object
        Linear perturbations model instance.
    NonLinPerturbations : object
        Non-linear perturbations model instance.
    mode : str, optional
        Mode for likelihood computation, default is "coupled".
    """

    pass

options: show_source: true

BNT variants — Cls likelihoods with B-mode Nulling Transform applied to shear blocks. Require a precomputed data['BNT_matrix']:

EuclidLikelihood_WL_BNT

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_WL_BNT

Bases: BNTMixin, EuclidLikelihood_WL

EuclidLikelihood_WL_BNT computes the weak lensing (WL) likelihood in BNT basis for photometric surveys using Euclid data.

Inherits from: EuclidLikelihood_WL: Base class for weak lensing likelihoods. BNTMixin: Mixin providing BNT specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_WL_BNT(BNTMixin, EuclidLikelihood_WL):
    """
    EuclidLikelihood_WL_BNT computes the weak lensing (WL) likelihood in BNT basis for photometric surveys using Euclid data.

    Inherits from:
        EuclidLikelihood_WL: Base class for weak lensing likelihoods.
        BNTMixin: Mixin providing BNT specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_GGL_BNT

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_GGL_BNT

Bases: BNTMixin, EuclidLikelihood_GGL

EuclidLikelihood_GGL_BNT class for galaxy-galaxy lensing likelihood computation in the BNT basis.

Inherits from: EuclidLikelihood_GGL: Base class for galaxy-galaxy lensing likelihoods. BNTMixin: Mixin providing BNT specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_GGL_BNT(BNTMixin, EuclidLikelihood_GGL):
    """
    EuclidLikelihood_GGL_BNT class for galaxy-galaxy lensing likelihood computation in the BNT basis.


    Inherits from:
        EuclidLikelihood_GGL: Base class for galaxy-galaxy lensing likelihoods.
        BNTMixin: Mixin providing BNT specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_3x2pt_BNT

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_3x2pt_BNT

Bases: BNTMixin, EuclidLikelihood_3x2pt

EuclidLikelihood__3x2pt_BNT weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL) likelihoods for photometric cosmological analyses, supporting scale cuts and masking. with WL in the BNT basis.

Inherits from: EuclidLikelihood_3x2pt: Base class for 3x2pt likelihoods. BNTMixin: Mixin providing BNT specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_3x2pt_BNT(BNTMixin, EuclidLikelihood_3x2pt):
    """
    EuclidLikelihood__3x2pt_BNT weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL)
    likelihoods for photometric cosmological analyses, supporting scale cuts and masking.
    with WL in the BNT basis.

    Inherits from:
        EuclidLikelihood_3x2pt: Base class for 3x2pt likelihoods.
        BNTMixin: Mixin providing BNT specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_2x2pt_BNT

cloelike.EuclidLikelihood_photo_Cls.EuclidLikelihood_2x2pt_BNT

Bases: BNTMixin, EuclidLikelihood_2x2pt

EuclidLikelihood__2x2pt_BNT weak lensing (WL) and galaxy-galaxy lensing (GGL) likelihoods for photometric cosmological analyses, supporting scale cuts and masking. with WL in the BNT basis.

Inherits from: EuclidLikelihood_2x2pt: Base class for 2x2pt likelihoods. BNTMixin: Mixin providing BNT specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_Cls.py
class EuclidLikelihood_2x2pt_BNT(BNTMixin, EuclidLikelihood_2x2pt):
    """
    EuclidLikelihood__2x2pt_BNT weak lensing (WL) and galaxy-galaxy lensing (GGL)
    likelihoods for photometric cosmological analyses, supporting scale cuts and masking.
    with WL in the BNT basis.

    Inherits from:
        EuclidLikelihood_2x2pt: Base class for 2x2pt likelihoods.
        BNTMixin: Mixin providing BNT specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true


Two-Point Correlation Functions (2PCF)

Classes from cloelike.EuclidLikelihood_photo_2pcf, computing likelihoods in real space (ξ₊, ξ₋, w, γₜ).

Mixins — composable building blocks for 2PCF likelihoods:

WLMixin (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.WLMixin

Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class WLMixin:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # Call the next class in the MRO
        self._init_wl()

    def _init_wl(self):
        self.n_she_bins = self.data["dndz_she"].shape[0]
        self._init_she_keys()
        self.WL_keys = [
            ("SHE", "SHE", i, j)
            for i in range(1, self.n_she_bins + 1)
            for j in range(i, self.n_she_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec_plus = np.concatenate(
            [
                self._masking(self.data["theta"], self.scale_cuts[key][:2])
                for key in self.WL_keys
            ]
        )
        vec_minus = np.concatenate(
            [
                self._masking(self.data["theta"], self.scale_cuts[key][2:4])
                for key in self.WL_keys
            ]
        )
        vec = np.concatenate(
            [vec_plus, vec_minus]
        )  # vec_plus:xi_plus,vec_minus:xi_minus
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec_plus = np.array(
            [self.data["2pcf"][key][0, 0] for key in self.WL_keys]
        ).flatten()
        vec_minus = np.array(
            [self.data["2pcf"][key][1, 1] for key in self.WL_keys]
        ).flatten()
        vec = np.concatenate([vec_plus, vec_minus])
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        she = self._get_she_tracer(parameters, nlp)
        cf_all_th = AngularCorrelationFunctionWigner(
            AngularTwoPoint(she, she), self.ells_integration, nlp.k
        ).get_xi(np.radians(self.data["theta"] / 60))
        vec_plus = np.array([cf_all_th[key][0, 0] for key in self.WL_keys]).flatten()
        vec_minus = np.array([cf_all_th[key][1, 1] for key in self.WL_keys]).flatten()
        vec = np.concatenate([vec_plus, vec_minus])
        self.theory_prediction = cf_all_th
        return np.concatenate([v, vec])

options: show_source: true

GCphMixin (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.GCphMixin

Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class GCphMixin:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._init_gcph()

    def _init_gcph(self):
        self.n_pos_bins = self.data["dndz_pos"].shape[0]
        self._init_pos_keys()
        self.GG_keys = [
            ("POS", "POS", i, j)
            for i in range(1, self.n_pos_bins + 1)
            for j in range(i, self.n_pos_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                self._masking(self.data["theta"], self.scale_cuts[key])
                for key in self.GG_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.array([self.data["2pcf"][key] for key in self.GG_keys]).flatten()
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        pos = self._get_pos_tracer(parameters, nlp)
        cf_all_th = AngularCorrelationFunctionWigner(
            AngularTwoPoint(pos, pos), self.ells_integration, nlp.k
        ).get_xi(np.radians(self.data["theta"] / 60))
        vec = np.array([cf_all_th[key] for key in self.GG_keys]).flatten()

        self.theory_prediction = cf_all_th
        return np.concatenate([v, vec])

options: show_source: true

GGLMixin (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.GGLMixin

Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class GGLMixin:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._init_ggl()

    def _init_ggl(self):
        self.n_pos_bins = self.data["dndz_pos"].shape[0]
        self.n_she_bins = self.data["dndz_she"].shape[0]
        self._init_pos_keys()
        self._init_she_keys()
        self.GGL_keys = [
            ("POS", "SHE", i, j)
            for i in range(1, self.n_pos_bins + 1)
            for j in range(1, self.n_she_bins + 1)
        ]

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                self._masking(self.data["theta"], self.scale_cuts[key])
                for key in self.GGL_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.array([self.data["2pcf"][key][0] for key in self.GGL_keys]).flatten()
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        pos = self._get_pos_tracer(parameters, nlp)
        she = self._get_she_tracer(parameters, nlp)

        cf_all_th = AngularCorrelationFunctionWigner(
            AngularTwoPoint(pos, she), self.ells_integration, nlp.k
        ).get_xi(np.radians(self.data["theta"] / 60))
        vec = np.array([cf_all_th[key][0] for key in self.GGL_keys]).flatten()

        self.theory_prediction = cf_all_th
        return np.concatenate([v, vec])

options: show_source: true

Concrete likelihoods:

EuclidLikelihood_WL (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.EuclidLikelihood_WL

Bases: WLMixin, PhotoLikelihoodBase

EuclidLikelihood_WL computes the weak lensing (WL) likelihood for photometric surveys using Euclid data.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. WLMixin: Mixin providing weak lensing specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class EuclidLikelihood_WL(WLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_WL computes the weak lensing (WL) likelihood for photometric surveys using Euclid data.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        WLMixin: Mixin providing weak lensing specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_GCph (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.EuclidLikelihood_GCph

Bases: GCphMixin, PhotoLikelihoodBase

EuclidLikelihood_GCph computes the likelihood for galaxy clustering photometric (GCph) data using the Euclid survey specifications.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. GCphMixin: Mixin providing GCph-specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class EuclidLikelihood_GCph(GCphMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_GCph computes the likelihood for galaxy clustering photometric (GCph) data
    using the Euclid survey specifications.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        GCphMixin: Mixin providing GCph-specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_GGL (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.EuclidLikelihood_GGL

Bases: GGLMixin, PhotoLikelihoodBase

EuclidLikelihood_GGL class for galaxy-galaxy lensing likelihood computation.

This class combines the functionalities of PhotoLikelihoodBase and GGLMixin to compute the likelihood for galaxy-galaxy lensing (GGL) using photometric data. It initializes the necessary components and constructs a masking vector based on scale cuts for each GGL key.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation, including observed ells and other relevant quantities.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
mode str

Mode of operation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class EuclidLikelihood_GGL(GGLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_GGL class for galaxy-galaxy lensing likelihood computation.

    This class combines the functionalities of PhotoLikelihoodBase and GGLMixin to compute
    the likelihood for galaxy-galaxy lensing (GGL) using photometric data. It initializes
    the necessary components and constructs a masking vector based on scale cuts for each
    GGL key.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation, including observed ells and other relevant quantities.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    mode : str, optional
        Mode of operation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_3x2pt (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.EuclidLikelihood_3x2pt

Bases: GCphMixin, GGLMixin, WLMixin, PhotoLikelihoodBase

EuclidLikelihood_3x2pt combines weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL) likelihoods for photometric cosmological analyses, supporting scale cuts and masking.

Parameters:

Name Type Description Default
data dict

Dictionary containing observational data vectors and related metadata.

required
settings dict

Configuration settings for the likelihood calculation.

required
Background object

Instance providing background cosmology calculations.

required
LinPerturbations object

Instance for linear perturbation theory calculations.

required
NonLinPerturbations object

Instance for non-linear perturbation theory calculations.

required
mode str

Mode for likelihood calculation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class EuclidLikelihood_3x2pt(GCphMixin, GGLMixin, WLMixin, PhotoLikelihoodBase):
    """
    EuclidLikelihood_3x2pt combines weak lensing (WL), galaxy clustering (GCph), and galaxy-galaxy lensing (GGL)
    likelihoods for photometric cosmological analyses, supporting scale cuts and masking.
    Parameters
    ----------
    data : dict
        Dictionary containing observational data vectors and related metadata.
    settings : dict
        Configuration settings for the likelihood calculation.
    Background : object
        Instance providing background cosmology calculations.
    LinPerturbations : object
        Instance for linear perturbation theory calculations.
    NonLinPerturbations : object
        Instance for non-linear perturbation theory calculations.
    mode : str, optional
        Mode for likelihood calculation, default is "coupled".
    """

    pass

options: show_source: true

EuclidLikelihood_2x2pt (2PCF)

cloelike.EuclidLikelihood_photo_2pcf.EuclidLikelihood_2x2pt

Bases: GCphMixin, GGLMixin, PhotoLikelihoodBase

Likelihood class for Euclid 2x2pt photometric clustering and galaxy-galaxy lensing analysis.

This class combines galaxy clustering (GCph) and galaxy-galaxy lensing (GGL) likelihoods, providing methods to compute the full data and theory vectors for both probes.

Parameters:

Name Type Description Default
data dict

Input data dictionary containing observed power spectra and related quantities.

required
settings dict

Configuration settings for the likelihood analysis.

required
Background object

Cosmological background model instance.

required
LinPerturbations object

Linear perturbations model instance.

required
NonLinPerturbations object

Non-linear perturbations model instance.

required
mode str

Mode for likelihood computation, default is "coupled".

required
Source code in cloelike/EuclidLikelihood_photo_2pcf.py
class EuclidLikelihood_2x2pt(GCphMixin, GGLMixin, PhotoLikelihoodBase):
    """
    Likelihood class for Euclid 2x2pt photometric clustering and galaxy-galaxy lensing analysis.

    This class combines galaxy clustering (GCph) and galaxy-galaxy lensing (GGL) likelihoods,
    providing methods to compute the full data and theory vectors for both probes.

    Parameters
    ----------
    data : dict
        Input data dictionary containing observed power spectra and related quantities.
    settings : dict
        Configuration settings for the likelihood analysis.
    Background : object
        Cosmological background model instance.
    LinPerturbations : object
        Linear perturbations model instance.
    NonLinPerturbations : object
        Non-linear perturbations model instance.
    mode : str, optional
        Mode for likelihood computation, default is "coupled".
    """

    pass

options: show_source: true


COSEBIs

Classes from cloelike.EuclidLikelihood_photo_COSEBIs. The data are the COSEBI objects returned by euclidlib.le3.twopcf_wl.cosebis, with shape (2, 2, n_modes); only the E-modes enter the likelihood. The angular range is set by the w_ells kernels, which must match the data thmin/thmax.

WLCosebi

cloelike.EuclidLikelihood_photo_COSEBIs.WLCosebi

WLCosebi class providing COSEBI weak lensing (WL) specific functionality for photometric likelihoods. This mixin extends the base photometric likelihood class to include methods and attributes necessary for handling COSEBI weak lensing data, such as initializing shear bins, constructing masking vectors, and computing data and theory vectors specific to weak lensing.

Only the E-modes (array[0, 0]) enter the likelihood. Data and theory are COSEBI objects of shape (2, 2, n_modes) ([[EE, EB], [EB, BB]]) and are matched by mode number, so selected_modes can be any subset of the data modes.

Required entries in data: cosebis: dict of COSEBI objects keyed by ('SHE', 'SHE', i, j), as returned by euclidlib.le3.twopcf_wl.cosebis. thmin and thmax are in arcmin, as in the Euclid LE3 product.

Required entries in settings: w_ells: harmonic-space COSEBI kernels (global or per-bin layout, see cloelib.summary_statistics.angular_two_point.get_cosebis_from_cl). They set the angular range (THMIN/THMAX in radians), which must match the data. ells_integration_COSEBI: multipoles at which w_ells are evaluated. selected_modes (optional): modes entering the likelihood, defaults to 1..7.

Source code in cloelike/EuclidLikelihood_photo_COSEBIs.py
class WLCosebi:
    """
    WLCosebi class providing COSEBI weak lensing (WL) specific functionality for photometric likelihoods.
    This mixin extends the base photometric likelihood class to include methods and attributes
    necessary for handling COSEBI weak lensing data, such as initializing shear bins, constructing
    masking vectors, and computing data and theory vectors specific to weak lensing.

    Only the E-modes (``array[0, 0]``) enter the likelihood. Data and theory are
    ``COSEBI`` objects of shape ``(2, 2, n_modes)`` (``[[EE, EB], [EB, BB]]``)
    and are matched by mode number, so ``selected_modes`` can be any subset of
    the data modes.

    Required entries in ``data``:
        cosebis: dict of ``COSEBI`` objects keyed by ``('SHE', 'SHE', i, j)``,
            as returned by ``euclidlib.le3.twopcf_wl.cosebis``. ``thmin`` and
            ``thmax`` are in arcmin, as in the Euclid LE3 product.

    Required entries in ``settings``:
        w_ells: harmonic-space COSEBI kernels (global or per-bin layout, see
            ``cloelib.summary_statistics.angular_two_point.get_cosebis_from_cl``).
            They set the angular range (THMIN/THMAX in radians), which must
            match the data.
        ells_integration_COSEBI: multipoles at which ``w_ells`` are evaluated.
        selected_modes (optional): modes entering the likelihood, defaults to 1..7.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # Call the next class in the MRO
        self._init_wl()
        self._init_cosebis()

    def _init_wl(self):
        self.n_she_bins = self.data["dndz_she"].shape[0]
        self._init_she_keys()
        self.WL_keys = [
            ("SHE", "SHE", i, j)
            for i in range(1, self.n_she_bins + 1)
            for j in range(i, self.n_she_bins + 1)
        ]

    def _init_cosebis(self):
        if "w_ells" not in self.settings:
            raise ValueError("settings['w_ells'] (COSEBI kernels) is required.")
        self.w_ells = self.settings["w_ells"]
        self.ells_integration_COSEBI = self.settings.get("ells_integration_COSEBI")
        if self.ells_integration_COSEBI is None:
            raise ValueError(
                "settings['ells_integration_COSEBI'] matching the w_ells is required."
            )
        self.selected_modes = [
            int(n) for n in np.unique(self.settings.get("selected_modes", range(1, 8)))
        ]

        # Position of each selected mode in the data vector of every bin pair
        self._mode_index = {}
        for key in self.WL_keys:
            data_modes = [int(n) for n in np.asarray(self.data["cosebis"][key].mode)]
            missing = [n for n in self.selected_modes if n not in data_modes]
            if missing:
                raise ValueError(f"selected_modes {missing} not in the data for {key}.")
            self._mode_index[key] = np.array(
                [data_modes.index(n) for n in self.selected_modes]
            )
        self._check_kernel_scales()

    def _kernel_dicts(self):
        """All kernel dicts in `w_ells`, for both the global and per-bin layouts."""
        first_val = next(v for k, v in self.w_ells.items() if k != "metadata")
        if isinstance(first_val, dict):
            return list(self.w_ells.values())
        return [self.w_ells]

    def _check_kernel_scales(self):
        """Check that the kernels cover the same angular range as the data."""
        for kernel in self._kernel_dicts():
            missing = [n for n in self.selected_modes if n not in kernel]
            if missing:
                raise ValueError(f"selected_modes {missing} not in the w_ells kernels.")
        for key in self.WL_keys:
            c = self.data["cosebis"][key]
            data_range = np.radians(np.array([c.thmin, c.thmax]) / 60)
            for kernel in self._kernel_dicts():
                meta = kernel["metadata"]
                kernel_range = np.array([meta["THMIN"], meta["THMAX"]])
                if not np.allclose(kernel_range, data_range, rtol=1e-3):
                    raise ValueError(
                        f"w_ells angular range {np.degrees(kernel_range) * 60} arcmin "
                        f"does not match the data range [{c.thmin}, {c.thmax}] arcmin "
                        f"for {key}."
                    )

    def get_masking_vector(self):
        v = super().get_masking_vector()
        vec = np.concatenate(
            [
                np.isin(self.data["cosebis"][key].mode, self.selected_modes)
                for key in self.WL_keys
            ]
        )
        return np.concatenate([v, vec])

    def get_data_vector_full(self):
        v = super().get_data_vector_full()
        vec = np.concatenate(
            [np.asarray(self.data["cosebis"][key].array[0, 0]) for key in self.WL_keys]
        )
        return np.concatenate([v, vec])

    def get_theory_vector_full(self, parameters):
        v = super().get_theory_vector_full(parameters)
        _, _, nlp = self._get_perturbations(parameters)
        she = self._get_she_tracer(parameters, nlp)
        cosebi_all_th = AngularTwoPoint(she, she).get_cosebis(
            self.ells_integration_COSEBI, 0, nlp.k, self.w_ells, self.selected_modes
        )

        # Place the theory at the data positions of each selected mode; the
        # remaining modes are NaN and removed by the masking vector.
        vecs = []
        for key in self.WL_keys:
            full = np.full(len(self.data["cosebis"][key].mode), np.nan)
            full[self._mode_index[key]] = np.asarray(cosebi_all_th[key].array[0, 0])
            vecs.append(full)
        self.theory_prediction = cosebi_all_th
        return np.concatenate([v, np.concatenate(vecs)])

options: show_source: true

EuclidLikelihood_WLCosebi

cloelike.EuclidLikelihood_photo_COSEBIs.EuclidLikelihood_WLCosebi

Bases: WLCosebi, PhotoLikelihoodBase

EuclidLikelihood_WLCosebi computes the weak lensing (WL) COSEBI likelihood for photometric surveys using Euclid data.

Inherits from: PhotoLikelihoodBase: Base class for photometric likelihoods. WLCosebi: Mixin providing COSEBI weak lensing specific functionality.

Parameters:

Name Type Description Default
data dict

Input data required for likelihood computation: cosebis (as read by euclidlib.le3.twopcf_wl.cosebis), dndz_she, z_arr and cov.

required
settings dict

Configuration settings: w_ells, ells_integration_COSEBI and optionally selected_modes. Scale cuts are set by the w_ells.

required
Background object

Instance representing the cosmological background model.

required
LinPerturbations object

Instance representing linear perturbations.

required
NonLinPerturbations object

Instance representing non-linear perturbations.

required
Source code in cloelike/EuclidLikelihood_photo_COSEBIs.py
class EuclidLikelihood_WLCosebi(WLCosebi, PhotoLikelihoodBase):
    """
    EuclidLikelihood_WLCosebi computes the weak lensing (WL) COSEBI likelihood for photometric surveys using Euclid data.

    Inherits from:
        PhotoLikelihoodBase: Base class for photometric likelihoods.
        WLCosebi: Mixin providing COSEBI weak lensing specific functionality.

    Parameters
    ----------
    data : dict
        Input data required for likelihood computation: ``cosebis`` (as read by
        ``euclidlib.le3.twopcf_wl.cosebis``), ``dndz_she``, ``z_arr`` and ``cov``.
    settings : dict
        Configuration settings: ``w_ells``, ``ells_integration_COSEBI`` and
        optionally ``selected_modes``. Scale cuts are set by the ``w_ells``.
    Background : object
        Instance representing the cosmological background model.
    LinPerturbations : object
        Instance representing linear perturbations.
    NonLinPerturbations : object
        Instance representing non-linear perturbations.
    """

    pass

options: show_source: true