| The Gaudi Framework v29r0 (ff2e7097)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

TESSerializer.cpp
Go to the documentation of this file.
1 #include "GaudiMP/TESSerializer.h"
2
3 // Framework include files
4 #include "GaudiKernel/DataObject.h"
5 #include "GaudiKernel/DataStoreItem.h"
6 #include "GaudiKernel/GaudiException.h"
7 #include "GaudiKernel/IDataManagerSvc.h"
8 #include "GaudiKernel/IDataProviderSvc.h"
9 #include "GaudiKernel/IRegistry.h"
10 #include "GaudiKernel/LinkManager.h"
11 #include "GaudiKernel/System.h"
12
13 #include "GaudiKernel/ClassID.h"
14 #include "GaudiKernel/GenericAddress.h"
15 #include "GaudiKernel/IOpaqueAddress.h"
16 #include "GaudiKernel/KeyedContainer.h"
17
18 #include "GaudiKernel/MsgStream.h"
19
20 // ROOT include files
21 #include "TBufferFile.h"
22 #include "TClass.h"
23 #include "TInterpreter.h"
24 #include "TROOT.h"
25
26 #include <map>
27
28 // a constant to guard against seg-faults in loadBuffer
29 #define SERIALIZER_END "EOF"
30
31 namespace
32 {
33 struct DataObjectPush {
34 DataObjectPush( DataObject*& p ) { Gaudi::pushCurrentDataObject( &p ); }
35 ~DataObjectPush() { Gaudi::popCurrentDataObject(); }
36 };
37 }
38
39 using namespace std;
40
41 bool GaudiMP::TESSerializer::analyse( IRegistry* dir, int level )
42 {
43 if ( level < m_currentItem->depth() ) {
44 if ( dir->object() != 0 ) {
45 m_objects.push_back( dir->object() );
46 return true;
47 }
48 }
49 return false;
50 }
51
53 GaudiMP::TESSerializer::TESSerializer( IDataProviderSvc* svc, IAddressCreator* ac )
54 : m_TES( svc )
55 , m_TESMgr( dynamic_cast<IDataManagerSvc*>( svc ) )
56 , m_currentItem( 0 )
57 , m_verifyItems( false )
58 , m_strict( false )
59 , m_addressCreator( ac )
60 {
61 }
62
64 void GaudiMP::TESSerializer::dumpBuffer( TBufferFile& buffer )
65 {
66 //
67 // Write all valid objects to the TBufferFile provided in the argument
68 // As objects are collected, the member variable m_classMap is filled
69 // with ROOT Class data, and is kept by the Serializer for future
70 // reference
71 //
72 // @paramTBufferFile& buffer : TBufferFile passed by reference
73 // Cannot be declared inside the method, as repeated calls
74 // can cause confusion and buffer wiping.
75 //
76 StatusCode status;
77 DataObject* obj;
78
79 // Clear current selection
80 m_objects.erase( m_objects.begin(), m_objects.end() );
81
82 // Traverse the tree and collect the requested objects
83 for ( Items::iterator i = m_itemList.begin(); i != m_itemList.end(); i++ ) {
84 m_currentItem = ( *i );
85 // cout << "Retrieving Mandatory Object : " << m_currentItem->path() << endl;
86 status = m_TES->retrieveObject( m_currentItem->path(), obj );
87 if ( status.isSuccess() ) {
88 m_TESMgr->traverseSubTree( obj, this );
89 } else {
90 string text( "WARNING: Cannot retrieve TES object(s) for serialisation: " );
91 text += m_currentItem->path();
92 if ( m_strict ) {
93 throw GaudiException( text + m_currentItem->path(), "", status );
94 } else {
95 cout << text << endl;
96 // return StatusCode::FAILURE;
97 }
98 }
99 }
100 // Traverse the tree and collect the requested objects (tolerate missing items here)
101 for ( Items::iterator i = m_optItemList.begin(); i != m_optItemList.end(); i++ ) {
102 m_currentItem = ( *i );
103 // cout << "Retrieving Optional Object : " << m_currentItem->path() << endl;
104 status = m_TES->retrieveObject( m_currentItem->path(), obj );
105 if ( status.isSuccess() ) {
106 m_TESMgr->traverseSubTree( obj, this );
107 }
108 }
109
110 // cout << "TESSerializer : Beginning loop to write to TBufferFile for nObjects : " << m_objects.size() << endl;
111 buffer.WriteInt( m_objects.size() );
112
113 for ( Objects::iterator i = m_objects.begin(); i != m_objects.end(); ++i ) {
114 DataObject* pObj = ( *i ); /* define pointer !pObj! to a data object */
115 DataObjectPush p( pObj ); /* add the data object to the list... */
116
117 // We build a map so gROOT has to access the whole class database as little as possible
118 TClass* cl; /* announce a TClass */
119 const type_info& objClass = typeid( *pObj ); /* get the type of the data object */
120 // cout << "TES Object : " << pObj->registry()->identifier() << endl;
121 string objClassName = System::typeinfoName( objClass ); /* and then get the descriptive string from System */
122
123 /* First go : populate the class map
124 Subsequent : refer to class map */
125 if ( m_classMap[objClassName] ) {
126 cl = m_classMap[objClassName];
127 } else {
128 /* Map new object : pull the class name from the objects c_str() method */
129 const char* clName = objClassName.c_str();
130 /* Find the relevant Tclass (cl) in gROOT, and fill the map entry */
131 cl = gROOT->GetClass( clName );
132 m_classMap[objClassName] = cl;
133 }
134
135 /* Now, check if clname was valid... */
136 if ( cl == 0 ) {
137 if ( m_strict ) {
138 throw GaudiException( "gROOT->GetClass cannot find clName", objClassName, StatusCode::FAILURE );
139 } else {
140 cout << "WARNING: gROOT->GetClass fails for clname : " << objClassName.c_str() << endl;
141 cout << "WARNING: Disregarding " << objClassName.c_str() << "erasing from object list" << endl;
142 m_objects.erase( i );
143 continue;
144 }
145 }
146
147 // write object to buffer in order location-name-object
148 std::string loc = pObj->registry()->identifier();
149 buffer.WriteString( loc.c_str() );
150 buffer.WriteString( cl->GetName() );
151 cl->Streamer( pObj, buffer );
152
153 /* take care of links */
154 LinkManager* linkMgr = pObj->linkMgr();
155 int numLinks = linkMgr->size();
156 buffer.WriteInt( numLinks );
157 // now write each link
158 for ( int it = 0; it != numLinks; it++ ) {
159 const string& link = linkMgr->link( it )->path();
160 buffer.WriteString( link.c_str() );
161 }
162
163 // now do the thing with the opaqueAddress
164 // to go from string->object when recovering, will need svc_type, and clid, aswell as the string version
165 IOpaqueAddress* iop = pObj->registry()->address();
166 if ( iop ) {
167 buffer.WriteInt( 1 );
168 const string* par = iop->par();
169 long svcType = iop->svcType();
170 long clid = iop->clID();
171 buffer.WriteLong( svcType );
172 buffer.WriteLong( clid );
173 buffer.WriteString( par->c_str() );
174 } else {
175 buffer.WriteInt( 0 );
176 }
177 // object complete, continue in for-loop
178 }
179
180 // Final Actions
181 // Write the End Flag, to avoid potential SegFaults on loadBuffer
182 buffer.WriteString( SERIALIZER_END );
183 // return StatusCode::SUCCESS;
184 }
185
187 void GaudiMP::TESSerializer::loadBuffer( TBufferFile& buffer )
188 {
189
190 // reverse mechanism of dumps
191 // buffer is: length of DataObjects vector
192 // location string
193 // type name string
194 // the object itself
195 // count of links
196 // list of links (conditional on count)
197 // flag indicating Opaque Address presence
198 // Opaque Address svcType (conditional on flag)
199 // Opaque Address clID (conditional on flag)
200 // Opaque Address par (conditional on flag)
201
202 int nObjects;
203 // 3 StatusCodes... for :
204 // general use : registering objects : creating OpaqueAddresses
205 StatusCode sc, registerStat, createAddressStat;
206
207 // Prepare for Reading
208 buffer.SetReadMode();
209 buffer.SetBufferOffset();
210
211 buffer.ReadInt( nObjects );
212 for ( int i = 0; i < nObjects; ++i ) {
213 char text[4096];
214 buffer.ReadString( text, sizeof( text ) );
215 string location( text );
216 if ( !location.compare( "EOF" ) ) {
217 /* There was an error in serialization, but the EOF
218 flag marks the endpoint in any case */
219 break;
220 }
221 buffer.ReadString( text, sizeof( text ) );
222 TClass* cl = gROOT->GetClass( text );
223 if ( cl == 0 ) {
224 if ( m_strict ) {
225 throw GaudiException( "gROOT->GetClass cannot find clName", text, StatusCode::FAILURE );
226 } else {
227 cout << "TESSerializer WARNING : gROOT->GetClass fails for clname : " << location.c_str() << endl;
228 continue;
229 }
230 }
231
233 DataObject* obj = (DataObject*)cl->New();
234 DataObjectPush push( obj ); // This is magic!
235 cl->Streamer( obj, buffer );
236
237 // now restore links
238 if ( obj ) {
239 int nlink = 0;
240 LinkManager* lnkMgr = obj->linkMgr();
241 buffer.ReadInt( nlink );
242
243 for ( int j = 0; j < nlink; ++j ) {
244 buffer.ReadString( text, sizeof( text ) );
245 lnkMgr->addLink( text, 0 );
246 }
247 }
248
249 // Re-register...
250 registerStat = m_TES->registerObject( location, obj );
251 if ( registerStat.isFailure() ) {
252 DataObject* dummy = NULL;
253 if ( location == "/Event" ) {
254 sc = m_TESMgr->setRoot( location, obj );
255 if ( sc.isFailure() ) throw GaudiException( "Cannot set root at location " + location, "", sc );
256 } else {
257 m_TES->findObject( location, dummy );
258 if ( !dummy )
259 m_TES->registerObject( location, obj );
260 else {
261 // skipping to the next object
262 // (flush the remaining metadata in the buffer)
263 int flag( 0 );
264 buffer.ReadInt( flag );
265 if ( flag ) {
266 long svcType;
267 buffer.ReadLong( svcType );
268 long clid;
269 buffer.ReadLong( clid );
270 buffer.ReadString( text, sizeof( text ) );
271 }
272 continue;
273 }
274 }
275 }
276 // next is the opaque address information
277 // create Generic Address using the info from the TBufferFile,
278 // then create an IOpaqueAddress object using the Persistency Svc
279 // IOpaque Address pointer (blank... pass the ref to the createAddress Fn)
280
281 int flag( 0 );
282 buffer.ReadInt( flag );
283 // flag will be 0 or 1 to indicate OpaqueAddress Info
284 if ( flag == 1 ) {
285 // will need an IOpaqueAddress and its ref
286 IOpaqueAddress* iop;
287 IOpaqueAddress*& iopref = iop;
288 // Read svcType, clID and par from buffer
289 long svcType;
290 buffer.ReadLong( svcType );
291
292 long clid;
293 buffer.ReadLong( clid );
294 const CLID classid( clid );
295
296 char* cp;
297 cp = buffer.ReadString( text, sizeof( text ) );
298 const string opaque( cp );
299 // create Generic address
300 // already have svcType, clID, par1.. just make dummy variables for par2, and ipar1 and 2
301 const string& p2 = "";
302 unsigned long ip1( 0 );
303 unsigned long ip2( 0 );
304 GenericAddress gadd( svcType, classid, opaque, p2, ip1, ip2 );
305
306 // now create the address
307 createAddressStat =
308 m_addressCreator->createAddress( gadd.svcType(), gadd.clID(), gadd.par(), gadd.ipar(), iopref );
309 if ( createAddressStat.isFailure() ) {
310 throw GaudiException( "Failure in creating OpaqueAddress for reconstructed registry", "", createAddressStat );
311 }
312 // And finally, set this address
313 obj->registry()->setAddress( iop );
314 }
315 // all done
316 }
317 }
318
319 // Protected
321 void GaudiMP::TESSerializer::addItem( Items& itms, const std::string& descriptor )
322 {
323 // supports # notation
324 int level = 0;
325
326 std::string slevel;
327 std::string obj_path;
328
329 // Process the incoming string
330 size_t sep = descriptor.rfind( "#" );
331 if ( sep > descriptor.length() ) {
332 // invalid sep case (# not found in string)
333 obj_path = descriptor;
334 slevel = "1";
335 } else {
336 // valid sep case
337 obj_path = descriptor.substr( 0, sep );
338 slevel = descriptor.substr( sep + 1 );
339 }
340
341 // Convert the level string to an integer
342 if ( slevel == "*" ) {
343 level = 9999999;
344 } else {
345 level = std::stoi( slevel );
346 }
347
348 // Are we verifying?
349 if ( m_verifyItems ) {
350 size_t idx = obj_path.find( "/", 1 );
351 while ( idx != std::string::npos ) {
352 std::string sub_item = obj_path.substr( 0, idx );
353 if ( 0 == findItem( sub_item ) ) {
354 cout << "... calling addItem with arg : " << sub_item << endl;
355 addItem( itms, sub_item );
356 }
357 idx = obj_path.find( "/", idx + 1 );
358 }
359 }
360 DataStoreItem* item = new DataStoreItem( obj_path, level );
361 // cout << "Adding TESSerializer item " << item->path()
362 // << " with " << item->depth()
363 // << " level(s)." << endl;
364 itms.push_back( item );
365 }
366
368 void GaudiMP::TESSerializer::addItem( const std::string& path )
369 {
370 // #notation supported
371 addItem( m_itemList, path );
372 }
373
375 void GaudiMP::TESSerializer::addOptItem( const std::string& path )
376 {
377 // #notation supported
378 addItem( m_optItemList, path );
379 }
380
382 void GaudiMP::TESSerializer::checkItems()
383 {
384 cout << "TESSerializer m_itemList : " << m_itemList.size() << " Items" << endl;
385 for ( Items::const_iterator i = m_itemList.begin(); i != m_itemList.end(); ++i ) {
386 cout << "\tItem : " << ( *i )->path() << endl;
387 }
388 cout << "TESSerializer m_optItemList : " << m_optItemList.size() << " Items" << endl;
389 for ( Items::const_iterator i = m_optItemList.begin(); i != m_optItemList.end(); ++i ) {
390 cout << "\tItem : " << ( *i )->path() << endl;
391 }
392 }
393
395 DataStoreItem* GaudiMP::TESSerializer::findItem( const std::string& path )
396 {
397 for ( Items::const_iterator i = m_itemList.begin(); i != m_itemList.end(); ++i ) {
398 if ( ( *i )->path() == path ) return ( *i );
399 }
400 for ( Items::const_iterator j = m_optItemList.begin(); j != m_optItemList.end(); ++j ) {
401 if ( ( *j )->path() == path ) return ( *j );
402 }
403 return 0;
404 }
System.h
LinkManager::Link::path
const std::string & path() const
Access to path of object.
Definition: LinkManager.h:66
GaudiMP::TESSerializer::checkItems
void checkItems()
print out the contents of m_itemList and m_optItemList (std::cout)
Definition: TESSerializer.cpp:382
ClassID.h
GaudiException
Define general base for Gaudi exception.
Definition: GaudiException.h:22
IOpaqueAddress::clID
virtual const CLID & clID() const =0
Retrieve class information from link.
LinkManager.h
GaudiPython.HistoUtils.path
path
Definition: HistoUtils.py:895
StatusCode::FAILURE
Definition: StatusCode.h:31
MsgStream.h
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:329
GaudiMP::TESSerializer::loadBuffer
void loadBuffer(TBufferFile &)
Rebuild TES from items in a TBufferFile.
Definition: TESSerializer.cpp:187
IAddressCreator::createAddress
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ipar, IOpaqueAddress *&refpAddress)=0
Create a Generic address using explicit arguments to identify a single object.
Gaudi::popCurrentDataObject
GAUDI_API void popCurrentDataObject()
Definition: RootIOHandler.cpp:41
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
GaudiMP::TESSerializer::TESSerializer
TESSerializer(IDataProviderSvc *svc, IAddressCreator *ac)
Constructor.
Definition: TESSerializer.cpp:53
std::string::rfind
T rfind(T...args)
GaudiPython.HistoUtils.location
location
Definition: HistoUtils.py:899
std::endl
T endl(T...args)
IAddressCreator
IAddressCreator interface definition.
Definition: IAddressCreator.h:28
GaudiMP::TESSerializer::m_optItemList
Items m_optItemList
Vector of optional items to be saved to this stream (DataStoreItem ptrs)
Definition: TESSerializer.h:81
std
STL namespace.
GaudiMP::TESSerializer::m_verifyItems
bool m_verifyItems
Boolean Flag as used by GaudiSvc/PersistencySvc/OutputStreamer.
Definition: TESSerializer.h:90
std::vector::end
T end(T...args)
LinkManager::addLink
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
Definition: LinkManager.cpp:59
GenericAddress
Generic Transient Address.
Definition: GenericAddress.h:20
IDataProviderSvc
Data provider interface definition.
Definition: IDataProviderSvc.h:45
IOpaqueAddress::par
virtual const std::string * par() const =0
Retrieve String parameters.
DataStoreItem
Description of the DataStoreItem class.
Definition: DataStoreItem.h:17
StatusCode::isFailure
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
GaudiMP::TESSerializer::m_addressCreator
IAddressCreator * m_addressCreator
IAddress Creator for Opaque Addresses.
Definition: TESSerializer.h:94
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
GaudiMP::TESSerializer::m_itemList
Items m_itemList
Vector of items to be saved to this stream (DataStoreItem ptrs)
Definition: TESSerializer.h:77
GaudiMP::TESSerializer::m_strict
bool m_strict
Boolean Flag used to determine error tolerance.
Definition: TESSerializer.h:92
DataObject::linkMgr
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:74
std::type_info
DataStoreItem::path
const std::string & path() const
Accessor: Retrieve load path.
Definition: DataStoreItem.h:58
std::string
STL class.
std::vector::push_back
T push_back(T...args)
DataStoreItem.h
IDataManagerSvc.h
compareOutputFiles.par
string par
Definition: compareOutputFiles.py:435
IDataProviderSvc.h
HiveAlgSequencer.p2
p2
Definition: HiveAlgSequencer.py:23
GaudiMP::TESSerializer::m_TESMgr
IDataManagerSvc * m_TESMgr
TES pointer.
Definition: TESSerializer.h:73
IDataProviderSvc::findObject
virtual StatusCode findObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject)=0
Find object identified by its directory entry.
GaudiMP::TESSerializer::analyse
bool analyse(IRegistry *dir, int level) override
Analysis callback.
Definition: TESSerializer.cpp:41
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
GaudiMP::TESSerializer::dumpBuffer
void dumpBuffer(TBufferFile &)
Dump TES contents listed in m_itemList/m_optItemList to a TBufferFile.
Definition: TESSerializer.cpp:64
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
GenericAddress::ipar
const unsigned long * ipar() const override
Retrieve integer parameters.
Definition: GenericAddress.h:86
GenericAddress::par
const std::string * par() const override
Retrieve string parameters.
Definition: GenericAddress.h:84
GaudiException.h
std::vector::erase
T erase(T...args)
LinkManager::link
Link * link(long id)
Retrieve symbolic link identified by ID.
Definition: LinkManager.cpp:31
IRegistry.h
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
IOpaqueAddress::svcType
virtual long svcType() const =0
Retrieve service type.
GaudiMP::TESSerializer::addItem
void addItem(const std::string &path)
add an item to the TESSerializer&#39;s list (#notation)
Definition: TESSerializer.cpp:368
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
Gaudi::pushCurrentDataObject
GAUDI_API void pushCurrentDataObject(DataObject **pobjAddr)
Definition: RootIOHandler.cpp:36
GenericAddress::svcType
long svcType() const override
Access : retrieve the storage type of the class id.
Definition: GenericAddress.h:80
compareOutputFiles.cp
cp
Definition: compareOutputFiles.py:466
IDataManagerSvc::setRoot
virtual StatusCode setRoot(std::string root_name, DataObject *pObject)=0
Initialize data store for new event by giving new event path.
IRegistry::object
virtual DataObject * object() const =0
Retrieve object behind the link.
IOpaqueAddress.h
std::string::find
T find(T...args)
std::vector::size
T size(T...args)
std::vector< DataStoreItem * >
IDataManagerSvc
Definition: IDataManagerSvc.h:45
std::vector::begin
T begin(T...args)
TESSerializer.h
IRegistry::setAddress
virtual void setAddress(IOpaqueAddress *pAddress)=0
Set/Update Opaque storage address.
GaudiMP::TESSerializer::m_objects
Objects m_objects
Selected list of Objects to be serialized (DataObject ptrs)
Definition: TESSerializer.h:85
std::string::c_str
T c_str(T...args)
std::string::substr
T substr(T...args)
gaudirun.level
level
Definition: gaudirun.py:271
GaudiMP::TESSerializer::addOptItem
void addOptItem(const std::string &path)
add an item to the TESSerializer&#39;s optional list (#notation)
Definition: TESSerializer.cpp:375
GaudiMP::TESSerializer::findItem
DataStoreItem * findItem(const std::string &path)
Find single item identified by its path (exact match)
Definition: TESSerializer.cpp:395
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
IDataProviderSvc::registerObject
virtual StatusCode registerObject(const std::string &fullPath, DataObject *pObject)=0
Register object with the data store.
GaudiMP::TESSerializer::m_currentItem
DataStoreItem * m_currentItem
Current item while traversing the TES tree.
Definition: TESSerializer.h:83
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
GenericAddress::clID
const CLID & clID() const override
Access : Retrieve class ID of the link.
Definition: GenericAddress.h:76
IDataManagerSvc::traverseSubTree
virtual StatusCode traverseSubTree(const std::string &sub_path, IDataStoreAgent *pAgent)=0
Analyse by traversing all data objects below the sub tree identified by its full path name...
SERIALIZER_END
#define SERIALIZER_END
Definition: TESSerializer.cpp:29
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:29
std::cout
GenericAddress.h
std::stoi
T stoi(T...args)
LinkManager
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
Definition: LinkManager.h:21
KeyedContainer.h
GaudiMP::TESSerializer::m_TES
IDataProviderSvc * m_TES
TES pointer.
Definition: TESSerializer.h:71
std::string::compare
T compare(T...args)
DataObject.h
LinkManager::size
long size() const
Retrieve number of link present.
Definition: LinkManager.h:105
GaudiMP::TESSerializer::m_classMap
std::map< std::string, TClass * > m_classMap
Map of gROOT class information.
Definition: TESSerializer.h:88
IDataProviderSvc::retrieveObject
virtual StatusCode retrieveObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.