FAQ:How do I access SimHeaders when using Sim15 output? Sometimes they are missing!

From Daya Bay

Jump to: navigation, search

Sim15 mixes different sources of events in time and at every stage of the simulation. As a consequence, for any given execution cycle there may be 0, 1 or many output HeaderObjects from a given stage. This does not match well with the TES which expects only 0 or 1 instance at every given location each execution cycle. In short, one should not use the TES to access output from Sim15 (except for the final resulting HeaderObject, eg. the ReadoutHeader or any down stream HeaderObject).

Use findHeaders()

Every HeaderObject has a method called findHeaders() that returns a vector of headers matching either a class ID or the location at which it was placed in the event store. For class ID use one of


Other ways

Using findHeaders() is best, but there are some other ways to find input headers.

Check the TES

Note, of caution. As said above, this section shows methods methods that are not good for looking up intermediate HeaderObjects produced by Sim15. They are only reliable for accessing the final output of the Sim15 stages or any downstream stage. These methods suffer because zero, one or multiple HeaderObjects from intermediate stages can be created in one execution cycle. When a stage produces a HeaderObject, only the last one produced will be found in the TES.

With that noted, the TES can be checked for the existence of an object at a given location in at least three ways.


Surround the get<>() with a C++ try/catch block. If the HeaderObject is missing an exception will be thrown.

Use GaudiAlgorithms exist<>()

Call the GaudiAlgorithm's method exist<>() for example like:

 bool tf = exist<SimHeader>(evtSvc(), "/Event/Sim/SimHeader");

If it exists you can use get<Type>("/Event/Thing/ThingHeader") to get the object w/out throwing an exception.

Use GaudiAlgorithm's method retrieveObject()

 DataObject *pObj;
 StatusCode sc = eventSvc()->retrieveObject(RawEventHeaderLocation::Default,pObj);
 if( sc.isSuccess() ) {
   RawEventHeader* reh = dynamic_cast<RawEventHeader*>(pObj);

The very basic "retrieveObject" is always safe to call even no data in that path. An exception will not be thrown but the returned StatusCode must be checked.

Check the inputHeaders

NB: this was needed before findHeaders() was added directly to HeaderObject.

Every HeaderObject has a list of other HeaderObjects that went in to creating them. This list is accessed through the HeaderObjects inputHeaders() method. Depending on the starting HeaderObject one may need to recourse through multiple inputHeader lists.

Here is an example from Trac ticket #466. This python function will recursively search through the list of inputHeaders and look for the headers you request.

def findHeader( header, classID ):
   "Recursively look for the type of header, using the header classID"
   if header.classID() == classID:
      return [ header ]
   headerList = []
   for inputHdr in header.inputHeaders():
      headerList += findHeader( inputHdr, classID )
   return headerList

Use these lines in your 'execute()' function to find the simulated events used to make a readout:

readoutHdr = evt["/Event/Readout/ReadoutHeader"]
simHdrs = findHeader( readoutHdr, gbl.DayaBay.SimHeader.classID() )
print "Number of simulated events used to make this readout:", len(simHdrs)

Update: The above code may give you duplicated entries. Upon r10095 you can directly use the member function findHeaders() of HeaderObject as such:

readoutHdr = evt["/Event/Readout/ReadoutHeader"]
simHdrs = readoutHdr.findHeaders( gbl.DayaBay.SimHeader.classID() )
print "Number of simulated events used to make this readout:", len(simHdrs)

Check the AES

If you don't have a starting HeaderObject you can look back through the Archive Event Service. It will hold past HeaderObjects at the same location as you expect to find them in the TES. They are held in a DybArchvieList which has the newest HeaderObject stored as element 0 of the list (FIFO).


Personal tools