Pattern Matching¶
The framework uses a pattern matching system in several places:
The
datasetfield inevent_collectionsto select which datasets to process.The
--filter-datasetand--filter-sampleCLI options.The
selectandgroupfields in postprocessing configurations.Style rules in postprocessing.
The
drop_sample_patternin postprocessing.The
systsfield inLimitSystsrun builders.
We summarize here the basics of the system. Ideally it would be nice to switch perhaps to a more robust pattern matcher in the future.
Basic Patterns¶
The most basic pattern matches against a simple scalar value, almost always a string.
The simplest and most common form is a glob pattern – a string with * as a wildcard:
dataset: 'signal_2018_*' # Matches any dataset starting with "signal_2018_"
dataset: '*JetHT*' # Matches any dataset containing "JetHT"
dataset: 'qcd_ht_2018' # Exact match (no wildcards)
Glob patterns are the default mode.
They use standard shell-style matching: * matches any sequence of characters, ? matches a single character.
Negation¶
Prefixing a pattern with ! negates it:
dataset_name: '!signal*' # Matches anything that does NOT start with "signal"
Regex Patterns¶
For more complex matching, prefix the pattern with re: to use a regular expression:
dataset_name: 're:signal_2018_312_(1000|1500)_.*'
This matches signal_2018_312_1000_... and signal_2018_312_1500_... but nothing else.
Deep Patterns (Metadata Matching)¶
For matching against more sophisticated data, we use a dictionary matching system, which we refer to as a deep pattern. When matching against structured metadata (a dictionary), you can specify patterns for specific keys. This is the most common usage in postprocessing configurations:
select:
type: Histogram # Match results of type "Histogram"
sample_type: MC # Match MC samples only
pipeline: "Signal*" # Match pipelines starting with "Signal"
dataset_name: "!signal*" # Exclude signal datasets
Each key-value pair becomes a DeepPattern: the key specifies the path in the metadata dictionary, and the value is a pattern matched against the value at that path.
When multiple keys are specified, they are combined with AND – all must match.
Nested keys are supported using dot notation:
group: {"era.name": "*"} # Group by the "name" field under the "era" key
Compound Patterns¶
For more complex logic, you can use explicit AND, OR, and NOT:
OR (match any):
drop_sample_pattern:
or_exprs:
- sample_name: "*50to100*"
- sample_name: "*100to200*"
- sample_name: "*200to300*"
AND (match all):
some_pattern:
and_exprs:
- dataset_name: "qcd*"
- era.name: "2018"
NOT (invert):
some_pattern:
not_expr:
dataset_name: "signal*"
Capture and Grouping¶
In postprocessing, patterns are used not only for filtering but also for grouping.
The group field specifies a pattern where * wildcards act as capture groups:
structure:
group: {"era.name": "*"}
This groups results by their era name – all results with era.name = "2018" are placed in one group, those with era.name = "2017" in another, etc.
The capture value becomes part of the metadata that can be used in output file naming:
output_name: "{prefix}/{era.name}/plot.png"
For more details on how grouping works in postprocessing, see Postprocessing Overview.
Summary of Pattern Syntax¶
Syntax |
Meaning |
|---|---|
|
Match anything (glob wildcard) |
|
Glob: starts with “signal” |
|
Negated glob: does NOT start with “signal” |
|
Regular expression matching |
|
Deep pattern: match |
|
Nested deep pattern: match against |
|
OR: match any sub-pattern |
|
AND: match all sub-patterns |
|
NOT: invert the sub-pattern |