Difference between revisions of "HOWTO add private code to a DANA application"

From GlueXWiki
Jump to: navigation, search
(first draft)
 
 
Line 8: Line 8:
 
* '''evnt''' called for every event
 
* '''evnt''' called for every event
  
Registration can be done with the AddProcessor method of the DApplication. For example:
+
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==
  
 
<pre>
 
<pre>
Line 15: Line 17:
 
   // Instantiate an event loop object
 
   // Instantiate an event loop object
 
   DApplication app(narg, argv);
 
   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;
 +
}
 +
</pre>
 +
 +
==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.
 +
 +
<pre>
 +
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
 
   // Register private code with the application
   app.AddProcessor(new MyProcessor());
+
   app.AddProcessor(&myproc1);
 +
  app.AddProcessor(&myproc2);
 +
  app.AddProcessor(&myproc3);
  
 
   // Run though all events
 
   // Run though all events
   app.Run(NULL, 1);
+
   app.Run(); // Processors already added so no arguments are needed for ''Run''
  
 
   return 0;
 
   return 0;
Line 26: Line 54:
 
</pre>
 
</pre>
  
Note that you can have as many processors as you would like. Each one must be instantiated and its pointer used to register it with the application.
+
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 [http://www.jlab.org/JANA/JANA_manual.pdf JANA manual] for more details.
 
See the section on Event Processors in the [http://www.jlab.org/JANA/JANA_manual.pdf JANA manual] for more details.

Latest revision as of 09:19, 5 April 2010

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.