00001 #include "RecoTracker/FinalTrackSelectors/src/MultiTrackSelector.h"
00002
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "DataFormats/Common/interface/ValueMap.h"
00005 #include <Math/DistFunc.h>
00006 #include "TMath.h"
00007
00008 using reco::modules::MultiTrackSelector;
00009
00010 MultiTrackSelector::MultiTrackSelector( const edm::ParameterSet & cfg ) :
00011 src_( cfg.getParameter<edm::InputTag>( "src" ) ),
00012 beamspot_( cfg.getParameter<edm::InputTag>( "beamspot" ) ),
00013 useVertices_( cfg.getParameter<bool>( "useVertices" ) ),
00014 useVtxError_( cfg.getParameter<bool>( "useVtxError" ) ),
00015 vertices_( useVertices_ ? cfg.getParameter<edm::InputTag>( "vertices" ) : edm::InputTag("NONE"))
00016
00017 {
00018
00019 std::vector<edm::ParameterSet> trkSelectors( cfg.getParameter<std::vector< edm::ParameterSet> >("trackSelectors") );
00020 qualityToSet_.reserve(trkSelectors.size());
00021 vtxNumber_.reserve(trkSelectors.size());
00022 vertexCut_.reserve(trkSelectors.size());
00023 res_par_.reserve(trkSelectors.size());
00024 chi2n_par_.reserve(trkSelectors.size());
00025 chi2n_no1Dmod_par_.reserve(trkSelectors.size());
00026 d0_par1_.reserve(trkSelectors.size());
00027 dz_par1_.reserve(trkSelectors.size());
00028 d0_par2_.reserve(trkSelectors.size());
00029 dz_par2_.reserve(trkSelectors.size());
00030 applyAdaptedPVCuts_.reserve(trkSelectors.size());
00031 max_d0_.reserve(trkSelectors.size());
00032 max_z0_.reserve(trkSelectors.size());
00033 nSigmaZ_.reserve(trkSelectors.size());
00034 min_layers_.reserve(trkSelectors.size());
00035 min_3Dlayers_.reserve(trkSelectors.size());
00036 max_lostLayers_.reserve(trkSelectors.size());
00037 applyAbsCutsIfNoPV_.reserve(trkSelectors.size());
00038 max_d0NoPV_.reserve(trkSelectors.size());
00039 max_z0NoPV_.reserve(trkSelectors.size());
00040 preFilter_.reserve(trkSelectors.size());
00041 max_relpterr_.reserve(trkSelectors.size());
00042 min_nhits_.reserve(trkSelectors.size());
00043
00044 for ( unsigned int i=0; i<trkSelectors.size(); i++) {
00045
00046 qualityToSet_.push_back( TrackBase::undefQuality );
00047
00048 vtxNumber_.push_back( useVertices_ ? trkSelectors[i].getParameter<int32_t>("vtxNumber") : 0 );
00049 vertexCut_.push_back( useVertices_ ? trkSelectors[i].getParameter<std::string>("vertexCut") : 0);
00050
00051 res_par_.push_back(trkSelectors[i].getParameter< std::vector<double> >("res_par") );
00052 chi2n_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_par") );
00053 chi2n_no1Dmod_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_no1Dmod_par") );
00054 d0_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par1"));
00055 dz_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par1"));
00056 d0_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par2"));
00057 dz_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par2"));
00058
00059 applyAdaptedPVCuts_.push_back(trkSelectors[i].getParameter<bool>("applyAdaptedPVCuts"));
00060
00061 max_d0_.push_back(trkSelectors[i].getParameter<double>("max_d0"));
00062 max_z0_.push_back(trkSelectors[i].getParameter<double>("max_z0"));
00063 nSigmaZ_.push_back(trkSelectors[i].getParameter<double>("nSigmaZ"));
00064
00065 min_layers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumberLayers") );
00066 min_3Dlayers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumber3DLayers") );
00067 max_lostLayers_.push_back(trkSelectors[i].getParameter<uint32_t>("maxNumberLostLayers"));
00068
00069 applyAbsCutsIfNoPV_.push_back(trkSelectors[i].getParameter<bool>("applyAbsCutsIfNoPV"));
00070 keepAllTracks_.push_back( trkSelectors[i].getParameter<bool>("keepAllTracks"));
00071 max_relpterr_.push_back(trkSelectors[i].getParameter<double>("max_relpterr"));
00072 min_nhits_.push_back(trkSelectors[i].getParameter<uint32_t>("min_nhits"));
00073
00074
00075 setQualityBit_.push_back( false );
00076 std::string qualityStr = trkSelectors[i].getParameter<std::string>("qualityBit");
00077 if (qualityStr != "") {
00078 setQualityBit_[i] = true;
00079 qualityToSet_[i] = TrackBase::qualityByName(trkSelectors[i].getParameter<std::string>("qualityBit"));
00080 }
00081
00082 if (setQualityBit_[i] && (qualityToSet_[i] == TrackBase::undefQuality)) throw cms::Exception("Configuration") <<
00083 "You can't set the quality bit " << trkSelectors[i].getParameter<std::string>("qualityBit") << " as it is 'undefQuality' or unknown.\n";
00084
00085 if (applyAbsCutsIfNoPV_[i]) {
00086 max_d0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_d0NoPV"));
00087 max_z0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_z0NoPV"));
00088 }
00089 else{
00090 max_d0NoPV_.push_back(0.);
00091 max_z0NoPV_.push_back(0.);
00092 }
00093
00094 name_.push_back( trkSelectors[i].getParameter<std::string>("name") );
00095
00096 preFilter_[i]=trkSelectors.size();
00097
00098 std::string pfName=trkSelectors[i].getParameter<std::string>("preFilterName");
00099 if (pfName!="") {
00100 bool foundPF=false;
00101 for ( unsigned int j=0; j<i; j++)
00102 if (name_[j]==pfName ) {
00103 foundPF=true;
00104 preFilter_[i]=j;
00105 }
00106 if ( !foundPF)
00107 throw cms::Exception("Configuration") << "Invalid prefilter name in MultiTrackSelector "
00108 << trkSelectors[i].getParameter<std::string>("preFilterName");
00109
00110 }
00111
00112
00113 produces<edm::ValueMap<int> >(name_[i]).setBranchAlias( name_[i] + "TrackQuals");
00114 }
00115 }
00116
00117 MultiTrackSelector::~MultiTrackSelector() {
00118 }
00119
00120 void MultiTrackSelector::produce( edm::Event& evt, const edm::EventSetup& es )
00121 {
00122 using namespace std;
00123 using namespace edm;
00124 using namespace reco;
00125
00126
00127 Handle<TrackCollection> hSrcTrack;
00128 evt.getByLabel( src_, hSrcTrack );
00129
00130
00131 edm::Handle<reco::BeamSpot> hBsp;
00132 evt.getByLabel(beamspot_, hBsp);
00133 reco::BeamSpot vertexBeamSpot;
00134 vertexBeamSpot = *hBsp;
00135
00136
00137 edm::Handle<reco::VertexCollection> hVtx;
00138 if (useVertices_) evt.getByLabel(vertices_, hVtx);
00139
00140 unsigned int trkSize=hSrcTrack->size();
00141 std::vector<int> selTracksSave( qualityToSet_.size()*trkSize,0);
00142
00143
00144 for (unsigned int i=0; i<qualityToSet_.size(); i++) {
00145 std::vector<int> selTracks(trkSize,0);
00146 auto_ptr<edm::ValueMap<int> > selTracksValueMap = auto_ptr<edm::ValueMap<int> >(new edm::ValueMap<int>);
00147 edm::ValueMap<int>::Filler filler(*selTracksValueMap);
00148
00149 std::vector<Point> points;
00150 std::vector<double> vterr;
00151 std::vector<double> vzerr;
00152 if (useVertices_) selectVertices(i,*hVtx, points, vterr, vzerr);
00153
00154
00155 size_t current = 0;
00156 for (TrackCollection::const_iterator it = hSrcTrack->begin(), ed = hSrcTrack->end(); it != ed; ++it, ++current) {
00157 const Track & trk = * it;
00158
00159
00160 LogTrace("TrackSelection") << "ready to check track with pt="<< trk.pt() ;
00161
00162
00163 bool ok=true;
00164 if (preFilter_[i]<i && selTracksSave[preFilter_[i]*trkSize+current] < 0) {
00165 selTracks.at(current)=-1;
00166 ok=false;
00167 if ( !keepAllTracks_[i])
00168 continue;
00169 }
00170 else {
00171 ok = select(i,vertexBeamSpot, trk, points, vterr, vzerr);
00172 if (!ok) {
00173 LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " NOT selected";
00174 if (!keepAllTracks_[i]) {
00175 selTracks.at(current)=-1;
00176 continue;
00177 }
00178 }
00179 else
00180 LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " selected";
00181 }
00182
00183 if (preFilter_[i]<i ) {
00184 selTracks.at(current)=selTracksSave[preFilter_[i]*trkSize+current];
00185 }
00186 else {
00187 selTracks.at(current)=trk.qualityMask();
00188 }
00189 if ( ok && setQualityBit_[i]) {
00190 selTracks.at(current)= (selTracks.at(current) | (1<<qualityToSet_[i]));
00191 if (!points.empty()) {
00192 if (qualityToSet_[i]==TrackBase::loose) {
00193 selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::looseSetWithPV));
00194 }
00195 else if (qualityToSet_[i]==TrackBase::highPurity) {
00196 selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::highPuritySetWithPV));
00197 }
00198 }
00199 }
00200 }
00201 for ( unsigned int j=0; j< trkSize; j++ ) selTracksSave[j+i*trkSize]=selTracks.at(j);
00202 filler.insert(hSrcTrack, selTracks.begin(),selTracks.end());
00203 filler.fill();
00204
00205
00206 evt.put(selTracksValueMap,name_[i]);
00207 }
00208 }
00209
00210
00211 bool MultiTrackSelector::select(unsigned int tsNum,
00212 const reco::BeamSpot &vertexBeamSpot,
00213 const reco::Track &tk,
00214 const std::vector<Point> &points,
00215 std::vector<double> &vterr,
00216 std::vector<double> &vzerr) {
00217
00218
00219 using namespace std;
00220
00221 if ( tk.ndof() < 1E-5 ) return false;
00222
00223
00224 uint32_t nlayers = tk.hitPattern().trackerLayersWithMeasurement();
00225 uint32_t nlayers3D = tk.hitPattern().pixelLayersWithMeasurement() +
00226 tk.hitPattern().numberOfValidStripLayersWithMonoAndStereo();
00227 uint32_t nlayersLost = tk.hitPattern().trackerLayersWithoutMeasurement();
00228 LogDebug("TrackSelection") << "cuts on nlayers: " << nlayers << " " << nlayers3D << " " << nlayersLost << " vs "
00229 << min_layers_[tsNum] << " " << min_3Dlayers_[tsNum] << " " << max_lostLayers_[tsNum];
00230 if (nlayers < min_layers_[tsNum]) return false;
00231 if (nlayers3D < min_3Dlayers_[tsNum]) return false;
00232 if (nlayersLost > max_lostLayers_[tsNum]) return false;
00233 LogTrace("TrackSelection") << "cuts on nlayers passed";
00234
00235 double chi2n = tk.normalizedChi2();
00236 double chi2n_no1Dmod = chi2n;
00237
00238 int count1dhits = 0;
00239 for (trackingRecHit_iterator ith = tk.recHitsBegin(), edh = tk.recHitsEnd(); ith != edh; ++ith) {
00240 const TrackingRecHit * hit = ith->get();
00241 DetId detid = hit->geographicalId();
00242 if (hit->isValid()) {
00243 if (typeid(*hit) == typeid(SiStripRecHit1D)) ++count1dhits;
00244 }
00245 }
00246 if (count1dhits > 0) {
00247 double chi2 = tk.chi2();
00248 double ndof = tk.ndof();
00249 chi2n = (chi2+count1dhits)/double(ndof+count1dhits);
00250 }
00251
00252
00253 if (chi2n > chi2n_par_[tsNum]*nlayers) return false;
00254
00255 if (chi2n_no1Dmod > chi2n_no1Dmod_par_[tsNum]*nlayers) return false;
00256
00257
00258 double pt = tk.pt(), eta = tk.eta();
00259
00260
00261 double relpterr = tk.ptError()/max(pt,1e-9);
00262 uint32_t nhits = tk.numberOfValidHits();
00263 if(relpterr > max_relpterr_[tsNum]) return false;
00264 if(nhits < min_nhits_[tsNum]) return false;
00265
00266
00267
00268 double d0 = -tk.dxy(vertexBeamSpot.position()), d0E = tk.d0Error(),
00269 dz = tk.dz(vertexBeamSpot.position()), dzE = tk.dzError();
00270
00271
00272 double nomd0E = sqrt(res_par_[tsNum][0]*res_par_[tsNum][0]+(res_par_[tsNum][1]/max(pt,1e-9))*(res_par_[tsNum][1]/max(pt,1e-9)));
00273
00274 double nomdzE = nomd0E*(std::cosh(eta));
00275
00276 double dzCut = min( pow(dz_par1_[tsNum][0]*nlayers,dz_par1_[tsNum][1])*nomdzE,
00277 pow(dz_par2_[tsNum][0]*nlayers,dz_par2_[tsNum][1])*dzE );
00278 double d0Cut = min( pow(d0_par1_[tsNum][0]*nlayers,d0_par1_[tsNum][1])*nomd0E,
00279 pow(d0_par2_[tsNum][0]*nlayers,d0_par2_[tsNum][1])*d0E );
00280
00281
00282
00283 bool primaryVertexZCompatibility(false);
00284 bool primaryVertexD0Compatibility(false);
00285
00286 if (points.empty()) {
00287
00288 if ( abs(dz) < hypot(vertexBeamSpot.sigmaZ()*nSigmaZ_[tsNum],dzCut) ) primaryVertexZCompatibility = true;
00289
00290 if (abs(d0) < d0Cut) primaryVertexD0Compatibility = true;
00291 }
00292
00293 int iv=0;
00294 for (std::vector<Point>::const_iterator point = points.begin(), end = points.end(); point != end; ++point) {
00295 LogTrace("TrackSelection") << "Test track w.r.t. vertex with z position " << point->z();
00296 if(primaryVertexZCompatibility && primaryVertexD0Compatibility) break;
00297 double dzPV = tk.dz(*point);
00298 double d0PV = tk.dxy(*point);
00299 if(useVtxError_){
00300 double dzErrPV = sqrt(dzE*dzE+vzerr[iv]*vzerr[iv]);
00301 double d0ErrPV = sqrt(d0E*d0E+vterr[iv]*vterr[iv]);
00302 iv++;
00303 if (abs(dzPV) < dz_par1_[tsNum][0]*pow(nlayers,dz_par1_[tsNum][1])*nomdzE &&
00304 abs(dzPV) < dz_par2_[tsNum][0]*pow(nlayers,dz_par2_[tsNum][1])*dzErrPV &&
00305 abs(dzPV) < max_z0_[tsNum]) primaryVertexZCompatibility = true;
00306 if (abs(d0PV) < d0_par1_[tsNum][0]*pow(nlayers,d0_par1_[tsNum][1])*nomd0E &&
00307 abs(d0PV) < d0_par2_[tsNum][0]*pow(nlayers,d0_par2_[tsNum][1])*d0ErrPV &&
00308 abs(d0PV) < max_d0_[tsNum]) primaryVertexD0Compatibility = true;
00309 }else{
00310 if (abs(dzPV) < dzCut) primaryVertexZCompatibility = true;
00311 if (abs(d0PV) < d0Cut) primaryVertexD0Compatibility = true;
00312 }
00313 LogTrace("TrackSelection") << "distances " << dzPV << " " << d0PV << " vs " << dzCut << " " << d0Cut;
00314 }
00315
00316 if (points.empty() && applyAbsCutsIfNoPV_[tsNum]) {
00317 if ( abs(dz) > max_z0NoPV_[tsNum] || abs(d0) > max_d0NoPV_[tsNum]) return false;
00318 } else {
00319
00320
00321 if (abs(d0) > max_d0_[tsNum] && !primaryVertexD0Compatibility) return false;
00322 LogTrace("TrackSelection") << "absolute cuts on d0 passed";
00323 if (abs(dz) > max_z0_[tsNum] && !primaryVertexZCompatibility) return false;
00324 LogTrace("TrackSelection") << "absolute cuts on dz passed";
00325 }
00326
00327 LogTrace("TrackSelection") << "cuts on PV: apply adapted PV cuts? " << applyAdaptedPVCuts_[tsNum]
00328 << " d0 compatibility? " << primaryVertexD0Compatibility
00329 << " z compatibility? " << primaryVertexZCompatibility ;
00330
00331 if (applyAdaptedPVCuts_[tsNum]) {
00332 return (primaryVertexD0Compatibility && primaryVertexZCompatibility);
00333 } else {
00334 return true;
00335 }
00336
00337 }
00338
00339 void MultiTrackSelector::selectVertices(unsigned int tsNum,
00340 const reco::VertexCollection &vtxs,
00341 std::vector<Point> &points,
00342 std::vector<double> &vterr,
00343 std::vector<double> &vzerr) {
00344
00345 using namespace reco;
00346 int32_t toTake = vtxNumber_[tsNum];
00347 for (VertexCollection::const_iterator it = vtxs.begin(), ed = vtxs.end(); it != ed; ++it) {
00348
00349 LogDebug("SelectVertex") << " select vertex with z position " << it->z() << " "
00350 << it->chi2() << " " << it->ndof() << " " << TMath::Prob(it->chi2(), static_cast<int32_t>(it->ndof()));
00351 Vertex vtx = *it;
00352 bool pass = vertexCut_[tsNum]( vtx );
00353 if( pass ) {
00354 points.push_back(it->position());
00355 vterr.push_back(sqrt(it->yError()*it->xError()));
00356 vzerr.push_back(it->zError());
00357 LogTrace("SelectVertex") << " SELECTED vertex with z position " << it->z();
00358 toTake--; if (toTake == 0) break;
00359 }
00360 }
00361 }