43 mClusterer = std::make_unique<o2::itsmft::Clusterer>();
45 mUseClusterDictionary = !ic.
options().
get<
bool>(
"ignore-cluster-dictionary");
47 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
48 mDetName = Origin.as<std::string>();
51 for (
int iLayer = 0; iLayer < NLayers; ++iLayer) {
52 mFilter.emplace_back(
"digits", Origin,
"DIGITS", iLayer, Lifetime::Timeframe);
53 mFilter.emplace_back(
"ROframe", Origin,
"DIGITSROF", iLayer, Lifetime::Timeframe);
55 mFilter.emplace_back(
"labels", Origin,
"DIGITSMCTR", iLayer, Lifetime::Timeframe);
56 mFilter.emplace_back(
"MC2ROframes", Origin,
"DIGITSMC2ROF", iLayer, Lifetime::Timeframe);
64 updateTimeDependentParams(pc);
67 std::array<gsl::span<const o2::itsmft::Digit>, NLayers>
digits;
68 std::array<gsl::span<const o2::itsmft::ROFRecord>, NLayers> rofs;
69 std::array<gsl::span<const char>, NLayers> labelsbuffer;
70 std::array<gsl::span<const o2::itsmft::MC2ROFRecord>, NLayers> mc2rofs;
72 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
77 rofs[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
ref);
80 labelsbuffer[dh->subSpecification] = pc.
inputs().
get<gsl::span<char>>(
ref);
83 mc2rofs[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::MC2ROFRecord>>(
ref);
96 for (uint32_t iLayer{0}; iLayer < NLayers; ++iLayer) {
99 LOG(info) << mDetName <<
"Clusterer:" <<
layer <<
" pulled " <<
digits[iLayer].size() <<
" digits, in " << rofs[iLayer].size() <<
" RO frames";
101 mClusterer->setMaxROFDepthToSquash(mClusterer->getMaxROFDepthToSquash(
layer));
110 LOG(info) << mDetName <<
"Clusterer:" <<
layer <<
" pulled " <<
labels.getNElements() <<
" labels ";
114 std::vector<o2::itsmft::CompClusterExt> clusCompVec;
115 std::vector<o2::itsmft::ROFRecord> clusROFVec;
116 std::vector<unsigned char> clusPattVec;
118 std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> clusterLabels;
120 clusterLabels = std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>();
122 mClusterer->process(mNThreads, reader, &clusCompVec, &clusPattVec, &clusROFVec, clusterLabels.get());
125 size_t nROFs = clusROFVec.size();
130 std::vector<o2::itsmft::ROFRecord> expClusRofVec(nROFsTF);
131 for (
int iROF{0}; iROF < nROFsTF; ++iROF) {
132 auto& rof = expClusRofVec[iROF];
137 rof.setROFrame(iROF);
139 rof.setFirstEntry(-1);
141 uint32_t prevEntry{0};
142 for (
const auto& rof : clusROFVec) {
143 const auto&
ir = rof.getBCData();
145 LOGP(warn,
"Discard ROF {} preceding TF 1st orbit {}, layer:{}",
ir.
asString(), firstTForbit, iLayer);
148 const auto irToFirst =
ir - firstIR;
149 const long irROF = irToFirst.
toLong() / par.getROFLengthInBC(iLayer);
150 if (irROF >= nROFsTF) {
151 LOGP(warn,
"Discard ROF {} exceding TF orbit range, layer:{}",
ir.
asString(), iLayer);
154 auto& expROF = expClusRofVec[irROF];
155 if (expROF.getNEntries() == 0) {
156 expROF.setFirstEntry(rof.getFirstEntry());
157 expROF.setNEntries(rof.getNEntries());
159 if (expROF.getNEntries() < rof.getNEntries()) {
160 LOGP(warn,
"Repeating ROF {} with {} clusters, prefer to already processed instance with {} clusters", rof.asString(), rof.getNEntries(), expROF.getNEntries());
161 expROF.setFirstEntry(rof.getFirstEntry());
162 expROF.setNEntries(rof.getNEntries());
164 LOGP(warn,
"Repeating ROF {} with {} clusters, discard preferring already processed instance with {} clusters", rof.asString(), rof.getNEntries(), expROF.getNEntries());
169 for (
auto& rof : expClusRofVec) {
170 if (rof.getFirstEntry() < 0) {
171 rof.setFirstEntry(prevLast);
173 prevLast = rof.getFirstEntry() + rof.getNEntries();
175 nROFs = expClusRofVec.size();
185 std::vector<o2::itsmft::MC2ROFRecord> clusterMC2ROframes(mc2rofs[iLayer].
size());
186 for (
int i = mc2rofs[iLayer].
size();
i--;) {
187 clusterMC2ROframes[
i] = mc2rofs[iLayer][
i];
196 LOG(info) << mDetName <<
"Clusterer:" <<
layer <<
" pushed " << clusCompVec.size() <<
" clusters, in " << nROFs <<
" RO frames in " <<
sw.RealTime() <<
" s";
199 LOG(info) << mDetName <<
"Clusterer produced " <<
nClusters <<
" clusters";
207 static bool initOnceDone =
false;
217 if (clParams.maxBCDiffToMaskBias > 0 && clParams.maxBCDiffToSquashBias > 0) {
218 LOGP(fatal,
"maxBCDiffToMaskBias = {} and maxBCDiffToSquashBias = {} cannot be set at the same time. Either set masking or squashing with a BCDiff > 0", clParams.maxBCDiffToMaskBias, clParams.maxBCDiffToSquashBias);
220 mClusterer->setDropHugeClusters(clParams.dropHugeClusters);
221 auto nbc = clParams.maxBCDiffToMaskBias;
223 mClusterer->setMaxBCSeparationToMask(nbc);
224 mClusterer->setMaxRowColDiffToMask(clParams.maxRowColDiffToMask);
227 mClusterer->setMaxBCSeparationToSquash(rofBC + clParams.maxBCDiffToSquashBias);
228 int nROFsToSquash = 0;
229 if (clParams.maxSOTMUS > 0 && rofBC > 0) {
232 mClusterer->setMaxROFDepthToSquash(nROFsToSquash);
234 if (mClusterer->isContinuousReadOut()) {
235 for (
int iLayer{0}; iLayer < NLayers; ++iLayer) {
236 mClusterer->addMaxBCSeparationToSquash(alpParams.getROFLengthInBC(iLayer) + clParams.getMaxBCDiffToSquashBias(iLayer));
241 mClusterer->print(
false);
254 LOG(info) <<
"cluster dictionary updated" << (!mUseClusterDictionary ?
" but its using is disabled" :
"");
255 if (mUseClusterDictionary) {
262 LOG(info) <<
"Alpide param updated";
264 par.printKeyValues();
268 LOG(info) <<
"Cluster param updated";
270 par.printKeyValues();
281 std::vector<InputSpec> inputs;
283 for (uint32_t iLayer = 0; iLayer < nLayers; ++iLayer) {
284 inputs.emplace_back(
"digits", Origin,
"DIGITS", iLayer, Lifetime::Timeframe);
285 inputs.emplace_back(
"ROframes", Origin,
"DIGITSROF", iLayer, Lifetime::Timeframe);
287 inputs.emplace_back(
"labels", Origin,
"DIGITSMCTR", iLayer, Lifetime::Timeframe);
288 inputs.emplace_back(
"MC2ROframes", Origin,
"DIGITSMC2ROF", iLayer, Lifetime::Timeframe);
291 inputs.emplace_back(
"cldict", Origin,
"CLUSDICT", 0, Lifetime::Condition,
ccdbParamSpec(
Origin.as<std::string>() +
"/Calib/ClusterDictionary"));
292 inputs.emplace_back(
"cluspar", Origin,
"CLUSPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
Origin.as<std::string>() +
"/Config/ClustererParam"));
293 inputs.emplace_back(
"alppar", Origin,
"ALPIDEPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
Origin.as<std::string>() +
"/Config/AlpideParam"));
294 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
302 std::vector<OutputSpec> outputs;
303 for (uint32_t iLayer = 0; iLayer <
nLayers; ++iLayer) {
304 outputs.emplace_back(Origin,
"COMPCLUSTERS", iLayer, Lifetime::Timeframe);
305 outputs.emplace_back(Origin,
"PATTERNS", iLayer, Lifetime::Timeframe);
306 outputs.emplace_back(Origin,
"CLUSTERSROF", iLayer, Lifetime::Timeframe);
308 outputs.emplace_back(Origin,
"CLUSTERSMCTR", iLayer, Lifetime::Timeframe);
309 outputs.emplace_back(Origin,
"CLUSTERSMC2ROF", iLayer, Lifetime::Timeframe);
318 {
"ignore-cluster-dictionary", VariantType::Bool,
false, {
"do not use cluster dictionary, always store explicit patterns"}},
319 {
"nthreads", VariantType::Int, 1, {
"Number of clustering threads"}}}};
325 return getClustererSpec<o2::detectors::DetID::ITS>(useMC);
330 return getClustererSpec<o2::detectors::DetID::MFT>(useMC);
std::vector< std::string > labels
Definition of the ITS/MFT clusterer settings.
Definition of the ITSMFT compact cluster.
A const (ready only) version of MCTruthContainer.
Definition of the Names Generator class.
Definition of the GeometryManager class.
Definition of the Alpide pixel reader for MC digits processing.
Header of the General Run Parameters object.
Header to collect LHC related constants.
void checkUpdates(o2::framework::ProcessingContext &pc)
static int getNHBFPerTF()
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static const DPLAlpideParam< N > & Instance()
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr int getNChips()
number of chips per barrel
static constexpr Int_t getNChips()
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void setDigitsMCTruth(const o2::dataformats::ConstMCTruthContainerView< o2::MCCompLabel > *m)
void setDigits(const gsl::span< const o2::itsmft::Digit > a)
void setSquashingDist(const int16_t v)
void setMaxBCSeparationToSquash(int n)
void setMC2ROFRecords(const gsl::span< const o2::itsmft::MC2ROFRecord > a)
void setROFRecords(const gsl::span< const o2::itsmft::ROFRecord > a)
void setSquashingDepth(const int16_t v)
GLenum GLuint GLint GLint layer
constexpr o2::header::DataOrigin gDataOriginMFT
constexpr o2::header::DataOrigin gDataOriginITS
constexpr double LHCBunchSpacingMUS
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
AlgorithmSpec adaptFromTask(Args &&... args)
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
framework::DataProcessorSpec getMFTClustererSpec(bool useMC)
framework::DataProcessorSpec getITSClustererSpec(bool useMC)
std::string asString() const
static bool match(DataRef const &ref, const char *binding)
static constexpr int getNLayers()
static constexpr bool supportsStaggering() noexcept
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits