CMS 3D CMS Logo

VersionedSelector.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_SelectorUtils_VersionedSelector_h
2 #define PhysicsTools_SelectorUtils_VersionedSelector_h
3 
14 #if (!defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__) && !defined(__CLING__))
15 
16 #define REGULAR_CPLUSPLUS 1
17 #define CINT_GUARD(CODE) CODE
19 #include <memory>
20 #define SHARED_PTR(T) std::shared_ptr<T>
21 
22 #else
23 
24 #define CINT_GUARD(CODE)
25 
26 #define SHARED_PTR(T) std::shared_ptr<T>
27 
28 #endif
29 
36 // because we need to be able to validate the ID
38 
39 namespace candf = candidate_functions;
40 
41 namespace vid {
42  class CutFlowResult;
43 }
44 
45 template <class T>
46 class VersionedSelector : public Selector<T> {
47 public:
49 
52 
53  name_ = conf.getParameter<std::string>("idName");
54 
55  // now setup the md5 and cute accessor functions
57  EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
58  const EVP_MD* md = EVP_get_digestbyname("MD5");
59  unsigned int md_len = 0;
60  std::string tracked(conf.trackedPart().dump());
61 
62  EVP_DigestInit_ex(mdctx, md, nullptr);
63  EVP_DigestUpdate(mdctx, tracked.c_str(), tracked.size());
64  EVP_DigestFinal_ex(mdctx, id_md5_, &md_len);
65  EVP_MD_CTX_free(mdctx);
66  id_md5_[md_len] = 0;
67  char tmp[EVP_MAX_MD_SIZE * 2 + 1];
68  for (unsigned int i = 0; i < md_len; i++) {
69  ::sprintf(&tmp[i * 2], "%02x", id_md5_[i]);
70  }
71  tmp[md_len * 2] = 0;
72  md5_string_ = tmp;
73  initialize(conf);
74  this->retInternal_ = this->getBitTemplate();
75  }
76 
77  bool operator()(const T& ref, pat::strbitset& ret) CINT_GUARD(final) {
78  howfar_ = 0;
79  bitmap_ = 0;
80  values_.clear();
81  bool failed = false;
82  if (!initialized_) {
83  throw cms::Exception("CutNotInitialized") << "VersionedGsfElectronSelector not initialized!" << std::endl;
84  }
85  for (unsigned i = 0; i < cuts_.size(); ++i) {
87  const bool result = (*cuts_[i])(temp);
88  values_.push_back(cuts_[i]->value(temp));
89  if (result || this->ignoreCut(cut_indices_[i])) {
90  this->passCut(ret, cut_indices_[i]);
91  bitmap_ |= 1 << i;
92  if (!failed)
93  ++howfar_;
94  } else {
95  failed = true;
96  }
97  }
98  this->setIgnored(ret);
99  return (bool)ret;
100  }
101 
102  bool operator()(const T& ref, edm::EventBase const& e, pat::strbitset& ret) CINT_GUARD(final) {
103  // setup isolation needs
104  for (size_t i = 0, cutssize = cuts_.size(); i < cutssize; ++i) {
105  if (needs_event_content_[i]) {
107  needsEvent->getEventContent(e);
108  }
109  }
110  return this->operator()(ref, ret);
111  }
112 
113  //repeat the other operator() we left out here
114  //in the base class here so they are exposed to ROOT
115 
116  /* VID BY VALUE */
117  bool operator()(typename T::value_type const& t) {
118  const T temp(&t, 0); // assuming T is edm::Ptr
119  return this->operator()(temp);
120  }
121 
122  bool operator()(typename T::value_type const& t, edm::EventBase const& e) {
123  const T temp(&t, 0);
124  return this->operator()(temp, e);
125  }
126 
127  bool operator()(T const& t) CINT_GUARD(final) {
128  this->retInternal_.set(false);
129  this->operator()(t, this->retInternal_);
130  this->setIgnored(this->retInternal_);
131  return (bool)this->retInternal_;
132  }
133 
134  bool operator()(T const& t, edm::EventBase const& e) CINT_GUARD(final) {
135  this->retInternal_.set(false);
136  this->operator()(t, e, this->retInternal_);
137  this->setIgnored(this->retInternal_);
138  return (bool)this->retInternal_;
139  }
140 
141  const unsigned char* md55Raw() const { return id_md5_; }
142  bool operator==(const VersionedSelector& other) const {
143  constexpr unsigned length = EVP_MAX_MD_SIZE;
144  return (0 == memcmp(id_md5_, other.id_md5_, length * sizeof(unsigned char)));
145  }
146  const std::string& md5String() const { return md5_string_; }
147 
148  const std::string& name() const { return name_; }
149 
150  const unsigned howFarInCutFlow() const { return howfar_; }
151 
152  const unsigned bitMap() const { return bitmap_; }
153 
154  const size_t cutFlowSize() const { return cuts_.size(); }
155 
157 
158  void initialize(const edm::ParameterSet&);
159 
161 
162 private:
163  //here we check that the parameters of the VID cuts are tracked
164  //we allow exactly one parameter to be untracked "isPOGApproved"
165  //as if its tracked, its a pain for the md5Sums
166  //due to the mechanics of PSets, it was demined easier just to
167  //create a new config which doesnt have an untracked isPOGApproved
168  //if isPOGApproved is tracked (if we decide to do that in the future), it keeps it
169  //see https://github.com/cms-sw/cmssw/issues/19799 for the discussion
170  static void validateParamsAreTracked(const edm::ParameterSet& conf) {
171  edm::ParameterSet trackedPart = conf.trackedPart();
172  edm::ParameterSet confWithoutIsPOGApproved;
173  for (auto& paraName : conf.getParameterNames()) {
174  if (paraName != "isPOGApproved")
175  confWithoutIsPOGApproved.copyFrom(conf, paraName);
176  else if (conf.existsAs<bool>(paraName, true))
177  confWithoutIsPOGApproved.copyFrom(conf, paraName); //adding isPOGApproved if its a tracked bool
178  }
179  std::string tracked(conf.trackedPart().dump()), untracked(confWithoutIsPOGApproved.dump());
180  if (tracked != untracked) {
181  throw cms::Exception("InvalidConfiguration") << "VersionedSelector does not allow untracked parameters"
182  << " in the cutflow ParameterSet!";
183  }
184  }
185 
186 protected:
188  std::vector<SHARED_PTR(candf::CandidateCut)> cuts_;
189  std::vector<bool> needs_event_content_;
190  std::vector<typename Selector<T>::index_type> cut_indices_;
191  unsigned howfar_, bitmap_;
192  std::vector<double> values_;
193 
194 private:
195  unsigned char id_md5_[EVP_MAX_MD_SIZE];
197 };
198 
199 template <class T>
201  if (initialized_) {
202  edm::LogWarning("VersionedPatElectronSelector") << "ID was already initialized!";
203  return;
204  }
205  const std::vector<edm::ParameterSet>& cutflow = conf.getParameterSetVector("cutFlow");
206  if (cutflow.empty()) {
207  throw cms::Exception("InvalidCutFlow") << "You have supplied a null/empty cutflow to VersionedIDSelector,"
208  << " please add content to the cuflow and try again.";
209  }
210 
211  // this lets us keep track of cuts without knowing what they are :D
212  std::vector<edm::ParameterSet>::const_iterator cbegin(cutflow.begin()), cend(cutflow.end());
213  std::vector<edm::ParameterSet>::const_iterator icut = cbegin;
214  std::map<std::string, unsigned> cut_counter;
215  std::vector<std::string> ignored_cuts;
216  for (; icut != cend; ++icut) {
217  std::stringstream realname;
218  const std::string& name = icut->getParameter<std::string>("cutName");
219  if (!cut_counter.count(name))
220  cut_counter[name] = 0;
221  realname << name << "_" << cut_counter[name];
222  const bool needsContent = icut->getParameter<bool>("needsAdditionalProducts");
223  const bool ignored = icut->getParameter<bool>("isIgnored");
224  CINT_GUARD(cuts_.emplace_back(CutApplicatorFactory::get()->create(name, *icut)));
225  needs_event_content_.push_back(needsContent);
226  const std::string therealname = realname.str();
227  this->push_back(therealname);
228  this->set(therealname);
229  if (ignored)
230  ignored_cuts.push_back(therealname);
231  cut_counter[name]++;
232  }
233  this->setIgnoredCuts(ignored_cuts);
234 
235  //have to loop again to set cut indices after all are filled
236  icut = cbegin;
237  cut_counter.clear();
238  for (; icut != cend; ++icut) {
239  std::stringstream realname;
240  const std::string& name = cuts_[std::distance(cbegin, icut)]->name();
241  if (!cut_counter.count(name))
242  cut_counter[name] = 0;
243  realname << name << "_" << cut_counter[name];
244  cut_indices_.push_back(typename Selector<T>::index_type(&(this->bits_), realname.str()));
245  cut_counter[name]++;
246  }
247 
248  initialized_ = true;
249 }
250 
251 #ifdef REGULAR_CPLUSPLUS
253 template <class T>
255  std::map<std::string, unsigned> names_to_index;
256  std::map<std::string, unsigned> cut_counter;
257  for (unsigned idx = 0; idx < cuts_.size(); ++idx) {
258  const std::string& name = cuts_[idx]->name();
259  if (!cut_counter.count(name))
260  cut_counter[name] = 0;
261  std::stringstream realname;
262  realname << name << "_" << cut_counter[name];
263  names_to_index.emplace(realname.str(), idx);
264  cut_counter[name]++;
265  }
266  return vid::CutFlowResult(name_, md5_string_, names_to_index, values_, bitmap_);
267 }
268 
270 template <class T>
272  for (size_t i = 0, cutssize = cuts_.size(); i < cutssize; ++i) {
273  if (needs_event_content_[i]) {
274  CutApplicatorWithEventContentBase* needsEvent = dynamic_cast<CutApplicatorWithEventContentBase*>(cuts_[i].get());
275  if (nullptr != needsEvent) {
276  needsEvent->setConsumes(cc);
277  } else {
278  throw cms::Exception("InvalidCutConfiguration") << "Cut: " << ((CutApplicatorBase*)cuts_[i].get())->name()
279  << " configured to consume event products but does not "
280  << " inherit from CutApplicatorWithEventContenBase "
281  << " please correct either your python or C++!";
282  }
283  }
284  }
285 }
286 #endif
287 
288 #endif
bool ignoreCut(std::string const &s) const
ignore the cut at index "s"
Definition: Selector.h:127
bool operator()(T const &t) final
This provides an alternative signature without the second ret.
void openssl_init()
Definition: openssl_init.cc:5
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool operator()(typename T::value_type const &t)
bool operator()(typename T::value_type const &t, edm::EventBase const &e)
std::vector< double > values_
ret
prodAgent to be discontinued
uint32_t cc[maxCellsPerHit]
Definition: gpuFishbone.h:49
const std::string & name() const
untracked
Definition: Types.py:34
ParameterSet trackedPart() const
const unsigned bitMap() const
void setIgnored(pat::strbitset &ret)
set ignored bits
Definition: Selector.h:181
std::vector< std::shared_ptr< candf::CandidateCut > > cuts_
pat::strbitset retInternal_
internal ret if users don&#39;t care about return bits
Definition: Selector.h:242
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:172
VersionedSelector(const edm::ParameterSet &conf)
#define EVP_MD_CTX_free
Definition: openssl_init.h:7
std::vector< bool > needs_event_content_
void copyFrom(ParameterSet const &from, std::string const &name)
void passCut(pat::strbitset &ret, std::string const &s)
Passing cuts.
Definition: Selector.h:142
void initialize(const edm::ParameterSet &)
virtual void getEventContent(const edm::EventBase &)=0
const std::string & md5String() const
#define EVP_MD_CTX_new
Definition: openssl_init.h:6
bool operator==(const VersionedSelector &other) const
const size_t cutFlowSize() const
vid::CutFlowResult cutFlowResult() const
Functor that operates on <T>
Definition: Selector.h:22
const unsigned char * md55Raw() const
pat::strbitset getBitTemplate() const
Get an empty bitset with the proper names.
Definition: Selector.h:168
bool operator()(const T &ref, edm::EventBase const &e, pat::strbitset &ret) final
This provides an alternative signature that includes extra information.
bool operator()(T const &t, edm::EventBase const &e) final
This provides an alternative signature that includes extra information.
strbitset & set(bool val=true)
set method of all bits
Definition: strbitset.h:126
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
void setConsumes(edm::ConsumesCollector)
VParameterSet const & getParameterSetVector(std::string const &name) const
std::string dump(unsigned int indent=0) const
#define CINT_GUARD(CODE)
#define get
Log< level::Warning, false > LogWarning
static void validateParamsAreTracked(const edm::ParameterSet &conf)
tmp
align.sh
Definition: createJobs.py:716
const unsigned howFarInCutFlow() const
long double T
std::vector< typename Selector< T >::index_type > cut_indices_
cut-flow versioning info in the event provenance
std::vector< std::string > getParameterNames() const
virtual void setConsumes(edm::ConsumesCollector &)=0
bool operator()(const T &ref, pat::strbitset &ret) final
This provides the interface for base classes to select objects.
unsigned char id_md5_[EVP_MAX_MD_SIZE]