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 //__________________________________________________________________________
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  Token* token = new 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  delete token;
74  return StatusCode::FAILURE;
75  }
76  tokAddr = new TokenAddress(*genAddr, token);
77  }
78  if( tokAddr->ipar()[0] > 0 and tokAddr->getToken()->auxString().empty() ) {
79  char text[32];
80  ::sprintf(text, "[CTXT=%08X]", static_cast<int>(*(pAddr->ipar())));
81  tokAddr->getToken()->setAuxString(text);
82  }
83  ATH_MSG_VERBOSE("createObj: " << tokAddr->getToken()->toString() << ", CTX=" << tokAddr->ipar()[0]
84  << ", auxStr=" << tokAddr->getToken()->auxString() );
85  std::lock_guard<CallMutex> lock(m_conv_mut);
86  m_i_poolToken = tokAddr->getToken();
87  try {
88  std::string key = pAddr->par()[1];
89  if (!PoolToDataObject(pObj, tokAddr->getToken(), key).isSuccess()) {
90  ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
91  pObj = nullptr;
92  }
93  } catch (std::exception& e) {
94  ATH_MSG_ERROR("createObj - caught exception: " << e.what());
95  pObj = nullptr;
96  }
97  if (pObj == nullptr) {
98  ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
99  }
100  if (ownTokAddr) {
101  delete tokAddr; tokAddr = nullptr;
102  }
103  m_i_poolToken = nullptr;
104  if (pObj == nullptr) {
105  return(StatusCode::FAILURE);
106  }
107  return(StatusCode::SUCCESS);
108 }
109 //__________________________________________________________________________
110 StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
111  const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
112  if (proxy == nullptr) {
113  ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " << pObj->name());
114  return(StatusCode::FAILURE);
115  }
116  try {
117  std::lock_guard<CallMutex> lock(m_conv_mut);
118  if (!DataObjectToPers(pObj, pAddr).isSuccess()) {
119  ATH_MSG_ERROR("CreateRep failed, key = " << pObj->name());
120  return(StatusCode::FAILURE);
121  }
122  } catch (std::exception& e) {
123  ATH_MSG_ERROR("createRep - caught exception: " << e.what());
124  return(StatusCode::FAILURE);
125  }
126  const CLID clid = proxy->clID();
127  if (pAddr == nullptr) {
128  // Create a IOpaqueAddress for this object.
129  pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
130  } else {
131  GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
132  if (gAddr != nullptr) {
133  gAddr->setSvcType(this->storageType());
134  }
135  }
136  return(StatusCode::SUCCESS);
137 }
138 //__________________________________________________________________________
139 StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
140  std::lock_guard<CallMutex> lock(m_conv_mut);
141  try {
142  if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
143  ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
144  return(StatusCode::FAILURE);
145  }
146  } catch (std::exception& e) {
147  ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
148  return(StatusCode::FAILURE);
149  }
150  return(StatusCode::SUCCESS);
151 }
152 //__________________________________________________________________________
154  return(POOL_StorageType);
155 }
156 //__________________________________________________________________________
157 AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
158  const char* name /*= nullptr*/) :
159  ::Converter(POOL_StorageType, myCLID, pSvcLocator),
160  ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
161  name ? name : "AthenaPoolConverter"),
162  m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
163  m_athenaPoolCnvSvc("AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
164  m_classDesc(),
165  m_className(),
166  m_classDescs(),
167  m_containerPrefix(""),
168  m_containerNameHint(""),
169  m_branchNameHint(""),
170  m_dataObject(nullptr),
171  m_i_poolToken(nullptr) {
172 }
173 //__________________________________________________________________________
174 Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
175  Placement placement;
176  // Override streaming parameters from StreamTool if requested.
177  std::string::size_type pos1 = output.find('[');
178  std::string outputConnectionSpec = output.substr(0, pos1);
179  int tech = 0;
180  m_athenaPoolCnvSvc->decodeOutputSpec(outputConnectionSpec, tech).ignore();
181  // Set DB and Container names
182  placement.setFileName(outputConnectionSpec);
183 
184  std::string containerPrefix = m_containerPrefix;
185  std::string dhContainerPrefix = pool::ROOTRNTUPLE_StorageType.exactMatch(tech) ? APRDefaults::RNTupleNames::DataHeader : APRDefaults::TTreeNames::DataHeader;
186  std::string containerName;
187 
188  // Get Technology from containerPrefix
189  std::size_t colonPos = containerPrefix.find(':');
190  if (colonPos != std::string::npos) {
191  dhContainerPrefix = containerPrefix.substr(0, colonPos + 1) + dhContainerPrefix;
192  }
193 
194  // Override streaming parameters from StreamTool if requested.
195  std::string containerNameHint = m_containerNameHint;
196  std::string branchNameHint = m_branchNameHint;
197  std::string containerFriendPostfix;
198  while (pos1 != std::string::npos) {
199  const std::string::size_type pos2 = output.find('=', pos1);
200  const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
201  const std::string::size_type pos3 = output.find(']', pos2);
202  const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
203  if (thisKey == "OutputCollection") {
204  dhContainerPrefix = value;
205  } else if (thisKey == "PoolContainerPrefix") {
206  containerPrefix = value;
207  } else if (thisKey == "TopLevelContainerName") {
208  containerNameHint = value;
209  } else if (thisKey == "SubLevelBranchName") {
210  branchNameHint = value;
211  } else if (thisKey == "PoolContainerFriendPostfix") {
212  containerFriendPostfix = value;
213  }
214  pos1 = output.find('[', pos3);
215  }
216 
217  // --- Special types: DataHeader & Form
218  if( tname.compare(0, 10, "DataHeader") == 0 ) {
219  if( tname.compare(10, 4, "Form") == 0 ) {
220  containerName = dhContainerPrefix + "Form" + "(" + tname + ")";
221  } else {
222  if (key[key.size() - 1] == '/') {
223  containerName = dhContainerPrefix + "(" + key + tname + ")";
224  } else {
225  containerName = dhContainerPrefix + "(" + tname + ")";
226  }
227  }
228  }
229  // AttributeList - writing attributes separately to EventTag container group
230  else if (tname.compare(0, 13, "AttributeList") == 0) {
231  // Find the right storage type and name for EventTag values
232  if( pool::ROOTRNTUPLE_StorageType.exactMatch(tech) ) {
233  containerName = std::string(APRDefaults::RNTupleNames::EventTag) + "(" + key + ")";
234  } else {
235  // no indexing needed (nothing points to Tags)
236  // safe to set tech here - it will not be overwritten by decodeOutput
237  tech = pool::ROOTTREE_StorageType.type();
238  containerName = std::string(APRDefaults::TTreeNames::EventTag) + "(" + key + ")";
239  }
240  }
241  // all other object types
242  else {
243  const std::string typeTok = "<type>", keyTok = "<key>";
244  containerName = containerPrefix + containerFriendPostfix + containerNameHint;
245  if (!branchNameHint.empty()) {
246  containerName += "(" + branchNameHint + ")";
247  }
248  const std::size_t pos1 = containerName.find(typeTok);
249  if (pos1 != std::string::npos) {
250  containerName.replace(pos1, typeTok.size(), tname);
251  }
252  const std::size_t pos2 = containerName.find(keyTok);
253  if (pos2 != std::string::npos) {
254  if (key.empty()) {
255  containerName.replace(pos2, keyTok.size(), tname);
256  } else {
257  containerName.replace(pos2, keyTok.size(), key);
258  }
259  }
260  }
261  m_athenaPoolCnvSvc->decodeOutputSpec(containerName, tech).ignore();
262  placement.setContainerName(containerName);
263  placement.setTechnology(tech);
264  return(placement);
265 }
266 //__________________________________________________________________________
267 const DataObject* AthenaPoolConverter::getDataObject() const {
268  return(m_dataObject);
269 }
270 //__________________________________________________________________________
272  return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false);
273 }
274 //__________________________________________________________________________
275 StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
276  ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
277  return(StatusCode::SUCCESS);
278 }
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:174
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:392
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:89
AthenaPoolConverter::compareClassGuid
bool compareClassGuid(const Guid &guid) const
Definition: AthenaPoolConverter.cxx:271
AthenaPoolConverter::storageType
static long storageType()
Definition: AthenaPoolConverter.cxx:153
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: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: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
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:275
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:157
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
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:139
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:228
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.
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:110
AthenaPoolConverter::m_branchNameHint
std::string m_branchNameHint
Definition: AthenaPoolConverter.h:127
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:267
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