Skip to content

Commit 1bcca06

Browse files
committed
Rewrite filter section
1 parent 16dd79f commit 1bcca06

File tree

1 file changed

+63
-33
lines changed

1 file changed

+63
-33
lines changed

docs/basics-tasks/FilteringPartitioning.md

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,34 +34,65 @@ properties passes a certain criteria. This can be specified with the `Filter` he
3434

3535
```cpp
3636
struct MyTask : AnalysisTask {
37-
Filter<Tracks> ptFilter = track::pt > 1;
37+
Filter ptFilter = track::pt > 1.f;
3838

39-
void process(Tracks const &filteredTracks) {
39+
void process(soa::Filtered<Tracks> const &filteredTracks) {
4040
for (auto& track : filteredTracks) {
4141
}
4242
}
4343
};
4444
```
4545
46-
filteredTracks will contain only the tracks in the table which pass the condition `track::pt > 1`.
46+
filteredTracks will contain only the tracks in the table which pass the condition `track::pt > 1.f`.
47+
48+
Filter is automatically associated with a compatible table, i.e. table that has all the columns that are present in the filter expression.
49+
It is currently impossible to have a filter that uses columns from more than one table.
50+
If there are several filters declared, that are compatible with a single table, they are combined with logical "and".
51+
52+
### Expressions
53+
`Filters` and `Partitions` are defined using `expressions`, as in the example above, which are C++ expressions that can contain _columns_, numerical and boolean _constants_, single-valued _configurables_, a limited set of special _functions_ and _branching_ conditions. The expressions are compiled on-the-fly to be applied and therefore require _explicit_ types to be used. For example in the expression `track::pt > 1.f` the numerical constant is marked to be `float`, while a simple `1` would be parsed as `int` and `1.` would be parsed as `double`.
54+
55+
`Filters` and `Partitions` require the expression result to be `boolean`.
56+
57+
The following funcitons and operations are permitted in expressions. Each `expr1` and `expr2` can be a single column, constant, configurable, condition, or a valid expression. Previously defined filters can also be used by name. Parentheses can be used as usual.
58+
59+
| Operation | Syntax | Description |
60+
|:----------|:----------|:----------|
61+
| Logical "and" | `expr1 && expr2` | logical multiplication of two expressions (both boolean) |
62+
| Logical "or" | `expr1 \|\| expr2` | logical addition of two expressions (bothboolean) |
63+
| Addition | `expr1 + expr2` | Addition of two expressions (compatible types) |
64+
| Subtraction | `expr1 - expr2` | Subtraction of two expressions (compatible types) |
65+
| Division | `expr1 / expr2` | Division of two expressions (compatibel types) |
66+
| Multiplication | `expr1 * expr2` | Multiplication of two expressions (compatible types) |
67+
| Bitwise "and" | `expr1 & expr2` | Bitwise logical multiplication (equally-sized integer types) |
68+
| Bitwise "or" | `expr1 \| expr2` | Bitwise logical addition (equally-sized integer types) |
69+
| Bitwise "xor" | `expr1 ^ expr2` | Bitwise exclusive logical multiplication (equally-sized integer types) |
70+
| Less than | `expr1 < expr2` | Comparison (compatible types) |
71+
| Less than or equal | `expr1 <= expr2` | -- |
72+
| Greater than | `expr1 > expr2` | -- |
73+
| Greater than or equal | `expr1 >= expr2` | -- |
74+
| Equal | `expr1 == expr2` | -- |
75+
| Not equal | `expr1 != expr2` | -- |
76+
| Atan2 | `natan2(expr1, expr2)` | 2-argument arctangent function |
77+
| Power | `npow(expr, constant)` | Exponentiation |
78+
| Square root | `nsqrt(expr)` | Square root function |
79+
| Exponent | `nexp(expr)` | Exponent function |
80+
| Logarithm | `nlog(expr)` | Natural logarithm function |
81+
| Base-10 logarithm | `nlog10(expr)` | Base-10 logarithm function |
82+
| Sine | `nsin(expr)` | Sine function |
83+
| Cosine | `ncos(expr)` | Cosine function |
84+
| Tangent | `ntan(expr)` | Tangent function |
85+
| Arcsine | `nasin(expr)` | Arcsine function |
86+
| Arccosine | `nacos(expr)` | Arccosine function |
87+
| Arctangent | `natan(expr)` | Arctangent function |
88+
| Absolute value | `nabs(expr)` | Absolute value function |
89+
| Rounding | `nround(expr)` | Rounding function |
90+
| Bitwise "not" | `bitwise_not(expr)` | Bitwise logical "not" (integers) |
91+
| Branching condition | `ifnode(expr_condition, expr_if_true, expr_if_false)` | Conditional expression, depending if the `expr_condition` is true or false, the result of this expression is either `expr_if_true` or `expr_if_false` |
92+
93+
Note that while normal function can be used in expressions, they are **evaluated on construction** so they are equivalent to numerical constants. All the specially declared functions that can act on `expressions` start with `n`.
4794
48-
You can specify multiple filters which will be applied in a sequence effectively resulting in the intersection of all them.
4995
50-
You can also specify filters on associated quantities:
51-
52-
```cpp
53-
struct MyTask : AnalysisTask {
54-
Filter<Collisions> collisionFilter = max(track::pt) > 1;
55-
56-
void process(Collisions const &filteredCollisions) {
57-
for (auto& collision: filteredCollisions) {
58-
...
59-
}
60-
}
61-
};
62-
```
63-
64-
will process all the collisions which have at least one track with `pt > 1`.
6596
6697
## Partitioning your inputs
6798
@@ -75,21 +106,25 @@ struct MyTask : AnalysisTask {
75106
Partition<Tracks> rightTracks = track::eta >= 0;
76107
77108
void process(Tracks const &tracks) {
78-
for (auto& left : leftTracks(tracks)) {
79-
for (auto& right : rightTracks(tracks)) {
109+
for (auto& left : leftTracks) {
110+
for (auto& right : rightTracks) {
80111
...
81112
}
82113
}
114+
for (auto& track : tracks) {
115+
...
116+
}
83117
}
84118
};
85119
```
86120

87-
i.e. `Filter` is applied to the objects before passing them to the `process` method, while `Select` objects can be used to do further reduction inside the `process` method itself.
121+
`Filter` is applied to the objects before passing them to the `process` method, while `Partitions` exist independently.
88122

89123
## Filtering and partitioning together
90124

91-
It is also possible to filter and partition data in the same task. Therefore, multiple `Filter`s are combined using the logical `AND`. These filters then are combined by a logical `AND` with all the specified selections `Select`, which themself are combined by logical `OR`s. E.g., `(Filter1 && Filter2) && (Select1 || Select2)`.
125+
It is possible to use filters and partition data in the same task. Filters are applied as usual, combined with logical "and", therefore `tracks` table will only have entries that satisfy the filter conditions. The partitions, however, are _independent_ and _not grouped_ (by collision, in this example).
92126

127+
One can also define a partition _over a filtered type_, `Partition<soa::Filtered<aod::Tracks>> part = nabs(track::eta) < 1.f`. Doing this will put the partition selection on top of whatever filter selections are also present in the same task.
93128
```cpp
94129
using namespace o2::aod;
95130

@@ -111,22 +146,17 @@ struct partandfiltexample {
111146
112147
## Configuring filters
113148
114-
One of the features of the current framework is the ability to customize on the fly cuts and selection. The idea is to allow that by having a `configurable("mnemonic-name-of-the-parameter")` helper which can be used to refer to configurable options. The previous example will then become:
149+
One of the features of the current framework is the ability to customize on the fly cuts and selection. Single-valued configurabled can be used in filter expressions directly, with some caveats. Configurables are defined to be implicitly convertable to their underlying type, however you do not want that to happen in your filter expressions as it would substitute its default value. It is possible to use the `.node()` method of the configurable in the expression, to ensure that it creates a placeholder node.
115150
116151
```cpp
117152
struct MyTask : AnalysisTask {
118-
Filter<Collisions> collisionFilter = max(track::pt) > configurable<float>("my-pt-cut");
153+
Configurable<float> myPtCut{"my-pt-cut", 10.f, "pt cut"};
154+
Filter trackFilter = track::pt >= myPtCut;
155+
156+
void process(Collision const& collision, soa::Filtered<Tracks> const& filteredTracks) {
119157
120-
void process(Collisions const &filteredCollisions) {
121-
for (auto& collision: filteredCollisions) {
122-
...
123-
}
124158
}
125159
};
126160
```
127161

128-
```todo
129-
- Complete list of methods related to filters and partitions
130-
```
131-
132162
See also tutorials [Data Selection](../tutorials/dataSelection.md).

0 commit comments

Comments
 (0)