<jupyter_start><jupyter_text>HistFactory<jupyter_code>%%html
<p align="center">
<iframe src="https://matthewfeickert.github.io/talk-SciPy-2020/index.html#2" width="1200" height="675"></iframe>
</p>
%%html
<p align="center">
<iframe src="https://matthewfeickert.github.io/talk-SciPy-2020/index.html#6" width="1200" height="675"></iframe>
</p>
%%html
<p align="center">
<iframe src="https://matthewfeickert.github.io/talk-SciPy-2020/index.html#7" width="1200" height="675"></iframe>
</p>
%%html
<p align="center">
<iframe src="https://matthewfeickert.github.io/talk-SciPy-2020/index.html#13" width="1200" height="675"></iframe>
</p><jupyter_output><empty_output><jupyter_text>JSON Spec Let's investiage this spec a bit more now ```json{    "channels": [        { "name": "singlechannel",          "samples": [            { "name": "signal",              "data": [5.0, 10.0],              "modifiers": [ { "name": "mu", "type": "normfactor", "data": null} ]            },            { "name": "background",              "data": [50.0, 60.0],              "modifiers": [ {"name": "uncorr_bkguncrt", "type": "shapesys", "data": [5.0, 12.0]} ]            }          ]        }    ],    "observations": [        { "name": "singlechannel", "data": [50.0, 60.0] }    ],    "measurements": [        { "name": "Measurement", "config": {"poi": "mu", "parameters": []} }    ],    "version": "1.0.0"}``` > which demonstrates a simple measurement of a single two-bin channel with two samples: a **signal sample** and a **background sample**. The signal sample has an _unconstrained normalisation factor_ $\mu$, while the background sample carries an _uncorrelated shape systematic_ controlled by parameters $\gamma_{1}$ and $\gamma_{2}$. The _background uncertainty_ for the bins is $10\%$ and $20\%$ respectively.<jupyter_code>import pyhf
import json<jupyter_output><empty_output><jupyter_text>Let's open up the spec and then load it into a workspace<jupyter_code>with open("data/2-bin_1-channel.json") as serialized:
  spec = json.load(serialized)

workspace = pyhf.Workspace(spec)<jupyter_output><empty_output><jupyter_text>and then create a statistical model from it<jupyter_code>model = workspace.model(measurement_name="Measurement")
# Take a quick look at the model spec
model.spec<jupyter_output><empty_output><jupyter_text>Let's clean that up a bit to make it more readable<jupyter_code>def pretty_json(jsonlike, indent=None):
    if indent is None: indent = 4
    print(json.dumps(jsonlike, indent=indent))
pretty_json(model.spec)<jupyter_output><empty_output><jupyter_text>and now actually break that down again.  Single Channel > demonstrates a simple measurement of a single two-bin channel<jupyter_code>print(f"Channels in model: {model.config.channels}\n")

single_channel = model.spec["channels"][0]

print(f"Number of bins in channel: {model.config.channel_nbins}\n")
single_channel<jupyter_output><empty_output><jupyter_text>Samples > with two samples<jupyter_code>model.config.samples
pretty_json(single_channel["samples"])<jupyter_output><empty_output><jupyter_text>Modifiers<jupyter_code>model.config.modifiers<jupyter_output><empty_output><jupyter_text>> The signal sample has an unconstrained normalisation factor $\mu$<jupyter_code>signal_sample = single_channel["samples"][0]
pretty_json(signal_sample["modifiers"])<jupyter_output><empty_output><jupyter_text>> the background sample carries an uncorrelated shape systematic controlled by parameters $\gamma_{1}$ and $\gamma_{2}$<jupyter_code># Each bin has its own shape systematic
background_sample = single_channel["samples"][1]
pretty_json(background_sample["modifiers"])<jupyter_output><empty_output><jupyter_text>> The background uncertainty for the bins is $10\%$ and $20\%$ respectively.<jupyter_code>import numpy as np

bkg_uncert = background_sample["modifiers"][0]["data"]
np.array(bkg_uncert)/np.array(background_sample["data"])
import requests

remote_url = "https://raw.githubusercontent.com/scikit-hep/pyhf/0f99cc488156e0826a27f55abc946d537a8922af/docs/examples/json/2-bin_1-channel.json"
response = json.loads(requests.get(remote_url).text)

pretty_json(response)<jupyter_output><empty_output><jupyter_text>Observations The data assocaited with a workspace<jupyter_code>workspace.data(model)<jupyter_output><empty_output><jupyter_text>contains both observations<jupyter_code>workspace.data(model, with_aux=False)<jupyter_output><empty_output><jupyter_text>as well as axuiliary information<jupyter_code>model.config.auxdata<jupyter_output><empty_output><jupyter_text>Measurements The parameter(s) of interest (POI) you're trying to measure<jupyter_code>pretty_json(workspace.get_measurement())<jupyter_output><empty_output><jupyter_text>Inspecting workspaces We can also use the `pyhf` command line tool to help us verify and inspect the workspace<jupyter_code>! pyhf inspect data/2-bin_1-channel.json<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1414882772680938, 'fraction_numerical': 0.02528032619775739, 'mean_word_length': 6.268148148148148, 'pattern_counts': {'":': 24, '<': 81, '<?xml version=': 0, '>': 87, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '244674', 'license': 'MIT', 'n_tokens_mistral': 1715, 'n_tokens_neox': 1609, 'n_words': 335, 'path': 'book/HistFactory.ipynb', 'repo_name': 'pyhf/tutorial-PyHEP-2020', 'size': '4905'}