CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ThinningProducer.h
Go to the documentation of this file.
1 #ifndef FWCore_Framework_ThinningProducer_h
2 #define FWCore_Framework_ThinningProducer_h
3 
9 
22 
23 #include <memory>
24 
25 namespace edm {
26 
27  class EventSetup;
28 
29  template <typename Collection, typename Selector>
31  public:
32  explicit ThinningProducer(ParameterSet const& pset);
33  virtual ~ThinningProducer();
34 
35  static void fillDescriptions(ConfigurationDescriptions & descriptions);
36 
37  virtual void produce(Event& event, EventSetup const& eventSetup) override;
38 
39  virtual void registerThinnedAssociations(ProductRegistry const& productRegistry,
40  ThinnedAssociationsHelper& thinnedAssociationsHelper) override;
41  private:
45  };
46 
47  template <typename Collection, typename Selector>
50  selector_(new Selector(pset, consumesCollector())) {
51 
52  inputTag_ = pset.getParameter<InputTag>("inputTag");
53  inputToken_ = consumes<Collection>(inputTag_);
54 
55  produces<Collection>();
56  produces<ThinnedAssociation>();
57  }
58 
59  template <typename Collection, typename Selector>
62 
63  template <typename Collection, typename Selector>
67  desc.setComment("Produces thinned collections and associations to them");
68  desc.add<edm::InputTag>("inputTag");
69  Selector::fillDescription(desc);
70  descriptions.addDefault(desc);
71  }
72 
73  template <typename Collection, typename Selector>
75  produce(Event& event, EventSetup const& eventSetup) {
76 
78  event.getByToken(inputToken_, inputCollection);
79 
80  edm::Event const& constEvent = event;
81  selector_->preChoose(inputCollection, constEvent, eventSetup);
82 
83  std::auto_ptr<Collection> thinnedCollection(new Collection);
84  std::auto_ptr<ThinnedAssociation> thinnedAssociation(new ThinnedAssociation);
85 
86  unsigned int iIndex = 0;
87  for(auto iter = inputCollection->begin(), iterEnd = inputCollection->end();
88  iter != iterEnd; ++iter, ++iIndex) {
89  if(selector_->choose(iIndex, *iter)) {
90  thinnedCollection->push_back(*iter);
91  thinnedAssociation->push_back(iIndex);
92  }
93  }
94  OrphanHandle<Collection> orphanHandle = event.put(thinnedCollection);
95 
96  thinnedAssociation->setParentCollectionID(inputCollection.id());
97  thinnedAssociation->setThinnedCollectionID(orphanHandle.id());
98  event.put(thinnedAssociation);
99  }
100 
101  template <typename Collection, typename Selector>
104  ThinnedAssociationsHelper& thinnedAssociationsHelper) {
105 
106  BranchID associationID;
107  BranchID thinnedCollectionID;
108 
109  // If the InputTag does not specify the process name, it is
110  // possible that there will be more than one match found below.
111  // For a particular event only one match is correct and the
112  // others will be false. It even possible for some events one
113  // match is correct and for others another is correct. This is
114  // a side effect of the lookup mechanisms when the process name
115  // is not specified.
116  // When using the registry this generates one would have to
117  // check the ProductIDs in ThinnedAssociation product to get
118  // the correct association. This ambiguity will probably be
119  // rare and possibly never occur in practice.
120  std::vector<BranchID> parentCollectionIDs;
121 
122  ProductRegistry::ProductList const& productList = productRegistry.productList();
123  for(auto const& product : productList) {
124  BranchDescription const& desc = product.second;
125  if(desc.unwrappedType().typeInfo() == typeid(Collection) ) {
126  if(desc.produced() &&
127  desc.moduleLabel() == moduleDescription().moduleLabel() &&
128  desc.productInstanceName().empty()) {
129 
130  thinnedCollectionID = desc.branchID();
131  }
132  if(desc.moduleLabel() == inputTag_.label() &&
133  desc.productInstanceName() == inputTag_.instance()) {
134  if(inputTag_.willSkipCurrentProcess()) {
135  if(!desc.produced()) {
136  parentCollectionIDs.push_back(desc.branchID());
137  }
138  } else if (inputTag_.process().empty() || inputTag_.process() == desc.processName()) {
139  if(desc.produced()) {
140  parentCollectionIDs.push_back(desc.originalBranchID());
141  } else {
142  parentCollectionIDs.push_back(desc.branchID());
143  }
144  }
145  }
146  }
147  if(desc.produced() &&
148  desc.unwrappedType().typeInfo() == typeid(ThinnedAssociation) &&
149  desc.moduleLabel() == moduleDescription().moduleLabel() &&
150  desc.productInstanceName().empty()) {
151 
152  associationID = desc.branchID();
153  }
154  }
155  if(parentCollectionIDs.empty()) {
156  // This could happen if the input collection was dropped. Go ahead and add
157  // an entry and let the exception be thrown only if the module is run (when
158  // it cannot find the product).
159  thinnedAssociationsHelper.addAssociation(BranchID(), associationID, thinnedCollectionID);
160  } else {
161  for(auto const& parentCollectionID : parentCollectionIDs) {
162  thinnedAssociationsHelper.addAssociation(parentCollectionID, associationID, thinnedCollectionID);
163  }
164  }
165  }
166 }
167 #endif
T getParameter(std::string const &) const
void addAssociation(BranchID const &, BranchID const &, BranchID const &)
ProductID id() const
Definition: HandleBase.cc:15
std::map< BranchKey, BranchDescription > ProductList
std::string const & processName() const
edm::propagate_const< std::unique_ptr< Selector > > selector_
ProductID id() const
ProductList const & productList() const
void setComment(std::string const &value)
void addDefault(ParameterSetDescription const &psetDescription)
std::string const & moduleLabel() const
std::string const & productInstanceName() const
ThinningProducer(ParameterSet const &pset)
edm::EDGetTokenT< Collection > inputToken_
virtual void produce(Event &event, EventSetup const &eventSetup) override
BranchID const & branchID() const
TypeWithDict const & unwrappedType() const
std::type_info const & typeInfo() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
Functor that operates on &lt;T&gt;
Definition: Selector.h:24
virtual void registerThinnedAssociations(ProductRegistry const &productRegistry, ThinnedAssociationsHelper &thinnedAssociationsHelper) override
BranchID const & originalBranchID() const
tuple inputCollection
static void fillDescriptions(ConfigurationDescriptions &descriptions)