Skip to content

Commit 54542b3

Browse files
authored
MUON: added forward tracks post-processing (#2150)
* [MUON] added forward tracks post-processing The post-processing is used to compute the matching efficiency for different MFT/MCH/MID combinations. See Readme.md file for more details. * [MUON] PR review comments
1 parent ec93049 commit 54542b3

19 files changed

Lines changed: 2086 additions & 195 deletions

Modules/MUON/Common/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ set(SRCS
99
src/TrackPlotter.cxx
1010
src/TracksCheck.cxx
1111
src/TracksTask.cxx
12+
src/TracksPostProcessing.cxx
13+
src/TracksPostProcessingConfig.cxx
14+
src/MatchingEfficiencyCheck.cxx
1215
)
1316

1417
set(HEADERS
@@ -17,6 +20,9 @@ set(HEADERS
1720
include/MUONCommon/TrackCheck.h
1821
include/MUONCommon/TrackPlotter.h
1922
include/MUONCommon/TracksTask.h
23+
include/MUONCommon/TracksPostProcessing.h
24+
include/MUONCommon/TracksPostProcessingConfig.h
25+
include/MUONCommon/MatchingEfficiencyCheck.h
2026
)
2127

2228
# ---- Library ----
@@ -51,6 +57,8 @@ add_root_dictionary(${MODULE_NAME}
5157
HEADERS include/MUONCommon/TrackPlotter.h
5258
include/MUONCommon/TracksCheck.h
5359
include/MUONCommon/TracksTask.h
60+
include/MUONCommon/TracksPostProcessing.h
61+
include/MUONCommon/MatchingEfficiencyCheck.h
5462
LINKDEF include/MUONCommon/LinkDef.h)
5563

5664
# ---- Tests ----

Modules/MUON/Common/Readme.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Muon Tracks QC
2+
3+
## TracksTask
4+
5+
The tracks task processes the forward muon tracks and produces a number of plots showing the kinematics and time distributions of the tracks.
6+
The type of tracks that are processed is controlled via the `GID` list in the task configuration. The following options can be selected:
7+
* `MCH`: all standalone MCH tracks are considered, independently of their matching with MFT and MID
8+
* `MFT-MCH`: tracks matched from MFT to MCH, independently of their matching with MID
9+
* `MCH-MID`: tracks matched from MCH to MID, independently of their matching with MFT
10+
* `MFT-MCH-MID`: global forward tracks matched to all three detectors
11+
12+
For each selection listed in the `GID` parameter, two sets of similar plots are produced, one for all the tracks, the second only considering the tracks that pass some standard cuts, namely:
13+
* `cutRAbsMin < RAbs < cutRAbsMax`
14+
* `cutEtaMin < eta < cutEtaMax`
15+
* `pT > cutPtMin`
16+
* `sigmaPDCA < nSigmaPDCA`
17+
* `chi2 < cutChi2Max`
18+
19+
All the cuts are computed using the standalone MCH tracks parameters, regardless of the matching, in order to have a consistent selection for all track types.
20+
21+
In addition to the single-track cuts listed above, a cut (`diMuonTimeCut`) on the time difference (in nanoseconds) between track pairs is applied when filling the di-muon invariant mass plot.
22+
23+
For each selection, the following histograms are filled:
24+
* track kinematic parameters (pT, eta, phi) and their correlations
25+
* distribution of the BC ids associated to the tracks
26+
* tracks multiplicity per TF
27+
* track quality parameters (chi2, RAbs, P*DCA, matching chi2 and probablity)
28+
* 2-D distributions of the MCH track impact points at the MFT exit and MID entrance planes
29+
30+
The plots are saved in sub-folders inside `GLO/MUONTracks`, one folder for each `GID`. An additional sub-folder is aslo created for the plots after selection cuts.
31+
In the example below, the folder structure would look like this:
32+
33+
```
34+
GLO/MUONTracks/MFT-MCH/
35+
GLO/MUONTracks/MFT-MCH/WithCuts/
36+
GLO/MUONTracks/MCH-MID/
37+
GLO/MUONTracks/MCH-MID/WithCuts/
38+
GLO/MUONTracks/MFT-MCH-MID/
39+
GLO/MUONTracks/MFT-MCH-MID/WithCuts/
40+
```
41+
42+
#### Configuration
43+
```json
44+
{
45+
"qc": {
46+
"tasks": {
47+
"TaskMUONTracks": {
48+
"active": "true",
49+
"className": "o2::quality_control_modules::muon::TracksTask",
50+
"moduleName": "QcMUONCommon",
51+
"detectorName": "GLO",
52+
"taskName": "MUONTracks",
53+
"cycleDurationSeconds": "300",
54+
"maxNumberCycles": "-1",
55+
"dataSource": {
56+
"type": "direct",
57+
"query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID;fwdtracks:GLO/GLFWD"
58+
},
59+
"taskParameters": {
60+
"maxTracksPerTF": "600",
61+
"cutRAbsMin": "17.6",
62+
"cutRAbsMax": "89.5",
63+
"cutEtaMin": "-4.0",
64+
"cutEtaMax": "-2.5",
65+
"cutPtMin": "0.5",
66+
"cutPtMin": "0.5",
67+
"nSigmaPDCA": "6",
68+
"cutChi2Max": "1000",
69+
"diMuonTimeCut": "100",
70+
"fullHistos": "0",
71+
"GID" : "MFT-MCH,MCH-MID,MFT-MCH-MID"
72+
},
73+
"grpGeomRequest": {
74+
"geomRequest": "Aligned",
75+
"askGRPECS": "true",
76+
"askGRPLHCIF": "false",
77+
"askGRPMagField": "true",
78+
"askMatLUT": "false",
79+
"askTime": "false",
80+
"askOnceAllButField": "false",
81+
"needPropagatorD": "false"
82+
},
83+
"location": "remote"
84+
}
85+
}
86+
}
87+
}
88+
```
89+
90+
## Tracks Post-processing
91+
92+
The tracks post-processing task takes the plots produced by the tracks task and computes the matching efficiency from their ratios.
93+
Each data source in the task configuration specifies the path of the plots from matched tracks(numerator), the path of the reference plots from un-matched tracks (denominator), and the path where to store the matching efficiency plots (ratios). The data source also contains a `names` parameter with the list of plots to be compared. Each plot name can be followed by an optional number, separated by a semi-colon, that indicates the rebinning factor to be applied to the plots before computing the ratio.
94+
95+
#### Configuration
96+
97+
```json
98+
{
99+
"qc": {
100+
"postprocessing": {
101+
"MUONTracks": {
102+
"active": "true",
103+
"className": "o2::quality_control_modules::muon::TracksPostProcessing",
104+
"moduleName": "QcMUONCommon",
105+
"detectorName": "GLO",
106+
"dataSources": [
107+
{
108+
"plotsPath": "GLO/MO/MUONTracks/MCH-MID/WithCuts",
109+
"refsPath": "MCH/MO/Tracks/WithCuts",
110+
"outputPath": "MCH-MID/WithCuts/MatchEff",
111+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID" ]
112+
},
113+
{
114+
"plotsPath": "GLO/MO/MUONTracks/MCH-MID/WithCuts",
115+
"refsPath": "MCH/MO/Tracks/WithCuts",
116+
"outputPath": "MCH-MID/WithCuts/MatchEff",
117+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID" ]
118+
},
119+
{
120+
"plotsPath": "GLO/MO/MUONTracks/MFT-MCH-MID",
121+
"refsPath": "MCH/MO/Tracks",
122+
"outputPath": "MFT-MCH-MID/MatchEff-MCH",
123+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID", "TrackPosAtMFT" ]
124+
},
125+
{
126+
"plotsPath": "GLO/MO/MUONTracks/MFT-MCH-MID",
127+
"refsPath": "GLO/MO/MUONTracks/MCH-MID",
128+
"outputPath": "MFT-MCH-MID/MatchEff-MCH-MID",
129+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID", "TrackPosAtMFT" ]
130+
},
131+
{
132+
"plotsPath": "GLO/MO/MUONTracks/MFT-MCH-MID/WithCuts",
133+
"refsPath": "MCH/MO/Tracks/WithCuts",
134+
"outputPath": "MFT-MCH-MID/WithCuts/MatchEff-MCH",
135+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID", "TrackPosAtMFT" ]
136+
},
137+
{
138+
"plotsPath": "GLO/MO/MUONTracks/MFT-MCH-MID/WithCuts",
139+
"refsPath": "GLO/MO/MUONTracks/MCH-MID/WithCuts",
140+
"outputPath": "MFT-MCH-MID/WithCuts/MatchEff-MCH-MID",
141+
"names": [ "TrackPt:5", "TrackEta:5", "TrackPhi:10", "TrackEtaPt", "TrackPhiPt", "TrackPosAtMID", "TrackPosAtMFT" ]
142+
}
143+
],
144+
"initTrigger": [
145+
"userorcontrol"
146+
],
147+
"updateTrigger": [
148+
"newobject:qcdb:GLO/MO/MUONTracks/MCH-MID/TrackPt"
149+
],
150+
"stopTrigger": [
151+
"userorcontrol"
152+
]
153+
}
154+
}
155+
}
156+
}
157+
```
158+
159+
## Matching Efficiency Checker
160+
161+
The matching efficiency checker takes the output of the tracks post-processing and verifies that the efficiency values in each plot are within configurable limits. The limits are defined separately for each histogram, or group of histograms, whose name matches a given string.
162+
For 1-D plots, the check can be additionally restricetd to one or more ranges in the x variable, in case some kinematical regions need to be excluded.
163+
164+
For example, the following line corresponds to an acceptable range, for the plots named `TrackEta`, of `[0.3,1.0]` and only checked within the eta ranges `[-4.0,-3.5]` and `[-3.0,-2.5]`:
165+
166+
```
167+
"range:TrackEta": "0.3,1.0:-4.0,-3.5:-3.0,-2.5"
168+
```
169+
170+
If no limit is specified for a given plot, the corresponding values are not checked and the plot is only beautified.
171+
172+
For 2-D plots, the beautification only consists in fixing the z-axis range to `[0.0,1.2]`.
173+
For 1-D plots, the acceptable range is also indicated with horizontal lines, and the plot is painted in red if the quality is judged to be bad.
174+
175+
#### Configuration
176+
177+
```json
178+
{
179+
"qc": {
180+
"checks": {
181+
"MUONMatchCheck": {
182+
"active": "true",
183+
"className": "o2::quality_control_modules::muon::MatchingEfficiencyCheck",
184+
"moduleName": "QcMUONCommon",
185+
"detectorName": "GLO",
186+
"policy": "OnAll",
187+
"extendedCheckParameters": {
188+
"default": {
189+
"default": {
190+
"range:TrackEta": "0.3,1.0:-4.0,-3.5:-3.0,-2.5",
191+
"range:TrackPt": "0.4,1.0:0.5,2.0",
192+
"range:WithCuts": "0.4,1.0"
193+
}
194+
}
195+
},
196+
"dataSource": [
197+
{
198+
"type": "PostProcessing",
199+
"name": "MUONTracks",
200+
"MOs" : [
201+
"MCH-MID/MatchEff/TrackPhi",
202+
"MCH-MID/MatchEff/TrackPt",
203+
"MCH-MID/MatchEff/TrackEta",
204+
"MCH-MID/WithCuts/MatchEff/TrackPhi",
205+
"MCH-MID/WithCuts/MatchEff/TrackPt",
206+
"MCH-MID/WithCuts/MatchEff/TrackEta",
207+
"MCH-MID/WithCuts/MatchEff/TrackPosAtMID"
208+
]
209+
}
210+
]
211+
}
212+
}
213+
}
214+
}
215+
```

Modules/MUON/Common/include/MUONCommon/Helpers.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,39 @@
1212
#ifndef QC_MODULE_MUON_COMMON_HELPERS_H
1313
#define QC_MODULE_MUON_COMMON_HELPERS_H
1414

15+
#include "QualityControl/CustomParameters.h"
1516
#include <gsl/span>
1617

1718
class TH1;
1819
class TLine;
1920

2021
namespace o2::quality_control_modules::muon
2122
{
23+
template <class T>
24+
T getConfigurationParameter(o2::quality_control::core::CustomParameters customParameters, std::string parName, const T defaultValue)
25+
{
26+
T result = defaultValue;
27+
auto parOpt = customParameters.atOptional(parName);
28+
if (parOpt.has_value()) {
29+
std::stringstream ss(parOpt.value());
30+
ss >> result;
31+
}
32+
return result;
33+
}
34+
35+
template <class T>
36+
T getConfigurationParameter(o2::quality_control::core::CustomParameters customParameters, std::string parName, const T defaultValue, const o2::quality_control::core::Activity& activity)
37+
{
38+
auto parOpt = customParameters.atOptional(parName, activity);
39+
if (parOpt.has_value()) {
40+
T result;
41+
std::stringstream ss(parOpt.value());
42+
ss >> result;
43+
return result;
44+
}
45+
return getConfigurationParameter<T>(customParameters, parName, defaultValue);
46+
}
47+
2248
TLine* addHorizontalLine(TH1& histo, double y,
2349
int lineColor = 1, int lineStyle = 10,
2450
int lineWidth = 1);

Modules/MUON/Common/include/MUONCommon/HistPlotter.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class HistPlotter
2424
{
2525
public:
2626
HistPlotter() = default;
27-
~HistPlotter() = default;
27+
virtual ~HistPlotter() = default;
2828

2929
public:
3030
struct HistInfo {
@@ -36,13 +36,18 @@ class HistPlotter
3636
/** reset all histograms */
3737
void reset();
3838

39+
virtual void endOfCycle() {}
40+
3941
std::vector<HistInfo>& histograms() { return mHistograms; }
4042
const std::vector<HistInfo>& histograms() const { return mHistograms; }
4143

4244
virtual void publish(std::shared_ptr<o2::quality_control::core::ObjectsManager> objectsManager);
45+
virtual void publish(std::shared_ptr<o2::quality_control::core::ObjectsManager> objectsManager, HistInfo& hinfo);
46+
virtual void unpublish(std::shared_ptr<o2::quality_control::core::ObjectsManager> objectsManager);
4347

4448
private:
4549
std::vector<HistInfo> mHistograms;
50+
std::vector<HistInfo> mPublishedHistograms;
4651
};
4752

4853
} // namespace o2::quality_control_modules::muon

Modules/MUON/Common/include/MUONCommon/LinkDef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
#pragma link C++ class o2::quality_control_modules::muon::TrackPlotter + ;
77
#pragma link C++ class o2::quality_control_modules::muon::TracksTask + ;
88
#pragma link C++ class o2::quality_control_modules::muon::TracksCheck + ;
9+
#pragma link C++ class o2::quality_control_modules::muon::TracksPostProcessing + ;
10+
#pragma link C++ class o2::quality_control_modules::muon::MatchingEfficiencyCheck + ;
911

1012
#endif
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file MatchingEfficiencyCheck.h
14+
/// \author Andrea Ferrero
15+
///
16+
17+
#ifndef QC_MODULE_MUON_MATCHINGEFFICIENCYCHECK_H
18+
#define QC_MODULE_MUON_MATCHINGEFFICIENCYCHECK_H
19+
20+
#include "QualityControl/CheckInterface.h"
21+
22+
#include <map>
23+
24+
namespace o2::quality_control_modules::muon
25+
{
26+
27+
/// \brief Check whether the matching efficiency is within some configurable limits
28+
///
29+
/// \author Andrea Ferrero
30+
class MatchingEfficiencyCheck : public o2::quality_control::checker::CheckInterface
31+
{
32+
public:
33+
/// Default constructor
34+
MatchingEfficiencyCheck() = default;
35+
/// Destructor
36+
~MatchingEfficiencyCheck() override = default;
37+
38+
void configure() override;
39+
Quality check(std::map<std::string, std::shared_ptr<MonitorObject>>* moMap) override;
40+
void beautify(std::shared_ptr<MonitorObject> mo, Quality checkResult = Quality::Null) override;
41+
std::string getAcceptedType() override;
42+
43+
void startOfActivity(const Activity& activity) override;
44+
void endOfActivity(const Activity& activity) override;
45+
46+
ClassDefOverride(MatchingEfficiencyCheck, 1);
47+
48+
private:
49+
void initRange(std::string key);
50+
std::optional<std::pair<double, double>> getRange(std::string key);
51+
52+
Activity mActivity;
53+
std::map<std::string, std::pair<double, double>> mRanges;
54+
std::map<std::string, std::vector<std::pair<double, double>>> mIntervals;
55+
std::map<std::string, Quality> mQualities;
56+
};
57+
58+
} // namespace o2::quality_control_modules::muon
59+
60+
#endif // QC_MODULE_MUON_MATCHINGEFFICIENCYCHECK_H

0 commit comments

Comments
 (0)