218 if (maxDistance < 0.0) {
219 maxDistance = 9999999.;
225 double backgroundLevel = 0.0;
227 backgroundLevel =
static_cast<double>(bkgdcount) /
static_cast<double>(
m_fullBkgdCount);
233 B2DEBUG(170,
"ECLCRSplitterModule::splitConnectedRegion: nLocalMaximums = " << nLocalMaximums);
242 if (nLocalMaximums == 1) {
248 aECLShower->addRelationTo(&aCR);
251 double weightSum = 0.0;
257 const int locmaxcellid = locmaxvector[0]->getCellId();
262 double highestEnergyTimeResolution = (
m_eclCalDigits[pos])->getTimeResolution();
274 std::vector<ECLCalDigit> digits;
275 std::vector<double> weights;
276 for (
auto& neighbourId : neighbourMap->
getNeighbours(highestEnergyID)) {
283 weights.push_back(1.0);
291 aECLShower->setTheta(showerposition.
Theta());
292 aECLShower->setPhi(showerposition.
Phi());
293 aECLShower->setR(showerposition.
Mag());
296 double showerEnergy = 0.0;
301 const unsigned int nOptimal =
static_cast<unsigned int>(nOptimalVec[0]);
302 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
306 aECLShower->setNOptimalGroupIndex(nOptimalVec[1]);
307 aECLShower->setNOptimalEnergyBin(nOptimalVec[2]);
308 aECLShower->setNOptimalEnergy(energyEstimation);
311 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
312 listCrystalPairs.resize(digits.size());
314 std::vector < std::pair<double, double> > weighteddigits;
315 weighteddigits.resize(digits.size());
316 for (
unsigned int i = 0; i < digits.size(); ++i) {
317 weighteddigits.at(i) = std::make_pair((digits.at(i)).getEnergy(), weights.at(i));
318 listCrystalPairs.at(i) = std::make_pair((digits.at(i)).getCellId(), weights.at(i) * (digits.at(i)).getEnergy());
322 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
const auto & left,
const auto & right) {
323 return left.second > right.second;
325 std::vector< unsigned int> listCrystals;
327 for (
unsigned int i = 0; i < digits.size(); ++i) {
329 listCrystals.push_back(listCrystalPairs[i].first);
333 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
334 aECLShower->setListOfCrystalsForEnergy(listCrystals);
337 B2DEBUG(175,
"Shower Energy (1): " << showerEnergy);
340 showerEnergy = Belle2::ECL::computeEnergySum(digits, weights);
343 aECLShower->setEnergy(showerEnergy);
344 aECLShower->setEnergyRaw(showerEnergy);
345 aECLShower->setEnergyHighestCrystal(highestEnergy);
346 aECLShower->setTime(highestEnergyTime);
347 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
348 aECLShower->setNumberOfCrystals(weightSum);
349 aECLShower->setCentralCellId(highestEnergyID);
351 B2DEBUG(175,
"theta = " << showerposition.
Theta());
352 B2DEBUG(175,
"phi = " << showerposition.
Phi());
353 B2DEBUG(175,
"R = " << showerposition.
Mag());
354 B2DEBUG(175,
"energy = " << showerEnergy);
355 B2DEBUG(175,
"time = " << highestEnergyTime);
356 B2DEBUG(175,
"time resolution = " << highestEnergyTimeResolution);
357 B2DEBUG(175,
"neighbours = " << nNeighbours);
358 B2DEBUG(175,
"backgroundLevel = " << backgroundLevel);
361 aECLShower->setShowerId(1);
363 aECLShower->setConnectedRegionId(aCR.
getCRId());
377 std::vector<std::pair<ECLLocalMaximum, double>> lm_energy_vector;
379 const int cellid = aLocalMaximum.getCellId();
382 lm_energy_vector.push_back(std::pair<ECLLocalMaximum, double>(aLocalMaximum, digitenergy));
386 if (lm_energy_vector.size() >=
static_cast<size_t>(
m_maxSplits)) {
387 std::sort(lm_energy_vector.begin(), lm_energy_vector.end(), [](
const std::pair<ECLLocalMaximum, double>& x,
388 const std::pair<ECLLocalMaximum, double>& y) {
389 return x.second > y.second;
395 std::vector<ECLCalDigit> digits;
396 std::vector<double> weights;
397 std::map<int, B2Vector3D> centroidList;
398 std::map<int, double> centroidEnergyList;
399 std::map<int, B2Vector3D> allPoints;
400 std::map<int, std::vector < double > > weightMap;
401 std::vector < ECLCalDigit > digitVector;
404 std::map<int, B2Vector3D> localMaximumsPoints;
405 std::map<int, B2Vector3D> centroidPoints;
407 for (
auto& aLocalMaximum : lm_energy_vector) {
409 int cellid = aLocalMaximum.first.getCellId();
413 localMaximumsPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
414 centroidPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
418 bool iterateclusters =
true;
422 centroidList.clear();
423 centroidEnergyList.clear();
430 const int cellid = aCalDigit.getCellId();
433 allPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
434 digits.push_back(aCalDigit);
437 for (
const auto& digitpoint : allPoints) {
438 const int cellid = digitpoint.first;
449 double centroidShiftAverage = 0.0;
453 B2DEBUG(175,
"Iteration: #" << nIterations <<
" (of max. " <<
m_maxIterations <<
")");
455 centroidShiftAverage = 0.0;
456 if (nIterations == 0) {
457 centroidList.clear();
458 centroidEnergyList.clear();
463 for (
const auto& locmaxpoint : localMaximumsPoints) {
466 const int locmaxcellid = locmaxpoint.first;
472 if (nIterations == 0) {
475 centroidEnergyList[locmaxcellid] = 1.5 * locmaxenergy;
478 B2DEBUG(175,
"local maximum cellid: " << locmaxcellid);
482 for (
const auto& digitpoint : allPoints) {
485 const int digitcellid = digitpoint.first;
493 double distance = 0.0;
494 double distanceEnergySum = 0.0;
497 for (
const auto& centroidpoint : centroidPoints) {
500 const int centroidcellid = centroidpoint.first;
501 B2Vector3D centroidpos = centroidpoint.second;
503 double thisdistance = 0.;
506 if (nIterations == 0 and digitcellid == centroidcellid) {
509 B2Vector3D vectorDistance = ((centroidpos) - (digitpos));
510 thisdistance = vectorDistance.
Mag();
519 if ((locmaxcellid == centroidcellid) and (thisdistance < maxDistance)) {
520 distance = thisdistance;
525 if (thisdistance < maxDistance) {
527 distanceEnergySum += (thisenergy * expfactor);
533 if (distanceEnergySum > 0.0) {
535 weight = energy * expfactor / distanceEnergySum;
547 B2WARNING(
"ECLCRSplitterModule::splitConnectedRegion: Floating point glitch, weight for this digit " << weight <<
548 ", resetting it to 1.0.");
553 B2DEBUG(175,
" cellid: " << digitcellid <<
", energy: " << digitenergy <<
", weight: " << weight <<
", distance: " << distance);
554 weights.push_back(weight);
559 B2Vector3D oldCentroidPos = (centroidPoints.find(locmaxcellid))->second;
565 const double newEnergy = Belle2::ECL::computeEnergySum(digits, weights);
568 const B2Vector3D centroidShift = (oldCentroidPos - newCentroidPos);
571 centroidList[locmaxcellid] = newCentroidPos;
572 weightMap[locmaxcellid] = weights;
574 B2DEBUG(175,
"--> inserting new energy: " << newEnergy <<
" for local maximum " << locmaxcellid);
575 centroidEnergyList[locmaxcellid] = newEnergy;
576 double showerenergy = (*centroidEnergyList.find(locmaxcellid)).second /
Belle2::Unit::MeV;
577 B2DEBUG(175,
"--> new energy = " << showerenergy <<
" MeV");
580 centroidShiftAverage += centroidShift.
Mag();
583 B2DEBUG(175,
" old centroid: " << oldCentroidPos.
X() <<
" cm, " << oldCentroidPos.
Y() <<
" cm, " << oldCentroidPos.
Z() <<
585 B2DEBUG(175,
" new centroid: " << newCentroidPos.
X() <<
" cm, " << newCentroidPos.
Y() <<
" cm, " << newCentroidPos.
Z() <<
587 B2DEBUG(175,
" centroid shift: " << centroidShift.
Mag() <<
" cm");
592 centroidShiftAverage /=
static_cast<double>(nLocalMaximums);
594 B2DEBUG(175,
"--> average centroid shift: " << centroidShiftAverage <<
" cm (tolerance is " <<
m_shiftTolerance <<
" cm)");
597 for (
const auto& locmaxpoint : localMaximumsPoints) {
598 centroidPoints[locmaxpoint.first] = (centroidList.find(locmaxpoint.first))->second;
603 }
while (nIterations < m_maxIterations and centroidShiftAverage >
m_shiftTolerance);
607 std::vector<int> markfordeletion;
608 iterateclusters =
false;
609 for (
const auto& locmaxpoint : localMaximumsPoints) {
612 const int locmaxcellid = locmaxpoint.first;
615 B2DEBUG(175,
"locmaxcellid: " << locmaxcellid);
617 B2DEBUG(175,
"ok: ");
620 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
622 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
625 const double weightInShower = myWeights[i];
632 if ((energy * weightInShower > LMEnergy and cellid != locmaxcellid and
m_removeShiftedLMs > 0) or
633 (energy * weightInShower <
m_threshold and cellid == locmaxcellid)) {
634 markfordeletion.push_back(locmaxcellid);
635 iterateclusters =
true;
642 for (
const auto lmid : markfordeletion) {
643 localMaximumsPoints.erase(lmid);
644 centroidPoints.erase(lmid);
647 }
while (iterateclusters);
650 unsigned int iShower = 1;
651 for (
const auto& locmaxpoint : localMaximumsPoints) {
653 const int locmaxcellid = locmaxpoint.first;
669 std::vector<short int> neighbourlist = neighbourMap->
getNeighbours(locmaxcellid);
672 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
675 std::vector<ECLCalDigit> newdigits;
676 std::vector<double> newweights;
677 double highestEnergy = 0.;
678 double highestEnergyTime = 0.;
679 double highestEnergyTimeResolution = 0.;
680 double weightSum = 0.0;
682 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
685 const double weight = myWeights[i];
695 if (std::find(neighbourlist.begin(), neighbourlist.end(), cellid) != neighbourlist.end()) {
699 newdigits.push_back(dig);
700 newweights.push_back(weight);
706 if (energy * weight > highestEnergy) {
707 highestEnergy = energy * weight;
708 highestEnergyTime = dig.
getTime();
718 B2DEBUG(175,
"old theta: " << oldshowerposition->
Theta());
719 B2DEBUG(175,
"old phi: " << oldshowerposition->
Phi());
720 B2DEBUG(175,
"old R: " << oldshowerposition->
Mag());
721 B2DEBUG(175,
"old energy: " << energyEstimation);
722 delete oldshowerposition;
727#ifndef __clang_analyzer__
729 aECLShower->setTheta(showerposition->
Theta());
730 aECLShower->setPhi(showerposition->
Phi());
731 aECLShower->setR(showerposition->
Mag());
733 B2DEBUG(175,
"new theta: " << showerposition->
Theta());
734 B2DEBUG(175,
"new phi: " << showerposition->
Phi());
735 B2DEBUG(175,
"new R: " << showerposition->
Mag());
736 delete showerposition;
740 double showerEnergy = 0.0;
746 const unsigned int nOptimal =
static_cast<unsigned int>(nOptimalVec[0]);
747 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
751 aECLShower->setNOptimalGroupIndex(nOptimalVec[1]);
752 aECLShower->setNOptimalEnergyBin(nOptimalVec[2]);
753 aECLShower->setNOptimalEnergy(energyEstimation);
756 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
757 listCrystalPairs.resize(newdigits.size());
759 std::vector < std::pair<double, double> > weighteddigits;
760 weighteddigits.resize(newdigits.size());
761 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
762 weighteddigits.at(i) = std::make_pair((newdigits.at(i)).getEnergy(), newweights.at(i));
763 listCrystalPairs.at(i) = std::make_pair((newdigits.at(i)).getCellId(), newweights.at(i) * (newdigits.at(i)).getEnergy());
767 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
const auto & left,
const auto & right) {
768 return left.second > right.second;
771 std::vector< unsigned int> listCrystals;
773 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
775 listCrystals.push_back(listCrystalPairs[i].first);
779 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
780 aECLShower->setListOfCrystalsForEnergy(listCrystals);
783 B2DEBUG(175,
"Shower Energy (2): " << showerEnergy);
786 showerEnergy = Belle2::ECL::computeEnergySum(newdigits, newweights);
789 aECLShower->setEnergy(showerEnergy);
790 aECLShower->setEnergyRaw(showerEnergy);
791 aECLShower->setEnergyHighestCrystal(highestEnergy);
792 aECLShower->setTime(highestEnergyTime);
793 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
794 aECLShower->setNumberOfCrystals(weightSum);
795 aECLShower->setCentralCellId(locmaxcellid);
797 B2DEBUG(175,
"new energy: " << showerEnergy);
800 aECLShower->setShowerId(iShower);
803 aECLShower->setConnectedRegionId(aCR.
getCRId());
806 aECLShower->addRelationTo(&aCR);