221 double backgroundLevel = 0.0;
223 backgroundLevel =
static_cast<double>(bkgdcount) /
static_cast<double>(
m_fullBkgdCount);
229 B2DEBUG(170,
"ECLCRSplitterModule::splitConnectedRegion: nLocalMaximums = " << nLocalMaximums);
238 if (nLocalMaximums == 1) {
244 aECLShower->addRelationTo(&aCR);
247 double weightSum = 0.0;
253 const int locmaxcellid = locmaxvector[0]->getCellId();
258 double highestEnergyTimeResolution = (
m_eclCalDigits[pos])->getTimeResolution();
270 std::vector<ECLCalDigit> digits;
271 std::vector<double> weights;
272 for (
auto& neighbourId : neighbourMap->
getNeighbours(highestEnergyID)) {
279 weights.push_back(1.0);
287 aECLShower->setTheta(showerposition.
Theta());
288 aECLShower->setPhi(showerposition.
Phi());
289 aECLShower->setR(showerposition.
Mag());
292 double showerEnergy = 0.0;
297 const unsigned int nOptimal =
static_cast<unsigned int>(nOptimalVec[0]);
298 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
302 aECLShower->setNOptimalGroupIndex(nOptimalVec[1]);
303 aECLShower->setNOptimalEnergyBin(nOptimalVec[2]);
304 aECLShower->setNOptimalEnergy(energyEstimation);
307 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
308 listCrystalPairs.resize(digits.size());
310 std::vector < std::pair<double, double> > weighteddigits;
311 weighteddigits.resize(digits.size());
312 for (
unsigned int i = 0; i < digits.size(); ++i) {
313 weighteddigits.at(i) = std::make_pair((digits.at(i)).getEnergy(), weights.at(i));
314 listCrystalPairs.at(i) = std::make_pair((digits.at(i)).getCellId(), weights.at(i) * (digits.at(i)).getEnergy());
318 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
const auto & left,
const auto & right) {
319 return left.second > right.second;
321 std::vector< unsigned int> listCrystals;
323 for (
unsigned int i = 0; i < digits.size(); ++i) {
325 listCrystals.push_back(listCrystalPairs[i].first);
329 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
330 aECLShower->setListOfCrystalsForEnergy(listCrystals);
333 B2DEBUG(175,
"Shower Energy (1): " << showerEnergy);
336 showerEnergy = Belle2::ECL::computeEnergySum(digits, weights);
339 aECLShower->setEnergy(showerEnergy);
340 aECLShower->setEnergyRaw(showerEnergy);
341 aECLShower->setEnergyHighestCrystal(highestEnergy);
342 aECLShower->setTime(highestEnergyTime);
343 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
344 aECLShower->setNumberOfCrystals(weightSum);
345 aECLShower->setCentralCellId(highestEnergyID);
347 B2DEBUG(175,
"theta = " << showerposition.
Theta());
348 B2DEBUG(175,
"phi = " << showerposition.
Phi());
349 B2DEBUG(175,
"R = " << showerposition.
Mag());
350 B2DEBUG(175,
"energy = " << showerEnergy);
351 B2DEBUG(175,
"time = " << highestEnergyTime);
352 B2DEBUG(175,
"time resolution = " << highestEnergyTimeResolution);
353 B2DEBUG(175,
"neighbours = " << nNeighbours);
354 B2DEBUG(175,
"backgroundLevel = " << backgroundLevel);
357 aECLShower->setShowerId(1);
359 aECLShower->setConnectedRegionId(aCR.
getCRId());
373 std::vector<std::pair<ECLLocalMaximum, double>> lm_energy_vector;
375 const int cellid = aLocalMaximum.getCellId();
378 lm_energy_vector.push_back(std::pair<ECLLocalMaximum, double>(aLocalMaximum, digitenergy));
382 if (lm_energy_vector.size() >=
static_cast<size_t>(
m_maxSplits)) {
383 std::sort(lm_energy_vector.begin(), lm_energy_vector.end(), [](
const std::pair<ECLLocalMaximum, double>& x,
384 const std::pair<ECLLocalMaximum, double>& y) {
385 return x.second > y.second;
391 std::vector<ECLCalDigit> digits;
392 std::vector<double> weights;
393 std::map<int, B2Vector3D> centroidList;
394 std::map<int, double> centroidEnergyList;
395 std::map<int, B2Vector3D> allPoints;
396 std::map<int, std::vector < double > > weightMap;
397 std::vector < ECLCalDigit > digitVector;
400 std::map<int, B2Vector3D> localMaximumsPoints;
401 std::map<int, B2Vector3D> centroidPoints;
403 for (
auto& aLocalMaximum : lm_energy_vector) {
405 int cellid = aLocalMaximum.first.getCellId();
409 localMaximumsPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
410 centroidPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
414 bool iterateclusters =
true;
418 centroidList.clear();
419 centroidEnergyList.clear();
426 const int cellid = aCalDigit.getCellId();
429 allPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
430 digits.push_back(aCalDigit);
433 for (
const auto& digitpoint : allPoints) {
434 const int cellid = digitpoint.first;
445 double centroidShiftAverage = 0.0;
449 B2DEBUG(175,
"Iteration: #" << nIterations <<
" (of max. " <<
m_maxIterations <<
")");
451 centroidShiftAverage = 0.0;
452 if (nIterations == 0) {
453 centroidList.clear();
454 centroidEnergyList.clear();
459 for (
const auto& locmaxpoint : localMaximumsPoints) {
462 const int locmaxcellid = locmaxpoint.first;
468 if (nIterations == 0) {
471 centroidEnergyList[locmaxcellid] = 1.5 * locmaxenergy;
474 B2DEBUG(175,
"local maximum cellid: " << locmaxcellid);
478 for (
const auto& digitpoint : allPoints) {
481 const int digitcellid = digitpoint.first;
489 double distance = 0.0;
490 double distanceEnergySum = 0.0;
493 for (
const auto& centroidpoint : centroidPoints) {
496 const int centroidcellid = centroidpoint.first;
497 B2Vector3D centroidpos = centroidpoint.second;
499 double thisdistance = 0.;
502 if (nIterations == 0 and digitcellid == centroidcellid) {
505 B2Vector3D vectorDistance = ((centroidpos) - (digitpos));
506 thisdistance = vectorDistance.
Mag();
514 if (locmaxcellid == centroidcellid) {
515 distance = thisdistance;
521 distanceEnergySum += (thisenergy * expfactor);
526 if (distanceEnergySum > 0.0) {
528 weight = energy * expfactor / distanceEnergySum;
540 B2WARNING(
"ECLCRSplitterModule::splitConnectedRegion: Floating point glitch, weight for this digit " << weight <<
541 ", resetting it to 1.0.");
546 B2DEBUG(175,
" cellid: " << digitcellid <<
", energy: " << digitenergy <<
", weight: " << weight <<
", distance: " << distance);
547 weights.push_back(weight);
552 B2Vector3D oldCentroidPos = (centroidPoints.find(locmaxcellid))->second;
558 const double newEnergy = Belle2::ECL::computeEnergySum(digits, weights);
561 const B2Vector3D centroidShift = (oldCentroidPos - newCentroidPos);
564 centroidList[locmaxcellid] = newCentroidPos;
565 weightMap[locmaxcellid] = weights;
567 B2DEBUG(175,
"--> inserting new energy: " << newEnergy <<
" for local maximum " << locmaxcellid);
568 centroidEnergyList[locmaxcellid] = newEnergy;
569 double showerenergy = (*centroidEnergyList.find(locmaxcellid)).second /
Belle2::Unit::MeV;
570 B2DEBUG(175,
"--> new energy = " << showerenergy <<
" MeV");
573 centroidShiftAverage += centroidShift.
Mag();
576 B2DEBUG(175,
" old centroid: " << oldCentroidPos.
X() <<
" cm, " << oldCentroidPos.
Y() <<
" cm, " << oldCentroidPos.
Z() <<
578 B2DEBUG(175,
" new centroid: " << newCentroidPos.
X() <<
" cm, " << newCentroidPos.
Y() <<
" cm, " << newCentroidPos.
Z() <<
580 B2DEBUG(175,
" centroid shift: " << centroidShift.
Mag() <<
" cm");
585 centroidShiftAverage /=
static_cast<double>(nLocalMaximums);
587 B2DEBUG(175,
"--> average centroid shift: " << centroidShiftAverage <<
" cm (tolerance is " <<
m_shiftTolerance <<
" cm)");
590 for (
const auto& locmaxpoint : localMaximumsPoints) {
591 centroidPoints[locmaxpoint.first] = (centroidList.find(locmaxpoint.first))->second;
596 }
while (nIterations < m_maxIterations and centroidShiftAverage >
m_shiftTolerance);
600 std::vector<int> markfordeletion;
601 iterateclusters =
false;
602 for (
const auto& locmaxpoint : localMaximumsPoints) {
605 const int locmaxcellid = locmaxpoint.first;
608 B2DEBUG(175,
"locmaxcellid: " << locmaxcellid);
610 B2DEBUG(175,
"ok: ");
613 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
615 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
618 const double weight = myWeights[i];
625 if ((energy * weight > lmenergy and cellid != locmaxcellid) or (energy * weight <
m_threshold and cellid == locmaxcellid)) {
626 markfordeletion.push_back(locmaxcellid);
627 iterateclusters =
true;
634 for (
const auto lmid : markfordeletion) {
635 localMaximumsPoints.erase(lmid);
636 centroidPoints.erase(lmid);
639 }
while (iterateclusters);
642 unsigned int iShower = 1;
643 for (
const auto& locmaxpoint : localMaximumsPoints) {
645 const int locmaxcellid = locmaxpoint.first;
661 std::vector<short int> neighbourlist = neighbourMap->
getNeighbours(locmaxcellid);
664 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
667 std::vector<ECLCalDigit> newdigits;
668 std::vector<double> newweights;
669 double highestEnergy = 0.;
670 double highestEnergyTime = 0.;
671 double highestEnergyTimeResolution = 0.;
672 double weightSum = 0.0;
674 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
677 const double weight = myWeights[i];
687 if (std::find(neighbourlist.begin(), neighbourlist.end(), cellid) != neighbourlist.end()) {
691 newdigits.push_back(dig);
692 newweights.push_back(weight);
698 if (energy * weight > highestEnergy) {
699 highestEnergy = energy * weight;
700 highestEnergyTime = dig.
getTime();
710 B2DEBUG(175,
"old theta: " << oldshowerposition->
Theta());
711 B2DEBUG(175,
"old phi: " << oldshowerposition->
Phi());
712 B2DEBUG(175,
"old R: " << oldshowerposition->
Mag());
713 B2DEBUG(175,
"old energy: " << energyEstimation);
714 delete oldshowerposition;
720 aECLShower->setTheta(showerposition->
Theta());
721 aECLShower->setPhi(showerposition->
Phi());
722 aECLShower->setR(showerposition->
Mag());
724 B2DEBUG(175,
"new theta: " << showerposition->
Theta());
725 B2DEBUG(175,
"new phi: " << showerposition->
Phi());
726 B2DEBUG(175,
"new R: " << showerposition->
Mag());
727 delete showerposition;
730 double showerEnergy = 0.0;
736 const unsigned int nOptimal =
static_cast<unsigned int>(nOptimalVec[0]);
737 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
741 aECLShower->setNOptimalGroupIndex(nOptimalVec[1]);
742 aECLShower->setNOptimalEnergyBin(nOptimalVec[2]);
743 aECLShower->setNOptimalEnergy(energyEstimation);
746 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
747 listCrystalPairs.resize(newdigits.size());
749 std::vector < std::pair<double, double> > weighteddigits;
750 weighteddigits.resize(newdigits.size());
751 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
752 weighteddigits.at(i) = std::make_pair((newdigits.at(i)).getEnergy(), newweights.at(i));
753 listCrystalPairs.at(i) = std::make_pair((newdigits.at(i)).getCellId(), newweights.at(i) * (newdigits.at(i)).getEnergy());
757 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
const auto & left,
const auto & right) {
758 return left.second > right.second;
761 std::vector< unsigned int> listCrystals;
763 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
765 listCrystals.push_back(listCrystalPairs[i].first);
769 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
770 aECLShower->setListOfCrystalsForEnergy(listCrystals);
773 B2DEBUG(175,
"Shower Energy (2): " << showerEnergy);
776 showerEnergy = Belle2::ECL::computeEnergySum(newdigits, newweights);
779 aECLShower->setEnergy(showerEnergy);
780 aECLShower->setEnergyRaw(showerEnergy);
781 aECLShower->setEnergyHighestCrystal(highestEnergy);
782 aECLShower->setTime(highestEnergyTime);
783 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
784 aECLShower->setNumberOfCrystals(weightSum);
785 aECLShower->setCentralCellId(locmaxcellid);
787 B2DEBUG(175,
"new energy: " << showerEnergy);
790 aECLShower->setShowerId(iShower);
793 aECLShower->setConnectedRegionId(aCR.
getCRId());
796 aECLShower->addRelationTo(&aCR);