ATLAS Offline Software
CaloCPUOutput.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
7 #include "CaloCPUOutput.h"
8 #include "CaloRecGPU/Helpers.h"
11 #include "StoreGate/DataHandle.h"
12 
13 using namespace CaloRecGPU;
14 
15 CaloCPUOutput::CaloCPUOutput(const std::string & type, const std::string & name, const IInterface * parent):
17 {
18  declareInterface<CaloClusterCollectionProcessor> (this);
19 }
20 
21 
23 {
25 
26  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
27 
28  return StatusCode::SUCCESS;
29 }
30 
31 StatusCode CaloCPUOutput::execute (const EventContext & ctx, xAOD::CaloClusterContainer * cluster_collection) const
32 {
33 
35 
38 
39  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
40  if ( !cell_collection.isValid() )
41  {
42  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
43  return StatusCode::FAILURE;
44  }
45 
46 
47  ret_info.allocate();
48  ret_state.allocate();
49  ret_clusts.allocate();
50 
51  for (int i = 0; i < NCaloCells; ++i)
52  {
53  ret_info->energy[i] = 0;
54  ret_info->gain[i] = GainConversion::invalid_gain();
55  ret_info->time[i] = 0;
56  ret_info->qualityProvenance[i] = 0;
57 
58  ret_state->clusterTag[i] = ClusterTag::make_invalid_tag();
59 
60  }
61 
62  for (CaloCellContainer::const_iterator iCells = cell_collection->begin(); iCells != cell_collection->end(); ++iCells)
63  {
64  const CaloCell * cell = (*iCells);
65 
66  const int index = m_calo_id->calo_cell_hash(cell->ID());
67 
68  const float energy = cell->energy();
69 
70  const unsigned int gain = GainConversion::from_standard_gain(cell->gain());
71 
72  ret_info->energy[index] = energy;
73  ret_info->gain[index] = gain;
74  ret_info->time[index] = cell->time();
75  ret_info->qualityProvenance[index] = QualityProvenance{cell->quality(), cell->provenance()};
76 
77  }
78 
79  size_t shared_count = 0;
80 
81  const auto cluster_end = cluster_collection->end();
82  auto cluster_iter = cluster_collection->begin();
83 
84  for (int cluster_number = 0; cluster_iter != cluster_end; ++cluster_iter, ++cluster_number )
85  {
86  const xAOD::CaloCluster * cluster = (*cluster_iter);
87  const CaloClusterCellLink * cell_links = cluster->getCellLinks();
88  if (!cell_links)
89  {
90  ATH_MSG_ERROR("Can't get valid links to CaloCells (CaloClusterCellLink)!");
91  return StatusCode::FAILURE;
92  }
93 
94  //--- fill data ---
95  ret_clusts->clusterEnergy[cluster_number] = cluster->e();
96  ret_clusts->clusterEt[cluster_number] = cluster->et();
97  ret_clusts->clusterEta[cluster_number] = cluster->eta();
98  ret_clusts->clusterPhi[cluster_number] = cluster->phi();
99 
100  const int seed_cell_index = m_calo_id->calo_cell_hash(cluster->cell_begin()->ID());
101 
102  ret_clusts->seedCellID[cluster_number] = seed_cell_index;
103 
104  for (auto it = cell_links->begin(); it != cell_links->end(); ++it)
105  {
106 
107  const int cell_ID = m_calo_id->calo_cell_hash(it->ID());
108  const float weight = it.weight();
109 
110  uint32_t weight_as_int = 0;
111  std::memcpy(&weight_as_int, &weight, sizeof(float));
112  //On the platforms we expect to be running this, it should be fine.
113  //Still UB.
114  //With C++20, we could do that bit-cast thing.
115 
116  if (weight_as_int == 0)
117  {
118  weight_as_int = 1;
119  //Subnormal,
120  //but just to distinguish from
121  //a non-shared cluster.
122  }
123 
124  const ClusterTag other_tag = ret_state->clusterTag[cell_ID];
125 
126  const int other_index = other_tag.is_part_of_cluster() ? other_tag.cluster_index() : -1;
127 
128  if (other_index < 0)
129  {
130  if (weight < 0.5f)
131  {
132  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, weight_as_int, 0);
133  }
134  else
135  {
136  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number);
137  }
138  }
139  else if (weight > 0.5f)
140  {
141  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, other_tag.secondary_cluster_weight(), other_index);
142  ++shared_count;
143  }
144  else if (weight == 0.5f)
145  //Unlikely, but...
146  {
147  const int max_cluster = cluster_number > other_index ? cluster_number : other_index;
148  const int min_cluster = cluster_number > other_index ? other_index : cluster_number;
149  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(max_cluster, weight_as_int, min_cluster);
150  ++shared_count;
151  }
152  else /*if (weight < 0.5f)*/
153  {
154  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(other_index, weight_as_int, cluster_number);
155  ++shared_count;
156  }
157  }
158  }
159 
160  ret_clusts->number = cluster_collection->size();
161 
162  ATH_MSG_INFO("Clusters: " << ret_clusts->number);
163  ATH_MSG_INFO("Shared Cells: " << shared_count);
164 
165  if (m_saveCellInfo)
166  {
167  const auto err = StandaloneDataIO::save_event_to_folder(ctx.evt(), std::string(m_savePath),
168  ret_info, ret_state, ret_clusts,
170 
172  {
173  return StatusCode::FAILURE;
174  }
175  }
176  else
177  {
178  const auto err1 = StandaloneDataIO::save_cell_state_to_folder(ctx.evt(), std::string(m_savePath),
179  ret_state, m_filePrefix, m_fileSuffix, m_numWidth);
180 
181  const auto err2 = StandaloneDataIO::save_clusters_to_folder(ctx.evt(), std::string(m_savePath),
182  ret_clusts, m_filePrefix, m_fileSuffix, m_numWidth);
183 
185  {
186  return StatusCode::FAILURE;
187  }
188  }
189 
190  return StatusCode::SUCCESS;
191 
192 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
CaloCPUOutput::m_cellsKey
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
Definition: CaloCPUOutput.h:80
xAOD::CaloCluster_v1::cell_begin
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
Definition: CaloCluster_v1.h:812
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
CaloRecGPU::Helpers::SimpleHolder
Holds one objects of type \T in memory context Context.
Definition: Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h:1069
CaloCPUOutput.h
skel.it
it
Definition: skel.GENtoEVGEN.py:423
StandaloneDataIO::save_event_to_folder
static ErrorState save_event_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
Definition: StandaloneDataIO.h:323
xAOD::CaloCluster_v1::et
double et() const
Definition: CaloCluster_v1.h:856
CaloCPUOutput::m_numWidth
Gaudi::Property< unsigned int > m_numWidth
The number of digits to reserve for the events.
Definition: CaloCPUOutput.h:67
DataHandle.h
CaloCPUOutput::initialize
virtual StatusCode initialize() override
Definition: CaloCPUOutput.cxx:22
CaloRecGPU::ClusterTag
Definition: TagDefinitions.h:222
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
CaloCPUOutput::m_saveCellInfo
Gaudi::Property< bool > m_saveCellInfo
If true, also outputs the cell energies, times, gains, qualities and provenances.
Definition: CaloCPUOutput.h:74
CaloRecGPU::ClusterTag::cluster_index
constexpr int32_t cluster_index() const
Definition: TagDefinitions.h:243
CaloCPUOutput::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *cluster_collection) const override
Execute on an entire collection of clusters.
Definition: CaloCPUOutput.cxx:31
StandaloneDataIO::ErrorState::OK
@ OK
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:193
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
lumiFormat.i
int i
Definition: lumiFormat.py:92
Helpers.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
test_pyathena.parent
parent
Definition: test_pyathena.py:15
StandaloneDataIO.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloRecGPU::NCaloCells
constexpr int NCaloCells
Definition: BaseDefinitions.h:13
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:905
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloCPUOutput::m_savePath
Gaudi::Property< std::string > m_savePath
The path specifying the folder to which the files should be saved.
Definition: CaloCPUOutput.h:52
StandaloneDataIO::save_cell_state_to_folder
static ErrorState save_cell_state_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
Definition: StandaloneDataIO.h:362
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
CaloCell::ID
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition: CaloCell.h:279
CaloRecGPU::ClusterTag::is_part_of_cluster
constexpr bool is_part_of_cluster() const
Definition: TagDefinitions.h:233
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
CaloCPUOutput::m_fileSuffix
Gaudi::Property< std::string > m_fileSuffix
The suffix of the saved files.
Definition: CaloCPUOutput.h:62
DeMoScan.index
string index
Definition: DeMoScan.py:362
CaloCPUOutput::m_filePrefix
Gaudi::Property< std::string > m_filePrefix
The prefix of the saved files.
Definition: CaloCPUOutput.h:57
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CaloRecGPU::QualityProvenance
Definition: EventInfoDefinitions.h:116
CUDAFriendlyClasses.h
StandaloneDataIO::save_clusters_to_folder
static ErrorState save_clusters_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
Definition: StandaloneDataIO.h:420
CaloCPUOutput::CaloCPUOutput
CaloCPUOutput(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloCPUOutput.cxx:15
AthAlgTool
Definition: AthAlgTool.h:26
CaloRecGPU
Definition: BaseDefinitions.h:11
CaloCPUOutput::m_calo_id
const CaloCell_ID * m_calo_id
Pointer to Calo ID Helper.
Definition: CaloCPUOutput.h:85
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
CaloRecGPU::ClusterTag::secondary_cluster_weight
constexpr int32_t secondary_cluster_weight() const
Definition: TagDefinitions.h:263
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.