21 #include <ecl/modules/eclSplitterN1/ECLSplitterN1Module.h>
34 #include <framework/logging/Logger.h>
35 #include <framework/utilities/FileSystem.h>
36 #include <framework/geometry/B2Vector3.h>
39 #include <ecl/utility/Position.h>
40 #include <ecl/dataobjects/ECLCalDigit.h>
41 #include <ecl/dataobjects/ECLConnectedRegion.h>
42 #include <ecl/dataobjects/ECLLocalMaximum.h>
43 #include <ecl/dataobjects/ECLShower.h>
44 #include <ecl/geometry/ECLNeighbours.h>
45 #include <ecl/geometry/ECLGeometryPar.h>
48 #include <mdst/dataobjects/EventLevelClusteringInfo.h>
65 m_eclCalDigits(eclCalDigitArrayName()),
66 m_eclConnectedRegions(eclConnectedRegionArrayName()),
67 m_eclShowers(eclShowerArrayName()),
68 m_eclLocalMaximums(eclLocalMaximumArrayName()),
69 m_eventLevelClusteringInfo(eventLevelClusteringInfoName())
72 setDescription(
"ECLSplitterN1Module: Baseline reconstruction splitter code for the n photon hypothesis.");
73 addParam(
"fullBkgdCount", m_fullBkgdCount,
74 "Number of background digits at full background (as provided by EventLevelClusteringInfo).",
80 addParam(
"threshold", m_threshold,
"Threshold energy after splitting.", 7.5 *
Belle2::Unit::MeV);
81 addParam(
"expConstant", m_expConstant,
"Constant a from exp(-a*dist/RM), typical: 1.5 to 3.5?", 2.5);
82 addParam(
"maxIterations", m_maxIterations,
"Maximum number of iterations for centroid shifts.", 100);
83 addParam(
"shiftTolerance", m_shiftTolerance,
"Tolerance level for centroid shifts.", 1.0 *
Belle2::Unit::mm);
84 addParam(
"minimumSharedEnergy", m_minimumSharedEnergy,
"Minimum shared energy.", 25.0 *
Belle2::Unit::keV);
85 addParam(
"maxSplits", m_maxSplits,
"Maximum number of splits within one connected region.", 10);
86 addParam(
"cutDigitEnergyForEnergy", m_cutDigitEnergyForEnergy,
87 "Minimum digit energy to be included in the shower energy calculation. (NOT USED)", 0.5 *
Belle2::Unit::MeV);
88 addParam(
"cutDigitTimeResidualForEnergy", m_cutDigitTimeResidualForEnergy,
89 "Maximum time residual to be included in the shower energy calculation. (NOT USED)", 5.0);
92 addParam(
"useOptimalNumberOfDigitsForEnergy", m_useOptimalNumberOfDigitsForEnergy,
93 "Optimize the number of digits for energy calculations.", 1);
94 addParam(
"fileBackgroundNormName", m_fileBackgroundNormName,
"Background filename.",
96 addParam(
"fileNOptimalFWDName", m_fileNOptimalFWDName,
"FWD number of optimal neighbours filename.",
98 addParam(
"fileNOptimalBarrelName", m_fileNOptimalBarrelName,
"Barrel number of optimal neighbours filename.",
100 addParam(
"fileNOptimalBWDName", m_fileNOptimalBWDName,
"BWD number of optimal neighbours filename.",
104 addParam(
"positionMethod", m_positionMethod,
"Position determination method.", std::string(
"lilo"));
105 addParam(
"liloParameterA", m_liloParameterA,
"Position determination linear-log. parameter A.", 4.0);
106 addParam(
"liloParameterB", m_liloParameterB,
"Position determination linear-log. parameter B.", 0.0);
107 addParam(
"liloParameterC", m_liloParameterC,
"Position determination linear-log. parameter C.", 0.0);
110 setPropertyFlags(c_ParallelProcessingCertified);
125 m_liloParameters.resize(3);
126 m_liloParameters.at(0) = m_liloParameterA;
127 m_liloParameters.at(1) = m_liloParameterB;
128 m_liloParameters.at(2) = m_liloParameterC;
131 m_eclCalDigits.registerInDataStore(eclCalDigitArrayName());
132 m_eclConnectedRegions.registerInDataStore(eclConnectedRegionArrayName());
133 m_eclShowers.registerInDataStore(eclShowerArrayName());
134 m_eclLocalMaximums.registerInDataStore(eclLocalMaximumArrayName());
135 m_eventLevelClusteringInfo.registerInDataStore(eventLevelClusteringInfoName());
138 m_eclShowers.registerRelationTo(m_eclConnectedRegions);
139 m_eclShowers.registerRelationTo(m_eclCalDigits);
140 m_eclShowers.registerRelationTo(m_eclLocalMaximums);
141 m_eclLocalMaximums.registerRelationTo(m_eclCalDigits);
148 m_StoreArrPosition.resize(8736 + 1);
149 m_StoreArrPositionLM.resize(8736 + 1);
152 m_fileBackgroundNorm =
new TFile(m_fileBackgroundNormName.c_str(),
"READ");
153 if (!m_fileBackgroundNorm) B2FATAL(
"Could not find file: " << m_fileBackgroundNormName);
154 m_th1fBackgroundNorm =
dynamic_cast<TH1F*
>(m_fileBackgroundNorm->Get(
"background_norm"));
155 if (!m_th1fBackgroundNorm) B2FATAL(
"Could not find m_th1fBackgroundNorm");
158 m_fileNOptimalFWD =
new TFile(m_fileNOptimalFWDName.c_str(),
"READ");
159 if (!m_fileNOptimalFWD) B2FATAL(
"Could not find file: " << m_fileNOptimalFWDName);
160 for (
unsigned t = 0; t < 13; ++t) {
161 for (
unsigned s = 0; s < c_nSectorCellIdFWD[t]; ++s) {
162 m_tg2dNOptimalFWD[t][s] =
dynamic_cast<TGraph2D*
>(m_fileNOptimalFWD->Get(Form(
"thetaid-%i_sectorcellid-%i", t, s)));
163 if (!m_tg2dNOptimalFWD[t][s]) B2FATAL(
"Could not find TGraph2D m_tg2dNOptimalFWD!");
167 m_fileNOptimalBarrel =
new TFile(m_fileNOptimalBarrelName.c_str(),
"READ");
168 if (!m_fileNOptimalBarrel) B2FATAL(
"Could not find file: " << m_fileNOptimalBarrelName);
170 m_tg2dNOptimalBarrel =
dynamic_cast<TGraph2D*
>(m_fileNOptimalBarrel->Get(
"thetaid-50_sectorcellid-8"));
171 if (!m_tg2dNOptimalBarrel) B2FATAL(
"Could not find TGraph2D m_tg2dNOptimalBarrel!");
173 m_fileNOptimalBWD =
new TFile(m_fileNOptimalBWDName.c_str(),
"READ");
174 if (!m_fileNOptimalBWD) B2FATAL(
"Could not find file: " << m_fileNOptimalBWDName);
175 for (
unsigned t = 0; t < 10; ++t) {
176 for (
unsigned s = 0; s < c_nSectorCellIdBWD[t]; ++s) {
177 m_tg2dNOptimalBWD[t][s] =
dynamic_cast<TGraph2D*
>(m_fileNOptimalBWD->Get(Form(
"thetaid-%i_sectorcellid-%i", t + 59, s)));
178 if (!m_tg2dNOptimalBWD[t][s]) B2FATAL(
"Could not find TGraph2D m_tg2dNOptimalBWD!");
191 B2DEBUG(175,
"ECLCRSplitterModule::event()");
194 memset(&m_StoreArrPosition[0], -1, m_StoreArrPosition.size() *
sizeof m_StoreArrPosition[0]);
195 for (
int i = 0; i < m_eclCalDigits.getEntries(); i++) {
196 m_StoreArrPosition[m_eclCalDigits[i]->getCellId()] = i;
200 memset(&m_StoreArrPositionLM[0], -1, m_StoreArrPositionLM.size() *
sizeof m_StoreArrPositionLM[0]);
201 for (
int i = 0; i < m_eclLocalMaximums.getEntries(); i++) {
202 m_StoreArrPositionLM[m_eclLocalMaximums[i]->getCellId()] = i;
206 for (
auto& aCR : m_eclConnectedRegions) {
208 m_cellIdInCR.clear();
210 const unsigned int entries = (aCR.getRelationsWith<
ECLCalDigit>(eclCalDigitArrayName())).size();
212 m_cellIdInCR.resize(entries);
216 for (
const auto& caldigit : aCR.getRelationsWith<
ECLCalDigit>(eclCalDigitArrayName())) {
217 m_cellIdInCR[i] = caldigit.getCellId();
222 splitConnectedRegion(aCR);
238 if (m_fileBackgroundNorm)
delete m_fileBackgroundNorm;
239 if (m_fileNOptimalFWD)
delete m_fileNOptimalFWD;
240 if (m_fileNOptimalBarrel)
delete m_fileNOptimalBarrel;
241 if (m_fileNOptimalBWD)
delete m_fileNOptimalBWD;
243 if (m_NeighbourMap9)
delete m_NeighbourMap9;
244 if (m_NeighbourMap21)
delete m_NeighbourMap21;
251 const int bkgdcount = m_eventLevelClusteringInfo->getNECLCalDigitsOutOfTime();
252 double backgroundLevel = 0.0;
253 if (m_fullBkgdCount > 0) {
254 backgroundLevel =
static_cast<double>(bkgdcount) /
static_cast<double>(m_fullBkgdCount);
260 B2DEBUG(175,
"ECLCRSplitterModule::splitConnectedRegion: nLocalMaximums = " << nLocalMaximums);
269 if (nLocalMaximums == 1 or nLocalMaximums >= m_maxSplits) {
272 const auto aECLShower = m_eclShowers.appendNew();
275 aECLShower->addRelationTo(&aCR);
278 double weightSum = 0.0;
284 const int locmaxcellid = locmaxvector[0]->getCellId();
285 const int pos = m_StoreArrPosition[locmaxcellid];
286 double highestEnergyID = (m_eclCalDigits[pos])->getCellId();
287 double highestEnergy = (m_eclCalDigits[pos])->getEnergy();
288 double highestEnergyTime = (m_eclCalDigits[pos])->getTime();
289 double highestEnergyTimeResolution = (m_eclCalDigits[pos])->getTimeResolution();
292 const double energyEstimation = estimateEnergy(highestEnergyID);
296 int nNeighbours = getNeighbourMap(energyEstimation, backgroundLevel);
297 if (nNeighbours == 9 and !m_useOptimalNumberOfDigitsForEnergy) neighbourMap = m_NeighbourMap9;
298 else neighbourMap = m_NeighbourMap21;
301 std::vector<ECLCalDigit> digits;
302 std::vector<double> weights;
303 for (
auto& neighbourId : neighbourMap->
getNeighbours(highestEnergyID)) {
304 const auto it = std::find(m_cellIdInCR.begin(), m_cellIdInCR.end(),
306 if (it == m_cellIdInCR.end())
continue;
308 const int neighbourpos = m_StoreArrPosition[neighbourId];
309 digits.push_back(*m_eclCalDigits[neighbourpos]);
310 weights.push_back(1.0);
313 aECLShower->addRelationTo(m_eclCalDigits[neighbourpos], 1.0);
317 const B2Vector3D& showerposition = Belle2::ECL::computePositionLiLo(digits, weights, m_liloParameters);
318 aECLShower->setTheta(showerposition.
Theta());
319 aECLShower->setPhi(showerposition.
Phi());
320 aECLShower->setR(showerposition.
Mag());
323 double showerEnergy = 0.0;
324 if (m_useOptimalNumberOfDigitsForEnergy) {
327 const unsigned int nOptimal = getOptimalNumberOfDigits(highestEnergyID, energyEstimation, backgroundLevel);
328 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
331 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
332 listCrystalPairs.resize(digits.size());
334 std::vector < std::pair<double, double> > weighteddigits;
335 weighteddigits.resize(digits.size());
336 for (
unsigned int i = 0; i < digits.size(); ++i) {
337 weighteddigits.at(i) = std::make_pair((digits.at(i)).getEnergy(), weights.at(i));
338 listCrystalPairs.at(i) = std::make_pair((digits.at(i)).getCellId(), weights.at(i) * (digits.at(i)).getEnergy());
342 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
auto & left,
auto & right) {
343 return left.second < right.second;
345 std::vector< unsigned int> listCrystals;
347 for (
unsigned int i = 0; i < digits.size(); ++i) {
349 listCrystals.push_back(listCrystalPairs[i].first);
353 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
354 aECLShower->setListOfCrystalsForEnergy(listCrystals);
356 showerEnergy = getEnergySum(weighteddigits, nOptimal);
357 B2DEBUG(150,
"Shower Energy (1): " << showerEnergy);
360 showerEnergy = Belle2::ECL::computeEnergySum(digits, weights);
363 aECLShower->setEnergy(showerEnergy);
364 aECLShower->setEnergyRaw(showerEnergy);
365 aECLShower->setEnergyHighestCrystal(highestEnergy);
366 aECLShower->setTime(highestEnergyTime);
367 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
368 aECLShower->setNumberOfCrystals(weightSum);
369 aECLShower->setCentralCellId(highestEnergyID);
371 B2DEBUG(175,
"theta = " << showerposition.
Theta());
372 B2DEBUG(175,
"phi = " << showerposition.
Phi());
373 B2DEBUG(175,
"R = " << showerposition.
Mag());
374 B2DEBUG(175,
"energy = " << showerEnergy);
375 B2DEBUG(175,
"time = " << highestEnergyTime);
376 B2DEBUG(175,
"time resolution = " << highestEnergyTimeResolution);
377 B2DEBUG(175,
"neighbours = " << nNeighbours);
378 B2DEBUG(175,
"backgroundLevel = " << backgroundLevel);
381 aECLShower->setShowerId(1);
383 aECLShower->setConnectedRegionId(aCR.
getCRId());
386 const int posLM = m_StoreArrPositionLM[locmaxcellid];
388 const int posDigit = m_StoreArrPosition[aDigit.getCellId()];
389 m_eclLocalMaximums[posLM]->addRelationTo(m_eclCalDigits[posDigit], 1.0);
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;
408 int cellid = aLocalMaximum.getCellId();
411 B2Vector3D vectorPosition = m_geom->GetCrystalPos(cellid - 1);
412 localMaximumsPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
413 centroidPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
417 bool iterateclusters =
true;
421 centroidList.clear();
422 centroidEnergyList.clear();
429 const int cellid = aCalDigit.getCellId();
431 B2Vector3D vectorPosition = m_geom->GetCrystalPos(cellid - 1);
432 allPoints.insert(std::map<int, B2Vector3D>::value_type(cellid, vectorPosition));
433 digits.push_back(aCalDigit);
436 for (
const auto& digitpoint : allPoints) {
437 const int cellid = digitpoint.first;
438 const int pos = m_StoreArrPosition[cellid];
439 digitVector.push_back(*m_eclCalDigits[pos]);
448 double centroidShiftAverage = 0.0;
452 B2DEBUG(175,
"Iteration: #" << nIterations <<
" (of max. " << m_maxIterations <<
")");
454 centroidShiftAverage = 0.0;
455 if (nIterations == 0) {
456 centroidList.clear();
457 centroidEnergyList.clear();
462 for (
const auto& locmaxpoint : localMaximumsPoints) {
465 const int locmaxcellid = locmaxpoint.first;
471 if (nIterations == 0) {
472 const int pos = m_StoreArrPosition[locmaxcellid];
473 const double locmaxenergy = m_eclCalDigits[pos]->getEnergy();
474 centroidEnergyList[locmaxcellid] = 1.5 * locmaxenergy;
477 B2DEBUG(175,
"local maximum cellid: " << locmaxcellid);
482 for (
const auto& digitpoint : allPoints) {
485 const int digitcellid = digitpoint.first;
488 const int pos = m_StoreArrPosition[digitcellid];
489 const double digitenergy = m_eclCalDigits[pos]->getEnergy();
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();
514 const int thispos = m_StoreArrPosition[centroidcellid];
515 const double thisenergy = m_eclCalDigits[thispos]->getEnergy();
518 if (locmaxcellid == centroidcellid) {
519 distance = thisdistance;
524 const double expfactor = exp(-m_expConstant * thisdistance / c_molierRadius);
525 distanceEnergySum += (thisenergy * expfactor);
530 if (distanceEnergySum > 0.0) {
531 const double expfactor = exp(-m_expConstant * distance / c_molierRadius);
532 weight = energy * expfactor / distanceEnergySum;
538 if ((digitenergy * weight) < m_minimumSharedEnergy) {
544 B2WARNING(
"ECLCRSplitterModule::splitConnectedRegion: Floating point glitch, weight for this digit " << weight <<
545 ", resetting it to 1.0.");
550 B2DEBUG(175,
" cellid: " << digitcellid <<
", energy: " << digitenergy <<
", weight: " << weight <<
", distance: " << distance);
551 weights.push_back(weight);
557 B2Vector3D oldCentroidPos = (centroidPoints.find(locmaxcellid))->second;
560 B2Vector3D newCentroidPos = Belle2::ECL::computePositionLiLo(digits, weights, m_liloParameters);
563 const double newEnergy = Belle2::ECL::computeEnergySum(digits, weights);
566 const B2Vector3D centroidShift = (oldCentroidPos - newCentroidPos);
569 centroidList[locmaxcellid] = newCentroidPos;
570 weightMap[locmaxcellid] = weights;
572 B2DEBUG(175,
"--> inserting new energy: " << newEnergy <<
" for local maximum " << locmaxcellid);
573 centroidEnergyList[locmaxcellid] = newEnergy;
574 double showerenergy = (*centroidEnergyList.find(locmaxcellid)).second /
Belle2::Unit::MeV;
575 B2DEBUG(175,
"--> new energy = " << showerenergy <<
" MeV");
578 centroidShiftAverage += centroidShift.
Mag();
581 B2DEBUG(175,
" old centroid: " << oldCentroidPos.
x() <<
" cm, " << oldCentroidPos.
y() <<
" cm, " << oldCentroidPos.
z() <<
583 B2DEBUG(175,
" new centroid: " << newCentroidPos.
x() <<
" cm, " << newCentroidPos.
y() <<
" cm, " << newCentroidPos.
z() <<
585 B2DEBUG(175,
" centroid shift: " << centroidShift.
Mag() <<
" cm");
590 centroidShiftAverage /=
static_cast<double>(nLocalMaximums);
592 B2DEBUG(175,
"--> average centroid shift: " << centroidShiftAverage <<
" cm (tolerance is " << m_shiftTolerance <<
" cm)");
595 for (
const auto& locmaxpoint : localMaximumsPoints) {
596 centroidPoints[locmaxpoint.first] = (centroidList.find(locmaxpoint.first))->second;
601 }
while (nIterations < m_maxIterations and centroidShiftAverage > m_shiftTolerance);
605 std::vector<int> markfordeletion;
606 iterateclusters =
false;
607 for (
const auto& locmaxpoint : localMaximumsPoints) {
610 const int locmaxcellid = locmaxpoint.first;
611 const int pos = m_StoreArrPosition[locmaxcellid];
613 B2DEBUG(175,
"locmaxcellid: " << locmaxcellid);
614 const double lmenergy = m_eclCalDigits[pos]->getEnergy();
615 B2DEBUG(175,
"ok: ");
618 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
620 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
623 const double weight = myWeights[i];
630 if ((energy * weight > lmenergy and cellid != locmaxcellid) or (energy * weight < m_threshold and cellid == locmaxcellid)) {
631 markfordeletion.push_back(locmaxcellid);
632 iterateclusters =
true;
639 for (
const auto lmid : markfordeletion) {
640 localMaximumsPoints.erase(lmid);
641 centroidPoints.erase(lmid);
644 }
while (iterateclusters);
647 unsigned int iShower = 1;
648 for (
const auto& locmaxpoint : localMaximumsPoints) {
650 const int locmaxcellid = locmaxpoint.first;
651 const int posLM = m_StoreArrPositionLM[locmaxcellid];
654 const auto aECLShower = m_eclShowers.appendNew();
657 const double energyEstimation = estimateEnergy(locmaxcellid);
661 int nNeighbours = getNeighbourMap(energyEstimation, backgroundLevel);
662 if (nNeighbours == 9 and !m_useOptimalNumberOfDigitsForEnergy) neighbourMap = m_NeighbourMap9;
663 else neighbourMap = m_NeighbourMap21;
666 std::vector<short int> neighbourlist = neighbourMap->
getNeighbours(locmaxcellid);
669 std::vector < double > myWeights = (*weightMap.find(locmaxcellid)).second;
672 std::vector<ECLCalDigit> newdigits;
673 std::vector<double> newweights;
674 double highestEnergy = 0.;
675 double highestEnergyTime = 0.;
676 double highestEnergyTimeResolution = 0.;
677 double weightSum = 0.0;
679 for (
unsigned int i = 0; i < digitVector.size(); ++i) {
682 const double weight = myWeights[i];
685 const int pos = m_StoreArrPosition[cellid];
688 m_eclLocalMaximums[posLM]->addRelationTo(m_eclCalDigits[pos], weight);
692 if (std::find(neighbourlist.begin(), neighbourlist.end(), cellid) != neighbourlist.end()) {
694 aECLShower->addRelationTo(m_eclCalDigits[pos], weight);
696 newdigits.push_back(dig);
697 newweights.push_back(weight);
703 if (energy * weight > highestEnergy) {
704 highestEnergy = energy * weight;
705 highestEnergyTime = dig.
getTime();
715 B2DEBUG(175,
"old theta: " << oldshowerposition->
Theta());
716 B2DEBUG(175,
"old phi: " << oldshowerposition->
Phi());
717 B2DEBUG(175,
"old R: " << oldshowerposition->
Mag());
718 B2DEBUG(175,
"old energy: " << energyEstimation);
719 delete oldshowerposition;
724 B2Vector3D* showerposition =
new B2Vector3D(Belle2::ECL::computePositionLiLo(newdigits, newweights, m_liloParameters));
725 aECLShower->setTheta(showerposition->
Theta());
726 aECLShower->setPhi(showerposition->
Phi());
727 aECLShower->setR(showerposition->
Mag());
729 B2DEBUG(175,
"new theta: " << showerposition->
Theta());
730 B2DEBUG(175,
"new phi: " << showerposition->
Phi());
731 B2DEBUG(175,
"new R: " << showerposition->
Mag());
732 delete showerposition;
735 double showerEnergy = 0.0;
736 if (m_useOptimalNumberOfDigitsForEnergy) {
739 const unsigned int nOptimal = getOptimalNumberOfDigits(locmaxcellid, energyEstimation, backgroundLevel);
740 aECLShower->setNominalNumberOfCrystalsForEnergy(
static_cast<double>(nOptimal));
743 std::vector< std::pair<unsigned int, double>> listCrystalPairs;
744 listCrystalPairs.resize(newdigits.size());
746 std::vector < std::pair<double, double> > weighteddigits;
747 weighteddigits.resize(newdigits.size());
748 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
749 weighteddigits.at(i) = std::make_pair((newdigits.at(i)).getEnergy(), newweights.at(i));
750 listCrystalPairs.at(i) = std::make_pair((newdigits.at(i)).getCellId(), newweights.at(i) * (newdigits.at(i)).getEnergy());
754 std::sort(listCrystalPairs.begin(), listCrystalPairs.end(), [](
auto & left,
auto & right) {
755 return left.second < right.second;
758 std::vector< unsigned int> listCrystals;
760 for (
unsigned int i = 0; i < newdigits.size(); ++i) {
762 listCrystals.push_back(listCrystalPairs[i].first);
766 aECLShower->setNumberOfCrystalsForEnergy(
static_cast<double>(listCrystals.size()));
767 aECLShower->setListOfCrystalsForEnergy(listCrystals);
769 showerEnergy = getEnergySum(weighteddigits, nOptimal);
770 B2DEBUG(150,
"Shower Energy (2): " << showerEnergy);
773 showerEnergy = Belle2::ECL::computeEnergySum(newdigits, newweights);
776 aECLShower->setEnergy(showerEnergy);
777 aECLShower->setEnergyRaw(showerEnergy);
778 aECLShower->setEnergyHighestCrystal(highestEnergy);
779 aECLShower->setTime(highestEnergyTime);
780 aECLShower->setDeltaTime99(highestEnergyTimeResolution);
781 aECLShower->setNumberOfCrystals(weightSum);
782 aECLShower->setCentralCellId(locmaxcellid);
784 B2DEBUG(175,
"new energy: " << showerEnergy);
787 aECLShower->setShowerId(iShower);
790 aECLShower->setConnectedRegionId(aCR.
getCRId());
793 aECLShower->addRelationTo(&aCR);
796 aECLShower->addRelationTo(m_eclLocalMaximums[posLM]);
803 if (background <= 0.1)
return 21;
805 if (energy > 0.06 + 0.4 * background)
return 21;
812 int nOptimalNeighbours = 21;
815 const double bgCorrected = bg * m_th1fBackgroundNorm->GetBinContent(cellid);
818 if (bgCorrected > 0.025) {
820 double energyChecked = energy;
821 double bgChecked = bgCorrected;
822 if (bgCorrected > 1.0) bgChecked = 1.0;
827 m_geom->Mapping(cellid - 1);
828 const int thetaId = m_geom->GetThetaID();
829 const int crystalsPerSector = c_crystalsPerRing[thetaId] / 16;
830 const int phiIdInSector = m_geom->GetPhiID() % crystalsPerSector;
833 nOptimalNeighbours =
static_cast<unsigned int>(m_tg2dNOptimalFWD[thetaId][phiIdInSector]->Interpolate(energyChecked, bgChecked));
834 }
else if (thetaId < 59) {
835 nOptimalNeighbours =
static_cast<unsigned int>(m_tg2dNOptimalBarrel->Interpolate(energyChecked, bgChecked));
837 nOptimalNeighbours =
static_cast<unsigned int>(m_tg2dNOptimalBWD[thetaId - 59][phiIdInSector]->Interpolate(energyChecked,
840 B2DEBUG(175,
"ECLSplitterN1Module::getOptimalNumberOfDigits: theta ID: " << thetaId <<
", bg: " << bg <<
" (after corr.: " <<
841 bgCorrected <<
"), energy: " << energy <<
", n: " << nOptimalNeighbours);
842 }
else B2DEBUG(175,
"ECLSplitterN1Module::getOptimalNumberOfDigits: small bg: " << bg <<
" (after corr.: " << bgCorrected <<
843 "), energy: " << energy <<
", n: " << nOptimalNeighbours);
845 return nOptimalNeighbours;
852 double energysum = 0.;
854 std::sort(weighteddigits.begin(), weighteddigits.end(), std::greater<std::pair<double, double>>());
856 unsigned int min = n;
857 if (weighteddigits.size() < n) min = weighteddigits.size();
859 for (
unsigned int i = 0; i < min; ++i) {
860 B2DEBUG(150,
"getEnergySum: " << weighteddigits.at(i).first <<
" " << weighteddigits.at(i).second);
861 energysum += (weighteddigits.at(i).first * weighteddigits.at(i).second);
863 B2DEBUG(150,
"getEnergySum: energysum=" << energysum);
872 double energyEstimation = 0.0;
874 for (
auto& neighbourId : m_NeighbourMap9->getNeighbours(centerid)) {
877 const auto it = std::find(m_cellIdInCR.begin(), m_cellIdInCR.end(),
879 if (it == m_cellIdInCR.end())
continue;
881 const int pos = m_StoreArrPosition[neighbourId];
882 const double energyNeighbour = m_eclCalDigits[pos]->getEnergy();
884 energyEstimation += energyNeighbour;
887 return energyEstimation;