Skip to content

Adding New Artus Processors

Daniel Savoiu edited this page Aug 19, 2017 · 12 revisions

Quick Start

  1. Create the processor source files (have a look at existing producers/filters and create your own by copy&paste and edit)
  2. To enable Artus to create an instance of the new processor, add an entry in the factory (e.g. in KappaAnalysis/src/KappaFactory.cc)
  3. If your producer has to be configurable, add the respective config tags in the settings file, e.g. in KappaAnalysis/interface/KappaSettings.h
  4. Do not forget to add the producer (and its config tags) to your configuration (JSON file) in order for it to be executed

Processor Modules

Processors (Producers, Filters or Consumers) are C++ classes that are derived from the base classes in the Artus Core:

These classes are templated (TTypes). These type defines the actual event, product and settings classes the modules are supposed to work on. Such a type is a key characteristic of a specialised analysis. See Creating a Specialised Artus Analysis for more information.

The base classes are abstract. Some functions need to be implemented in the derived classes in order to be able to create instances of these types. It is always recommended to call the upper class functions at the beginning of the lower class function in case this implementation exists.

Common functions to be implemented

Unique processor name

These functions return a unique name of the processor as a std::string.

Initialisation

The initialisation of the processors can depend on settings defined in the Artus configuration. Therefore it is not possible to fully initialise the processors in the constructor functions but special init functions are provided. They only need to be overwritten in case something needs to be initialised depending on the settings.

Special processors tasks to be implemented

Producers

The task of producers is to add or modify quantities (members) of the product class. This task is implemented in the Produce function.

Only the product parameter is therefore passed as a non-const reference, whereas the event and the settings can only be read but not changed. (The event is only meant to be changed by the EventProvider and the settings are read in once a the beginning of the program.) The Produce functions cannot modify members of the producer class itself. In rare cases where this is needed, these members have to be defined as mutable.

Filters

The task of filters is to disgard events from being processed and thus making selections. This task is implemented in the DoesEventPass function.

As this function is only meant to make selections, neither the filter instance itself nor members of the event, product and settings objects can be changed. The result of the filter decision is tracked by Artus and can later be used by the consumers.

Consumers

The task of consumers is to write out calculations to the (ROOT) output file. This task is implemented in ProcessEvent functions.

The first function is called only for events that survive all filters whereas the second function is called for all events. In the latter version, the result of all filters is passed as an argument to be evaluated in this function. In usual cases it only makes sense to implement one of these two functions in a single consumer.

Consumers provide a function to save the output into the output file after all events are processed. These actions are implemented in the Finish function.

Registration and creation of processors

Every analysis needs a derived class of the FactoryBase which maintains the instances of the the processors and does the matching between the processor names as they are specified in the Artus configuration and the actual instances.

These functions are called once per processor configured in the Artus configuration, where the passed ID names differ. This means, that it is not possible to create two different processor instances in the same pipeline based on the same ID name. The convention is currently to choose the ID names the same as the class names.

In order to execute the processors they finally need to be configured in the JSON config file.

{
	"Processors" : [
		"filter:<filter ID>",
		"producer:<producer ID>"
	],
	"Consumers" : [
		"<consumer ID>"
	]
}

Keep in mind, that the order of filters and producers is flexible but consumers are always executed after all filters and producers of a pipeline have been finished. Consumers cannot be added to the global pipeline.