3.5.4. Filtering¶
Filter |
Operator |
Output family length |
---|---|---|
\(a' = \filter{\phi}\ a\) |
\(\phi: \bool^n \rightarrow \bool\) |
\(|a'| \le |a|\) |
As mentioned in Section 3.5.3, the execution of workflow graph can be short-circuited if data products do not meet specified criteria. This process, known as filtering, effectively shortens the input family \(a\) by retaining only those entries that satisfy a predicate \(\phi\), thus creating a different family \(a'\) composed of elements from \(a\).
Filtering is of interest only when there is a downstream node that can receive the filtered family. Therefore, Phlex will not schedule a filter for execution if the only nodes downstream of it are other filters or predicates.
Filtering can be applied to the input data-product families of any HOFs without explicitly registering a filter HOF. This is done through a predicate expression, which is a stringized form of the predicate \(\phi\) that is applied to the input data-product family, retaining only the elements that satisfy the predicate.
3.5.4.1. Predicate Expression¶
The predicate \(\phi\) is Boolean expression whose input arguments correspond to the Boolean results of explicitly registered predicates. For example, in Fig. 3.1, the predicate in \(\textit{filter(high\_energy)}\) is \(\textit{high\_energy}\), which is an explicitly registered predicate, as presented in Section 3.5.3.2.
It is possible for one filter named "only_high_energy"
to use as its predicate \(\textit{high\_energy}\), whereas another filter named "not_high_energy"
could use the negation \(\textit{filter}(\neg \textit{high\_energy})\).
In this case, the predicate \(\textit{high\_energy}\) is executed only once, but its value can be used in different ways in the predicate expression.
A predicate expression can be evaluated on a higher-level data cell than the data-product family in question. For example, suppose none of the \(\textit{GoodHits}\) data products in a given Spill were suitable for processing. It is possible to create a filter that would reject all \(\textit{GoodHits}\) data products from that Spill even though the predicate itself interrogated only the Spill information and not the lower-level good-hits information from the APA.
The supported grammar of the predicate expression is discussed in the technical design (under preparation).
3.5.4.2. Registration interface¶
The following example shows the complete registration for histogramming the filtered \(\textit{GoodHits}\) data products shown in Fig. 3.1.
class hits { ... };
void histogram_hits(hits const&, TH1F&) { ... }
PHLEX_REGISTER_ALGORITHMS(m, config)
{
auto h_resource = m.resource<histogramming>();
observe(histogram_hits, concurrency::serial)
.family("GoodHits"_in("APA"), h_resource->make<TH1F>(...))
.when("high_energy"); // <= predicate expression within the when(...) call
}
In practice, it is convenient to specify a predicate expression as part of a Phlex program’s run-time configuration instead of hard-coded into a compiled library. Phlex allows users to specify predicate expressions in a program configuration:
{
# Speculative configurations for two observer nodes that use the same module library
histogram_high_energy_hits: {
plugin: "histogram_hits.so",
},
histogram_low_energy_hits: {
plugin: "histogram_hits.so",
when: "!high_energy" # Negate filter, overriding compiled when(...) clause
},
}
Note that specifying a predicate expression via the when
configuration parameter overrides whatever predicate expression may have been hard-coded into the compiled module.