41 ATH_MSG_ERROR(
"Failed to get TrackPositionProvider for cluster preselection!");
42 return StatusCode::FAILURE;
64 return StatusCode::SUCCESS;
73 data.caloObjects = theEflowCaloObjectContainer;
82 ATH_MSG_DEBUG(
"This event has " <<
data.tracks.size() <<
" tracks " <<
data.clusters.size() <<
" clusters ");
104 unsigned int nMatches(0);
107 const unsigned int nCaloObj =
data.caloObjects->size();
108 const EventContext &ctx = Gaudi::Hive::currentContext();
111 for (
auto *thisEfRecTrack :
data.tracks)
114 if (!thisEfRecTrack->hasBin()) {
115 std::unique_ptr<eflowCaloObject> thisEflowCaloObject = std::make_unique<eflowCaloObject>();
116 thisEflowCaloObject->
addTrack(thisEfRecTrack);
117 data.caloObjects->push_back(std::move(thisEflowCaloObject));
127 std::vector<eflowTrackClusterLink*> bestClusters;
128 std::vector<float> deltaRPrime;
137 TruthLink truthLink = truthLinkAccessor(*(thisEfRecTrack->getTrack()));
140 if (truthLink.
isValid()) trackMatchedTruthParticle = *truthLink;
142 if (trackMatchedTruthParticle){
146 if (!caloClusterReadDecorHandleNLeadingTruthParticles.isValid()){
147 ATH_MSG_WARNING(
"Failed to retrieve CaloCluster decoration with key " << caloClusterReadDecorHandleNLeadingTruthParticles.key());
150 for (
auto * thisCluster :
data.clusters){
155 std::string::size_type
pos = decorHandleName.find(
".");
156 std::string decorName = decorHandleName.substr(
pos+1);
160 std::vector<std::pair<unsigned int, double > > barCodeTruthPairs =
accessor(*(thisCluster->getCluster()));
162 for (
auto &barCodeTruthPair : barCodeTruthPairs){
163 if (barCodeTruthPair.first ==
barcode){
165 bestClusters.push_back(thisLink);
172 else ATH_MSG_WARNING(
"Track with pt, eta and phi " << thisEfRecTrack->getTrack()->pt() <<
", " << thisEfRecTrack->getTrack()->eta() <<
" and " << thisEfRecTrack->getTrack()->phi() <<
" does not have a valid truth pointer");
180 for (
auto &matchpair : bestClusters_02)
183 float distancesq = matchpair.second;
185 if (distancesq < 0.15 * 0.15)
189 thisEfRecTrack->addAlternativeClusterMatch(trackClusterLink,
"cone_015");
191 thisEfRecTrack->addAlternativeClusterMatch(trackClusterLink,
"cone_02");
196 for (
auto thePair : matchedClusters) {
198 if (
m_addCPData) deltaRPrime.push_back(std::sqrt(thePair.second));
202 const std::vector<eflowTrackClusterLink*>* matchedClusters_02 = thisEfRecTrack->getAlternativeClusterMatches(
"cone_02");
203 if (!matchedClusters_02)
continue;
204 else bestClusters = *matchedClusters_02;
207 if (bestClusters.empty())
continue;
211 for (
auto *thisClusterLink : bestClusters ) {
213 ATH_MSG_DEBUG(
"Matched this track to cluster with e,pt, eta and phi " << thisCluster->
e() <<
", " << thisCluster->
pt() <<
", " << thisCluster->
eta() <<
" and " << thisCluster->
phi());
221 for (
auto *trkClusLink : bestClusters){
227 if (
std::find(
data.clusters.begin(),
data.clusters.end(), trkClusLink->getCluster()) ==
data.clusters.end()) {
234 thisEfRecTrack->addClusterMatch(trackClusterLink);
236 thisEfRecTrack->addDeltaRPrime(deltaRPrime[
linkIndex]);
244 std::vector<eflowRecCluster *>
clusters(
data.clusters.begin(),
data.clusters.end());
247 ATH_MSG_DEBUG(
"Created " << nCaloObjects <<
" eflowCaloObjects.");
249 for (
auto thisEFlowCaloObject : *(
data.caloObjects)){
250 ATH_MSG_DEBUG(
"This eflowCaloObject has " << thisEFlowCaloObject->nTracks() <<
" tracks and " << thisEFlowCaloObject->nClusters() <<
" clusters ");
251 for (
unsigned int count = 0;
count < thisEFlowCaloObject->nTracks();
count++){
253 ATH_MSG_DEBUG(
"Have track with e, pt, eta and phi of " << thisTrack->
e() <<
", " << thisTrack->
pt() <<
", " << thisTrack->
eta() <<
" and " << thisTrack->
phi());
255 for (
unsigned int count = 0;
count < thisEFlowCaloObject->nClusters();
count++){
257 ATH_MSG_DEBUG(
"Have cluster with e, pt, eta and phi of " << thisCluster->
e() <<
", " << thisCluster->
pt() <<
", " << thisCluster->
eta() <<
" and " << thisCluster->
phi());
262 const double gaussianRadius = 0.032;
263 const double gaussianRadiusError = 1.0e-3;
264 const double maximumRadiusSigma = 3.0;
272 for (
unsigned int iCalo = nCaloObj; iCalo <
data.caloObjects->size(); ++iCalo) {
280 else return nCaloObj;
284 unsigned int nEFCaloObs =
data.caloObjects->size();
285 for (
unsigned int iCalo = startingPoint; iCalo < nEFCaloObs; ++iCalo) {
295 unsigned int nClusters = thisEflowCaloObject.
nClusters();
296 unsigned int nTrackMatches = thisEflowCaloObject.
nTracks();
298 ATH_MSG_DEBUG(
"Have got an eflowCaloObject with " << nClusters <<
" clusters and " << nTrackMatches <<
" track matches");
301 for (
unsigned int iTrack = 0; iTrack < nTrackMatches; ++iTrack){
311 if (nTrackMatches < 1)
return;
319 if (
isEOverPFail(expectedEnergy, expectedSigma, clusterEnergy))
return;
322 const std::vector<std::pair<eflowTrackClusterLink *, std::pair<float, float>>> &matchedTrackList = thisEflowCaloObject.
efRecLink();
324 ATH_MSG_DEBUG(
"Matched Track List has size " << matchedTrackList.size());
328 for (
unsigned int iTrack = 0; iTrack < nTrackMatches; ++iTrack)
331 ATH_MSG_DEBUG(
"eflowCaloObject has track match with E, pt and eta " << thisTrack->
e() <<
", " << thisTrack->
pt() <<
" and " << thisTrack->
eta());
335 ATH_MSG_DEBUG(
"About to perform subtraction for this eflowCaloObject");
337 bool wasAnnihilated =
false;
342 if (
canAnnihilate(expectedEnergy, expectedSigma, clusterEnergy)){
344 wasAnnihilated =
true;
346 std::vector<std::pair<xAOD::CaloCluster *, bool>> clusterList;
347 std::map<xAOD::CaloCluster *, double> clusterEnergyMap;
348 unsigned nCluster = thisEflowCaloObject.
nClusters();
349 for (
unsigned iCluster = 0; iCluster < nCluster; ++iCluster){
353 ATH_MSG_DEBUG(
"We are going to annihilate. ExpectedEnergy, expectedSigma and clusterEnergy are " << expectedEnergy <<
", " << expectedSigma <<
" and " << clusterEnergy);
355 for (
auto thisPair : clusterList)
356 ATH_MSG_DEBUG(
"Annihilating cluster with E and eta " << thisPair.first->e() <<
" and " << thisPair.first->eta());
363 Subtractor::annihilateClusters(clusterList);
366 for (
auto thisPair : clusterList)
367 ATH_MSG_DEBUG(
"Have Annihilated cluster with E and eta " << thisPair.first->e() <<
" and " << thisPair.first->eta());
370 for (
unsigned iTrack = 0; iTrack < thisEflowCaloObject.
nTracks(); ++iTrack){
371 eflowRecTrack *thisEfRecTrack = (matchedTrackList[iTrack].first)->getTrack();
379 for (
unsigned iTrack = 0; iTrack < thisEflowCaloObject.
nTracks(); ++iTrack){
386 if (!thisEfRecTrack->
hasBin())
continue;
392 ATH_MSG_DEBUG(
"Am not in dense environment for this eflowCaloObject");
395 std::vector<eflowRecCluster *> matchedClusters;
397 matchedClusters.reserve(
links.size());
398 for (
auto* thisEFlowTrackClusterLink :
links)
399 matchedClusters.push_back(thisEFlowTrackClusterLink->getCluster());
401 std::sort(matchedClusters.begin(),
402 matchedClusters.end(),
406 for (
auto* thisClus : matchedClusters)
408 "Haved matched cluster "
409 << thisClus->getCluster()->index() <<
" with e,pt, eta and phi of "
410 << thisClus->getCluster()->e() <<
", "
411 << thisClus->getCluster()->pt() <<
", "
412 << thisClus->getCluster()->eta() <<
" and "
413 << thisClus->getCluster()->phi() <<
" will be subtracted");
417 std::vector<std::pair<xAOD::CaloCluster *, bool>> clusterSubtractionList;
418 clusterSubtractionList.reserve(matchedClusters.size());
419 std::map<xAOD::CaloCluster *, double> clusterEnergyMap;
420 for (
auto *thisEFlowRecCluster : matchedClusters){
422 clusterSubtractionList.emplace_back(thisCluster,
false);
423 clusterEnergyMap[thisCluster] = thisCluster->
e();
426 ATH_MSG_DEBUG(
"Have filled clusterSubtractionList for this eflowCaloObject");
428 unsigned int trackIndex = thisEfRecTrack->
getTrack()->
index();
431 auto sumClusEnergy = [](
double accumulator, std::pair<xAOD::CaloCluster *, bool> thisPair){
return accumulator += thisPair.first->e();};
432 double totalClusterEnergy =
std::accumulate(clusterSubtractionList.begin(),clusterSubtractionList.end(),0.0,sumClusEnergy);
438 for (
auto thisPair : clusterSubtractionList)
439 ATH_MSG_DEBUG(
"Annihilating cluster with E and eta " << thisPair.first->e() <<
" and " << thisPair.first->eta());
444 Subtractor::annihilateClusters(clusterSubtractionList);
447 std::vector<std::pair<float, float>> clusterSubtractedEnergyRatios;
458 totalClusterEnergy =
std::accumulate(clusterSubtractionList.begin(),clusterSubtractionList.end(),0.0,sumClusEnergy);
464 for (
auto thisPair : clusterSubtractionList){
465 ATH_MSG_DEBUG(
"Annihilating remnant cluster with E and eta " << thisPair.first->e() <<
" and " << thisPair.first->eta());
469 std::vector<std::pair<float, float>> clusterSubtractedEnergyRatios;
475 std::vector<std::pair<float, float>> clusterSubtractedEnergyRatios;
482 ATH_MSG_DEBUG(
"Have subtracted charged shower for this eflowRecTrack");
496 unsigned int nEFCaloObs =
data.caloObjects->size();
498 for (
unsigned int iCalo = 0; iCalo < nEFCaloObs; ++iCalo) {
507 for (
unsigned iTrack = 0; iTrack < thisEflowCaloObject.
nTracks(); ++iTrack){
512 if (!thisEfRecTrack->
hasBin())
continue;
522 for (
auto thisLink :
links){
533 for (; theCell != lastCell; ++theCell){
537 double oldCellEnergy = theCell->
energy()*(theCell.
weight());
538 double subtractedCellWeight = (oldCellEnergy - truthEnergy)/oldCellEnergy;
544 float oldEnergy = thisCluster->
e();
546 if (0.0 != oldEnergy) {
547 float energyAdjustment = thisCluster->
e() / oldEnergy;
548 thisCluster->
setRawE(thisCluster->
rawE() * energyAdjustment);
560 if ((expectedEnergy == 0) && (clusterEnergy > 0))
return false;
571 result <<
" track with E, eta and phi "<<
track->e() <<
", " <<
track->eta() <<
" and " <<
track->phi();
577 result <<
" cluster with E, eta and phi of " << cluster->
e() <<
", " << cluster->
eta() <<
" and " << cluster->
phi();
583 for (
const auto *thisEFRecCluster : recClusterContainer){
584 if (thisEFRecCluster->getTrackMatches().empty()) {
588 std::vector<eflowTrackClusterLink*> theTrackLinks = thisEFRecCluster->getTrackMatches();
589 for (
auto *thisTrack : theTrackLinks){
598 unsigned int numTracks = thisEflowCaloObject.
nTracks();
600 for (
unsigned int iTrack = 0; iTrack < numTracks; ++iTrack){
602 for (
auto thisPair : clusterList){