CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/HiggsAnalysis/CombinedLimit/src/ProcessNormalization.cc

Go to the documentation of this file.
00001 #include "../interface/ProcessNormalization.h"
00002 
00003 #include <cmath>
00004 #include <cassert>
00005 #include <cstdio>
00006 
00007 ProcessNormalization::ProcessNormalization(const char *name, const char *title, double nominal) :
00008         RooAbsReal(name,title),
00009         nominalValue_(nominal),
00010         thetaList_("thetaList","List of nuisances for symmetric kappas", this), 
00011         asymmThetaList_("asymmThetaList","List of nuisances for asymmetric kappas", this), 
00012         otherFactorList_("otherFactorList","Other multiplicative terms", this)
00013 { 
00014 }
00015 
00016 ProcessNormalization::ProcessNormalization(const char *name, const char *title, RooAbsReal &nominal) :
00017         RooAbsReal(name,title),
00018         nominalValue_(1.0),
00019         thetaList_("thetaList", "List of nuisances for symmetric kappas", this), 
00020         asymmThetaList_("asymmThetaList", "List of nuisances for asymmetric kappas", this), 
00021         otherFactorList_("otherFactorList", "Other multiplicative terms", this)
00022 { 
00023     otherFactorList_.add(nominal);
00024 }
00025 
00026 ProcessNormalization::ProcessNormalization(const ProcessNormalization &other, const char *newname) :
00027         RooAbsReal(other, newname ? newname : other.GetName()),
00028         nominalValue_(other.nominalValue_),
00029         logKappa_(other.logKappa_),
00030         thetaList_("thetaList", this, other.thetaList_), 
00031         logAsymmKappa_(other.logAsymmKappa_),
00032         asymmThetaList_("asymmThetaList", this, other.asymmThetaList_), 
00033         otherFactorList_("otherFactorList", this, other.otherFactorList_)
00034 {
00035 }
00036 
00037 ProcessNormalization::~ProcessNormalization() {}
00038 
00039 void ProcessNormalization::addLogNormal(double kappa, RooAbsReal &theta) {
00040     if (kappa != 0.0 && kappa != 1.0) {
00041         logKappa_.push_back(std::log(kappa));
00042         thetaList_.add(theta);
00043     }
00044 }
00045 
00046 void ProcessNormalization::addAsymmLogNormal(double kappaLo, double kappaHi, RooAbsReal &theta) {
00047     if (fabs(kappaLo*kappaHi - 1) < 1e-5) {
00048         addLogNormal(kappaHi, theta);
00049     } else {
00050         logAsymmKappa_.push_back(std::make_pair(std::log(kappaLo), std::log(kappaHi)));
00051         asymmThetaList_.add(theta);
00052     }
00053 }
00054 
00055 void ProcessNormalization::addOtherFactor(RooAbsReal &factor) {
00056     otherFactorList_.add(factor);
00057 }
00058 
00059 Double_t ProcessNormalization::evaluate() const {
00060     double logVal = 0.0;
00061     if (!logKappa_.empty()) {
00062         RooLinkedListIter iterTheta = thetaList_.iterator();
00063         std::vector<double>::const_iterator logKappa = logKappa_.begin();
00064         for (RooAbsReal *theta = (RooAbsReal*) iterTheta.Next(); theta != 0; theta = (RooAbsReal*) iterTheta.Next(), ++logKappa) {
00065             logVal += theta->getVal() * (*logKappa);
00066         }
00067     }
00068     if (!logAsymmKappa_.empty()) {
00069         RooLinkedListIter iterTheta = asymmThetaList_.iterator();
00070         std::vector<std::pair<double,double> >::const_iterator logKappas = logAsymmKappa_.begin();
00071         for (RooAbsReal *theta = (RooAbsReal*) iterTheta.Next(); theta != 0; theta = (RooAbsReal*) iterTheta.Next(), ++logKappas) {
00072             double x = theta->getVal();
00073             logVal +=  x * logKappaForX(x, *logKappas);
00074         }
00075     }
00076     double norm = nominalValue_;
00077     if (logVal) norm *= std::exp(logVal);
00078     if (otherFactorList_.getSize()) {
00079         RooLinkedListIter iterOther = otherFactorList_.iterator();
00080         for (RooAbsReal *fact = (RooAbsReal*) iterOther.Next(); fact != 0; fact = (RooAbsReal*) iterOther.Next()) {
00081             norm *= fact->getVal();
00082         }
00083     }
00084     return norm;
00085 }
00086 
00087 Double_t ProcessNormalization::logKappaForX(double x, const std::pair<double,double> &logKappas) const {
00088     if (fabs(x) >= 0.5) return (x >= 0 ? logKappas.second : -logKappas.first);
00089     // interpolate between log(kappaHigh) and -log(kappaLow) 
00090     //    logKappa(x) = avg + halfdiff * h(2x)
00091     // where h(x) is the 3th order polynomial
00092     //    h(x) = (3 x^5 - 10 x^3 + 15 x)/8;
00093     // chosen so that h(x) satisfies the following:
00094     //      h (+/-1) = +/-1 
00095     //      h'(+/-1) = 0
00096     //      h"(+/-1) = 0
00097     double logKhi =  logKappas.second;
00098     double logKlo = -logKappas.first;
00099     double avg = 0.5*(logKhi + logKlo), halfdiff = 0.5*(logKhi - logKlo);
00100     double twox = x+x, twox2 = twox*twox;
00101     double alpha = 0.125 * twox * (twox2 * (3*twox2 - 10.) + 15.);
00102     double ret = avg + alpha*halfdiff;
00103     return ret;
00104 } 
00105 
00106 void ProcessNormalization::dump() const {
00107     std::cout << "Dumping ProcessNormalization " << GetName() << " @ " << (void*)this << std::endl;
00108     std::cout << "\tnominal value: " << nominalValue_ << std::endl;
00109     std::cout << "\tlog-normals (" << logKappa_.size() << "):"  << std::endl;
00110     for (unsigned int i = 0; i < logKappa_.size(); ++i) {
00111         std::cout << "\t\t kappa = " << exp(logKappa_[i]) << ", logKappa = " << logKappa_[i] << 
00112                      ", theta = " << thetaList_.at(i)->GetName() << " = " << ((RooAbsReal*)thetaList_.at(i))->getVal() << std::endl;
00113     }
00114     std::cout << "\tasymm log-normals (" << logAsymmKappa_.size() << "):"  << std::endl;
00115     for (unsigned int i = 0; i < logAsymmKappa_.size(); ++i) {
00116         std::cout << "\t\t kappaLo = " << exp(logAsymmKappa_[i].first) << ", logKappaLo = " << logAsymmKappa_[i].first << 
00117                      ", kappaHi = " << exp(logAsymmKappa_[i].second) << ", logKappaHi = " << logAsymmKappa_[i].second << 
00118                      ", theta = " << thetaList_.at(i)->GetName() << " = " << ((RooAbsReal*)thetaList_.at(i))->getVal() << std::endl;
00119     }
00120     std::cout << "\tother terms (" << otherFactorList_.getSize() << "):"  << std::endl;
00121     for (int i = 0; i < otherFactorList_.getSize(); ++i) {  
00122         std::cout << "\t\t term " << otherFactorList_.at(i)->GetName() <<
00123                      " (class " << otherFactorList_.at(i)->ClassName() << 
00124                      "), value = " << ((RooAbsReal*)otherFactorList_.at(i))->getVal() << std::endl;
00125     }
00126     std::cout << std::endl;
00127 }
00128 ClassImp(ProcessNormalization)