CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/PhysicsTools/PatAlgos/plugins/ObjectSpatialResolution.h

Go to the documentation of this file.
00001 //
00002 // $Id: ObjectSpatialResolution.h,v 1.3 2010/10/20 23:09:25 wmtan Exp $
00003 //
00004 
00005 #ifndef PhysicsTools_PatAlgos_ObjectSpatialResolution_h
00006 #define PhysicsTools_PatAlgos_ObjectSpatialResolution_h
00007 
00022 #include <cmath>
00023 
00024 #include "FWCore/Framework/interface/Frameworkfwd.h"
00025 #include "FWCore/Framework/interface/EDProducer.h"
00026 #include "FWCore/Framework/interface/Event.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include "FWCore/Utilities/interface/InputTag.h"
00029 
00030 #include "FWCore/ServiceRegistry/interface/Service.h"
00031 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00032 #include "CLHEP/Random/RandGaussQ.h"
00033 #include "DataFormats/Math/interface/normalizedPhi.h"
00034 
00035 #include <cmath>
00036 
00037 
00038 namespace pat {
00039 
00040 
00041   template<class T>
00042   class ObjectSpatialResolution : public edm::EDProducer {
00043 
00044     public:
00045 
00046       explicit ObjectSpatialResolution(const edm::ParameterSet& iConfig);
00047       ~ObjectSpatialResolution();
00048 
00049     private:
00050 
00051       virtual void produce(edm::Event& iEvent, const edm::EventSetup& iSetup);
00052 
00053       void smearAngles(T& object);
00054 
00055       edm::InputTag objects_;
00056       double        iniResPolar_,
00057                     worsenResPolar_,
00058                     iniResPhi_,
00059                     worsenResPhi_;
00060       bool          useDefaultIniRes_,
00061                     usePolarTheta_,
00062                     useWorsenResPolarByFactor_,
00063                     useWorsenResPhiByFactor_;
00064 
00065       CLHEP::RandGaussQ* gaussian_;
00066 
00067   };
00068 
00069 
00070 }
00071 
00072 
00073 template<class T>
00074 pat::ObjectSpatialResolution<T>::ObjectSpatialResolution(const edm::ParameterSet& iConfig)
00075 {
00076   objects_                   = iConfig.getParameter<edm::InputTag>("movedObject");
00077   useDefaultIniRes_          = iConfig.getParameter<bool>         ("useDefaultInitialResolutions");
00078   iniResPhi_                 = iConfig.getParameter<double>       ("initialResolutionPhi");
00079   worsenResPhi_              = iConfig.getParameter<double>       ("worsenResolutionPhi");
00080   useWorsenResPhiByFactor_   = iConfig.getParameter<bool>         ("worsenResolutionPhiByFactor");
00081   usePolarTheta_             = iConfig.getParameter<bool>         ("usePolarTheta");
00082   iniResPolar_               = iConfig.getParameter<double>       ("initialResolutionPolar");
00083   worsenResPolar_            = iConfig.getParameter<double>       ("worsenResolutionPolar");
00084   useWorsenResPolarByFactor_ = iConfig.getParameter<bool>         ("worsenResolutionPolarByFactor");
00085 
00086   edm::Service<edm::RandomNumberGenerator> rng;
00087   CLHEP::HepRandomEngine& engine = rng->getEngine();
00088   gaussian_ = new CLHEP::RandGaussQ(engine);
00089 
00090   produces<std::vector<T> >();
00091 }
00092 
00093 
00094 template<class T>
00095 pat::ObjectSpatialResolution<T>::~ObjectSpatialResolution()
00096 {
00097   delete gaussian_;
00098 }
00099 
00100 
00101 template<class T>
00102 void pat::ObjectSpatialResolution<T>::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00103 {
00104   edm::Handle<std::vector<T> > objectsHandle;
00105   iEvent.getByLabel(objects_, objectsHandle);
00106   std::vector<T> objects = *objectsHandle;
00107   std::auto_ptr<std::vector<T> > objectsVector(new std::vector<T>);
00108   objectsVector->reserve(objectsHandle->size());
00109 
00110   for ( unsigned int i = 0; i < objects.size(); i++ ) {
00111     smearAngles(objects[i]);
00112     objectsVector->push_back(objects[i]);
00113   }
00114   iEvent.put(objectsVector);
00115 }
00116 
00117 
00120 template<class T>
00121 void pat::ObjectSpatialResolution<T>::smearAngles(T& object)
00122 {
00123   // overwrite config file parameters 'initialResolution...' if required
00124   if ( useDefaultIniRes_ ) {
00125     // get initial resolutions from input object
00126     iniResPhi_   = object.resolutionPhi();    // overwrites config file parameter "initialResolution"
00127     iniResPolar_ = usePolarTheta_      ?
00128                    object.resolutionTheta():
00129                    object.resolutionEta();    // overwrites config file parameter "initialResolution"
00130   }
00131   // smear phi
00132   double finalResPhi = useWorsenResPhiByFactor_                            ?
00133                        (1.+fabs(1.-fabs(worsenResPhi_))) * fabs(iniResPhi_):
00134                        fabs(worsenResPhi_) + fabs(iniResPhi_);               // conversions as protection from "finalRes_<iniRes_"
00135   double smearedPhi = normalizedPhi( gaussian_->fire(object.phi(), sqrt(std::pow(finalResPhi,2)-std::pow(iniResPhi_,2))) );
00136   double finalResPolar = useWorsenResPolarByFactor_                              ?
00137                          (1.+fabs(1.-fabs(worsenResPolar_))) * fabs(iniResPolar_):
00138                          fabs(worsenResPolar_) + fabs(iniResPolar_);               // conversions as protection from "finalRes_<iniRes_"
00139   // smear theta/eta
00140   const double thetaMin = 2.*atan(exp(-ROOT::Math::etaMax<double>())); // to be on the safe side; however, etaMax=22765 ==> thetaMin=0 within double precision
00141   double smearedTheta,
00142          smearedEta;
00143   if ( usePolarTheta_ ) {
00144     smearedTheta = gaussian_->fire(object.theta(), sqrt(std::pow(finalResPolar,2)-std::pow(iniResPolar_,2)));
00145     // 0<theta<Pi needs to be assured to have proper calculation of eta
00146     while ( fabs(smearedTheta) > M_PI ) smearedTheta = smearedTheta < 0.     ?
00147                                                        smearedTheta + 2.*M_PI:
00148                                                        smearedTheta - 2.*M_PI;
00149     if ( smearedTheta < 0. ) {
00150       smearedTheta = -smearedTheta;
00151       smearedPhi   = normalizedPhi(smearedPhi+M_PI);
00152     }
00153     smearedEta = smearedTheta < thetaMin          ?
00154                  ROOT::Math::etaMax<double>()     :
00155                  ( smearedTheta > M_PI-thetaMin ?
00156                    -ROOT::Math::etaMax<double>():
00157                    -log(tan(smearedTheta/2.))    ); // eta not calculable for theta=0,Pi, which could occur
00158   } else {
00159     smearedEta = gaussian_->fire(object.eta(), sqrt(std::pow(finalResPolar,2)-std::pow(iniResPolar_,2)));
00160     if ( fabs(smearedEta) > ROOT::Math::etaMax<double>() ) smearedEta = smearedEta < 0.              ?
00161                                                                         -ROOT::Math::etaMax<double>():
00162                                                                          ROOT::Math::etaMax<double>();
00163     smearedTheta = 2. * atan(exp(-smearedEta)); // since exp(x)>0 && atan() returns solution closest to 0, 0<theta<Pi should be assured.
00164   }
00165   // set smeared new 4-vector
00166   math::PtEtaPhiELorentzVector newLorentzVector(object.p()*sin(smearedTheta),
00167                                                 smearedEta,
00168                                                 smearedPhi,
00169                                                 object.energy());
00170   object.setP4(reco::Particle::LorentzVector(newLorentzVector.Px(),
00171                                              newLorentzVector.Py(),
00172                                              newLorentzVector.Pz(),
00173                                              newLorentzVector.E() ));
00174 }
00175 
00176 
00177 #endif