Project
Loading...
Searching...
No Matches
CalibDataProcessorSpec.cxx
Go to the documentation of this file.
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
16
18
19#include <array>
20#include <vector>
21#include <gsl/gsl>
26#include "Framework/InputSpec.h"
27#include "Framework/Logger.h"
28#include "Framework/Task.h"
30#include "CCDB/CcdbObjectInfo.h"
36
37namespace of = o2::framework;
38
39namespace o2
40{
41namespace mid
42{
43
45{
46 public:
47 CalibDataProcessorDPL(const FEEIdConfig& feeIdConfig, const CrateMasks& crateMasks)
48 {
49 auto refMasks = makeDefaultMasksFromCrateConfig(feeIdConfig, crateMasks);
50 mFetToDead.setMasks(refMasks);
51 }
52
54 {
55 mMinDiff = ic.options().get<int64_t>("mid-merge-fet-bc-diff-min");
56 mMaxDiff = ic.options().get<int64_t>("mid-merge-fet-bc-diff-max");
57 }
58
60 {
61 std::array<gsl::span<const ColumnData>, 3> data;
62 std::array<gsl::span<const ROFRecord>, 3> dataRof;
63
64 std::vector<of::InputSpec> filter = {
65 {"check_data", of::ConcreteDataTypeMatcher{header::gDataOriginMID, "DATA"}, of::Lifetime::Timeframe},
66 {"check_rof", of::ConcreteDataTypeMatcher{header::gDataOriginMID, "DATAROF"}, of::Lifetime::Timeframe},
67 };
68
69 for (auto const& inputRef : of::InputRecordWalker(pc.inputs(), filter)) {
70 auto const* dh = framework::DataRefUtils::getHeader<o2::header::DataHeader*>(inputRef);
71 auto subSpecIdx = static_cast<size_t>(dh->subSpecification);
72 if (of::DataRefUtils::match(inputRef, "mid_data")) {
73 data[subSpecIdx] = pc.inputs().get<gsl::span<o2::mid::ColumnData>>(inputRef);
74 } else if (of::DataRefUtils::match(inputRef, "mid_data_rof")) {
75 dataRof[subSpecIdx] = pc.inputs().get<gsl::span<o2::mid::ROFRecord>>(inputRef);
76 }
77 }
78
79 mNoise.clear();
80 mNoiseROF.clear();
81 mDead.clear();
82 mDeadROF.clear();
83
84 if (data[1].empty()) {
85 mNoise.insert(mNoise.end(), data[0].begin(), data[0].end());
86 mNoiseROF.insert(mNoiseROF.end(), dataRof[0].begin(), dataRof[0].end());
87 } else {
88
89 mNoise.insert(mNoise.end(), data[1].begin(), data[1].end());
90 mNoiseROF.insert(mNoiseROF.end(), dataRof[1].begin(), dataRof[1].end());
91
92 mergeChannels(data[2], dataRof[2], data[0], dataRof[0]);
93 }
94
95 pc.outputs().snapshot(of::Output{header::gDataOriginMID, "NOISE", 0}, mNoise);
96 pc.outputs().snapshot(of::Output{header::gDataOriginMID, "NOISEROF", 0}, mNoiseROF);
97 pc.outputs().snapshot(of::Output{header::gDataOriginMID, "DEAD", 0}, mDead);
98 pc.outputs().snapshot(of::Output{header::gDataOriginMID, "DEADROF", 0}, mDeadROF);
99 }
100
101 private:
102 FetToDead mFetToDead{};
103 std::vector<ColumnData> mNoise;
104 std::vector<ROFRecord> mNoiseROF;
105 std::vector<ColumnData> mDead;
106 std::vector<ROFRecord> mDeadROF;
107 int64_t mMinDiff = -1;
108 int64_t mMaxDiff = 1;
109
110 void mergeChannels(gsl::span<const ColumnData> fetData, gsl::span<const ROFRecord> fetDataRof, gsl::span<const ColumnData> selfTrigData, gsl::span<const ROFRecord> selfTrigDataRof)
111 {
112 // This method selects the self-triggered events that are close in time with a FET event and merges them with the fet event.
113 // This is needed since the detector answer is not perfectly aligned in time.
114 // Since calibration runs occur with no beam, all other self-triggers are actually noise.
115
116 ColumnDataHandler handler;
117 // The FET data can be split into different BCs.
118 // Try to merge the expected FET data with the data in the close BCs
119 // which are probably badly tagged FET data
120 auto auxRofIt = selfTrigDataRof.begin();
121 // Loop on FET ROF
122 for (auto& rof : fetDataRof) {
123 handler.clear();
124 auto eventFetData = fetData.subspan(rof.firstEntry, rof.nEntries);
125 handler.merge(eventFetData);
126 for (; auxRofIt != selfTrigDataRof.end(); ++auxRofIt) {
127 auto bcDiff = auxRofIt->interactionRecord.differenceInBC(rof.interactionRecord);
128 if (bcDiff > mMaxDiff) {
129 // ROFs are time ordered. If the difference is larger than the maximum difference for merging,
130 // it means that the auxRofIt is in the future.
131 // We break and compare it to the next rof.
132 break;
133 } else if (bcDiff >= mMinDiff) {
134 // With the previous condition, this implies mMinDiff <= bcDiff <= mMaxDiff
135 auto auxFet = selfTrigData.subspan(auxRofIt->firstEntry, auxRofIt->nEntries);
136 handler.merge(auxFet);
137 } else {
138 // If bcDiff is < mMinDiff, it means that the auxRofIt is too much in the past
139 // So this was actually noise
140 mNoise.insert(mNoise.end(), selfTrigData.begin() + auxRofIt->firstEntry, selfTrigData.begin() + auxRofIt->getEndIndex());
141 mNoiseROF.emplace_back(*auxRofIt);
142 }
143 }
144 auto eventDeadChannels = mFetToDead.process(handler.getMerged());
145 mDeadROF.emplace_back(rof.interactionRecord, rof.eventType, mDead.size(), eventDeadChannels.size());
146 mDead.insert(mDead.end(), eventDeadChannels.begin(), eventDeadChannels.end());
147 }
148 }
149};
150
152{
153 std::vector<of::InputSpec> inputSpecs;
154 inputSpecs.emplace_back("mid_data", of::ConcreteDataTypeMatcher(header::gDataOriginMID, "DATA"), of::Lifetime::Timeframe);
155 inputSpecs.emplace_back("mid_data_rof", of::ConcreteDataTypeMatcher(header::gDataOriginMID, "DATAROF"), of::Lifetime::Timeframe);
156
157 std::vector<of::OutputSpec> outputSpecs;
158 outputSpecs.emplace_back(header::gDataOriginMID, "NOISE", 0);
159 outputSpecs.emplace_back(header::gDataOriginMID, "NOISEROF", 0);
160 outputSpecs.emplace_back(header::gDataOriginMID, "DEAD", 0);
161 outputSpecs.emplace_back(header::gDataOriginMID, "DEADROF", 0);
162
164 "MIDFetToDead",
165 {inputSpecs},
166 {outputSpecs},
167 of::AlgorithmSpec{of::adaptFromTask<o2::mid::CalibDataProcessorDPL>(feeIdConfig, crateMasks)},
169 {"mid-merge-fet-bc-diff-min", of::VariantType::Int, -1, {"Merge to FET if BC-BC_FET >= this value"}},
170 {"mid-merge-fet-bc-diff-max", of::VariantType::Int, 1, {"Merge to FET if BC-BC_FET <= this value"}}}};
171}
172} // namespace mid
173} // namespace o2
Device to convert the calibration data into a list of bad channel candidates.
MID digits handler.
Strip pattern (aka digits)
Utils and constants for calibration and related workflows.
Class to convert the FEE test event into dead channels.
A helper class to iteratate over all parts of all input routes.
Definition of the MID event record.
Function to produce the MID masks.
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
Definition InitContext.h:33
A helper class to iteratate over all parts of all input routes.
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
void run(of::ProcessingContext &pc)
CalibDataProcessorDPL(const FEEIdConfig &feeIdConfig, const CrateMasks &crateMasks)
std::vector< ColumnData > process(gsl::span< const ColumnData > fetData)
Definition FetToDead.cxx:51
void setMasks(const std::vector< ColumnData > &masks)
Sets the masks.
Definition FetToDead.h:44
GLboolean * data
Definition glcorearb.h:298
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
constexpr o2::header::DataOrigin gDataOriginMID
Definition DataHeader.h:573
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
framework::DataProcessorSpec getCalibDataProcessorSpec(const FEEIdConfig &feeIdConfig, const CrateMasks &crateMasks)
std::vector< ColumnData > makeDefaultMasksFromCrateConfig(const FEEIdConfig &feeIdConfig=FEEIdConfig(), const CrateMasks &crateMasks=CrateMasks())
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void empty(int)