Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
AthenaPoolConverter.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 
13 #include "SGTools/DataProxy.h"
14 
19 #include "StorageSvc/DbType.h"
20 #include "RootUtils/APRDefaults.h"
21 
22 //__________________________________________________________________________
24  delete m_i_poolToken; m_i_poolToken = nullptr;
25 }
26 //__________________________________________________________________________
29 
30  // We do not retrieve m_detStore as that store may not always be available!
31 
32  ATH_CHECK( m_athenaPoolCnvSvc.retrieve() );
33 
34  IProperty* propertyServer(dynamic_cast<IProperty*>(m_athenaPoolCnvSvc.get()));
35  StringProperty containerPrefixProp("PoolContainerPrefix", "CollectionTree");
36  StringProperty containerNameHintProp("TopLevelContainerName", "");
37  StringProperty branchNameHintProp("SubLevelBranchName", "<type>/<key>");
38  if (propertyServer != nullptr) {
39  propertyServer->getProperty(&containerPrefixProp).ignore();
40  propertyServer->getProperty(&containerNameHintProp).ignore();
41  propertyServer->getProperty(&branchNameHintProp).ignore();
42  }
43  m_containerPrefix = containerPrefixProp.value();
44  m_containerNameHint = containerNameHintProp.value();
45  m_branchNameHint = branchNameHintProp.value();
46  return(StatusCode::SUCCESS);
47 }
48 //__________________________________________________________________________
50  // Release AthenaPoolCnvSvc
51  if (!m_athenaPoolCnvSvc.release().isSuccess()) {
52  ATH_MSG_WARNING("Cannot release AthenaPoolCnvSvc.");
53  }
54  return(::Converter::finalize());
55 }
56 //__________________________________________________________________________
58  return(POOL_StorageType);
59 }
60 //__________________________________________________________________________
61 StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
62  TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
63 
64  bool ownTokAddr = false;
65  if (tokAddr == nullptr || tokAddr->getToken() == nullptr) {
66  ownTokAddr = true;
67  auto token = std::make_unique<Token>();
68  token->fromString(*(pAddr->par()));
69  GenericAddress* genAddr = dynamic_cast<GenericAddress*>(pAddr);
70  if (not genAddr){
71  ATH_MSG_ERROR("Dynamic cast failed in AthenaPoolConverter::createObj");
72  //clean up
73  return StatusCode::FAILURE;
74  }
75  tokAddr = new TokenAddress(*genAddr, std::move(token));
76  }
77  if( tokAddr->ipar()[0] > 0 and tokAddr->getToken()->auxString().empty() ) {
78  char text[32];
79  ::sprintf(text, "[CTXT=%08X]", static_cast<int>(*(pAddr->ipar())));
80  tokAddr->getToken()->setAuxString(text);
81  }
82  ATH_MSG_VERBOSE("createObj: " << tokAddr->getToken()->toString() << ", CTX=" << tokAddr->ipar()[0]
83  << ", auxStr=" << tokAddr->getToken()->auxString() );
84  std::lock_guard<CallMutex> lock(m_conv_mut);
85  m_i_poolToken = tokAddr->getToken();
86  try {
87  std::string key = pAddr->par()[1];
88  if (!PoolToDataObject(pObj, tokAddr->getToken(), key).isSuccess()) {
89  ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
90  pObj = nullptr;
91  }
92  } catch (std::exception& e) {
93  ATH_MSG_ERROR("createObj - caught exception: " << e.what());
94  pObj = nullptr;
95  }
96  if (pObj == nullptr) {
97  ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
98  }
99  if (ownTokAddr) {
100  delete tokAddr; tokAddr = nullptr;
101  }
102  m_i_poolToken = nullptr;
103  if (pObj == nullptr) {
104  return(StatusCode::FAILURE);
105  }
106  return(StatusCode::SUCCESS);
107 }
108 //__________________________________________________________________________
109 StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
110  const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
111  if (proxy == nullptr) {
112  ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " << pObj->name());
113  return(StatusCode::FAILURE);
114  }
115  try {
116  std::lock_guard<CallMutex> lock(m_conv_mut);
117  if (!DataObjectToPers(pObj, pAddr).isSuccess()) {
118  ATH_MSG_ERROR("CreateRep failed, key = " << pObj->name());
119  return(StatusCode::FAILURE);
120  }
121  } catch (std::exception& e) {
122  ATH_MSG_ERROR("createRep - caught exception: " << e.what());
123  return(StatusCode::FAILURE);
124  }
125  const CLID clid = proxy->clID();
126  if (pAddr == nullptr) {
127  // Create a IOpaqueAddress for this object.
128  pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
129  } else {
130  GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
131  if (gAddr != nullptr) {
132  gAddr->setSvcType(this->storageType());
133  }
134  }
135  return(StatusCode::SUCCESS);
136 }
137 //__________________________________________________________________________
138 StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
139  std::lock_guard<CallMutex> lock(m_conv_mut);
140  try {
141  if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
142  ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
143  return(StatusCode::FAILURE);
144  }
145  } catch (std::exception& e) {
146  ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
147  return(StatusCode::FAILURE);
148  }
149  return(StatusCode::SUCCESS);
150 }
151 //__________________________________________________________________________
153  return(POOL_StorageType);
154 }
155 //__________________________________________________________________________
156 AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
157  const char* name /*= nullptr*/) :
158  ::Converter(POOL_StorageType, myCLID, pSvcLocator),
159  ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
160  name ? name : "AthenaPoolConverter"),
161  m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
162  m_athenaPoolCnvSvc("AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
163  m_classDesc(),
164  m_className(),
165  m_classDescs(),
166  m_containerPrefix(""),
167  m_containerNameHint(""),
168  m_branchNameHint(""),
169  m_dataObject(nullptr),
170  m_i_poolToken(nullptr) {
171 }
172 //__________________________________________________________________________
173 Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
174  Placement placement;
175  // Override streaming parameters from StreamTool if requested.
176  std::string::size_type pos1 = output.find('[');
177  std::string outputConnectionSpec = output.substr(0, pos1);
178  int tech = 0;
179  m_athenaPoolCnvSvc->decodeOutputSpec(outputConnectionSpec, tech).ignore();
180  // Set DB and Container names
181  placement.setFileName(outputConnectionSpec);
182 
183  std::string containerPrefix = m_containerPrefix;
184  std::string dhContainerPrefix = pool::ROOTRNTUPLE_StorageType.exactMatch(tech) ? APRDefaults::RNTupleNames::DataHeader : APRDefaults::TTreeNames::DataHeader;
185  std::string containerName;
186 
187  // Get Technology from containerPrefix
188  std::size_t colonPos = containerPrefix.find(':');
189  if (colonPos != std::string::npos) {
190  dhContainerPrefix = containerPrefix.substr(0, colonPos + 1) + dhContainerPrefix;
191  }
192 
193  // Override streaming parameters from StreamTool if requested.
194  std::string containerNameHint = m_containerNameHint;
195  std::string branchNameHint = m_branchNameHint;
196  std::string containerFriendPostfix;
197  while (pos1 != std::string::npos) {
198  const std::string::size_type pos2 = output.find('=', pos1);
199  const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
200  const std::string::size_type pos3 = output.find(']', pos2);
201  const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
202  if (thisKey == "OutputCollection") {
203  dhContainerPrefix = value;
204  } else if (thisKey == "PoolContainerPrefix") {
205  containerPrefix = value;
206  } else if (thisKey == "TopLevelContainerName") {
207  containerNameHint = value;
208  } else if (thisKey == "SubLevelBranchName") {
209  branchNameHint = value;
210  } else if (thisKey == "PoolContainerFriendPostfix") {
211  containerFriendPostfix = value;
212  }
213  pos1 = output.find('[', pos3);
214  }
215 
216  // --- Special types: DataHeader & Form
217  if( tname.compare(0, 10, "DataHeader") == 0 ) {
218  if( tname.compare(10, 4, "Form") == 0 ) {
219  containerName = dhContainerPrefix + "Form" + "(" + tname + ")";
220  } else {
221  if (key[key.size() - 1] == '/') {
222  containerName = dhContainerPrefix + "(" + key + tname + ")";
223  } else {
224  containerName = dhContainerPrefix + "(" + tname + ")";
225  }
226  }
227  }
228  // AttributeList - writing attributes separately to EventTag container group
229  else if (tname.compare(0, 13, "AttributeList") == 0) {
230  // Find the right storage type and name for EventTag values
231  if( pool::ROOTRNTUPLE_StorageType.exactMatch(tech) ) {
232  containerName = std::string(APRDefaults::RNTupleNames::EventTag) + "(" + key + ")";
233  } else {
234  // no indexing needed (nothing points to Tags)
235  // safe to set tech here - it will not be overwritten by decodeOutput
236  tech = pool::ROOTTREE_StorageType.type();
237  containerName = std::string(APRDefaults::TTreeNames::EventTag) + "(" + key + ")";
238  }
239  }
240  // all other object types
241  else {
242  const std::string typeTok = "<type>", keyTok = "<key>";
243  containerName = containerPrefix + containerFriendPostfix + containerNameHint;
244  if (!branchNameHint.empty()) {
245  containerName += "(" + branchNameHint + ")";
246  }
247  const std::size_t pos1 = containerName.find(typeTok);
248  if (pos1 != std::string::npos) {
249  containerName.replace(pos1, typeTok.size(), tname);
250  }
251  const std::size_t pos2 = containerName.find(keyTok);
252  if (pos2 != std::string::npos) {
253  if (key.empty()) {
254  containerName.replace(pos2, keyTok.size(), tname);
255  } else {
256  containerName.replace(pos2, keyTok.size(), key);
257  }
258  }
259  }
260  m_athenaPoolCnvSvc->decodeOutputSpec(containerName, tech).ignore();
261  placement.setContainerName(containerName);
262  placement.setTechnology(tech);
263  return(placement);
264 }
265 //__________________________________________________________________________
266 const DataObject* AthenaPoolConverter::getDataObject() const {
267  return(m_dataObject);
268 }
269 //__________________________________________________________________________
271  return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false);
272 }
273 //__________________________________________________________________________
274 StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
275  ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
276  return(StatusCode::SUCCESS);
277 }
AthenaPoolConverter::setPlacementWithType
virtual Placement setPlacementWithType(const std::string &tname, const std::string &key, const std::string &output)
Set POOL placement hint for a given type.
Definition: AthenaPoolConverter.cxx:173
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
AthenaPoolConverter::m_dataObject
const DataObject * m_dataObject
Definition: AthenaPoolConverter.h:129
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:50
Placement
This class holds all the necessary information to guide the writing of an object in a physical place.
Definition: Placement.h:19
AthenaPoolConverter.h
This file contains the class definition for the AthenaPoolConverter class.
IAthenaPoolCnvSvc.h
This file contains the class definition for the IAthenaPoolCnvSvc interface class.
AthenaPoolConverter::DataObjectToPool
virtual StatusCode DataObjectToPool(IOpaqueAddress *pAddr, DataObject *pObj)=0
Write an object into POOL.
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:395
APRDefaults::RNTupleNames::DataHeader
static constexpr const char * DataHeader
Definition: APRDefaults.h:20
AthenaPoolConverter::m_athenaPoolCnvSvc
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
Definition: AthenaPoolConverter.h:117
AthenaPoolConverter::~AthenaPoolConverter
virtual ~AthenaPoolConverter()
Destructor.
Definition: AthenaPoolConverter.cxx:23
initialize
void initialize()
Definition: run_EoverP.cxx:894
Token::auxString
const std::string & auxString() const
Access auxiliary string.
Definition: Token.h:91
AthenaPoolConverter::compareClassGuid
bool compareClassGuid(const Guid &guid) const
Definition: AthenaPoolConverter.cxx:270
AthenaPoolConverter::storageType
static long storageType()
Definition: AthenaPoolConverter.cxx:152
APRDefaults::TTreeNames::EventTag
static constexpr const char * EventTag
Definition: APRDefaults.h:13
athena.value
value
Definition: athena.py:124
DbType.h
Token::classID
const Guid & classID() const
Access database identifier.
Definition: Token.h:73
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Placement::setContainerName
Placement & setContainerName(const std::string &containerName)
Set container name.
Definition: Placement.h:34
AthenaPoolConverter::repSvcType
virtual long repSvcType() const override
Definition: AthenaPoolConverter.cxx:57
AthenaPoolConverter::initialize
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
Definition: AthenaPoolConverter.cxx:27
pool::DbType::type
int type() const
Access to full type.
Definition: DbType.h:66
AthenaPoolConverter::m_conv_mut
CallMutex m_conv_mut
Definition: AthenaPoolConverter.h:133
TokenAddress
This class provides a Generic Transient Address for POOL tokens.
Definition: TokenAddress.h:23
AthenaPoolConverter::cleanUp
virtual StatusCode cleanUp(const std::string &output) override
Implement cleanUp for AthenaPoolConverter to do nothing.
Definition: AthenaPoolConverter.cxx:274
APRDefaults.h
AthenaPoolConverter::m_i_poolToken
const Token * m_i_poolToken
Definition: AthenaPoolConverter.h:130
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
AthenaPoolConverter::AthenaPoolConverter
AthenaPoolConverter(const CLID &id, ISvcLocator *pSvcLocator, const char *name=nullptr)
Standard Service Constructor.
Definition: AthenaPoolConverter.cxx:156
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthenaPoolConverter::m_containerPrefix
std::string m_containerPrefix
Definition: AthenaPoolConverter.h:125
calibdata.exception
exception
Definition: calibdata.py:496
AthenaPoolConverter::m_containerNameHint
std::string m_containerNameHint
Definition: AthenaPoolConverter.h:126
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TokenAddress::getToken
Token * getToken()
Definition: TokenAddress.cxx:15
Placement::setFileName
Placement & setFileName(const std::string &fileName)
Set file name.
Definition: Placement.h:30
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
APRDefaults::RNTupleNames::EventTag
static constexpr const char * EventTag
Definition: APRDefaults.h:19
AthenaPoolConverter::fillRepRefs
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj) override
Create a POOL persistent representation for a transient object.
Definition: AthenaPoolConverter.cxx:138
pool_uuid.guid
guid
Definition: pool_uuid.py:112
merge.output
output
Definition: merge.py:17
APRDefaults::TTreeNames::DataHeader
static constexpr const char * DataHeader
Definition: APRDefaults.h:14
Converter
Definition: Converter.h:27
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
AthenaPoolConverter::PoolToDataObject
virtual StatusCode PoolToDataObject(DataObject *&pObj, const Token *token, const std::string &key)=0
Read an object from POOL.
Token::toString
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition: Token.cxx:129
AthenaPoolConverter::DataObjectToPers
virtual StatusCode DataObjectToPers(DataObject *pObj, IOpaqueAddress *&pAddr)=0
Convert an object into Persistent.
TokenAddress.h
This file contains the class definition for the TokenAddress class.
Guid
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition: Guid.h:20
pool::DbType::exactMatch
bool exactMatch(const DbType &typ) const
Definition: DbType.h:73
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AthenaPoolConverter::createRep
virtual StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr) override
Create a POOL persistent representation for a transient object.
Definition: AthenaPoolConverter.cxx:109
AthenaPoolConverter::m_branchNameHint
std::string m_branchNameHint
Definition: AthenaPoolConverter.h:127
Token::setAuxString
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
Definition: Token.h:93
Placement::setTechnology
Placement & setTechnology(int technology)
Set technology type.
Definition: Placement.h:38
AthenaPoolConverter::getDataObject
virtual const DataObject * getDataObject() const
Definition: AthenaPoolConverter.cxx:266
makeTransCanvas.text
text
Definition: makeTransCanvas.py:11
AthenaPoolConverter::finalize
virtual StatusCode finalize() override
Definition: AthenaPoolConverter.cxx:49
Guid.h
This file contains the class definition for the Guid class (migrated from POOL).
Placement.h
This file contains the class definition for the Placement class (migrated from POOL).
SG::DataProxy
Definition: DataProxy.h:45
Token.h
This file contains the class definition for the Token class (migrated from POOL).
AthenaPoolConverter::createObj
virtual StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&pObj) override
Create a transient object from a POOL persistent representation.
Definition: AthenaPoolConverter.cxx:61
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
DataProxy.h