We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
staterror regressions blocking v0.7.0
Before `v0.7.0rc2` can go out and then `v0.7.0` we have to fix the regressions in `staterror`. This Issue is just to keep track of them and help us squash them all.

* [ ] Issue #1720
* [x] Issue #1944

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyhf/modifiers/staterror.py`
Content:
```
1 import logging
2 from typing import List
3 
4 import pyhf
5 from pyhf import events
6 from pyhf.exceptions import InvalidModifier
7 from pyhf.parameters import ParamViewer
8 from pyhf.tensor.manager import get_backend
9 
10 log = logging.getLogger(__name__)
11 
12 
13 def required_parset(sigmas, fixed: List[bool]):
14     n_parameters = len(sigmas)
15     return {
16         'paramset_type': 'constrained_by_normal',
17         'n_parameters': n_parameters,
18         'is_shared': True,
19         'is_scalar': False,
20         'inits': (1.0,) * n_parameters,
21         'bounds': ((1e-10, 10.0),) * n_parameters,
22         'fixed': tuple(fixed),
23         'auxdata': (1.0,) * n_parameters,
24         'sigmas': tuple(sigmas),
25     }
26 
27 
28 class staterror_builder:
29     """Builder class for collecting staterror modifier data"""
30 
31     def __init__(self, config):
32         self.builder_data = {}
33         self.config = config
34         self.required_parsets = {}
35 
36     def collect(self, thismod, nom):
37         uncrt = thismod['data'] if thismod else [0.0] * len(nom)
38         mask = [True if thismod else False] * len(nom)
39         return {'mask': mask, 'nom_data': nom, 'uncrt': uncrt}
40 
41     def append(self, key, channel, sample, thismod, defined_samp):
42         self.builder_data.setdefault(key, {}).setdefault(sample, {}).setdefault(
43             'data', {'uncrt': [], 'nom_data': [], 'mask': []}
44         )
45         nom = (
46             defined_samp['data']
47             if defined_samp
48             else [0.0] * self.config.channel_nbins[channel]
49         )
50         moddata = self.collect(thismod, nom)
51         self.builder_data[key][sample]['data']['mask'].append(moddata['mask'])
52         self.builder_data[key][sample]['data']['uncrt'].append(moddata['uncrt'])
53         self.builder_data[key][sample]['data']['nom_data'].append(moddata['nom_data'])
54 
55     def finalize(self):
56         default_backend = pyhf.default_backend
57 
58         for modifier_name, modifier in self.builder_data.items():
59             for sample_name, sample in modifier.items():
60                 sample["data"]["mask"] = default_backend.concatenate(
61                     sample["data"]["mask"]
62                 )
63                 sample["data"]["uncrt"] = default_backend.concatenate(
64                     sample["data"]["uncrt"]
65                 )
66                 sample["data"]["nom_data"] = default_backend.concatenate(
67                     sample["data"]["nom_data"]
68                 )
69                 if len(sample["data"]["nom_data"]) != len(sample["data"]["uncrt"]):
70                     _modifier_type, _modifier_name = modifier_name.split("/")
71                     _sample_data_len = len(sample["data"]["nom_data"])
72                     _uncrt_len = len(sample["data"]["uncrt"])
73                     raise InvalidModifier(
74                         f"The '{sample_name}' sample {_modifier_type} modifier"
75                         + f" '{_modifier_name}' has data shape inconsistent with the sample.\n"
76                         + f"{sample_name} has 'data' of length {_sample_data_len} but {_modifier_name}"
77                         + f" has 'data' of length {_uncrt_len}."
78                     )
79 
80         for modname in self.builder_data.keys():
81             parname = modname.split('/')[1]
82 
83             nomsall = default_backend.sum(
84                 [
85                     modifier_data['data']['nom_data']
86                     for modifier_data in self.builder_data[modname].values()
87                     if default_backend.astensor(modifier_data['data']['mask']).any()
88                 ],
89                 axis=0,
90             )
91             relerrs = default_backend.sum(
92                 [
93                     [
94                         (modifier_data['data']['uncrt'][binnr] / nomsall[binnr]) ** 2
95                         if nomsall[binnr] > 0
96                         else 0.0
97                         for binnr in range(len(modifier_data['data']['nom_data']))
98                     ]
99                     for modifier_data in self.builder_data[modname].values()
100                 ],
101                 axis=0,
102             )
103             relerrs = default_backend.sqrt(relerrs)
104 
105             masks = {}
106             for modifier_data in self.builder_data[modname].values():
107                 mask_this_sample = default_backend.astensor(
108                     modifier_data['data']['mask'], dtype='bool'
109                 )
110                 if mask_this_sample.any():
111                     if modname not in masks:
112                         masks[modname] = mask_this_sample
113                     else:
114                         assert (mask_this_sample == masks[modname]).all()
115 
116             for modifier_data in self.builder_data[modname].values():
117                 modifier_data['data']['mask'] = masks[modname]
118             sigmas = relerrs[masks[modname]]
119             # list of bools, consistent with other modifiers (no numpy.bool_)
120             fixed = default_backend.tolist(sigmas == 0)
121             # ensures non-Nan constraint term, but in a future PR we need to remove constraints for these
122             sigmas[fixed] = 1.0
123             self.required_parsets.setdefault(parname, [required_parset(sigmas, fixed)])
124         return self.builder_data
125 
126 
127 class staterror_combined:
128     name = 'staterror'
129     op_code = 'multiplication'
130 
131     def __init__(self, modifiers, pdfconfig, builder_data, batch_size=None):
132 
133         default_backend = pyhf.default_backend
134         self.batch_size = batch_size
135 
136         keys = [f'{mtype}/{m}' for m, mtype in modifiers]
137         self._staterr_mods = [m for m, _ in modifiers]
138 
139         parfield_shape = (self.batch_size or 1, pdfconfig.npars)
140         self.param_viewer = ParamViewer(
141             parfield_shape, pdfconfig.par_map, self._staterr_mods
142         )
143 
144         self._staterror_mask = [
145             [[builder_data[m][s]['data']['mask']] for s in pdfconfig.samples]
146             for m in keys
147         ]
148         self.__staterror_uncrt = default_backend.astensor(
149             [
150                 [
151                     [
152                         builder_data[m][s]['data']['uncrt'],
153                         builder_data[m][s]['data']['nom_data'],
154                     ]
155                     for s in pdfconfig.samples
156                 ]
157                 for m in keys
158             ]
159         )
160         global_concatenated_bin_indices = [
161             [[j for c in pdfconfig.channels for j in range(pdfconfig.channel_nbins[c])]]
162         ]
163 
164         self._access_field = default_backend.tile(
165             global_concatenated_bin_indices,
166             (len(self._staterr_mods), self.batch_size or 1, 1),
167         )
168 
169         self._reindex_access_field(pdfconfig)
170 
171         self._precompute()
172         events.subscribe('tensorlib_changed')(self._precompute)
173 
174     def _reindex_access_field(self, pdfconfig):
175         default_backend = pyhf.default_backend
176         for syst_index, syst_access in enumerate(self._access_field):
177             singular_sample_index = [
178                 idx
179                 for idx, syst in enumerate(
180                     default_backend.astensor(self._staterror_mask)[syst_index, :, 0]
181                 )
182                 if any(syst)
183             ][-1]
184 
185             for batch_index, batch_access in enumerate(syst_access):
186                 selection = self.param_viewer.index_selection[syst_index][batch_index]
187                 access_field_for_syst_and_batch = default_backend.zeros(
188                     len(batch_access)
189                 )
190 
191                 sample_mask = self._staterror_mask[syst_index][singular_sample_index][0]
192                 access_field_for_syst_and_batch[sample_mask] = selection
193                 self._access_field[
194                     syst_index, batch_index
195                 ] = access_field_for_syst_and_batch
196 
197     def _precompute(self):
198         if not self.param_viewer.index_selection:
199             return
200         tensorlib, _ = get_backend()
201         self.staterror_mask = tensorlib.astensor(self._staterror_mask, dtype="bool")
202         self.staterror_mask = tensorlib.tile(
203             self.staterror_mask, (1, 1, self.batch_size or 1, 1)
204         )
205         self.access_field = tensorlib.astensor(self._access_field, dtype='int')
206         self.sample_ones = tensorlib.ones(tensorlib.shape(self.staterror_mask)[1])
207         self.staterror_default = tensorlib.ones(tensorlib.shape(self.staterror_mask))
208 
209     def apply(self, pars):
210         if not self.param_viewer.index_selection:
211             return
212 
213         tensorlib, _ = get_backend()
214         if self.batch_size is None:
215             flat_pars = pars
216         else:
217             flat_pars = tensorlib.reshape(pars, (-1,))
218         statfactors = tensorlib.gather(flat_pars, self.access_field)
219         results_staterr = tensorlib.einsum('mab,s->msab', statfactors, self.sample_ones)
220         results_staterr = tensorlib.where(
221             self.staterror_mask, results_staterr, self.staterror_default
222         )
223         return results_staterr
224
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/pyhf/modifiers/staterror.py b/src/pyhf/modifiers/staterror.py
--- a/src/pyhf/modifiers/staterror.py
+++ b/src/pyhf/modifiers/staterror.py
@@ -100,8 +100,12 @@
                 ],
                 axis=0,
             )
+            # here relerrs still has all the bins, while the staterror are usually per-channel
+            # so we need to pick out the masks for this modifier to extract the
+            # modifier configuration (sigmas, etc..)
+            # so loop over samples and extract the first mask
+            # while making sure any subsequent mask is consistent
             relerrs = default_backend.sqrt(relerrs)
-
             masks = {}
             for modifier_data in self.builder_data[modname].values():
                 mask_this_sample = default_backend.astensor(
@@ -113,12 +117,14 @@
                     else:
                         assert (mask_this_sample == masks[modname]).all()
 
-            for modifier_data in self.builder_data[modname].values():
-                modifier_data['data']['mask'] = masks[modname]
+            # extract sigmas using this modifiers mask
             sigmas = relerrs[masks[modname]]
+
             # list of bools, consistent with other modifiers (no numpy.bool_)
             fixed = default_backend.tolist(sigmas == 0)
-            # ensures non-Nan constraint term, but in a future PR we need to remove constraints for these
+            # FIXME: sigmas that are zero will be fixed to 1.0 arbitrarily to ensure
+            # non-Nan constraint term, but in a future PR need to remove constraints
+            # for these
             sigmas[fixed] = 1.0
             self.required_parsets.setdefault(parname, [required_parset(sigmas, fixed)])
         return self.builder_data
@@ -145,18 +151,6 @@
             [[builder_data[m][s]['data']['mask']] for s in pdfconfig.samples]
             for m in keys
         ]
-        self.__staterror_uncrt = default_backend.astensor(
-            [
-                [
-                    [
-                        builder_data[m][s]['data']['uncrt'],
-                        builder_data[m][s]['data']['nom_data'],
-                    ]
-                    for s in pdfconfig.samples
-                ]
-                for m in keys
-            ]
-        )
         global_concatenated_bin_indices = [
             [[j for c in pdfconfig.channels for j in range(pdfconfig.channel_nbins[c])]]
         ]

{"golden_diff": "diff --git a/src/pyhf/modifiers/staterror.py b/src/pyhf/modifiers/staterror.py\n--- a/src/pyhf/modifiers/staterror.py\n+++ b/src/pyhf/modifiers/staterror.py\n@@ -100,8 +100,12 @@\n                 ],\n                 axis=0,\n             )\n+            # here relerrs still has all the bins, while the staterror are usually per-channel\n+            # so we need to pick out the masks for this modifier to extract the\n+            # modifier configuration (sigmas, etc..)\n+            # so loop over samples and extract the first mask\n+            # while making sure any subsequent mask is consistent\n             relerrs = default_backend.sqrt(relerrs)\n-\n             masks = {}\n             for modifier_data in self.builder_data[modname].values():\n                 mask_this_sample = default_backend.astensor(\n@@ -113,12 +117,14 @@\n                     else:\n                         assert (mask_this_sample == masks[modname]).all()\n \n-            for modifier_data in self.builder_data[modname].values():\n-                modifier_data['data']['mask'] = masks[modname]\n+            # extract sigmas using this modifiers mask\n             sigmas = relerrs[masks[modname]]\n+\n             # list of bools, consistent with other modifiers (no numpy.bool_)\n             fixed = default_backend.tolist(sigmas == 0)\n-            # ensures non-Nan constraint term, but in a future PR we need to remove constraints for these\n+            # FIXME: sigmas that are zero will be fixed to 1.0 arbitrarily to ensure\n+            # non-Nan constraint term, but in a future PR need to remove constraints\n+            # for these\n             sigmas[fixed] = 1.0\n             self.required_parsets.setdefault(parname, [required_parset(sigmas, fixed)])\n         return self.builder_data\n@@ -145,18 +151,6 @@\n             [[builder_data[m][s]['data']['mask']] for s in pdfconfig.samples]\n             for m in keys\n         ]\n-        self.__staterror_uncrt = default_backend.astensor(\n-            [\n-                [\n-                    [\n-                        builder_data[m][s]['data']['uncrt'],\n-                        builder_data[m][s]['data']['nom_data'],\n-                    ]\n-                    for s in pdfconfig.samples\n-                ]\n-                for m in keys\n-            ]\n-        )\n         global_concatenated_bin_indices = [\n             [[j for c in pdfconfig.channels for j in range(pdfconfig.channel_nbins[c])]]\n         ]\n", "issue": "staterror regressions blocking v0.7.0\nBefore `v0.7.0rc2` can go out and then `v0.7.0` we have to fix the regressions in `staterror`. This Issue is just to keep track of them and help us squash them all.\r\n\r\n* [ ] Issue #1720\r\n* [x] Issue #1944\n", "before_files": [{"content": "import logging\nfrom typing import List\n\nimport pyhf\nfrom pyhf import events\nfrom pyhf.exceptions import InvalidModifier\nfrom pyhf.parameters import ParamViewer\nfrom pyhf.tensor.manager import get_backend\n\nlog = logging.getLogger(__name__)\n\n\ndef required_parset(sigmas, fixed: List[bool]):\n    n_parameters = len(sigmas)\n    return {\n        'paramset_type': 'constrained_by_normal',\n        'n_parameters': n_parameters,\n        'is_shared': True,\n        'is_scalar': False,\n        'inits': (1.0,) * n_parameters,\n        'bounds': ((1e-10, 10.0),) * n_parameters,\n        'fixed': tuple(fixed),\n        'auxdata': (1.0,) * n_parameters,\n        'sigmas': tuple(sigmas),\n    }\n\n\nclass staterror_builder:\n    \"\"\"Builder class for collecting staterror modifier data\"\"\"\n\n    def __init__(self, config):\n        self.builder_data = {}\n        self.config = config\n        self.required_parsets = {}\n\n    def collect(self, thismod, nom):\n        uncrt = thismod['data'] if thismod else [0.0] * len(nom)\n        mask = [True if thismod else False] * len(nom)\n        return {'mask': mask, 'nom_data': nom, 'uncrt': uncrt}\n\n    def append(self, key, channel, sample, thismod, defined_samp):\n        self.builder_data.setdefault(key, {}).setdefault(sample, {}).setdefault(\n            'data', {'uncrt': [], 'nom_data': [], 'mask': []}\n        )\n        nom = (\n            defined_samp['data']\n            if defined_samp\n            else [0.0] * self.config.channel_nbins[channel]\n        )\n        moddata = self.collect(thismod, nom)\n        self.builder_data[key][sample]['data']['mask'].append(moddata['mask'])\n        self.builder_data[key][sample]['data']['uncrt'].append(moddata['uncrt'])\n        self.builder_data[key][sample]['data']['nom_data'].append(moddata['nom_data'])\n\n    def finalize(self):\n        default_backend = pyhf.default_backend\n\n        for modifier_name, modifier in self.builder_data.items():\n            for sample_name, sample in modifier.items():\n                sample[\"data\"][\"mask\"] = default_backend.concatenate(\n                    sample[\"data\"][\"mask\"]\n                )\n                sample[\"data\"][\"uncrt\"] = default_backend.concatenate(\n                    sample[\"data\"][\"uncrt\"]\n                )\n                sample[\"data\"][\"nom_data\"] = default_backend.concatenate(\n                    sample[\"data\"][\"nom_data\"]\n                )\n                if len(sample[\"data\"][\"nom_data\"]) != len(sample[\"data\"][\"uncrt\"]):\n                    _modifier_type, _modifier_name = modifier_name.split(\"/\")\n                    _sample_data_len = len(sample[\"data\"][\"nom_data\"])\n                    _uncrt_len = len(sample[\"data\"][\"uncrt\"])\n                    raise InvalidModifier(\n                        f\"The '{sample_name}' sample {_modifier_type} modifier\"\n                        + f\" '{_modifier_name}' has data shape inconsistent with the sample.\\n\"\n                        + f\"{sample_name} has 'data' of length {_sample_data_len} but {_modifier_name}\"\n                        + f\" has 'data' of length {_uncrt_len}.\"\n                    )\n\n        for modname in self.builder_data.keys():\n            parname = modname.split('/')[1]\n\n            nomsall = default_backend.sum(\n                [\n                    modifier_data['data']['nom_data']\n                    for modifier_data in self.builder_data[modname].values()\n                    if default_backend.astensor(modifier_data['data']['mask']).any()\n                ],\n                axis=0,\n            )\n            relerrs = default_backend.sum(\n                [\n                    [\n                        (modifier_data['data']['uncrt'][binnr] / nomsall[binnr]) ** 2\n                        if nomsall[binnr] > 0\n                        else 0.0\n                        for binnr in range(len(modifier_data['data']['nom_data']))\n                    ]\n                    for modifier_data in self.builder_data[modname].values()\n                ],\n                axis=0,\n            )\n            relerrs = default_backend.sqrt(relerrs)\n\n            masks = {}\n            for modifier_data in self.builder_data[modname].values():\n                mask_this_sample = default_backend.astensor(\n                    modifier_data['data']['mask'], dtype='bool'\n                )\n                if mask_this_sample.any():\n                    if modname not in masks:\n                        masks[modname] = mask_this_sample\n                    else:\n                        assert (mask_this_sample == masks[modname]).all()\n\n            for modifier_data in self.builder_data[modname].values():\n                modifier_data['data']['mask'] = masks[modname]\n            sigmas = relerrs[masks[modname]]\n            # list of bools, consistent with other modifiers (no numpy.bool_)\n            fixed = default_backend.tolist(sigmas == 0)\n            # ensures non-Nan constraint term, but in a future PR we need to remove constraints for these\n            sigmas[fixed] = 1.0\n            self.required_parsets.setdefault(parname, [required_parset(sigmas, fixed)])\n        return self.builder_data\n\n\nclass staterror_combined:\n    name = 'staterror'\n    op_code = 'multiplication'\n\n    def __init__(self, modifiers, pdfconfig, builder_data, batch_size=None):\n\n        default_backend = pyhf.default_backend\n        self.batch_size = batch_size\n\n        keys = [f'{mtype}/{m}' for m, mtype in modifiers]\n        self._staterr_mods = [m for m, _ in modifiers]\n\n        parfield_shape = (self.batch_size or 1, pdfconfig.npars)\n        self.param_viewer = ParamViewer(\n            parfield_shape, pdfconfig.par_map, self._staterr_mods\n        )\n\n        self._staterror_mask = [\n            [[builder_data[m][s]['data']['mask']] for s in pdfconfig.samples]\n            for m in keys\n        ]\n        self.__staterror_uncrt = default_backend.astensor(\n            [\n                [\n                    [\n                        builder_data[m][s]['data']['uncrt'],\n                        builder_data[m][s]['data']['nom_data'],\n                    ]\n                    for s in pdfconfig.samples\n                ]\n                for m in keys\n            ]\n        )\n        global_concatenated_bin_indices = [\n            [[j for c in pdfconfig.channels for j in range(pdfconfig.channel_nbins[c])]]\n        ]\n\n        self._access_field = default_backend.tile(\n            global_concatenated_bin_indices,\n            (len(self._staterr_mods), self.batch_size or 1, 1),\n        )\n\n        self._reindex_access_field(pdfconfig)\n\n        self._precompute()\n        events.subscribe('tensorlib_changed')(self._precompute)\n\n    def _reindex_access_field(self, pdfconfig):\n        default_backend = pyhf.default_backend\n        for syst_index, syst_access in enumerate(self._access_field):\n            singular_sample_index = [\n                idx\n                for idx, syst in enumerate(\n                    default_backend.astensor(self._staterror_mask)[syst_index, :, 0]\n                )\n                if any(syst)\n            ][-1]\n\n            for batch_index, batch_access in enumerate(syst_access):\n                selection = self.param_viewer.index_selection[syst_index][batch_index]\n                access_field_for_syst_and_batch = default_backend.zeros(\n                    len(batch_access)\n                )\n\n                sample_mask = self._staterror_mask[syst_index][singular_sample_index][0]\n                access_field_for_syst_and_batch[sample_mask] = selection\n                self._access_field[\n                    syst_index, batch_index\n                ] = access_field_for_syst_and_batch\n\n    def _precompute(self):\n        if not self.param_viewer.index_selection:\n            return\n        tensorlib, _ = get_backend()\n        self.staterror_mask = tensorlib.astensor(self._staterror_mask, dtype=\"bool\")\n        self.staterror_mask = tensorlib.tile(\n            self.staterror_mask, (1, 1, self.batch_size or 1, 1)\n        )\n        self.access_field = tensorlib.astensor(self._access_field, dtype='int')\n        self.sample_ones = tensorlib.ones(tensorlib.shape(self.staterror_mask)[1])\n        self.staterror_default = tensorlib.ones(tensorlib.shape(self.staterror_mask))\n\n    def apply(self, pars):\n        if not self.param_viewer.index_selection:\n            return\n\n        tensorlib, _ = get_backend()\n        if self.batch_size is None:\n            flat_pars = pars\n        else:\n            flat_pars = tensorlib.reshape(pars, (-1,))\n        statfactors = tensorlib.gather(flat_pars, self.access_field)\n        results_staterr = tensorlib.einsum('mab,s->msab', statfactors, self.sample_ones)\n        results_staterr = tensorlib.where(\n            self.staterror_mask, results_staterr, self.staterror_default\n        )\n        return results_staterr\n", "path": "src/pyhf/modifiers/staterror.py"}], "after_files": [{"content": "import logging\nfrom typing import List\n\nimport pyhf\nfrom pyhf import events\nfrom pyhf.exceptions import InvalidModifier\nfrom pyhf.parameters import ParamViewer\nfrom pyhf.tensor.manager import get_backend\n\nlog = logging.getLogger(__name__)\n\n\ndef required_parset(sigmas, fixed: List[bool]):\n    n_parameters = len(sigmas)\n    return {\n        'paramset_type': 'constrained_by_normal',\n        'n_parameters': n_parameters,\n        'is_shared': True,\n        'is_scalar': False,\n        'inits': (1.0,) * n_parameters,\n        'bounds': ((1e-10, 10.0),) * n_parameters,\n        'fixed': tuple(fixed),\n        'auxdata': (1.0,) * n_parameters,\n        'sigmas': tuple(sigmas),\n    }\n\n\nclass staterror_builder:\n    \"\"\"Builder class for collecting staterror modifier data\"\"\"\n\n    def __init__(self, config):\n        self.builder_data = {}\n        self.config = config\n        self.required_parsets = {}\n\n    def collect(self, thismod, nom):\n        uncrt = thismod['data'] if thismod else [0.0] * len(nom)\n        mask = [True if thismod else False] * len(nom)\n        return {'mask': mask, 'nom_data': nom, 'uncrt': uncrt}\n\n    def append(self, key, channel, sample, thismod, defined_samp):\n        self.builder_data.setdefault(key, {}).setdefault(sample, {}).setdefault(\n            'data', {'uncrt': [], 'nom_data': [], 'mask': []}\n        )\n        nom = (\n            defined_samp['data']\n            if defined_samp\n            else [0.0] * self.config.channel_nbins[channel]\n        )\n        moddata = self.collect(thismod, nom)\n        self.builder_data[key][sample]['data']['mask'].append(moddata['mask'])\n        self.builder_data[key][sample]['data']['uncrt'].append(moddata['uncrt'])\n        self.builder_data[key][sample]['data']['nom_data'].append(moddata['nom_data'])\n\n    def finalize(self):\n        default_backend = pyhf.default_backend\n\n        for modifier_name, modifier in self.builder_data.items():\n            for sample_name, sample in modifier.items():\n                sample[\"data\"][\"mask\"] = default_backend.concatenate(\n                    sample[\"data\"][\"mask\"]\n                )\n                sample[\"data\"][\"uncrt\"] = default_backend.concatenate(\n                    sample[\"data\"][\"uncrt\"]\n                )\n                sample[\"data\"][\"nom_data\"] = default_backend.concatenate(\n                    sample[\"data\"][\"nom_data\"]\n                )\n                if len(sample[\"data\"][\"nom_data\"]) != len(sample[\"data\"][\"uncrt\"]):\n                    _modifier_type, _modifier_name = modifier_name.split(\"/\")\n                    _sample_data_len = len(sample[\"data\"][\"nom_data\"])\n                    _uncrt_len = len(sample[\"data\"][\"uncrt\"])\n                    raise InvalidModifier(\n                        f\"The '{sample_name}' sample {_modifier_type} modifier\"\n                        + f\" '{_modifier_name}' has data shape inconsistent with the sample.\\n\"\n                        + f\"{sample_name} has 'data' of length {_sample_data_len} but {_modifier_name}\"\n                        + f\" has 'data' of length {_uncrt_len}.\"\n                    )\n\n        for modname in self.builder_data.keys():\n            parname = modname.split('/')[1]\n\n            nomsall = default_backend.sum(\n                [\n                    modifier_data['data']['nom_data']\n                    for modifier_data in self.builder_data[modname].values()\n                    if default_backend.astensor(modifier_data['data']['mask']).any()\n                ],\n                axis=0,\n            )\n            relerrs = default_backend.sum(\n                [\n                    [\n                        (modifier_data['data']['uncrt'][binnr] / nomsall[binnr]) ** 2\n                        if nomsall[binnr] > 0\n                        else 0.0\n                        for binnr in range(len(modifier_data['data']['nom_data']))\n                    ]\n                    for modifier_data in self.builder_data[modname].values()\n                ],\n                axis=0,\n            )\n            # here relerrs still has all the bins, while the staterror are usually per-channel\n            # so we need to pick out the masks for this modifier to extract the\n            # modifier configuration (sigmas, etc..)\n            # so loop over samples and extract the first mask\n            # while making sure any subsequent mask is consistent\n            relerrs = default_backend.sqrt(relerrs)\n            masks = {}\n            for modifier_data in self.builder_data[modname].values():\n                mask_this_sample = default_backend.astensor(\n                    modifier_data['data']['mask'], dtype='bool'\n                )\n                if mask_this_sample.any():\n                    if modname not in masks:\n                        masks[modname] = mask_this_sample\n                    else:\n                        assert (mask_this_sample == masks[modname]).all()\n\n            # extract sigmas using this modifiers mask\n            sigmas = relerrs[masks[modname]]\n\n            # list of bools, consistent with other modifiers (no numpy.bool_)\n            fixed = default_backend.tolist(sigmas == 0)\n            # FIXME: sigmas that are zero will be fixed to 1.0 arbitrarily to ensure\n            # non-Nan constraint term, but in a future PR need to remove constraints\n            # for these\n            sigmas[fixed] = 1.0\n            self.required_parsets.setdefault(parname, [required_parset(sigmas, fixed)])\n        return self.builder_data\n\n\nclass staterror_combined:\n    name = 'staterror'\n    op_code = 'multiplication'\n\n    def __init__(self, modifiers, pdfconfig, builder_data, batch_size=None):\n\n        default_backend = pyhf.default_backend\n        self.batch_size = batch_size\n\n        keys = [f'{mtype}/{m}' for m, mtype in modifiers]\n        self._staterr_mods = [m for m, _ in modifiers]\n\n        parfield_shape = (self.batch_size or 1, pdfconfig.npars)\n        self.param_viewer = ParamViewer(\n            parfield_shape, pdfconfig.par_map, self._staterr_mods\n        )\n\n        self._staterror_mask = [\n            [[builder_data[m][s]['data']['mask']] for s in pdfconfig.samples]\n            for m in keys\n        ]\n        global_concatenated_bin_indices = [\n            [[j for c in pdfconfig.channels for j in range(pdfconfig.channel_nbins[c])]]\n        ]\n\n        self._access_field = default_backend.tile(\n            global_concatenated_bin_indices,\n            (len(self._staterr_mods), self.batch_size or 1, 1),\n        )\n\n        self._reindex_access_field(pdfconfig)\n\n        self._precompute()\n        events.subscribe('tensorlib_changed')(self._precompute)\n\n    def _reindex_access_field(self, pdfconfig):\n        default_backend = pyhf.default_backend\n        for syst_index, syst_access in enumerate(self._access_field):\n            singular_sample_index = [\n                idx\n                for idx, syst in enumerate(\n                    default_backend.astensor(self._staterror_mask)[syst_index, :, 0]\n                )\n                if any(syst)\n            ][-1]\n\n            for batch_index, batch_access in enumerate(syst_access):\n                selection = self.param_viewer.index_selection[syst_index][batch_index]\n                access_field_for_syst_and_batch = default_backend.zeros(\n                    len(batch_access)\n                )\n\n                sample_mask = self._staterror_mask[syst_index][singular_sample_index][0]\n                access_field_for_syst_and_batch[sample_mask] = selection\n                self._access_field[\n                    syst_index, batch_index\n                ] = access_field_for_syst_and_batch\n\n    def _precompute(self):\n        if not self.param_viewer.index_selection:\n            return\n        tensorlib, _ = get_backend()\n        self.staterror_mask = tensorlib.astensor(self._staterror_mask, dtype=\"bool\")\n        self.staterror_mask = tensorlib.tile(\n            self.staterror_mask, (1, 1, self.batch_size or 1, 1)\n        )\n        self.access_field = tensorlib.astensor(self._access_field, dtype='int')\n        self.sample_ones = tensorlib.ones(tensorlib.shape(self.staterror_mask)[1])\n        self.staterror_default = tensorlib.ones(tensorlib.shape(self.staterror_mask))\n\n    def apply(self, pars):\n        if not self.param_viewer.index_selection:\n            return\n\n        tensorlib, _ = get_backend()\n        if self.batch_size is None:\n            flat_pars = pars\n        else:\n            flat_pars = tensorlib.reshape(pars, (-1,))\n        statfactors = tensorlib.gather(flat_pars, self.access_field)\n        results_staterr = tensorlib.einsum('mab,s->msab', statfactors, self.sample_ones)\n        results_staterr = tensorlib.where(\n            self.staterror_mask, results_staterr, self.staterror_default\n        )\n        return results_staterr\n", "path": "src/pyhf/modifiers/staterror.py"}]}