00001 #include "RecoParticleFlow/PFSimProducer/plugins/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/TrackFitters/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::beginRun(edm::Run& run,
00117 const edm::EventSetup & es)
00118 {
00119
00120
00121 edm::ESHandle < HepPDT::ParticleDataTable > pdt;
00122
00123 es.getData(pdt);
00124 if ( !ParticleTable::instance() ) ParticleTable::instance(&(*pdt));
00125 mySimEvent->initializePdt(&(*pdt));
00126
00127 }
00128
00129
00130 void PFSimParticleProducer::produce(Event& iEvent,
00131 const EventSetup& iSetup)
00132 {
00133
00134 LogDebug("PFSimParticleProducer")<<"START event: "<<iEvent.id().event()
00135 <<" in run "<<iEvent.id().run()<<endl;
00136
00137
00138
00139
00140
00141 std::vector<unsigned> recTrackSimID;
00142
00143
00144
00145
00146
00147 typedef std::pair<double, unsigned> hitSimID;
00148 typedef std::list< std::pair<double, unsigned> >::iterator ITM;
00149 std::vector< std::list <hitSimID> > caloHitsEBID(62000);
00150 std::vector<double> caloHitsEBTotE(62000,0.0);
00151
00152 if(mctruthMatchingInfo_){
00153
00154
00155 edm::Handle<edm::PCaloHitContainer> pcalohits;
00156
00157
00158
00159
00160 bool found_phit
00161 = iEvent.getByLabel(inputTagFamosSimHits_,pcalohits);
00162
00163
00164 if(!found_phit) {
00165 ostringstream err;
00166 err<<"could not find pcaloHit "<<"famosSimHits:EcalHitsEB";
00167 LogError("PFSimParticleProducer")<<err.str()<<endl;
00168
00169 throw cms::Exception( "MissingProduct", err.str());
00170 }
00171 else {
00172 assert( pcalohits.isValid() );
00173
00174
00175
00176
00177 edm::PCaloHitContainer::const_iterator it
00178 = pcalohits.product()->begin();
00179 edm::PCaloHitContainer::const_iterator itend
00180 = pcalohits.product()->end();
00181
00182
00183 for(;it!=itend;++it)
00184 {
00185 EBDetId detid(it->id());
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 if(it->energy() > 0.0) {
00196 std::pair<double, unsigned> phitsimid
00197 = make_pair(it->energy(),it->geantTrackId());
00198 caloHitsEBID[detid.hashedIndex()].push_back(phitsimid);
00199 caloHitsEBTotE[detid.hashedIndex()]
00200 += it->energy();
00201 }
00202
00203 }
00204 }
00205
00206
00207
00208 Handle< reco::PFRecTrackCollection > recTracks;
00209 try{
00210 LogDebug("PFSimParticleProducer")<<"getting PFRecTracks"<<endl;
00211 iEvent.getByLabel(inputTagRecTracks_, recTracks);
00212
00213 } catch (cms::Exception& err) {
00214 LogError("PFSimParticleProducer")<<err
00215 <<" cannot get collection "
00216 <<"particleFlowBlock"<<":"
00217 <<""
00218 <<endl;
00219 }
00220
00221
00222
00223 getSimIDs( recTracks, recTrackSimID );
00224
00225 }
00226
00227
00228 if( processParticles_) {
00229
00230 auto_ptr< reco::PFSimParticleCollection >
00231 pOutputPFSimParticleCollection(new reco::PFSimParticleCollection );
00232
00233 Handle<vector<SimTrack> > simTracks;
00234 bool found = iEvent.getByLabel(inputTagSim_,simTracks);
00235 if(!found) {
00236
00237 ostringstream err;
00238 err<<"cannot find sim tracks: "<<inputTagSim_;
00239 LogError("PFSimParticleProducer")<<err.str()<<endl;
00240
00241 throw cms::Exception( "MissingProduct", err.str());
00242 }
00243
00244
00245
00246 Handle<vector<SimVertex> > simVertices;
00247 found = iEvent.getByLabel(inputTagSim_,simVertices);
00248 if(!found) {
00249 LogError("PFSimParticleProducer")
00250 <<"cannot find sim vertices: "<<inputTagSim_<<endl;
00251 return;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 mySimEvent->fill( *simTracks, *simVertices );
00263
00264 if(verbose_)
00265 mySimEvent->print();
00266
00267
00268 for(unsigned i=0; i<mySimEvent->nTracks(); i++) {
00269
00270 const FSimTrack& fst = mySimEvent->track(i);
00271
00272 int motherId = -1;
00273 if( ! fst.noMother() )
00274 motherId = fst.mother().id();
00275
00276
00277
00278
00279
00280
00281
00282
00283 unsigned recTrackID = 99999;
00284 vector<unsigned> recHitContrib;
00285 vector<double> recHitContribFrac;
00286
00287 if(mctruthMatchingInfo_){
00288
00289 for(unsigned lo=0; lo<recTrackSimID.size();
00290 lo++) {
00291 if( i == recTrackSimID[lo] ) {
00292
00293
00294 recTrackID = lo;
00295 }
00296 }
00297
00298
00299
00300
00301
00302 edm::Handle<EcalRecHitCollection> rhcHandle;
00303 bool found = iEvent.getByLabel(inputTagEcalRecHitsEB_,
00304 rhcHandle);
00305 if(!found) {
00306 ostringstream err;
00307 err<<"could not find rechits "<< inputTagEcalRecHitsEB_;
00308 LogError("PFSimParticleProducer")<<err.str()<<endl;
00309
00310 throw cms::Exception( "MissingProduct", err.str());
00311 }
00312 else {
00313 assert( rhcHandle.isValid() );
00314
00315
00316
00317 EBRecHitCollection::const_iterator it_rh
00318 = rhcHandle.product()->begin();
00319 EBRecHitCollection::const_iterator itend_rh
00320 = rhcHandle.product()->end();
00321
00322 for(;it_rh!=itend_rh;++it_rh)
00323 {
00324 unsigned rhit_hi
00325 = EBDetId(it_rh->id()).hashedIndex();
00326 EBDetId detid(it_rh->id());
00327
00328
00329
00330
00331 ITM it_phit = caloHitsEBID[rhit_hi].begin();
00332 ITM itend_phit = caloHitsEBID[rhit_hi].end();
00333 for(;it_phit!=itend_phit;++it_phit)
00334 {
00335 if(i == it_phit->second)
00336 {
00337
00338
00339 bool alreadyin = false;
00340 for( unsigned ihit = 0; ihit < recHitContrib.size();
00341 ++ihit )
00342 if(detid.rawId() == recHitContrib[ihit])
00343 alreadyin = true;
00344
00345 if(!alreadyin){
00346 double pcalofraction = 0.0;
00347 if(caloHitsEBTotE[rhit_hi] != 0.0)
00348 pcalofraction
00349 = (it_phit->first/caloHitsEBTotE[rhit_hi])*100.0;
00350
00351
00352 recHitContrib.push_back(it_rh->id());
00353 recHitContribFrac.push_back(pcalofraction);
00354 }
00355 }
00356 }
00357
00358 }
00359
00360 }
00361
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371 reco::PFSimParticle particle( fst.charge(),
00372 fst.type(),
00373 fst.id(),
00374 motherId,
00375 fst.daughters(),
00376 recTrackID,
00377 recHitContrib,
00378 recHitContribFrac);
00379
00380
00381 const FSimVertex& originVtx = fst.vertex();
00382
00383 math::XYZPoint posOrig( originVtx.position().x(),
00384 originVtx.position().y(),
00385 originVtx.position().z() );
00386
00387 math::XYZTLorentzVector momOrig( fst.momentum().px(),
00388 fst.momentum().py(),
00389 fst.momentum().pz(),
00390 fst.momentum().e() );
00391 reco::PFTrajectoryPoint
00392 pointOrig(-1,
00393 reco::PFTrajectoryPoint::ClosestApproach,
00394 posOrig, momOrig);
00395
00396
00397 particle.addPoint(pointOrig);
00398
00399
00400 if( ! fst.noEndVertex() ) {
00401 const FSimVertex& endVtx = fst.endVertex();
00402
00403 math::XYZPoint posEnd( endVtx.position().x(),
00404 endVtx.position().y(),
00405 endVtx.position().z() );
00406
00407
00408
00409
00410 math::XYZTLorentzVector momEnd;
00411
00412 reco::PFTrajectoryPoint
00413 pointEnd( -1,
00414 reco::PFTrajectoryPoint::BeamPipeOrEndVertex,
00415 posEnd, momEnd);
00416
00417 particle.addPoint(pointEnd);
00418 }
00419 else {
00420 reco::PFTrajectoryPoint dummy;
00421 particle.addPoint(dummy);
00422 }
00423
00424
00425 if( fst.onLayer1() ) {
00426 const RawParticle& rp = fst.layer1Entrance();
00427
00428 math::XYZPoint posLayer1( rp.x(), rp.y(), rp.z() );
00429 math::XYZTLorentzVector momLayer1( rp.px(), rp.py(), rp.pz(), rp.e() );
00430 reco::PFTrajectoryPoint layer1Pt(-1, reco::PFTrajectoryPoint::PS1,
00431 posLayer1, momLayer1);
00432
00433 particle.addPoint( layer1Pt );
00434
00435
00436 }
00437 else {
00438 reco::PFTrajectoryPoint dummy;
00439 particle.addPoint(dummy);
00440 }
00441
00442 if( fst.onLayer2() ) {
00443 const RawParticle& rp = fst.layer2Entrance();
00444
00445 math::XYZPoint posLayer2( rp.x(), rp.y(), rp.z() );
00446 math::XYZTLorentzVector momLayer2( rp.px(), rp.py(), rp.pz(), rp.e() );
00447 reco::PFTrajectoryPoint layer2Pt(-1, reco::PFTrajectoryPoint::PS2,
00448 posLayer2, momLayer2);
00449
00450 particle.addPoint( layer2Pt );
00451
00452
00453 }
00454 else {
00455 reco::PFTrajectoryPoint dummy;
00456 particle.addPoint(dummy);
00457 }
00458
00459 if( fst.onEcal() ) {
00460 const RawParticle& rp = fst.ecalEntrance();
00461
00462 math::XYZPoint posECAL( rp.x(), rp.y(), rp.z() );
00463 math::XYZTLorentzVector momECAL( rp.px(), rp.py(), rp.pz(), rp.e() );
00464 reco::PFTrajectoryPoint ecalPt(-1,
00465 reco::PFTrajectoryPoint::ECALEntrance,
00466 posECAL, momECAL);
00467
00468 particle.addPoint( ecalPt );
00469
00470
00471 }
00472 else {
00473 reco::PFTrajectoryPoint dummy;
00474 particle.addPoint(dummy);
00475 }
00476
00477
00478 reco::PFTrajectoryPoint dummy;
00479 particle.addPoint(dummy);
00480
00481 if( fst.onHcal() ) {
00482
00483 const RawParticle& rpin = fst.hcalEntrance();
00484
00485 math::XYZPoint posHCALin( rpin.x(), rpin.y(), rpin.z() );
00486 math::XYZTLorentzVector momHCALin( rpin.px(), rpin.py(), rpin.pz(),
00487 rpin.e() );
00488 reco::PFTrajectoryPoint hcalPtin(-1,
00489 reco::PFTrajectoryPoint::HCALEntrance,
00490 posHCALin, momHCALin);
00491
00492 particle.addPoint( hcalPtin );
00493
00494 const RawParticle& rpout = fst.hcalExit();
00495
00496 math::XYZPoint posHCALout( rpout.x(), rpout.y(), rpout.z() );
00497 math::XYZTLorentzVector momHCALout( rpout.px(), rpout.py(), rpout.pz(),
00498 rpout.e() );
00499 reco::PFTrajectoryPoint
00500 hcalPtout(-1, reco::PFTrajectoryPoint::HCALExit,
00501 posHCALout, momHCALout);
00502
00503 particle.addPoint( hcalPtout );
00504
00505 const RawParticle& rpho = fst.hoEntrance();
00506
00507 math::XYZPoint posHOEntrance( rpho.x(), rpho.y(), rpho.z() );
00508 math::XYZTLorentzVector momHOEntrance( rpho.px(), rpho.py(), rpho.pz(),
00509 rpho.e() );
00510 reco::PFTrajectoryPoint
00511 hoPtin(-1, reco::PFTrajectoryPoint::HOLayer,
00512 posHOEntrance, momHOEntrance);
00513
00514 particle.addPoint( hoPtin );
00515
00516
00517
00518
00519 }
00520 else {
00521 reco::PFTrajectoryPoint dummy;
00522 particle.addPoint(dummy);
00523 }
00524
00525 pOutputPFSimParticleCollection->push_back( particle );
00526 }
00527
00528 iEvent.put(pOutputPFSimParticleCollection);
00529 }
00530
00531
00532 LogDebug("PFSimParticleProducer")<<"STOP event: "<<iEvent.id().event()
00533 <<" in run "<<iEvent.id().run()<<endl;
00534 }
00535
00536 void PFSimParticleProducer::getSimIDs( const TrackHandle& trackh,
00537 std::vector<unsigned>& recTrackSimID )
00538 {
00539
00540 if( trackh.isValid() ) {
00541
00542
00543 for(unsigned i=0;i<trackh->size(); i++) {
00544
00545 reco::PFRecTrackRef ref( trackh,i );
00546 const reco::PFRecTrack& PFT = *ref;
00547 const reco::TrackRef trackref = PFT.trackRef();
00548
00549
00550
00551
00552
00553
00554 trackingRecHit_iterator rhitbeg
00555 = trackref->recHitsBegin();
00556 trackingRecHit_iterator rhitend
00557 = trackref->recHitsEnd();
00558 for (trackingRecHit_iterator it = rhitbeg;
00559 it != rhitend; it++){
00560
00561 if( it->get()->isValid() ){
00562
00563 const SiTrackerGSMatchedRecHit2D * rechit
00564 = (const SiTrackerGSMatchedRecHit2D*) (it->get());
00565
00566
00567
00568
00569
00570
00571 recTrackSimID.push_back( rechit->simtrackId() );
00572 break;
00573 }
00574 }
00575 }
00576 }
00577 }