61 static constexpr int DoGEM = 0x0002;
71 return (
mode & selectedMode);
99 void saveStatistics(uint32_t
orbit, uint16_t bunchCrossing, uint32_t iPreCluster, uint16_t nPads, uint16_t nbrClusters, uint16_t DEId,
double duration)
101 statStream << iPreCluster <<
" " << bunchCrossing <<
" " <<
orbit <<
" "
102 << nPads <<
" " << nbrClusters <<
" " << DEId <<
" " << duration << std::endl;
109 LOG(info) <<
"initializing cluster finder";
111 auto config = ic.
options().
get<std::string>(
"mch-config");
112 if (!config.empty()) {
115 bool run2Config = ic.
options().
get<
bool>(
"run2-config");
119 printf(
"------------------------------------> GG Mode mode=%d\n",
mode);
122 LOG(info) <<
"initializing cluster finder";
131 mOriginalDump =
new ClusterDump(
"OrigRun2.dat", 0);
138 statStream <<
"# iPrecluster bunchCrossing orbit nPads nClusters DEId duration (in ms)" << std::endl;
142 LOG(info) <<
"Configuration";
143 LOG(info) <<
" Mode : " <<
mode;
153 mClusterFinderOriginal.
init(run2Config);
155 mClusterFinderGEM.
init(
mode, run2Config);
161 LOG(info) <<
"cluster finder duration = " << mTimeClusterFinder.count() <<
" s";
163 this->mClusterFinderOriginal.
deinit();
165 this->mClusterFinderGEM.
deinit();
168 delete mOriginalDump;
169 mOriginalDump =
nullptr;
176 LOGP(warning,
"{}", error.
asString());
179 auto stop = [
this]() {
181 LOG(info) <<
"stop GEM";
192 auto preClusterROFs = pc.
inputs().
get<gsl::span<ROFRecord>>(
"preclusterrofs");
193 auto preClusters = pc.
inputs().
get<gsl::span<PreCluster>>(
"preclusters");
202 uint32_t iPreCluster = 0;
204 clusterROFs.reserve(preClusterROFs.size());
207 for (
const auto& preClusterROF : preClusterROFs) {
213 uint16_t bCrossing = preClusterROF.getBCData().bc;
214 uint32_t
orbit = preClusterROF.getBCData().orbit;
215 std::chrono::duration<double> preClusterDuration{};
216 auto tStart = std::chrono::high_resolution_clock::now();
221 mClusterFinderOriginal.
reset();
224 mClusterFinderGEM.
reset();
227 size_t startGEMIdx = mClusterFinderGEM.
getClusters().size();
228 size_t startOriginalIdx = mClusterFinderOriginal.
getClusters().size();
229 uint16_t nbrClusters(0);
231 for (
const auto& preCluster : preClusters.subspan(preClusterROF.getFirstIdx(), preClusterROF.getNEntries())) {
232 auto tPreClusterStart = std::chrono::high_resolution_clock::now();
234 startGEMIdx = mClusterFinderGEM.
getClusters().size();
235 startOriginalIdx = mClusterFinderOriginal.
getClusters().size();
240 mClusterFinderGEM.
dumpPreCluster(mOriginalDump,
digits.subspan(preCluster.firstDigit, preCluster.nDigits), bCrossing,
orbit, iPreCluster);
243 mClusterFinderGEM.
dumpPreCluster(mGEMDump,
digits.subspan(preCluster.firstDigit, preCluster.nDigits), bCrossing,
orbit, iPreCluster);
247 mClusterFinderOriginal.
findClusters(
digits.subspan(preCluster.firstDigit, preCluster.nDigits));
248 nbrClusters = mClusterFinderOriginal.
getClusters().size() - startOriginalIdx;
251 mClusterFinderGEM.
findClusters(
digits.subspan(preCluster.firstDigit, preCluster.nDigits), bCrossing,
orbit, iPreCluster);
252 nbrClusters = mClusterFinderGEM.
getClusters().size() - startGEMIdx;
265 auto tPreClusterEnd = std::chrono::high_resolution_clock::now();
266 preClusterDuration = tPreClusterEnd - tPreClusterStart;
267 int16_t nPads = preCluster.nDigits;
268 int16_t DEId =
digits[preCluster.firstDigit].getDetID();
271 preClusterDuration = tPreClusterEnd - tPreClusterStart;
272 double dt = preClusterDuration.count();
274 dt = (dt < 1.0e-06) ? 0.0 : dt * 1000;
280 auto tEnd = std::chrono::high_resolution_clock::now();
281 mTimeClusterFinder += tEnd - tStart;
285 clusterROFs.emplace_back(preClusterROF.getBCData(),
clusters.size(), mClusterFinderGEM.
getClusters().size());
287 clusterROFs.emplace_back(preClusterROF.getBCData(),
clusters.size(), mClusterFinderOriginal.
getClusters().size());
290 writeClusters(
clusters, usedDigits);
296 clusterErrors.emplace_back(error);
298 mErrorMap.
add(errorMap);
300 LOGP(info,
"Found {:4d} clusters from {:4d} preclusters in {:2d} ROFs",
301 clusters.size(), preClusters.size(), preClusterROFs.size());
306 void writeClusters(std::vector<
Cluster, o2::pmr::polymorphic_allocator<Cluster>>&
clusters,
307 std::vector<
Digit, o2::pmr::polymorphic_allocator<Digit>>& usedDigits)
const
311 auto clusterOffset =
clusters.size();
317 auto digitOffset = usedDigits.size();
321 usedDigits.insert(usedDigits.end(), mClusterFinderOriginal.
getUsedDigits().begin(), mClusterFinderOriginal.
getUsedDigits().end());
324 for (
auto itCluster =
clusters.begin() + clusterOffset; itCluster <
clusters.end(); ++itCluster) {
325 itCluster->firstDigit += digitOffset;
329 ClusterFinderOriginal mClusterFinderOriginal{};
330 ClusterFinderGEM mClusterFinderGEM{};
332 ClusterDump* mGEMDump;
333 ClusterDump* mOriginalDump;
334 ErrorMap mErrorMap{};
335 std::chrono::duration<double> mTimeClusterFinder{};
343 Inputs{
InputSpec{
"preclusterrofs",
"MCH",
"PRECLUSTERROFS", 0, Lifetime::Timeframe},
344 InputSpec{
"preclusters",
"MCH",
"PRECLUSTERS", 0, Lifetime::Timeframe},
345 InputSpec{
"digits",
"MCH",
"PRECLUSTERDIGITS", 0, Lifetime::Timeframe}},
346 Outputs{
OutputSpec{{
"clusterrofs"},
"MCH",
"CLUSTERROFS", 0, Lifetime::Timeframe},
347 OutputSpec{{
"clusters"},
"MCH",
"CLUSTERS", 0, Lifetime::Timeframe},
348 OutputSpec{{
"clusterdigits"},
"MCH",
"CLUSTERDIGITS", 0, Lifetime::Timeframe},
349 OutputSpec{{
"clustererrors"},
"MCH",
"CLUSTERERRORS", 0, Lifetime::Timeframe}},
352 {
"mch-config", VariantType::String,
"", {
"JSON or INI file with clustering parameters"}},
353 {
"run2-config", VariantType::Bool,
false, {
"Setup for run2 data"}},
Definition of a data processor to run the GEM MLEM cluster finder.
Definition of a class to reconstruct clusters with the original MLEM algorithm.
Configurable parameters for MCH clustering.
Definition of the MCH precluster minimal structure.
static void updateFromFile(std::string const &, std::string const ¶msList="", bool unchangedOnly=false)
T get(const char *key) const
decltype(auto) make(const Output &spec, Args... args)
ServiceRegistryRef services()
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.
static constexpr int GEMOutputStream
void init(framework::InitContext &ic)
void run(framework::ProcessingContext &pc)
static constexpr char statFileName[]
void saveStatistics(uint32_t orbit, uint16_t bunchCrossing, uint32_t iPreCluster, uint16_t nPads, uint16_t nbrClusters, uint16_t DEId, double duration)
static constexpr int DumpGEM
static constexpr int DoGEM
static constexpr int DoOriginal
bool isActive(int selectedMode) const
static constexpr int TimingStats
static constexpr int DumpOriginal
void findClusters(gsl::span< const Digit > digits, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
void dumpPreCluster(ClusterDump *dumpFile, gsl::span< const Digit > digits, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
const std::vector< Cluster > & getClusters() const
return the list of reconstructed clusters
void init(int mode, bool run2Config)
void dumpClusterResults(ClusterDump *dumpFile, const std::vector< Cluster > &clusters, size_t startIdx, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
const std::vector< Digit > & getUsedDigits() const
return the list of digits used in reconstructed clusters
const std::vector< Digit > & getUsedDigits() const
return the list of digits used in reconstructed clusters
void init(bool run2Config)
void findClusters(gsl::span< const Digit > digits)
const std::vector< Cluster > & getClusters() const
return the list of reconstructed clusters
MCH digit implementation.
A container class to summarize errors encountered during processing.
void forEach(ErrorFunction f) const
void add(ErrorType errorType, uint32_t id0, uint32_t id1, uint64_t n=1)
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > Inputs
std::vector< OutputSpec > Outputs
o2::framework::DataProcessorSpec getClusterFinderGEMSpec(const char *specName)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
cluster minimal structure
std::string asString() const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters
std::vector< Digit > digits