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