Programming Cuts » History » Version 1
Ole Hansen, 04/05/2018 10:16 AM
1 | 1 | Ole Hansen | h1. Dynamically defined logical expressions (tests/cuts) |
---|---|---|---|
2 | |||
3 | h2. Overview |
||
4 | |||
5 | An important feature of the C+ analyzer is the ability to define arithmetic and logical expressions dynamically (on the fly) without the need to recompile any code. Underlying both types of expressions are "global variables" that are represented by the "@THaVar@":https://hallaweb.jlab.org/podd/html/THaVar.html class and collected in the global variable list "@THaVarList@":https://hallaweb.jlab.org/podd/html/THaVarList.html. Each analysis module (detector, apparatus, physics module) normally adds internal variables of interest to the global variable list @gHaVars@ as part of its [[Writing Detector Code#Initialization|initialization]] and removes those variables from the list in its destructor. For an example, see "@THaScintillator@":https://hallaweb.jlab.org/podd/html/THaScintillator.html. In this way, analysis results are conveniently available for use in expressions and by "@THaOutput@":https://hallaweb.jlab.org/podd/html/THaOutput.html. |
||
6 | |||
7 | Arithmetic expressions are supported by the "@THaFormula@":https://hallaweb.jlab.org/podd/html/THaFormula.html class, while tests/cuts are special cases of @THaFormulas@ which evaluate to either 1 or 0 (true or false) and are represented by the "@THaCut@":https://hallaweb.jlab.org/podd/html/THaCut.html class. In the C++ analyzer, @THaFormulas@ are primarily used in the "@THaOutput@":https://hallaweb.jlab.org/podd/html/THaOutput.html system, while @THaCuts@ are used for two purposes: |
||
8 | |||
9 | # in @THaOutput@ as conditions on histograms; and |
||
10 | # to control the flow of the data analysis in the standard analysis algorithm. |
||
11 | |||
12 | The latter is supported by a special global list of tests, "@THaCutList@":https://hallaweb.jlab.org/podd/html/THaCutList.html, THaCutList supports the concept of "blocks" of cuts which can be evaluated as a unit. Blocks are evaluated at the end of each stage of the analysis (Decode/Reconstruct/Physics). |
||
13 | |||
14 | The interactive interface to the analyzer, "@THaInterface@":https://hallaweb.jlab.org/podd/html/THaInterface.html, automatically creates an instance of "@THaVarList@":https://hallaweb.jlab.org/podd/html/THaVarList.html and "@THaCutList@":https://hallaweb.jlab.org/podd/html/THaCutList.html upon startup. These are called the "global variable list" and "global cut list", respecively. They are accessible via the global variables @gHaVars@ and @gHaCuts@ from anywhere in the analyzer if you @#include@ "@THaGlobals.h@":https://hallaweb.jlab.org/podd/html/THaGlobals.h. |
||
15 | |||
16 | h2. Examples |
||
17 | |||
18 | A short tutorial on using the test/cut classes along with the global variable system follows. As mentioned, the relevant classes are: |
||
19 | * "@THaCutList@":https://hallaweb.jlab.org/podd/html/THaCutList.html -- Define and evaluate cuts. Automatically manages cuts with the help of internal lists. |
||
20 | * "@THaVarList@":https://hallaweb.jlab.org/podd/html/THaVarList.html -- Manage "global" symbolic variables. |
||
21 | * "@THaCut@":https://hallaweb.jlab.org/podd/html/THaCut.html -- Definition of a single cut. This is a low-level class which should normally only be used internally by THaCutList. |
||
22 | * "@THaVar@":https://hallaweb.jlab.org/podd/html/THaVar.html -- Definition of a single symbolic variable. This is a low-level class which should normally only be used internally by THaVarList. |
||
23 | |||
24 | Here is a sample session to demonstrate the use of these classes: |
||
25 | |||
26 | <pre> |
||
27 | analyzer [0] double xvar=10 // Define a variable xvar |
||
28 | analyzer [1] gHaVars->Define("x",xvar) // Add xvar to global var list, name it "x" |
||
29 | analyzer [2] gHaVars->PrintFull() // Show all global vars defined including their current values |
||
30 | OBJ: THaVar x x |
||
31 | (Double_t)[1] 10 |
||
32 | |||
33 | analyzer [3] gHaCuts->Define("cut1","x>0") // Define a cut named "cut1" that is true if x>0. |
||
34 | analyzer [4] gHaCuts->Define("cut2","abs(x)>5") // dto., but |x|>5 |
||
35 | analyzer [5] gHaCuts->Print() // List all defined cuts |
||
36 | Name Def T Block Called Passed |
||
37 | ------------------------------------------------- |
||
38 | cut1 x>0 0 Default 0 0 (0.0%) |
||
39 | cut2 abs(x)>5 0 Default 0 0 (0.0%) |
||
40 | |||
41 | analyzer [6] gHaCuts->Eval() // Evaluate all defined cuts |
||
42 | analyzer [7] gHaCuts->Print() |
||
43 | Name Def T Block Called Passed |
||
44 | ------------------------------------------------- |
||
45 | cut1 x>0 1 Default 1 1 (100%) |
||
46 | cut2 abs(x)>5 1 Default 1 1 (100%) |
||
47 | |||
48 | (Note the current value ("T") of each of the cuts. Both are true since both |
||
49 | conditions are true for x=10). |
||
50 | |||
51 | analyzer [8] xvar=2 // Give xvar a new value |
||
52 | analyzer [9] gHaCuts->Eval() // Evaluate the cuts again |
||
53 | analyzer [10] gHaCuts->Print() |
||
54 | Name Def T Block Called Passed |
||
55 | ------------------------------------------------- |
||
56 | cut1 x>0 1 Default 2 2 (100%) |
||
57 | cut2 abs(x)>5 0 Default 2 1 (50%) |
||
58 | |||
59 | (Note that cut2 is now false since |x| is less than 5.) |
||
60 | |||
61 | analyzer [11] gHaCuts->Result("cut2") // Retrieve result of cut2 |
||
62 | // NB: This does not re-evaluate the cut |
||
63 | (Int_t)0 |
||
64 | analyzer [11] gHaCuts->Result("cut1") |
||
65 | (Int_t)1 |
||
66 | </pre> |
||
67 | |||
68 | Tests may refer to other tests already defined in @gHaCuts@. When evaluating cuts containing other tests, the referenced tests are not re-evaluated, but the result of their last evaluation is used (as in the call to "@THaCutList::Result()@":https://hallaweb.jlab.org/podd/html/THaCutList.html#THaCutList:Result above). This ensures that the test statistics (i.e. number of calls/number of passes) remain consistent when evaluating all the tests for an event. Here's an example, continuing from above: |
||
69 | |||
70 | <pre> |
||
71 | analyzer [12] gHaCuts->Define("cut3","cut1&&!cut2") // Define cut based on two previously-defined cuts |
||
72 | analyzer [13] gHaCuts->Eval() // Evaluate defined cuts again |
||
73 | analyzer [14] gHaCuts->Print() |
||
74 | Name Def T Block Called Passed |
||
75 | ---------------------------------------------------- |
||
76 | cut1 x>0 1 Default 3 3 (100%) |
||
77 | cut2 abs(x)>5 0 Default 3 1 (33.3%) |
||
78 | cut3 cut1&&!cut2 1 Default 1 1 (100%) |
||
79 | </pre> |