HOWTO add private code to a DANA application

From GlueXWiki
Revision as of 09:19, 5 April 2010 by Davidl (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

hd_ana and other DApps, in and of themselves, will not call any user code. To introduce user code one needs to write a class which derives from JEventProcessor and then register that class with the DApplication.

The JEventProcessor-inheriting class, let's call it MyProcessor, contains methods which include:

  • init called at initialization time
  • fini called at end of processing
  • brun called at the beginning of each run
  • erun called at the end of each run
  • evnt called for every event

Registration can be done with the AddProcessor method of the DApplication or by passing a pointer to the processor object to the Run method of DApplication. See examples below.

Adding a single processor

int main(int narg, char *argv[])
{
   // Instantiate an event loop object
   DApplication app(narg, argv);

   // Create object with private code 
   MyProcessor myproc;

   // Register private code with application and run though all events
   app.Run(&myproc);

   return 0;
}

Adding multiple processors

Any number of JEventProcessors can be added to the application. This is useful when one has multiple, independent analyses that may have overlapping requirements (e.g. both require track and photon reconstruction). This ensures that the CPU expensive parts are done once and shared by all processes.

int main(int narg, char *argv[])
{
   // Instantiate an event loop object
   DApplication app(narg, argv);

   // Create objects with private code 
   MyProcessor1 myproc1;
   MyProcessor2 myproc2;
   MyProcessor3 myproc3;

   // Register private code with the application
   app.AddProcessor(&myproc1);
   app.AddProcessor(&myproc2);
   app.AddProcessor(&myproc3);

   // Run though all events
   app.Run();  // Processors already added so no arguments are needed for ''Run''

   return 0;
}

Each processor will be called for every event. Processors will be called in the order they are registered.

Advanced: Automatic object deletion

In the above examples, the processor objects are created on the stack and so are implicitly deleted when main returns. One tempting modification for the above code would be to simultaneously instantiate the processor objects on the heap and register them like this:

  // Instantiating on the heap
  app.AddProcessor(new MyProcessor1(), true);
  app.AddProcessor(new MyProcessor2(), true);
  app.AddProcessor(new MyProcessor3(), true);

The second argument of "true" tells the framework to take ownership of the object and explicitly delete it before Run returns at the end of event processing. If "true" were not passed in the above example, then it becomes the responsibility of the DANA application author to delete the processor objects. (Note: one can get an STL vector of the JEventProcessor pointers using the DApplication::GetProcessors() method, but for most cases, authors will just want to pass the "true" argument.) The second boolean argument of AddProcessor is needed since the author can pass pointers to stack allocated objects as well as heap objects. Attempting to call delete on stack objects will cause program errors and no common mechanism exists across platforms for determining the nature of a pointer from the pointer itself.


See the section on Event Processors in the JANA manual for more details.