CMS 3D CMS Logo

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 
42  private:
48  };
49 
50  template <typename Collection, typename Selector>
52  : selector_(new Selector(pset, consumesCollector())) {
53  inputTag_ = pset.getParameter<InputTag>("inputTag");
54  inputToken_ = consumes<Collection>(inputTag_);
55 
56  outputToken_ = produces<Collection>();
57  thinnedOutToken_ = produces<ThinnedAssociation>();
58  }
59 
60  template <typename Collection, typename Selector>
62 
63  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  auto inputCollection = event.getHandle(inputToken_);
75 
76  edm::Event const& constEvent = event;
77  selector_->preChoose(inputCollection, constEvent, eventSetup);
78 
79  Collection thinnedCollection;
80  ThinnedAssociation thinnedAssociation;
81 
82  unsigned int iIndex = 0;
83  for (auto iter = inputCollection->begin(), iterEnd = inputCollection->end(); iter != iterEnd; ++iter, ++iIndex) {
84  if (selector_->choose(iIndex, *iter)) {
85  thinnedCollection.push_back(*iter);
86  thinnedAssociation.push_back(iIndex);
87  }
88  }
89  OrphanHandle<Collection> orphanHandle = event.emplace(outputToken_, std::move(thinnedCollection));
90 
91  thinnedAssociation.setParentCollectionID(inputCollection.id());
92  thinnedAssociation.setThinnedCollectionID(orphanHandle.id());
93  event.emplace(thinnedOutToken_, std::move(thinnedAssociation));
94  }
95 
96  template <typename Collection, typename Selector>
98  ProductRegistry const& productRegistry, ThinnedAssociationsHelper& thinnedAssociationsHelper) {
99  BranchID associationID;
100  BranchID thinnedCollectionID;
101 
102  // If the InputTag does not specify the process name, it is
103  // possible that there will be more than one match found below.
104  // For a particular event only one match is correct and the
105  // others will be false. It even possible for some events one
106  // match is correct and for others another is correct. This is
107  // a side effect of the lookup mechanisms when the process name
108  // is not specified.
109  // When using the registry this generates one would have to
110  // check the ProductIDs in ThinnedAssociation product to get
111  // the correct association. This ambiguity will probably be
112  // rare and possibly never occur in practice.
113  std::vector<BranchID> parentCollectionIDs;
114 
115  ProductRegistry::ProductList const& productList = productRegistry.productList();
116  for (auto const& product : productList) {
117  BranchDescription const& desc = product.second;
118  if (desc.unwrappedType().typeInfo() == typeid(Collection)) {
119  if (desc.produced() && desc.moduleLabel() == moduleDescription().moduleLabel() &&
120  desc.productInstanceName().empty()) {
121  thinnedCollectionID = desc.branchID();
122  }
123  if (desc.moduleLabel() == inputTag_.label() && desc.productInstanceName() == inputTag_.instance()) {
125  if (!desc.produced()) {
126  parentCollectionIDs.push_back(desc.branchID());
127  }
128  } else if (inputTag_.process().empty() || inputTag_.process() == desc.processName()) {
129  if (desc.produced()) {
130  parentCollectionIDs.push_back(desc.originalBranchID());
131  } else {
132  parentCollectionIDs.push_back(desc.branchID());
133  }
134  }
135  }
136  }
137  if (desc.produced() && desc.unwrappedType().typeInfo() == typeid(ThinnedAssociation) &&
138  desc.moduleLabel() == moduleDescription().moduleLabel() && desc.productInstanceName().empty()) {
139  associationID = desc.branchID();
140  }
141  }
142  if (parentCollectionIDs.empty()) {
143  // This could happen if the input collection was dropped. Go ahead and add
144  // an entry and let the exception be thrown only if the module is run (when
145  // it cannot find the product).
146  thinnedAssociationsHelper.addAssociation(BranchID(), associationID, thinnedCollectionID);
147  } else {
148  for (auto const& parentCollectionID : parentCollectionIDs) {
149  thinnedAssociationsHelper.addAssociation(parentCollectionID, associationID, thinnedCollectionID);
150  }
151  }
152  }
153 } // namespace edm
154 #endif
T getParameter(std::string const &) const
void addAssociation(BranchID const &, BranchID const &, BranchID const &)
void setThinnedCollectionID(ProductID const &v)
std::map< BranchKey, BranchDescription > ProductList
std::string const & processName() const
edm::propagate_const< std::unique_ptr< Selector > > selector_
ProductID id() const
edm::EDPutTokenT< Collection > outputToken_
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_
edm::EDPutTokenT< ThinnedAssociation > thinnedOutToken_
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 <T>
Definition: Selector.h:22
void push_back(unsigned int index)
virtual void registerThinnedAssociations(ProductRegistry const &productRegistry, ThinnedAssociationsHelper &thinnedAssociationsHelper) override
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
void setParentCollectionID(ProductID const &v)
std::string const & label() const
Definition: InputTag.h:36
std::string const & process() const
Definition: InputTag.h:40
HLT enums.
BranchID const & originalBranchID() const
static void fillDescriptions(ConfigurationDescriptions &descriptions)
std::string const & instance() const
Definition: InputTag.h:37
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1