CMS 3D CMS Logo

MultiVertexFitter.cc
Go to the documentation of this file.
2 // #include "Vertex/VertexPrimitives/interface/TransientVertex.h"
3 #include <map>
4 #include <algorithm>
5 #include <iomanip>
6 // #include "Vertex/VertexRecoAnalysis/interface/RecTrackNamer.h"
7 // #include "Vertex/MultiVertexFit/interface/TransientVertexNamer.h"
14 
15 // #define MVFHarvestingDebug
16 #ifdef MVFHarvestingDebug
17 #include "Vertex/VertexSimpleVis/interface/PrimitivesHarvester.h"
18 #endif
19 
20 using namespace std;
21 using namespace reco;
22 
23 namespace {
24  typedef MultiVertexFitter::TrackAndWeight TrackAndWeight;
25  typedef MultiVertexFitter::TrackAndSeedToWeightMap TrackAndSeedToWeightMap;
26  typedef MultiVertexFitter::SeedToWeightMap SeedToWeightMap;
27  typedef CachingVertex<5>::RefCountedVertexTrack RefCountedVertexTrack;
28 
29  int verbose() {
30  static const int ret = 0; /*SimpleConfigurable<int>
31  (0, "MultiVertexFitter:Debug").value(); */
32  return ret;
33  }
34 
35  double minWeightFraction() {
36  // minimum weight that a track has to have
37  // in order to be taken into account for the
38  // vertex fit.
39  // Given as a fraction of the total weight.
40  static const float ret = 1e-6; /* SimpleConfigurable<float>
41  (1e-6, "MultiVertexFitter:MinimumWeightFraction").value(); */
42  return ret;
43  }
44 
45  bool discardLightWeights() {
46  static const bool ret = true; /* SimpleConfigurable<bool>
47  (true, "MultiVertexFitter:DiscardLightWeights").value();*/
48  return ret;
49  }
50 
51  /*
52  struct CompareRaveTracks
53  {
54  bool operator() ( const TransientTrack & r1,
55  const TransientTrack & r2 ) const
56  {
57  return r1 < r2;
58  };
59  }*/
60 
61  CachingVertex<5> createSeedFromLinPt(const GlobalPoint &gp) {
62  return CachingVertex<5>(gp, GlobalError(), vector<RefCountedVertexTrack>(), 0.0);
63  }
64 
65  double validWeight(double weight) {
66  if (weight > 1.0) {
67  cout << "[MultiVertexFitter] weight=" << weight << "??" << endl;
68  return 1.0;
69  };
70 
71  if (weight < 0.0) {
72  cout << "[MultiVertexFitter] weight=" << weight << "??" << endl;
73  return 0.0;
74  };
75  return weight;
76  }
77 } // namespace
78 
80  theAssComp->resetAnnealing();
81  theTracks.clear();
82  thePrimaries.clear();
83  theVertexStates.clear();
84  theWeights.clear();
85  theCache.clear();
86 }
87 
88 // creates the seed, additionally it pushes all tracks
89 // onto theTracks
90 
91 void MultiVertexFitter::createSeed(const vector<TransientTrack> &tracks) {
92  if (tracks.size() > 1) {
93  CachingVertex<5> vtx = createSeedFromLinPt(theSeeder->getLinearizationPoint(tracks));
94  int snr = seedNr();
95  theVertexStates.push_back(pair<int, CachingVertex<5> >(snr, vtx));
96  for (vector<TransientTrack>::const_iterator track = tracks.begin(); track != tracks.end(); ++track) {
97  theWeights[*track][snr] = 1.;
98  theTracks.push_back(*track);
99  };
100  };
101 }
102 
103 void MultiVertexFitter::createPrimaries(const std::vector<reco::TransientTrack> &tracks) {
104  // cout << "[MultiVertexFitter] creating primaries: ";
105  for (vector<reco::TransientTrack>::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
106  thePrimaries.insert(*i);
107  // cout << i->id() << " ";
108  }
109  // cout << endl;
110 }
111 
112 int MultiVertexFitter::seedNr() { return theVertexStateNr++; }
113 
114 void MultiVertexFitter::resetSeedNr() { theVertexStateNr = 0; }
115 
116 void MultiVertexFitter::createSeed(const vector<TrackAndWeight> &tracks) {
117  // create initial seed for every bundle
118  vector<RefCountedVertexTrack> newTracks;
119 
120  for (vector<TrackAndWeight>::const_iterator track = tracks.begin(); track != tracks.end(); ++track) {
121  double weight = validWeight(track->second);
122  const GlobalPoint &pos = track->first.impactPointState().globalPosition();
123  GlobalError err; // FIXME
124  VertexState realseed(pos, err);
125 
126  RefCountedLinearizedTrackState lTrData = theCache.linTrack(pos, track->first);
127 
128  VertexTrackFactory<5> vTrackFactory;
129  RefCountedVertexTrack vTrData = vTrackFactory.vertexTrack(lTrData, realseed, weight);
130  newTracks.push_back(vTrData);
131  };
132 
133  if (newTracks.size() > 1) {
135  int snr = seedNr();
136  theVertexStates.push_back(pair<int, CachingVertex<5> >(snr, vtx));
137 
138  // We initialise the weights with the original
139  // user supplied weights.
140  for (vector<TrackAndWeight>::const_iterator track = tracks.begin(); track != tracks.end(); ++track) {
141  if (thePrimaries.count(track->first)) {
142  /*
143  cout << "[MultiVertexFitter] " << track->first.id() << " is a primary."
144  << " setting weight for state " << theVertexStates[0].first
145  << " to " << track->second
146  << endl;
147  */
148  theWeights[track->first][theVertexStates[0].first] = track->second;
149  continue;
150  };
151  float weight = track->second;
152  if (weight > 1.0) {
153  cout << "[MultiVertexFitter] error weight " << weight << " > 1.0 given." << endl;
154  cout << "[MultiVertexFitter] will revert to 1.0" << endl;
155  weight = 1.0;
156  };
157  if (weight < 0.0) {
158  cout << "[MultiVertexFitter] error weight " << weight << " < 0.0 given." << endl;
159  cout << "[MultiVertexFitter] will revert to 0.0" << endl;
160  weight = 0.0;
161  };
162  theWeights[track->first][snr] = weight;
163  theTracks.push_back(track->first);
164  };
165  };
166 
167  // this thing will actually have to discard tracks
168  // that have been submitted - attached to a different vertex - already.
169  // sort ( theTracks.begin(), theTracks.end(), CompareRaveTracks() );
170  sort(theTracks.begin(), theTracks.end());
171  for (vector<TransientTrack>::iterator i = theTracks.begin(); i < theTracks.end(); ++i) {
172  if (i != theTracks.begin()) {
173  if ((*i) == (*(i - 1))) {
174  theTracks.erase(i);
175  };
176  };
177  };
178 }
179 
180 vector<CachingVertex<5> > MultiVertexFitter::vertices(const vector<TransientVertex> &vtces,
181  const vector<TransientTrack> &primaries) {
182  // FIXME if vtces.size < 1 return sth that includes the primaries
183  if (vtces.empty()) {
184  return vector<CachingVertex<5> >();
185  };
186  vector<vector<TrackAndWeight> > bundles;
187  for (vector<TransientVertex>::const_iterator vtx = vtces.begin(); vtx != vtces.end(); ++vtx) {
188  vector<TransientTrack> trks = vtx->originalTracks();
189  vector<TrackAndWeight> tnws;
190  for (vector<TransientTrack>::const_iterator trk = trks.begin(); trk != trks.end(); ++trk) {
191  float w = vtx->trackWeight(*trk);
192  if (w > 1e-5) {
193  TrackAndWeight tmp(*trk, w);
194  tnws.push_back(tmp);
195  };
196  };
197  bundles.push_back(tnws);
198  };
199  return vertices(bundles, primaries);
200 }
201 
202 vector<CachingVertex<5> > MultiVertexFitter::vertices(const vector<CachingVertex<5> > &initials,
203  const vector<TransientTrack> &primaries) {
204  clear();
205  createPrimaries(primaries);
206  // FIXME if initials size < 1 return sth that includes the primaries
207  if (initials.empty())
208  return initials;
209  for (vector<CachingVertex<5> >::const_iterator vtx = initials.begin(); vtx != initials.end(); ++vtx) {
210  int snr = seedNr();
211  theVertexStates.push_back(pair<int, CachingVertex<5> >(snr, *vtx));
212  TransientVertex rvtx = *vtx;
213  const vector<TransientTrack> &trks = rvtx.originalTracks();
214  for (vector<TransientTrack>::const_iterator trk = trks.begin(); trk != trks.end(); ++trk) {
215  if (!(thePrimaries.count(*trk))) {
216  // cout << "[MultiVertexFitter] free track " << trk->id() << endl;
217  theTracks.push_back(*trk);
218  } else {
219  // cout << "[MultiVertexFitter " << trk->id() << " is not free." << endl;
220  }
221  cout << "[MultiVertexFitter] error! track weight currently set to one"
222  << " FIXME!!!" << endl;
223  theWeights[*trk][snr] = 1.0;
224  };
225  };
226 #ifdef MVFHarvestingDebug
227  for (vector<CachingVertex<5> >::const_iterator i = theVertexStates.begin(); i != theVertexStates.end(); ++i)
228  PrimitivesHarvester::file()->save(*i);
229 #endif
230  return fit();
231 }
232 
233 vector<CachingVertex<5> > MultiVertexFitter::vertices(const vector<vector<TransientTrack> > &tracks,
234  const vector<TransientTrack> &primaries) {
235  clear();
236  createPrimaries(primaries);
237 
238  for (vector<vector<TransientTrack> >::const_iterator cluster = tracks.begin(); cluster != tracks.end(); ++cluster) {
239  createSeed(*cluster);
240  };
241  if (verbose()) {
242  printSeeds();
243  };
244 #ifdef MVFHarvestingDebug
245  for (vector<CachingVertex<5> >::const_iterator i = theVertexStates.begin(); i != theVertexStates.end(); ++i)
246  PrimitivesHarvester::file()->save(*i);
247 #endif
248  return fit();
249 }
250 
251 vector<CachingVertex<5> > MultiVertexFitter::vertices(const vector<vector<TrackAndWeight> > &tracks,
252  const vector<TransientTrack> &primaries) {
253  clear();
254  createPrimaries(primaries);
255 
256  for (vector<vector<TrackAndWeight> >::const_iterator cluster = tracks.begin(); cluster != tracks.end(); ++cluster) {
257  createSeed(*cluster);
258  };
259  if (verbose()) {
260  printSeeds();
261  };
262 
263  return fit();
264 }
265 
267  const LinearizationPointFinder &seeder,
268  float revive_below)
269  : theVertexStateNr(0), theReviveBelow(revive_below), theAssComp(ann.clone()), theSeeder(seeder.clone()) {}
270 
275  theSeeder(o.theSeeder->clone()) {}
276 
278  delete theAssComp;
279  delete theSeeder;
280 }
281 
283  theWeights.clear();
284  if (verbose() & 4) {
285  cout << "[MultiVertexFitter] Start weight update." << endl;
286  };
287 
289 
293  for (set<TransientTrack>::const_iterator trk = thePrimaries.begin(); trk != thePrimaries.end(); ++trk) {
294  int seednr = theVertexStates[0].first;
296  pair<bool, double> result = theComp.estimate(seed, theCache.linTrack(seed.position(), *trk));
297  double weight = 0.;
298  if (result.first)
299  weight = theAssComp->phi(result.second);
300  theWeights[*trk][seednr] = weight; // FIXME maybe "hard" 1.0 or "soft" weight?
301  }
302 
306  for (vector<TransientTrack>::const_iterator trk = theTracks.begin(); trk != theTracks.end(); ++trk) {
307  double tot_weight = theAssComp->phi(theAssComp->cutoff() * theAssComp->cutoff());
308 
309  for (vector<pair<int, CachingVertex<5> > >::const_iterator seed = theVertexStates.begin();
310  seed != theVertexStates.end();
311  ++seed) {
312  pair<bool, double> result = theComp.estimate(seed->second, theCache.linTrack(seed->second.position(), *trk));
313  double weight = 0.;
314  if (result.first)
315  weight = theAssComp->phi(result.second);
316  tot_weight += weight;
317  theWeights[*trk][seed->first] = weight;
318  /* cout << "[MultiVertexFitter] w[" << TransientTrackNamer().name(*trk)
319  << "," << seed->position() << "] = " << weight << endl;*/
320  };
321 
322  // normalize to sum of all weights of one track equals 1.
323  // (if we include the "cutoff", as well)
324  if (tot_weight > 0.0) {
325  for (vector<pair<int, CachingVertex<5> > >::const_iterator seed = theVertexStates.begin();
326  seed != theVertexStates.end();
327  ++seed) {
328  double normedweight = theWeights[*trk][seed->first] / tot_weight;
329  if (normedweight > 1.0) {
330  cout << "[MultiVertexFitter] he? w[" // << TransientTrackNamer().name(*trk)
331  << "," << seed->second.position() << "] = " << normedweight << " totw=" << tot_weight << endl;
332  normedweight = 1.0;
333  };
334  if (normedweight < 0.0) {
335  cout << "[MultiVertexFitter] he? weight=" << normedweight << " totw=" << tot_weight << endl;
336  normedweight = 0.0;
337  };
338  theWeights[*trk][seed->first] = normedweight;
339  };
340  } else {
341  // total weight equals zero? restart, with uniform distribution!
342  cout << "[MultiVertexFitter] track found with no assignment - ";
343  cout << "will assign uniformly." << endl;
344  float w = .5 / (float)theVertexStates.size();
345  for (vector<pair<int, CachingVertex<5> > >::const_iterator seed = theVertexStates.begin();
346  seed != theVertexStates.end();
347  ++seed) {
348  theWeights[*trk][seed->first] = w;
349  };
350  };
351  };
352  if (verbose() & 2)
353  printWeights();
354 }
355 
357  double max_disp = 0.;
358  // need to fit with the right weights.
359  // also trigger an updateWeights.
360  // if the seeds dont move much we return true
361 
362  vector<pair<int, CachingVertex<5> > > newSeeds;
363 
364  for (vector<pair<int, CachingVertex<5> > >::const_iterator seed = theVertexStates.begin();
365  seed != theVertexStates.end();
366  ++seed) {
367  // for each seed get the tracks with the right weights.
368  // TransientVertex rv = seed->second;
369  // const GlobalPoint & seedpos = seed->second.position();
370  int snr = seed->first;
371  VertexState realseed(seed->second.position(), seed->second.error());
372 
373  double totweight = 0.;
374  for (vector<TransientTrack>::const_iterator track = theTracks.begin(); track != theTracks.end(); ++track) {
375  totweight += theWeights[*track][snr];
376  };
377 
378  int nr_good_trks = 0; // how many tracks above weight limit
379  // we count those tracks, because that way
380  // we can discard lightweights if there are enough tracks
381  // and not discard the lightweights if that would give us
382  // fewer than two tracks ( we would loose a seed, then ).
383  if (discardLightWeights()) {
384  for (vector<TransientTrack>::const_iterator track = theTracks.begin(); track != theTracks.end(); ++track) {
385  if (theWeights[*track][snr] > totweight * minWeightFraction()) {
386  nr_good_trks++;
387  };
388  };
389  };
390 
391  vector<RefCountedVertexTrack> newTracks;
392  for (vector<TransientTrack>::const_iterator track = theTracks.begin(); track != theTracks.end(); ++track) {
393  double weight = validWeight(theWeights[*track][snr]);
394  // Now we add a track, if
395  // a. we consider all tracks or
396  // b. we discard the lightweights but the track's weight is high enough or
397  // c. we discard the lightweights but there arent enough good tracks,
398  // so we add all lightweights again (too expensive to figure out
399  // which lightweights are the most important)
400  if (!discardLightWeights() || weight > minWeightFraction() * totweight || nr_good_trks < 2) {
401  // if the linearization point didnt move too much,
402  // we take the old LinTrackState.
403  // Otherwise we relinearize.
404 
405  RefCountedLinearizedTrackState lTrData = theCache.linTrack(seed->second.position(), *track);
406 
407  VertexTrackFactory<5> vTrackFactory;
408  RefCountedVertexTrack vTrData = vTrackFactory.vertexTrack(lTrData, realseed, weight);
409  newTracks.push_back(vTrData);
410  };
411  };
412 
413  for (set<TransientTrack>::const_iterator track = thePrimaries.begin(); track != thePrimaries.end(); ++track) {
414  double weight = validWeight(theWeights[*track][snr]);
415 
416  RefCountedLinearizedTrackState lTrData = theCache.linTrack(seed->second.position(), *track);
417 
418  VertexTrackFactory<5> vTrackFactory;
419  RefCountedVertexTrack vTrData = vTrackFactory.vertexTrack(lTrData, realseed, weight);
420  newTracks.push_back(vTrData);
421  };
422 
423  try {
424  if (newTracks.size() < 2) {
425  throw VertexException("less than two tracks in vector");
426  };
427 
428  if (verbose()) {
429  cout << "[MultiVertexFitter] now fitting with Kalman: ";
430  for (vector<RefCountedVertexTrack>::const_iterator i = newTracks.begin(); i != newTracks.end(); ++i) {
431  cout << (**i).weight() << " ";
432  };
433  cout << endl;
434  };
435 
436  if (newTracks.size() > 1) {
437  KalmanVertexFitter fitter;
438  // warning! first track determines lin pt!
439  CachingVertex<5> newVertex = fitter.vertex(newTracks);
440  int snr = seedNr();
441  double disp = (newVertex.position() - seed->second.position()).mag();
442  if (disp > max_disp)
443  max_disp = disp;
444  newSeeds.push_back(pair<int, CachingVertex<5> >(snr, newVertex));
445  };
446  } catch (exception &e) {
447  cout << "[MultiVertexFitter] exception: " << e.what() << endl;
448  }
449  };
450 
451  // now discard all old seeds and weights, compute new ones.
452  theVertexStates.clear();
453  theWeights.clear();
454  theVertexStates = newSeeds;
455 #ifdef MVFHarvestingDebug
456  for (vector<CachingVertex<5> >::const_iterator i = theVertexStates.begin(); i != theVertexStates.end(); ++i)
457  PrimitivesHarvester::file()->save(*i);
458 #endif
459  updateWeights();
460 
461  static const double disp_limit = 1e-4; /* SimpleConfigurable<double>
462  (0.0001, "MultiVertexFitter:DisplacementLimit" ).value(); */
463 
464  if (verbose() & 2) {
465  printSeeds();
466  cout << "[MultiVertexFitter] max displacement in this iteration: " << max_disp << endl;
467  };
468  if (max_disp < disp_limit)
469  return false;
470  return true;
471 }
472 
473 // iterating over the fits
474 vector<CachingVertex<5> > MultiVertexFitter::fit() {
475  if (verbose() & 2)
476  printWeights();
477  int ctr = 1;
478  static const int ctr_max = 50; /* SimpleConfigurable<int>(100,
479  "MultiVertexFitter:MaxIterations").value(); */
480  while (updateSeeds() || !(theAssComp->isAnnealed())) {
481  if (++ctr >= ctr_max)
482  break;
483  theAssComp->anneal();
484  // lostVertexClaimer(); // was a silly(?) idea to "revive" vertex candidates.
485  resetSeedNr();
486  };
487 
488  if (verbose()) {
489  cout << "[MultiVertexFitter] number of iterations: " << ctr << endl;
490  cout << "[MultiVertexFitter] remaining seeds: " << theVertexStates.size() << endl;
491  printWeights();
492  };
493 
494  vector<CachingVertex<5> > ret;
495  for (vector<pair<int, CachingVertex<5> > >::const_iterator i = theVertexStates.begin(); i != theVertexStates.end();
496  ++i) {
497  ret.push_back(i->second);
498  };
499 
500  return ret;
501 }
502 
504  // cout << "Trk " << t.id();
505  for (vector<pair<int, CachingVertex<5> > >::const_iterator seed = theVertexStates.begin();
506  seed != theVertexStates.end();
507  ++seed) {
508  double val = 0;
509  auto a = theWeights.find(t);
510  if (a != theWeights.end()) {
511  auto b = a->second.find(seed->first);
512  if (b != a->second.end())
513  val = b->second;
514  }
515  cout << " -- Vertex[" << seed->first << "] with " << setw(12) << setprecision(3) << val;
516  };
517  cout << endl;
518 }
519 
521  cout << endl << "Weight table: " << endl << "=================" << endl;
522  for (set<TransientTrack>::const_iterator trk = thePrimaries.begin(); trk != thePrimaries.end(); ++trk) {
523  printWeights(*trk);
524  };
525  for (vector<TransientTrack>::const_iterator trk = theTracks.begin(); trk != theTracks.end(); ++trk) {
526  printWeights(*trk);
527  };
528 }
529 
531  cout << endl << "Seed table: " << endl << "=====================" << endl;
532  /*
533  for ( vector < pair < int, CachingVertex<5> > >::const_iterator seed=theVertexStates.begin();
534  seed!=theVertexStates.end(); ++seed )
535  {
536  cout << " Vertex[" << TransientVertexNamer().name(seed->second) << "] at "
537  << seed->second.position() << endl;
538  };*/
539 }
540 
542  if (!(theReviveBelow < 0.))
543  return;
544  // this experimental method is used to get almost lost vertices
545  // back into the play by upweighting vertices with very low total weights
546 
547  bool has_revived = false;
548  // find out about total weight
549  for (vector<pair<int, CachingVertex<5> > >::const_iterator i = theVertexStates.begin(); i != theVertexStates.end();
550  ++i) {
551  double totweight = 0.;
552  for (vector<TransientTrack>::const_iterator trk = theTracks.begin(); trk != theTracks.end(); ++trk) {
553  totweight += theWeights[*trk][i->first];
554  };
555 
556  /*
557  cout << "[MultiVertexFitter] vertex seed " << TransientVertexNamer().name(*i)
558  << " total weight=" << totweight << endl;*/
559 
560  if (totweight < theReviveBelow && totweight > 0.0) {
561  cout << "[MultiVertexFitter] now trying to revive vertex"
562  << " revive_below=" << theReviveBelow << endl;
563  has_revived = true;
564  for (vector<TransientTrack>::const_iterator trk = theTracks.begin(); trk != theTracks.end(); ++trk) {
565  theWeights[*trk][i->first] /= totweight;
566  };
567  };
568  };
569  if (has_revived && verbose())
570  printWeights();
571 }
std::vector< CachingVertex< 5 > > vertices(const std::vector< std::vector< reco::TransientTrack > > &, const std::vector< reco::TransientTrack > &primaries=std::vector< reco::TransientTrack >())
MultiVertexFitter(const AnnealingSchedule &sched=DefaultMVFAnnealing(), const LinearizationPointFinder &seeder=DefaultLinearizationPointFinder(), float revive_below=-1.)
const double w
Definition: UKUtility.cc:23
RefCountedVertexTrack vertexTrack(const RefCountedLinearizedTrackState lt, const VertexState vs, float weight=1.0) const
Common base class.
ret
prodAgent to be discontinued
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
BDpair estimate(const CachingVertex< N > &vrt, const RefCountedVertexTrack track, unsigned int hint=UINT_MAX) const override
void printWeights() const
GlobalErrorBase< double, ErrorMatrixTag > GlobalError
Definition: GlobalError.h:13
void createPrimaries(const std::vector< reco::TransientTrack > &tracks)
Definition: weight.py:1
LinearizationPointFinder * theSeeder
std::set< reco::TransientTrack > thePrimaries
virtual bool isAnnealed() const =0
static int verbose
std::vector< reco::TransientTrack > const & originalTracks() const
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:151
LinTrackCache theCache
virtual double phi(double chi2) const =0
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const override
virtual double cutoff() const =0
std::vector< std::pair< int, CachingVertex< 5 > > > theVertexStates
std::pair< reco::TransientTrack, float > TrackAndWeight
std::map< int, double > SeedToWeightMap
void printSeeds() const
double b
Definition: hdecay.h:118
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
void createSeed(const std::vector< reco::TransientTrack > &tracks)
RefCountedLinearizedTrackState linTrack(const GlobalPoint &, const reco::TransientTrack &)
GlobalPoint position() const
fixed size matrix
CachingVertex< 5 >::RefCountedVertexTrack RefCountedVertexTrack
double a
Definition: hdecay.h:119
std::vector< CachingVertex< 5 > > fit()
std::vector< reco::TransientTrack > theTracks
virtual void anneal()=0
AnnealingSchedule * theAssComp
tmp
align.sh
Definition: createJobs.py:716
std::map< reco::TransientTrack, SeedToWeightMap > TrackAndSeedToWeightMap
TrackAndSeedToWeightMap theWeights