Repository: scikit-hep/cabinetry

Issue:
Config changes to disable adding staterror systematics?
It would be great to have a way to have the cabinetry example build a workspace similar to the `pyhf.simplemodels` from ntuples without having to change it too much (e.g. to use `lumi` or strip `staterror`).

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/scikit-hep/cabinetry/pull/359?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep) Report
> Merging [#359](https://codecov.io/gh/scikit-hep/cabinetry/pull/359?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep) (5bc8a94) into [master](https://codecov.io/gh/scikit-hep/cabinetry/commit/724e5f8030511ccee995390fd9cc975a7fc0d6bd?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep) (724e5f8) will **decrease** coverage by `0.04%`.
> The diff coverage is `83.33%`.

```diff
@@             Coverage Diff             @@
##            master     #359      +/-   ##
===========================================
- Coverage   100.00%   99.95%   -0.05%     
===========================================
  Files           23       23              
  Lines         2001     2002       +1     
  Branches       326      327       +1     
===========================================
  Hits          2001     2001              
- Partials         0        1       +1     
```


| [Impacted Files](https://codecov.io/gh/scikit-hep/cabinetry/pull/359?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep) | Coverage Δ | |
|---|---|---|
| [src/cabinetry/workspace.py](https://codecov.io/gh/scikit-hep/cabinetry/pull/359/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep#diff-c3JjL2NhYmluZXRyeS93b3Jrc3BhY2UucHk=) | `99.44% <83.33%> (-0.56%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-hep)


Patch:
diff --git a/src/cabinetry/schemas/config.json b/src/cabinetry/schemas/config.json
index d841da9..62704b7 100644
--- a/src/cabinetry/schemas/config.json
+++ b/src/cabinetry/schemas/config.json
@@ -198,6 +198,10 @@
                     "description": "if it is a data sample",
                     "type": "boolean"
                 },
+                "DisableStaterror": {
+                    "description": "whether to disable the automatic inclusion of staterror modifiers for this sample, defaults to False",
+                    "type": "boolean"
+                },
                 "Regions": {
                     "description": "region(s) that contain the sample, defaults to all regions",
                     "$ref": "#/definitions/regions_setting"
diff --git a/src/cabinetry/workspace.py b/src/cabinetry/workspace.py
index 4f3d0a1..e6729ec 100644
--- a/src/cabinetry/workspace.py
+++ b/src/cabinetry/workspace.py
@@ -286,11 +286,15 @@ class WorkspaceBuilder:
                 modifiers = []
 
                 # gammas
-                gammas = {}
-                gammas.update({"name": "staterror_" + region["Name"].replace(" ", "-")})
-                gammas.update({"type": "staterror"})
-                gammas.update({"data": sample_hist.stdev.tolist()})
-                modifiers.append(gammas)
+                if not sample.get("DisableStaterror", False):
+                    # staterror modifiers are added unless DisableStaterror is True
+                    gammas = {}
+                    gammas.update(
+                        {"name": "staterror_" + region["Name"].replace(" ", "-")}
+                    )
+                    gammas.update({"type": "staterror"})
+                    gammas.update({"data": sample_hist.stdev.tolist()})
+                    modifiers.append(gammas)
 
                 # modifiers can have region and sample dependence, which is checked
                 # check if normfactors affect sample in region, add modifiers as needed


Test patch:
diff --git a/tests/test_workspace.py b/tests/test_workspace.py
index 27c5cce..8cfa0af 100644
--- a/tests/test_workspace.py
+++ b/tests/test_workspace.py
@@ -256,7 +256,9 @@ def test_WorkspaceBuilder_sys_modifiers(mock_norm, mock_norm_shape):
     "cabinetry.workspace.histo.Histogram.from_config",
     return_value=histo.Histogram.from_arrays([0, 1, 2], [1.0, 2.0], [0.1, 0.1]),
 )
-@mock.patch("cabinetry.configuration.region_contains_sample", side_effect=[True, False])
+@mock.patch(
+    "cabinetry.configuration.region_contains_sample", side_effect=[True, False, True]
+)
 def test_WorkspaceBuilder_channels(mock_contains, mock_histogram):
     # should mock normfactor_modifiers / sys_modifiers
     example_config = {
@@ -314,6 +316,17 @@ def test_WorkspaceBuilder_channels(mock_contains, mock_histogram):
     # no calls to read histogram content
     assert mock_histogram.call_count == 1
 
+    # staterror creation disabled
+    example_config = {
+        "General": {"HistogramFolder": "path"},
+        "Regions": [{"Name": "region_1"}],
+        "Samples": [{"Name": "signal", "DisableStaterror": True}],
+        "NormFactors": [],
+    }
+    ws_builder = workspace.WorkspaceBuilder(example_config)
+    channels = ws_builder.channels()
+    assert channels[0]["samples"][0]["modifiers"] == []
+
 
 def test_WorkspaceBuilder_measurements():
     example_config = {