C++ Interface Description for Global Modules

Complete: 4

Contacts

Base Class

Each of the three fundamental types of modules, EDProducer, EDFilter and EDAnalyzer, all have their own base class which reside in the edm::global namespace. The base classes are names
  • edm::global::EDProducer<>
  • edm::global::EDFilter<>
  • edm::global::EDAnalyzer<>
All the base classes are templatized and take optional template arguments. The optional template arguments are used to extend the interface and therefore abilities of the base classes. Each of the allowed template arguments are described later in this page.

The interface available to all modules inheriting from the base classes (with or without giving additional template arguments) is described below. The methods which take a edm::StreamID are called from a particular Stream, where the Stream is identified using the opaque C++ class edm::StreamID.

void beginJob()
Called once each job just before processing the data.
void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const
This is called each Event. This is only available to edm::global::EDProducer<>
bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const
This is called each Event. The return value decides whether the modules following the filter on its Paths will be processed this Event. This is only available to edm::global::EDFilter<>
void analyze(edm::StreamID, edm::Event& const, edm::EventSetup const&) const
This is called each Event. This is only available to edm::global::EDAnalyzer<>
void endJob()
Called once each job just after processing has ended.

All the Stream methods are const since multiple events are being processed simultaneously which means the framework may call your member functions simultaneously for different Events. The easiest way to make the module thread safe is to not modify any member data during the call. Using const helps enforce that behavior. You can use mutable member data if you make sure that those member data are updated in a thread safe manner.

Template Arguments

Each of the base classes can take multiple template arguments. These template arguments allow one to extend the interface in order to get additional information about the state of the system or manage cache information for different transitions. If multiple template arguments are used, the order of the arguments does not matter.

edm::StreamCache<T>

This extension allows the module to hold independent data for each Stream. The type of the per Stream data is specified by the template argument T. A per Stream cache can be useful as Event level scratch space that you want to reuse for optimization reasons. Since a Stream processed data serially, the data held by the class T does not have to be thread-safe since the framework guarantees that the methods which take a edm::StreamID as an argument are never called simultaneously using the same edm::StreamID instance.

The extended interface is as follows:

std::unique_ptr<T> beginStream(edm::StreamID) const
This is called once for each Stream being used in the job to create the cache object T that will be used for that particular Stream.
void streamBeginRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const
Called when the Stream is switching from one Run to a new Run. It is possible for the Source to start a new Run and for some of the Streams to never see that Run if there are less Events in that Run then there are Streams in the job. In the case where there are no LuminosityBlocks in a Run, one and only one Stream will see a streamBeginRun/streamEndRun transition pair.
void streamBeginLuminosityBlock(edm::StreamID, edm::LuminosityBlock const&, edm::EventSetup const&) const
Called when the Stream is switching from one LuminosityBlock to a new LuminosityBlock. It is possible for the Source to start a new LuminosityBlock and for some of the Streams to never see that Run if there are less Events in that LuminosityBlock then there Streams in the job. In the case where there are no Events in a LuminosityBlock, one and only one Stream will see a streamBeginLuminosityBlock/streamEndLuminosityBlock transition pair.
void streamEndLuminosityBlock(edm::StreamID, edm::LuminosityBlock const&, edm::EventSetup const&) const
Called when the Stream has finished processing all data from a LuminosityBlock and is switching to a new LuminosityBlock.
void streamEndRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const
Called when the Stream has finished processing all data from a Run and is switching to a new Run.
void endStream(edm::StreamID) const
Called only once when a Stream has finished processing data.
T * streamCache(edm::StreamID iID) const
Returns the Stream Cache instance associated with the Stream identified by iID. This method can be called from any method which takes an edm::StreamID as an argument.

example usage: Using a non-thread safe helper

Below is shown an example where we have a helper class, TrackFitter, we use to create the data we want to put into the event. Although multiple instances of this helper are independent and therefore can be used simultaneously on different threads, a single instance of the helper is not thread safe.

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class TrackFitterProducer : public edm::global::EDProducer<edm::StreamCache<TrackFitter>> {
public:
   TrackFitterProducer(edm::ParameterSet const& iPSet) {
      //record the parameters needed to configure the TrackFitter
      ...
      m_seedTag = iPSet.getParameter<edm::InputTag>("seedTag");
      ...
   }
   
   std::unique_ptr<TrackFitter> beginStream(StreamID) const {
       return std::unique_ptr<TrackFitter>(new TrackFitter(...));
   }

   void produce(StreamID iID, edm::Event const& iEvent, edm::EventSetup const&) const {
      edm::Handle<TrackSeeds> hSeeds;
      iEvent.getByLabel(m_seedTag, hSeeds);

      //Call the TrackFitter::fitAllTracks method using the Stream specific instance of TrackFitter
      auto tracks = streamCache(iID)->fitAllTracks(hSeeds);
      iEvent.put( tracks );
   }
private:
   edm::InputTag m_seedTag; //edm::InputTag's const methods are safe to call from multiple threads

   //member data used to configure TrackFitter
   ...
};
} //ends namespace

edm::RunCache<T>

This extension manages information pertaining to Runs and properly handles the case where multiple Runs are occuring in the job at the same time. The actual information stored is up to the developer and is specified to the system based on the template parameter of the edm::RunCache<T> class. The only restriction is all const interactions with the class must be thread safe. Note that the template argument void is an allowed value and can be used in the case where you just want to be informed about the globalEndRun but do not need to store per Run information.

The main reason to use this extension is if the item (or items) requires a lot of memory or a lot of CPU time to construct. If it only takes modest amounts of both it is better to just use a StreamCache and have a per Stream instance of that data. Another reason to use this extension is if you must accumulate simple information for a Run and that information can easily be made thread safe. If it is not trivial to make the information thread-safe, use the RunSummary extension instead.

The extended interface is as follows:

std::shared_ptr<T> globalBeginRun(edm::Run const&, edm::EventSetup const&) const
This method is called each time the Source sees a new Run. This method is guaranteed to finish before any Stream calls streamBeginRun for that same Run. Therefore it is safe to call runCache() from within streamBeginRun. The return value is a std::shared_ptr<T> rather than a T* in order to facilitate the possibility of reusing the created object. (See example below.)
T const* runCache(edm::RunIndex) const
Returns the approriate run cache object created from globalBeginRun. The Run is identified by a edm::RunIndex which can be obtained through the edm::Run (and indirectly through edm::LuminosityBlock and edm::Event.)
void globalEndRun(edm::Run const&, edm::EventSetup const&) const
This method is called after all Streams have finished processing a given Run (i.e. streamEndRun for all Streams have completed). This method is also when data created by edm::EndRunProducers are accessible as well as Run products which are mergeable.

example usage: counting events in a run

The following example counts the number of events in a Run. It is crucial to use a std::atomic<unsigned int> rather than an unsigned int since we need to safely update the value from multiple Streams.

#include <atomic>

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {
struct Count { 
   Count():value(0) {}
   //Using mutable since we want to update the value.
   mutable std::atomic<unsigned int> value;
};

class MyAnalyzer : public edm::global::EDAnalyzer<edm::RunCache<Count>> {
public:
   MyAnalyzer(edm::ParameterSet const&) {}
   
   std::shared_ptr<Count> globalBeginRun(edm::Run const&, edm::EventSetup const&) const {
       return std::shared_ptr<Count>(new Count());
   }

   void analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const {
      //This can safely be called from multiple Streams because we are using an std::atomic
      ++(runCache(iEvent.getRun().index())->value);
   }

   void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const {
      std::cout <<"Number of events seen in Run "<<iRun.runNumber()<<" = "<<runCache(iRun.index())->value<<std::endl;
   }
};
} //ends namespace

example usage: reusing a heavy weight object that gets updated each run

The following example guarantees that we have a unique instance of a heavy weight object (TrackFitter) for each Run. By using a edm::ReusableObjectHolder<> the system only creates new instances of the TrackFitter if an unused older instance is not available. This guarantees the minimum number of TrackFitters in the job needed without causing the system to wait on Run boundaries. The edm::ReusuableObjectHolder<> is maintained as member data since that allows one to re-use a TrackFitter across Run boundaries.

#include "FWCore/Utilities/interface/ReusableObjectHolder.h"

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {
class ATrackFitter : public edm::global::EDProducer<edm::RunCache<TrackFitter> > {
public:

   ATrackFitter(edm::ParameterSet const& iPSet) {
     //save parameter information needed to createa a TrackFitter
     ...
   }
   
   std::shared_ptr<TrackFitter> globalBeginRun(edm::Run const& iRun, edm::EventSetup const& iES) const {
      //use a lambda to generate a new TrackFitter only if there isn't an old one available
      auto trackFitter = m_holder->makeOrGet( [this](){ return this->makeNewTrackFitter();} );
      trackFitter->update(iRun,iES);
      return trackFitter;
   }

   void producer(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const {
      //Get the track you are interested in
      ...
      //Refit the track using the Run specific TrackFitter
      runCache(iEvent.getRun().index())->fit(track);

      //Do what ever else is needed
      ...
   }

private:
  TrackFitter* makeNewTrackFitter() const; //helper function that creates a new TrackFitter based on the saved parameters

  mutable edm::ReusuableObjectHolder<TrackFitter> m_holder;

  //This is where all the data is pulled from the PSet
  ...

};
} //ends namespace

edm::LuminosityBlockCache<T>

This extension manages information pertaining to LuminosityBlocks and properly handles the case where multiple LuminosityBlocks are occuring in the job at the same time. The actual information is up to the developer and is specified to the system based on the template parameter of the edm::LuminosityBlockCache<T> class. The only restriction is all const interactions with the class must be thread safe. Note that the template argument void is an allowed value and can be used in the case where you just want to be informed about the globalEndLuminosityBlock and do not need to share any information across the Stream instances.

The main reason to use this extension is if the item (or items) either requires a lot of memory or a lot of CPU time to construct. If it only takes modest amounts of both it is better to use the StreamCache extension and have a per Stream instance of that data. Another reason to use this extension is if you must accumulate simple information for a LuminosityBlock and that information can easily be made thread safe. If it is not trivial to make the information thread-safe, use the LuminosityBlockSummary extension instead.

The extended interface is as follows:

std::shared_ptr<T> globalBeginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const
This method is called each time the Source sees a new LuminosityBlock. This method is guaranteed to finish before any Stream calls streamBeginLuminosityBlock for that same LuminosityBlock. Therefore it is safe to call luminosityBlockCache from within streamBeginLuminosityBlock. The return value is a std::shared_ptr<T> rather than a T* in order to facilitate the possibility of reusing the created object.
T const* luminosityBlockCache(edm::LuminosityBlockIndex) const
Returns the approriate luminosity block cache object created from globalBeginLuminosityBlock.
void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const
This method is called after all Streams have finished processing a given LuminosityBlock (i.e. streamEndLuminosityBlock for all Streams have completed). This method is also when data created by edm::EndLuminosityBlockProducers are accessible as well as LuminosityBlock products which are mergeable.

example usage: updating a helper object only if a condition actually changed

The following example updates a helper class, PositionFinder, only if a particular condition has changed. This code assumes that the condition in question is only allowed to change on LuminosityBlock boundaries (which is the common case). Like the Run example, we will use an edm::ReusableObjectHolder<> object to allow us to reuse old instances of the PositionFinder. In addition, we need to use an edm::SerialTaskQueue when determining if the condition has changed from one LuminosityBlock to the next since the function globalBeginLuminosityBlock may be called simultaneously from different Streams because multiple new LuminosityBlocks have entered the system. If that happens, we need to use the edm::SerialTaskQueue in order to guarantee that one Stream doesn't update the PositionFinder while a different Stream is reading the old value.

NOTE: The design presented in this example should only be used if all of the following apply

  1. The change of conditions requires a length recalculation and/or the creation of a large memory structure.
  2. Using the structure does not cause the structure to change its state.
  3. The structure created is only useful to this module.
If you just need to have access to an object in the edm::EventSetup it is better just to ask for that item once each Event. Fetching data from the edm::EventSetup is very fast. If the data structure is not modified each Event, consider moving it into the EventSetup directly and let the framework manage the proper updating of the structure.

#include "FWCore/Utilities/interface/ReusableObjectHolder.h"
#include "FWCore/Utilities/interface/SerialTaskQueue.h"

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class MovedItemProducer : public edm::global::EDProducer<edm::LuminosityBlockCache<PositionFinder> > {
public:

   MovedItemProducer(edm::ParameterSet const& iPSet) {
      //store parameters needed to create the PositionFinder
      ...
   }
   
   std::shared_ptr<PositionFinder> globalBeginLuminosityBlock(edm::LuminosityBlock const&, 
                                                              edm::EventSetup const& iES) const {
      // use the serial queue to guarantee serial read/write of m_watcher and m_mostRecentPositionFinder
      std::shared_ptr<PositionFinder> returnValue;
      m_queue.pushAndWait([&]() {
         if(!this->m_watcher.check(iES)) {
            //the condition hasn't changed so we can just use our old value
            returnValue = m_mostRecentPositionFinder;
         } else {
            //the condition has changed so we need to update
            //use a lambda to generate a new PositionFinder only if there isn't an old one available
            returnValue = m_holder->makeOrGet( [this] (){ return this->makeNewPositionFinder();} );
            returnValue->update(iES.get<AlignmentRcd>());
            m_mostRecentPositionFinder = returnValue;
         }
      });
      return returnValue;
   }

   void producer(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const {
      //Get the item you need to move
      ...
      //Apply the move
      luminosityBlockCache(iEvent.luminosityBlock().luminosityBlockIndex())->move(item);

      //Do what ever else is needed
      ...
   }

private:
  PositionFinder* makeNewPositionFinder() const;

  mutable edm::ReusuableObjectHolder<PositionFinder> m_holder;
  mutable edm::SerialTaskQueue m_queue;
  //the access to the two following member data are controlled by the queue
  mutable edm::ESWatcher<AlignmentRcd> m_watcher; 
  mutable std::shared_ptr<PositionFinder> m_mostRecentPostionFinder;

  //This is where all the data is pulled from the PSet
  ...
};
} //ends namespace

edm::RunSummaryCache<T>

This extension makes it easy to accumulate a partial sum of information about a Run in each Stream and then, when all of the Streams have finished with that Run, the partial sums can be accumulated into a final sum. The actual summary information is up to the developer and is specified to the system based on the template parameter T of the edm:RunSummaryCache<T> class. The system guarantees serial access to T so its member data does not need to be thread-safe. This extension is meant to work with the edm::StreamCache extension where you store the partial sum in the Stream cache.

The extended interface is as follows:

std::shared_ptr<T> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const
This method is called each time the Source sees a new Run. This method is guaranteed to be called after globalBeginRun in the case where the class also uses the edm::RunCache extension. The return value is a std::shared_ptr<T> rather than a T* in order to facilitate the possibility of reusing the created object.
void streamEndRunSummary(StreamID, edm::Run const&, edm::EventSetup const&, T*) const
Called when a Stream has finished processing a Run. The framework guarantees that only one streamEndRunSummary is called at a time. Therefore it is safe to modify the summary information which is passes in as the argument T *. The framework guarantees that streamEndRun is called before streamEndRunSummary.
void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, T*) const
This method is called after the streamEndRunSummary method for all Streams have finished processing a given Run. At this point the summary object T* is complete. This method is guaranteed to be called before globalEndRun in the case where the class also uses the edm::RunCache extension.

example usage: filling a histogram for each run

This example uses a fictitious histogramming library to create histograms that are per Run and filled with information obtained from the Event. The fictitious histogram library is assumed to have the following properties
  1. It is safe to do operations simultaneously on two different object instances. This holds for different HistFile, MemoryHist1D and StoredHist1D.
  2. Simultaneous operations on the same object instance are not safe (i.e. the classes instances are not thread-safe).
  3. Class methods do not affect any global state of the system.
The design for this example is as follows
  1. We have a HistFile member data as well as a SerialTaskQueue which is used to make all interactions with the HistFile thread safe.
  2. Each Run gets its own new StoredHist1D which is attached to the HistFile.
  3. The edm::StreamCache holds a MemoryHist1D which is used to accumulate information from the Events that the particular Stream sees.
  4. Once a Stream finishes with a Run its MemoryHist1D is added to the StoredHist1D.
  5. When all Streams have finished with a Run the StoredHist1D is written out to the file and then the StoredHist1D is removed from the HistFile object's data structure so its memory can be reclaimed.

#include "FWCore/Utilities/interface/SerialTaskQueue.h"

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {
class HistFillerAnalyzer : public edm::global::EDAnalyzer<edm::StreamCache<MemoryHist1D>, edm::RunSummaryCache<StoredHist1D> > {
public:

   HistFillerAnalyzer(edm::ParameterSet const& iPSet): m_file(new HistFile(iPSet.getParameter<std::string>("histFileName"))){
   }

   std::shared_ptr<MemoryHist1D> beginStream(StreamID) const {
      return new MemoryHist1D(...);
   }   

   std::shared_ptr<StoredHist1D> globalBeginRunSummary(edm::Run const& iRun, edm::EventSetup const&) const {
      std::shared_ptr<StoredHist1D> returnValue;
      unsigned int runNumber = iRun.runNumber();

      //make sure only one thread is asking for a new histogram at a time
      m_queue.pushAndWait([&]() {
         //use iRunNumber to create a unique name
         std::string name = ...;
         returnValue = this->m_file->bookHist1D(name, ...);
      });
      return returnValue;
   }

   void analyze(StreamID iID, edm::Event const& iEvent, edm::EventSetup const&) const {
      //Get the information you are interested in
      ...
      //fill the histogram for this stream
      streamCache(iID)->fill(value);

      //Do what ever else is needed
      ...
   }
   void streamEndRunSummary(edm::StreamID iID, edm::Run const& iRun, edm::EventSetup const&, StoredHist1D* iStoredHist) const {
      //Add the values seen in this Stream to the total for this Run
      iStoredHist->add( *(streamCache(iID)) );

      //now clear in order to be ready for the next Run
      streamCache(iID)->clear();
   }

   void globalEndRunSummary(edm::Run const& iRun, edm::EventSetup const&, StoredHist1D* iStoredHist) const {
      //need to serialize writing to the file and updating the file's internal data structures
      m_queue.pushAndWait([&]() {
         this->m_file->write(iStoredHist);
         this->m_file->release(iStoredHist);
      });
   }

   void endJob() {
      m_file->close();
   }
private:
   mutable std::unique_ptr<HistFile> m_file;
   mutable SerialTaskQueue m_queue; //queue is used to serialize access to m_file
};
} //ends namespace

edm::LuminosityBlockSummaryCache<T>

This extension makes it easy to accumulate a partial sum of information about a LuminosityBlock in each Stream and then, when all of the Streams have finished with that LuminosityBlock, the partial sums can be accumulated into a final sum. The actual summary information is up to the developer and is specified to the system based on the template parameter T of the edm:LuminosityBlockSummaryCache<T> class. The system guarantees serial access to T so its member data does not need to be thread-safe. This extension is meant to work with the edm::StreamCache extension where you store the partial sum in the Stream cache.

The extended interface is as follows:

std::shared_ptr<T> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&) const
This method is called each time the Source sees a new LuminosityBlock. This method is guaranteed to be called after globalBeginLuminosityBlock in the case where the class also uses the edm::LuminosityBlockCache extension. The return value is a std::shared_ptr<T> rather than a T* in order to facilitate the possibility of reusing the created object.
void streamEndLuminosityBlockSummary(edm::StreamID, edm::LuminosityBlock const&, edm::EventSetup const&, T*) const
Called when a Stream has finished processing a Run. The framework guarantees that only one streamEndLuminosityBlockSummary is called at a time. Therefore it is safe to modify the summary information which is passes in as the argument T *. The framework guarantees that streamEndLuminosityBlock is called before streamEndLuminosityBlockSummary.
void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, T*) const
This method is called after the streamEndLuminosityBlockSummary method for all Streams have finished processing a given LuminosityBlock. This method is guaranteed to be called before globalEndLuminosityBlock in the case where the class also uses the edm::LuminosityBlockCache extension.

example usage: calculating per luminosity block statistics

This example calculates statistics for the number of tracks in all events in a luminosity block. This requires keeping a list of the number of tracks in all events in a given luminosity block.

#include <vector>

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class TrackStatisticsAnalyzer : public edm::global::EDAnalyzer<edm::LuminosityBlockCache<std::vector<unsigned int>>, 
                                                               edm::LuminosityBlockSummaryCache<std::vector<unsigned int>> > {
public:

   HistFillerAnalyzer(edm::ParameterSet const& iPSet): m_trackTag(iPSet.getParameter<edm::InputTag>("trackTag")) {}

   std::shared_ptr<std::vector<unsigned int>> beginStream(StreamID) const {
      return new std::vector<unsigned int>();
   }
   
   std::shared_ptr<std::vector<unsigned int>> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&, 
                                                                                edm::EventSetup const& ) const {
       return new std::vector<unsigned int>();
   }

   void analyze(edm::StreamID iID, edm::Event const& iEvent, edm::EventSetup const&) const {
      //Get the track info
      edm::Handle<std::vector<reco::Track>> hTracks;
      iEvent.getByLabel(m_trackTag,hTracks);
  
      streamCache(iID)->push_back(hTracks->size());
   }
   
   void streamEndLuminosityBlockSummary(edm::StreamID iID,
                                        edm::LuminosityBlock const& iRun, 
                                        edm::EventSetup const&, 
                                        std::vector<unsigned int>* iSummary) const {
      //add the Stream's partial information to the full information
      auto cache = streamCache(iID);
      iSummary->insert(cache->begin(),cache->end());

      //now clear in order to be ready for the next LuminosityBlock
      cache->clear();
   }

   void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, 
                                        edm::EventSetup const&, 
                                        std::vector<unsigned int>* iSummary) const {
     //calculate lots of statistically interesting quantities and print them
     ...
   }

private:

   edm::InputTag m_trackTag;
};
} //ends namespace

edm::BeginRunProducer

This extension allows an EDProducer to put data into the Run at the begin of Run transition. Items placed during the begin of Run transition are available to get for any method that directly or indirectly provides a edm::Run.

The extended interface is as follows:

void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const
This method is called each time the Source sees a new Run. This method is guaranteed to be called after globalBeginRun in the case where the class also uses the edm::RunCache extension.

example usage: pull data from a database and put it into the run

This example will use a fictitious thread-safe database interface to retrieve data and then place it into the Run.

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class LHCStatusProducer : public edm::global::EDProducer<edm::BeginRunProducer> {
public:
   LHCStatusProducer(edm::ParameterSet const& iPSet): m_dbConnection(iPSet.getParameter<std::string>("dbURL")){
      //we need to register the fact that we will make the LHCStatus object
      produces<LHCStatus, edm::Transition::BeginRun>();
   }
   
   void produce(edm::Event const& iEvent, edm::EventSetup const&) const {
      //Do nothing
   }

   void globalBeginRunProduce(edm::Run& iRun, edm::EventSetup const&) const {
      std::auto_ptr<LHCStatus> status(new LHCStatus);
      m_dbConnection.fill(*status);
 
      iRun.put(status);
   }

   void endJob() {
      m_dbConnection.closeConnection();
   }

private:
   DBConnection m_dbConnection;
};
} //ends namespace

edm::BeginLuminosityBlockProducer

This extension allows an EDProducer to put data into the LuminosityBlock at the begin of LuminosityBlock transition. Items placed during the begin of LuminosityBlock transition are available to get for any method that directly or indirectly provides a edm::LuminosityBlock.

The extended interface is as follows:

void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const
This method is called each time the Source sees a new LuminosityBlock. This method is guaranteed to be called after globalBeginLuminosityBlock in the case where the class also uses the edm::LuminosityBlockCache extension.

example usage: pull data from a database and put it into the luminosity block

This example will use a fictitious thread-safe database interface to retrieve data and then place it into the LuminosityBlock.

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class LumiSummaryProducer : public edm::global::EDProducer<edm::BeginLuminosityBlockProducer> {
public:

   LumiSummaryProducer(edm::ParameterSet const& iPSet): m_dbConnection(iPSet.getParameter<std::string>("dbURL")) {
      //we need to register the fact that we will make the LumiSummary object
      produces<LumiSummary, edm::Transition::BeginLuminosityBlock>();
   }
   
   void produce(edm::Event const& iEvent, edm::EventSetup const&) const {
      //Do nothing
   }

   void globalBeginLuminosityBlockProduce(edm::LuminosityBlock& iLumi, edm::EventSetup const&) const {
      std::auto_ptr<LumiSummary> summary(new LumiSummary);
      m_dbConnection.fill(iLumi.runNumber(), iLumi.luminosityBlockNumber(),*summary);
 
      iLumi.put(summary);
   }

   void endJob() {
      m_dbConnection.closeConnection();
   }
private:
   mutable DBConnection m_dbConnection; //is thread-safe
};
} //ends namespace

edm::EndRunProducer

This extension allows an EDProducer to put data into the Run at the end of Run transition. Items placed during the end of Run transition are only available during globalEndRun calls and are not available to the standard Stream method streamEndRun. The reason for this restriction is the need to make all Run products invariant for the entire processing of the Run.

The normal extended interface is as follows:

void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const
This method is called once all Streams processing a Run are done with the Run. This method is guaranteed to be called before globalEndRun in the case where the class also uses the edm::RunCache extension.
If the module also uses the edm::RunSummaryCache<T> extension then the interfaces is modified to give access to the summary object
void globalEndRunProduce(edm::Run&, edm::EventSetup const&, T const*) const
Same as above except also gives access to Run summary information via T const*. This method is guaranteed to be called after globalEndRunSummary so that the Run summary object is complete.

example usage: calculate a Run average efficiency

#include <atomic>
#include "DataFormats/Something/interface/Efficiency.h"

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

struct TempEfficiency {
   mutable std::atomic<unsigned long> m_numerator=0;
   mutable std::atomic<unsigned long> m_denominator=0;
};

class RunEfficiencyAnalyzer : public edm::global::EDProducer< edm::RunCache<TempEfficiency>, EndRunProducer > {
public:

   RunEfficiencyAnalyzer(edm::ParameterSet const&) {
      //have to register what we will make
      produces<Efficiency, edm::Transition::EndRun>();
   }
   
   std::shared_ptr<Efficiency> globalBeginRun(edm::Run const&, edm::EventSetup const&) const {
       return new Efficiency;
   }

   void produce(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const {
      //Get the information you are interested in and see if it passes your requirement
      ...
      auto cache = runCache(iEvent.getRun().index());
      ++(cache->m_denominator);
      if(passesCuts) {
         ++(cache->m_numerator);
      }
   }

   void globalEndRun(edm::Run const&, edm::EventSetup const&) const {
      //don't need to do anything
   }

   void globalEndRunProduce(edm::Run& iRun, edm::EventSetup const&) const {
      auto cache = runCache(iRun.index());
      std::auto_ptr<Efficiency> eff(new Efficiency(cache->m_numerator, cache->m_denominator));
      iRun.put(eff);
   }
};
} //ends namespace

edm::EndLuminosityBlockProducer

This extension allows an EDProducer to put data into the LuminosityBlock at the end of a LuminosityBlock transition. Items placed during the end of LuminosityBlock transition are only available during globalEndLuminosityBlock calls and are not available to the standard Stream method streamEndLuminosityBlock. The reason for this restriction is the final product cannot be determined until all the Streams have completed their processing of that LuminosityBlock.

The normal extended interface is as follows:

void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const
This method is called once all Streams processing a LuminosityBlock are done with the LuminosityBlock. This method is guaranteed to be called before globalEndLuminosityBlock in the case where the class also uses the edm::LuminosityBlockCache extension.
If the module also uses the edm::LuminosityBlockSummaryCache<T> extension then the interfaces is modified to give access to the summary object
void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, T const*) const
Same as above except also gives access to LuminosityBlock summary information via T const*. This method is guaranteed to be called after globalEndLuminosityBlockSummary so that the LuminosityBlock summary object is complete.

example usage: find a luminosity block average beam spot

This example keeps track of all vertices for all events in a luminosity block and then when the luminosity block ends we form a beam spot. We accumulate a list of points for each Stream independently. When a Stream finishes processing a luminosity block its lists of points is added to the global luminosity block point list.

//use an anonymous namespace since there is no need for any other file to see these class names
namespace {

class BeamSpotProducer : public edm::global::EDProducer<edm::StreamCache<std::vector<Point3D>>,
                                                        edm::LuminosityBlockSummaryCache<std::vector<Point3D>>, 
                                                        edm::EndLuminosityBlockProducer> {
public:

   BeamSpotProducer(edm::ParameterSet const& iPSet) : m_tag(iPSet.getParameter<edm::InputTag>("vertexTag")){
      
      //we need to register the fact that we will make the BeamSpot object
      produces<BeamSpot, edm::Transition::EndLuminosityBlock>();
   }
  
   std::unique_ptr<std::vector<Point3D>> beginStream(StreamID) const {
      return new std::vector<Point3D>();
   }   

   std::shared_ptr<std::vector<Point3D>> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&, 
                                                                           edm::EventSetup const&) const {
       return new std::vector<Point3D>();
   }

   void produce(edm::StreamID iID, edm::Event& iEvent, edm::EventSetup const&) const {
      //Get vertices
      edm::Handle<std::vector<Vertex>> vertices;
      iEvent.getByLabel(m_tag, vertices);

      auto points = streamCache(iID);
      points->reserve(points->size()+vertices->size());
      for( auto v : *vertices) {
         points->push_back(v.point());
      }
   }

   void streamEndLuminosityBlockSummary(StreamID iID,
                                        edm::LuminosityBlock const&,
                                        edm::EventSetup const&,
                                        std::vector<Point3D>* iPoints) const{
      auto points = streamCache(iID);

      //add the Stream's partial information to the full information
      iPoints->insert(points->begin(),points->end());

      //now clear in order to be ready for the next LuminosityBlock
      points->clear();
   }

   void globalEndLuminosityBlockProduce(edm::LuminosityBlock& iLumi, 
                                        edm::EventSetup const&, 
                                        std::vector<Point3D> const* iPoints) const {
      //calculate beam spot from the points
      
      std::auto_ptr<BeamSpot> spot( makeBeamSpotFromPoints(*iPoints) );
 
      iLumi.put(spot);
   }
};
} //ends namespace

edm::Accumulator

This extension is usually used with EDProducers that put products in the Run or LuminosityBlock but do not put products in the Event. Although they do not put products in the Event, these EDProducers need data from Events for the products they put in the Run or LuminosityBlock. Without this extension and if the EDProducer is configured to run unscheduled, its event method will never run because nothing ever requests a product it produces. With this extension, these modules will run their event method on every event and accumulate the data they need.

The declaration of an EDProducer with the Accumulator feature looks like this:

class MyProducer : public edm::global::EDProducer<edm::Accumulator>

This only works with the EDProducer base class. It does not work with EDAnalyzers, EDFilters, or OutputModules.

When you use this feature you must replace the produce function with the accumulate function. It will not compile if you do not define the accumulate function. It will not compile if you define the produce function. The accumulate function will not allow products to be put into the Event because the Event argument is declared const.

void accumulate(edm::StreamID iID, edm::Event const&, edm::EventSetup const&) const override

You can put modules with this feature on a Path or EndPath. The special behavior does not occur then. In that case, they run on the Path or EndPath the same as if they did not have the Accumulate extension. If the module is on a Path after an EDFilter that does not pass the event, then the module will not run.

Usually this feature extension will be used with other feature extensions. For example, it might be used with LuminosityBlockSummaryCache and EndLuminosityBlockProducer.

This extension was first added in release 10_1_0 (in 2018), it cannot be used in earlier releases.

edm::ExternalWork

This extension was added to provide Framework support for future modules that run in new ways. For example, modules that use GPUs or FPGAs might use this extension. Initially, this extension may be used for prototypes and tests of such modules. As of this writing (January 2018), none of these modules exist and the only things using this extension are Framework tests.

This extension affects the event processing part of the module and divides it into 3 parts. Without this extension there is one function called produce or filter. With this extension, there is a new acquire function added that is defined in the module. Its purpose is to get data from the Event and communicate to "something external to the module". One possible example of "something external to the module" would be a service that runs GPU processing. The acquire method also passes to this external thing an edm::WaitingTaskWithArenaHolder. Then the acquire method returns and is not left on the stack. It is important that it is not left on the stack because that eliminates the potential problem that it might block its thread or deadlock. Then the external thing performs the work. The third part is that the Framework calls the produce or filter method of the module. The external thing is not part of the Framework and there are very few requirements on what it is or how it functions. It must exchange data with the module in some way so that the acquire function can pass it input and the produce/filter method can use the results it produces. It also must call the doneWaiting function of the WaitingTaskWithArenaHolder. This lets the Framework know when it can call the produce or filter function. Beyond that, the Framework places no requirements on the design of the external work entity. There is great freedom in how it is designed and how it works.

One defines a class with this extension as follows:

class MyProducer : public edm::global::EDProducer<edm::ExternalWork>

This will work for both EDProducers and EDFilters, but not for EDAnalyzers or OutputModules.

One must define one additional function in the module when this extension used:

void acquire(edm::StreamID, edm::Event const&, edm::EventSetup const&, edm::WaitingTaskWithArenaHolder) const override;

This extension was first added in release 10_0_0 (in 2017), it cannot be used in earlier releases.

Review status

Reviewer/Editor and Date Comments
Last reviewed by: ChrisDJones - 14-Nov-2012 Created the page

Responsible: ChrisDJones
Last reviewed by:

Edit | Attach | Watch | Print version | History: r16 < r15 < r14 < r13 < r12 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r16 - 2018-07-12 - DavidDagenhart
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    CMSPublic All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback