ATLAS Offline Software
TrigSerializeConverter.h
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 
3 /*
4  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // $Id$
8 #ifndef TRIGSERIALIZECONVERTER_H
9 #define TRIGSERIALIZECONVERTER_H
10 
11 #include "GaudiKernel/Converter.h"
12 #include "GaudiKernel/ToolHandle.h"
13 #include "GaudiKernel/ServiceHandle.h"
14 
17 #include "StoreGate/StoreGateSvc.h"
18 
22 
26 
27 #include <memory>
28 
29 
30 //fwd
31 template< class Cnv >
32 class CnvFactory;
33 
34 /***
35  * @brief TrigSerializeConverter is a templated converter which implements
36  * conversions from transient to persistent representation (and back)
37  * used by TrigSerializeCnvSvc to serialize and deserialize Trigger objects
38  *
39  * @author Jiri Masik Jiri.Masik@cern.ch
40  * @author Lukas Heinrich lukas.heinrich@cern.ch
41  */
42 
43 namespace SG{class AuxElement;}
44 namespace SG{class IAuxStore;}
45 
46 
47 template<typename T>
48  struct isxAOD {
49  template<typename C>
50  constexpr static typename std::enable_if<std::is_base_of<SG::AuxElement,typename std::pointer_traits<typename C::value_type>::element_type>::value,bool>::type isxAODVector(C*){return true;}
51  template<typename C>
52  constexpr static bool isxAODVector(...){return false;}
53  template<typename C>
54  constexpr static typename std::enable_if<std::is_base_of<SG::IAuxStore,C>::value,bool>::type isAuxVector(C*){return true;}
55  template<typename C>
56  constexpr static bool isAuxVector(...){return false;}
57  static const bool value = isxAODVector<T>(0) || isAuxVector<T>(0);
58 };
59 
60 
61 namespace TrigSerialization {
62 
63 
71 template <class DATA>
72 DATA* prepareForWrite (DATA* d, std::unique_ptr<DATA>& /*holder*/)
73 {
74  return d;
75 }
76 
77 
88 template <class DV>
90  std::unique_ptr<ViewVector<DV> >& holder)
91 {
92  holder = std::make_unique<ViewVector<DV> > (*d);
93  holder->setClearOnPersistent();
94  return holder.get();
95 }
96 
97 
104 template <class DATA>
105 DATA* finishRead (DATA* d)
106 {
107  return d;
108 }
109 
110 
118 template <class DV>
120 {
121  // In the case of schema evolution, we'll actually get a
122  // @c ViewVector for a different _v type.
123  if (typeid(*d) != typeid(ViewVector<DV>)) {
124  auto d2 = std::make_unique<ViewVector<DV> > (*d);
125  delete d;
126  d = d2.release();
127  // root read rule doesn't do anything in this case.
128  d->toTransient();
129  }
130  d->clearPersistent();
131  return d;
132 }
133 
134 
135 } // namespace TrigSerialization
136 
137 
138 template< typename DATA >
140 
141 public:
142  static const bool typeIsxAOD = isxAOD<DATA>::value;
143 
144  // per->tran
145  StatusCode createObj( IOpaqueAddress* iAddr, DataObject *& pO ) {
146 
147  const std::string clname = ClassID_traits< DATA >::typeName();
148 
149  std::string normalized = SG::normalizedTypeinfoName( typeid(DATA) ); // normalized string representation (matching the names used in the root dictionary)
150 
151 
152  void *ptr( 0 );
153  if( m_log->level() <= MSG::DEBUG ) {
154  *m_log << MSG::DEBUG << "In createObj for : " << clname << " normalized to " << normalized << endmsg;
155  }
156 
157  StatusCode sc = m_convHelper->createObj( normalized, iAddr, ptr, typeIsxAOD);
158  if( sc.isFailure() ){
159  *m_log << MSG::WARNING << "m_convHelper->createObj failed for "
160  << clname << endmsg;
161  }
162 
163  DATA *nObj = ( DATA* ) ptr;
164  nObj = TrigSerialization::finishRead (nObj);
165  pO = SG::asStorable( nObj );
166 
167  if( m_log->level() <= MSG::DEBUG ) {
168  *m_log << MSG::DEBUG << "IOpaq: " << iAddr
169  << " created nObj: " << nObj << endmsg;
170  }
171 
172 
173 
174 
175  if( m_sgsvc && nObj ){
176  TrigStreamAddress *addr = dynamic_cast< TrigStreamAddress* >( iAddr );
177  if( addr ) {
178  if( m_sgsvc->contains< DATA >( addr->sgkey() ) ) {
179  *m_log << MSG::WARNING << "TrigSerializeConverter::createObj object "
180  << clname << " / " << addr->sgkey()
181  << " is already in the store; not overwriting"
182  << endmsg;
183  } else {
184  sc = m_sgsvc->record( nObj, addr->sgkey() );
185  }
186  if( sc.isFailure() ) {
187  *m_log << MSG::ERROR << "SG::record failed for " << addr->sgkey()
188  << endmsg;
189  } else if( m_log->level() <= MSG::DEBUG ) {
190  *m_log << MSG::DEBUG << "SG::record key: "
191  << addr->sgkey() << " class: " << clname << endmsg;
192  }
193  } else {
194  *m_log << MSG::WARNING << "createObj cast failed" << endmsg;
195  }
196  } else if( m_log->level() <= MSG::DEBUG ) {
197  *m_log << MSG::DEBUG << "did not put an object into SG" << endmsg;
198  }
199 
200  return sc;
201  }
202 
203  // tran->per
204  StatusCode createRep( DataObject* pObj, IOpaqueAddress*& pAddr ) {
205 
206  // const std::string clname = ClassID_traits<DATA>::typeName(); // old style, does not contain the _vX of the actual class type
207 
208  // const std::type_info& typeId = ClassID_traits<DATA>::typeId(); // damn, this line just does not compile
209 
210  std::string classname = SG::normalizedTypeinfoName( typeid(DATA) ); // normalized string representation (matching the names used in the root dictionary)
211 
212  DATA *d( 0 );
213  SG::fromStorable( pObj, d );
214  if( m_log->level() <= MSG::DEBUG ) {
215  *m_log << MSG::DEBUG << "My createRep for " << classID() << " "
216  << classname << endmsg;
217  }
218 
219  std::unique_ptr<DATA> holder;
220  void *serptr = TrigSerialization::prepareForWrite (d, holder);
221  //
222  std::vector< uint32_t > ser;
223 
224  StatusCode sc = m_convHelper->createRep( classname, serptr, ser, typeIsxAOD);
225  if( m_log->level() <= MSG::DEBUG ) {
226  *m_log << MSG::DEBUG << "convHelper " << ser.size() << endmsg;
227  }
228 
229  TrigStreamAddress *addr = new TrigStreamAddress( classID(), classname, "" );
230  addr->add( ser );
231 
232  pAddr = addr;
233 
234  return sc;
235  }
236 
238 
239  if( m_log ) {
240  m_log->setLevel( msgSvc()->outputLevel( "TrigSerializeConverter" ) );
241  } else {
242  return StatusCode::FAILURE;
243  }
244 
245  StatusCode sc = m_convHelper.retrieve();
246  if( ! sc.isSuccess() ) {
247  if( m_log->level() <= MSG::DEBUG ) {
248  *m_log << MSG::DEBUG << m_convHelper << "not retrieved" << endmsg;
249  }
250  } else {
251  if( m_log->level() <= MSG::DEBUG ) {
252  *m_log << MSG::DEBUG << m_convHelper << "m_serializer retrieved"
253  << endmsg;
254  }
255  if( ! m_convHelper->initialize().isSuccess() ) {
256  if( m_log->level() <= MSG::DEBUG ) {
257  *m_log << MSG::DEBUG << m_convHelper << " not initialized"
258  << endmsg;
259  }
260  }
261  }
262 
263  StatusCode scsg = m_sgHandle.retrieve();
264  if (scsg.isFailure())
265  *m_log << MSG::ERROR << "cannot access SG" << endmsg;
266  else {
267  m_sgsvc = m_sgHandle.operator->();
268  }
269  return sc;
270  }
271 
272  static const CLID& classID() { return ClassID_traits<DATA>::ID(); }
273 
274  virtual long int repSvcType() const;
275  static long int storageType();
276 
277  TrigSerializeConverter( ISvcLocator* svcloc )
278  : Converter( storageType(), classID(), svcloc ),
279  m_convHelper( "TrigSerializeConvHelper/TrigSerializeConvHelper" ),
280  m_sgHandle( "StoreGateSvc", "TrigSerializeConverter" ),
281  m_log( 0 ), m_sgsvc( 0 ) {
282 
283  m_log = new MsgStream( msgSvc(), "TrigSerializeConverter" );
284  }
285 
287  delete m_log;
288  }
289 
290 private:
291  ToolHandle< ITrigSerializeConvHelper > m_convHelper;
293  MsgStream *m_log;
295 };
296 
297 
298 template <typename DATA>
301 }
302 template <typename DATA>
304  return storageType();
305 }
306 
307 
308 #endif // TRIGSERIALIZECONVERTER_H
StoreGateSvc::record
StatusCode record(T *p2BRegistered, const TKEY &key)
Record an object with a key.
StoreGateSvc::contains
bool contains(const TKEY &key) const
Look up a keyed object in TDS (compare also tryRetrieve) returns false if object not available in TDS...
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
isxAOD::value
static const bool value
Definition: TrigSerializeConverter.h:57
SG::fromStorable
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
Definition: StorableConversions.h:180
StorableConversions.h
convert to and from a SG storable
SG::normalizedTypeinfoName
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Definition: normalizedTypeinfoName.cxx:120
TrigSerializeConverter::m_log
MsgStream * m_log
Definition: TrigSerializeConverter.h:293
hist_file_dump.d
d
Definition: hist_file_dump.py:137
TrigSerializeConverter::createObj
StatusCode createObj(IOpaqueAddress *iAddr, DataObject *&pO)
Definition: TrigSerializeConverter.h:145
DMTest::C
C_v1 C
Definition: C.h:26
TrigSerializeConverter::storageType
static long int storageType()
Definition: TrigSerializeConverter.h:299
TrigSerializeCnvSvc.h
SG::asStorable
DataObject * asStorable(T *pObject)
Definition: StorableConversions.h:158
athena.value
value
Definition: athena.py:124
isxAOD
Definition: TrigSerializeConverter.h:48
TrigSerializeConverter::typeIsxAOD
static const bool typeIsxAOD
Definition: TrigSerializeConverter.h:142
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
TrigSerializeConverter
Definition: TrigSerializeConverter.h:139
TrigSerializeConverter::~TrigSerializeConverter
~TrigSerializeConverter()
Definition: TrigSerializeConverter.h:286
TrigStreamAddress::sgkey
const std::string & sgkey() const
Definition: TrigStreamAddress.h:37
TrigSerializeConverter::m_sgHandle
ServiceHandle< StoreGateSvc > m_sgHandle
Definition: TrigSerializeConverter.h:292
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
isxAOD::isxAODVector
constexpr static bool isxAODVector(...)
Definition: TrigSerializeConverter.h:52
ClassID_traits::ID
static const CLID & ID()
the CLID of T
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:50
isxAOD::isAuxVector
constexpr static std::enable_if< std::is_base_of< SG::IAuxStore, C >::value, bool >::type isAuxVector(C *)
Definition: TrigSerializeConverter.h:54
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:125
ClassID_traits::typeName
static const std::string & typeName()
the demangled type name of T
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:56
isxAOD::isAuxVector
constexpr static bool isAuxVector(...)
Definition: TrigSerializeConverter.h:56
TrigStreamAddress.h
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
TrigStreamAddress::add
void add(const std::vector< uint32_t > &a)
Definition: TrigStreamAddress.cxx:27
ClassID_traits.h
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
TrigSerializeConverter::m_convHelper
ToolHandle< ITrigSerializeConvHelper > m_convHelper
Definition: TrigSerializeConverter.h:291
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TrigSerializeConverter::classID
static const CLID & classID()
Definition: TrigSerializeConverter.h:272
ViewVector
Identify view containers to be made persistent.
Definition: ViewVector.h:67
TrigSerializeCnvSvc::storageType
static long int storageType()
Definition: TrigSerializeCnvSvc.h:17
CnvFactory
Abstract factory to create the converter.
Definition: ToyConverter.h:16
TrigSerialization::finishRead
DATA * finishRead(DATA *d)
Called after an object has been read from BS.
Definition: TrigSerializeConverter.h:105
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
TrigSerializeConverter::repSvcType
virtual long int repSvcType() const
Definition: TrigSerializeConverter.h:303
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Converter
Definition: Converter.h:27
ITrigSerConvHelper.h
TrigSerializeConverter::m_sgsvc
StoreGateSvc * m_sgsvc
Definition: TrigSerializeConverter.h:294
python.TrigPSCPythonDbSetup.outputLevel
outputLevel
Definition: TrigPSCPythonDbSetup.py:30
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TrigSerialization
Definition: TrigSerializeConverter.h:61
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
DEBUG
#define DEBUG
Definition: page_access.h:11
TrigStreamAddress
IOpaqueAddress for TrigSerializenCnvSvc.
Definition: TrigStreamAddress.h:23
TrigSerialization::NO_SANITIZE_UNDEFINED
ViewVector< DV > *finishRead NO_SANITIZE_UNDEFINED(ViewVector< DV > *d)
Called after an object has been read from BS.
Definition: TrigSerializeConverter.h:119
no_sanitize_undefined.h
Helper to disable undefined behavior sanitizer for a function.
TrigSerializeConverter::createRep
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr)
Definition: TrigSerializeConverter.h:204
TrigSerialization::prepareForWrite
DATA * prepareForWrite(DATA *d, std::unique_ptr< DATA > &)
Called before serializing an object to BS.
Definition: TrigSerializeConverter.h:72
StoreGateSvc.h
ViewVector.h
Identify view containers to be made persistent.
TrigSerializeConverter::TrigSerializeConverter
TrigSerializeConverter(ISvcLocator *svcloc)
Definition: TrigSerializeConverter.h:277
TrigSerializeConverter::initialize
StatusCode initialize()
Definition: TrigSerializeConverter.h:237
ServiceHandle< StoreGateSvc >
isxAOD::isxAODVector
constexpr static std::enable_if< std::is_base_of< SG::AuxElement, typename std::pointer_traits< typename C::value_type >::element_type >::value, bool >::type isxAODVector(C *)
Definition: TrigSerializeConverter.h:50