Project
Loading...
Searching...
No Matches
ClusterQCSpec.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
15
16#include <algorithm>
17#include <iterator>
18#include <vector>
19#include <memory>
20#include <random>
21
22// o2 includes
23#include "TPCQC/Clusters.h"
25#include "Framework/Logger.h"
26#include "Framework/Task.h"
31
33
34using namespace o2::framework;
35using namespace o2::tpc::constants;
36
37namespace o2::tpc
38{
39
40class ClusterQCDevice : public Task
41{
42 public:
43 void init(framework::InitContext& ic) final;
44 void run(ProcessingContext& pc) final;
45 void endOfStream(EndOfStreamContext& eos) final;
46
47 private:
48 void sendOutput(DataAllocator& output);
49 void endInterval();
50
51 unsigned int mProcessEveryNthTF{1};
52 uint32_t mTFCounter{0};
53 uint32_t mFirstTF{0};
54 uint32_t mLastTF{0};
55 uint64_t mFirstCreation{0};
56 uint64_t mLastCreation{0};
57 uint32_t mRunNumber{0};
58 int mMaxTFPerFile{-1};
59 std::string mOutputFileName;
60 bool mNewInterval{true};
61 qc::Clusters mClusterQC;
62};
63
65{
66 mOutputFileName = ic.options().get<std::string>("output-file-name");
67 mMaxTFPerFile = ic.options().get<int>("max-tf-per-file");
68
69 mProcessEveryNthTF = ic.options().get<int>("processEveryNthTF");
70 if (mProcessEveryNthTF <= 0) {
71 mProcessEveryNthTF = 1;
72 }
73
74 if (mProcessEveryNthTF > 1) {
75 std::mt19937 rng(std::time(nullptr));
76 std::uniform_int_distribution<std::mt19937::result_type> dist(1, mProcessEveryNthTF);
77 mTFCounter = dist(rng);
78 LOGP(info, "Skipping first {} TFs", mProcessEveryNthTF - mTFCounter);
79 }
80}
81
83{
84 if (mTFCounter++ % mProcessEveryNthTF) {
85 const auto currentTF = processing_helpers::getCurrentTF(pc);
86 LOGP(info, "Skipping TF {}", currentTF);
87 return;
88 }
89
90 if (mNewInterval) {
91 mRunNumber = processing_helpers::getRunNumber(pc);
93 mFirstCreation = processing_helpers::getCreationTime(pc);
94 mNewInterval = false;
95 }
96
98 mLastCreation = processing_helpers::getCreationTime(pc);
99
100 const auto& clustersInputs = getWorkflowTPCInput(pc);
101 const auto& clusterIndex = clustersInputs->clusterIndex;
102
103 for (int sector = 0; sector < MAXSECTOR; ++sector) {
104 for (int padrow = 0; padrow < MAXGLOBALPADROW; ++padrow) {
105
106 for (size_t icl = 0; icl < clusterIndex.nClusters[sector][padrow]; ++icl) {
107 const auto& cl = clusterIndex.clusters[sector][padrow][icl];
108 mClusterQC.processCluster(cl, sector, padrow);
109 }
110 }
111 }
112
113 mClusterQC.endTF();
114 if ((mMaxTFPerFile > 0) && (mClusterQC.getProcessedTFs() % mMaxTFPerFile) == 0) {
115 endInterval();
116 }
117}
118
119void ClusterQCDevice::endInterval()
120{
121 if (mClusterQC.getProcessedTFs() == 0) {
122 return;
123 }
124
125 mClusterQC.analyse();
126 LOGP(info, "End interval for run: {}, TFs: {} - {}, creation: {} - {}, processed TFs: {}",
127 mRunNumber, mFirstTF, mLastTF, mFirstCreation, mLastCreation, mClusterQC.getProcessedTFs());
128
129 const auto outputFileName = fmt::format(fmt::runtime(mOutputFileName), fmt::arg("run", mRunNumber),
130 fmt::arg("firstTF", mFirstTF), fmt::arg("lastTF", mLastTF),
131 fmt::arg("firstCreation", mFirstCreation), fmt::arg("lastCreation", mLastCreation));
132 std::unique_ptr<TFile> f(TFile::Open(outputFileName.data(), "recreate"));
133 f->WriteObject(&mClusterQC, "ClusterQC");
134 f->Close();
135
136 mClusterQC.reset();
137 mRunNumber = mFirstTF = mLastTF = mFirstCreation = mLastCreation = 0;
138 mNewInterval = true;
139}
140
142{
143 LOG(info) << "Finalizig Cluster QC filter";
144 endInterval();
145}
146
148{
149 std::vector<InputSpec> inputs;
150 std::vector<OutputSpec> outputs;
151
152 inputs.emplace_back("clusTPC", ConcreteDataTypeMatcher{"TPC", "CLUSTERNATIVE"}, Lifetime::Timeframe);
153
154 return DataProcessorSpec{
155 "tpc-cluster-qc",
156 inputs,
157 outputs,
158 adaptFromTask<ClusterQCDevice>(),
159 Options{
160 {"output-file-name", VariantType::String, "clusterQC_{run}_{firstCreation}_{lastCreation}_{firstTF}_{lastTF}.root", {"name of the output file"}},
161 {"processEveryNthTF", VariantType::Int, 1, {"Using only a fraction of the data: 1: Use every TF, 10: Process only every tenth TF."}},
162 {"max-tf-per-file", VariantType::Int, -1, {"Number of TFs to process before a file is written. -1 = all"}},
163 }};
164}
165
166} // namespace o2::tpc
Workflow to run clusterQC.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
uint32_t padrow
Definition RawData.h:5
Helper class to obtain TPC clusters / digits / labels from DPL.
ConfigParamRegistry const & options()
Definition InitContext.h:33
void endOfStream(EndOfStreamContext &eos) final
void init(framework::InitContext &ic) final
void run(ProcessingContext &pc) final
size_t getProcessedTFs()
Definition Clusters.h:80
bool processCluster(const T &cluster, const o2::tpc::Sector sector, const int row)
Definition Clusters.cxx:34
GLdouble f
Definition glcorearb.h:310
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
constexpr int MAXSECTOR
Definition Constants.h:28
constexpr int MAXGLOBALPADROW
Definition Constants.h:34
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
uint64_t getRunNumber(o2::framework::ProcessingContext &pc)
uint64_t getCreationTime(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
o2::framework::DataProcessorSpec getClusterQCSpec()
create a processor speco2::framework::DataProcessorSpec getClusterQCSpec();
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"