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`).

Comments:

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 = {