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