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 
23 
24 #include <memory>
25 #include <optional>
26 #include <type_traits>
27 
28 namespace edm {
29 
30  class EventSetup;
31 
32  namespace detail {
33  template <typename T>
34  struct IsStdOptional {
35  static constexpr bool value = false;
36  };
37  template <typename T>
38  struct IsStdOptional<std::optional<T>> {
39  static constexpr bool value = true;
40  };
41 
42  template <typename Item, typename Selector, typename Collection>
43  void fillCollectionForThinning(Item const& item,
44  Selector& selector,
45  unsigned int iIndex,
46  Collection& output,
48  using SelectorChooseReturnType = decltype(selector.choose(0U, std::declval<Item const&>()));
50  if constexpr (isSlimming) {
51  std::optional<typename SelectorChooseReturnType::value_type> obj = selector.choose(iIndex, item);
52  if (obj.has_value()) {
53  // move to support std::unique_ptr<T> with edm::OwnVector<T> or std::vector<unique_ptr<T>>
54  output.push_back(std::move(*obj));
55  association.push_back(iIndex);
56  }
57  } else {
58  if (selector.choose(iIndex, item)) {
59  output.push_back(item);
60  association.push_back(iIndex);
61  }
62  }
63  }
64 
65  } // namespace detail
66 
67  template <typename Collection, typename Selector>
69  public:
70  explicit ThinningProducer(ParameterSet const& pset);
71  ~ThinningProducer() override;
72 
73  static void fillDescriptions(ConfigurationDescriptions& descriptions);
74 
75  void produce(Event& event, EventSetup const& eventSetup) override;
76 
77  void registerThinnedAssociations(ProductRegistry const& productRegistry,
78  ThinnedAssociationsHelper& thinnedAssociationsHelper) override;
79 
80  private:
86 
88  decltype(selector_->choose(0U, std::declval<typename detail::ElementType<Collection>::type const>()));
90  static_assert(
91  std::is_same_v<SelectorChooseReturnType, bool> || isSlimming,
92  "Selector::choose() must return bool (for pure thinning) or std::optional<ElementType> (for slimming)");
93  };
94 
95  template <typename Collection, typename Selector>
97  : selector_(new Selector(pset, consumesCollector())) {
98  inputTag_ = pset.getParameter<InputTag>("inputTag");
99  inputToken_ = consumes<Collection>(inputTag_);
100 
101  outputToken_ = produces<Collection>();
102  thinnedOutToken_ = produces<ThinnedAssociation>();
103  }
104 
105  template <typename Collection, typename Selector>
107 
108  template <typename Collection, typename Selector>
111  desc.setComment("Produces thinned collections and associations to them");
112  desc.add<edm::InputTag>("inputTag");
114  descriptions.addWithDefaultLabel(desc);
115  }
116 
117  template <typename Collection, typename Selector>
119  auto inputCollection = event.getHandle(inputToken_);
120 
121  edm::Event const& constEvent = event;
122  selector_->preChoose(inputCollection, constEvent, eventSetup);
123 
124  Collection thinnedCollection;
125  ThinnedAssociation thinnedAssociation;
126 
127  unsigned int iIndex = 0;
128  for (auto iter = inputCollection->begin(), iterEnd = inputCollection->end(); iter != iterEnd; ++iter, ++iIndex) {
129  using namespace detail;
130  fillCollectionForThinning(*iter, *selector_, iIndex, thinnedCollection, thinnedAssociation);
131  }
132  selector_->reset();
133 
134  OrphanHandle<Collection> orphanHandle = event.emplace(outputToken_, std::move(thinnedCollection));
135 
136  thinnedAssociation.setParentCollectionID(inputCollection.id());
137  thinnedAssociation.setThinnedCollectionID(orphanHandle.id());
138  event.emplace(thinnedOutToken_, std::move(thinnedAssociation));
139  }
140 
141  template <typename Collection, typename Selector>
143  ProductRegistry const& productRegistry, ThinnedAssociationsHelper& thinnedAssociationsHelper) {
144  BranchID associationID;
145  BranchID thinnedCollectionID;
146 
147  // If the InputTag does not specify the process name, it is
148  // possible that there will be more than one match found below.
149  // For a particular event only one match is correct and the
150  // others will be false. It even possible for some events one
151  // match is correct and for others another is correct. This is
152  // a side effect of the lookup mechanisms when the process name
153  // is not specified.
154  // When using the registry this generates one would have to
155  // check the ProductIDs in ThinnedAssociation product to get
156  // the correct association. This ambiguity will probably be
157  // rare and possibly never occur in practice.
158  std::vector<BranchID> parentCollectionIDs;
159 
160  ProductRegistry::ProductList const& productList = productRegistry.productList();
161  for (auto const& product : productList) {
162  BranchDescription const& desc = product.second;
163  if (desc.unwrappedType().typeInfo() == typeid(Collection)) {
164  if (desc.produced() && desc.moduleLabel() == moduleDescription().moduleLabel() &&
165  desc.productInstanceName().empty()) {
166  thinnedCollectionID = desc.branchID();
167  }
168  if (desc.moduleLabel() == inputTag_.label() && desc.productInstanceName() == inputTag_.instance()) {
169  if (inputTag_.willSkipCurrentProcess()) {
170  if (!desc.produced()) {
171  parentCollectionIDs.push_back(desc.branchID());
172  }
173  } else if (inputTag_.process().empty() || inputTag_.process() == desc.processName()) {
174  if (desc.produced()) {
175  parentCollectionIDs.push_back(desc.originalBranchID());
176  } else {
177  parentCollectionIDs.push_back(desc.branchID());
178  }
179  }
180  }
181  }
182  if (desc.produced() && desc.unwrappedType().typeInfo() == typeid(ThinnedAssociation) &&
183  desc.moduleLabel() == moduleDescription().moduleLabel() && desc.productInstanceName().empty()) {
184  associationID = desc.branchID();
185  }
186  }
187  if (parentCollectionIDs.empty()) {
188  // This could happen if the input collection was dropped. Go ahead and add
189  // an entry and let the exception be thrown only if the module is run (when
190  // it cannot find the product).
191  thinnedAssociationsHelper.addAssociation(BranchID(), associationID, thinnedCollectionID, isSlimming);
192  } else {
193  for (auto const& parentCollectionID : parentCollectionIDs) {
194  thinnedAssociationsHelper.addAssociation(parentCollectionID, associationID, thinnedCollectionID, isSlimming);
195  }
196  }
197  }
198 } // namespace edm
199 #endif
ConfigurationDescriptions.h
ThinnedAssociationsHelper.h
Handle.h
Selector
Functor that operates on <T>
Definition: Selector.h:22
edm::InputTag::instance
std::string const & instance() const
Definition: InputTag.h:37
propagate_const.h
convertSQLitetoXML_cfg.output
output
Definition: convertSQLitetoXML_cfg.py:72
edm::EDGetTokenT< Collection >
edm
HLT enums.
Definition: AlignableModifier.h:19
edm::EDPutTokenT< Collection >
edm::ParameterSetDescription
Definition: ParameterSetDescription.h:52
edm::ThinnedAssociation
Definition: ThinnedAssociation.h:15
Types.optional
optional
Definition: Types.py:199
EDProducer.h
edm::ThinningProducer
Definition: ThinningProducer.h:68
edm::InputTag::process
std::string const & process() const
Definition: InputTag.h:40
edm::ThinningProducer::outputToken_
edm::EDPutTokenT< Collection > outputToken_
Definition: ThinningProducer.h:84
edm::detail::fillCollectionForThinning
void fillCollectionForThinning(Item const &item, Selector &selector, unsigned int iIndex, Collection &output, ThinnedAssociation &association)
Definition: ThinningProducer.h:43
ProductRegistry.h
detail
Definition: ConvertingESProducerWithDependenciesT.h:23
edm::ThinningProducer::selector_
edm::propagate_const< std::unique_ptr< Selector > > selector_
Definition: ThinningProducer.h:81
edm::ThinnedAssociation::setThinnedCollectionID
void setThinnedCollectionID(ProductID const &v)
Definition: ThinnedAssociation.h:29
edm::ThinningProducer::ThinningProducer
ThinningProducer(ParameterSet const &pset)
Definition: ThinningProducer.h:96
edm::ThinningProducer::SelectorChooseReturnType
decltype(selector_->choose(0U, std::declval< typename detail::ElementType< Collection >::type const >())) SelectorChooseReturnType
Definition: ThinningProducer.h:88
edm::InputTag::willSkipCurrentProcess
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
edm::ProductRegistry
Definition: ProductRegistry.h:37
edm::InputTag::label
std::string const & label() const
Definition: InputTag.h:36
edm::ThinningProducer::inputToken_
edm::EDGetTokenT< Collection > inputToken_
Definition: ThinningProducer.h:82
edm::propagate_const
Definition: propagate_const.h:32
edm::detail::IsStdOptional
Definition: ThinningProducer.h:34
OrphanHandle.h
edm::BranchID
Definition: BranchID.h:14
edm::ThinningProducer::registerThinnedAssociations
void registerThinnedAssociations(ProductRegistry const &productRegistry, ThinnedAssociationsHelper &thinnedAssociationsHelper) override
Definition: ThinningProducer.h:142
fillCollectionForThinning.h
ParameterSetDescription.h
edm::detail::ElementType::type
typename std::remove_reference< decltype(*std::declval< Collection >().begin())>::type type
Definition: fillCollectionForThinning.h:17
EDGetToken.h
getGTfromDQMFile.obj
obj
Definition: getGTfromDQMFile.py:32
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
edm::ConfigurationDescriptions
Definition: ConfigurationDescriptions.h:28
edm::ThinnedAssociationsHelper
Definition: ThinnedAssociationsHelper.h:37
edm::ProductRegistry::ProductList
std::map< BranchKey, BranchDescription > ProductList
Definition: ProductRegistry.h:39
edm::ThinnedAssociation::setParentCollectionID
void setParentCollectionID(ProductID const &v)
Definition: ThinnedAssociation.h:28
edm::ParameterSet
Definition: ParameterSet.h:47
Event.h
edm::ThinnedAssociationsHelper::addAssociation
void addAssociation(BranchID const &, BranchID const &, BranchID const &, bool slimmed)
Definition: ThinnedAssociationsHelper.cc:61
HLT_FULL_cff.inputCollection
inputCollection
Definition: HLT_FULL_cff.py:11707
reco::modules::fillPSetDescription
void fillPSetDescription(edm::ParameterSetDescription &desc)
Definition: ParameterAdapter.h:34
edm::ThinningProducer::thinnedOutToken_
edm::EDPutTokenT< ThinnedAssociation > thinnedOutToken_
Definition: ThinningProducer.h:85
edm::ThinningProducer::produce
void produce(Event &event, EventSetup const &eventSetup) override
Definition: ThinningProducer.h:118
edmPickEvents.event
event
Definition: edmPickEvents.py:273
edm::ThinningProducer::inputTag_
edm::InputTag inputTag_
Definition: ThinningProducer.h:83
value
Definition: value.py:1
edm::stream::EDProducer
Definition: EDProducer.h:38
B2GTnPMonitor_cfi.item
item
Definition: B2GTnPMonitor_cfi.py:147
edm::EventSetup
Definition: EventSetup.h:58
InputTag.h
edm::OrphanHandleBase::id
ProductID id() const
Definition: OrphanHandleBase.cc:6
submitPVResolutionJobs.desc
string desc
Definition: submitPVResolutionJobs.py:251
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
edm::ProductRegistry::productList
ProductList const & productList() const
Definition: ProductRegistry.h:76
edm::OrphanHandle
Definition: EDProductfwd.h:39
hgcal::association
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
Definition: LayerClusterAssociatorByEnergyScoreImpl.h:44
edm::ThinningProducer::~ThinningProducer
~ThinningProducer() override
Definition: ThinningProducer.h:106
ThinnedAssociation.h
edm::BranchDescription
Definition: BranchDescription.h:32
EventSetup
ParameterSet.h
event
Definition: event.py:1
edm::Event
Definition: Event.h:73
edm::ThinningProducer::isSlimming
static constexpr bool isSlimming
Definition: ThinningProducer.h:89
edm::InputTag
Definition: InputTag.h:15
muonDTDigis_cfi.pset
pset
Definition: muonDTDigis_cfi.py:27
edm::ConfigurationDescriptions::addWithDefaultLabel
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
Definition: ConfigurationDescriptions.cc:87
edm::ThinningProducer::fillDescriptions
static void fillDescriptions(ConfigurationDescriptions &descriptions)
Definition: ThinningProducer.h:109