19#include <fairmq/Tools.h>
20#include <fairlogger/Logger.h>
43 for (
auto i = 0;
i < SNDEs;
i++) {
58 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
59 for (
int iPlane = 0; iPlane < 2; ++iPlane) {
60 mPreClusters[iDE][iPlane].reserve(100);
78 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
89 DetectionElement&
de(*(mDEs[deIndex]));
92 for (
int iPlane = 0; iPlane < 2; ++iPlane) {
95 mNPreClusters[deIndex][iPlane] = 0;
98 for (
int iFiredPad = 0; iFiredPad <
de.nFiredPads[iPlane]; ++iFiredPad) {
100 pad = &
de.mapping->pads[
de.firedPads[iPlane][iFiredPad]];
106 de.nFiredPads[iPlane] = 0;
110 de.nOrderedPads[0] = 0;
111 de.nOrderedPads[1] = 0;
118 for (
const auto& digit :
digits) {
128 int deIndex = mDEIndices.at(digit.
getDetID());
133 throw out_of_range(
"invalid pad index");
137 int iPlane = (iPad <
de.mapping->nPads[0]) ? 0 : 1;
140 if (
de.mapping->pads[iPad].useMe) {
146 uint16_t iDigit =
de.nFiredPads[0] +
de.nFiredPads[1];
147 if (iDigit >=
de.digits.size()) {
148 de.digits.push_back(&digit);
150 de.digits[iDigit] = &digit;
152 de.mapping->pads[iPad].iDigit = iDigit;
153 de.mapping->pads[iPad].useMe =
true;
156 if (
de.nFiredPads[iPlane] <
de.firedPads[iPlane].size()) {
157 de.firedPads[iPlane][
de.nFiredPads[iPlane]] = iPad;
159 de.firedPads[iPlane].push_back(iPad);
161 ++
de.nFiredPads[iPlane];
169 static constexpr double maxOccupancy = 0.2;
170 static constexpr int maxHighOccupancyDE = 4;
172 if (!perDE && !perEvent) {
178 int nRemovedDigits(0);
179 int nHighOccupancyDE(0);
180 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
182 nDigits +=
de.nFiredPads[0] +
de.nFiredPads[1];
183 if (
de.mapping->uid >= 500 &&
184 (
de.nFiredPads[0] > maxOccupancy *
de.mapping->nPads[0] ||
185 de.nFiredPads[1] > maxOccupancy *
de.mapping->nPads[1])) {
188 nRemovedDigits +=
de.nFiredPads[0] +
de.nFiredPads[1];
195 if (perEvent && nHighOccupancyDE > maxHighOccupancyDE) {
196 nRemovedDigits = nDigits;
200 return nRemovedDigits;
207 preClusterizeRecursive();
208 return mergePreClusters();
218 for (
int iDE = 0, nDEs = SNDEs; iDE < nDEs; ++iDE) {
221 if (
de.nOrderedPads[1] == 0) {
225 for (
int iPlane = 0; iPlane < 2; ++iPlane) {
226 for (
int iCluster = 0; iCluster < mNPreClusters[iDE][iPlane]; ++iCluster) {
228 PreCluster* cluster = mPreClusters[iDE][iPlane][iCluster].get();
229 if (!cluster->storeMe) {
234 uint32_t firstDigit =
digits.size();
235 uint32_t nDigits = cluster->lastPad - cluster->firstPad + 1;
236 preClusters.push_back({firstDigit, nDigits});
239 for (uint16_t iOrderedPad = cluster->firstPad; iOrderedPad <= cluster->lastPad; ++iOrderedPad) {
240 digits.emplace_back(*
de.digits[
de.mapping->pads[
de.orderedPads[1][iOrderedPad]].iDigit]);
248void PreClusterFinder::preClusterizeRecursive()
256 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
258 DetectionElement&
de(*(mDEs[iDE]));
261 for (
int iPlane = 0; iPlane < 2; ++iPlane) {
264 for (
int iFiredPad = 0; iFiredPad <
de.nFiredPads[iPlane]; ++iFiredPad) {
266 iPad =
de.firedPads[iPlane][iFiredPad];
268 if (
de.mapping->pads[iPad].useMe) {
271 if (mNPreClusters[iDE][iPlane] >= mPreClusters[iDE][iPlane].
size()) {
272 mPreClusters[iDE][iPlane].push_back(std::make_unique<PreCluster>());
276 cluster = mPreClusters[iDE][iPlane][mNPreClusters[iDE][iPlane]].get();
277 ++mNPreClusters[iDE][iPlane];
280 cluster->area[0][0] = 1.e6;
281 cluster->area[0][1] = -1.e6;
282 cluster->area[1][0] = 1.e6;
283 cluster->area[1][1] = -1.e6;
284 cluster->useMe =
true;
285 cluster->storeMe =
false;
288 cluster->firstPad =
de.nOrderedPads[0];
289 addPad(
de, iPad, *cluster);
297void PreClusterFinder::addPad(DetectionElement&
de, uint16_t iPad, PreCluster& cluster)
301 Mapping::MpPad* pads(
de.mapping->pads.get());
304 Mapping::MpPad& pad(pads[iPad]);
305 if (
de.nOrderedPads[0] <
de.orderedPads[0].size()) {
306 de.orderedPads[0][
de.nOrderedPads[0]] = iPad;
308 de.orderedPads[0].push_back(iPad);
310 cluster.lastPad =
de.nOrderedPads[0];
311 ++
de.nOrderedPads[0];
312 if (pad.area[0][0] < cluster.area[0][0]) {
313 cluster.area[0][0] = pad.area[0][0];
315 if (pad.area[0][1] > cluster.area[0][1]) {
316 cluster.area[0][1] = pad.area[0][1];
318 if (pad.area[1][0] < cluster.area[1][0]) {
319 cluster.area[1][0] = pad.area[1][0];
321 if (pad.area[1][1] > cluster.area[1][1]) {
322 cluster.area[1][1] = pad.area[1][1];
328 for (
int iNeighbour = 0; iNeighbour < pad.nNeighbours; ++iNeighbour) {
330 if (pads[pad.neighbours[iNeighbour]].useMe) {
333 addPad(
de, pad.neighbours[iNeighbour], cluster);
339int PreClusterFinder::mergePreClusters()
344 PreCluster* cluster(
nullptr);
348 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
350 DetectionElement&
de(*(mDEs[iDE]));
353 for (
int iCluster = 0; iCluster < mNPreClusters[iDE][0]; ++iCluster) {
355 if (!mPreClusters[iDE][0][iCluster]->useMe) {
359 cluster = mPreClusters[iDE][0][iCluster].get();
360 cluster->useMe =
false;
363 PreCluster* mergedCluster(
nullptr);
364 mergePreClusters(*cluster, mPreClusters[iDE], mNPreClusters[iDE],
de, 1, mergedCluster);
367 if (!mergedCluster) {
368 mergedCluster = usePreClusters(cluster,
de);
370 mergePreClusters(*mergedCluster, *cluster,
de);
377 for (
int iCluster = 0; iCluster < mNPreClusters[iDE][1]; ++iCluster) {
379 if (!mPreClusters[iDE][1][iCluster]->useMe) {
384 usePreClusters(mPreClusters[iDE][1][iCluster].
get(),
de);
394void PreClusterFinder::mergePreClusters(PreCluster& cluster, std::vector<std::unique_ptr<PreCluster>> preClusters[2],
395 int nPreClusters[2], DetectionElement&
de,
int iPlane,
396 PreCluster*& mergedCluster)
401 constexpr float overlapPrecision = -1.e-4;
403 PreCluster* cluster2(
nullptr);
406 for (
int iCluster = 0; iCluster < nPreClusters[iPlane]; ++iCluster) {
408 if (!preClusters[iPlane][iCluster]->useMe) {
414 areOverlapping(cluster, *cluster2,
de, overlapPrecision)) {
416 cluster2->useMe =
false;
419 mergePreClusters(*cluster2, preClusters, nPreClusters,
de, (iPlane + 1) % 2, mergedCluster);
422 if (!mergedCluster) {
423 mergedCluster = usePreClusters(cluster2,
de);
425 mergePreClusters(*mergedCluster, *cluster2,
de);
432PreClusterFinder::PreCluster* PreClusterFinder::usePreClusters(PreCluster* cluster, DetectionElement&
de)
436 uint16_t firstPad =
de.nOrderedPads[1];
439 for (
int iOrderPad = cluster->firstPad; iOrderPad <= cluster->lastPad; ++iOrderPad) {
441 if (
de.nOrderedPads[1] <
de.orderedPads[1].size()) {
442 de.orderedPads[1][
de.nOrderedPads[1]] =
de.orderedPads[0][iOrderPad];
444 de.orderedPads[1].push_back(
de.orderedPads[0][iOrderPad]);
447 ++
de.nOrderedPads[1];
450 cluster->firstPad = firstPad;
451 cluster->lastPad =
de.nOrderedPads[1] - 1;
453 cluster->storeMe =
true;
459void PreClusterFinder::mergePreClusters(PreCluster& cluster1, PreCluster& cluster2, DetectionElement&
de)
464 for (
int iOrderPad = cluster2.firstPad; iOrderPad <= cluster2.lastPad; ++iOrderPad) {
466 if (
de.nOrderedPads[1] <
de.orderedPads[1].size()) {
467 de.orderedPads[1][
de.nOrderedPads[1]] =
de.orderedPads[0][iOrderPad];
469 de.orderedPads[1].push_back(
de.orderedPads[0][iOrderPad]);
472 ++
de.nOrderedPads[1];
475 cluster1.lastPad =
de.nOrderedPads[1] - 1;
479bool PreClusterFinder::areOverlapping(PreCluster& cluster1, PreCluster& cluster2, DetectionElement&
de,
float precision)
485 for (
int iOrderPad1 = cluster1.firstPad; iOrderPad1 <= cluster1.lastPad; ++iOrderPad1) {
488 for (
int iOrderPad2 = cluster2.firstPad; iOrderPad2 <= cluster2.lastPad; ++iOrderPad2) {
491 de.mapping->pads[
de.orderedPads[0][iOrderPad2]].area,
precision)) {
501void PreClusterFinder::createMapping()
505 auto tStart = std::chrono::high_resolution_clock::now();
509 if (mpDEs.size() != SNDEs) {
513 mDEIndices.reserve(SNDEs);
515 for (
int iDE = 0; iDE < SNDEs; ++iDE) {
517 DetectionElement&
de(*(mDEs[iDE]));
519 de.mapping = std::move(mpDEs[iDE]);
521 mDEIndices.emplace(
de.mapping->uid, iDE);
523 int initialSize = (
de.mapping->nPads[0] / 10 +
de.mapping->nPads[1] / 10);
525 de.digits.reserve(initialSize);
526 de.nOrderedPads[0] = 0;
527 de.orderedPads[0].reserve(initialSize);
528 de.nOrderedPads[1] = 0;
529 de.orderedPads[1].reserve(initialSize);
531 for (
int iPlane = 0; iPlane < 2; ++iPlane) {
532 de.nFiredPads[iPlane] = 0;
533 de.firedPads[iPlane].reserve(
de.mapping->nPads[iPlane] / 10);
537 auto tEnd = std::chrono::high_resolution_clock::now();
538 LOG(info) <<
"create mapping in: " << std::chrono::duration<double, std::milli>(tEnd - tStart).count() <<
" ms";
definition of the MCH processing errors
MCH digit implementation.
void add(ErrorType errorType, uint32_t id0, uint32_t id1, uint64_t n=1)
static std::vector< std::unique_ptr< MpDE > > createMapping()
static bool areOverlapping(float area1[2][2], float area2[2][2], float precision)
void loadDigits(gsl::span< const Digit > digits)
void loadDigit(const Digit &digit)
int discardHighOccupancy(bool perDE, bool perEvent)
void getPreClusters(std::vector< o2::mch::PreCluster > &preClusters, std::vector< Digit > &digits)
GLenum GLint GLint * precision
RuntimeErrorRef runtime_error(const char *)
@ PreClustering_MultipleDigitsInSamePad
gsl::span< const PreCluster > preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size())
Defining DataPointCompositeObject explicitly as copiable.
std::vector< const Digit * > digits
std::vector< uint16_t > orderedPads[2]
std::vector< uint16_t > firedPads[2]
std::unique_ptr< Mapping::MpDE > mapping
precluster minimal structure
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits