Skip to content

Commit 5020bf2

Browse files
pillotcomrademarvin
authored andcommitted
[MCH] filter digits based on HV status (#13308)
* preparation for recording HV status in status map * Addition of HV issues algorithm * improve TF timestamp calculation and add time margin * activate the digit filtering on bad HV * update documentation * add protection against invalid DCS alias --------- Co-authored-by: Stephan Potgieter <77969712+comrademarvin@users.noreply.github.com>
1 parent 867392c commit 5020bf2

File tree

8 files changed

+403
-51
lines changed

8 files changed

+403
-51
lines changed

Detectors/MUON/MCH/DigitFiltering/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ o2-mch-digits-filtering-workflow
1111

1212
Filter out some digits.
1313

14+
**StatusMap based filtering :**
15+
16+
The [status map](/Detectors/MUON/MCH/Status/README.md) lists all the pads that are not perfect and assigns them a status word summarizing the origin of the issue(s). The filtering based on the status map is governed by the [MCHDigitFilterParam](/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h)`.statusMask` parameter, from which we can select the issue(s) to be filtered.
17+
1418
**Noise filtering :**
1519

1620
The exact behavior of the noise filtering is governed by the [MCHDigitFilterParam](/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h) configurable param, where you can select the minimum ADC value to consider, and whether to select signal (i.e. killing as much background as possible, possibly killing some signal as well) and/or to reject background (while not killing signal).

Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitFilterParam.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "CommonUtils/ConfigurableParam.h"
1616
#include "CommonUtils/ConfigurableParamHelper.h"
17+
#include "MCHStatus/StatusMap.h"
1718

1819
namespace o2::mch
1920
{
@@ -29,7 +30,8 @@ struct DigitFilterParam : public o2::conf::ConfigurableParamHelper<DigitFilterPa
2930
bool rejectBackground = true; ///< attempts to reject background (loose background selection, don't kill signal)
3031
bool selectSignal = false; ///< attempts to select only signal (strict background selection, might loose signal)
3132
int timeOffset = 120; ///< digit time calibration offset
32-
uint32_t statusMask = 3; ///< mask to reject digits based on the statusmap (0=no rejection,1=badchannels from ped calib only,2=badchannels from rejectlist,3=1+2)
33+
/// mask to reject digits based on the statusmap (0 = no rejection)
34+
uint32_t statusMask = StatusMap::kBadPedestal | StatusMap::kRejectList | StatusMap::kBadHV;
3335

3436
O2ParamDef(DigitFilterParam, "MCHDigitFilter");
3537
};

Detectors/MUON/MCH/Status/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
o2_add_library(MCHStatus
1313
SOURCES
14+
src/HVStatusCreator.cxx
1415
src/StatusMap.cxx
1516
src/StatusMapCreatorParam.cxx
1617
src/StatusMapCreatorSpec.cxx
1718
PUBLIC_LINK_LIBRARIES
1819
fmt::fmt
20+
O2::DetectorsDCS
1921
O2::DataFormatsMCH
2022
O2::MCHGlobalMapping)
2123

Detectors/MUON/MCH/Status/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The status map is an object that list all pads that are not perfect, for some re
66

77
The gathering of all the sources of information is performed by the [StatusMapCreatorSpec](src/StatusMapCreatorSpec.cxx), either in standalone [o2-mch-statusmap-creator-workflow](src/statusmap-creator-workflow.cxx) device, or, most probably, as part of the regular [o2-mch-reco-workflow](../Workflow/src/reco-workflow.cxx).
88

9-
So far only we have only implemented the bad channel list from pedestal runs and the manual reject list. Next in line will be the usage of the HV and LV values.
9+
So far we have implemented the bad channel list from pedestal runs, HV status and the manual reject list.
1010

1111
## StatusMap usage
1212

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
#ifndef O2_MCH_HV_STATUS_CREATOR_H_
13+
#define O2_MCH_HV_STATUS_CREATOR_H_
14+
15+
#include <set>
16+
#include <string>
17+
#include <unordered_map>
18+
#include <vector>
19+
20+
#include "DetectorsDCS/DataPointIdentifier.h"
21+
#include "DetectorsDCS/DataPointValue.h"
22+
23+
namespace o2::mch
24+
{
25+
26+
class StatusMap;
27+
28+
/**
29+
* @class HVStatusCreator
30+
* @brief Find HV issues from DCS data points and add them to the status map
31+
*
32+
* This is a 3 step procedure:
33+
*
34+
* 1) Find all potential issues from the DCS data points stored in one HV file.
35+
* This must be done each time a new HV file is read from the CCDB. It stores in
36+
* an internal map the time range(s) of the issue(s) for each affected HV channel.
37+
*
38+
* 2) Find all real issues at a given time stamp.
39+
* This must be done for every TF. It updates the internal list of bad HV
40+
* channels if it is different from the current one and tells if that happens.
41+
*
42+
* 3) Update the status maps if needed.
43+
* This must be done each time the current list of bad HV channel has changed.
44+
* It adds every electronics channels associated to the bad HV channels into the
45+
* status map given as a parameter.
46+
*/
47+
class HVStatusCreator
48+
{
49+
public:
50+
using DPID = o2::dcs::DataPointIdentifier;
51+
using DPVAL = o2::dcs::DataPointValue;
52+
using DPMAP = std::unordered_map<DPID, std::vector<DPVAL>>;
53+
54+
/// Internal structure to define a time range
55+
struct TimeRange {
56+
uint64_t begin = 0; ///< beginning of time range
57+
uint64_t end = 0; ///< end of time range
58+
59+
/**
60+
* Constructor of time range
61+
* @param begin beginning of time range (ms)
62+
* @param end end of time range (ms)
63+
*/
64+
TimeRange(uint64_t begin, uint64_t end) : begin(begin), end(end){};
65+
66+
/**
67+
* Check if the time range contains the given time stamp
68+
* @param timestamp time stamp of interest (ms)
69+
* @return true if the time stamp is in the time range
70+
*/
71+
bool contains(uint64_t timestamp) const { return timestamp >= begin && timestamp < end; }
72+
};
73+
74+
using BADHVMAP = std::unordered_map<std::string, std::vector<TimeRange>>;
75+
76+
/**
77+
* Getter for the internal map of HV issues
78+
* @return map of bad HV channels with the time ranges concerned
79+
*/
80+
const BADHVMAP& getBadHVs() const { return mBadHVTimeRanges; }
81+
82+
/**
83+
* Find all HV issues and their time ranges
84+
* @param dpMap DCS HV data points from CCDB
85+
*/
86+
void findBadHVs(const DPMAP& dpMap);
87+
88+
/**
89+
* Find HV issues at a given time stamp
90+
* @param timestamp time stamp of interest
91+
* @return true if the list of issues has changed
92+
*/
93+
bool findCurrentBadHVs(uint64_t timestamp);
94+
95+
/**
96+
* Add channels affected by current HV issues to the status map
97+
* @param statusMap statusMap to update
98+
*/
99+
void updateStatusMap(StatusMap& statusMap) const;
100+
101+
/// Clear the internal lists of HV issues
102+
void clear()
103+
{
104+
mBadHVTimeRanges.clear();
105+
mCurrentBadHVs.clear();
106+
}
107+
108+
private:
109+
/// map of bad HV channels with the time ranges concerned
110+
BADHVMAP mBadHVTimeRanges{};
111+
std::set<std::string> mCurrentBadHVs{}; ///< current list of bad HV channels
112+
};
113+
114+
} // namespace o2::mch
115+
116+
#endif // O2_MCH_HV_STATUS_CREATOR_H_

Detectors/MUON/MCH/Status/include/MCHStatus/StatusMapCreatorParam.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,16 @@ namespace o2::mch
2525
struct StatusMapCreatorParam : public o2::conf::ConfigurableParamHelper<StatusMapCreatorParam> {
2626

2727
bool useBadChannels = true; ///< reject bad channels (obtained during pedestal calibration runs)
28-
bool useRejectList = true; ///< use extra (relative to bad channels above) rejection list
28+
bool useRejectList = true; ///< use extra rejection list (relative to other bad channels sources)
29+
bool useHV = true; ///< reject channels connected to bad HV sectors
2930

30-
bool isActive() const { return useBadChannels || useRejectList; }
31+
/// chambers HV thresholds for detecting issues
32+
double hvLimits[10] = {1550., 1550., 1600., 1600., 1600., 1600., 1600., 1600., 1600., 1600.};
33+
uint64_t hvMinDuration = 10000; ///< minimum duration of HV issues in ms
34+
35+
uint64_t timeMargin = 2000; ///< time margin for comparing DCS and TF timestamps in ms
36+
37+
bool isActive() const { return useBadChannels || useRejectList || useHV; }
3138

3239
O2ParamDef(StatusMapCreatorParam, "MCHStatusMap");
3340
};
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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+
#include <algorithm>
13+
#include <map>
14+
15+
#include "MCHStatus/HVStatusCreator.h"
16+
17+
#include "MCHConditions/DCSAliases.h"
18+
#include "MCHConditions/DetectionElement.h"
19+
#include "MCHGlobalMapping/Mapper.h"
20+
#include "MCHStatus/StatusMap.h"
21+
#include "MCHStatus/StatusMapCreatorParam.h"
22+
23+
using DPMAP2 = std::unordered_map<std::string, std::map<uint64_t, double>>;
24+
25+
/// Converts DCS data point value to double HV value
26+
double dpConverter(o2::dcs::DataPointValue v)
27+
{
28+
union Converter {
29+
uint64_t raw_data;
30+
double value;
31+
} converter;
32+
converter.raw_data = v.payload_pt1;
33+
return converter.value;
34+
};
35+
36+
/// Decode the DCS DPMAP to be processed for HV issues
37+
DPMAP2 decodeDPMAP(const o2::mch::HVStatusCreator::DPMAP& dpMap)
38+
{
39+
DPMAP2 dpsMapPerAlias{};
40+
41+
auto timeMargin = o2::mch::StatusMapCreatorParam::Instance().timeMargin;
42+
43+
for (const auto& [dpId, dpsHV] : dpMap) {
44+
std::string alias = dpId.get_alias();
45+
46+
if (alias.find("vMon") != std::string::npos && o2::mch::dcs::isValid(alias)) {
47+
auto& dps2 = dpsMapPerAlias[alias];
48+
49+
// copy first point to the beginning of time + margin (will be subtracted later on)
50+
dps2.emplace(timeMargin, dpConverter(dpsHV.front()));
51+
52+
for (const auto& value : dpsHV) {
53+
dps2.emplace(value.get_epoch_time(), dpConverter(value));
54+
}
55+
56+
// copy last point to the end of time - margin (will be added later on)
57+
dps2.emplace(std::numeric_limits<uint64_t>::max() - timeMargin, dpConverter(dpsHV.back()));
58+
}
59+
}
60+
61+
return dpsMapPerAlias;
62+
}
63+
64+
namespace o2::mch
65+
{
66+
67+
void HVStatusCreator::findBadHVs(const DPMAP& dpMap)
68+
{
69+
// clear current list of issues
70+
mBadHVTimeRanges.clear();
71+
72+
// decode the DCS DPMAP
73+
DPMAP2 dpsMapPerAlias = decodeDPMAP(dpMap);
74+
75+
auto minDuration = StatusMapCreatorParam::Instance().hvMinDuration;
76+
auto timeMargin = StatusMapCreatorParam::Instance().timeMargin;
77+
78+
// find list of HV issues per alias
79+
for (const auto& [alias, dpsHV] : dpsMapPerAlias) {
80+
int chamber = o2::mch::dcs::toInt(o2::mch::dcs::aliasToChamber(alias));
81+
auto chamberThreshold = StatusMapCreatorParam::Instance().hvLimits[chamber];
82+
83+
std::vector<TimeRange> hvIssuesList{};
84+
uint64_t tStart = 0;
85+
uint64_t tStop = 0;
86+
bool ongoingIssue = false;
87+
88+
for (auto [timestamp, valueHV] : dpsHV) {
89+
if (valueHV < chamberThreshold) {
90+
if (!ongoingIssue) {
91+
tStart = timestamp;
92+
tStop = tStart;
93+
ongoingIssue = true;
94+
} else {
95+
tStop = timestamp;
96+
}
97+
} else {
98+
if (ongoingIssue) {
99+
tStop = timestamp;
100+
if (tStop - tStart > minDuration) {
101+
hvIssuesList.emplace_back(tStart - timeMargin, tStop + timeMargin);
102+
}
103+
ongoingIssue = false;
104+
}
105+
}
106+
}
107+
108+
// ongoing issue at the end of the object
109+
if (ongoingIssue && tStop - tStart > minDuration) {
110+
hvIssuesList.emplace_back(tStart - timeMargin, tStop + timeMargin);
111+
}
112+
113+
// add issues for the alias if non-empty
114+
if (!hvIssuesList.empty()) {
115+
mBadHVTimeRanges.emplace(alias, hvIssuesList);
116+
}
117+
}
118+
}
119+
120+
bool HVStatusCreator::findCurrentBadHVs(uint64_t timestamp)
121+
{
122+
// list issues at the given time stamp
123+
std::set<std::string> currentBadHVs{};
124+
for (const auto& [alias, timeRanges] : mBadHVTimeRanges) {
125+
auto it = std::find_if(timeRanges.begin(), timeRanges.end(),
126+
[timestamp](const TimeRange& r) { return r.contains(timestamp); });
127+
if (it != timeRanges.end()) {
128+
currentBadHVs.emplace(alias);
129+
}
130+
}
131+
132+
// check if the list of issues has changed and update it in this case
133+
if (currentBadHVs != mCurrentBadHVs) {
134+
mCurrentBadHVs.swap(currentBadHVs);
135+
return true;
136+
}
137+
138+
return false;
139+
}
140+
141+
void HVStatusCreator::updateStatusMap(StatusMap& statusMap) const
142+
{
143+
for (const auto& alias : mCurrentBadHVs) {
144+
int deId = dcs::aliasToDetElemId(alias).value();
145+
if (deId < 500) {
146+
for (auto dsIndex : dcs::aliasToDsIndices(alias)) {
147+
statusMap.addDS(dsIndex, StatusMap::kBadHV);
148+
}
149+
} else {
150+
statusMap.addDE(deId, StatusMap::kBadHV);
151+
}
152+
}
153+
}
154+
155+
} // namespace o2::mch

0 commit comments

Comments
 (0)