Persistent references to EDProducts

Complete: 3

Goal of this page

To explain how to create persistent references to EDM objects, and which reference to use.

Introduction

Three types of references are currently supported
   edm::RefProd<T> - a persistable reference to an EDProduct of type T

   edm::Ref<C, T=C::value_type, F=refhelper::FindTrait<C,T>::value> - a persistable reference to 
an element of type T in a collection of type C

   edm::Ptr<T> - a persistable polymorphic reference to an element of type T in a collection of an unspecified type
In addition, also supported are
   edm::RefVector<C, T=C::value_type>
    a persistable vector of edm::Ref<C,T,F>, where every element is a member of the same EDProduct.

   edm::PtrVector<T>
    a persistable vector of edm::Ptr<T>, where every element is a member of the same EDProduct.

edm::RefVector<C> and edm::PtrVector<T>
are (nearly) functionally equivalent respectively to
std::vector<edm::Ref<C> > and std::vector<edm::Ptr<T> >.
The purpose of RefVector or PtrVector is to save storage. Since every element points to an element of the same EDProduct, the EDProduct information needs to be stored only once.

Note that the second and third template parameters of edm::Ref and edm::RefVector have defaults, so that they need not be specified in most places. (For more information on the template parameters, see the customization heading at the bottom of this page.) The major exception is in the XML specification of the class name in classes_def.xml to define a data dictionary, in which the template parameters must be explicitly specified, although typedefs may be usable.

When needed, the header files defining these references can be included like so:

#include "DataFormats/Common/interface/Ptr.h"
#include "DataFormats/Common/interface/PtrVector.h"
#include "DataFormats/Common/interface/RefProd.h"
#include "DataFormats/Common/interface/Ref.h"
#include "DataFormats/Common/interface/RefVector.h"

Characteristics of an edm::RefProd, edm::Ref, edm::Ptr, edm::RefVector, or edm::PtrVector

  • It does not own the product that it references.
  • It is freely copyable or assignable.
  • It is persistable (requires data dictionary).
  • It can be a member of any object, persistent or otherwise.
  • If a member of a per Event EDProduct, it can only reference a product in the same Event.
  • It contains no global identifiers. It is entirely internal to one Event.

Which to use, edm::Ref or edm::Ptr

  • An edm::Ptr can be used polymorphically. An edm::Ptr< T > can reference any item of a class that publicly inherits from T.
  • An edm::Ref cannot be used polymorphically. An edm::Ref<C, T> can only reference an item of class T in a container of class C.

So, you must use an edm::Ptr if you need a polymorphic reference to an item.

  • An edm::Ptr can be used even if the type of the collection is unspecified or unknown.
  • An edm::Ref must specify the type of the collection as its first template parameter.

So, you must use an edm::Ptr if the type of the collection is unspecified or unknown.

  • An edm::Ref can provide access to the collection itself, because an edm::RefProd may be constructed from an edm::Ref.
  • An edm::Ptr cannot provide access to the collection itself, only to the item in the collection.

So, you must use an edm::Ref if you need to be able to access the collection itself from the reference.

  • An edm::Ref can access a member in the collection, given an index of an arbitrary type, in a customizable manner (see below).
  • An edm::Ptr can access a member in the collection only with an integer index.

So, you must use an edm::Ref if members in the collection need to be accessed in a customizable way.

If either edm::Ref or edm::Ptr will work, an edm::Ref should be used, as it is often significntly faster than edm::Ptr, due to the dynamic typing needed in the implementation of edm::Ptr.

Dereferencing an edm::RefProd, edm::Ref, or edm::Ptr

An edm::RefProd, edm::Ref, or edm::Ptr can be dereferenced as if it were a simple pointer by the operators * or ->.

   *  retrieves the referenced product or collection element
   -> retrieves the designated member of the product or element

If the RefProd, Ref, or Ptr is null (i.e. does not reference a product), or if the referenced product is no longer in the event (because it was not selected for output at some previous processing stage), dereferencing will cause an exception to be thrown.

Note: The module or source that produces a product does not immediately add the product to the event. It simply places the product in a queue. Immediately after the module or source returns successfully, the framework puts any queued products into the event. This means that a product cannot be obtained by dereferencing a RefProd, Ref, or Ptr immediately by the same module instance that produced the product.

Transient only edm::RefProd, edm::Ref, edm::Ptr, edm::RefVector, and edm::PtrVector

A persistable edm::RefProd, edm::Ref, or edm::Ptr* may only reference a product that has been put into an event. In order that classes or algorithms using references can be used outside the Framework, such as by FWLite, references can be constructed to refer to products that have not and will not be put into the event. These references are transient only. A transient reference is distinguishable from a persistable one because it is created by a different constructor, as described below. Any object containing a transient reference may not be put into the event or persisted. A transient edm::Ref or edm::Ptr may be stored in a transient edm::RefVector or edm::PtrVector respectively, but a persistable edm::Ref (edm::Ptr) and a transient edm::Ref (edm::Ptr) may not be stored in the same edm::RefVector (edm::PtrVector). All transient references in a given edm::RefVector or edm::PtrVector must reference objects in the same collection.

Detailed description of edm::RefProd, edm::Ref, and edm::Ptr

Constructing an edm::RefProd or edm::Ref

A persistable edm::RefProd or edm::Ref is typically constructed from a edm::Handle to the referenced product as follows:

edm::RefProd<C> myRefProd(const edm::Handle<C> & product)

edm::Ref<C> myRef(const edm::Handle<C> & collection, size_type indexIntoCollection)

An OrphanHandle (similar to a Handle, but with no provenance information) may be used in place of the full Handle. edm::Event::put(...) returns an OrphanHandle to the put product.

A null persistable edm::Ref may be constructed from a valid edm::ProductID, like so:

edm::Ref<C> myRef(const edm::ProductID& valid_id);

In contrast, a transient edm::RefProd or edm::Ref is constructed from a bare pointer to the referenced product as follows:

edm::RefProd<C> myRefProd(const C* product)

edm::Ref<C> myRef(const C* collection, size_type indexIntoCollection)

A null transient edm::RefProd or edm::Ref may be constructed by passing a null pointer to the above constructors.

An edm::Ref may also be constructed from an edm::RefProd and an index, like so:

edm::Ref<C> myRef(const edm::RefProd<C> & collection, size_type indexIntoCollection)

An edm::Ref so constructed will be persistable if and only if the edm::RefProd is persistable.

An edm::RefProd may also be constructed from an edm::Ref, like so:

edm::RefProd<C> myRefProd(const edm::Ref<C> & ref)

An edm::RefProd so constructed will be persistable if and only if the edm::Ref is persistable.

Constructing an edm::Ptr

A persistable edm::Ptr is typically constructed from a edm::Handle to the referenced collection as follows:

edm::Ptr<T> myPtr(const edm::Handle<C> & collection, size_type indexIntoCollection)

An OrphanHandle (similar to a Handle, but with no provenance information) may be used in place of the full Handle. edm::Event::put(...) returns an OrphanHandle to the put product.

A null persistable edm::Ptr may be constructed from a valid edm::ProductID, like so:

edm::Ptr<T> myPtr(const edm::ProductID& valid_id);

In contrast, a transient edm::Ptr is constructed from a bare pointer to the referenced collection as follows:

edm::Ptr<T> myRef(const C* collection, size_type indexIntoCollection)

A null transient edm::Ptr may be constructed by passing a null pointer to the above constructor.

An edm::Ptr may also be constructed from an edm::Ref, by calling the refToPtr function, as shown below:

#include "DataFprmats/Common/interface/RefToPtr.h"
...
edm::Ptr<C::value_type> myPtr = edm::refToPtr(const edm::Ref<C, C::value_type> & myRef)

An edm::Ptr so constructed will be persistable if and only if the edm::Ref is persistable.

It is not possible to construct an edm::Ref from an edm::Ptr.

Customization of edm::Ref

The edm::Ref<> takes three template parameters
  1. C: The type of the container that is holding the item
  2. T: The type of the item. This defaults to C::value_type
  3. F: A helper class (a functor) that knows how to find a particular 'T' within the container given an appropriate index. The type of the index is deduced from F::second_argument. The default for F is refhelper::FindTrait<C,T>::value. If no specialization of FindTrait<> is available for the conbination (C,T) then it defaults to getting the iterator to be beginning of the container and using std::advance() to move to the appropriate index in the container.

It is possible to customize the 'lookup' algorithm used. The helper class should publicly inherit from

     std::binary_function<const C&, typename IndexT, const T*>
and define the function
     result_type operator()(first_argument_type iContainer, second_argument_type iIndex)
where result_type, first_argument_type and second_argument_type are typedefs inherited from std::binary_function<>. If one wishes to make a specialized lookup the default lookup for the container/type pair then one needs to partially specialize the templated class
     edm::refhelper::FindTrait<C,T>
such that it has a typedef named 'value' that refers to the specialized helper class (i.e., F)

Review Status

Reviewer/Editor and Date (copy from screen) Comments
WilliamTanenbaum - 14 Jan 2007 page last content editor
JennyWilliams - 31 Jan 2007 editing to include in SWGuide
Main.paterno - 29 Mar 2007 added information about making a null reference, corrected note about OrphanHandle
WilliamTanenbaum - 08 Nov 2008 Clarifications
WilliamTanenbaum - 26 Jul 2011 added documentaion of Ptr

Responsible: WilliamTanenbaum
Last reviewed by: Reviewer

Edit | Attach | Watch | Print version | History: r17 < r16 < r15 < r14 < r13 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r17 - 2011-07-26 - WilliamTanenbaum



 
    • 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