Go to the documentation of this file.00001
00002
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
00124 if ( useDefaultIniRes_ ) {
00125
00126 iniResPhi_ = object.resolutionPhi();
00127 iniResPolar_ = usePolarTheta_ ?
00128 object.resolutionTheta():
00129 object.resolutionEta();
00130 }
00131
00132 double finalResPhi = useWorsenResPhiByFactor_ ?
00133 (1.+fabs(1.-fabs(worsenResPhi_))) * fabs(iniResPhi_):
00134 fabs(worsenResPhi_) + fabs(iniResPhi_);
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_);
00139
00140 const double thetaMin = 2.*atan(exp(-ROOT::Math::etaMax<double>()));
00141 double smearedTheta,
00142 smearedEta;
00143 if ( usePolarTheta_ ) {
00144 smearedTheta = gaussian_->fire(object.theta(), sqrt(std::pow(finalResPolar,2)-std::pow(iniResPolar_,2)));
00145
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.)) );
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));
00164 }
00165
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