Ejemplo n.º 1
0
def test_from_and_to_hist():
    h3 = hist.NamedHist(
        hist.axis.Regular(25, -3.5, 3, name="x", flow=False),
        hist.axis.Regular(21, -4, 5, name="y", flow=False),
        storage=hist.storage.Weight(),
    )

    x2 = np.random.randn(1_000)
    y2 = 0.5 * np.random.randn(1_000)

    h3.fill(x=x2, y=y2)

    from zfit._data.binneddatav1 import BinnedData

    for _ in range(10):  # make sure this works many times
        h1 = BinnedData.from_hist(h3)
        np.testing.assert_allclose(h1.variances(), h3.variances())
        np.testing.assert_allclose(h1.values(), h3.values())
        unbinned = h1.to_unbinned()
        assert unbinned.value().shape[1] == 2
        assert unbinned.value().shape[0] == unbinned.weights.shape[0]

        h3recreated = h1.to_hist()
        assert h3recreated == h3

    bh3 = bh.Histogram(h1)
    np.testing.assert_allclose(h1.variances(), bh3.variances())
    np.testing.assert_allclose(h1.values(), bh3.values())
Ejemplo n.º 2
0
    def __init__(
        self,
        data: ztyping.BinnedDataInputType,
        extended: Optional[ztyping.ExtendedInputType] = None,
        norm: Optional[ztyping.NormInputType] = None,
        name: str = "HistogramPDF",
    ) -> None:
        """Binned PDF resembling a histogram.

        Simple histogram PDF that can be used to model a histogram as a PDF.


        Args:
            data: Histogram to be used as PDF.
            extended: |@doc:pdf.init.extended| The overall yield of the PDF.
               If this is parameter-like, it will be used as the yield,
               the expected number of events, and the PDF will be extended.
               An extended PDF has additional functionality, such as the
               `ext_*` methods and the `counts` (for binned PDFs). |@docend:pdf.init.extended|
               |@doc:pdf.init.extended.auto| If `True`,
               the PDF will be extended automatically if the PDF is extended
               using the total number of events in the histogram.
               This is the default. |@docend:pdf.init.extended.auto|
            norm: |@doc:pdf.init.norm| Normalization of the PDF.
               By default, this is the same as the default space of the PDF. |@docend:pdf.init.norm|
            name: |@doc:model.init.name| Human-readable name
               or label of
               the PDF for better identification.
               Has no programmatical functional purpose as identification. |@docend:model.init.name|
        """
        if extended is None:
            extended = True
        if not isinstance(data, ZfitBinnedData):
            if isinstance(data, PlottableHistogram):
                from zfit._data.binneddatav1 import BinnedData

                data = BinnedData.from_hist(data)
            else:
                raise TypeError(
                    "data must be of type PlottableHistogram (UHI) or ZfitBinnedData"
                )

        params = {}
        if extended is True:
            self._automatically_extended = True
            extended = znp.sum(data.values())
        else:
            self._automatically_extended = False
        super().__init__(obs=data.space,
                         extended=extended,
                         norm=norm,
                         params=params,
                         name=name)
        self._data = data
Ejemplo n.º 3
0
    def __init__(
        self,
        model: ztyping.BinnedPDFInputType,
        data: ztyping.BinnedDataInputType,
        constraints: ConstraintsInputType = None,
        options: OptionsInputType = None,
    ):
        model = convert_to_container(model)
        data = convert_to_container(data)
        from zfit._data.binneddatav1 import BinnedData

        data = [
            BinnedData.from_hist(d) if
            (isinstance(d, PlottableHistogram)
             and not isinstance(d, ZfitBinnedData)) else d for d in data
        ]
        not_binned_pdf = [
            mod for mod in model if not isinstance(mod, ZfitBinnedPDF)
        ]
        not_binned_data = [
            dat for dat in data if not isinstance(dat, ZfitBinnedData)
        ]
        not_binned_pdf_msg = (
            "The following PDFs are not binned but need to be. They can be wrapped in an "
            f"BinnedFromUnbinnedPDF. {not_binned_pdf} ")
        not_binned_data_msg = (
            "The following datasets are not binned but need to be. They can be converted to a binned "
            f"using the `to_binned` method. {not_binned_data}")
        error_msg = ""
        if not_binned_pdf:
            error_msg += not_binned_pdf_msg
        if not_binned_data:
            error_msg += not_binned_data_msg
        if error_msg:
            raise ValueError(error_msg)

        super().__init__(
            model=model,
            data=data,
            constraints=constraints,
            fit_range=None,
            options=options,
        )
Ejemplo n.º 4
0
    def _convert_input_binned_x(self, x, none_is_space=None):
        if x is None and none_is_space:
            return self.space
        if isinstance(x, uhi.typing.plottable.PlottableHistogram) and not isinstance(
            x, ZfitBinnedData
        ):
            x = BinnedData.from_hist(x)
        if not isinstance(x, ZfitBinnedData):
            if not isinstance(x, ZfitSpace):
                if not isinstance(x, ZfitUnbinnedData):
                    try:
                        x = Data.from_tensor(obs=self.obs, tensor=x)
                    except Exception as error:

                        raise TypeError(
                            f"Data to {self} has to be Binned Data, not {x}. (It can also be unbinned Data)"
                            + f" but conversion to it failed (see also above) with the following error:"
                            + f" {error})"
                        ) from error

            # TODO: should we allow spaces? Or what?
        return x
Ejemplo n.º 5
0
def test_from_and_to_binned():
    h3 = hist.Hist(
        hist.axis.Regular(3, -3, 3, name="x", flow=False),
        hist.axis.Regular(2, -5, 5, name="y", flow=False),
        storage=hist.storage.Weight(),
    )

    x2 = np.random.randn(1_000)
    y2 = 0.5 * np.random.randn(1_000)

    h3.fill(x=x2, y=y2)

    from zfit._data.binneddatav1 import BinnedData

    h1 = BinnedData.from_hist(h3)
    for _ in range(10):  # make sure this works many times
        unbinned = h1.to_unbinned()
        binned = unbinned.to_binned(space=h1.space)
        np.testing.assert_allclose(binned.values(), h1.values())
        # we can't test the variances, this info is lost
        h1 = binned
    bh3 = bh.Histogram(h1)
    np.testing.assert_allclose(h1.values(), bh3.values())
Ejemplo n.º 6
0
def test_with_obs():
    from zfit._data.binneddatav1 import BinnedData

    h1 = hist.NamedHist(
        hist.axis.Regular(25, -3.5, 3, name="x", flow=False),
        hist.axis.Regular(21, -4, 5, name="y", flow=False),
        hist.axis.Regular(15, -2, 1, name="z", flow=False),
        storage=hist.storage.Weight(),
    )

    x2 = np.random.randn(1_000)
    y2 = 0.5 * np.random.randn(1_000)
    z2 = 0.3 * np.random.randn(1_000)

    h1.fill(x=x2, y=y2, z=z2)
    h = BinnedData.from_hist(h1)
    obs = ("x", "y", "z")
    obs2 = ("y", "x", "z")
    assert obs == h.obs
    h2 = h.with_obs(obs2)
    assert h2.obs == obs2
    np.testing.assert_allclose(h.values()[:, 3, 5], h2.values()[3, :, 5])
    np.testing.assert_allclose(h.variances()[:, 3, 5], h2.variances()[3, :, 5])