Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CaloCPUOutput.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2025 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):
16  base_class(type, name, parent)
17 {
18 }
19 
20 
22 {
24 
25  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
26 
27  return StatusCode::SUCCESS;
28 }
29 
30 StatusCode CaloCPUOutput::execute (const EventContext & ctx, xAOD::CaloClusterContainer * cluster_collection) const
31 {
32 
34 
37 
38  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
39  if ( !cell_collection.isValid() )
40  {
41  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
42  return StatusCode::FAILURE;
43  }
44 
45 
46  ret_info.allocate();
47  ret_state.allocate();
48  ret_clusts.allocate();
49 
50  for (int i = 0; i < NCaloCells; ++i)
51  {
52  ret_info->energy[i] = 0;
53  ret_info->gain[i] = GainConversion::invalid_gain();
54  ret_info->time[i] = 0;
55  ret_info->qualityProvenance[i] = 0;
56 
57  ret_state->clusterTag[i] = ClusterTag::make_invalid_tag();
58 
59  }
60 
61  for (CaloCellContainer::const_iterator iCells = cell_collection->begin(); iCells != cell_collection->end(); ++iCells)
62  {
63  const CaloCell * cell = (*iCells);
64 
65  const int index = m_calo_id->calo_cell_hash(cell->ID());
66 
67  const float energy = cell->energy();
68 
69  const unsigned int gain = GainConversion::from_standard_gain(cell->gain());
70 
71  ret_info->energy[index] = energy;
72  ret_info->gain[index] = gain;
73  ret_info->time[index] = cell->time();
74  ret_info->qualityProvenance[index] = QualityProvenance{cell->quality(), cell->provenance()};
75 
76  }
77 
78  size_t shared_count = 0;
79 
80  const auto cluster_end = cluster_collection->end();
81  auto cluster_iter = cluster_collection->begin();
82 
83  for (int cluster_number = 0; cluster_iter != cluster_end; ++cluster_iter, ++cluster_number )
84  {
85  const xAOD::CaloCluster * cluster = (*cluster_iter);
86  const CaloClusterCellLink * cell_links = cluster->getCellLinks();
87  if (!cell_links)
88  {
89  ATH_MSG_ERROR("Can't get valid links to CaloCells (CaloClusterCellLink)!");
90  return StatusCode::FAILURE;
91  }
92 
93  //--- fill data ---
94  ret_clusts->clusterEnergy[cluster_number] = cluster->e();
95  ret_clusts->clusterEt[cluster_number] = cluster->et();
96  ret_clusts->clusterEta[cluster_number] = cluster->eta();
97  ret_clusts->clusterPhi[cluster_number] = cluster->phi();
98 
99  const int seed_cell_index = m_calo_id->calo_cell_hash(cluster->cell_begin()->ID());
100 
101  ret_clusts->seedCellID[cluster_number] = seed_cell_index;
102 
103  for (auto it = cell_links->begin(); it != cell_links->end(); ++it)
104  {
105 
106  const int cell_ID = m_calo_id->calo_cell_hash(it->ID());
107  const float weight = it.weight();
108 
109  uint32_t weight_as_int = 0;
110  std::memcpy(&weight_as_int, &weight, sizeof(float));
111  //On the platforms we expect to be running this, it should be fine.
112  //Still UB.
113  //With C++20, we could do that bit-cast thing.
114 
115  if (weight_as_int == 0)
116  {
117  weight_as_int = 1;
118  //Subnormal,
119  //but just to distinguish from
120  //a non-shared cluster.
121  }
122 
123  const ClusterTag other_tag = ret_state->clusterTag[cell_ID];
124 
125  const int other_index = other_tag.is_part_of_cluster() ? other_tag.cluster_index() : -1;
126 
127  if (other_index < 0)
128  {
129  if (weight < 0.5f)
130  {
131  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, weight_as_int, 0);
132  }
133  else
134  {
135  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number);
136  }
137  }
138  else if (weight > 0.5f)
139  {
140  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, other_tag.secondary_cluster_weight(), other_index);
141  ++shared_count;
142  }
143  else if (weight == 0.5f)
144  //Unlikely, but...
145  {
146  const int max_cluster = cluster_number > other_index ? cluster_number : other_index;
147  const int min_cluster = cluster_number > other_index ? other_index : cluster_number;
148  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(max_cluster, weight_as_int, min_cluster);
149  ++shared_count;
150  }
151  else /*if (weight < 0.5f)*/
152  {
153  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(other_index, weight_as_int, cluster_number);
154  ++shared_count;
155  }
156  }
157  }
158 
159  ret_clusts->number = cluster_collection->size();
160 
161  ATH_MSG_INFO("Clusters: " << ret_clusts->number);
162  ATH_MSG_INFO("Shared Cells: " << shared_count);
163 
164  if (m_saveCellInfo)
165  {
166  const auto err = StandaloneDataIO::save_event_to_folder(ctx.evt(), std::string(m_savePath),
167  ret_info, ret_state, ret_clusts,
169 
171  {
172  return StatusCode::FAILURE;
173  }
174  }
175  else
176  {
177  const auto err1 = StandaloneDataIO::save_cell_state_to_folder(ctx.evt(), std::string(m_savePath),
178  ret_state, m_filePrefix, m_fileSuffix, m_numWidth);
179 
180  const auto err2 = StandaloneDataIO::save_clusters_to_folder(ctx.evt(), std::string(m_savePath),
181  ret_clusts, m_filePrefix, m_fileSuffix, m_numWidth);
182 
184  {
185  return StatusCode::FAILURE;
186  }
187  }
188 
189  return StatusCode::SUCCESS;
190 
191 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
CaloCPUOutput::m_cellsKey
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
Definition: CaloCPUOutput.h:80
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:67
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:1067
CaloCPUOutput.h
skel.it
it
Definition: skel.GENtoEVGEN.py:407
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
CaloCPUOutput::m_numWidth
Gaudi::Property< unsigned int > m_numWidth
The number of digits to reserve for the events.
Definition: CaloCPUOutput.h:67
DataHandle.h
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
CaloCPUOutput::initialize
virtual StatusCode initialize() override
Definition: CaloCPUOutput.cxx:21
CaloRecGPU::ClusterTag
Definition: TagDefinitions.h:222
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
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
Definition: CaloCPUOutput.cxx:30
StandaloneDataIO::ErrorState::OK
@ OK
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
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:182
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
hist_file_dump.f
f
Definition: hist_file_dump.py:141
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:794
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
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
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:240
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:364
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
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
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.
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.