00001 #include "RecoParticleFlow/PFBlockProducer/interface/PFSimParticleProducer.h"
00002
00003 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00004 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00005
00006 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
00007 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00008
00009 #include "DataFormats/ParticleFlowReco/interface/PFSimParticle.h"
00010 #include "DataFormats/ParticleFlowReco/interface/PFSimParticleFwd.h"
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "FWCore/Framework/interface/ESHandle.h"
00022 #include "MagneticField/Engine/interface/MagneticField.h"
00023 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00024 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00025 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00026 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00027 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00028 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00029 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00030 #include "DataFormats/GeometrySurface/interface/TkRotation.h"
00031 #include "DataFormats/GeometrySurface/interface/SimpleCylinderBounds.h"
00032 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
00033 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00034 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00035 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00036 #include "TrackingTools/PatternTools/interface/TrajectoryFitter.h"
00037
00038 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00039
00040 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00041 #include "FWCore/Utilities/interface/Exception.h"
00042 #include "FWCore/Framework/interface/EventSetup.h"
00043
00044 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
00045 #include "FastSimulation/Event/interface/FSimEvent.h"
00046 #include "FastSimulation/Event/interface/FSimTrack.h"
00047 #include "FastSimulation/Event/interface/FSimVertex.h"
00048 #include "FastSimulation/Particle/interface/ParticleTable.h"
00049
00050 #include "SimDataFormats/CaloHit/interface/PCaloHit.h"
00051 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00052 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00053 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00054 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00055 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
00056 #include "DataFormats/TrackReco/interface/Track.h"
00057 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00058 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSMatchedRecHit2D.h"
00059 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSMatchedRecHit2DCollection.h"
00060
00061 #include <set>
00062 #include <sstream>
00063
00064 using namespace std;
00065 using namespace edm;
00066
00067 PFSimParticleProducer::PFSimParticleProducer(const edm::ParameterSet& iConfig)
00068 {
00069
00070
00071 processParticles_ =
00072 iConfig.getUntrackedParameter<bool>("process_Particles",true);
00073
00074
00075 inputTagSim_
00076 = iConfig.getParameter<InputTag>("sim");
00077
00078
00079
00080
00081 inputTagFamosSimHits_
00082 = iConfig.getUntrackedParameter<InputTag>("famosSimHits");
00083 mctruthMatchingInfo_ =
00084 iConfig.getUntrackedParameter<bool>("MCTruthMatchingInfo",false);
00085
00086
00087 inputTagRecTracks_
00088 = iConfig.getParameter<InputTag>("RecTracks");
00089 inputTagEcalRecHitsEB_
00090 = iConfig.getParameter<InputTag>("ecalRecHitsEB");
00091 inputTagEcalRecHitsEE_
00092 = iConfig.getParameter<InputTag>("ecalRecHitsEE");
00093
00094 verbose_ =
00095 iConfig.getUntrackedParameter<bool>("verbose",false);
00096
00097
00098
00099 produces<reco::PFSimParticleCollection>();
00100
00101 particleFilter_ = iConfig.getParameter<ParameterSet>
00102 ( "ParticleFilter" );
00103
00104 mySimEvent = new FSimEvent( particleFilter_ );
00105 }
00106
00107
00108
00109 PFSimParticleProducer::~PFSimParticleProducer()
00110 {
00111 delete mySimEvent;
00112 }
00113
00114
00115 void
00116 PFSimParticleProducer::beginJob(const edm::EventSetup & es)
00117 {
00118
00119
00120 edm::ESHandle < HepPDT::ParticleDataTable > pdt;
00121
00122 es.getData(pdt);
00123 if ( !ParticleTable::instance() ) ParticleTable::instance(&(*pdt));
00124 mySimEvent->initializePdt(&(*pdt));
00125 }
00126
00127
00128 void PFSimParticleProducer::produce(Event& iEvent,
00129 const EventSetup& iSetup)
00130 {
00131
00132 LogDebug("PFSimParticleProducer")<<"START event: "<<iEvent.id().event()
00133 <<" in run "<<iEvent.id().run()<<endl;
00134
00135
00136
00137
00138
00139 std::vector<unsigned> recTrackSimID;
00140
00141
00142
00143
00144
00145 typedef std::pair<double, unsigned> hitSimID;
00146 typedef std::list< std::pair<double, unsigned> >::iterator ITM;
00147 std::vector< std::list <hitSimID> > caloHitsEBID(62000);
00148 std::vector<double> caloHitsEBTotE(62000,0.0);
00149
00150 if(mctruthMatchingInfo_){
00151
00152
00153 edm::Handle<edm::PCaloHitContainer> pcalohits;
00154
00155
00156
00157
00158 bool found_phit
00159 = iEvent.getByLabel(inputTagFamosSimHits_,pcalohits);
00160
00161
00162 if(!found_phit) {
00163 ostringstream err;
00164 err<<"could not find pcaloHit "<<"famosSimHits:EcalHitsEB";
00165 LogError("PFSimParticleProducer")<<err.str()<<endl;
00166
00167 throw cms::Exception( "MissingProduct", err.str());
00168 }
00169 else {
00170 assert( pcalohits.isValid() );
00171
00172
00173
00174
00175 edm::PCaloHitContainer::const_iterator it
00176 = pcalohits.product()->begin();
00177 edm::PCaloHitContainer::const_iterator itend
00178 = pcalohits.product()->end();
00179
00180
00181 for(;it!=itend;++it)
00182 {
00183 EBDetId detid(it->id());
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 if(it->energy() > 0.0) {
00194 std::pair<double, unsigned> phitsimid
00195 = make_pair(it->energy(),it->geantTrackId());
00196 caloHitsEBID[detid.hashedIndex()].push_back(phitsimid);
00197 caloHitsEBTotE[detid.hashedIndex()]
00198 += it->energy();
00199 }
00200
00201 }
00202 }
00203
00204
00205
00206 Handle< reco::PFRecTrackCollection > recTracks;
00207 try{
00208 LogDebug("PFSimParticleProducer")<<"getting PFRecTracks"<<endl;
00209 iEvent.getByLabel(inputTagRecTracks_, recTracks);
00210
00211 } catch (cms::Exception& err) {
00212 LogError("PFSimParticleProducer")<<err
00213 <<" cannot get collection "
00214 <<"particleFlowBlock"<<":"
00215 <<""
00216 <<endl;
00217 }
00218
00219
00220
00221 getSimIDs( recTracks, recTrackSimID );
00222
00223 }
00224
00225
00226 if( processParticles_) {
00227
00228 auto_ptr< reco::PFSimParticleCollection >
00229 pOutputPFSimParticleCollection(new reco::PFSimParticleCollection );
00230
00231 Handle<vector<SimTrack> > simTracks;
00232 bool found = iEvent.getByLabel(inputTagSim_,simTracks);
00233 if(!found) {
00234
00235 ostringstream err;
00236 err<<"cannot find sim tracks: "<<inputTagSim_;
00237 LogError("PFSimParticleProducer")<<err.str()<<endl;
00238
00239 throw cms::Exception( "MissingProduct", err.str());
00240 }
00241
00242
00243
00244 Handle<vector<SimVertex> > simVertices;
00245 found = iEvent.getByLabel(inputTagSim_,simVertices);
00246 if(!found) {
00247 LogError("PFSimParticleProducer")
00248 <<"cannot find sim vertices: "<<inputTagSim_<<endl;
00249 return;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 mySimEvent->fill( *simTracks, *simVertices );
00261
00262 if(verbose_)
00263 mySimEvent->print();
00264
00265
00266 for(unsigned i=0; i<mySimEvent->nTracks(); i++) {
00267
00268 const FSimTrack& fst = mySimEvent->track(i);
00269
00270 int motherId = -1;
00271 if( ! fst.noMother() )
00272 motherId = fst.mother().id();
00273
00274
00275
00276
00277
00278
00279
00280
00281 unsigned recTrackID = 99999;
00282 vector<unsigned> recHitContrib;
00283 vector<double> recHitContribFrac;
00284
00285 if(mctruthMatchingInfo_){
00286
00287 for(unsigned lo=0; lo<recTrackSimID.size();
00288 lo++) {
00289 if( i == recTrackSimID[lo] ) {
00290
00291
00292 recTrackID = lo;
00293 }
00294 }
00295
00296
00297
00298
00299
00300 edm::Handle<EcalRecHitCollection> rhcHandle;
00301 bool found = iEvent.getByLabel(inputTagEcalRecHitsEB_,
00302 rhcHandle);
00303 if(!found) {
00304 ostringstream err;
00305 err<<"could not find rechits "<< inputTagEcalRecHitsEB_;
00306 LogError("PFSimParticleProducer")<<err.str()<<endl;
00307
00308 throw cms::Exception( "MissingProduct", err.str());
00309 }
00310 else {
00311 assert( rhcHandle.isValid() );
00312
00313
00314
00315 EBRecHitCollection::const_iterator it_rh
00316 = rhcHandle.product()->begin();
00317 EBRecHitCollection::const_iterator itend_rh
00318 = rhcHandle.product()->end();
00319
00320 for(;it_rh!=itend_rh;++it_rh)
00321 {
00322 unsigned rhit_hi
00323 = EBDetId(it_rh->id()).hashedIndex();
00324 EBDetId detid(it_rh->id());
00325
00326
00327
00328
00329 ITM it_phit = caloHitsEBID[rhit_hi].begin();
00330 ITM itend_phit = caloHitsEBID[rhit_hi].end();
00331 for(;it_phit!=itend_phit;++it_phit)
00332 {
00333 if(i == it_phit->second)
00334 {
00335
00336
00337 bool alreadyin = false;
00338 for( unsigned ihit = 0; ihit < recHitContrib.size();
00339 ++ihit )
00340 if(detid.rawId() == recHitContrib[ihit])
00341 alreadyin = true;
00342
00343 if(!alreadyin){
00344 double pcalofraction = 0.0;
00345 if(caloHitsEBTotE[rhit_hi] != 0.0)
00346 pcalofraction
00347 = (it_phit->first/caloHitsEBTotE[rhit_hi])*100.0;
00348
00349
00350 recHitContrib.push_back(it_rh->id());
00351 recHitContribFrac.push_back(pcalofraction);
00352 }
00353 }
00354 }
00355
00356 }
00357
00358 }
00359
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 reco::PFSimParticle particle( fst.charge(),
00370 fst.type(),
00371 fst.id(),
00372 motherId,
00373 fst.daughters(),
00374 recTrackID,
00375 recHitContrib,
00376 recHitContribFrac);
00377
00378
00379 const FSimVertex& originVtx = fst.vertex();
00380
00381 math::XYZPoint posOrig( originVtx.position().x(),
00382 originVtx.position().y(),
00383 originVtx.position().z() );
00384
00385 math::XYZTLorentzVector momOrig( fst.momentum().px(),
00386 fst.momentum().py(),
00387 fst.momentum().pz(),
00388 fst.momentum().e() );
00389 reco::PFTrajectoryPoint
00390 pointOrig(-1,
00391 reco::PFTrajectoryPoint::ClosestApproach,
00392 posOrig, momOrig);
00393
00394
00395 particle.addPoint(pointOrig);
00396
00397
00398 if( ! fst.noEndVertex() ) {
00399 const FSimVertex& endVtx = fst.endVertex();
00400
00401 math::XYZPoint posEnd( endVtx.position().x(),
00402 endVtx.position().y(),
00403 endVtx.position().z() );
00404
00405
00406
00407
00408 math::XYZTLorentzVector momEnd;
00409
00410 reco::PFTrajectoryPoint
00411 pointEnd( -1,
00412 reco::PFTrajectoryPoint::BeamPipeOrEndVertex,
00413 posEnd, momEnd);
00414
00415 particle.addPoint(pointEnd);
00416 }
00417 else {
00418 reco::PFTrajectoryPoint dummy;
00419 particle.addPoint(dummy);
00420 }
00421
00422
00423 if( fst.onLayer1() ) {
00424 const RawParticle& rp = fst.layer1Entrance();
00425
00426 math::XYZPoint posLayer1( rp.x(), rp.y(), rp.z() );
00427 math::XYZTLorentzVector momLayer1( rp.px(), rp.py(), rp.pz(), rp.e() );
00428 reco::PFTrajectoryPoint layer1Pt(-1, reco::PFTrajectoryPoint::PS1,
00429 posLayer1, momLayer1);
00430
00431 particle.addPoint( layer1Pt );
00432
00433
00434 }
00435 else {
00436 reco::PFTrajectoryPoint dummy;
00437 particle.addPoint(dummy);
00438 }
00439
00440 if( fst.onLayer2() ) {
00441 const RawParticle& rp = fst.layer2Entrance();
00442
00443 math::XYZPoint posLayer2( rp.x(), rp.y(), rp.z() );
00444 math::XYZTLorentzVector momLayer2( rp.px(), rp.py(), rp.pz(), rp.e() );
00445 reco::PFTrajectoryPoint layer2Pt(-1, reco::PFTrajectoryPoint::PS2,
00446 posLayer2, momLayer2);
00447
00448 particle.addPoint( layer2Pt );
00449
00450
00451 }
00452 else {
00453 reco::PFTrajectoryPoint dummy;
00454 particle.addPoint(dummy);
00455 }
00456
00457 if( fst.onEcal() ) {
00458 const RawParticle& rp = fst.ecalEntrance();
00459
00460 math::XYZPoint posECAL( rp.x(), rp.y(), rp.z() );
00461 math::XYZTLorentzVector momECAL( rp.px(), rp.py(), rp.pz(), rp.e() );
00462 reco::PFTrajectoryPoint ecalPt(-1,
00463 reco::PFTrajectoryPoint::ECALEntrance,
00464 posECAL, momECAL);
00465
00466 particle.addPoint( ecalPt );
00467
00468
00469 }
00470 else {
00471 reco::PFTrajectoryPoint dummy;
00472 particle.addPoint(dummy);
00473 }
00474
00475
00476 reco::PFTrajectoryPoint dummy;
00477 particle.addPoint(dummy);
00478
00479 if( fst.onHcal() ) {
00480
00481 const RawParticle& rpin = fst.hcalEntrance();
00482
00483 math::XYZPoint posHCALin( rpin.x(), rpin.y(), rpin.z() );
00484 math::XYZTLorentzVector momHCALin( rpin.px(), rpin.py(), rpin.pz(),
00485 rpin.e() );
00486 reco::PFTrajectoryPoint hcalPtin(-1,
00487 reco::PFTrajectoryPoint::HCALEntrance,
00488 posHCALin, momHCALin);
00489
00490 particle.addPoint( hcalPtin );
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504 else {
00505 reco::PFTrajectoryPoint dummy;
00506 particle.addPoint(dummy);
00507 }
00508
00509 pOutputPFSimParticleCollection->push_back( particle );
00510 }
00511
00512 iEvent.put(pOutputPFSimParticleCollection);
00513 }
00514
00515
00516 LogDebug("PFSimParticleProducer")<<"STOP event: "<<iEvent.id().event()
00517 <<" in run "<<iEvent.id().run()<<endl;
00518 }
00519
00520 void PFSimParticleProducer::getSimIDs( const TrackHandle& trackh,
00521 std::vector<unsigned>& recTrackSimID )
00522 {
00523
00524 if( trackh.isValid() ) {
00525
00526
00527 for(unsigned i=0;i<trackh->size(); i++) {
00528
00529 reco::PFRecTrackRef ref( trackh,i );
00530 const reco::PFRecTrack& PFT = *ref;
00531 const reco::TrackRef trackref = PFT.trackRef();
00532
00533
00534
00535
00536
00537
00538 trackingRecHit_iterator rhitbeg
00539 = trackref->recHitsBegin();
00540 trackingRecHit_iterator rhitend
00541 = trackref->recHitsEnd();
00542 for (trackingRecHit_iterator it = rhitbeg;
00543 it != rhitend; it++){
00544
00545 if( it->get()->isValid() ){
00546
00547 const SiTrackerGSMatchedRecHit2D * rechit
00548 = (const SiTrackerGSMatchedRecHit2D*) (it->get());
00549
00550
00551
00552
00553
00554
00555 recTrackSimID.push_back( rechit->simtrackId() );
00556 break;
00557 }
00558 }
00559 }
00560 }
00561 }