ATLAS Offline Software
Loading...
Searching...
No Matches
HIEventShapeJetIteration.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
12
16
17namespace
18{
19 struct SelectByList{
20
21 SelectByList() : used_set(nullptr) {};
22 const std::set<unsigned int>* used_set;
23 bool operator()(const xAOD::HIEventShape* in_slice)
24 {
25 unsigned int eb=HI::TowerBins::findBinEta(0.5*(in_slice->etaMin()+in_slice->etaMax()));
26 return (used_set->find(eb)==used_set->end());
27 }
28
29 };
30} //annonymous namespace
31
32
34{
35}
36
38{
39 ATH_MSG_VERBOSE("HIEventShapeJetIteration initialize");
40 ATH_CHECK( m_inputEventShapeKey.initialize( !m_inputEventShapeKey.key().empty()) );
41 ATH_CHECK( m_outputEventShapeKey.initialize( !m_outputEventShapeKey.key().empty()) );
45
46 return StatusCode::SUCCESS;
47}
48
50{
52 ATH_MSG_DEBUG( "Starting HIEventShapeJetIteration execution" );
53 const xAOD::HIEventShapeContainer* input_shape=nullptr;
54 xAOD::HIEventShapeContainer* output_shape=nullptr;
55 getShapes(input_shape,output_shape,true).ignore();
56
57 const HIEventShapeIndex* es_index = m_eventShapeMapTool->getIndexFromShape(input_shape);
58 //New implementation after moving away from mutable
59 ATH_MSG_DEBUG("HIEventShapeJetIteration: found index for " << m_inputEventShapeKey.key());
60 if(es_index==nullptr)
61 {
62 ATH_MSG_FATAL("No HIEventShapeIndex w/ name " << m_inputEventShapeKey.key() << ". Shape not TOWER nor COMPACT");
63 }
64
65 const HIEventShapeIndex* other_index = m_eventShapeMapTool->getIndexFromShape(output_shape);
66 if(!other_index) {
67 ATH_MSG_FATAL("No HIEventShapeIndex w/ name " << m_outputEventShapeKey.key() << ". Shape not TOWER nor COMPACT");
68 }
69 //End of new implementation
70
71 const xAOD::JetContainer* theCaloJets=0;
72 const xAOD::JetContainer* theTrackJets=0;
73
74 if(!m_caloJetSeedKey.empty()){
76 theCaloJets = readHandleCaloJets.cptr();
77 }
78 if(!m_trackJetSeedKey.empty()){
80 theTrackJets = readHandleTrackJets.cptr();
81 }
82
83 if(theTrackJets && m_excludeConstituents)
84 {
85 ATH_MSG_ERROR("Incompatible options. Cannot track jets and constituents together.");
86 return 1;
87 }
88
89 std::set<unsigned int> used_indices;
90 std::set<unsigned int> used_eta_bins;
91
92 std::vector<const xAOD::CaloCluster*> assoc_clusters;
93 assoc_clusters.reserve(6400);
94 if(theCaloJets) ATH_CHECK(makeClusterList(assoc_clusters,theCaloJets,used_indices,used_eta_bins), 1);
95 if(theTrackJets) ATH_CHECK(makeClusterList(assoc_clusters,theTrackJets,used_indices,used_eta_bins), 1);
96 updateShape(output_shape,assoc_clusters,es_index);
97
98 ATH_MSG_DEBUG( "Checking Modulation Scheme" );
99
100 //compute ES for modulation
102 {
104 ATH_MSG_DEBUG( "Key HIEventShapeJetIteration: " << m_modulationKey.key() );
105
106 auto modShape = std::make_unique<xAOD::HIEventShapeContainer> ();
107 auto modShapeAux = std::make_unique<xAOD::HIEventShapeAuxContainer> ();
108 modShape->setStore( modShapeAux.get() );
109
111 modShape->push_back(ms);
112 ATH_CHECK( fillModulatorShape(ms, output_shape, used_eta_bins, m_modulationScheme), 1 );
113 if(m_doRemodulation) ATH_CHECK( remodulate(output_shape, ms, used_indices), 1 );
114
115 if(write_handle_modShape.record ( std::move(modShape), std::move(modShapeAux)).isFailure() ){
116 ATH_MSG_ERROR("Unable to write newHIEventShapeContainer for modulated shape with key: " << m_modulationKey.key());
117 return 0;
118 }
119 }
120
121 return 0;
122}
123
124StatusCode HIEventShapeJetIteration::makeClusterList(std::vector<const xAOD::CaloCluster*>& particleList, const xAOD::JetContainer* theJets,
125 std::set<unsigned int>& used_indices, std::set<unsigned int>& used_eta_bins) const
126{
127 for(const auto *theJet : *theJets)
128 {
129 xAOD::IParticle::FourMom_t jet4mom=theJet->p4();
130 std::vector<const xAOD::IParticle*> assoc_clusters;
131 //only use jet constituents
132 if(m_excludeConstituents) assoc_clusters=theJet->getConstituents().asIParticleVector();
133 else
134 {
135 if(! (theJet->getAssociatedObjects<xAOD::IParticle>(m_associationKey, assoc_clusters)) )
136 {
137 //this should only happen if SOME of the jets in the collection are missing the association
138 //technically possible, but should NOT happen
139 ATH_MSG_ERROR("Individual jet missing association " << m_associationKey);
140 return StatusCode::FAILURE;
141 }
142 }
143 ATH_MSG_DEBUG( "Jet " << std::setw(10) << jet4mom.Pt()*1e-3
144 << std::setw(10) << jet4mom.Eta()
145 << std::setw(10) << jet4mom.Phi()
146 << std::setw(10) << jet4mom.E()*1e-3
147 << std::setw(25) << " has " << assoc_clusters.size() << " assoc. clusters");
148
149 for(auto & assoc_cluster : assoc_clusters)
150 {
151 if( jet4mom.DeltaR( assoc_cluster->p4() ) > m_excludeDR ) continue;
152 const xAOD::CaloCluster* cl_ptr=static_cast<const xAOD::CaloCluster*>(assoc_cluster);
153 unsigned int tower_index=HI::TowerBins::findEtaPhiBin(cl_ptr->eta0(),cl_ptr->phi0());
154
155 if(used_indices.insert(tower_index).second)
156 {
157 particleList.push_back(cl_ptr);
158 used_eta_bins.insert(HI::TowerBins::findBinEta(cl_ptr->eta0()));
159 }
160 }
161 }
162 return StatusCode::SUCCESS;
163
164}
165
166StatusCode HIEventShapeJetIteration::makeClusterList(std::vector<const xAOD::CaloCluster*>& particleList, const xAOD::JetContainer* theJets) const
167{
168 std::set<unsigned int> used_indices;
169 std::set<unsigned int> used_eta_bins;
170 return makeClusterList(particleList,theJets,used_indices,used_eta_bins);
171}
172StatusCode HIEventShapeJetIteration::makeClusterList(std::vector<const xAOD::CaloCluster*>& particleList, const std::vector<const xAOD::JetContainer*>& theJets_vector) const
173{
174 std::set<unsigned int> used_indices;
175 std::set<unsigned int> used_eta_bins;
176 for(const auto *theJets : theJets_vector)
177 {
178 ATH_CHECK(makeClusterList(particleList,theJets,used_indices,used_eta_bins));
179 }
180 return StatusCode::SUCCESS;
181}
182
183void HIEventShapeJetIteration::updateShape(xAOD::HIEventShapeContainer* output_shape, const std::vector<const xAOD::CaloCluster*>& assoc_clusters, const HIEventShapeIndex* es_index ) const
184{
185 if(es_index==nullptr)
186 {
187 ATH_MSG_INFO("Problem, null pointer");
188
189 es_index=m_eventShapeMapTool->getIndexFromShape(output_shape);
190 if(es_index==nullptr)
191 {
192 ATH_MSG_FATAL("Can't find correspondent index for map " << m_inputEventShapeKey.key() << " in the HIEventShapeMapTool");
193 }
194 }
195
196 for(const auto *assoc_cluster : assoc_clusters)
197 {
198 m_subtractorTool->updateUsingCluster(output_shape,es_index,assoc_cluster);
199 }
200
201 if(!m_subtractorTool->usesCells())
202 {
203 for(auto s : *output_shape)
204 {
205 float sum_et=s->et();
206 float sum_nc=0.;
207 if(sum_et!=0.) sum_nc=s->rho()*s->area()/sum_et;
208 s->setNCells(sum_nc);
209 }
210 }
211}
212
213StatusCode HIEventShapeJetIteration::fillModulatorShape(xAOD::HIEventShape* ms, const xAOD::HIEventShapeContainer* output_shape, const std::set<unsigned int>& used_eta_bins, unsigned int scheme) const
214{
215 if(scheme==1 || scheme==2)
216 {
217 SelectByList selector;
218 selector.used_set=&used_eta_bins;
219 HI::fillSummary(output_shape,ms,selector);
220 }
221
222 if(scheme > 1)
223 {
224 const xAOD::HIEventShapeContainer* summary_container=0;
225
226 SG::ReadHandle<xAOD::HIEventShapeContainer> read_handle_cont ( "CaloSums" );
227 if (!read_handle_cont.isValid()) {
228 ATH_MSG_FATAL( "Could not find HI event shape! CaloSums" );
229 return(StatusCode::FAILURE);
230 }
231 summary_container = read_handle_cont.cptr();
232
233 const xAOD::HIEventShape* s_fcal=0;
234 for(const auto *sh : *summary_container)
235 {
236 std::string summary;
237 static const SG::ConstAccessor<std::string> SummaryAcc("Summary");
238 if(SummaryAcc.isAvailable(*sh)) summary=SummaryAcc(*sh);
239 if(summary.compare("FCal")==0)
240 {
241 s_fcal=sh;
242 break;
243 }
244 }
245 if (!s_fcal) std::abort();
246 if(scheme==3) (*ms)=(*s_fcal);
247 else
248 {
249 float et_fcal=s_fcal->et();
250 float et_fcal_recip=0;
251 if(et_fcal > 0.) et_fcal_recip=1.0/et_fcal;
252 for(unsigned int ih=0; ih < ms->etCos().size(); ih++)
253 {
254 float qx=ms->etCos().at(ih);
255 float qy=ms->etSin().at(ih);
256
257 float qx_fcal=s_fcal->etCos().at(ih);
258 float qy_fcal=s_fcal->etSin().at(ih);
259
260 ms->etCos()[ih]=(qx*qx_fcal+qy*qy_fcal)*et_fcal_recip;
261 ms->etSin()[ih]=(qy*qx_fcal-qx*qy_fcal)*et_fcal_recip;
262 } //end loop on harmonics
263 } //end scheme==2
264 } // end modulation > 1 case
265 return StatusCode::SUCCESS;
266}
267
268
269StatusCode HIEventShapeJetIteration::remodulate(xAOD::HIEventShapeContainer* output_shape, const xAOD::HIEventShape* ms, const std::set<unsigned int>& used_indices) const
270{
271 std::vector<float> mod_factors(HI::TowerBins::numEtaBins(),0);
272 std::vector<float> mod_counts(HI::TowerBins::numEtaBins(),0);
273
274 for(unsigned int used_indice : used_indices)
275 {
276 unsigned int phi_bin=used_indice % HI::TowerBins::numPhiBins();
277 unsigned int eta_bin=used_indice / HI::TowerBins::numPhiBins();
278 mod_counts[eta_bin]++;
279 mod_factors[eta_bin]+=(m_modulatorTool->getModulation(HI::TowerBins::getBinCenterPhi(phi_bin),ms)-1.);
280 }
281 double nphibins=HI::TowerBins::numPhiBins();
282 //now loop on shape and correct;
283 for(auto && i : *output_shape)
284 {
286 float eta0=0.5*(s->etaMin()+s->etaMax());
287 unsigned int eb=HI::TowerBins::findBinEta(eta0);
288 double neff=nphibins-mod_counts[eb];
289 double cf=1;
290 if (neff-mod_factors[eb] != 0) {//PEF fix
291 cf=neff/(neff-mod_factors[eb]);
292 }
293 //check on value of cf;
294 if(cf < 0.) cf =1;
295 if(cf > 2.) cf=2;
296
297 s->setEt(s->et()*cf);
298 s->setRho(s->rho()*cf);
299 }
300
301 return StatusCode::SUCCESS;
302}
303
304StatusCode HIEventShapeJetIteration::getShapes(const xAOD::HIEventShapeContainer*& input_shape, xAOD::HIEventShapeContainer*& output_shape, bool record) const
305{
308
309 input_shape = readHandleEvtShape.ptr();
310
311 if(m_shallowCopy)
312 {
313 auto shape_copy=xAOD::shallowCopyContainer(*input_shape);
314 auto unique_first_copy = xAOD::prepareElementForShallowCopy(shape_copy.first);
315 auto unique_second_copy = xAOD::prepareElementForShallowCopy(shape_copy.second);
316 output_shape=shape_copy.first;
317 if(record)
318 {
319 ATH_MSG_DEBUG( "Write Handle current key is : " << m_outputEventShapeKey.key() );
320 if(writeHandleEvtShape.record ( std::move(unique_first_copy), std::move(unique_second_copy)).isFailure() ){
321 ATH_MSG_ERROR("Unable to write Shallow Copy containers for event shape with key: " << m_outputEventShapeKey.key());
322 return(StatusCode::FAILURE);
323 }
324 }
325
326 }
327 else
328 {
329 auto output_shapex=std::make_unique<xAOD::HIEventShapeContainer> ();
330 auto output_Aux=std::make_unique<xAOD::HIEventShapeAuxContainer> ();
331 output_shapex->setStore( output_Aux.get() );
332 output_shapex->reserve( input_shape->size() );
333
334 for(const auto *s : *input_shape)
335 {
337 output_shapex->push_back(s_copy);
338 *s_copy=*s;
339 }
340 if(record)
341 {
342 if(writeHandleEvtShape.record ( std::move(output_shapex), std::move(output_Aux)).isFailure() ){
343 ATH_MSG_ERROR("Unable to write Output Shape containers for event shape with key: " << m_outputEventShapeKey.key());
344 return(StatusCode::FAILURE);
345 }
346 output_shape = writeHandleEvtShape.ptr();
347 }
348
349 }
350
351 return StatusCode::SUCCESS;
352}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide constant type-safe access to aux data.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
size_type size() const noexcept
Returns the number of elements in the collection.
ToolHandle< IHIEventShapeMapTool > m_eventShapeMapTool
Gaudi::Property< std::string > m_associationKey
Name of jet attribute providing link between jets and clusters.
Gaudi::Property< bool > m_shallowCopy
HIEventShapeJetIteration(const std::string &name)
Gaudi::Property< unsigned int > m_modulationScheme
StatusCode fillModulatorShape(xAOD::HIEventShape *ms, const xAOD::HIEventShapeContainer *output_shape, const std::set< unsigned int > &used_indices, unsigned int scheme) const
StatusCode makeClusterList(std::vector< const xAOD::CaloCluster * > &particleList, const xAOD::JetContainer *theJets, std::set< unsigned int > &used_indices, std::set< unsigned int > &used_eta_bins) const
StatusCode remodulate(xAOD::HIEventShapeContainer *output_shape, const xAOD::HIEventShape *ms, const std::set< unsigned int > &used_indices) const
void updateShape(xAOD::HIEventShapeContainer *output_shape, const std::vector< const xAOD::CaloCluster * > &assoc_clusters, const HIEventShapeIndex *es_index=nullptr) const
SG::WriteHandleKey< xAOD::HIEventShapeContainer > m_outputEventShapeKey
Name of output HIEventShapeContainer.
StatusCode getShapes(const xAOD::HIEventShapeContainer *&input_shape, xAOD::HIEventShapeContainer *&output_shape, bool record_aux=false) const
virtual int execute() const override
Method to be called for each event.
Gaudi::Property< bool > m_doRemodulation
SG::ReadHandleKey< xAOD::HIEventShapeContainer > m_inputEventShapeKey
Name of input HIEventShapeContainer.
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
SG::ReadHandleKey< xAOD::JetContainer > m_trackJetSeedKey
ToolHandle< IHISubtractorTool > m_subtractorTool
SG::WriteHandleKey< xAOD::HIEventShapeContainer > m_modulationKey
SG::ReadHandleKey< xAOD::JetContainer > m_caloJetSeedKey
List of names of JetCollections, all jets in these collections are seeds.
ToolHandle< IHIUEModulatorTool > m_modulatorTool
Gaudi::Property< float > m_excludeDR
All clusters w/in this DR of jet are excluded from shape calc.
Gaudi::Property< bool > m_excludeConstituents
If selected, the jet constituents define the associated clusters.
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.
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
flt_t eta0() const
Returns raw of cluster seed.
flt_t phi0() const
Returns raw of cluster seed.
float etaMax() const
eta slice "right" edge
const std::vector< float > & etSin() const
sine (x) part of the harmonic modulation strength
const std::vector< float > & etCos() const
cosine (y) part of the harmonic modulation strength Following convention is used: index 0 is first ha...
float et() const
Transverse energy reconstructed on the slice.
float etaMin() const
eta slice "left" edge
Class providing the definition of the 4-vector interface.
TLorentzVector FourMom_t
Definition of the 4-momentum type.
constexpr unsigned int numPhiBins()
Definition HIEventDefs.h:22
unsigned int findEtaPhiBin(float eta, float phi)
Definition HIEventDefs.h:52
unsigned int findBinEta(float eta)
Definition HIEventDefs.h:46
constexpr unsigned int numEtaBins()
Definition HIEventDefs.h:19
float getBinCenterPhi(unsigned int pb)
Definition HIEventDefs.h:44
void fillSummary(const xAOD::HIEventShapeContainer *in, xAOD::HIEventShape *out, const std::function< bool(const xAOD::HIEventShape *)> &incFunction, const std::function< void(xAOD::HIEventShape *, const xAOD::HIEventShape *)> &addFunction)
std::unique_ptr< CaloCluster > prepareElementForShallowCopy(const CaloCluster *orgCluster)
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
HIEventShapeContainer_v2 HIEventShapeContainer
Define the latest version of the container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
HIEventShape_v2 HIEventShape
Definition of the latest event info version.