34#include "GaudiKernel/StatusCode.h"
35#include "CLHEP/Units/SystemOfUnits.h"
52 const std::string& name,
53 const IInterface* parent)
95 declareInterface<CaloClusterCollectionProcessor> (
this);
193 " SeedThresholdOnEinSigma=")
196 ", NeighborThresholdOnEinSigma=")
199 ", CellThresholdOnEinSigma=")
217 return StatusCode::FAILURE;
225 if ( caloName ==
"LAREM" )
227 else if ( caloName ==
"LARHEC" )
229 else if ( caloName ==
"LARFCAL" )
231 else if ( caloName ==
"TILE" )
235 <<
" is not a valid Calorimeter name and will be ignored! "
236 <<
"Valid names are: LAREM, LARHEC, LARFCAL, and TILE." );
241 if ( sampName ==
"PreSamplerB" )
243 else if ( sampName ==
"EMB1" )
245 else if ( sampName ==
"EMB2" )
247 else if ( sampName ==
"EMB3" )
249 else if ( sampName ==
"PreSamplerE" )
251 else if ( sampName ==
"EME1" )
253 else if ( sampName ==
"EME2" )
255 else if ( sampName ==
"EME3" )
257 else if ( sampName ==
"HEC0" )
259 else if ( sampName ==
"HEC1" )
261 else if ( sampName ==
"HEC2" )
263 else if ( sampName ==
"HEC3" )
265 else if ( sampName ==
"TileBar0" )
267 else if ( sampName ==
"TileBar1" )
269 else if ( sampName ==
"TileBar2" )
271 else if ( sampName ==
"TileGap1" )
273 else if ( sampName ==
"TileGap2" )
275 else if ( sampName ==
"TileGap3" )
277 else if ( sampName ==
"TileExt0" )
279 else if ( sampName ==
"TileExt1" )
281 else if ( sampName ==
"TileExt2" )
283 else if ( sampName ==
"FCAL0" )
285 else if ( sampName ==
"FCAL1" )
287 else if ( sampName ==
"FCAL2" )
291 <<
" is not a valid Calorimeter sampling name and will be ignored! "
292 <<
"Valid names are: "
293 <<
"PreSamplerB, EMB1, EMB2, EMB3, "
294 <<
"PreSamplerE, EME1, EME2, EME3, "
295 <<
"HEC0, HEC1, HEC2, HEC3, "
296 <<
"TileBar0, TileBar1, TileBar2, "
297 <<
"TileGap1, TileGap2, TileGap3, "
298 <<
"TileExt0, TileExt1, TileExt2, "
299 <<
"FCAL0, FCAL1, FCAL2." );
302 msg(MSG::INFO) <<
"Samplings to consider for seeds:";
304 msg() <<
" " << sampName;
324 msg(MSG::INFO) <<
"Calorimeters to consider:";
326 msg() <<
" " << caloName;
355 return StatusCode::SUCCESS;
367 const float epsilon = 0.00001;
379 std::vector<HashCell> mySeedCells;
380 mySeedCells.reserve (2000);
382 std::vector<HashCluster *> myHashClusters;
383 myHashClusters.reserve (10000);
387 HashCell* hashCells = cellVector.data() -
m_hashMin;
399 << cellColl.
name() );
400 return StatusCode::RECOVERABLE;
411 auto cellIter = cellColl->beginConstCalo (subdet);
412 auto cellIterEnd = cellColl->endConstCalo (subdet);
413 for (
int iCell = cellColl->indexFirstCellCalo(subdet);
414 cellIter != cellIterEnd;
423 float signedE = pCell->
energy();
424 float signedEt = pCell->
et();
425 float signedRatio = epsilon;
427 signedRatio = signedE/noiseSigma;
435 bool passedSeedAndTimeCut = (passedSeedCut && passTimeCut_seedCell);
437 bool passedNeighborAndTimeCut = passedNeighborCut;
438 if(
m_cutOOTseed && passedSeedCut && !passTimeCut_seedCell) passedNeighborAndTimeCut=
false;
440 bool passedCellAndTimeCut = passedCellCut;
441 if(
m_cutOOTseed && passedSeedCut && !passTimeCut_seedCell) passedCellAndTimeCut=
false;
443 if ( passedCellAndTimeCut || passedNeighborAndTimeCut || passedSeedAndTimeCut ) {
452 if ( m_doALotOfPrintoutInFirstEvent ) {
453 ATH_MSG_DEBUG(
" [ExtId|Id|SubDet|HashId|eta|phi|E/noise|Et]: "
454 <<
"[" <<
m_calo_id->show_to_string(pCell->
ID(),0,
'/')
455 <<
"|" << mypCell->ID().getString()
457 <<
"|" << (
unsigned int)hashid
458 <<
"|" << pCell->
eta()
459 <<
"|" << pCell->
phi()
460 <<
"|" << signedRatio
466 HashCell hashCell(tmpClusterCell);
467 if ( passedNeighborAndTimeCut || passedSeedAndTimeCut ) {
468 HashCluster *tmpCluster =
469 new (tmpclus_pool.
allocate()) HashCluster (tmplist_pool);
471 tmpCluster->add(hashCell);
472 myHashClusters.push_back(tmpCluster);
474 if ( passedSeedAndTimeCut
479 mySeedCells.push_back(hashCell);
482 hashCells[hashid] = hashCell;
495 std::sort(mySeedCells.begin(),mySeedCells.end(),compareSoverN);
499 std::sort(mySeedCells.begin(),mySeedCells.end(),compareSoverN);
505 std::sort(mySeedCells.begin(),mySeedCells.end(),compareSoverN);
509 std::sort(mySeedCells.begin(),mySeedCells.end(),compareSoverN);
515 for (
const HashCell& hc : mySeedCells) {
517 << hc.getCaloTopoTmpClusterCell()->getSubDet()
519 << (
unsigned int)hc.getCaloTopoTmpClusterCell()->getID()
521 << hc.getCaloTopoTmpClusterCell()->getSignedRatio()
527 std::vector<HashCell> myNextCells;
528 myNextCells.reserve (1000);
530 std::vector<IdentifierHash> theNeighbors;
531 theNeighbors.reserve(22);
533 std::vector<IdentifierHash> theNNeighbors;
534 theNNeighbors.reserve(22);
543 while ( !mySeedCells.empty() ) {
548 for (HashCell& hc : mySeedCells) {
558 doRestrictHECIWandFCal &&
568 m_calo_id->get_neighbours(hashid,opt,theNeighbors);
576 HashCell neighborCell = hashCells[nId];
577 if ( neighborCell.getCaloTopoTmpClusterCell() ) {
581 bool isAboveNeighborThreshold =
584 if ( isAboveNeighborThreshold && !pNCell->
getUsed() ) {
586 myNextCells.push_back(neighborCell);
589 if ( myCluster != otherCluster ) {
590 HashCluster *toKill =
nullptr;
591 HashCluster *toKeep =
nullptr;
592 if ( !otherCluster || isAboveNeighborThreshold ) {
594 auto compareClusters = [&](
const auto & c1,
const auto & c2) {
599 return compare(*(c1->begin()), *(c2->begin()));
603 return compare(*(c1->begin()), *(c2->begin()));
608 return c1->size() > c2->size();
612 if ( !otherCluster || compareClusters(myCluster, otherCluster) ) {
613 toKill = otherCluster;
618 toKeep = otherCluster;
621 for (
auto *hc : *toKill)
622 hc->setCaloTopoTmpHashCluster(toKeep);
623 toKeep->add(*toKill);
627 toKeep->add(neighborCell);
637 mySeedCells.swap (myNextCells);
644 std::vector<std::unique_ptr<CaloProtoCluster> > sortClusters;
645 sortClusters.reserve (myHashClusters.size());
647 for (HashCluster* tmpCluster : myHashClusters) {
648 bool addCluster(
false);
649 if ( tmpCluster->size() > 1 )
651 else if ( tmpCluster->size() == 1 ) {
653 HashCluster::iterator clusCellIter=tmpCluster->begin();
654 if ( clusCellIter->getUsed() )
658 std::unique_ptr<CaloProtoCluster> myCluster = std::make_unique<CaloProtoCluster>(cellCollLink);
660 myCluster->getCellLinks()->reserve(tmpCluster->size());
663 const size_t iCell = cell->getCaloCell();
664 myCluster->addCell(iCell,1.);
666 const float cl_et = myCluster->et();
668 sortClusters.push_back(std::move(myCluster));
674 std::sort(sortClusters.begin(),sortClusters.end(),[](
const std::unique_ptr<CaloProtoCluster>& pc1,
675 const std::unique_ptr<CaloProtoCluster>& pc2) {
678 volatile double et1(pc1->et());
679 volatile double et2(pc2->et());
685 clusColl->
reserve(sortClusters.size());
687 for (
const auto& protoCluster: sortClusters) {
690 xAODCluster->
addCellLink(protoCluster->releaseCellLinks());
695 tmpclus_pool.
erase();
696 tmpcell_pool.
erase();
698 return StatusCode::SUCCESS;
722 bool isInTime =
true;
726 if (sam != CaloSampling::PreSamplerB && sam != CaloSampling::PreSamplerE && sam != CaloSampling::Unknown) {
727 const unsigned pmask= pCell->
caloDDE()->
is_tile() ? 0x8080 : 0x2000;
733 if (
m_xtalkEM2 && (!isInTime) && (pCell->
energy() > 0 && (sam == CaloSampling::EMB2 || (sam == CaloSampling::EME2 && std::abs(pCell->
eta()) < 2.5)))) {
738 std::vector<IdentifierHash> theNeighbors;
740 m_calo_id->get_neighbours(hashid,opt,theNeighbors);
758 std::vector<IdentifierHash> theNextNeighbors;
759 m_calo_id->get_neighbours(nId,opt,theNextNeighbors);
761 if (n2Id != hashid) {
779 if (
m_xtalkEMEta && (!isInTime) && (pCell->
energy() > 0 && (sam == CaloSampling::EMB2 || (sam == CaloSampling::EME2 && std::abs(pCell->
eta()) < 2.5)))) {
781 std::vector<IdentifierHash> theNeighbors;
783 m_calo_id->get_neighbours(hashid,opt,theNeighbors);
802 if (
m_xtalkEM2D && (!isInTime) && (pCell->
energy() > 0 && (sam == CaloSampling::EMB2 || (sam == CaloSampling::EME2 && std::abs(pCell->
eta()) < 2.5)))) {
804 std::vector<IdentifierHash> theNeighbors;
806 m_calo_id->get_neighbours(hashid,opt,theNeighbors);
813 if ( isInTime )
break;
821 if (
m_xtalkEM3 && (!isInTime) && (pCell->
energy() > 0 && (sam == CaloSampling::EMB3 || (sam == CaloSampling::EME3 && std::abs(pCell->
eta()) < 2.5)))) {
824 std::vector<IdentifierHash> theNeighbors;
826 m_calo_id->get_neighbours(hashid,opt,theNeighbors);
User interface for allocating memory. See Arena.h for an overview of the arena-based memory allocator...
Pool-based allocator. See Arena.h for an overview of the arena-based memory allocators.
#define ATH_CHECK
Evaluate an expression and check for errors.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
Container class for CaloCell.
const CaloCell * findCell(const IdentifierHash theHash) const
fast find method given identifier hash.
CaloCell_Base_ID::SUBCALO SUBCALO
Data object for each calorimeter readout cell.
float time() const
get time (data member)
virtual double phi() const override final
get phi (through CaloDetDescrElement)
double energy() const
get energy (data member)
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
uint16_t provenance() const
get provenance (data member)
virtual double eta() const override final
get eta (through CaloDetDescrElement)
CaloGain::CaloGain gain() const
get gain (data member )
virtual double et() const override final
get et
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
This class groups all DetDescr information related to a CaloCell.
IdentifierHash calo_hash() const
cell calo hash
bool is_tile() const
cell belongs to Tile
CaloCell_ID::CaloSample getSampling() const
cell sampling
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
float getEffectiveSigma(const Identifier id, const int gain, const float energy) const
Wrapper for SG::ArenaHandle with pre-fetching.
void * allocate()
Return space for new element, then allocate and prefetch one more.
void erase()
Free all allocated elements.
Gaudi::Property< bool > m_useGPUCriteria
float m_xtalkDeltaT
additional max.
float m_seedThresholdOnEorAbsEinSigma
cells with start a cluster
bool m_xtalkEM2D
if set to true, the time window is softened in the EMB2 and EME2_OW due to xtalk from all 2D neighors
bool m_subcaloUsed[CaloCell_ID::NSUBCALO]
Flag which subdetectors are to be used.
float m_xtalkEtaEratio
cut on Eneighbor/E to revover out of time layer 2 cell close in eta to energetic neighor cell
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
bool m_twogaussiannoise
if set to true use 2-gaussian noise description for TileCal
bool m_xtalkEM3
if set to true we extend the time window for direct layer 3 neighbors of high energy layer 2 cells
bool m_treatL1PredictedCellsAsGood
if set to true treat cells with a dead OTX which can be predicted by L1 trigger info as good instead ...
bool m_cellCutsInAbsE
if set to true cell cuts are on and .
float m_neighborThresholdOnEorAbsEinSigma
cells with extend the cluster
std::string m_neighborOption
type of neighbor relations to use.
bool m_clusterCutsInAbsE
if set to true final cluster cuts are on .
bool passCellTimeCut(const CaloCell *, const CaloCellContainer *) const
bool m_xtalkEMEta
if set to true, the time window is softened in the EMB2 and EME2_OW due to xtalk from direct neighbou...
float m_xtalk2Eratio2
cut on Eneighbor/E to revover out of time cell close to energetic second phi neighbor cell
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
bool m_useTimeCutUpperLimit
if set to true, the time cut is not applied on cell of large significance
int m_maxSampling
largest valid seed sampling found
CaloTopoClusterMaker(const std::string &type, const std::string &name, const IInterface *parent)
const CaloCell_ID * m_calo_id
float m_cellThresholdOnEorAbsEinSigma
all cells have to satisfy
bool m_neighborCutsInAbsE
if set to true neighbor cuts are on and .
float m_timeCutUpperLimit
upper limit on the energy significance, for applying the cell time cut
float m_seedThresholdOnTAbs
threshold used for timing cut on seed cells.
float m_clusterEtorAbsEtCut
cut on the final cluster.
std::vector< std::string > m_caloNames
vector of names of the calorimeters to consider.
float m_xtalk2Eratio1
cut on Eneighbor/E to revover out of time cell close to energetic first phi neighbor cell
bool m_xtalkEM2
if set to true, the time window is softened in the EMB2 and EME2_OW due to xtalk from direct neighbou...
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusters) const override
Execute on an entire collection of clusters.
virtual StatusCode initialize() override
std::set< int > m_validSamplings
actual set of samplings to be used for seeds
LArNeighbours::neighbourOption m_nOption
std::vector< std::string > m_samplingNames
vector of names of the calorimeter samplings to consider for seeds.
bool m_restrictPSNeighbors
if set to true limit the neighbors in presampler Barrel and Endcap.
bool m_xtalkEM2n
if set to true (together with m_xtalkEM2) we also extend the time window for 2nd phi neighbors
std::vector< bool > m_useSampling
flag for all samplings - true for used ones, false for excluded ones
int m_minSampling
smallest valid seed sampling found
bool m_seedCutsInT
if set to true, time cut is applied to seed cells, no cut otherwise
bool m_seedCutsInAbsE
if set to true seed cuts are on and .
float m_xtalk3Eratio
cut on Eneighbor/E to revover out of time layer 3cell close to energetic previous sampling neighbor
float m_xtalk2DEratio
cut on Eneighbor/E to remove out of time layer layer2 all 2D neighbors
bool m_restrictHECIWandFCalNeighbors
if set to true limit the neighbors in HEC IW and FCal2&3.
bool m_cutOOTseed
if set to true, seed cells failing the time cut are also excluded from cluster at all
xAOD::CaloCluster::ClusterSize m_clusterSize
Cluster size enum. Set based on energy cut jobO.
const float & getSignedRatio() const
CaloCell_ID::SUBCALO getSubDet() const
const IdentifierHash & getID() const
void setCaloTopoTmpHashCluster(CaloTopoTmpHashCluster *cluster)
const CaloTopoTmpHashCluster * getCaloTopoTmpHashCluster() const
pointer_list::pool_type pool_type
Object reference supporting deferred reading from StoreGate.
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
This is a "hash" representation of an Identifier.
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const std::string & name() const
Return the StoreGate ID for the referenced object.
void addCellLink(CaloClusterCellLink *CCCL)
void setClusterSize(const ClusterSize)
Get cluster size.
void nextDDE(Iter iter, Iter endIter)
Prefetch next CaloDDE.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
static bool isBad(const CaloCell *pCell, bool treatL1PredictedCellsAsGood)