ATLAS Offline Software
Loading...
Searching...
No Matches
ElementLinkVectorCnv_p1.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/** @file ElementLinkVectorCnv_p1.icc
6 * @brief This file contains the implementation for the ElementLinkVectorCnv_p1 template methods.
7 * @author Marcin.Nowak@cern.ch
8 **/
9
10#include <stdexcept>
11
12#include "AthLinks/ElementLinkVector.h"
13#include "AthenaKernel/ThinningCache.h"
14#include "AthenaKernel/ThinningDecisionBase.h"
15#include "AthenaKernel/getThinningCache.h"
16
17//#include <iostream>
18//using namespace std;
19
20//#define ELVEC_DEBUG
21
22
23template <typename LINK_TYPE>
24void
25ElementLinkVectorCnv_p1<LINK_TYPE>::transToPers(const LinkVect_t& trans,
26 PersLinkVect_t& pers,
27 const SG::ThinningCache* cache,
28 MsgStream& msg) const
29{
30 pers.m_elementRefs.clear();
31 pers.m_links.clear();
32
33 LinkVect_t tmpTrans = trans;
34 tmpTrans.doRemap();
35
36 // easy case first
37 if ( !cache ) {
38 std::vector<typename LinkVect_t::DataLinkVector::size_type> shortrefs;
39 tmpTrans.toPersistent(shortrefs);
40 // copy the container keys
41 m_DLinkVectorCnv.transToPers(&tmpTrans.hostDObjs(), &pers.m_links, msg);
42
43 // copy the element links in the compact form
44 size_t link_n = tmpTrans.size();
45 pers.m_elementRefs.reserve(link_n);
46 for ( std::size_t i=0; i!=link_n; ++i ) {
47 using Index_t = typename PersLinkVect_t::Index_t;
48 size_t idx = SG::ThinningDecisionBase::RemovedIdx;
49 if (shortrefs[i] != SG::ThinningDecisionBase::RemovedIdx)
50 idx = tmpTrans.elementIndex(i);
51 pers.m_elementRefs.emplace_back( static_cast<Index_t>(idx), shortrefs[i] );
52 }
53 return;
54 }
55
56 // the not so easy case: thinning occured...
57
58 // Note: we can't use ElementLinkVector::toPersistent.
59 // we have to first handle the DataLinks and then the elementlink refs
60 // otherwise we:
61 // - corrupt the ElementLinks
62 // - generate many-many ERRORs (when the EL points at a thinned away elmt)
63
64 // set all DataLinks to persistent state
65 tmpTrans.toPersistentDL();
66
67 // copy the container keys
68 m_DLinkVectorCnv.transToPers(&tmpTrans.hostDObjs(), &pers.m_links, msg);
69 //std::cout << "*** -- ElementLinkVectorCnv: KEY=" << *iter << std::endl;
70
71 // copy the element links in the compact form
72 size_t link_n = tmpTrans.size();
73 pers.m_elementRefs.reserve(link_n);
74 typedef typename LinkVect_t::ElemLink EL;
75 for ( std::size_t ilink = 0; ilink != link_n; ++ilink ) {
76 // note the _copy_ of the original
77 // (needed for multi-stream thinning)
78 EL el = tmpTrans[ilink];
79 // here is the problem: in case the ElementLink was directly created w/
80 // only a pointer to the element, _and_ if the the pointed-at element
81 // has been thinned away, EL::index() will throw b/c
82 // IndexingPolicy::setIndex will fail.
83 std::size_t orig_idx = SG::ThinningDecisionBase::RemovedIdx;
84 try {
85 orig_idx = el.index();
86 } catch ( const SG::maybe_thinning_error& err ) {
87 // ok. that's the corner case we talked about above.
88 msg << MSG::DEBUG
89 << "caught a maybe_thinning_error: [" << err.what() << "]"
90 << endmsg
91 << "(this is an expected case of the EL-state-phase-space "
92 << "when thinning is active)"
93 << endmsg;
94 }
95 std::size_t idx = orig_idx;
96 if (cache) {
97 const SG::ThinningDecisionBase* dec = cache->thinning (el.key());
98 if (dec) {
99 idx = dec->index (idx);
100 }
101 }
102
103 typename LinkVect_t::size_type shortref = 0;
104 if ( idx == SG::ThinningDecisionBase::RemovedIdx ) {
105 // that element has been thinned away.
106 shortref = idx; //< 'special' well-known value
107 } else {
108 // element not thinned away
109 typename LinkVect_t::DataLinkVector::iterator ihost =
110 tmpTrans.findHostDObj (el);
111 if (ihost != tmpTrans.endHostDObjs())
112 shortref = std::distance (tmpTrans.beginHostDObjs(), ihost);
113 else {
114 msg << MSG::WARNING
115 << "link not found in ElemLinkVector" << endmsg;
116 }
117 }
118 typedef typename PersLinkVect_t::ElementRef PersELRef;
119 pers.m_elementRefs.push_back( PersELRef (idx, shortref) );
120 }
121}
122
123
124template <typename LINK_TYPE>
125void ElementLinkVectorCnv_p1<LINK_TYPE>::transToPers(const LinkVect_t& trans,
126 PersLinkVect_t& pers,
127 MsgStream& msg) const
128{
129 transToPers (trans, pers,
130 SG::getThinningCache(),
131 msg);
132}
133
134
135template <typename LINK_TYPE >
136void ElementLinkVectorCnv_p1< LINK_TYPE >::persToTrans(const PersLinkVect_t& pers, LinkVect_t& trans, MsgStream& msg) const
137{
138 // copy the container keys
139 typename LinkVect_t::DataLinkVector dl;
140 m_DLinkVectorCnv.persToTrans(&pers.m_links, &dl, msg);
141 trans.clear();
142 trans.moveHostDObjs (dl);
143 trans.toTransient();
144 // cout << "*** -- ElementLinkVectorCnv: KEY=" << *iter << endl;
145 // copy the element links in the compact form
146 size_t link_n = pers.m_elementRefs.size();
147 trans.reserve(link_n);
148 typename PersLinkVect_t::ElementRefVector::const_iterator link_iter = pers.m_elementRefs.begin();
149 while(link_n--) {
150 // This test needed for 32/64 bit compatibility.
151 if ( link_iter->m_nameIndex == static_cast<uint32_t>(SG::ThinningDecisionBase::RemovedIdx) &&
152 link_iter->m_elementIndex == static_cast<Index_t>(SG::ThinningDecisionBase::RemovedIdx) )
153 {
154 // thinned-away element...
155 trans.push_back (SG::ThinningDecisionBase::RemovedIdx,
156 SG::ThinningDecisionBase::RemovedIdx);
157 }
158 else
159 trans.push_back (link_iter->m_nameIndex, link_iter->m_elementIndex);
160
161 #ifdef ELVEC_DEBUG
162 msg << MSG::DEBUG
163 << "ElementLinkVectorCnv_p1::PersToTrans(): KEY="
164 << pers->m_links[link_iter->m_nameIndex].m_link
165 << ", IDX=" << link_iter->m_elementIndex
166 << endmsg;
167 #endif
168 ++link_iter;
169 }
170}
171
172
173
174
175template <typename LINK_TYPE>
176inline
177void
178ElementLinkVectorCnv_p1<LINK_TYPE>
179::transToPers(const LinkVect_t* trans, PersLinkVect_t* pers, MsgStream& msg) const
180{
181 this->transToPers(*trans, *pers, msg);
182}
183
184
185template <typename LINK_TYPE >
186inline
187void
188ElementLinkVectorCnv_p1< LINK_TYPE >
189::persToTrans(const PersLinkVect_t* pers, LinkVect_t* trans, MsgStream& msg) const
190{
191 this->persToTrans(*pers, *trans, msg);
192}