ATLAS Offline Software
Loading...
Searching...
No Matches
CaloClusterContainerCnv_p4.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
12//#include "CaloEvent/CaloSampling.h"
15
16
17namespace {
18
19inline
20bool testbit (unsigned int x, unsigned int i)
21{
22 return (x & (1U << i)) != 0;
23}
24
25} // anonymous namespace
26
27
30 MsgStream &log) const
31{
32 if (log.level() <= MSG::DEBUG) log<< MSG::DEBUG << "Reading CaloClusterContainerCnv_p4" << endmsg;
33
34 // reset element link converters, and provide container name lookup table
35 ShowerLinkState showerLinkState (pers->m_linkNames);
36 CellLinkState cellLinkState (pers->m_linkNames);
37
38 // Use data pool for clusters to avoid calling constructor for each event
39 DataPool<CaloCluster> clusters;
40
41 trans->clear (SG::VIEW_ELEMENTS);
42 trans->reserve(pers->m_vec.size());
43
46
47 std::vector<float> temp_Moments;
49 A.expandToFloat( pers->m_momentContainer.m_Mvalue, temp_Moments); // unpacks moments
50
51 std::vector<float>::const_iterator i_mom = temp_Moments.begin();
52 std::vector<float>::const_iterator i_mom_e = temp_Moments.end();
53
54 const std::vector<unsigned short>& keys = pers->m_momentContainer.m_Mkey;
55 unsigned int nkeys = keys.size();
56
57 unsigned int c1=0;
58
59 std::vector<float> tmp_badChannelEta;
60 std::vector<float> tmp_badChannelPhi;
61 Compressor B;
62 B.expandToFloat(pers->m_badEtaList,tmp_badChannelEta);
63 B.expandToFloat(pers->m_badPhiList,tmp_badChannelPhi);
64
65 std::vector<float> tmp_rawE;
67 C.expandToFloat(pers->m_rawEEtaPhiM,tmp_rawE);
68 std::vector<float>::const_iterator iraw1 = tmp_rawE.begin();
69 std::vector<float>::const_iterator iraw2 = tmp_rawE.end();
70
71 std::vector<short>::const_iterator ibad1 = pers->m_badClusIndexList.begin();
72 std::vector<short>::const_iterator ibad2 = pers->m_badClusIndexList.end();
73 int nbad=0;
74
75 bool mom_overrun_err = false;
76 bool store_overrun_err = false;
77 bool raw_overrun_err = false;
78 size_t dataStore_size = pers->m_dataStore.size();
79
80 bool fillBad=true;
81 if (tmp_badChannelEta.size() != pers->m_badClusIndexList.size() ||
82 tmp_badChannelPhi.size() != pers->m_badClusIndexList.size() ||
83 pers->m_badLayerStatusList.size() != pers->m_badClusIndexList.size()) {
84 log << MSG::WARNING << " problem to decode bad channel information, not filled..." << endmsg;
85 fillBad=false;
86 }
87
88 short index=0;
89 for(;itp!=itp_e;++itp) {
90 index++;
91
92 CaloCluster* transCluster = clusters.nextElementPtr();// Get next ptr for next cluster
93 persToTrans(&(*itp),transCluster,
94 showerLinkState,
95 cellLinkState,
96 log); //Convert Cluster-quantities
97
98 CaloSamplingData *trDS =&(transCluster->m_dataStore);
99
101 int nVar=trDS->getNumberOfVariableTypes();
102 int nSamplings=trDS->getNumberOfSamplings();
103
106
107 for (int i=0;i<nVar;++i) {// here loops to read them in ...
108 if (testbit (trDS->m_varTypePattern, i)) {
109
110 // can be optimized: no decoding for each variable.
111 for (int j=0;j<nSamplings; ++j){
112
113 if ( testbit(transCluster->m_samplingPattern, j) ){
114 float val;
115 if (c1 < dataStore_size)
116 val = pers->m_dataStore[c1++];
117 else {
118 val = 0;
119 if (!store_overrun_err) {
120 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
121 "CaloClusterContainerCnv_p4")
122 << "Corrupted data: data store array overrun "
123 << pers->m_vec.size() << " clusters "
124 << nkeys << " moment keys "
125 << temp_Moments.size() << " total moments.";
126 store_overrun_err = true;
127 }
128 }
129 trDS->storeData(static_cast<vartype>(i),
130 static_cast<samptype>(j),
131 val);
132 }
133 else{
134
135 trDS->removeVariable(static_cast<vartype>(i),
136 static_cast<samptype>(j));
137 //std::cout<<"a:0"<<"\t";
138 }
139 }
140 // std::cout<<std::endl;
141 }
142 else
143 trDS->removeVariable(static_cast<vartype>(i));
144 }
145
146 transCluster->m_barrel= (bool)(0x001ff00f & transCluster->m_samplingPattern);
147 transCluster->m_endcap= (bool)(0x00e00ff0 & transCluster->m_samplingPattern);
148 // std::cout<<" <<< Read"<<std::endl;
149
150
151 //Convert moment store
153 for (unsigned short i=0;i<nkeys;++i) {
154 float val;
155 if (i_mom == i_mom_e) {
156 val = 0;
157 if (!mom_overrun_err) {
158 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
159 "CaloClusterContainerCnv_p4")
160 << "Corrupted data: moment array overrun "
161 << pers->m_vec.size() << " clusters "
162 << nkeys << " moment keys "
163 << temp_Moments.size() << " total moments.";
164 mom_overrun_err = true;
165 }
166 }
167 else {
168 val = *i_mom;
169 ++i_mom;
170 }
171 transStore.insert (transStore.end(), CaloClusterMomentStore::moment_store::value_type( keys[i], val ) );
172 }
173 transCluster->m_momentStore.setMomentStore (std::move (transStore));
174
175 // fill bad channel information
176 transCluster->resetBadChannel();
177 if (fillBad){
178 while (ibad1 != ibad2 && (*ibad1) ==index) {
179 float eta = tmp_badChannelEta[nbad] + transCluster->eta();
180 float phi = CaloPhiRange::fix(tmp_badChannelPhi[nbad] + transCluster->phi());
181 short status=pers->m_badLayerStatusList[nbad];
182 CaloSampling::CaloSample layer = (CaloSampling::CaloSample) (status & 0xff);
183 CaloBadChannel flag = CaloBadChannel( ((status>>8) & 0xff) );
184 CaloClusterBadChannelData data(eta,phi,layer,flag);
185 // std::cout << " add bad channel data " << transCluster << " " << eta << " " << phi << " " << layer << " " << status << " " << flag.packedData() << std::endl;
186 transCluster->addBadChannel(data);
187 ++ibad1;
188 ++nbad;
189 }
190 }
191
192// fill raw E,eta,phi,M
193 if (iraw1 != iraw2) {
194 if (std::fabs(transCluster->e())>0.1) {
195 transCluster->m_rawE = (*iraw1) * transCluster->e();
196 }
197 else
198 transCluster->m_rawE = (*iraw1);
199 ++iraw1;
200 }
201 if (iraw1 != iraw2) {
202 transCluster->m_rawEta = (*iraw1) + transCluster->eta();
203 ++iraw1;
204 }
205 if (iraw1 != iraw2) {
206 transCluster->m_rawPhi = CaloPhiRange::fix((*iraw1)+transCluster->phi());
207 ++iraw1;
208 }
209 if (iraw1 == iraw2 && !raw_overrun_err) {
210 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
211 "CaloClusterContainerCnv_p4")
212 << "Corrupted data: raw array overrun "
213 << pers->m_vec.size() << " clusters "
214 << tmp_rawE.size() << " raw values.";
215 raw_overrun_err = true;
216 }
217 if (iraw1 != iraw2) {
218 transCluster->m_rawM = (*iraw1);
219 ++iraw1;
220 }
221 // std::cout << " perstotrans rawE/eta/phi/M " << transCluster->m_rawE << " " << transCluster->m_rawEta << " " <<
222 // transCluster->m_rawPhi << " " << transCluster->m_rawM << std::endl;
223
224 // no alt calib information available in p4 persistent
225 transCluster->m_altE=0.;
226 transCluster->m_altEta=0.;
227 transCluster->m_altPhi=0.;
228 transCluster->m_altM=0.;
229
230
231 trans->push_back(transCluster);
232 }
233
234 if (i_mom != i_mom_e && !mom_overrun_err) {
235 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
236 "CaloClusterContainerCnv_p4")
237 << "Corrupted data: not all moments read "
238 << pers->m_vec.size() << " clusters "
239 << nkeys << " moment keys "
240 << temp_Moments.size() << " total moments "
241 << i_mom-temp_Moments.begin() << " read.";
242 }
243
244 if (c1 != dataStore_size && !store_overrun_err) {
245 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
246 "CaloClusterContainerCnv_p4")
247 << "Corrupted data: not all data store members read "
248 << dataStore_size << " elements "
249 << c1 << " read.";
250 }
251
252 if (iraw1 != iraw2 && !raw_overrun_err) {
253 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
254 "CaloClusterContainerCnv_p4")
255 << "Corrupted data: not all raw values read "
256 << pers->m_vec.size() << " clusters "
257 << tmp_rawE.size() << " raw values "
258 << iraw1-tmp_rawE.begin() << " read.";
259 }
260
261 if (ibad1 != ibad2) {
262 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
263 "CaloClusterContainerCnv_p4")
264 << "Corrupted data: not all bad data read "
265 << pers->m_badClusIndexList.size() << " bad values "
266 << nbad << " read.";
267 }
268
269 //Convert TowerSegment
270 CaloTowerSeg seg;
271 m_caloTowerSegCnv.persToTrans(&(pers->m_towerSeg),&seg);
272 trans->setTowerSeg (seg);
273}
274
275
276
279 MsgStream &log) const
280{
281 if (log.level() <= MSG::DEBUG) log<< MSG::DEBUG << "Writing CaloClusterContainerCnv_p4" << endmsg;
282
283
284 // reset element link converters, and provide container name lookup table
285 ShowerLinkState showerLinkState (pers->m_linkNames);
286 CellLinkState cellLinkState (pers->m_linkNames);
287
288 pers->m_vec.resize(trans->size());
292
293 pers->m_badClusIndexList.clear();
294 pers->m_badLayerStatusList.clear();
295 pers->m_badEtaList.clear();
296 pers->m_badPhiList.clear();
297
298 pers->m_rawEEtaPhiM.clear();
299
300 // Set varTypePattern to the OR of the patterns of all clusters.
301 // (For samplings.)
302 // Trigger can make cluster collections with multiple pattern masks!
303 //
304 // Also pick up moment keys here. Trigger can make clusters with no
305 // stored moments, so we need to look until we find one that isn't empty.
306 // Store the moment keys and their number.
307 pers->m_varTypePattern=0;
308 pers->m_momentContainer.m_Mkey.clear();
310 for (CaloClusterContainer::const_iterator it2 = it; it2 != it_e; ++it2)
311 {
312 const CaloCluster& cl = **it2;
313 const CaloClusterMomentStore& ms = cl.m_momentStore;
314 pers->m_varTypePattern |= cl.m_dataStore.m_varTypePattern;
315
316 if (pers->m_momentContainer.m_nMoments == 0 && ms.size() != 0) {
318 int nMom=ms.size();
319 pers->m_momentContainer.m_nMoments = nMom;
320 for (int w=0; w<nMom; w++){ // here stores moment keys per container not cluster
321 pers->m_momentContainer.m_Mkey.push_back(mit.getMomentType());
322 ++mit;
323 }
324 }
325 else if (ms.size() > 0 && pers->m_momentContainer.m_nMoments != ms.size())
326 {
327 REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,
328 "CaloClusterContainerCnv_p4")
329 << "Inconsistent number of cluster moments: cluster "
330 << it2 - trans->begin() << " of " << trans->size()
331 << " have " << ms.size()
332 << " expect " << pers->m_momentContainer.m_nMoments;
333 }
334
335 }
336
337 std::vector<float> temp_Moments;
338 temp_Moments.reserve (trans->size() * pers->m_momentContainer.m_nMoments);
339 std::vector<float> tmp_badChannelEta;
340 std::vector<float> tmp_badChannelPhi;
341
342 std::vector<float> tmp_rawE;
343 tmp_rawE.reserve(4*trans->size());
344
345
346 short index=0;
347 for(;it!=it_e;++it,++itp) { // LOOP over clusters
348 const CaloCluster& cl = **it;
349 index++;
350 transToPers(&cl,&(*itp),
351 showerLinkState,
352 cellLinkState,
353 log); // tP of CaloCluster to CaloCluster_p
354
355 const CaloSamplingData* trDS=&cl.m_dataStore; //transient
356 int nVar=trDS->getNumberOfVariableTypes();
357 int nSamplings=trDS->getNumberOfSamplings();
358// std::cout<<"vars:"<<nVar<<"\t samplings:"<<nSamplings<<std::endl;
359// std::cout<<"b:"<<(*it)->m_barrel<<"\te:"<<(*it)->m_endcap<<std::endl;
360// std::cout<<"sPattern: "<<(*it)->m_samplingPattern<<"\tgB:"<<(0x001ff00f & (*it)->m_samplingPattern) <<"\tgEC:"<< (0x00e00ff0 & (*it)->m_samplingPattern) <<std::endl;
361
364
365 for (int i=0;i<nVar;++i) {
366 if (testbit (pers->m_varTypePattern, i)) {
367 // We're writing this pattern. Was it in the cluster?
368 if (testbit (trDS->m_varTypePattern, i)) {
369 // Yes, store it.
370 for (int j=0;j<nSamplings; ++j)
371 if ( testbit(cl.m_samplingPattern, j)) {
372 pers->m_dataStore.push_back(trDS->retrieveData
373 (static_cast<vartype>(i),
374 static_cast<samptype>(j)));
375 }
376 }
377 else {
378 // Not in the cluster. Store 0's.
379 for (int j=0;j<nSamplings; ++j)
380 if ( testbit(cl.m_samplingPattern, j))
381 pers->m_dataStore.push_back(0);
382 }
383 }
384 else{
385 // We're not writing. Check that nothing was stored...
386 for (int j=0;j<nSamplings; ++j)
387 if ( testbit(cl.m_samplingPattern, j))
388 if(trDS->retrieveData(static_cast<vartype>(i),
389 static_cast<samptype>(j)))
390 if (log.level() <= MSG::DEBUG) log<< MSG::DEBUG<<"BIG PROBLEM ! not stored and has value:"
391 <<trDS->retrieveData(static_cast<vartype>(i),
392 static_cast<samptype>(j))
393 <<"\t var: "<<i
394 <<"\t sampling: "<<j<<endmsg;
395 }
396 }
397
398
399 //CaloClusterMomentStore::moment_iterator itm=cl.m_momentStore.begin();
400 //CaloClusterMomentStore::moment_iterator itm_e=cl.m_momentStore.end();
401
402 std::vector<unsigned short>::const_iterator itk =
403 pers->m_momentContainer.m_Mkey.begin();
404 std::vector<unsigned short>::const_iterator itk_e =
405 pers->m_momentContainer.m_Mkey.end();
407 cl.m_momentStore.begin();
409 cl.m_momentStore.end();
410 for (; itk != itk_e; ++itk) {
411 float val = 0;
412 if (itm != itm_e && itm.getMomentType() == *itk) {
413 val = (*itm).getValue();
414 ++itm;
415 }
416 else {
417 itm = cl.m_momentStore.find
418 (static_cast<CaloClusterMomentStore::moment_type> (*itk));
419 if (itm != itm_e) {
420 val = (*itm).getValue();
421 ++itm;
422 }
423 }
424 temp_Moments.push_back(val);
425 }
426
427// bad channel info
428 const CaloCluster::badChannelList* badlist = cl.getBadChannel();
429 // std::cout << " transtopers: bad channel size " << badlist->size() << std::endl;
430 for (const CaloClusterBadChannelData& bad : *badlist) {
431 pers->m_badClusIndexList.push_back(index);
432 float etac = bad.getEta()-(cl.eta());
433 float phic = CaloPhiRange::diff(bad.getPhi(),cl.phi());
434 CaloSampling::CaloSample sampl = bad.getLayer();
435 CaloBadChannel flag = bad.getFlag();
436 short status = ((sampl & 0xff) | ((flag.packedData() & 0xff) << 8));
437 tmp_badChannelEta.push_back(etac);
438 tmp_badChannelPhi.push_back(phic);
439 pers->m_badLayerStatusList.push_back(status);
440 }
441
442// raw E-eta-phi-M
443 // std::cout << "transtopers: rawE/eta/phi/M " << (*it)->m_rawE << " " << (*it)->m_rawEta << " " << (*it)->m_rawPhi << " " << (*it)->m_rawM << std::endl;
444 double e = cl.e();
445 if (std::fabs(e)>0.1) {
446 float eratio = cl.m_rawE / e;
447 tmp_rawE.push_back( eratio);
448 }
449 else
450 tmp_rawE.push_back( cl.m_rawE);
451 tmp_rawE.push_back( cl.m_rawEta-cl.eta());
452 float dphi = CaloPhiRange::diff ( cl.m_rawPhi, cl.phi());
453 tmp_rawE.push_back( dphi);
454 tmp_rawE.push_back( cl.m_rawM);
455 } // end of loop over clusters
456
458 A.setNrBits(16);
459 // A.setIgnoreSign();
460 A.reduce(temp_Moments,pers->m_momentContainer.m_Mvalue); // packs moments
461
462 Compressor B;
463 B.setNrBits(16);
464 B.reduce(tmp_badChannelEta,pers->m_badEtaList);
465 B.reduce(tmp_badChannelPhi,pers->m_badPhiList);
466
468 C.setNrBits(16);
469 C.reduce(tmp_rawE,pers->m_rawEEtaPhiM);
470
471 m_caloTowerSegCnv.transToPers(&trans->getTowerSeg(),&(pers->m_towerSeg));
472}
473
474
475
478 ShowerLinkState& showerLinkState,
479 CellLinkState& cellLinkState,
480 MsgStream& log) const
481{
482 trans->setDefaultSignalState (P4SignalState::CALIBRATED);
483 trans->setBasicEnergy (pers->m_basicSignal);
484 trans->setTime (pers->m_time);
485 trans->m_samplingPattern=pers->m_samplingPattern;
486 trans->m_eta0=pers->m_eta0;
487 trans->m_phi0=pers->m_phi0;
488 trans->m_status = CaloRecoStatus(pers->m_caloRecoStatus);
489 trans->setClusterSize (pers->m_clusterSize);
490
491 //Convert base class and element links
492 m_P4EEtaPhiMCnv.persToTrans(&pers->m_P4EEtaPhiM,static_cast<P4EEtaPhiM*>(trans),log);
493 m_showerElementLinkCnv.persToTrans(showerLinkState, pers->m_dataLink, trans->m_dataLink,log);
494 m_cellElementLinkCnv.persToTrans(cellLinkState, pers->m_cellLink, trans->m_cellLink,log);
495 trans->setAthenaBarCode (IAthenaBarCode::UNDEFINEDBARCODE);
496
497}
498
499
502 ShowerLinkState& showerLinkState,
503 CellLinkState& cellLinkState,
504 MsgStream& log) const
505{
506 pers->m_basicSignal=trans->getBasicEnergy();
507 pers->m_time=trans->getTime();
508 pers->m_samplingPattern=trans->m_samplingPattern;
509 pers->m_eta0=trans->eta0();
510 pers->m_phi0=trans->phi0();
511 pers->m_caloRecoStatus=trans->m_status.getStatusWord();
512 pers->m_clusterSize=trans->getClusterSize();
513
514 //Convert base class and element links
515 P4EEtaPhiM tmp = *trans;
516 m_P4EEtaPhiMCnv.transToPers(&tmp,&pers->m_P4EEtaPhiM,log);
517 m_showerElementLinkCnv.transToPers(showerLinkState, trans->m_dataLink, pers->m_dataLink,log);
518 m_cellElementLinkCnv.transToPers(cellLinkState, trans->m_cellLink, pers->m_cellLink,log);
519}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
CaloPhiRange class declaration.
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
#define x
virtual void persToTrans(const CaloClusterContainer_p4 *pers, CaloClusterContainer *trans, MsgStream &log) const override
ElementLinkCnv_p2< ElementLink< CaloCellLinkContainer > > m_cellElementLinkCnv
virtual void transToPers(const CaloClusterContainer *trans, CaloClusterContainer_p4 *pers, MsgStream &log) const override
ElementLinkCnv_p2< ElementLink< CaloShowerContainer > > m_showerElementLinkCnv
ElementLinkCnv_p2< ElementLink< CaloCellLinkContainer > >::State CellLinkState
ElementLinkCnv_p2< ElementLink< CaloShowerContainer > >::State ShowerLinkState
contType::const_iterator const_iterator
std::vector< unsigned int > m_rawEEtaPhiM
std::vector< short > m_badClusIndexList
std::vector< float > m_dataStore
CaloClusterMomentContainer_p2 m_momentContainer
ElementLinkContNames_p2 m_linkNames
std::vector< short > m_badLayerStatusList
std::vector< unsigned int > m_badPhiList
std::vector< unsigned int > m_badEtaList
Stores CaloClusterMoment in a keyed map.
CaloClusterMomentIterator moment_iterator
External moment iterator type.
virtual void setMomentStore(const moment_store &rMomStore)
Set internal store.
CaloClusterMoment::MomentType moment_type
Moment type.
std::map< moment_key, moment_value > moment_store
Internal moment store type.
Principal data class for CaloCell clusters.
CaloClusterMomentStore m_momentStore
cluster moments
void resetBadChannel()
Reset Bad channel list.
unsigned int m_samplingPattern
Sampling pattern.
double m_altE
Stores calibrated (cell weight) signal.
void addBadChannel(const CaloClusterBadChannelData &badChannel)
Add Bad channel information.
virtual double e() const
Retrieve energy independent of signal state.
double m_altPhi
Stores calibrated (cell weight) signal.
std::vector< CaloClusterBadChannelData > badChannelList
Get Bad Channel information.
virtual double eta() const
Retrieve eta independent of signal state.
bool m_endcap
Flag is true if at least one cell in EMB.
double m_altM
Stores calibrated (cell weight) signal.
virtual double phi() const
Retrieve phi independent of signal state.
CaloSamplingData m_dataStore
{\ brief Cached Stores
bool m_barrel
Flag is true if at least one cell in EMB.
double m_altEta
Stores calibrated (cell weight) signal.
static double fix(double phi)
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
reconstruction status indicator
Simple data object to store all variables in calorimeter samplings.
size_t getNumberOfSamplings() const
Set variable type pattern for this store.
CaloVariableType::VariableType variable_key_type
Variable look-up type.
unsigned int m_varTypePattern
value_type retrieveData(variable_key_type theVariable, sampling_key_type theSampling) const
Retrieve const reference to individual variable.
CaloSampling::CaloSample sampling_key_type
Sampling look-up key type.
size_t getNumberOfVariableTypes() const
Return number of variable types.
bool storeData(variable_key_type theVariable, sampling_key_type theSampling, value_type theData)
}
bool removeVariable(variable_key_type theVariable, sampling_key_type theSampling)
Remove a certain variable.
Data object stores CaloTower segmentation.
a typed memory pool that saves time spent allocation small object.
Definition DataPool.h:63
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:861
static const AthenaBarCode_t UNDEFINEDBARCODE
TH1F * trans(TH1F *h, bool t=false)
struct color C
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition index.py:1
hold the test vectors and ease the comparison