From 65059d29590fdc80045e618851e055a3f1f85240 Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Thu, 14 Mar 2024 11:15:07 +0100 Subject: [PATCH 01/11] empty commit From 0912897fa0548899860bf9c2d0ba894a3b6c5ab0 Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Thu, 14 Mar 2024 13:36:09 +0100 Subject: [PATCH 02/11] first attempt --- zfit_physics/models/pdf_cmsshape.py | 68 +++++++++++++++++++++++++++++ zfit_physics/pdf.py | 3 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 zfit_physics/models/pdf_cmsshape.py diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py new file mode 100644 index 0000000..b4e6bac --- /dev/null +++ b/zfit_physics/models/pdf_cmsshape.py @@ -0,0 +1,68 @@ +from typing import Optional + +import numpy as np +import tensorflow as tf +import zfit +from zfit import z +from zfit.core.space import ANY_LOWER, ANY_UPPER, Space +from zfit.util import ztyping + + +@z.function(wraps="tensor") +def cmsshape_pdf_func(x, beta, gamma, m): + x = z.unstack_x(x) + half = 0.5 + two = 2.0 + t1 = tf.math.exp(-gamma * (x - m)) + t2 = tf.math.erfc(-beta * (x - m)) + t3 = half * gamma * tf.math.exp(-((half * gamma / beta) ** two)) + return t1 * t2 * t3 + + +@z.function(wraps="tensor") +def cmsshape_cdf_func(x, beta, gamma, m): + half = 0.5 + two = 2.0 + y = x - m + t1 = tf.math.erf(gamma / (two * beta) + beta * y) + t2 = tf.math.exp(-((gamma / (two * beta)) ** two) - gamma * y) + t3 = tf.math.erfc(-beta * y) + return half * (t1 - t2 * t3) + half + + +def cmsshape_integral(limits: ztyping.SpaceType, params: dict, model) -> tf.Tensor: + lower, upper = limits.rect_limits + beta = params["beta"] + gamma = params["gamma"] + m = params["m"] + lower_cdf = cmsshape_cdf_func(lower, beta, gamma, m) + upper_cdf = cmsshape_cdf_func(upper, beta, gamma, m) + return upper_cdf - lower_cdf + + +class CMSShape(zfit.pdf.BasePDF): + _N_OBS = 1 + + def __init__( + self, + beta: ztyping.ParamTypeInput, + gamma: ztyping.ParamTypeInput, + m: ztyping.ParamTypeInput, + obs: ztyping.ObsTypeInput, + *, + extended: ztyping.ExtendedInputType = None, + norm: ztyping.NormInputType = None, + name: str = "CMSShape", + ): + params = {"beta": beta, "gamma": gamma, "m": m} + super().__init__(obs=obs, params=params, name=name, extended=extended, norm=norm) + + def _unnormalized_pdf(self, x: tf.Tensor) -> tf.Tensor: + beta = self.params["beta"] + gamma = self.params["gamma"] + m = self.params["m"] + return cmsshape_pdf_func(x, beta, gamma, m) + + +cmsshape_integral_limits = Space(axes=(0,), limits=(((ANY_LOWER,),), ((ANY_UPPER,),))) +CMSShape.register_analytic_integral(func=cmsshape_integral, limits=cmsshape_integral_limits) diff --git a/zfit_physics/pdf.py b/zfit_physics/pdf.py index 875e0bd..2e7112b 100644 --- a/zfit_physics/pdf.py +++ b/zfit_physics/pdf.py @@ -1,4 +1,5 @@ from .models.pdf_argus import Argus +from .models.pdf_cmsshape import CMSShape from .models.pdf_relbw import RelativisticBreitWigner -__all__ = ["Argus", "RelativisticBreitWigner"] +__all__ = ["Argus", "RelativisticBreitWigner", "CMSShape"] From 9040fa43a99b5756700aa286cc7c81b6dabb04b2 Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Thu, 14 Mar 2024 14:39:37 +0100 Subject: [PATCH 03/11] be more explicit --- zfit_physics/models/pdf_cmsshape.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index b4e6bac..54c0417 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -35,8 +35,8 @@ def cmsshape_integral(limits: ztyping.SpaceType, params: dict, model) -> tf.Tens beta = params["beta"] gamma = params["gamma"] m = params["m"] - lower_cdf = cmsshape_cdf_func(lower, beta, gamma, m) - upper_cdf = cmsshape_cdf_func(upper, beta, gamma, m) + lower_cdf = cmsshape_cdf_func(x=lower, beta=beta, gamma=gamma, m=m) + upper_cdf = cmsshape_cdf_func(x=upper, beta=beta, gamma=gamma, m=m) return upper_cdf - lower_cdf @@ -50,8 +50,8 @@ def __init__( m: ztyping.ParamTypeInput, obs: ztyping.ObsTypeInput, *, - extended: ztyping.ExtendedInputType = None, - norm: ztyping.NormInputType = None, + extended: Optional[ztyping.ExtendedInputType] = None, + norm: Optional[ztyping.NormInputType] = None, name: str = "CMSShape", ): params = {"beta": beta, "gamma": gamma, "m": m} From 3b0a4befd22b603410040152eddbfbd071872a91 Mon Sep 17 00:00:00 2001 From: Iason Krommydas Date: Fri, 15 Mar 2024 11:22:31 +0100 Subject: [PATCH 04/11] fix `.pdf(x)` output shape Co-authored-by: Jonas Eschle --- zfit_physics/models/pdf_cmsshape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index 54c0417..f01f582 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -31,7 +31,7 @@ def cmsshape_cdf_func(x, beta, gamma, m): def cmsshape_integral(limits: ztyping.SpaceType, params: dict, model) -> tf.Tensor: - lower, upper = limits.rect_limits + lower, upper = limits.limit1d beta = params["beta"] gamma = params["gamma"] m = params["m"] From dc6e255209053957b3816131c4c7b3201c2ba19a Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Fri, 15 Mar 2024 12:05:45 +0100 Subject: [PATCH 05/11] add some testing --- requirements_dev.txt | 1 + tests/test_pdf_cmsshape.py | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/test_pdf_cmsshape.py diff --git a/requirements_dev.txt b/requirements_dev.txt index 579934e..6a64811 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -2,6 +2,7 @@ bumpversion>=0.5.3 coverage>=4.5.1 coverage>=4.5.1 flake8>=3.5.0 +numba-stats @ git+https://github.com/HDembinski/numba-stats.git pip>=9.0.1 pre-commit pytest>=3.4.2 diff --git a/tests/test_pdf_cmsshape.py b/tests/test_pdf_cmsshape.py new file mode 100644 index 0000000..40f2e3a --- /dev/null +++ b/tests/test_pdf_cmsshape.py @@ -0,0 +1,60 @@ +"""Tests for CMSShape PDF.""" +import pytest +import tensorflow as tf +import zfit +from numba_stats import cmsshape as cmsshape_numba + +# Important, do the imports below +from zfit.core.testing import tester + +import zfit_physics as zphys + +# specify globals here. Do NOT add any TensorFlow but just pure python +beta_true = 0.2 +gamma_true = 0.3 +m_true = 90.0 + + +def create_cmsshape(gamma, beta, m, limits): + obs = zfit.Space("obs1", limits) + cmsshape = zphys.pdf.CMSShape(gamma=gamma, beta=beta, m=m, obs=obs) + return cmsshape, obs + + +def test_cmsshape_pdf(): + # Test PDF here + cmsshape, _ = create_cmsshape(gamma=gamma_true, beta=beta_true, m=m_true, limits=(50, 130)) + assert zfit.run(cmsshape.pdf(90.0)) == pytest.approx( + cmsshape_numba.pdf(90.0, beta=beta_true, gamma=gamma_true, loc=m_true).item(), rel=1e-4 + ) + assert cmsshape.pdf(tf.range(50.0, 130, 10_000)) <= cmsshape.pdf(90.0) + + sample = cmsshape.sample(1000) + tf.debugging.assert_all_finite(sample.value(), "Some samples from the cmsshape PDF are NaN or infinite") + assert sample.n_events == 1000 + assert all(tf.logical_and(50 <= sample.value(), sample.value() <= 130)) + + +def test_cmsshape_integral(): + # Test CDF and integral here + cmsshape, obs = create_cmsshape(gamma=gamma_true, beta=beta_true, m=m_true, limits=(50, 130)) + full_interval_analytic = zfit.run(cmsshape.analytic_integrate(obs, norm_range=False)) + full_interval_numeric = zfit.run(cmsshape.numeric_integrate(obs, norm_range=False)) + true_integral = 0.99999 + assert full_interval_analytic == pytest.approx(true_integral, 1e-4) + assert full_interval_numeric == pytest.approx(true_integral, 1e-2) + + analytic_integral = zfit.run(cmsshape.analytic_integrate(limits=(80, 100), norm_range=False)) + numeric_integral = zfit.run(cmsshape.numeric_integrate(limits=(80, 100), norm_range=False)) + assert analytic_integral == pytest.approx(numeric_integral, 0.01) + + +# register the pdf here and provide sets of working parameter configurations +def cmsshape_params_factory(): + beta = zfit.Parameter("beta", beta_true) + gamma = zfit.Parameter("gamma", gamma_true) + m = zfit.Parameter("m", m_true) + return {"beta": beta, "gamma": gamma, "m": m} + + +tester.register_pdf(pdf_class=zphys.pdf.CMSShape, params_factories=cmsshape_params_factory) From 7db91fe56626ff928ac0c2bc89de89be9e26b01c Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Fri, 15 Mar 2024 12:21:12 +0100 Subject: [PATCH 06/11] more testing against numba-stats --- tests/test_pdf_cmsshape.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/test_pdf_cmsshape.py b/tests/test_pdf_cmsshape.py index 40f2e3a..9f123a7 100644 --- a/tests/test_pdf_cmsshape.py +++ b/tests/test_pdf_cmsshape.py @@ -1,4 +1,5 @@ """Tests for CMSShape PDF.""" +import numpy as np import pytest import tensorflow as tf import zfit @@ -25,7 +26,12 @@ def test_cmsshape_pdf(): # Test PDF here cmsshape, _ = create_cmsshape(gamma=gamma_true, beta=beta_true, m=m_true, limits=(50, 130)) assert zfit.run(cmsshape.pdf(90.0)) == pytest.approx( - cmsshape_numba.pdf(90.0, beta=beta_true, gamma=gamma_true, loc=m_true).item(), rel=1e-4 + cmsshape_numba.pdf(90.0, beta=beta_true, gamma=gamma_true, loc=m_true).item(), rel=1e-5 + ) + np.testing.assert_allclose( + cmsshape.pdf(tf.range(50.0, 130, 10_000)), + cmsshape_numba.pdf(tf.range(50.0, 130, 10_000).numpy(), beta=beta_true, gamma=gamma_true, loc=m_true), + rtol=1e-5, ) assert cmsshape.pdf(tf.range(50.0, 130, 10_000)) <= cmsshape.pdf(90.0) @@ -41,12 +47,21 @@ def test_cmsshape_integral(): full_interval_analytic = zfit.run(cmsshape.analytic_integrate(obs, norm_range=False)) full_interval_numeric = zfit.run(cmsshape.numeric_integrate(obs, norm_range=False)) true_integral = 0.99999 - assert full_interval_analytic == pytest.approx(true_integral, 1e-4) - assert full_interval_numeric == pytest.approx(true_integral, 1e-2) + numba_stats_full_integral = cmsshape_numba.cdf( + 130, beta=beta_true, gamma=gamma_true, loc=m_true + ) - cmsshape_numba.cdf(50, beta=beta_true, gamma=gamma_true, loc=m_true) + assert full_interval_analytic == pytest.approx(true_integral, 1e-5) + assert full_interval_numeric == pytest.approx(true_integral, 1e-5) + assert full_interval_analytic == pytest.approx(numba_stats_full_integral, 1e-8) + assert full_interval_numeric == pytest.approx(numba_stats_full_integral, 1e-8) analytic_integral = zfit.run(cmsshape.analytic_integrate(limits=(80, 100), norm_range=False)) numeric_integral = zfit.run(cmsshape.numeric_integrate(limits=(80, 100), norm_range=False)) - assert analytic_integral == pytest.approx(numeric_integral, 0.01) + numba_stats_integral = cmsshape_numba.cdf(100, beta=beta_true, gamma=gamma_true, loc=m_true) - cmsshape_numba.cdf( + 80, beta=beta_true, gamma=gamma_true, loc=m_true + ) + assert analytic_integral == pytest.approx(numeric_integral, 1e-8) + assert analytic_integral == pytest.approx(numba_stats_integral, 1e-8) # register the pdf here and provide sets of working parameter configurations From 47bbde8cc0eb9ec4969897efce97194d44c847ed Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Fri, 15 Mar 2024 12:48:14 +0100 Subject: [PATCH 07/11] add docstrings --- CHANGELOG.rst | 1 + zfit_physics/models/pdf_cmsshape.py | 88 ++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 18c438e..c90496c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,7 @@ Develop Major Features and Improvements ------------------------------- +- added CMSShape PDF Breaking changes ------------------ diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index f01f582..b3db5fe 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -1,6 +1,5 @@ from typing import Optional -import numpy as np import tensorflow as tf import zfit from zfit import z @@ -10,6 +9,21 @@ @z.function(wraps="tensor") def cmsshape_pdf_func(x, beta, gamma, m): + """Calculate the CMSShape PDF. + + Args: + x: value(s) for which the PDF will be calculated. + beta: steepness of the error function. + gamma: steepness of the exponential distribution. + m: approximate center of the distribution. + + Returns: + `tf.Tensor`: The calculated PDF values. + + Notes: + Based on code from [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) + and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py). + """ x = z.unstack_x(x) half = 0.5 two = 2.0 @@ -17,10 +31,35 @@ def cmsshape_pdf_func(x, beta, gamma, m): t2 = tf.math.erfc(-beta * (x - m)) t3 = half * gamma * tf.math.exp(-((half * gamma / beta) ** two)) return t1 * t2 * t3 + """Calculates the analytic integral of the relativistic Breit-Wigner PDF. + + Args: + limits: An object with attribute rect_limits. + params: A hashmap from which the parameters that defines the PDF will be extracted. + model: Will be ignored. + + Returns: + The calculated integral. + """ @z.function(wraps="tensor") def cmsshape_cdf_func(x, beta, gamma, m): + """Analtical function for the CDF of the CMSShape distribution. + + Args: + x: value(s) for which the CDF will be calculated. + beta: steepness of the error function. + gamma: steepness of the exponential distribution. + m: approximate center of the distribution. + + Returns: + `tf.Tensor`: The calculated CDF values. + + Notes: + Based on code from [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) + and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py). + """ half = 0.5 two = 2.0 y = x - m @@ -31,6 +70,16 @@ def cmsshape_cdf_func(x, beta, gamma, m): def cmsshape_integral(limits: ztyping.SpaceType, params: dict, model) -> tf.Tensor: + """Calculates the analytic integral of the CMSShape PDF. + + Args: + limits: An object with attribute limit1d. + params: A hashmap from which the parameters that defines the PDF will be extracted. + model: Will be ignored. + + Returns: + The calculated integral. + """ lower, upper = limits.limit1d beta = params["beta"] gamma = params["gamma"] @@ -54,6 +103,43 @@ def __init__( norm: Optional[ztyping.NormInputType] = None, name: str = "CMSShape", ): + """CMSShape PDF. + + The distribution consists of an exponential decay suppressed at small values by the + complementary error function. The product is an asymmetric peak with a bell shape on the + left-hand side at low mass due to threshold effect and an exponential tail on the right-hand side. + This shape is used by the CMS experiment to model the background in the invariant mass distribution + of Z to ll decay candidates. + + Formula for the PDF and CDF are based on code from + [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) + and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py) + + Args: + beta: Steepness of the error function. + gamma: Steepness of the exponential distribution. + m: Approximate center of the distribution. + obs: |@doc:pdf.init.obs| Observables of the + model. This will be used as the default space of the PDF and, + if not given explicitly, as the normalization range. + + The default space is used for example in the sample method: if no + sampling limits are given, the default space is used. + + The observables are not equal to the domain as it does not restrict or + truncate the model outside this range. |@docend:pdf.init.obs| + 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| + 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:pdf.init.name| Human-readable name + or label of + the PDF for better identification. + Has no programmatical functional purpose as identification. |@docend:pdf.init.name| + """ params = {"beta": beta, "gamma": gamma, "m": m} super().__init__(obs=obs, params=params, name=name, extended=extended, norm=norm) From 343013583f68725720c6d6d1aa9bbf0491e208eb Mon Sep 17 00:00:00 2001 From: Iason Krommydas Date: Fri, 15 Mar 2024 16:40:57 +0100 Subject: [PATCH 08/11] Update requirements_dev.txt Co-authored-by: Jonas Eschle --- requirements_dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_dev.txt b/requirements_dev.txt index 6a64811..03c364d 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -2,7 +2,7 @@ bumpversion>=0.5.3 coverage>=4.5.1 coverage>=4.5.1 flake8>=3.5.0 -numba-stats @ git+https://github.com/HDembinski/numba-stats.git +numba-stats @ git+https://github.com/HDembinski/numba-stats.git # CMSShape not yet released (expected 1.8.0) pip>=9.0.1 pre-commit pytest>=3.4.2 From 4e2e271a87016b85a70c4d2be5e8ef90dc6afac1 Mon Sep 17 00:00:00 2001 From: iasonkrom Date: Fri, 15 Mar 2024 17:00:52 +0100 Subject: [PATCH 09/11] put m parameter first --- tests/test_pdf_cmsshape.py | 15 ++++++++------- zfit_physics/models/pdf_cmsshape.py | 24 ++++++++++++------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/test_pdf_cmsshape.py b/tests/test_pdf_cmsshape.py index 9f123a7..f91d859 100644 --- a/tests/test_pdf_cmsshape.py +++ b/tests/test_pdf_cmsshape.py @@ -11,20 +11,20 @@ import zfit_physics as zphys # specify globals here. Do NOT add any TensorFlow but just pure python +m_true = 90.0 beta_true = 0.2 gamma_true = 0.3 -m_true = 90.0 -def create_cmsshape(gamma, beta, m, limits): +def create_cmsshape(m, beta, gamma, limits): obs = zfit.Space("obs1", limits) - cmsshape = zphys.pdf.CMSShape(gamma=gamma, beta=beta, m=m, obs=obs) + cmsshape = zphys.pdf.CMSShape(m=m, beta=beta, gamma=gamma, obs=obs) return cmsshape, obs def test_cmsshape_pdf(): # Test PDF here - cmsshape, _ = create_cmsshape(gamma=gamma_true, beta=beta_true, m=m_true, limits=(50, 130)) + cmsshape, _ = create_cmsshape(m=m_true, beta=beta_true, gamma=gamma_true, limits=(50, 130)) assert zfit.run(cmsshape.pdf(90.0)) == pytest.approx( cmsshape_numba.pdf(90.0, beta=beta_true, gamma=gamma_true, loc=m_true).item(), rel=1e-5 ) @@ -43,7 +43,7 @@ def test_cmsshape_pdf(): def test_cmsshape_integral(): # Test CDF and integral here - cmsshape, obs = create_cmsshape(gamma=gamma_true, beta=beta_true, m=m_true, limits=(50, 130)) + cmsshape, obs = create_cmsshape(m=m_true, beta=beta_true, gamma=gamma_true, limits=(50, 130)) full_interval_analytic = zfit.run(cmsshape.analytic_integrate(obs, norm_range=False)) full_interval_numeric = zfit.run(cmsshape.numeric_integrate(obs, norm_range=False)) true_integral = 0.99999 @@ -66,10 +66,11 @@ def test_cmsshape_integral(): # register the pdf here and provide sets of working parameter configurations def cmsshape_params_factory(): + m = zfit.Parameter("m", m_true) beta = zfit.Parameter("beta", beta_true) gamma = zfit.Parameter("gamma", gamma_true) - m = zfit.Parameter("m", m_true) - return {"beta": beta, "gamma": gamma, "m": m} + + return {"m": m, "beta": beta, "gamma": gamma} tester.register_pdf(pdf_class=zphys.pdf.CMSShape, params_factories=cmsshape_params_factory) diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index b3db5fe..58c4324 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -8,14 +8,14 @@ @z.function(wraps="tensor") -def cmsshape_pdf_func(x, beta, gamma, m): +def cmsshape_pdf_func(x, m, beta, gamma): """Calculate the CMSShape PDF. Args: x: value(s) for which the PDF will be calculated. + m: approximate center of the disribution. beta: steepness of the error function. gamma: steepness of the exponential distribution. - m: approximate center of the distribution. Returns: `tf.Tensor`: The calculated PDF values. @@ -44,14 +44,14 @@ def cmsshape_pdf_func(x, beta, gamma, m): @z.function(wraps="tensor") -def cmsshape_cdf_func(x, beta, gamma, m): +def cmsshape_cdf_func(x, m, beta, gamma): """Analtical function for the CDF of the CMSShape distribution. Args: x: value(s) for which the CDF will be calculated. + m: approximate center of the distribution. beta: steepness of the error function. gamma: steepness of the exponential distribution. - m: approximate center of the distribution. Returns: `tf.Tensor`: The calculated CDF values. @@ -81,11 +81,11 @@ def cmsshape_integral(limits: ztyping.SpaceType, params: dict, model) -> tf.Tens The calculated integral. """ lower, upper = limits.limit1d + m = params["m"] beta = params["beta"] gamma = params["gamma"] - m = params["m"] - lower_cdf = cmsshape_cdf_func(x=lower, beta=beta, gamma=gamma, m=m) - upper_cdf = cmsshape_cdf_func(x=upper, beta=beta, gamma=gamma, m=m) + lower_cdf = cmsshape_cdf_func(x=lower, m=m, beta=beta, gamma=gamma) + upper_cdf = cmsshape_cdf_func(x=upper, m=m, beta=beta, gamma=gamma) return upper_cdf - lower_cdf @@ -94,9 +94,9 @@ class CMSShape(zfit.pdf.BasePDF): def __init__( self, + m: ztyping.ParamTypeInput, beta: ztyping.ParamTypeInput, gamma: ztyping.ParamTypeInput, - m: ztyping.ParamTypeInput, obs: ztyping.ObsTypeInput, *, extended: Optional[ztyping.ExtendedInputType] = None, @@ -116,9 +116,9 @@ def __init__( and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py) Args: + m: Approximate center of the distribution. beta: Steepness of the error function. gamma: Steepness of the exponential distribution. - m: Approximate center of the distribution. obs: |@doc:pdf.init.obs| Observables of the model. This will be used as the default space of the PDF and, if not given explicitly, as the normalization range. @@ -140,14 +140,14 @@ def __init__( the PDF for better identification. Has no programmatical functional purpose as identification. |@docend:pdf.init.name| """ - params = {"beta": beta, "gamma": gamma, "m": m} + params = {"m": m, "beta": beta, "gamma": gamma} super().__init__(obs=obs, params=params, name=name, extended=extended, norm=norm) def _unnormalized_pdf(self, x: tf.Tensor) -> tf.Tensor: + m = self.params["m"] beta = self.params["beta"] gamma = self.params["gamma"] - m = self.params["m"] - return cmsshape_pdf_func(x, beta, gamma, m) + return cmsshape_pdf_func(x=x, m=m, beta=beta, gamma=gamma) cmsshape_integral_limits = Space(axes=(0,), limits=(((ANY_LOWER,),), ((ANY_UPPER,),))) From 7d3ffaf6fb6300ea890d5cd43d10e09735b005cb Mon Sep 17 00:00:00 2001 From: Jonas Eschle Date: Fri, 15 Mar 2024 14:28:37 -0400 Subject: [PATCH 10/11] remove typo --- zfit_physics/models/pdf_cmsshape.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index 58c4324..d29de7e 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -31,16 +31,6 @@ def cmsshape_pdf_func(x, m, beta, gamma): t2 = tf.math.erfc(-beta * (x - m)) t3 = half * gamma * tf.math.exp(-((half * gamma / beta) ** two)) return t1 * t2 * t3 - """Calculates the analytic integral of the relativistic Breit-Wigner PDF. - - Args: - limits: An object with attribute rect_limits. - params: A hashmap from which the parameters that defines the PDF will be extracted. - model: Will be ignored. - - Returns: - The calculated integral. - """ @z.function(wraps="tensor") From 4779dca77c3e0ca99c97b17e6f756161508a3a71 Mon Sep 17 00:00:00 2001 From: Jonas Eschle Date: Fri, 15 Mar 2024 14:39:18 -0400 Subject: [PATCH 11/11] docs: md to rst links --- zfit_physics/models/pdf_cmsshape.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zfit_physics/models/pdf_cmsshape.py b/zfit_physics/models/pdf_cmsshape.py index d29de7e..196d40e 100644 --- a/zfit_physics/models/pdf_cmsshape.py +++ b/zfit_physics/models/pdf_cmsshape.py @@ -21,8 +21,8 @@ def cmsshape_pdf_func(x, m, beta, gamma): `tf.Tensor`: The calculated PDF values. Notes: - Based on code from [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) - and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py). + Based on code from `spark_tnp `_ and + `numba-stats `_. """ x = z.unstack_x(x) half = 0.5 @@ -47,8 +47,8 @@ def cmsshape_cdf_func(x, m, beta, gamma): `tf.Tensor`: The calculated CDF values. Notes: - Based on code from [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) - and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py). + Based on code from `spark_tnp `_ and + `numba-stats `_ """ half = 0.5 two = 2.0 @@ -102,8 +102,8 @@ def __init__( of Z to ll decay candidates. Formula for the PDF and CDF are based on code from - [spark_tnp](https://gitlab.cern.ch/cms-muonPOG/spark_tnp/-/blob/Spark3/RooCMSShape.cc) - and [numba-stats](https://github.com/HDembinski/numba-stats/blob/main/src/numba_stats/cmsshape.py) + `spark_tnp `_ and + `numba-stats `_ Args: m: Approximate center of the distribution.