D0 GROUP LEVEL3
ONLINE LESSONS
Gustaaf Brooijmans
Fermilab, MS # 357
Tel: +1 (630) 840 4269 |
|
Episode XVI
Getting Debugging Information Written Out
by Gustaaf
Brooijmans
While you are developing your tool
offline, you have many handles to understand its behavior, for example
text output, and filling histograms and ntuples with the tool's results,
which you can retrieve through the accessors provided for other tools and/or
ScriptRunner.
However, in real running mode, most
of the time only the contents of the L3xxxPhysicsResults classes
will be written out. To be able to track potential problems, or better
verify good performance, we will have special runs where debugging information
is written to file with the event.
Obviously, debugging information
for tools will come in very different formats, leading us to introduce
a new class to present debugging information in a uniform way to ScriptRunner:
L3DebugInfo.
L3DebugInfo
is an abstract class, of which tooldevelopers should create a daughter
class which contains the debugging information needed, and the adequate
accessors to interpret that information.
How do I create my L3DebugInfo class?
Piece of cake: if you look at l3fMcTool, a
fair example class is
L3McPartDebugInfo.
It inherits from L3DebugInfo, and contains lists of particles and jets.
I'll discuss the filling of this class further down, but let's concentrate
on creating the class first. This is what you need to do:
-
create a class that inherits from L3DebugInfo;
-
make it persistent (see episode
on d0om): i.e. add the D0_OBJECT_SETUP
macro,
use only persistent elements, add the file to your D0OM_COMPONENTS
so the linkage file is produced, and include the reference header file
protected by #ifndef __CINT__ ;
-
implement a constructor from a pointer to a class of the same type
(ScriptRunner will need this);
-
implement the bool isComplete();method,
such that it returns true if all the information is present (since one
of the purposes of this class is to understand problems, this is a good
way to start: make sure you get everything you expect);
-
provide accessors to the data contained in the class, so you can look at
it offline;
-
implement the bool operator== (L3DebugInfo*
info); method, which will be used to compare two instances
of this class at trigger verification time. Note the unusual pointer
argument to this operator;
-
implement an ostream operator for
easy ascii output of the class' contents.
How and when do I fill this class?
Well, we clearly do not want to waste time filling this class when we're
not writing it out. So filling it should only happen on request,
i.e. when ScriptRunner calls the void Write(L3DebugInfo ** myinfo);
method. Here's how it works: we decide that we want to write
out debugging information for this event, so at the end of event processing,
ScriptRunner
calls
the void Write(L3DebugInfo ** myinfo); for all the tools.
When this gets called, the tool fills its L3DebugInfo class with the information
needed, and ScriptRunner stores it in the L3Chunk
(along with the
tool identification). When we then examine the event offline, we
can access this information.
So filling this class needs to be done in the void Write(L3DebugInfo
** myinfo); of your tool (which you therefore need to implement), see
for example L3TMcParticle in l3fMcTool.
My recommendation is that you have a pointer to one instance of this
class as one of the members of your tool. That way you don't need
to create a new one for every time Write gets called. I also
made my tool a friend of my L3DebugInfo class - that way
it's easy to fill it.
A fair example of all this can be found in package l3fMcTool,
v00-03-00 and up.
As usual: comments, questions? -> Feel free to contact me.