ATLAS Offline Software
TrigSerTPTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id$
6 
7 // ROOT include(s):
8 #include <TClass.h>
9 
10 // Gaudi/Athena include(s):
11 #include "GaudiKernel/System.h"
16 
17 // Local include(s):
19 
20 
21 TrigSerTPTool::TrigSerTPTool( const std::string& type,
22  const std::string& name,
23  const IInterface* parent) :
25  m_msgsvcTP( "", name ),
26  m_dictSvc( "AthDictLoaderSvc", name ),
27  m_useAthDictLoader( true ),
28  m_online( false ),
29  m_tpcnvsvc( "AthTPCnvSvc", name ) {
30 
31  declareInterface< TrigSerTPTool >( this );
32 
33  declareProperty( "TPMap", m_TPmap, "map of T->P classes" );
34  declareProperty( "ActiveClasses", m_activeClasses,
35  "allows to skip classes not relevant in the current "
36  "trigger level" );
37  declareProperty( "debuggingMsgSvc", m_msgsvcTP,
38  "an instance of the messageSvc for debugging purposes" );
39  declareProperty( "onlineMode", m_online,
40  "simpler setup for running online" );
41  declareProperty( "useAthDictLoader", m_useAthDictLoader,
42  "use AthDictLoaderSvc instead of plain ROOT" );
43 }
44 
46 
47  // Greet the user:
48  ATH_MSG_INFO( "Initializing" );
49 
50  // Retrieve a custom message service:
51  if( ! m_msgsvcTP.empty() ) {
52  if( m_msgsvcTP.retrieve().isFailure() ) {
53  ATH_MSG_INFO( "Could not retrieve a separate MsgSvc for "
54  "the T/P debugging" );
55  } else {
56  ATH_MSG_DEBUG( "Using " << m_msgsvcTP << " for debugging" );
57  IMessageSvc* msvc = m_msgsvcTP.operator->();
58  m_logTP = std::make_unique< MsgStream >( msvc,
59  "TrigSerTPTool-T/P" );
60  }
61  }
62 
63  // Retrieve the used services:
64  ATH_CHECK( m_dictSvc.retrieve() );
65  ATH_CHECK( m_tpcnvsvc.retrieve() );
66 
67  /* When a P<->T conversion is requested, this tool makes a call to TClass::GetClass.
68  * The way it's done here can cause performance issues in some circumstances.
69  * For example, reading data16 RAW files trigger a P->T conversion from
70  * DataVector<xAOD::TauJet_v2> to DataVector<xAOD::TauJet_v3> in RAWtoALL/22.0.62.
71  * The problem is that the converter returns the full class name through
72  * ITPCnvBase::transientTInfo(), which in this case resolves into
73  * DataVector<xAOD::TauJet_v3,DataVector<xAOD::IParticle,DataModel_detail::NoBase> >
74  * Passing this directly to TClass::GetClass causes AutoLoading/HeaderParsing
75  * which notoriously allocates memory and never releases it. Here, we work
76  * around this problem by stripping the base class information from the name
77  * that's passed to TClass::GetClass, in this case simply DataVector<xAOD::TauJet_v3>
78  */
79  m_clNameRules.add("DataVector<$T, $B>", "DataVector<$T>");
80 
81  return StatusCode::SUCCESS;
82 }
83 
85 {
86  std::lock_guard<std::mutex> lock(m_convertersCacheMutex);
87  ITPCnvBase* cnvtr = m_convertesCache[persistent];
88  if ( ATH_LIKELY( cnvtr ) )
89  return cnvtr;
90 
91  // no converter, we need to find it, first the trigger specific one
93  if( ! cnvtr ) {
94  // If there is no such thing, try a generic one:
95  cnvtr = m_tpcnvsvc->p2t_cnv( persistent );
96  }
97  m_convertesCache[persistent] = cnvtr;
98  return cnvtr;
99 }
100 
101 void* TrigSerTPTool::convertTP( const std::string &clname, void *ptr,
102  std::string &persName ) const
103 {
104  ATH_MSG_DEBUG( "TrigSerTPTool::convertTP" );
105 
106  //pers and persName set only after successful conversion
107  persName = "";
108  void *pers( 0 );
109 
110  // Start by trying to find the correct persistent class from the TP map
111  // Otherwise, use the internal logic of the TPCnvSvc
112  const auto tpItr = m_TPmap.find( clname );
113  if( tpItr == m_TPmap.end() ) {
114  REPORT_MESSAGE( MSG::ERROR )
115  << "Transient class " << clname
116  << " is not in the T/P Converter map";
117  return 0;
118  }
119  persName = tpItr->second;
120 
121  ITPCnvBase* cnvtr = getConverter( persName );
122  if( ! cnvtr ) {
123  ATH_MSG_ERROR( "T/P Converter for transient class " << tpItr->first
124  << " persistent class " << persName << " could not be retrieved");
125  return nullptr;
126  }
127 
128  // Create a persistent object:
129  const std::string persname =
131  TClass *persObjCl = getClass( persname );
132  void *persptr( 0 );
133  if( persObjCl ) {
134  persptr = persObjCl->New();
135  ATH_MSG_DEBUG( "created object of " << persptr << " at " << persptr );
136  } else {
137  REPORT_MESSAGE( MSG::ERROR )
138  << "Couldn't find dictionary for type " << persname;
139  return 0;
140  }
141 
142  // Do the conversion:
143  ATH_MSG_DEBUG( "invoking TP for " << clname << " at " << ptr );
144  try {
145  cnvtr->transToPersUntyped( ptr, persptr, m_logTP ? *m_logTP : msg() );
146  persName = persname;
147  pers = persptr;
148  ATH_MSG_DEBUG( "succeeded at " << persptr );
149  }
150  catch( const std::runtime_error& e ){
151 
152  //delete persObjCl->New();
153  const std::string issue = e.what();
154  if( issue.find( "is deprecated" ) != std::string::npos ) {
155  ATH_MSG_INFO( "An exception " << e.what() );
156  } else {
157  pers = 0;
158  REPORT_MESSAGE( MSG::ERROR ) << "An exception occurred: " << e.what();
159  }
160  }
161 
162  // Return the converted object:
163  return pers;
164 }
165 
166 void* TrigSerTPTool::convertPT( const std::string &persName, void *pers,
167  std::string& transName ) const
168 {
169  // First look for a trigger specific converter:
170  ITPCnvBase* cnvtr =
171  m_tpcnvsvc->p2t_cnv( persName, Athena::TPCnvType::Trigger );
172  if( ! cnvtr ) {
173  // If there is no such thing, try a generic one:
174  cnvtr = m_tpcnvsvc->p2t_cnv( persName );
175  }
176  if( ! cnvtr ) {
177  REPORT_MESSAGE( MSG::ERROR )
178  << "T/P Converter for persistent class "
179  << persName << " could not be retrieved";
180  return 0;
181  }
182 
183  // Get the name of the transient class:
184  transName = m_clNameRules.apply( System::typeinfoName( cnvtr->transientTInfo() ) );
185 
186  // Create the transient object:
187  TClass *transCl = getClass( transName );
188  void *trans( 0 );
189  if( transCl ){
190  trans = transCl->New();
191  ATH_MSG_DEBUG( "trans " << trans );
192  }
193 
194  // Do the conversion:
195  ATH_MSG_DEBUG( "invoking PT for " << transName );
196  try {
197  cnvtr->persToTransWithKeyUntyped( pers, trans, "", m_logTP ? *m_logTP : msg() );
198  ATH_MSG_DEBUG( " succeeded at " << trans );
199  }
200  catch (const std::runtime_error& e){
201  REPORT_MESSAGE( MSG::ERROR ) << "An exception occurred: " << e.what();
202  //it should destruct trans here (is it in a good state?)
203  trans = 0;
204  }
205 
206  // Return the converted object:
207  return trans;
208 }
209 
210 const std::string&
211 TrigSerTPTool::persClassName( const std::string& transClassName ) const {
212 
213  // Try to extract from the TP map
214  const auto tpItr = m_TPmap.find( transClassName );
215  if( tpItr == m_TPmap.end() ) {
216  REPORT_MESSAGE( MSG::ERROR )
217  << "Transient class " << transClassName
218  << " is not in the T/P Converter map";
219  static const std::string dummy( "" );
220  return dummy;
221  }
222 
223  // Return the persistent class name:
224  return tpItr->second;
225 }
226 
227 TClass *TrigSerTPTool::getClass( const std::string &cname ) const {
228 
229  TClass *cl( 0 );
230  if( m_useAthDictLoader && m_dictSvc ){
231  m_dictSvc->load_type( cname );
232  }
233  cl = TClass::GetClass( cname.c_str() );
234  return cl;
235 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TrigSerTPTool.h
python.TriggerEDMRun3.persistent
def persistent(transient)
Definition: TriggerEDMRun3.py:1157
TrigSerTPTool::m_tpcnvsvc
ServiceHandle< ITPCnvSvc > m_tpcnvsvc
Definition: TrigSerTPTool.h:71
TrigSerTPTool::m_TPmap
std::map< std::string, std::string > m_TPmap
Definition: TrigSerTPTool.h:65
CxxUtils::ClassName::Rules::add
void add(const ClassName &pattern, const ClassName &replacement)
Add a new transformation rule.
Definition: CxxUtils/Root/ClassName.cxx:60
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TrigSerTPTool::m_dictSvc
ServiceHandle< IDictLoaderSvc > m_dictSvc
Definition: TrigSerTPTool.h:68
TrigSerTPTool::m_convertersCacheMutex
std::mutex m_convertersCacheMutex
Definition: TrigSerTPTool.h:72
Athena::TPCnvType::Trigger
@ Trigger
Definition: TPCnvFactory.h:125
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
ITPCnvBase.h
ITPCnvBase::transientTInfo
virtual const std::type_info & transientTInfo() const =0
return C++ type id of the transient class this converter is for
TrigSerTPTool::persClassName
const std::string & persClassName(const std::string &transClassName) const
Get the name of the persistent class belonging to a transient one.
Definition: TrigSerTPTool.cxx:211
TrigSerTPTool::getConverter
ITPCnvBase * getConverter(const std::string &persistent) const
Definition: TrigSerTPTool.cxx:84
TrigSerTPTool::m_msgsvcTP
ServiceHandle< IMessageSvc > m_msgsvcTP
Definition: TrigSerTPTool.h:67
ITPCnvBase::transToPersUntyped
virtual void transToPersUntyped(const void *trans, void *pers, MsgStream &msg)=0
Convert transient object representation to persistent.
AthUnlikelyMacros.h
TrigSerTPTool::m_logTP
std::unique_ptr< MsgStream > m_logTP
Definition: TrigSerTPTool.h:64
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Athena::typeinfoName
std::string typeinfoName(const std::type_info &ti)
Convert a type_info to a demangled string.
Definition: AthenaKernel/src/ClassName.cxx:23
TrigSerTPTool::convertTP
void * convertTP(const std::string &transName, void *trans, std::string &persName) const
Convert a transient object to its persistent self.
Definition: TrigSerTPTool.cxx:101
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
TrigSerTPTool::convertPT
void * convertPT(const std::string &persName, void *pers, std::string &transName) const
Convert a persistent object to its transient self.
Definition: TrigSerTPTool.cxx:166
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CxxUtils::ClassName::Rules::apply
std::string apply(const std::string &name) const
Apply transformations to a class name.
Definition: CxxUtils/Root/ClassName.cxx:127
python.xAODType.dummy
dummy
Definition: xAODType.py:4
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrigSerTPTool::m_useAthDictLoader
bool m_useAthDictLoader
Definition: TrigSerTPTool.h:69
TrigSerTPTool::TrigSerTPTool
TrigSerTPTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard AlgTool constructor.
Definition: TrigSerTPTool.cxx:21
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
errorcheck.h
Helpers for checking error return status codes and reporting errors.
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
ITPCnvBase
Definition: ITPCnvBase.h:24
ITPCnvBase::persToTransWithKeyUntyped
virtual void persToTransWithKeyUntyped(const void *pers, void *trans, const std::string &, MsgStream &msg)
Convert persistent object representation to transient.
Definition: ITPCnvBase.h:53
ATH_LIKELY
#define ATH_LIKELY(x)
Definition: AthUnlikelyMacros.h:16
IDictLoaderSvc.h
ITPCnvBase::persistentTInfo
virtual const std::type_info & persistentTInfo() const =0
return C++ type id of the persistent class this converter is for
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TrigSerTPTool::m_activeClasses
std::vector< std::string > m_activeClasses
Definition: TrigSerTPTool.h:66
TrigSerTPTool::initialize
virtual StatusCode initialize() override
Function initialising the tool.
Definition: TrigSerTPTool.cxx:45
AthAlgTool
Definition: AthAlgTool.h:26
TrigSerTPTool::getClass
TClass * getClass(const std::string &clname) const
Get the ROOT dictionary for a type.
Definition: TrigSerTPTool.cxx:227
TrigSerTPTool::m_clNameRules
CxxUtils::ClassName::Rules m_clNameRules
Definition: TrigSerTPTool.h:62
TrigSerTPTool::m_online
bool m_online
Definition: TrigSerTPTool.h:70
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26