Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
DataHeaderCnv.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 #include "DataHeaderCnv.h"
11 
15 
18 
19 #include "CoralBase/AttributeList.h"
20 #include "CoralBase/Attribute.h"
21 
22 #include "GaudiKernel/IIncidentSvc.h"
23 #include "GaudiKernel/FileIncident.h"
25 
26 #include <stdexcept>
27 #include <format>
28 
29 
30 static const pool::Guid DHForm_p6_Guid("7BE56CEF-C866-4BEE-9348-A5F34B5F1DAD");
31 
32 // cppcheck-suppress uninitMemberVar
33 DataHeaderCnv::DataHeaderCnv(ISvcLocator* svcloc) :
34  DataHeaderCnvBase(svcloc, "DataHeaderCnv")
35 {
36  m_classDesc = RootType( "DataHeader_p6" );
37 }
38 
39 //______________________________________________________________________________
41 {
42  // Remove itself from the IncidentSvc - if it is still around
43  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", "DataHeaderCnv");
44  if( incSvc.retrieve().isSuccess() ) {
45  incSvc->removeListener(this, IncidentType::EndInputFile);
46  }
47 }
48 //______________________________________________________________________________
50 {
51  // Read properties from the ConversionSvc
52  m_inDHFMapMaxsize = 100; // default DHForm cache size
53  bool doFilterDHAliases = true;
54  SmartIF<IProperty> cnvSvc{service("AthenaPoolCnvSvc")};
55  if( cnvSvc ) {
56  IntegerProperty sizeProp("maxDHFormCacheSize", m_inDHFMapMaxsize);
57  if( cnvSvc->getProperty(&sizeProp).isSuccess() ) {
58  m_inDHFMapMaxsize = sizeProp.value();
59  }
60  BooleanProperty aliasFilterProp("doFilterDHAliases", doFilterDHAliases);
61  if( cnvSvc->getProperty(&aliasFilterProp).isSuccess() ) {
62  doFilterDHAliases = aliasFilterProp.value();
63  }
64  BooleanProperty oneDHForm("OneDataHeaderForm", m_oneDHForm);
65  if( cnvSvc->getProperty(&oneDHForm).isSuccess() ) {
66  m_oneDHForm = oneDHForm.value();
67  }
68  }
69  ATH_MSG_VERBOSE("Using DHForm cache size: " << m_inDHFMapMaxsize);
70  if( doFilterDHAliases ) {
71  ATH_MSG_VERBOSE("Will filter SG Aux aliases in DataHeader");
72  } else {
73  ATH_MSG_VERBOSE("Will NOT filter SG Aux aliases in DataHeader");
74  }
75  m_tpOutConverter.setSGAliasFiltering( doFilterDHAliases );
76 
77  // Get IncidentSvc
78  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", "DataHeaderCnv");
79  ATH_CHECK( incSvc.retrieve() );
80  // Listen to EndInputFile incidents to clear old DataHeaderForms from the cache
81  incSvc->addListener(this, IncidentType::EndInputFile, 0);
82  incSvc->addListener(this, "PreFork", 0);
83  // Listen to WriteDataHeaderForms incidents to flush DHForms after
84  incSvc->addListener(this, "WriteDataHeaderForms", 0);
86 }
87 
88 
89 void DataHeaderCnv::handle(const Incident& incident)
90 {
91  if( incident.type() == "PreFork" ) {
92  m_persFormMap.clear();
93  }
94  if( incident.type() == IncidentType::EndInputFile ) {
95  // remove cached DHForms that came from the file that is now being closed
96  const std::string& guid = static_cast<const FileIncident&>(incident).fileGuid();
98  }
99  if( incident.type() == "WriteDataHeaderForms" ) {
100  // Issued from OutputStream MetaData write() or directly called from AthenaPoolCnvSvc
101  const std::string& fileName = static_cast<const FileIncident*>(&incident)->fileName();
102  // Write out all the cached DHForms before closing a given output stream
103  std::vector<std::string> toWrite;
104  auto pos = fileName.find("[OutputCollection=MetaDataHdr]");
105  bool metaDataCommit = (pos != std::string::npos);
106  std::string justFileName = fileName.substr(0, pos);
107  ATH_MSG_DEBUG("Handling WriteDataHeaderForms incident for stream: " << fileName);
108  // collect DHForms related to the stream
109  for( const auto& elem : m_persFormMap ) {
110  const std::string& placementStr = elem.first;
111  Placement formPlacement;
112  formPlacement.fromString( placementStr );
113  ATH_MSG_VERBOSE("DatHeaderForm key in map=" << placementStr);
114  if( formPlacement.fileName() == justFileName or fileName == "*" ) {
115  // write only the Forms that correspond to the commit type (MetaData or others)
116  if( (placementStr.find("[CONT=MetaData") != std::string::npos) == metaDataCommit ) {
117  toWrite.push_back( placementStr );
118  }
119  }
120  }
121  // write the DHForms one by one (the only mode supported by RNTuple)
122  for( std::size_t n = 0; const std::string& placementStr : toWrite ) {
123  Placement formPlacement;
124  formPlacement.fromString( placementStr );
125  auto form_ptr = m_persFormMap[placementStr].get();
126  if( form_ptr->isModified() ) {
127  static const RootType dhFormType( typeid( *form_ptr ) );
128  ATH_MSG_DEBUG("Writing DatHeaderForm " << placementStr);
129  Token* form_token = m_athenaPoolCnvSvc->registerForWrite(&formPlacement, form_ptr, dhFormType);
130  if( !form_token ) {
131  std::string errmsg = std::format("Failed to write {} {}", dhFormType.Name(), placementStr);
132  ATH_MSG_FATAL( errmsg );
133  throw GaudiException(errmsg, "DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
134  }
135  ATH_MSG_DEBUG("Wrote DatHeaderForm, placeemnt was " << placementStr << " token=" << form_token->toString());
136  form_token->release(); form_token = nullptr;
137  bool doCommit = (++n == toWrite.size());
138  const std::string connection = ( fileName!="*"? fileName : formPlacement.fileName() );
139  if( !m_athenaPoolCnvSvc->commitOutput(connection, doCommit).isSuccess() ) {
140  throw GaudiException("WriteDataHeaderForms failed", "DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
141  }
142  }
143  m_persFormMap.erase( placementStr );
144  }
145  }
146 }
147 
148 
149 void DataHeaderCnv::clearInputDHFormCache( const std::string& dbGuid )
150 {
151  auto iter = m_inputDHForms.begin();
152  while( iter != m_inputDHForms.end() ) {
153  size_t dbpos = iter->first.find("[DB=");
154  if( dbpos != std::string::npos && iter->first.compare(dbpos+4, dbpos+36, dbGuid) == 0 ) {
155  iter = m_inputDHForms.erase( iter );
156  } else {
157  iter++;
158  }
159  }
160  m_inDHFormCount[ dbGuid ] = 0;
161 }
162 
163 
164 std::string getValForKey(const std::string& str, const std::string& key)
165 {
166  auto start = str.find(key);
167  if( start == std::string::npos )
168  return "";
169  start += key.size();
170  auto end = str.find("]", start);
171  return str.substr(start, end-start);
172 }
173 
174 inline
175 std::string getSWNFromStr(const std::string& str) { return getValForKey(str, "[SWN="); }
176 inline
177 std::string getFILEFromStr(const std::string& str) { return getValForKey(str, "[FILE="); }
178 
179 std::string makeKeyValStr(const std::string &key, const std::string & val) {
180  return std::format("[{}={}]", key, val);
181 }
182 
183 
184 // Sort DHForms according to the SW client number so they can be written out in the correct order
185 inline
186 std::string storeSWNInStr(const std::string& str) { return std::format("[SWN={}]", str); }
187 
188 bool DataHeaderCnv::placementComp::operator() (const std::string& lhs, const std::string& rhs) const
189 {
190  std::string lval = getValForKey(lhs,"[FILE=") + getValForKey(lhs,"[CONT=");
191  std::string rval = getValForKey(rhs,"[FILE=") + getValForKey(rhs,"[CONT=");
192  if( lval != rval ) return lval < rval;
193 
194  lval = getSWNFromStr(lhs);
195  rval = getSWNFromStr(rhs);
196  if( lval.empty() or rval.empty() ) return false;
197  return std::stoul( lval ) < std::stoul( rval );
198 }
199 
200 //______________________________________________________________________________
201 /* For SharedWriter
202  Update the DataHeader reference to the DataHeaderForm with new fileName, DataHeader SG Key
203  and SharedWriter client number. The client number will be used by DH to find the right DHForm.
204  The forms are written out in the order of the client numbers, so the Form object OID
205  corresponds to the client number
206  pObject contains pointer to DataHeader_p6
207  pAddress: par[0] contains DH token, par[1] contains placement + DH processingTag as KEY
208 */
209 StatusCode DataHeaderCnv::updateRep(IOpaqueAddress* pAddress, DataObject* pObject)
210 {
211  auto dataHeader = reinterpret_cast<DataHeader_p6*>( pObject );
212  const std::string dhRef = pAddress->par()[0];
213  const std::string dhPlacementStr = pAddress->par()[1];
214  const std::string dhFile = getFILEFromStr( dhPlacementStr );
215  Placement dhFormPlacement;
216  dhFormPlacement.fromString( dataHeader->dhFormToken() );
217  dhFormPlacement.setFileName( dhFile );
218  const std::string clientN = getSWNFromStr( dhPlacementStr );
219  if( !clientN.empty() ) {
220  // Client num in the DHForm ref means it's OneDataHeaderForm mode
221  std::string dhFormNewRef = dhFormPlacement.toString() + storeSWNInStr( clientN );
222  ATH_MSG_DEBUG("Setting DH formRef to: " << dhFormNewRef);
223  dataHeader->setDhFormToken( dhFormNewRef );
224  } else {
225  /* DH is received by the SharedWriter first and needs the DHForm object both for
226  reference (Token) and to add DHElem with the ref to itself.
227  These updates will be handled by updateRepRefs() - cache the DH info so it can
228  by used later by updateRepRefs
229  */
230  if( m_sharedWriterCachedDH ) {
231  ATH_MSG_ERROR( "updateRep called but the previous DataHeader was not yet processed."
232  << " cached DH Key=" << m_sharedWriterCachedDHKey
233  << " cached DH Ref=" << m_sharedWriterCachedDHToken );
234  return StatusCode::FAILURE;
235  }
236  // remember this DH and finish processing in updateRepRefs()
237  m_sharedWriterCachedDH = dataHeader;
239  std::size_t tagBeg = dhPlacementStr.find("[KEY=") + 5;
240  std::size_t tagSize = dhPlacementStr.find(']', tagBeg) - tagBeg;
241  m_sharedWriterCachedDHKey = dhPlacementStr.substr( tagBeg, tagSize );
242  }
243  return StatusCode::SUCCESS;
244 }
245 
246 //______________________________________________________________________________
247 StatusCode DataHeaderCnv::updateRepRefs(IOpaqueAddress* pAddress, DataObject* pObject)
248 {
249  if( m_sharedWriterCachedDH ) {
250  /* Attach a DHForm to the previous DataHeader (in SharedWriter server mode)
251  Finish writing of the DataHeader by attaching the DHForm to it and by adding
252  the self reference. DHForm is passed as pObject and is cached until a new one
253  arrives. This method is called for each event after the DH is received.
254  pObject is null if there is no new DHForm for this event - in this case the old
255  one is used
256  */
257  std::string dhid = pAddress->par()[1];
258  if( pObject ) {
259  this->setToken( pAddress->par()[0] );
260  if( !compareClassGuid( DHForm_p6_Guid ) ) {
261  ATH_MSG_ERROR( "updateRepRefs called without DataHeaderForm" );
262  return StatusCode::FAILURE;
263  }
264  // replace the old DHForm
265  // will keep this DHForm until a new one arrives
266  m_sharedWriterCachedDHForm[dhid].reset( reinterpret_cast<DataHeaderForm_p6*>( pObject ) );
267  m_sharedWriterCachedDHForm[dhid]->setToken( pAddress->par()[0] );
268  }
269  if( m_sharedWriterCachedDHForm.find(dhid) == m_sharedWriterCachedDHForm.end() ) {
270  ATH_MSG_ERROR( "updateRepRefs: missing DataHeaderForm for DH ID=" << dhid );
271  return StatusCode::FAILURE;
272  }
273  // update the cached DataHeader (can be done until a commit is called)
277  // this DataHeader object is now fully processed, so forget it
278  m_sharedWriterCachedDH = nullptr;
279  }
280  else {
281  // In OneDataHeaderForm mode - keep the DHForms from all clients and write them out at the end
282  m_persFormMap[ pAddress->par()[1] ].reset( reinterpret_cast<DataHeaderForm_p6*>( pObject ) );
283  }
284  return(StatusCode::SUCCESS);
285 }
286 
287 //______________________________________________________________________________
288 StatusCode DataHeaderCnv::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj)
289 {
290  DataHeader* obj = nullptr;
291  if (!SG::fromStorable(pObj, obj) || obj == nullptr) {
292  ATH_MSG_ERROR( "Failed to cast DataHeader to transient type" );
293  return(StatusCode::FAILURE);
294  }
295  // DHForm placement:
296  Placement dhf_placement = setPlacementWithType("DataHeaderForm", pObj->name(), *pAddr->par());
297  std::string form_placement_str = dhf_placement.toString();
298  // Find or create Form
299  std::unique_ptr<DataHeaderForm_p6>& dhForm = m_persFormMap[form_placement_str];
300  if (dhForm == nullptr) {
301  // create new DHF for this file. Every new file/container should get its own DHForm
302  dhForm = std::make_unique<DataHeaderForm_p6>();
303  dhForm->setProcessTag( obj->getProcessTag() );
304  }
305 
306  // DH placement first:
307  Placement dh_placement = setPlacementWithType("DataHeader", pObj->name(), *pAddr->par());
308  // remember the connection string, it may get changed in registerForWrite by SharedWriter
309  const std::string connection = dh_placement.fileName();
310  // Create persistent DH and update Form
311  DataHeader_p6* persObj = nullptr;
312  try {
313  persObj = createPersistent(obj, dhForm.get());
314  } catch (std::exception &e) {
315  ATH_MSG_FATAL("Failed to convert DataHeader to persistent type: " << e.what());
316  return(StatusCode::FAILURE);
317  }
318  // Queue the DH for write
319  std::unique_ptr<Token> dh_token (m_athenaPoolCnvSvc->registerForWrite(&dh_placement, persObj, m_classDesc));
320  if (dh_token == nullptr) {
321  ATH_MSG_FATAL("Failed to write DataHeader");
322  return(StatusCode::FAILURE);
323  }
324  keepPoolObj(persObj, connection);
325  // insert self reference - this updates DH and can modify the Form
326  m_tpOutConverter.insertDHRef(persObj, obj->getProcessTag(), dh_token->toString(), *dhForm);
327 
328  if( !m_oneDHForm ) {
329  if( dhForm->isModified() ) {
330  // Write DHForm if in legacy mode in case it was modified (or new)
332  static const RootType dhFormType(typeid(*dhForm));
333  Token* dhf_token = m_athenaPoolCnvSvc->registerForWrite(&dhf_placement, dhForm.get(), dhFormType);
334  if (dhf_token == nullptr) {
335  ATH_MSG_FATAL("Failed to write " << dhFormType.Name());
336  return(StatusCode::FAILURE);
337  }
338  if (dhf_token->technology() != 0) { // Only store DHF token if technology allows it to be appended to DH
339  dhForm->setToken(dhf_token->toString());
340  } else { // Otherwise keep string empty to cause DHF reading via DH token
341  ATH_MSG_DEBUG("Technology does not support setting DHF token for: " << dh_token->toString());
342  dhForm->setToken("");
343  }
344  ATH_MSG_DEBUG("wrote new DHForm with " << dhForm->sizeObj() << " SG object data");
345  dhf_token->release(); dhf_token = nullptr;
346  dhForm->clearModified();
347  }
348  // update the Ref to the DHForm
349  persObj->setDhFormToken( dhForm->getToken() );
350  }
351  else {
352  // use the DHForm placement as a Ref, as the DHForm will be written out at the end only
353  // but add DB ID to the placement str in case the filename is not unique between jobs
354  if( dhForm->getToken().empty() ) {
355  form_placement_str += std::format("[DB={}]", dh_token->dbID().toString());
356  dhForm->setToken( form_placement_str );
357  } else {
358  form_placement_str = dhForm->getToken();
359  }
360  // remove the [FILE= part as the DBID will be enough for reading back
361  auto b = form_placement_str.find("[FILE=");
362  auto e = form_placement_str.find("]", b);
363  form_placement_str.erase(b, e-b+1);
364  // store the modified DHForm placement in place of the Ref in the DH
365  persObj->setDhFormToken( form_placement_str );
366  }
367 
368  const coral::AttributeList* list = obj->getAttributeList();
369  if (list != nullptr) {
370  obj->setEvtRefTokenStr(dh_token->toString());
371  Placement attr_placement = this->setPlacementWithType("AttributeList", "Token", *pAddr->par());
372  const Token* ref_token = m_athenaPoolCnvSvc->registerForWrite(&attr_placement,
373  obj->getEvtRefTokenStr().c_str(),
374  RootType("Token"));
375  delete ref_token; ref_token = nullptr;
376  for (coral::AttributeList::const_iterator iter = list->begin(), last = list->end(); iter != last; ++iter) {
377  attr_placement = this->setPlacementWithType("AttributeList", (*iter).specification().name(), *pAddr->par());
378  const Token* attr_token = m_athenaPoolCnvSvc->registerForWrite(&attr_placement,
379  (*iter).addressOfData(),
380  RootType((*iter).specification().type()) );
381  delete attr_token; attr_token = nullptr;
382  }
383  }
384  TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
385  if (tokAddr != nullptr) {
386  tokAddr->setToken(std::move(dh_token));
387  } else {
388  return(StatusCode::FAILURE);
389  }
390  return(StatusCode::SUCCESS);
391 }
392 
393 //______________________________________________________________________________
394 std::unique_ptr<DataHeader_p5> DataHeaderCnv::poolReadObject_p5()
395 {
396  void* voidPtr1 = nullptr;
397  m_athenaPoolCnvSvc->setObjPtr(voidPtr1, m_i_poolToken);
398  if (voidPtr1 == nullptr) {
399  throw std::runtime_error("Could not get object for token = " + m_i_poolToken->toString());
400  }
401  std::unique_ptr<DataHeader_p5> header( reinterpret_cast<DataHeader_p5*>(voidPtr1) );
402 
403  void* voidPtr2 = nullptr;
404  Token mapToken;
405  mapToken.fromString( header->dhFormToken() );
406  mapToken.setAuxString( m_i_poolToken->auxString() ); // set PersSvc context
407  if (mapToken.classID() != Guid::null()) {
408  if( header->dhFormMdx() != m_dhFormMdx ) {
409  m_athenaPoolCnvSvc->setObjPtr(voidPtr2, &mapToken);
410  if (voidPtr2 == nullptr) {
411  throw std::runtime_error("Could not get object for token = " + mapToken.toString());
412  }
413  m_dhInForm5.reset( reinterpret_cast<DataHeaderForm_p5*>(voidPtr2) );
414  m_dhFormMdx = header->dhFormMdx();
415  }
416  }
417  return header;
418 }
419 
420 //______________________________________________________________________________
421 // Read the persistent rep of DataHeader
422 // Also read DataHeaderForm if not yet cached
423 std::unique_ptr<DataHeader_p6> DataHeaderCnv::poolReadObject_p6()
424 {
425  void* voidPtr1 = nullptr;
426  std::string error_message;
427  try {
428  m_athenaPoolCnvSvc->setObjPtr(voidPtr1, m_i_poolToken);
429  } catch(const std::exception& err) {
430  voidPtr1 = nullptr;
431  error_message = err.what();
432  }
433  if (voidPtr1 == nullptr) {
434  throw std::runtime_error("Could not get object for token = " + m_i_poolToken->toString() + ", " + error_message);
435  }
436  std::unique_ptr<DataHeader_p6> header( reinterpret_cast<DataHeader_p6*>(voidPtr1) );
437 
438  std::string dhFormToken = header->dhFormToken();
439  Token formToken;
440  if( !dhFormToken.empty() and dhFormToken.find("[OID=") == std::string::npos) {
441  // OneForm format of Form Ref (without OID)
442  // we need to reconstruct the real Ref before checking in the Ref cache
443  Placement dhf_placement;
444  dhf_placement.fromString( dhFormToken );
445  formToken.setDb( m_i_poolToken->dbID() );
446  formToken.setCont( dhf_placement.containerName() );
447  formToken.setTechnology( dhf_placement.technology() );
448  formToken.setAuxString( dhf_placement.auxString() );
449  formToken.setClassID( DHForm_p6_Guid );
450  std::int64_t oid2 = m_i_poolToken->oid().second;
451  oid2 >>= 32; oid2 <<= 32;
452  std::string swn = getSWNFromStr( dhFormToken );
453  // add the row number from the SHForm Ref
454  if( !swn.empty() ) oid2 += std::stoul( swn ) - 1;
455  formToken.setOid( {0,oid2} );
456  ATH_MSG_DEBUG("Constructed DHForm Ref=" << formToken.toString() << " from " << dhFormToken );
457  dhFormToken = formToken.toString();
458  header->setDhFormToken( dhFormToken );
459  }
460  // see if the DataHeaderForm is already cached
461  if( dhFormToken.empty() || m_inputDHForms.find(dhFormToken) == m_inputDHForms.end() ) {
462  // no cached DHForm
463  size_t dbpos = dhFormToken.find("[DB=");
464  if( dbpos != std::string::npos ) {
465  const std::string dbGuid = dhFormToken.substr(dbpos+4, dbpos+36);
466  if( ++m_inDHFormCount[dbGuid] > m_inDHFMapMaxsize ) {
467  // prevent the input DHFMap from growing too large
468  clearInputDHFormCache( dbGuid );
469  m_inDHFormCount[dbGuid] = 1;
470  }
471  }
472  // we need to read a new DHF
473  void* voidPtr2 = nullptr;
474  if( dhFormToken.empty() ) {
475  // Some technologies can't set DHF token, use DH token with new CLID.
476  m_i_poolToken->setData(&formToken);
477  formToken.setClassID( DHForm_p6_Guid );
478  } else {
479  formToken.fromString( dhFormToken );
480  formToken.setAuxString( m_i_poolToken->auxString() ); // set PersSvc context
481  }
482  if (formToken.classID() != Guid::null()) {
483  try {
484  m_athenaPoolCnvSvc->setObjPtr(voidPtr2, &formToken);
485  } catch(const std::exception& err) {
486  voidPtr2 = nullptr;
487  error_message = err.what();
488  }
489  if (voidPtr2 == nullptr) {
490  // if there is no good lastGoodDHFRef then try reading DataHeaderForm Token from the first DataHeader
491  if( m_lastGoodDHFRef.find(m_i_poolToken->contID()) == m_lastGoodDHFRef.end() ) {
492  Token firstToken;
493  m_i_poolToken->setData(&firstToken);
494  firstToken.setOid(Token::OID_t(firstToken.oid().first, 0));
495  void* firstPtr1 = nullptr;
496  try {
497  m_athenaPoolCnvSvc->setObjPtr(firstPtr1, &firstToken);
498  } catch(const std::exception& err) {
499  firstPtr1 = nullptr;
500  error_message = err.what();
501  }
502  if (firstPtr1 == nullptr) throw std::runtime_error("Could not get first DataHeader for token = " + firstToken.toString() + ", " + error_message);
503 
504  // Get DataHeaderForm Token from the first DataHeader
505  std::unique_ptr<DataHeader_p6> firstHeader( reinterpret_cast<DataHeader_p6*>(firstPtr1) );
506  dhFormToken = firstHeader->dhFormToken();
507 
508  // Read DataHeaderForm and insert it to the cache
509  formToken.fromString( dhFormToken );
510  formToken.setAuxString( m_i_poolToken->auxString() ); // set PersSvc context
511  try {
512  m_athenaPoolCnvSvc->setObjPtr(voidPtr2, &formToken);
513  } catch(const std::exception& err) {
514  voidPtr2 = nullptr;
515  error_message = err.what();
516  }
517  if (voidPtr2 == nullptr) throw std::runtime_error("Could not get DataHeaderForm for token = " + formToken.toString() + ", " + error_message);
518  m_lastGoodDHFRef[m_i_poolToken->contID()] = dhFormToken;
519  m_inputDHForms[dhFormToken].reset( reinterpret_cast<DataHeaderForm_p6*>(voidPtr2) );
520  ATH_MSG_WARNING("DataHeaderForm read exception: " << error_message << " - reusing the last good DHForm");
521  } else {
522  // try to reuse the last good DHForm Ref (object is already cached)
523  ATH_MSG_WARNING("DataHeaderForm read exception: " << error_message << " - reusing the last good DHForm");
524  }
525  header->setDhFormToken(m_lastGoodDHFRef[m_i_poolToken->contID()]);
526  return header;
527  }
528  if (voidPtr2 == nullptr) {
529  throw std::runtime_error("Could not get object for token = " + formToken.toString());
530  }
531  m_lastGoodDHFRef[m_i_poolToken->contID()] = dhFormToken;
532  }
533  m_inputDHForms[dhFormToken].reset( reinterpret_cast<DataHeaderForm_p6*>(voidPtr2) );
534  }
535  return header;
536 }
537 
538 //______________________________________________________________________________
540 {
541  return m_tpOutConverter.createPersistent( transObj, *dh_form );
542 }
543 
544 //______________________________________________________________________________
546 {
547  auto iter = dh->m_inputDataHeader.begin();
548  while( iter != dh->m_inputDataHeader.end() ) {
549  if( iter->getToken()->dbID() == Guid::null() ) {
550  ATH_MSG_WARNING("Removed incomplete Input Element");
551  iter = dh->m_inputDataHeader.erase(iter);
552  } else {
553  ++iter;
554  }
555  }
556 }
557 
558 //______________________________________________________________________________
560  if (this->m_i_poolToken == nullptr) {
561  return(nullptr);
562  }
563  if (this->m_i_poolToken->technology() == 0x00001000) { // Artificial ByteStream DataHeader Token
564  DataHeader* dh = new DataHeader();
565  std::string bestPfn, fileType;
566  m_athenaPoolCnvSvc->getPoolSvc()->lookupBestPfn(this->m_i_poolToken->dbID().toString(), bestPfn, fileType);
568  dh->insert(dhe);
569  return(dh);
570  }
571  static const pool::Guid p6_guid("4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
572  static const pool::Guid p5_guid("D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
573  static const pool::Guid p4_guid("9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
574  static const pool::Guid p3_guid("EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
575  try {
576  if( compareClassGuid( p6_guid ) ) {
577  std::unique_ptr<DataHeader_p6> header( poolReadObject_p6() );
578  auto dhForm = m_inputDHForms[ header->dhFormToken() ].get();
579  auto dh = m_tpInConverter.createTransient( header.get(), *dhForm, m_i_poolToken );
581  // To dump the DataHeader uncomment below
582  // std::ostringstream ss; dh->dump(ss); std::cout << ss.str() << std::endl;
583  return dh;
584  } else if (this->compareClassGuid( p5_guid )) {
585  std::unique_ptr<DataHeader_p5> obj_p5( poolReadObject_p5() );
586  return m_tpInConverter_p5.createTransient( *obj_p5, *m_dhInForm5 ).release();
587  } else if (this->compareClassGuid( p4_guid )) {
588  std::unique_ptr<DataHeader_p4> obj_p4(this->poolReadObject<DataHeader_p4>());
589  DataHeaderCnv_p4 tPconverter_p4;
590  return(tPconverter_p4.createTransient(obj_p4.get()));
591  } else if (this->compareClassGuid( p3_guid )) {
592  std::unique_ptr<DataHeader_p3> obj_p3(this->poolReadObject<DataHeader_p3>());
593  DataHeaderCnv_p3 tPconverter_p3;
594  return(tPconverter_p3.createTransient(obj_p3.get()));
595  }
596  } catch (std::exception &e) {
597  // upgrade all exceptions to runtime_error (who needs that? MN)
598  std::string error = e.what();
599  throw std::runtime_error(error);
600  }
601  return(nullptr);
602 }
DataHeaderCnv::handle
virtual void handle(const Incident &incident) override
Incident service handle listening for EndInputFile.
Definition: DataHeaderCnv.cxx:89
getFILEFromStr
std::string getFILEFromStr(const std::string &str)
Definition: DataHeaderCnv.cxx:177
DataHeaderForm_p6
This class provides storage for the constant fields of the persistent DataHeader class.
Definition: DataHeader_p6.h:27
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
DataHeaderCnv::m_persFormMap
std::map< std::string, std::unique_ptr< DataHeaderForm_p6 >, placementComp > m_persFormMap
Definition: DataHeaderCnv.h:75
DataHeaderCnv_p6::setSGAliasFiltering
void setSGAliasFiltering(bool doFiltering)
Definition: DataHeaderCnv_p6.h:45
Guid::null
static const Guid & null()
NULL-Guid: static class method.
Definition: Guid.cxx:18
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:56
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
DataHeaderForm_p6::isModified
bool isModified() const
Definition: DataHeader_p6.cxx:134
storeSWNInStr
std::string storeSWNInStr(const std::string &str)
Definition: DataHeaderCnv.cxx:186
DataHeaderCnv::updateRep
virtual StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Extend base-class conversion methods.
Definition: DataHeaderCnv.cxx:209
DataHeaderCnv::createTransient
virtual DataHeader * createTransient() override
Definition: DataHeaderCnv.cxx:559
header
Definition: hcg.cxx:526
DataHeaderCnv::m_sharedWriterCachedDHToken
std::string m_sharedWriterCachedDHToken
Definition: DataHeaderCnv.h:96
Placement::containerName
const std::string & containerName() const
Access container name.
Definition: Placement.h:32
vtune_athena.format
format
Definition: vtune_athena.py:14
DataHeaderForm_p6::setVersion
void setVersion(const DHVersions ver)
change version if writing backward compatible format
Definition: DataHeader_p6.h:87
AthCheckMacros.h
Token::contID
const std::string & contID() const
Access container identifier.
Definition: Token.h:69
SG::fromStorable
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
Definition: StorableConversions.h:169
AthenaPoolConverter::m_athenaPoolCnvSvc
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
Definition: AthenaPoolConverter.h:117
DataHeaderCnv::m_dhFormMdx
std::string m_dhFormMdx
Definition: DataHeaderCnv.h:89
DataHeaderCnv::m_sharedWriterCachedDHKey
std::string m_sharedWriterCachedDHKey
Definition: DataHeaderCnv.h:95
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
Token::auxString
const std::string & auxString() const
Access auxiliary string.
Definition: Token.h:91
DataHeaderCnv::m_tpOutConverter
DataHeaderCnv_p6 m_tpOutConverter
Definition: DataHeaderCnv.h:65
Token::dbID
const Guid & dbID() const
Access database identifier.
Definition: Token.h:64
T_AthenaPoolCustomCnvWithKey::keepPoolObj
void keepPoolObj(PERS *obj, const std::string &output)
Remember the POOL object to be written out (will be deleted after commit)
DataHeaderForm_p5
This class provides storage for the constant fields of the persistent DataHeader class.
Definition: DataHeader_p5.h:42
Placement::technology
int technology() const
Access technology type.
Definition: Placement.h:36
Guid::toString
const std::string toString() const
Automatic conversion to string representation.
Definition: Guid.cxx:58
DataHeaderCnv::m_tpInConverter_p5
DataHeaderCnv_p5 m_tpInConverter_p5
for use when reading DataHeader_p5
Definition: DataHeaderCnv.h:87
PyPoolBrowser.dh
dh
Definition: PyPoolBrowser.py:102
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
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
DataHeaderForm_p6::setProcessTag
void setProcessTag(const std::string &tag)
Definition: DataHeader_p6.h:84
DataHeaderCnv::m_inputDHForms
std::map< std::string, std::unique_ptr< DataHeaderForm_p6 > > m_inputDHForms
DHForm cache indexed by the DHForm reference (from DataHeader) that was used to read it.
Definition: DataHeaderCnv.h:77
DataHeader_p6::setDhFormToken
void setDhFormToken(const std::string &formToken)
Definition: DataHeader_p6.cxx:166
DataHeaderCnv::m_sharedWriterCachedDHForm
std::map< std::string, std::unique_ptr< DataHeaderForm_p6 > > m_sharedWriterCachedDHForm
map of cached DHForms for DataHeader ID
Definition: DataHeaderCnv.h:94
makeKeyValStr
std::string makeKeyValStr(const std::string &key, const std::string &val)
Definition: DataHeaderCnv.cxx:179
getSWNFromStr
std::string getSWNFromStr(const std::string &str)
Definition: DataHeaderCnv.cxx:175
RootType
TTypeAdapter RootType
Definition: RootType.h:211
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
T_AthenaPoolCustCnv::setToken
virtual void setToken(const std::string &token)
Set the token (in std::string representation) and classID for the object that will be read next.
Token
This class provides a token that identifies in a unique way objects on the persistent storage.
Definition: Token.h:21
DataHeaderCnv::DataHeaderCnv
DataHeaderCnv(ISvcLocator *svcloc)
Definition: DataHeaderCnv.cxx:33
DataHeaderCnv::placementComp::operator()
bool operator()(const std::string &lhs, const std::string &rhs) const
Definition: DataHeaderCnv.cxx:188
TokenAddress
This class provides a Generic Transient Address for POOL tokens.
Definition: TokenAddress.h:23
DataHeaderCnv::m_inDHFMapMaxsize
unsigned m_inDHFMapMaxsize
Max DHForms to cache per input file.
Definition: DataHeaderCnv.h:82
DataHeaderForm_p6::DHverFormRef
@ DHverFormRef
Definition: DataHeader_p6.h:50
getValForKey
std::string getValForKey(const std::string &str, const std::string &key)
Definition: DataHeaderCnv.cxx:164
Token::OID_t
Definition: Token.h:24
pool::Guid
::Guid Guid
Definition: T_AthenaPoolCustCnv.h:19
Token::fromString
Token & fromString(const std::string &from)
Build from the string representation of a token.
Definition: Token.cxx:148
Token::setClassID
Token & setClassID(const Guid &cl_id)
Access database identifier.
Definition: Token.h:75
DataHeaderElement
This class provides a persistent form for the TransientAddress.
Definition: DataHeader.h:37
Token::technology
int technology() const
Access technology type.
Definition: Token.h:77
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
DataHeaderCnv_p6::insertDHRef
void insertDHRef(DataHeader_p6 *pers_dh, const std::string &key, const std::string &dh_tokstr, DataHeaderForm_p6 &dh_form) const
insert DH self reference as one of the DHElements. Contains the stream Key
Definition: DataHeaderCnv_p6.cxx:180
DataHeaderForm_p6::getToken
const std::string & getToken() const
Definition: DataHeader_p6.cxx:147
DataHeaderCnv::m_sharedWriterCachedDH
DataHeader_p6 * m_sharedWriterCachedDH
cached values for use with SharedWriter server
Definition: DataHeaderCnv.h:92
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
T_AthenaPoolCustomCnv
Compatibility for old converter classes that don't get passed the key.
Definition: T_AthenaPoolCustomCnv.h:132
DataHeader
This class provides the layout for summary information stored for data written to POOL.
Definition: DataHeader.h:126
DataHeader_p6::dhFormToken
const std::string & dhFormToken() const
Definition: DataHeader_p6.cxx:162
beamspotman.n
n
Definition: beamspotman.py:731
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
DataHeaderCnv::updateRepRefs
virtual StatusCode updateRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Definition: DataHeaderCnv.cxx:247
DataHeaderCnv_p6::createPersistent
DataHeader_p6 * createPersistent(const DataHeader *transObj, DataHeaderForm_p6 &form) const
Definition: DataHeaderCnv_p6.cxx:162
DataHeaderCnv::DataObjectToPool
virtual StatusCode DataObjectToPool(IOpaqueAddress *pAddr, DataObject *pObj) override
Write an object into POOL.
Definition: DataHeaderCnv.cxx:288
ClassID_traits
Default, invalid implementation of ClassID_traits.
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:37
DataHeaderCnv::m_tpInConverter
DataHeaderCnv_p6 m_tpInConverter
Definition: DataHeaderCnv.h:66
calibdata.exception
exception
Definition: calibdata.py:496
DataHeaderCnv_p3.h
This file contains the class definition for the DataHeaderCnv_p3 and DataHeaderElementCnv_p3 classes.
DataHeaderCnv::clearInputDHFormCache
void clearInputDHFormCache(const std::string &dbGuid)
Delete cached DHForms for a given input file GUID.
Definition: DataHeaderCnv.cxx:149
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Token::setDb
Token & setDb(const Guid &db)
Set database name.
Definition: Token.h:66
Placement::fileName
const std::string & fileName() const
Access file name.
Definition: Placement.h:28
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
Token::release
int release()
Release token: Decrease reference count and eventually delete.
Definition: Token.cxx:75
Placement::setFileName
Placement & setFileName(const std::string &fileName)
Set file name.
Definition: Placement.h:30
Token::setTechnology
Token & setTechnology(int t)
Set technology type.
Definition: Token.h:79
DataHeader_p6
This class provides a persistent representation for the DataHeader class.
Definition: DataHeader_p6.h:115
Placement::auxString
const std::string & auxString() const
Access auxiliary string.
Definition: Placement.h:40
DataHeaderCnv_p4::createTransient
DataHeader * createTransient(const DataHeader_p4 *persObj)
Definition: DataHeaderCnv_p4.h:51
TScopeAdapter::Name
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition: RootType.cxx:607
DataHeaderCnv::createPersistent
DataHeader_p6 * createPersistent(DataHeader *transObj, DataHeaderForm_p6 *)
Definition: DataHeaderCnv.cxx:539
DataHeaderCnv::m_dhInForm5
std::unique_ptr< DataHeaderForm_p5 > m_dhInForm5
Definition: DataHeaderCnv.h:88
DataHeaderCnv::poolReadObject_p5
std::unique_ptr< DataHeader_p5 > poolReadObject_p5()
Definition: DataHeaderCnv.cxx:394
DataHeader::insert
void insert(const SG::TransientAddress *sgAddress, IOpaqueAddress *tokAddress=0, const std::string &pTag="")
Insert a new element into the "DataObject" vector.
Definition: DataHeader.cxx:266
pool_uuid.guid
guid
Definition: pool_uuid.py:112
TokenAddress::setToken
void setToken(std::unique_ptr< Token > token)
Definition: TokenAddress.cxx:9
DataHeaderCnv::m_lastGoodDHFRef
std::map< std::string, std::string > m_lastGoodDHFRef
Definition: DataHeaderCnv.h:84
DataHeaderForm_p6::clearModified
void clearModified()
Definition: DataHeader_p6.cxx:138
DataHeaderCnv_p4.h
This file contains the class definition for the DataHeaderCnv_p4 and DataHeaderElementCnv_p4 classes.
DataHeaderCnv::m_oneDHForm
bool m_oneDHForm
if true write only one DataHeaderForm at the end (stop, finalize, or WriteDataHeaderForms incident) t...
Definition: DataHeaderCnv.h:72
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
DataHeaderForm_p6::setToken
void setToken(const std::string &tok)
Definition: DataHeader_p6.cxx:142
DataHeaderCnv_p4
This class provides the converter to customize the saving of DataHeader_p4.
Definition: DataHeaderCnv_p4.h:35
Token::toString
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition: Token.cxx:129
DataHeaderForm_p6::sizeObj
std::size_t sizeObj() const
Definition: DataHeader_p6.cxx:100
DataHeaderCnv::m_inDHFormCount
std::map< std::string, unsigned > m_inDHFormCount
How many DHForms for an input file are in the cache.
Definition: DataHeaderCnv.h:80
Token::setOid
Token & setOid(const OID_t &oid)
Set object identifier.
Definition: Token.h:85
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Placement::toString
const std::string toString() const
Retrieve the string representation of the placement.
Definition: Placement.cxx:15
DataHeaderCnv_p3::createTransient
DataHeader * createTransient(const DataHeader_p3 *persObj)
Definition: DataHeaderCnv_p3.h:51
DataHeaderCnv_p6::createTransient
DataHeader * createTransient(const DataHeader_p6 *persObj, const DataHeaderForm_p6 &form, const Token *dhToken) const
Definition: DataHeaderCnv_p6.cxx:72
TokenAddress.h
This file contains the class definition for the TokenAddress class.
DataHeaderCnv::removeBadElements
void removeBadElements(DataHeader *dh)
Remove DataHeaderElements with incomplete (dbID="") refs.
Definition: DataHeaderCnv.cxx:545
DataHeaderCnv_p5::createTransient
std::unique_ptr< DataHeader > createTransient(const DataHeader_p5 &persObj, const DataHeaderForm_p5 &dhForm) const
Definition: DataHeaderCnv_p5.h:70
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
DataHeader_p5
This class provides a persistent representation for the DataHeader class.
Definition: DataHeader_p5.h:67
Token::oid
const OID_t & oid() const
Access object identifier.
Definition: Token.h:81
Token::setAuxString
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
Definition: Token.h:93
Token::setCont
Token & setCont(const std::string &cnt)
Set container name.
Definition: Token.h:71
str
Definition: BTagTrackIpAccessor.cxx:11
T_AthenaPoolCustCnv::compareClassGuid
virtual bool compareClassGuid(const Guid &clid) const
Compare POOL class GUID with the one of the object being read.
jobOptions.fileName
fileName
Definition: jobOptions.SuperChic_ALP2.py:39
Placement.h
This file contains the class definition for the Placement class (migrated from POOL).
DataHeaderCnv_p3
This class provides the converter to customize the saving of DataHeader_p3.
Definition: DataHeaderCnv_p3.h:35
AthenaPoolConverter::m_classDesc
RootType m_classDesc
Definition: AthenaPoolConverter.h:118
Token::setData
const Token & setData(Token *pToken) const
Set all the data part of the token.
Definition: Token.cxx:209
makeTOC.header
header
Definition: makeTOC.py:28
T_AthenaPoolCustCnv::initialize
virtual StatusCode initialize()
Gaudi Service Interface method implementations:
python.PyAthena.obj
obj
Definition: PyAthena.py:132
DataHeaderCnv::~DataHeaderCnv
~DataHeaderCnv()
Definition: DataHeaderCnv.cxx:40
Token.h
This file contains the class definition for the Token class (migrated from POOL).
error
Definition: IImpactPoint3dEstimator.h:70
Placement::fromString
Placement & fromString(const std::string &from)
Build from the string representation of a placement.
Definition: Placement.cxx:28
DataHeaderCnv::poolReadObject_p6
std::unique_ptr< DataHeader_p6 > poolReadObject_p6()
Definition: DataHeaderCnv.cxx:423
DataHeaderCnv::initialize
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
Definition: DataHeaderCnv.cxx:49
ServiceHandle< IIncidentSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
DataHeaderCnv.h
This file contains the class definition for the DataHeaderCnv class.
TScopeAdapter
Definition: RootType.h:119