CMS 3D CMS Logo

DisplacedRegionSeedingVertexProducer.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <limits>
3 #include <string>
4 #include <atomic>
5 
16 
23 
25 
27 
28 using namespace std;
31 
33 public:
36  void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
38 
39 private:
40  // clustering parameters
41  const double rParam_;
42 
43  // selection parameters
44  const double minRadius_;
45  const double nearThreshold_;
46  const double farThreshold_;
47  const double discriminatorCut_;
48  const unsigned int maxPseudoROIs_;
49  const vector<string> input_names_;
50  const vector<string> output_names_;
51 
54 
55  tensorflow::Session *session_;
56 
57  double getDiscriminatorValue(const DisplacedVertexCluster &, const reco::BeamSpot &) const;
58 };
59 
61  : rParam_(cfg.getParameter<double>("rParam")),
62  minRadius_(cfg.getParameter<double>("minRadius")),
63  nearThreshold_(cfg.getParameter<double>("nearThreshold")),
64  farThreshold_(cfg.getParameter<double>("farThreshold")),
65  discriminatorCut_(cfg.getParameter<double>("discriminatorCut")),
66  maxPseudoROIs_(cfg.getParameter<unsigned int>("maxPseudoROIs")),
67  input_names_(cfg.getParameter<vector<string> >("input_names")),
68  output_names_(cfg.getParameter<vector<string> >("output_names")),
69  beamSpotToken_(consumes<reco::BeamSpot>(cfg.getParameter<edm::InputTag>("beamSpot"))),
70  trackClustersToken_(
71  consumes<edm::View<reco::VertexCompositeCandidate> >(cfg.getParameter<edm::InputTag>("trackClusters"))) {
72  unsigned nThreads = cfg.getUntrackedParameter<unsigned>("nThreads");
74  options.setThreading(nThreads);
75  string pbFile = cfg.getParameter<edm::FileInPath>("graph_path").fullPath();
76  auto graphDef = tensorflow::loadGraphDef(pbFile);
78 
79  produces<vector<reco::Vertex> >("nearRegionsOfInterest");
80  produces<vector<reco::Vertex> >("farRegionsOfInterest");
81 }
82 
84  if (session_ != nullptr)
86 }
87 
90  const edm::EventSetup &setup) const {
91  const auto &beamSpot = event.get(beamSpotToken_);
92  const math::XYZVector bs(beamSpot.position());
93 
94  const auto &trackClusters = event.get(trackClustersToken_);
95 
96  // Initialize distances.
97  vector<DisplacedVertexCluster> pseudoROIs;
98  pseudoROIs.reserve(std::min(maxPseudoROIs_, trackClusters.size()));
99  vector<Distance> distances;
100  const double minTrackClusterRadius = minRadius_ - rParam_;
101  for (unsigned i = 0; i < trackClusters.size(); i++) {
102  const reco::VertexCompositeCandidate &trackCluster = trackClusters[i];
103  const math::XYZVector x(trackCluster.vertex());
104  if (minRadius_ < 0.0 || minTrackClusterRadius < 0.0 || (x - bs).rho() > minTrackClusterRadius)
105  pseudoROIs.emplace_back(&trackClusters.at(i), rParam_);
106  if (pseudoROIs.size() == maxPseudoROIs_) {
107  edm::LogWarning("DisplacedRegionSeedingVertexProducer")
108  << "Truncated list of pseudoROIs at " << maxPseudoROIs_ << " out of " << trackClusters.size()
109  << " possible track clusters.";
110  break;
111  }
112  }
113  if (pseudoROIs.size() > 1) {
114  distances.reserve(pseudoROIs.size() * std::max(1.0, pseudoROIs.size() * 0.05));
115  DisplacedVertexClusterItr secondToLast = pseudoROIs.end();
116  secondToLast--;
117  for (DisplacedVertexClusterItr i = pseudoROIs.begin(); i != secondToLast; i++) {
119  j++;
120  for (; j != pseudoROIs.end(); j++) {
121  distances.emplace_back(i, j);
122 
123  // Track clusters farther apart than 4 times rParam_ (i.e., 16 times
124  // rParam_^2) cannot wind up in the same ROI, so remove these pairs.
125  if (distances.back().distance2() > 16.0 * rParam_ * rParam_)
126  distances.pop_back();
127  }
128  }
129  }
130 
131  auto itBegin = distances.begin();
132  auto itLast = distances.end();
133 
134  // Do clustering.
135  while (itBegin != itLast) {
136  //find the lowest distance. Lots of repeatitive calculations done here
137  //as from loop iteration to loop iteration only sqrt(distances.size()) distances
138  //need to be recomputed (those involving best_i
139  //but this is much better than sorting distances..
140  DistanceItr dBest = itBegin;
141  double distanceBest = dBest->distance2();
142 
143  for (auto i = itBegin; i != itLast; i++) {
144  if (distanceBest > i->distance2()) {
145  dBest = i;
146  distanceBest = i->distance2();
147  }
148  }
149 
150  if (dBest->distance2() > rParam_ * rParam_)
151  break;
152 
153  dBest->entities().first->merge(*dBest->entities().second);
154  dBest->entities().second->setInvalid();
155 
156  const auto distancePred = [](const Distance &a) {
157  return (!a.entities().first->valid() || !a.entities().second->valid());
158  };
159  itLast = std::remove_if(itBegin, itLast, distancePred);
160  }
161 
162  const auto pseudoROIPred = [](const DisplacedVertexCluster &a) { return !a.valid(); };
163  auto remove_invalid = std::remove_if(pseudoROIs.begin(), pseudoROIs.end(), pseudoROIPred);
164 
165  // Remove invalid ROIs.
166  const auto roiPred = [&](const DisplacedVertexCluster &roi) {
167  if (!roi.valid())
168  return true;
169  const auto &x(roi.centerOfMass());
170  if ((x - bs).rho() < minRadius_)
171  return true;
172  const double discriminatorValue = ((discriminatorCut_ > 0.0) ? getDiscriminatorValue(roi, beamSpot) : 1.0);
173  if (discriminatorValue < discriminatorCut_)
174  return true;
175  return false;
176  };
177  auto remove_pred = std::remove_if(pseudoROIs.begin(), remove_invalid, roiPred);
178 
179  auto nearRegionsOfInterest = make_unique<vector<reco::Vertex> >();
180  auto farRegionsOfInterest = make_unique<vector<reco::Vertex> >();
181 
182  constexpr std::array<double, 6> errorA{{1.0, 0.0, 1.0, 0.0, 0.0, 1.0}};
183  static const reco::Vertex::Error errorRegion(errorA.begin(), errorA.end(), true, true);
184 
185  for (auto it = pseudoROIs.begin(); it != remove_pred; ++it) {
186  auto const &roi = *it;
187  const auto &x(roi.centerOfMass());
188  if ((x - bs).rho() < nearThreshold_)
189  nearRegionsOfInterest->emplace_back(reco::Vertex::Point(roi.centerOfMass()), errorRegion);
190  if ((x - bs).rho() > farThreshold_)
191  farRegionsOfInterest->emplace_back(reco::Vertex::Point(roi.centerOfMass()), errorRegion);
192  }
193 
194  event.put(std::move(nearRegionsOfInterest), "nearRegionsOfInterest");
195  event.put(std::move(farRegionsOfInterest), "farRegionsOfInterest");
196 }
197 
200 
201  desc.add<double>("rParam", 1.0);
202  desc.add<double>("minRadius", -1.0);
203  desc.add<double>("nearThreshold", 9999.0);
204  desc.add<double>("farThreshold", -1.0);
205  desc.add<double>("discriminatorCut", -1.0);
206  desc.add<vector<string> >("input_names", {"phi_0", "phi_1"});
207  desc.add<vector<string> >("output_names", {"model_5/activation_10/Softmax"});
208  desc.add<unsigned int>("maxPseudoROIs", 10000);
209  desc.addUntracked<unsigned>("nThreads", 1);
210  desc.add<edm::FileInPath>(
211  "graph_path",
213  "RecoTracker/DisplacedRegionalTracking/data/FullData_Phi-64-128-256_16-32-64_F-128-64-32_Model.pb"));
214  desc.add<edm::InputTag>("beamSpot", edm::InputTag("offlineBeamSpot"));
215  desc.add<edm::InputTag>("trackClusters", edm::InputTag("generalV0Candidates", "Kshort"));
216 
217  descriptions.add("displacedRegionProducer", desc);
218 }
219 
221  const reco::BeamSpot &bs) const {
222  // The network takes in two maps of data features, one with information
223  // related to the pairwise track vertices and one with information related to
224  // the tracks in an isolation annulus.
225 
226  constexpr int maxNVertices = 40; // maximum number of pairwise track vertices per ROI
227  constexpr int nVertexFeatures = 23; // number of features per pairwise track vertex
228  constexpr int nDimVertices = 3; // number of tensor dimensions for the map of pairwise track vertices
229 
230  constexpr int maxNAnnulusTracks = 10; // maximum number of annulus tracks per ROI
231  constexpr int nAnnulusTrackFeatures = 8; // number of features per annulus track
232  constexpr int nDimAnnulusTracks = 3; // number of tensor dimensions for the map of annulus tracks
233 
234  tensorflow::Tensor vertexTensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, maxNVertices, nVertexFeatures}));
235  auto vertex_map = vertexTensor.tensor<float, nDimVertices>();
236  tensorflow::Tensor annulusTensor(tensorflow::DT_FLOAT,
237  tensorflow::TensorShape({1, maxNAnnulusTracks, nAnnulusTrackFeatures}));
238  auto annulus_map = annulusTensor.tensor<float, nDimAnnulusTracks>();
239 
240  for (int i = 0, map_i = 0; map_i < maxNVertices; i++, map_i++) {
241  if (i >= static_cast<int>(roi.nConstituents()))
242  for (unsigned j = 0; j < nVertexFeatures; j++)
243  vertex_map(0, map_i, j) = 0.0;
244  else {
245  const auto &trackCluster = *roi.constituent(i);
246  const auto &track0 = *trackCluster.daughter(0)->bestTrack();
247  const auto &track1 = *trackCluster.daughter(1)->bestTrack();
248 
249  vertex_map(0, map_i, 0) = trackCluster.vx() - bs.x0();
250  vertex_map(0, map_i, 1) = trackCluster.vy() - bs.y0();
251  vertex_map(0, map_i, 2) = trackCluster.vz() - bs.z0();
252 
253  vertex_map(0, map_i, 3) = trackCluster.vertexCovariance()(0, 0);
254  vertex_map(0, map_i, 4) = trackCluster.vertexCovariance()(0, 1);
255  vertex_map(0, map_i, 5) = trackCluster.vertexCovariance()(0, 2);
256  vertex_map(0, map_i, 6) = trackCluster.vertexCovariance()(1, 1);
257  vertex_map(0, map_i, 7) = trackCluster.vertexCovariance()(1, 2);
258  vertex_map(0, map_i, 8) = trackCluster.vertexCovariance()(2, 2);
259 
260  vertex_map(0, map_i, 9) = track0.charge() * track0.pt();
261  vertex_map(0, map_i, 10) = track0.eta();
262  vertex_map(0, map_i, 11) = track0.phi();
263  vertex_map(0, map_i, 12) = track0.dxy(bs);
264  vertex_map(0, map_i, 13) = track0.dz(bs.position());
265  vertex_map(0, map_i, 14) = track0.normalizedChi2();
266  vertex_map(0, map_i, 15) = track0.quality(reco::Track::highPurity) ? 1 : 0;
267 
268  vertex_map(0, map_i, 16) = track1.charge() * track1.pt();
269  vertex_map(0, map_i, 17) = track1.eta();
270  vertex_map(0, map_i, 18) = track1.phi();
271  vertex_map(0, map_i, 19) = track1.dxy(bs);
272  vertex_map(0, map_i, 20) = track1.dz(bs.position());
273  vertex_map(0, map_i, 21) = track1.normalizedChi2();
274  vertex_map(0, map_i, 22) = track1.quality(reco::Track::highPurity) ? 1 : 0;
275  }
276  }
277 
278  for (int i = 0; i < maxNAnnulusTracks; i++)
279  for (unsigned j = 0; j < nAnnulusTrackFeatures; j++)
280  annulus_map(0, i, j) = 0.0;
281 
282  tensorflow::NamedTensorList input_tensors;
283  input_tensors.resize(2);
284  input_tensors[0] = tensorflow::NamedTensor(input_names_.at(0), vertexTensor);
285  input_tensors[1] = tensorflow::NamedTensor(input_names_.at(1), annulusTensor);
286  vector<tensorflow::Tensor> outputs;
287  tensorflow::run(session_, input_tensors, output_names_, &outputs);
288 
289  return (outputs.at(0).flat<float>()(1));
290 }
291 
const Candidate * daughter(size_type) const override
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
std::vector< NamedTensor > NamedTensorList
Definition: TensorFlow.h:31
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:655
GraphDef * loadGraphDef(const std::string &pbFile)
Definition: TensorFlow.cc:120
std::vector< DisplacedVertexCluster >::iterator DisplacedVertexClusterItr
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:45
const Point & vertex() const override
vertex position (overwritten by PF...)
std::pair< std::string, Tensor > NamedTensor
Definition: TensorFlow.h:30
const reco::VertexCompositeCandidate * constituent(const unsigned i) const
DisplacedVertexCluster::DistanceItr DistanceItr
std::vector< Distance >::iterator DistanceItr
DisplacedVertexCluster::Distance Distance
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:272
bool closeSession(Session *&session)
Definition: TensorFlow.cc:234
math::XYZPoint Point
point in the space
Definition: Vertex.h:40
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Session * createSession()
Definition: TensorFlow.cc:137
static void fillDescriptions(edm::ConfigurationDescriptions &)
const edm::EDGetTokenT< edm::View< reco::VertexCompositeCandidate > > trackClustersToken_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
double getDiscriminatorValue(const DisplacedVertexCluster &, const reco::BeamSpot &) const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const edm::EDGetTokenT< reco::BeamSpot > beamSpotToken_
fixed size matrix
HLT enums.
double a
Definition: hdecay.h:121
virtual const Track * bestTrack() const
Definition: Candidate.h:268
Log< level::Warning, false > LogWarning
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1