ATLAS Offline Software
Loading...
Searching...
No Matches
EventSelectionConfigSplitOutput_unitTest.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3"""Unit tests for OutputAnalysisConfig.splitBySelection: one tree per region,
4each in its own stream and filled only for events passing that region.
5"""
6
7import unittest
8from AnaAlgorithm.DualUseConfig import isAthena
9from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
10from AnalysisAlgorithmsConfig.ConfigSequence import ConfigSequence
11from AsgAnalysisAlgorithms.OutputAnalysisConfig import OutputAnalysisConfig
12from EventSelectionAlgorithms.EventSelectionConfig import EventSelectionConfig
13from EventSelectionAlgorithms.EventSelectionConfigTestSupport import _new_accumulator, named, prop
14
15
16def run_split(region_names, **options):
17 algSeq, config = _new_accumulator(DataType.FullSim, [])
18 config.setDefaultHistogramStream("HISTOGRAM") # as in the runners, apart from the tree stream
19 seq = ConfigSequence()
20 for name in region_names:
21 block = EventSelectionConfig()
22 block.setOptionValue("selectionName", name)
23 block.setOptionValue("selectionCuts", "RUN_NUMBER >= 0")
24 seq.append(block)
25 output = OutputAnalysisConfig()
26 output.setOptionValue("vars", ["EventInfo.runNumber -> runNumber"])
27 output.setOptionValue("splitBySelection", True)
28 for opt, val in options.items():
29 output.setOptionValue(opt, val)
30 seq.append(output)
31 seq.fullConfigure(config)
32 if isAthena:
33 algs = config.CA.getEventAlgos()
34 config.CA.wasMerged()
35 return algs, config.outputStreams()
36 return list(algSeq), config.outputStreams()
37
38
39class TestSplitOutput(unittest.TestCase):
41 algs, streams = run_split(["SR", "CR", "SUB_hidden"])
42 for region in ["SR", "CR"]:
43 stream = f"ANALYSIS_{region}"
44 for alg in named(algs, f"TreeMaker_{region}") + named(algs, f"NTupleMaker_{region}"):
45 self.assertEqual(prop(alg, "RootStreamName"), stream)
46 filler = named(algs, f"TreeFiller_{region}")
47 self.assertEqual(len(filler), 1)
48 self.assertEqual(prop(filler[0], "RootStreamName"), stream)
49 self.assertEqual(prop(filler[0], "EventSelection"), f"pass_{region}_%SYS%,as_char")
50 self.assertIn(stream, streams) # requested, so the runner declares it
51 # no combined tree and no tree for SUB-regions
52 self.assertEqual(len([a for a in algs if a.getType() == "CP::TreeMakerAlg"]), 2)
53 self.assertNotIn("ANALYSIS", streams) # so the runners write no tree.root
54
56 algs, streams = run_split(["SR", "CR"], outputFormat="RNTuple")
57 self.assertEqual(len([a for a in algs if a.getType() == "CP::RNtupleTreeMakerAlg"]), 2)
58 for region in ["SR", "CR"]:
59 maker = named(algs, f"RNtupleMaker_{region}")
60 self.assertEqual(len(maker), 1)
61 self.assertEqual(prop(maker[0], "OutputStreamName"), f"ANALYSIS_{region}")
62 self.assertEqual(prop(maker[0], "EventSelection"), f"pass_{region}_%SYS%,as_char")
63 self.assertIn(f"ANALYSIS_{region}", streams)
64
66 algs, streams = run_split(["SR", "SUB_hidden"])
67 makers = [a for a in algs if a.getType() == "CP::TreeMakerAlg"]
68 self.assertEqual(len(makers), 1)
69 self.assertEqual(prop(makers[0], "RootStreamName"), "ANALYSIS")
70 fillers = [a for a in algs if a.getType() == "CP::TreeFillerAlg"]
71 self.assertEqual(len(fillers), 1)
72 self.assertEqual(prop(fillers[0], "EventSelection", ""), "")
73 self.assertIn("ANALYSIS", streams)
74 self.assertNotIn("ANALYSIS_SR", streams)
75
76
77if __name__ == "__main__":
78 unittest.main()