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
00090
00091
00092
00093
00094
00095
00096
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)