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 
21 
22 #include <memory>
23 
24 namespace edm {
25 
26  class EventSetup;
27 
28  template <typename Collection, typename Selector>
30  public:
31  explicit ThinningProducer(ParameterSet const& pset);
32  virtual ~ThinningProducer();
33 
34  static void fillDescriptions(ConfigurationDescriptions & descriptions);
35 
36  virtual void produce(Event& event, EventSetup const& eventSetup) override;
37 
38  virtual void registerThinnedAssociations(ProductRegistry const& productRegistry,
39  ThinnedAssociationsHelper& thinnedAssociationsHelper) override;
40  private:
41  std::unique_ptr<Selector> selector_;
44  };
45 
46  template <typename Collection, typename Selector>
49  selector_(new Selector(pset, consumesCollector())) {
50 
51  inputTag_ = pset.getParameter<InputTag>("inputTag");
52  inputToken_ = consumes<Collection>(inputTag_);
53 
54  produces<Collection>();
55  produces<ThinnedAssociation>();
56  }
57 
58  template <typename Collection, typename Selector>
61 
62  template <typename Collection, typename Selector>
66  desc.setComment("Produces thinned collections and associations to them");
67  desc.add<edm::InputTag>("inputTag");
68  Selector::fillDescription(desc);
69  descriptions.addDefault(desc);
70  }
71 
72  template <typename Collection, typename Selector>
74  produce(Event& event, EventSetup const& eventSetup) {
75 
77  event.getByToken(inputToken_, inputCollection);
78 
79  edm::Event const& constEvent = event;
80  selector_->preChoose(inputCollection, constEvent, eventSetup);
81 
82  std::auto_ptr<Collection> thinnedCollection(new Collection);
83  std::auto_ptr<ThinnedAssociation> thinnedAssociation(new ThinnedAssociation);
84 
85  unsigned int iIndex = 0;
86  for(auto iter = inputCollection->begin(), iterEnd = inputCollection->end();
87  iter != iterEnd; ++iter, ++iIndex) {
88  if(selector_->choose(iIndex, *iter)) {
89  thinnedCollection->push_back(*iter);
90  thinnedAssociation->push_back(iIndex);
91  }
92  }
93  OrphanHandle<Collection> orphanHandle = event.put(thinnedCollection);
94 
95  thinnedAssociation->setParentCollectionID(inputCollection.id());
96  thinnedAssociation->setThinnedCollectionID(orphanHandle.id());
97  event.put(thinnedAssociation);
98  }
99 
100  template <typename Collection, typename Selector>
103  ThinnedAssociationsHelper& thinnedAssociationsHelper) {
104 
105  BranchID associationID;
106  BranchID thinnedCollectionID;
107 
108  // If the InputTag does not specify the process name, it is
109  // possible that there will be more than one match found below.
110  // For a particular event only one match is correct and the
111  // others will be false. It even possible for some events one
112  // match is correct and for others another is correct. This is
113  // a side effect of the lookup mechanisms when the process name
114  // is not specified.
115  // When using the registry this generates one would have to
116  // check the ProductIDs in ThinnedAssociation product to get
117  // the correct association. This ambiguity will probably be
118  // rare and possibly never occur in practice.
119  std::vector<BranchID> parentCollectionIDs;
120 
121  ProductRegistry::ProductList const& productList = productRegistry.productList();
122  for(auto const& product : productList) {
123  BranchDescription const& desc = product.second;
124  if(desc.unwrappedType().typeInfo() == typeid(Collection) ) {
125  if(desc.produced() &&
126  desc.moduleLabel() == moduleDescription().moduleLabel() &&
127  desc.productInstanceName().empty()) {
128 
129  thinnedCollectionID = desc.branchID();
130  }
131  if(desc.moduleLabel() == inputTag_.label() &&
132  desc.productInstanceName() == inputTag_.instance()) {
133  if(inputTag_.willSkipCurrentProcess()) {
134  if(!desc.produced()) {
135  parentCollectionIDs.push_back(desc.branchID());
136  }
137  } else if (inputTag_.process().empty() || inputTag_.process() == desc.processName()) {
138  if(desc.produced()) {
139  parentCollectionIDs.push_back(desc.originalBranchID());
140  } else {
141  parentCollectionIDs.push_back(desc.branchID());
142  }
143  }
144  }
145  }
146  if(desc.produced() &&
147  desc.unwrappedType().typeInfo() == typeid(ThinnedAssociation) &&
148  desc.moduleLabel() == moduleDescription().moduleLabel() &&
149  desc.productInstanceName().empty()) {
150 
151  associationID = desc.branchID();
152  }
153  }
154  if(parentCollectionIDs.empty()) {
155  // This could happen if the input collection was dropped. Go ahead and add
156  // an entry and let the exception be thrown only if the module is run (when
157  // it cannot find the product).
158  thinnedAssociationsHelper.addAssociation(BranchID(), associationID, thinnedCollectionID);
159  } else {
160  for(auto const& parentCollectionID : parentCollectionIDs) {
161  thinnedAssociationsHelper.addAssociation(parentCollectionID, associationID, thinnedCollectionID);
162  }
163  }
164  }
165 }
166 #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
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
std::unique_ptr< Selector > selector_
BranchID const & originalBranchID() const
static void fillDescriptions(ConfigurationDescriptions &descriptions)