CMS 3D CMS Logo

PrimaryVertexProducer.cc
Go to the documentation of this file.
2 
9 
13 
18 
20 
22  :theConfig(conf)
23 {
24 
25  fVerbose = conf.getUntrackedParameter<bool>("verbose", false);
26 
27  trkToken = consumes<reco::TrackCollection>(conf.getParameter<edm::InputTag>("TrackLabel"));
28  bsToken = consumes<reco::BeamSpot>(conf.getParameter<edm::InputTag>("beamSpotLabel"));
29  f4D = false;
30 
31  // select and configure the track selection
32  std::string trackSelectionAlgorithm=conf.getParameter<edm::ParameterSet>("TkFilterParameters").getParameter<std::string>("algorithm");
33  if(trackSelectionAlgorithm=="filter"){
34  theTrackFilter= new TrackFilterForPVFinding( conf.getParameter<edm::ParameterSet>("TkFilterParameters") );
35  }else if (trackSelectionAlgorithm=="filterWithThreshold"){
37  }else{
38  throw VertexException("PrimaryVertexProducerAlgorithm: unknown track selection algorithm: " + trackSelectionAlgorithm);
39  }
40 
41 
42  // select and configure the track clusterizer
43  std::string clusteringAlgorithm=conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<std::string>("algorithm");
44  if (clusteringAlgorithm=="gap"){
45  theTrackClusterizer = new GapClusterizerInZ(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkGapClusParameters"));
46  }else if(clusteringAlgorithm=="DA"){
47  theTrackClusterizer = new DAClusterizerInZ(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkDAClusParameters"));
48  }
49  // provide the vectorized version of the clusterizer, if supported by the build
50  else if(clusteringAlgorithm == "DA_vect") {
51  theTrackClusterizer = new DAClusterizerInZ_vect(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkDAClusParameters"));
52  } else if( clusteringAlgorithm=="DA2D_vect" ) {
53  theTrackClusterizer = new DAClusterizerInZT_vect(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkDAClusParameters"));
54  f4D = true;
55  }
56 
57  else{
58  throw VertexException("PrimaryVertexProducerAlgorithm: unknown clustering algorithm: " + clusteringAlgorithm);
59  }
60 
61  if( f4D ) {
62  trkTimesToken = consumes<edm::ValueMap<float> >(conf.getParameter<edm::InputTag>("TrackTimesLabel") );
63  trkTimeResosToken = consumes<edm::ValueMap<float> >(conf.getParameter<edm::InputTag>("TrackTimeResosLabel") );
64  }
65 
66 
67  // select and configure the vertex fitters
68  if (conf.exists("vertexCollections")){
69  std::vector<edm::ParameterSet> vertexCollections =conf.getParameter< std::vector<edm::ParameterSet> >("vertexCollections");
70 
71  for( std::vector< edm::ParameterSet >::const_iterator algoconf = vertexCollections.begin(); algoconf != vertexCollections.end(); algoconf++){
72 
74  std::string fitterAlgorithm = algoconf->getParameter<std::string>("algorithm");
75  if (fitterAlgorithm=="KalmanVertexFitter") {
76  algorithm.fitter= new KalmanVertexFitter();
77  } else if( fitterAlgorithm=="AdaptiveVertexFitter") {
78  algorithm.fitter= new AdaptiveVertexFitter( GeometricAnnealing( algoconf->getParameter<double>("chi2cutoff")));
79  } else {
80  throw VertexException("PrimaryVertexProducerAlgorithm: unknown algorithm: " + fitterAlgorithm);
81  }
82  algorithm.label = algoconf->getParameter<std::string>("label");
83  algorithm.minNdof = algoconf->getParameter<double>("minNdof");
84  algorithm.useBeamConstraint=algoconf->getParameter<bool>("useBeamConstraint");
85  algorithm.vertexSelector=new VertexCompatibleWithBeam(VertexDistanceXY(), algoconf->getParameter<double>("maxDistanceToBeam"));
86  algorithms.push_back(algorithm);
87 
88  produces<reco::VertexCollection>(algorithm.label);
89  }
90  }else{
91  edm::LogWarning("MisConfiguration")<<"this module's configuration has changed, please update to have a vertexCollections=cms.VPSet parameter.";
92 
94  std::string fitterAlgorithm = conf.getParameter<std::string>("algorithm");
95  if (fitterAlgorithm=="KalmanVertexFitter") {
96  algorithm.fitter= new KalmanVertexFitter();
97  } else if( fitterAlgorithm=="AdaptiveVertexFitter") {
98  algorithm.fitter= new AdaptiveVertexFitter();
99  } else {
100  throw VertexException("PrimaryVertexProducerAlgorithm: unknown algorithm: " + fitterAlgorithm);
101  }
102  algorithm.label = "";
103  algorithm.minNdof = conf.getParameter<double>("minNdof");
104  algorithm.useBeamConstraint=conf.getParameter<bool>("useBeamConstraint");
105 
106  algorithm.vertexSelector=new VertexCompatibleWithBeam(VertexDistanceXY(), conf.getParameter<edm::ParameterSet>("PVSelParameters").getParameter<double>("maxDistanceToBeam"));
107 
108  algorithms.push_back(algorithm);
109  produces<reco::VertexCollection>(algorithm.label);
110  }
111 
112 
113 }
114 
115 
117  if (theTrackFilter) delete theTrackFilter;
119  for( std::vector <algo>::const_iterator algorithm=algorithms.begin(); algorithm!=algorithms.end(); algorithm++){
120  if (algorithm->fitter) delete algorithm->fitter;
121  if (algorithm->vertexSelector) delete algorithm->vertexSelector;
122  }
123 }
124 
125 
126 void
128 {
129 
130  // get the BeamSpot, it will alwys be needed, even when not used as a constraint
132  edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
133  iEvent.getByToken(bsToken,recoBeamSpotHandle);
134  if (recoBeamSpotHandle.isValid()){
135  beamSpot = *recoBeamSpotHandle;
136  }else{
137  edm::LogError("UnusableBeamSpot") << "No beam spot available from EventSetup";
138  }
139 
140  bool validBS = true;
141  VertexState beamVertexState(beamSpot);
142  if ( (beamVertexState.error().cxx() <= 0.) ||
143  (beamVertexState.error().cyy() <= 0.) ||
144  (beamVertexState.error().czz() <= 0.) ) {
145  validBS = false;
146  edm::LogError("UnusableBeamSpot") << "Beamspot with invalid errors "<<beamVertexState.error().matrix();
147  }
148 
149 
150  // get RECO tracks from the event
151  // `tks` can be used as a ptr to a reco::TrackCollection
153  iEvent.getByToken(trkToken, tks);
154 
155 
156  // interface RECO tracks to vertex reconstruction
158  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theB);
159  std::vector<reco::TransientTrack> t_tks;
160 
161  if( f4D ) {
162  edm::Handle<edm::ValueMap<float> > trackTimesH;
163  edm::Handle<edm::ValueMap<float> > trackTimeResosH;
164  iEvent.getByToken(trkTimesToken, trackTimesH);
165  iEvent.getByToken(trkTimeResosToken, trackTimeResosH);
166  t_tks = (*theB).build(tks, beamSpot, *(trackTimesH.product()), *(trackTimeResosH.product()));
167  } else {
168  t_tks = (*theB).build(tks, beamSpot);
169  }
170  if(fVerbose) {std::cout << "RecoVertex/PrimaryVertexProducer"
171  << "Found: " << t_tks.size() << " reconstructed tracks" << "\n";
172  }
173 
174 
175  // select tracks
176  std::vector<reco::TransientTrack> && seltks = theTrackFilter->select( t_tks );
177 
178  // clusterize tracks in Z
179  std::vector< std::vector<reco::TransientTrack> > && clusters = theTrackClusterizer->clusterize(seltks);
180 
181  if (fVerbose){std::cout << " clustering returned "<< clusters.size() << " clusters from " << seltks.size() << " selected tracks" <<std::endl;}
182 
183 
184  // vertex fits
185  for( std::vector <algo>::const_iterator algorithm=algorithms.begin(); algorithm!=algorithms.end(); algorithm++){
186 
187 
188  auto result = std::make_unique<reco::VertexCollection>();
189  reco::VertexCollection & vColl = (*result);
190 
191 
192  std::vector<TransientVertex> pvs;
193  for (std::vector< std::vector<reco::TransientTrack> >::const_iterator iclus
194  = clusters.begin(); iclus != clusters.end(); iclus++) {
195 
196  double sumwt = 0.;
197  double sumwt2 = 0.;
198  double sumw = 0.;
199  double meantime = 0.;
200  double vartime = 0.;
201  if( f4D ) {
202  for( const auto& tk : *iclus ) {
203  const double time = tk.timeExt();
204  const double err = tk.dtErrorExt();
205  const double inverr = err > 0. ? 1.0/err : 0.;
206  const double w = inverr*inverr;
207  sumwt += w*time;
208  sumwt2 += w*time*time;
209  sumw += w;
210  }
211  meantime = sumwt/sumw;
212  double sumsq = sumwt2 - sumwt*sumwt/sumw;
213  double chisq = iclus->size()>1 ? sumsq/double(iclus->size()-1) : sumsq/double(iclus->size());
214  vartime = chisq/sumw;
215  }
216 
218  if( algorithm->useBeamConstraint && validBS &&((*iclus).size()>1) ){
219 
220  v = algorithm->fitter->vertex(*iclus, beamSpot);
221 
222  if( f4D ) {
223  if( v.isValid() ) {
224  auto err = v.positionError().matrix4D();
225  err(3,3) = vartime;
226  v = TransientVertex(v.position(),meantime,err,v.originalTracks(),v.totalChiSquared());
227  }
228  }
229 
230  }else if( !(algorithm->useBeamConstraint) && ((*iclus).size()>1) ) {
231 
232  v = algorithm->fitter->vertex(*iclus);
233 
234  if( f4D ) {
235  if( v.isValid() ) {
236  auto err = v.positionError().matrix4D();
237  err(3,3) = vartime;
238  v = TransientVertex(v.position(),meantime,err,v.originalTracks(),v.totalChiSquared());
239  }
240  }
241 
242  }// else: no fit ==> v.isValid()=False
243 
244 
245  if (fVerbose){
246  if (v.isValid()) {
247  std::cout << "x,y,z";
248  if (f4D) std::cout << ",t";
249  std::cout << "=" << v.position().x() <<" " << v.position().y() << " " << v.position().z();
250  if (f4D) std::cout << " " << v.time();
251  std::cout << " cluster size = " << (*iclus).size() << std::endl;
252  }
253  else{
254  std::cout <<"Invalid fitted vertex, cluster size=" << (*iclus).size() << std::endl;
255  }
256  }
257 
258  if ( v.isValid()
259  && (v.degreesOfFreedom()>=algorithm->minNdof)
260  && (!validBS || (*(algorithm->vertexSelector))(v,beamVertexState))
261  ) pvs.push_back(v);
262  }// end of cluster loop
263 
264  if(fVerbose){
265  std::cout << "PrimaryVertexProducerAlgorithm::vertices candidates =" << pvs.size() << std::endl;
266  }
267 
268 
269  if (clusters.size()>2 && clusters.size() > 2*pvs.size())
270  edm::LogWarning("PrimaryVertexProducer") << "more than half of candidate vertices lost " << pvs.size() << ' ' << clusters.size();
271 
272  if (pvs.empty() && seltks.size()>5)
273  edm::LogWarning("PrimaryVertexProducer") << "no vertex found with " << seltks.size() << " tracks and " << clusters.size() <<" vertex-candidates";
274 
275  // sort vertices by pt**2 vertex (aka signal vertex tagging)
276  if(pvs.size()>1){
277  sort(pvs.begin(), pvs.end(), VertexHigherPtSquared());
278  }
279 
280 
281 
282  // convert transient vertices returned by the theAlgo to (reco) vertices
283  for (std::vector<TransientVertex>::const_iterator iv = pvs.begin();
284  iv != pvs.end(); iv++) {
285  reco::Vertex v = *iv;
286  vColl.push_back(v);
287  }
288 
289  if (vColl.empty()) {
290  GlobalError bse(beamSpot.rotatedCovariance3D());
291  if ( (bse.cxx() <= 0.) ||
292  (bse.cyy() <= 0.) ||
293  (bse.czz() <= 0.) ) {
295  we(0,0)=10000; we(1,1)=10000; we(2,2)=10000;
296  vColl.push_back(reco::Vertex(beamSpot.position(), we,0.,0.,0));
297  if(fVerbose){
298  std::cout <<"RecoVertex/PrimaryVertexProducer: "
299  << "Beamspot with invalid errors "<<bse.matrix()<<std::endl;
300  std::cout << "Will put Vertex derived from dummy-fake BeamSpot into Event.\n";
301  }
302  } else {
303  vColl.push_back(reco::Vertex(beamSpot.position(),
304  beamSpot.rotatedCovariance3D(),0.,0.,0));
305  if(fVerbose){
306  std::cout <<"RecoVertex/PrimaryVertexProducer: "
307  << " will put Vertex derived from BeamSpot into Event.\n";
308  }
309  }
310  }
311 
312  if(fVerbose){
313  int ivtx=0;
314  for(reco::VertexCollection::const_iterator v=vColl.begin();
315  v!=vColl.end(); ++v){
316  std::cout << "recvtx "<< ivtx++
317  << "#trk " << std::setw(3) << v->tracksSize()
318  << " chi2 " << std::setw(4) << v->chi2()
319  << " ndof " << std::setw(3) << v->ndof()
320  << " x " << std::setw(6) << v->position().x()
321  << " dx " << std::setw(6) << v->xError()
322  << " y " << std::setw(6) << v->position().y()
323  << " dy " << std::setw(6) << v->yError()
324  << " z " << std::setw(6) << v->position().z()
325  << " dz " << std::setw(6) << v->zError();
326  if( f4D ) {
327  std::cout << " t " << std::setw(6) << v->t()
328  << " dt " << std::setw(6) << v->tError();
329  }
330  std::cout << std::endl;
331  }
332  }
333 
334  iEvent.put(std::move(result), algorithm->label);
335  }
336 
337 }
338 
339 
340 //define this as a plug-in
GlobalError positionError() const
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
vertexCollections
1 cm max separation between clusters
edm::EDGetTokenT< reco::BeamSpot > bsToken
const double w
Definition: UKUtility.cc:23
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
Common base class.
const AlgebraicSymMatrix33 matrix() const
float totalChiSquared() const
edm::EDGetTokenT< reco::TrackCollection > trkToken
TrackClusterizerInZ * theTrackClusterizer
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
edm::EDGetTokenT< edm::ValueMap< float > > trkTimesToken
const AlgebraicSymMatrix44 & matrix4D() const
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepSym< double, 3 > > AlgebraicSymMatrix33
std::vector< reco::TransientTrack > const & originalTracks() const
edm::EDGetTokenT< edm::ValueMap< float > > trkTimeResosToken
float degreesOfFreedom() const
VertexCompatibleWithBeam * vertexSelector
GlobalPoint position() const
T z() const
Definition: PV3DBase.h:64
TrackFilterForPVFindingBase * theTrackFilter
bool isValid() const
Definition: HandleBase.h:74
virtual std::vector< std::vector< reco::TransientTrack > > clusterize(const std::vector< reco::TransientTrack > &tracks) const =0
T const * product() const
Definition: Handle.h:74
std::vector< algo > algorithms
virtual std::vector< reco::TransientTrack > select(const std::vector< reco::TransientTrack > &tracks) const =0
double time() const
void produce(edm::Event &, const edm::EventSetup &) override
T get() const
Definition: EventSetup.h:71
PrimaryVertexProducer(const edm::ParameterSet &)
GlobalError error() const
Definition: VertexState.h:74
const Point & position() const
position
Definition: BeamSpot.h:62
Covariance3DMatrix rotatedCovariance3D() const
Definition: BeamSpot.cc:78
T x() const
Definition: PV3DBase.h:62
bool isValid() const
def move(src, dest)
Definition: eostools.py:511