CMS 3D CMS Logo

MuonHLTSeedMVAClassifier.cc
Go to the documentation of this file.
1 
2 // Package: RecoMuon_TrackerSeedGenerator
3 // Class: MuonHLTSeedMVAClassifier
4 
5 // Original Author: Won Jun, OH Minseok
6 // Created: Fri, 28 May 2021
7 
8 // system include files
9 #include <memory>
10 #include <cmath>
11 #include <tinyxml2.h>
12 
13 // user include files
16 
19 
22 
23 // Geometry
26 
28 
29 // TrajectorySeed
36 
38 
39 // class declaration
40 bool sortByMvaScore(const std::pair<unsigned, double>& A, const std::pair<unsigned, double>& B) {
41  return (A.second > B.second);
42 };
43 
45 public:
47  ~MuonHLTSeedMVAClassifier() override = default;
48 
49  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
50  bool checkMVAFileConsistency(const std::string& weightsFileFullPath, bool isFromL1) const;
51 
52 private:
53  void produce(edm::Event&, const edm::EventSetup&) override;
54 
55  // member data
60 
61  typedef std::pair<std::unique_ptr<const SeedMvaEstimator>, std::unique_ptr<const SeedMvaEstimator>>
64 
65  const bool rejectAll_;
66  const bool isFromL1_;
67 
70 
71  const std::vector<double> mvaScaleMeanB_;
72  const std::vector<double> mvaScaleStdB_;
73  const std::vector<double> mvaScaleMeanE_;
74  const std::vector<double> mvaScaleStdE_;
75 
76  const bool doSort_;
77  const int nSeedsMaxB_;
78  const int nSeedsMaxE_;
79 
80  const double etaEdge_;
81  const double mvaCutB_;
82  const double mvaCutE_;
83 
84  const int minL1Qual_;
85  const double baseScore_;
86 
87  double getSeedMva(const PairSeedMvaEstimator& pairMvaEstimator,
88  const TrajectorySeed& seed,
89  const GlobalVector& global_p,
90  const l1t::MuonBxCollection& l1Muons,
92 };
93 
95  const bool isFromL1) const {
96  tinyxml2::XMLDocument xmlDoc;
97  if (reco::details::hasEnding(weightsFileFullPath, ".xml")) {
98  xmlDoc.LoadFile(weightsFileFullPath.c_str());
99  } else {
100  edm::LogError("MuonHLTSeedMVAClassifier") << "unsupported file extension, it should be a .xml file!";
101  return false;
102  }
103  tinyxml2::XMLElement* root = xmlDoc.FirstChildElement("MethodSetup");
104  if (root == nullptr) {
105  edm::LogError("MuonHLTSeedMVAClassifier") << "could not retrieve the MethodSetup node from XML file!";
106  return false;
107  }
108 
109  const auto& vars = root->FirstChildElement("Variables");
110  size_t n = 0;
111  if (vars != nullptr) {
112  for (tinyxml2::XMLElement* e = vars->FirstChildElement("Variable"); e != nullptr;
113  e = e->NextSiblingElement("Variable")) {
114  ++n;
115  }
116  } else {
117  edm::LogError("MuonHLTSeedMVAClassifier") << "could not retrieve the Variables node from XML file!";
118  return false;
119  }
120 
121  LogTrace("MuonHLTSeedMVAClassifier") << "MVA file:" << weightsFileFullPath.c_str() << " n Var:" << n;
122  bool condition = (isFromL1 && (n == inputIndexes::kLastL1)) || (!isFromL1 && (n == inputIndexes::kLastL2));
123  return condition;
124 }
125 
127  : seedToken_(consumes<TrajectorySeedCollection>(iConfig.getParameter<edm::InputTag>("src"))),
128  l1MuonToken_(consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("L1Muon"))),
129  l2MuonToken_(consumes<reco::RecoChargedCandidateCollection>(iConfig.getParameter<edm::InputTag>("L2Muon"))),
130  trackerGeometryToken_(esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>()),
131  rejectAll_(iConfig.getParameter<bool>("rejectAll")),
132  isFromL1_(iConfig.getParameter<bool>("isFromL1")),
133  mvaFileB_(iConfig.getParameter<edm::FileInPath>("mvaFileB")),
134  mvaFileE_(iConfig.getParameter<edm::FileInPath>("mvaFileE")),
135  mvaScaleMeanB_(iConfig.getParameter<std::vector<double>>("mvaScaleMeanB")),
136  mvaScaleStdB_(iConfig.getParameter<std::vector<double>>("mvaScaleStdB")),
137  mvaScaleMeanE_(iConfig.getParameter<std::vector<double>>("mvaScaleMeanE")),
138  mvaScaleStdE_(iConfig.getParameter<std::vector<double>>("mvaScaleStdE")),
139  doSort_(iConfig.getParameter<bool>("doSort")),
140  nSeedsMaxB_(iConfig.getParameter<int>("nSeedsMaxB")),
141  nSeedsMaxE_(iConfig.getParameter<int>("nSeedsMaxE")),
142  etaEdge_(iConfig.getParameter<double>("etaEdge")),
143  mvaCutB_(iConfig.getParameter<double>("mvaCutB")),
144  mvaCutE_(iConfig.getParameter<double>("mvaCutE")),
145  minL1Qual_(iConfig.getParameter<int>("minL1Qual")),
146  baseScore_(iConfig.getParameter<double>("baseScore")) {
147  const auto& mvaFileBPath = mvaFileB_.fullPath();
148  const auto& mvaFileEPath = mvaFileE_.fullPath();
149 
150  if (!checkMVAFileConsistency(mvaFileBPath, isFromL1_) || !checkMVAFileConsistency(mvaFileEPath, isFromL1_)) {
151  throw cms::Exception("ConfigurationError") << " MVA files appear to be not consistent with the value of isFromL1 "
152  "parameter.\n Please check your configuration.";
153  }
154 
155  if (!rejectAll_) {
156  mvaEstimator_ = std::make_pair(
157  std::make_unique<SeedMvaEstimator>(mvaFileB_, mvaScaleMeanB_, mvaScaleStdB_, isFromL1_, minL1Qual_),
158  std::make_unique<SeedMvaEstimator>(mvaFileE_, mvaScaleMeanE_, mvaScaleStdE_, isFromL1_, minL1Qual_));
159  }
160 
161  produces<TrajectorySeedCollection>();
162 }
163 
164 // -- method called on each new Event
166  auto result = std::make_unique<TrajectorySeedCollection>();
167 
168  if (rejectAll_) {
169  iEvent.put(std::move(result));
170  return;
171  }
172 
173  if (doSort_ && nSeedsMaxB_ <= 0 && nSeedsMaxE_ <= 0) {
174  iEvent.put(std::move(result));
175  return;
176  }
177 
178  if (!doSort_ && mvaCutB_ > 1. && mvaCutE_ > 1.) {
179  iEvent.put(std::move(result));
180  return;
181  }
182 
184  const l1t::MuonBxCollection& l1Muons = iEvent.get(l1MuonToken_);
186  const TrackerGeometry& trkGeom = iEventSetup.getData(trackerGeometryToken_);
187 
188  std::vector<std::pair<unsigned, double>> pairSeedIdxMvaScoreB = {};
189  std::vector<std::pair<unsigned, double>> pairSeedIdxMvaScoreE = {};
190  for (auto& seed : seeds) {
191  const GlobalVector global_p =
192  trkGeom.idToDet(seed.startingState().detId())->surface().toGlobal(seed.startingState().parameters().momentum());
193 
194  bool isB = (std::abs(global_p.eta()) < etaEdge_);
195 
196  if (doSort_) {
197  if (isB) {
198  if (nSeedsMaxB_ <= 0) {
199  continue;
200  }
201  } else {
202  if (nSeedsMaxE_ <= 0) {
203  continue;
204  }
205  }
206  } else {
207  if (isB) {
208  if (mvaCutB_ > 1.0) {
209  continue;
210  } else if (mvaCutB_ <= 0.) {
211  result->emplace_back(seed);
212  continue;
213  }
214  } else {
215  if (mvaCutE_ > 1.0) {
216  continue;
217  } else if (mvaCutE_ <= 0.) {
218  result->emplace_back(seed);
219  continue;
220  }
221  }
222  }
223 
224  double mva = getSeedMva(mvaEstimator_, seed, global_p, l1Muons, l2Muons);
225 
226  double score = 1. / (1. + std::exp(-1. * mva));
227  bool passMva = isB ? score > mvaCutB_ : score > mvaCutE_;
228  if (!passMva)
229  continue;
230 
231  if (doSort_) {
232  if (isB)
233  pairSeedIdxMvaScoreB.push_back(std::make_pair(&seed - &seeds.at(0), score));
234  else
235  pairSeedIdxMvaScoreE.push_back(std::make_pair(&seed - &seeds.at(0), score));
236  } else {
237  result->emplace_back(seed);
238  }
239  }
240 
241  if (doSort_) {
242  std::sort(pairSeedIdxMvaScoreB.begin(), pairSeedIdxMvaScoreB.end(), sortByMvaScore);
243  std::sort(pairSeedIdxMvaScoreE.begin(), pairSeedIdxMvaScoreE.end(), sortByMvaScore);
244 
245  for (auto i = 0U; i < pairSeedIdxMvaScoreB.size(); ++i) {
246  if ((int)i == nSeedsMaxB_)
247  break;
248  const auto& seed(seeds.at(pairSeedIdxMvaScoreB.at(i).first));
249  result->emplace_back(seed);
250  }
251 
252  for (auto i = 0U; i < pairSeedIdxMvaScoreE.size(); ++i) {
253  if ((int)i == nSeedsMaxE_)
254  break;
255  const auto& seed(seeds.at(pairSeedIdxMvaScoreE.at(i).first));
256  result->emplace_back(seed);
257  }
258  }
259 
260  iEvent.put(std::move(result));
261 }
262 
264  const TrajectorySeed& seed,
265  const GlobalVector& global_p,
266  const l1t::MuonBxCollection& l1Muons,
267  const reco::RecoChargedCandidateCollection& l2Muons) {
268  double mva = 0.;
269  if (std::abs(global_p.eta()) < etaEdge_) {
270  mva = pairMvaEstimator.first->computeMva(seed, global_p, l1Muons, l2Muons);
271  } else {
272  mva = pairMvaEstimator.second->computeMva(seed, global_p, l1Muons, l2Muons);
273  }
274 
275  return (mva + baseScore_);
276 }
277 
278 // -- method fills 'descriptions' with the allowed parameters for the module ------------
281  desc.add<edm::InputTag>("src", edm::InputTag("hltIter2IterL3MuonPixelSeeds", ""));
282  desc.add<edm::InputTag>("L1Muon", edm::InputTag("hltGtStage2Digis", "Muon"));
283  desc.add<edm::InputTag>("L2Muon", edm::InputTag("hltL2MuonCandidates", ""));
284 
285  desc.add<bool>("rejectAll", false);
286  desc.add<bool>("isFromL1", false);
287 
288  desc.add<edm::FileInPath>("mvaFileB",
289  edm::FileInPath("RecoMuon/TrackerSeedGenerator/data/xgb_Run3_Iter2FromL1Seeds_barrel.xml"));
290  desc.add<edm::FileInPath>("mvaFileE",
291  edm::FileInPath("RecoMuon/TrackerSeedGenerator/data/xgb_Run3_Iter2FromL1Seeds_endcap.xml"));
292  desc.add<std::vector<double>>("mvaScaleMeanB", {0., 0., 0., 0., 0., 0., 0., 0.});
293  desc.add<std::vector<double>>("mvaScaleStdB", {1., 1., 1., 1., 1., 1., 1., 1.});
294  desc.add<std::vector<double>>("mvaScaleMeanE", {0., 0., 0., 0., 0., 0., 0., 0.});
295  desc.add<std::vector<double>>("mvaScaleStdE", {1., 1., 1., 1., 1., 1., 1., 1.});
296 
297  desc.add<bool>("doSort", false);
298  desc.add<int>("nSeedsMaxB", 1e6);
299  desc.add<int>("nSeedsMaxE", 1e6);
300 
301  desc.add<double>("etaEdge", 1.2);
302  desc.add<double>("mvaCutB", -1.);
303  desc.add<double>("mvaCutE", -1.);
304 
305  desc.add<int>("minL1Qual", 7);
306  desc.add<double>("baseScore", 0.5);
307 
308  descriptions.add("MuonHLTSeedMVAClassifier", desc);
309 }
310 
311 //define this as a plug-in
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
Definition: APVGainStruct.h:7
bool hasEnding(std::string const &fullString, std::string const &ending)
std::string fullPath() const
Definition: FileInPath.cc:161
vars
Definition: DeepTauIdBase.h:60
void produce(edm::Event &, const edm::EventSetup &) override
T eta() const
Definition: PV3DBase.h:73
const std::vector< double > mvaScaleStdB_
MuonHLTSeedMVAClassifier(const edm::ParameterSet &)
delete x;
Definition: CaloConfig.h:22
const std::vector< double > mvaScaleMeanB_
Log< level::Error, false > LogError
double getSeedMva(const PairSeedMvaEstimator &pairMvaEstimator, const TrajectorySeed &seed, const GlobalVector &global_p, const l1t::MuonBxCollection &l1Muons, const reco::RecoChargedCandidateCollection &l2Muons)
#define LogTrace(id)
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryToken_
int iEvent
Definition: GenABIO.cc:224
const edm::EDGetTokenT< l1t::MuonBxCollection > l1MuonToken_
std::vector< TrajectorySeed > TrajectorySeedCollection
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
~MuonHLTSeedMVAClassifier() override=default
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const TrackerGeomDet * idToDet(DetId) const override
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
BXVector< Muon > MuonBxCollection
Definition: Muon.h:11
std::vector< RecoChargedCandidate > RecoChargedCandidateCollection
collectin of RecoChargedCandidate objects
bool checkMVAFileConsistency(const std::string &weightsFileFullPath, bool isFromL1) const
PairSeedMvaEstimator mvaEstimator_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::pair< std::unique_ptr< const SeedMvaEstimator >, std::unique_ptr< const SeedMvaEstimator > > PairSeedMvaEstimator
fixed size matrix
HLT enums.
bool sortByMvaScore(const std::pair< unsigned, double > &A, const std::pair< unsigned, double > &B)
Definition: APVGainStruct.h:7
const std::vector< double > mvaScaleMeanE_
def move(src, dest)
Definition: eostools.py:511
const std::vector< double > mvaScaleStdE_
const edm::EDGetTokenT< TrajectorySeedCollection > seedToken_
const edm::EDGetTokenT< reco::RecoChargedCandidateCollection > l2MuonToken_