Product Mixing » History » Version 3

« Previous - Version 3/19 (diff) - Next » - Current version
Christopher Green, 10/26/2011 08:26 PM

Product Mixing


Product Mixing is our label for the ability to take a feed from a source of secondary events, and combine the products (usually collections) from multiple events into a single product or collection to be placed in the primary event. The motivation is of course obvious: background (eg cosmic) events or pile-up.

This feature is implemented by providing a module template, MixFilter as a skeleton to handle the low-level interaction with the primary event and secondary files, including the collection of multiple products from different secondary events and the registration of outgoing products. The user must provide a "detail" class implementation which has some mandatory and some optional members in order to register necessary products at the right time and mix the prepared groups of incoming products. The MixFilter will take care of reading the secondary data, either sequentially or randomly and cycling through multiple secondary input files as necessary.

In order to make the mixing task easier, we have provided several auxiliary utilities which will be described later.

In summary, the MixFilter module will do the following tasks:

  1. Construct a MixHelper object for use by the user's detail class, hereafter referred to as Detail (class) or detail (object).
  2. Construct detail, passing the helper and the module's parameter set. At this point, detail should register any mix operations (one per product to be mixed) using MixHelper::declareMixOp<>(), and any non-mixing products to go in to the event (e.g. bookkeeping objects) using MixHelper::produces<>().
  3. For each primary event:
    1. Call the optional Detail::startEvent() function if it exists so detail can position itself for the coming event.
    2. Call Detail::nSecondaries() to decide how many secondary events to read.
    3. Decide which secondary events are to be read.
    4. Call the optional Detail::processEventIDs() function in case the Detail class is interested in the sequence of event IDs (e.g. for bookkeeping purposes).
    5. Call the registered mixing operation for each product to be mixed, providing the secondary data to be mixed and putting the resultant mixed product into the primary event.
    6. Call the optional Detail::finalizeEvent() function to tidy up and possibly put any bookkeeping products (registered with MixHelper::produces<>()) into the primary event.

The MixFilter module will take care of opening new secondary files as necessary, and will additionally call an optional function Detail::eventsToSkip() as each file is opened (in sequential mode only) if it is desired to have a particular offset into each file to insure against coherent backgrounds in events.

Mix operations: what are they and what do they need to do?

A mix operation is a function provided by the user which returns a bool and expects three arguments:

  • vector<PROD const *> const & containing the secondary products to be mixed;
  • PROD &, the output product to be filled by the mix function; and
  • PtrRemapper const &, a helper for use remapping Ptr and friends (see below).

It may be a free function, a member function of Detail or some other user class, or a function object ("functor") whose operator() has the correct signature. It is supposed to use the information contained in the secondary products to fill the output product, using the PtrRemapper if necessary, and return a bool indicating whether the output product should be placed in the event.

All mix operations must be declared at construction time by detail, using the MixHelper provided as a constructor argument.

Mandatory interface for Detail.


Detail(fhicl::ParameterSet const & ps, art::MixHelper & helper);


size_t nSecondaries();

Optional interface for Detail.


void startEvent(art::Event const & evt);


size_t eventsToSkip();


void processEventIDs(art::EventIDSequence const & seq);


void finalizeEvent(art::Event & evt);

Helper utilities.


CollectionUtilities.h: concatContainers() and flattenCollections().