00001 #include "MuScleFitMuonSelector.h"
00002 #include "DataFormats/MuonReco/interface/CaloMuon.h"
00003 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00004
00005 const double MuScleFitMuonSelector::mMu2 = 0.011163612;
00006 const unsigned int MuScleFitMuonSelector::motherPdgIdArray[] = {23, 100553, 100553, 553, 100443, 443};
00007
00008 const reco::Candidate*
00009 MuScleFitMuonSelector::getStatus1Muon(const reco::Candidate* status3Muon){
00010 const reco::Candidate* tempStatus1Muon = status3Muon;
00011 int status = tempStatus1Muon->status();
00012 while(tempStatus1Muon == 0 || tempStatus1Muon->numberOfDaughters()!=0){
00013 if (status == 1) break;
00014
00015 for (unsigned int i=0; i<tempStatus1Muon->numberOfDaughters(); ++i){
00016 if ( tempStatus1Muon->daughter(i)->pdgId()==tempStatus1Muon->pdgId() ){
00017 tempStatus1Muon = tempStatus1Muon->daughter(i);
00018 status = tempStatus1Muon->status();
00019 break;
00020 }else continue;
00021 }
00022 }
00023
00024 return tempStatus1Muon;
00025 }
00026
00027
00028 bool MuScleFitMuonSelector::selGlobalMuon(const pat::Muon* aMuon)
00029 {
00030 reco::TrackRef iTrack = aMuon->innerTrack();
00031 const reco::HitPattern& p = iTrack->hitPattern();
00032
00033 reco::TrackRef gTrack = aMuon->globalTrack();
00034 const reco::HitPattern& q = gTrack->hitPattern();
00035
00036 return (
00037 iTrack->found() > 11 &&
00038 gTrack->chi2()/gTrack->ndof() < 20.0 &&
00039 q.numberOfValidMuonHits() > 0 &&
00040 iTrack->chi2()/iTrack->ndof() < 4.0 &&
00041 aMuon->muonID("TrackerMuonArbitrated") &&
00042 aMuon->muonID("TMLastStationAngTight") &&
00043 p.pixelLayersWithMeasurement() > 1 &&
00044 fabs(iTrack->dxy()) < 3.0 &&
00045 fabs(iTrack->dz()) < 15.0
00046 );
00047 }
00048
00049 bool MuScleFitMuonSelector::selTrackerMuon(const pat::Muon* aMuon)
00050 {
00051 reco::TrackRef iTrack = aMuon->innerTrack();
00052 const reco::HitPattern& p = iTrack->hitPattern();
00053
00054 return (
00055 iTrack->found() > 11 &&
00056 iTrack->chi2()/iTrack->ndof() < 4.0 &&
00057 aMuon->muonID("TrackerMuonArbitrated") &&
00058 aMuon->muonID("TMLastStationAngTight") &&
00059 p.pixelLayersWithMeasurement() > 1 &&
00060 fabs(iTrack->dxy()) < 3.0 &&
00061 fabs(iTrack->dz()) < 15.0
00062 );
00063 }
00064
00065
00066
00067
00068 void MuScleFitMuonSelector::selectMuons(const edm::Event & event, std::vector<reco::LeafCandidate> & muons,
00069 std::vector<GenMuonPair> & genPair,
00070 std::vector<std::pair<lorentzVector,lorentzVector> > & simPair,
00071 MuScleFitPlotter * plotter)
00072 {
00073 edm::Handle<pat::CompositeCandidateCollection > collAll;
00074 try {event.getByLabel("onia2MuMuPatTrkTrk",collAll);}
00075 catch (...) {std::cout << "J/psi not present in event!" << std::endl;}
00076 std::vector<const pat::Muon*> collMuSel;
00077
00078
00079
00080 if( muonType_ <= -1 && PATmuons_) {
00081 std::vector<const pat::CompositeCandidate*> collSelGG;
00082 std::vector<const pat::CompositeCandidate*> collSelGT;
00083 std::vector<const pat::CompositeCandidate*> collSelTT;
00084 if (collAll.isValid()) {
00085
00086 for(std::vector<pat::CompositeCandidate>::const_iterator it=collAll->begin();
00087 it!=collAll->end();++it) {
00088
00089 const pat::CompositeCandidate* cand = &(*it);
00090
00091 const pat::Muon* muon1 = dynamic_cast<const pat::Muon*>(cand->daughter("muon1"));
00092 const pat::Muon* muon2 = dynamic_cast<const pat::Muon*>(cand->daughter("muon2"));
00093
00094 if((muon1->charge() * muon2->charge())>0)
00095 continue;
00096
00097 if (muon1->isGlobalMuon() && muon2->isGlobalMuon() ) {
00098 if (selGlobalMuon(muon1) && selGlobalMuon(muon2) && cand->userFloat("vProb") > 0.001 ) {
00099 collSelGG.push_back(cand);
00100 continue;
00101 }
00102 }
00103
00104 if (muon1->isGlobalMuon() && muon2->isTrackerMuon() ) {
00105 if (selGlobalMuon(muon1) && selTrackerMuon(muon2) && cand->userFloat("vProb") > 0.001 ) {
00106 collSelGT.push_back(cand);
00107 continue;
00108 }
00109 }
00110 if (muon2->isGlobalMuon() && muon1->isTrackerMuon() ) {
00111 if (selGlobalMuon(muon2) && selTrackerMuon(muon1) && cand->userFloat("vProb") > 0.001) {
00112 collSelGT.push_back(cand);
00113 continue;
00114 }
00115 }
00116
00117 if (muon1->isTrackerMuon() && muon2->isTrackerMuon() ) {
00118 if (selTrackerMuon(muon1) && selTrackerMuon(muon2) && cand->userFloat("vProb") > 0.001) {
00119 collSelTT.push_back(cand);
00120 continue;
00121 }
00122 }
00123 }
00124 }
00125
00126 std::vector<reco::Track> tracks;
00127 if(collSelGG.size()){
00128
00129 const pat::Muon* muon1 = dynamic_cast<const pat::Muon*>(collSelGG[0]->daughter("muon1"));
00130 const pat::Muon* muon2 = dynamic_cast<const pat::Muon*>(collSelGG[0]->daughter("muon2"));
00131 if( muonType_ == -1 || muonType_ == -2 ) {
00132 tracks.push_back(*(muon1->innerTrack()));
00133 tracks.push_back(*(muon2->innerTrack()));
00134 collMuSel.push_back(muon1);
00135 collMuSel.push_back(muon2);
00136 }
00137 }
00138 else if(!collSelGG.size() && collSelGT.size()){
00139
00140 const pat::Muon* muon1 = dynamic_cast<const pat::Muon*>(collSelGT[0]->daughter("muon1"));
00141 const pat::Muon* muon2 = dynamic_cast<const pat::Muon*>(collSelGT[0]->daughter("muon2"));
00142 if( muonType_ == -1 || muonType_ == -3 ) {
00143 tracks.push_back(*(muon1->innerTrack()));
00144 tracks.push_back(*(muon2->innerTrack()));
00145 collMuSel.push_back(muon1);
00146 collMuSel.push_back(muon2);
00147 }
00148 }
00149 else if(!collSelGG.size() && !collSelGT.size() && collSelTT.size()){
00150
00151 const pat::Muon* muon1 = dynamic_cast<const pat::Muon*>(collSelTT[0]->daughter("muon1"));
00152 const pat::Muon* muon2 = dynamic_cast<const pat::Muon*>(collSelTT[0]->daughter("muon2"));
00153 if( muonType_ == -1 || muonType_ == -4 ) {
00154 tracks.push_back(*(muon1->innerTrack()));
00155 tracks.push_back(*(muon2->innerTrack()));
00156 collMuSel.push_back(muon1);
00157 collMuSel.push_back(muon2);
00158 }
00159 }
00160 if (tracks.size() != 2 && tracks.size() != 0){
00161 std::cout<<"ERROR strange number of muons selected by onia cuts!"<<std::endl;
00162 abort();
00163 }
00164 muons = fillMuonCollection(tracks);
00165 }
00166 else if( (muonType_<4 && muonType_>=0) || muonType_>=10 ) {
00167 std::vector<reco::Track> tracks;
00168 if( PATmuons_ == true ) {
00169 edm::Handle<pat::MuonCollection> allMuons;
00170 event.getByLabel( muonLabel_, allMuons );
00171 if( muonType_ == 0 ) {
00172
00173 muons = fillMuonCollection(*allMuons);
00174 }
00175 else {
00176 for( std::vector<pat::Muon>::const_iterator muon = allMuons->begin(); muon != allMuons->end(); ++muon ) {
00177
00178 takeSelectedMuonType(muon, tracks);
00179 }
00180 muons = fillMuonCollection(tracks);
00181 }
00182 }
00183 else {
00184 edm::Handle<reco::MuonCollection> allMuons;
00185 event.getByLabel (muonLabel_, allMuons);
00186 if( muonType_ == 0 ) {
00187
00188 muons = fillMuonCollection(*allMuons);
00189 }
00190 else {
00191 for( std::vector<reco::Muon>::const_iterator muon = allMuons->begin(); muon != allMuons->end(); ++muon ) {
00192 takeSelectedMuonType(muon, tracks);
00193 }
00194 muons = fillMuonCollection(tracks);
00195 }
00196 }
00197 }
00198 else if(muonType_==4){
00199 edm::Handle<reco::CaloMuonCollection> caloMuons;
00200 event.getByLabel (muonLabel_, caloMuons);
00201 std::vector<reco::Track> tracks;
00202 for (std::vector<reco::CaloMuon>::const_iterator muon = caloMuons->begin(); muon != caloMuons->end(); ++muon){
00203 tracks.push_back(*(muon->track()));
00204 }
00205 muons = fillMuonCollection(tracks);
00206 }
00207
00208 else if (muonType_==5) {
00209 edm::Handle<reco::TrackCollection> tracks;
00210 event.getByLabel (muonLabel_, tracks);
00211 muons = fillMuonCollection(*tracks);
00212 }
00213 plotter->fillRec(muons);
00214
00215
00216 if( speedup_ == false )
00217 {
00218 if( PATmuons_ ) {
00219 selectGeneratedMuons(collAll, collMuSel, genPair, plotter);
00220 }
00221 else {
00222 selectGenSimMuons(event, genPair, simPair, plotter);
00223 }
00224 }
00225 }
00226
00228 void MuScleFitMuonSelector::selectGeneratedMuons(const edm::Handle<pat::CompositeCandidateCollection> & collAll,
00229 const std::vector<const pat::Muon*> & collMuSel,
00230 std::vector<GenMuonPair> & genPair,
00231 MuScleFitPlotter * plotter)
00232 {
00233 reco::GenParticleCollection* genPatParticles = new reco::GenParticleCollection;
00234
00235
00236 for(std::vector<pat::CompositeCandidate>::const_iterator it=collAll->begin();
00237 it!=collAll->end();++it) {
00238 reco::GenParticleRef genJpsi = it->genParticleRef();
00239 bool isMatched = (genJpsi.isAvailable() && genJpsi->pdgId() == 443);
00240 if (isMatched){
00241 genPatParticles->push_back(*(const_cast<reco::GenParticle*>(genJpsi.get())));
00242 }
00243 }
00244
00245 if(collMuSel.size()==2) {
00246 reco::GenParticleRef genMu1 = collMuSel[0]->genParticleRef();
00247 reco::GenParticleRef genMu2 = collMuSel[1]->genParticleRef();
00248 bool isMuMatched = (genMu1.isAvailable() && genMu2.isAvailable() &&
00249 genMu1->pdgId()*genMu2->pdgId() == -169);
00250 if (isMuMatched) {
00251 genPatParticles->push_back(*(const_cast<reco::GenParticle*>(genMu1.get())));
00252 genPatParticles->push_back(*(const_cast<reco::GenParticle*>(genMu2.get())));
00253
00254 unsigned int motherId = 0;
00255 if( genMu1->mother() != 0 ) {
00256 motherId = genMu1->mother()->pdgId();
00257 }
00258 if(genMu1->pdgId()==13)
00259 genPair.push_back(GenMuonPair(genMu1.get()->p4(), genMu2.get()->p4(), motherId));
00260 else
00261
00262 genPair.push_back(GenMuonPair(genMu2.get()->p4(), genMu1.get()->p4(), motherId));
00263
00264 plotter->fillGen(const_cast <reco::GenParticleCollection*> (genPatParticles), true);
00265
00266 if (debug_>0) std::cout << "Found genParticles in PAT" << std::endl;
00267 }
00268 else {
00269 std::cout << "No recomuon selected so no access to generated info"<<std::endl;
00270
00271
00272 genPair.push_back( GenMuonPair(lorentzVector(0.,0.,0.,0.), lorentzVector(0.,0.,0.,0.), 0 ) );
00273 }
00274 }
00275 else{
00276 std::cout << "No recomuon selected so no access to generated info"<<std::endl;
00277
00278
00279 genPair.push_back( GenMuonPair(lorentzVector(0.,0.,0.,0.), lorentzVector(0.,0.,0.,0.), 0 ) );
00280 }
00281 if(debug_>0) {
00282 std::cout << "genParticles:" << std::endl;
00283
00284 std::cout << genPair.back().mu1 << " , " << genPair.back().mu2 << std::endl;
00285 }
00286 }
00287
00288 void MuScleFitMuonSelector::selectGenSimMuons(const edm::Event & event,
00289 std::vector<GenMuonPair> & genPair,
00290 std::vector<std::pair<lorentzVector,lorentzVector> > & simPair,
00291 MuScleFitPlotter * plotter)
00292 {
00293
00294
00295 edm::Handle<edm::HepMCProduct> evtMC;
00296 edm::Handle<reco::GenParticleCollection> genParticles;
00297
00298
00299 bool ifHepMC=false;
00300
00301 event.getByLabel( genParticlesName_, evtMC );
00302 event.getByLabel( genParticlesName_, genParticles );
00303 if( evtMC.isValid() ) {
00304 genPair.push_back( findGenMuFromRes(evtMC.product()) );
00305 plotter->fillGen(evtMC.product(), sherpa_);
00306 ifHepMC = true;
00307 if (debug_>0) std::cout << "Found hepMC" << std::endl;
00308 }
00309 else if( genParticles.isValid() ) {
00310 genPair.push_back( findGenMuFromRes(genParticles.product()) );
00311 plotter->fillGen(genParticles.product());
00312 if (debug_>0) std::cout << "Found genParticles" << std::endl;
00313 }
00314 else {
00315 std::cout<<"ERROR "<<"non generation info and speedup true!!!!!!!!!!!!"<<std::endl;
00316
00317
00318 genPair.push_back( GenMuonPair( lorentzVector(0.,0.,0.,0.), lorentzVector(0.,0.,0.,0.), 0 ) );
00319 }
00320 if(debug_>0) {
00321 std::cout << "genParticles:" << std::endl;
00322 std::cout << genPair.back().mu1 << " , " << genPair.back().mu2 << std::endl;
00323 }
00324 selectSimulatedMuons(event, ifHepMC, evtMC, simPair, plotter);
00325 }
00326
00327 void MuScleFitMuonSelector::selectSimulatedMuons(const edm::Event & event,
00328 const bool ifHepMC, edm::Handle<edm::HepMCProduct> evtMC,
00329 std::vector<std::pair<lorentzVector,lorentzVector> > & simPair,
00330 MuScleFitPlotter * plotter)
00331 {
00332 edm::Handle<edm::SimTrackContainer> simTracks;
00333 bool simTracksFound = false;
00334 event.getByLabel(simTracksCollectionName_, simTracks);
00335 if( simTracks.isValid() ) {
00336 plotter->fillSim(simTracks);
00337 if(ifHepMC) {
00338 simPair.push_back( findSimMuFromRes(evtMC, simTracks) );
00339 simTracksFound = true;
00340 plotter->fillGenSim(evtMC,simTracks);
00341 }
00342 }
00343 else {
00344 std::cout << "SimTracks not existent" << std::endl;
00345 }
00346 if( !simTracksFound ) {
00347 simPair.push_back( std::make_pair( lorentzVector(0.,0.,0.,0.), lorentzVector(0.,0.,0.,0.) ) );
00348 }
00349 }
00350
00351 GenMuonPair MuScleFitMuonSelector::findGenMuFromRes( const edm::HepMCProduct* evtMC )
00352 {
00353 const HepMC::GenEvent* Evt = evtMC->GetEvent();
00354 GenMuonPair muFromRes;
00355
00356 for (HepMC::GenEvent::particle_const_iterator part=Evt->particles_begin();
00357 part!=Evt->particles_end(); part++) {
00358 if (fabs((*part)->pdg_id())==13 && (*part)->status()==1) {
00359 bool fromRes = false;
00360 unsigned int motherPdgId = 0;
00361 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
00362 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
00363 motherPdgId = (*mother)->pdg_id();
00364
00365
00366
00367 if( sherpa_ ) {
00368 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes = true;
00369 }
00370 else {
00371 for( int ires = 0; ires < 6; ++ires ) {
00372 if( motherPdgId == motherPdgIdArray[ires] && resfind_[ires] ) fromRes = true;
00373 }
00374 }
00375 }
00376 if(fromRes){
00377 if((*part)->pdg_id()==13) {
00378
00379 muFromRes.mu1 = (lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
00380 (*part)->momentum().pz(),(*part)->momentum().e()));
00381 }
00382 else {
00383 muFromRes.mu2 = (lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
00384 (*part)->momentum().pz(),(*part)->momentum().e()));
00385 }
00386 muFromRes.motherId = motherPdgId;
00387 }
00388 }
00389 }
00390 return muFromRes;
00391 }
00392
00393
00394 GenMuonPair MuScleFitMuonSelector::findGenMuFromRes( const reco::GenParticleCollection* genParticles)
00395 {
00396
00397 GenMuonPair muFromRes;
00398
00399
00400 if( debug_>0 ) std::cout << "Starting loop on " << genParticles->size() << " genParticles" << std::endl;
00401 for( reco::GenParticleCollection::const_iterator part=genParticles->begin(); part!=genParticles->end(); ++part ) {
00402 if (debug_>0) std::cout<<"genParticle has pdgId = "<<fabs(part->pdgId())<<" and status = "<<part->status()<<std::endl;
00403 if (fabs(part->pdgId())==13){
00404 bool fromRes = false;
00405 unsigned int motherPdgId = part->mother()->pdgId();
00406 if( debug_>0 ) {
00407 std::cout << "Found a muon with mother: " << motherPdgId << std::endl;
00408 }
00409 for( int ires = 0; ires < 6; ++ires ) {
00410 if( motherPdgId == motherPdgIdArray[ires] && resfind_[ires] ) fromRes = true;
00411 }
00412 if(fromRes){
00413 if (debug_>0) std::cout<<"fromRes = true, motherPdgId = "<<motherPdgId<<std::endl;
00414 const reco::Candidate* status3Muon = &(*part);
00415 const reco::Candidate* status1Muon = getStatus1Muon(status3Muon);
00416 if(part->pdgId()==13) {
00417 muFromRes.mu1 = status1Muon->p4();
00418 if( debug_>0 ) std::cout << "Found a genMuon - : " << muFromRes.mu1 << std::endl;
00419
00420
00421 }
00422 else {
00423 muFromRes.mu2 = status1Muon->p4();
00424 if( debug_>0 ) std::cout << "Found a genMuon + : " << muFromRes.mu2 << std::endl;
00425
00426
00427 }
00428 }
00429 }
00430 }
00431 return muFromRes;
00432 }
00433
00434 std::pair<lorentzVector, lorentzVector> MuScleFitMuonSelector::findSimMuFromRes( const edm::Handle<edm::HepMCProduct> & evtMC,
00435 const edm::Handle<edm::SimTrackContainer> & simTracks )
00436 {
00437
00438 std::pair<lorentzVector, lorentzVector> simMuFromRes;
00439 for( edm::SimTrackContainer::const_iterator simTrack=simTracks->begin(); simTrack!=simTracks->end(); ++simTrack ) {
00440
00441 if (fabs((*simTrack).type())==13) {
00442
00443 if ((*simTrack).genpartIndex()>0) {
00444 HepMC::GenParticle* gp = evtMC->GetEvent()->barcode_to_particle ((*simTrack).genpartIndex());
00445 if( gp != 0 ) {
00446
00447 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
00448 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
00449
00450 bool fromRes = false;
00451 unsigned int motherPdgId = (*mother)->pdg_id();
00452 for( int ires = 0; ires < 6; ++ires ) {
00453 if( motherPdgId == motherPdgIdArray[ires] && resfind_[ires] ) fromRes = true;
00454 }
00455 if( fromRes ) {
00456 if(gp->pdg_id() == 13)
00457 simMuFromRes.first = lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
00458 simTrack->momentum().pz(),simTrack->momentum().e());
00459 else
00460 simMuFromRes.second = lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
00461 simTrack->momentum().pz(),simTrack->momentum().e());
00462 }
00463 }
00464 }
00465
00466 }
00467 }
00468 }
00469 return simMuFromRes;
00470 }