# Statisical Model Plugins for Spey
[](https://github.com/joes-git/strathisla/actions/workflows/tests.yml)
[](https://github.com/joes-git/strathisla/blob/main/LICENSE)
Various likelihood plugins for [Spey](https://github.com/SpeysideHEP/spey). The package is named after the [Strathisla](https://en.wikipedia.org/wiki/Strathisla_distillery), the Speyside distillery.
Available models:
- [`FullNuisanceParameters`](#fullnuisanceparameters): Poisson likelihood with nuisance parameters on the signal, background and data.
- [`SimpleMultivariateGaussianEFT`](#simplemultivariategaussianeft): Multivariate Gaussian likelihood with no nuisance parameters. Two signal inputs: the first scales linearly with the parameter of interest, the second quadratically.
- [`MultivariateGaussianCovarianceScaledEFT`](#multivariategaussiancovariancescaledeft): As above, but the signal covariance matrices are scaled by the parameter of interest
## Installation
To use these plugins with Spey:
0. (Optional) Setup a virtual environment
```
python -m venv spey_venv
source spey_venv/bin/activate
pip install spey
```
1. Clone this repo
```
git@github.com:joes-git/strathisla.git
```
2. Add this repo to your environment
```
cd strathisla
pip install -e .
```
3. Check the plugins are available in Spey
```python
import spey
installed_plugins = [
'strathisla.full_nuisance_parameters',
'strathisla.simple_multivariate_gaussian_eft',
'strathisla.multivariate_gaussian_scaled_covariance_eft'
]
print(all(plugin in spey.AvailableBackends() for plugin in installed_plugins))
# True
```
## `FullNuisanceParameters`
From equation 8 of [arXiv:2102.04377](https://arxiv.org/pdf/2102.04377.pdf), this is the likelihood for a histogram with $i$ bins and covariance matrices ($\Sigma$) for the signal ($s$), background ($b$) and data ($n$) yields. This likelihood has the following form:
$$
L(\mu, \theta) =
\prod_{i \in {\rm bins}}
{\rm Poiss}
(n_i \vert \mu s_i+b_i + \sum_{j \in n,s,b} \theta_i^{(j)} \sigma_i^{(j)})
\prod_{j \in n,s,b}
{\rm Gauss}(\theta^{(j)}|0,\Sigma^{(j)})
$$
where $\mu$ is the parameter of interest, and $\theta$ are nuisance parameters.
### Example
```python
import spey
import numpy as np
data = np.array([30, 35, 40])
signal_yields = np.array([8.0, 10.0, 12.0])
background_yields = np.array([25.0, 28.0, 32.0])
signal_covariance = np.array([[1.0, 0.2, 0.1],
[0.2, 1.5, 0.3],
[0.1, 0.3, 2.0]])
background_covariance = np.array([[16.0, 4.0, 2.0],
[4.0, 25.0, 5.0],
[2.0, 5.0, 36.0]])
data_covariance = np.array([[30.0,2.0,0.5],
[4.3, 35.0, 9.0],
[6.2, 13.0, 40.0]])
backend = spey.get_backend("strathisla.full_nuisance_parameters")
stat_model = backend(
signal_yields=signal_yields,
background_yields=background_yields,
data=data,
signal_covariance=signal_covariance,
background_covariance=background_covariance,
data_covariance=data_covariance
)
CLs = stat_model.exclusion_confidence_level()[0]
print(CLs)
```
## `SimpleMultivariateGaussianEFT`
Simple multivariate Gaussian likelihood (no nuisance parameters) for a histogram with $i$ correlated bins and two signal contributions: A term $s_{\text{lin}}$ with scales linearly with the signal strength $\mu$, and a term $s_{\text{quad}}$, which scales with $\mu^2$. The form of this likelihood is:
$$
L(\mu) =
\frac{1}{\sqrt{(2\pi)^k \det(\Sigma)}}
\exp \left( -\frac{1}{2} (\mu^2 s_{\text{quad}} + \mu s_{\text{lin}} + b - n)^{\text{T}} \Sigma^{-1} (\mu^2 s_{\text{quad}} + \mu s_{\text{lin}} + b - n) \right),
$$
where $\Sigma$ is the covariance matrix, $b$ is the background and $n$ is the data.
### Example
```python
import spey
import numpy as np
quadratic_term = np.array([9.908565e-04, 1.082060e-02, 4.402903e-02])
linear_term = np.array([0.00045349, 0.00304028, 0.0090483])
background = np.array([0.25291, 0.59942, 1.52996])
data = np.array([0.2325, 0.5385, 1.25734])
covariance = np.array([
[0.06427483, 0.05824, 0.01225],
[0.05824, 0.06694904, 0.01207],
[0.01225, 0.01207, 0.02126036]])
backend = spey.get_backend("strathisla.simple_multivariate_gaussian_eft")
stat_model = backend(
quadratic_term=quadratic_term,
linear_term=linear_term,
background=background,
data=data,
covariance=covariance
)
CLs = stat_model.exclusion_confidence_level()
print(CLs[0])
```
## `MultivariateGaussianCovarianceScaledEFT`
The multivariante Gaussian likelihood above, but the signal contributions to the covariance matrix are scaled by the parameter of interest as:
$$
\Sigma(\mu) = \mu^4 \Sigma_{\text{quad}} + \mu^2 \Sigma_{\text{lin}} + \Sigma_b + \Sigma_n
$$
### Example
```python
import spey
import numpy as np
quadratic_term = np.array([9.908565e-04, 1.082060e-02, 4.402903e-02])
linear_term = np.array([0.00045349, 0.00304028, 0.0090483])
background = np.array([0.25291, 0.59942, 1.52996])
data = np.array([0.2325, 0.5385, 1.25734])
covariance = np.array([
[0.06427483, 0.05824, 0.01225],
[0.05824, 0.06694904, 0.01207],
[0.01225, 0.01207, 0.02126036]])
background_covariance = np.zeros_like(covariance) # assume 'covariance' has both data and background
quadratic_term_covariance = np.diag([1.42421005e-07, 8.57147040e-07, 1.99661509e-06])
linear_term_covariance = np.diag([3.60939969e-08, 4.65573038e-07, 9.61593099e-07])
backend = spey.get_backend("strathisla.multivariate_gaussian_scaled_covariance_eft")
stat_model = backend(
quadratic_term=quadratic_term,
linear_term=linear_term,
background=background,
data=data,
data_covariance=covariance,
background_covariance=background_covariance,
quadratic_term_covariance=quadratic_term_covariance,
linear_term_covariance=linear_term_covariance
)
CLs = stat_model.exclusion_confidence_level()
print(CLs[0])
```
Raw data
{
"_id": null,
"home_page": null,
"name": "strathisla",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "high energy physics, statistics, particle physics, spey, likelihood, EFT, fitting, re-interpretation, BSM",
"author": null,
"author_email": "Joe Egan <joseph.caimin.egan@cern.ch>",
"download_url": "https://files.pythonhosted.org/packages/89/c5/039f6507d5a42d415495de3847100ff4a2c281063b690cc65a3fbed5baf8/strathisla-1.0.0.tar.gz",
"platform": null,
"description": "# Statisical Model Plugins for Spey\n\n[](https://github.com/joes-git/strathisla/actions/workflows/tests.yml)\n[](https://github.com/joes-git/strathisla/blob/main/LICENSE)\n\nVarious likelihood plugins for [Spey](https://github.com/SpeysideHEP/spey). The package is named after the [Strathisla](https://en.wikipedia.org/wiki/Strathisla_distillery), the Speyside distillery.\n\nAvailable models:\n\n- [`FullNuisanceParameters`](#fullnuisanceparameters): Poisson likelihood with nuisance parameters on the signal, background and data.\n- [`SimpleMultivariateGaussianEFT`](#simplemultivariategaussianeft): Multivariate Gaussian likelihood with no nuisance parameters. Two signal inputs: the first scales linearly with the parameter of interest, the second quadratically.\n- [`MultivariateGaussianCovarianceScaledEFT`](#multivariategaussiancovariancescaledeft): As above, but the signal covariance matrices are scaled by the parameter of interest\n\n## Installation\n\nTo use these plugins with Spey:\n\n0. (Optional) Setup a virtual environment\n```\npython -m venv spey_venv\nsource spey_venv/bin/activate\npip install spey\n```\n\n1. Clone this repo\n```\ngit@github.com:joes-git/strathisla.git\n```\n\n2. Add this repo to your environment\n```\ncd strathisla\npip install -e .\n```\n\n3. Check the plugins are available in Spey\n```python\nimport spey\ninstalled_plugins = [\n 'strathisla.full_nuisance_parameters',\n 'strathisla.simple_multivariate_gaussian_eft',\n 'strathisla.multivariate_gaussian_scaled_covariance_eft'\n\n]\n\nprint(all(plugin in spey.AvailableBackends() for plugin in installed_plugins))\n# True\n```\n \n## `FullNuisanceParameters` \n\nFrom equation 8 of [arXiv:2102.04377](https://arxiv.org/pdf/2102.04377.pdf), this is the likelihood for a histogram with $i$ bins and covariance matrices ($\\Sigma$) for the signal ($s$), background ($b$) and data ($n$) yields. This likelihood has the following form:\n\n$$\nL(\\mu, \\theta) = \n\\prod_{i \\in {\\rm bins}} \n{\\rm Poiss}\n(n_i \\vert \\mu s_i+b_i + \\sum_{j \\in n,s,b} \\theta_i^{(j)} \\sigma_i^{(j)})\n\\prod_{j \\in n,s,b} \n{\\rm Gauss}(\\theta^{(j)}|0,\\Sigma^{(j)})\n$$\n\nwhere $\\mu$ is the parameter of interest, and $\\theta$ are nuisance parameters.\n\n### Example\n```python\nimport spey\nimport numpy as np\n\ndata = np.array([30, 35, 40])\nsignal_yields = np.array([8.0, 10.0, 12.0])\nbackground_yields = np.array([25.0, 28.0, 32.0])\n \nsignal_covariance = np.array([[1.0, 0.2, 0.1], \n [0.2, 1.5, 0.3], \n [0.1, 0.3, 2.0]])\n \nbackground_covariance = np.array([[16.0, 4.0, 2.0],\n [4.0, 25.0, 5.0],\n [2.0, 5.0, 36.0]])\n \ndata_covariance = np.array([[30.0,2.0,0.5],\n [4.3, 35.0, 9.0],\n [6.2, 13.0, 40.0]])\n\nbackend = spey.get_backend(\"strathisla.full_nuisance_parameters\")\n\nstat_model = backend(\n signal_yields=signal_yields,\n background_yields=background_yields,\n data=data,\n signal_covariance=signal_covariance,\n background_covariance=background_covariance,\n data_covariance=data_covariance\n)\n\nCLs = stat_model.exclusion_confidence_level()[0]\nprint(CLs)\n```\n\n## `SimpleMultivariateGaussianEFT`\n\nSimple multivariate Gaussian likelihood (no nuisance parameters) for a histogram with $i$ correlated bins and two signal contributions: A term $s_{\\text{lin}}$ with scales linearly with the signal strength $\\mu$, and a term $s_{\\text{quad}}$, which scales with $\\mu^2$. The form of this likelihood is:\n\n$$\nL(\\mu) = \n\\frac{1}{\\sqrt{(2\\pi)^k \\det(\\Sigma)}}\n\\exp \\left( -\\frac{1}{2} (\\mu^2 s_{\\text{quad}} + \\mu s_{\\text{lin}} + b - n)^{\\text{T}} \\Sigma^{-1} (\\mu^2 s_{\\text{quad}} + \\mu s_{\\text{lin}} + b - n) \\right),\n$$\n\nwhere $\\Sigma$ is the covariance matrix, $b$ is the background and $n$ is the data.\n\n### Example\n```python\nimport spey\nimport numpy as np\n\nquadratic_term = np.array([9.908565e-04, 1.082060e-02, 4.402903e-02])\nlinear_term = np.array([0.00045349, 0.00304028, 0.0090483])\nbackground = np.array([0.25291, 0.59942, 1.52996])\ndata = np.array([0.2325, 0.5385, 1.25734])\n\ncovariance = np.array([\n [0.06427483, 0.05824, 0.01225],\n [0.05824, 0.06694904, 0.01207],\n [0.01225, 0.01207, 0.02126036]])\n\nbackend = spey.get_backend(\"strathisla.simple_multivariate_gaussian_eft\")\n\nstat_model = backend(\n quadratic_term=quadratic_term,\n linear_term=linear_term,\n background=background,\n data=data,\n covariance=covariance\n)\n \nCLs = stat_model.exclusion_confidence_level()\n\nprint(CLs[0])\n```\n\n## `MultivariateGaussianCovarianceScaledEFT`\n\nThe multivariante Gaussian likelihood above, but the signal contributions to the covariance matrix are scaled by the parameter of interest as:\n\n$$\n\\Sigma(\\mu) = \\mu^4 \\Sigma_{\\text{quad}} + \\mu^2 \\Sigma_{\\text{lin}} + \\Sigma_b + \\Sigma_n\n$$\n\n### Example\n```python\nimport spey\nimport numpy as np\n\nquadratic_term = np.array([9.908565e-04, 1.082060e-02, 4.402903e-02])\nlinear_term = np.array([0.00045349, 0.00304028, 0.0090483])\nbackground = np.array([0.25291, 0.59942, 1.52996])\ndata = np.array([0.2325, 0.5385, 1.25734])\n\ncovariance = np.array([\n [0.06427483, 0.05824, 0.01225],\n [0.05824, 0.06694904, 0.01207],\n [0.01225, 0.01207, 0.02126036]])\n\nbackground_covariance = np.zeros_like(covariance) # assume 'covariance' has both data and background\n\nquadratic_term_covariance = np.diag([1.42421005e-07, 8.57147040e-07, 1.99661509e-06])\nlinear_term_covariance = np.diag([3.60939969e-08, 4.65573038e-07, 9.61593099e-07])\n\nbackend = spey.get_backend(\"strathisla.multivariate_gaussian_scaled_covariance_eft\")\n\nstat_model = backend(\n quadratic_term=quadratic_term,\n linear_term=linear_term,\n background=background,\n data=data,\n data_covariance=covariance,\n background_covariance=background_covariance,\n quadratic_term_covariance=quadratic_term_covariance,\n linear_term_covariance=linear_term_covariance\n)\n \nCLs = stat_model.exclusion_confidence_level()\n\nprint(CLs[0])\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "Likelihood plugins for the Spey package",
"version": "1.0.0",
"project_urls": {
"Bug Reports": "https://github.com/joes-git/strathisla/issues",
"Homepage": "https://github.com/joes-git/strathisla",
"Source": "https://github.com/joes-git/strathisla"
},
"split_keywords": [
"high energy physics",
" statistics",
" particle physics",
" spey",
" likelihood",
" eft",
" fitting",
" re-interpretation",
" bsm"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c00199a88af83b97dda010d1a5039a46fec5f91a3c8b5c61838a0ec27a1febc0",
"md5": "38b4f74f2c41e651fda84340df2133ad",
"sha256": "b588f135f94aa1eb4ad49da83b20fed42e696ed44ea45a24988582cf6d4a3ad9"
},
"downloads": -1,
"filename": "strathisla-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "38b4f74f2c41e651fda84340df2133ad",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 13718,
"upload_time": "2025-08-01T15:42:35",
"upload_time_iso_8601": "2025-08-01T15:42:35.824753Z",
"url": "https://files.pythonhosted.org/packages/c0/01/99a88af83b97dda010d1a5039a46fec5f91a3c8b5c61838a0ec27a1febc0/strathisla-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "89c5039f6507d5a42d415495de3847100ff4a2c281063b690cc65a3fbed5baf8",
"md5": "e5cabe3f7c3b44d497a669557dbf55b2",
"sha256": "d6c14755ff9b08c9330d7455ee6f1da967ceb5087e918077d7649f9e8cf21559"
},
"downloads": -1,
"filename": "strathisla-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "e5cabe3f7c3b44d497a669557dbf55b2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 15796,
"upload_time": "2025-08-01T15:42:37",
"upload_time_iso_8601": "2025-08-01T15:42:37.153203Z",
"url": "https://files.pythonhosted.org/packages/89/c5/039f6507d5a42d415495de3847100ff4a2c281063b690cc65a3fbed5baf8/strathisla-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-01 15:42:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "joes-git",
"github_project": "strathisla",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "strathisla"
}