#include <iostream>
#include "QFramework/TQCounter.h"
#include "QFramework/TQStringUtils.h"
#include "TMath.h"
ClassImp(TQCounter)
TQCounter::TQCounter() : TNamed() {
reset();
}
TQCounter::TQCounter(const char * name) : TNamed(name, "") {
reset();
}
TQCounter::TQCounter(const char * name, const char* title) : TNamed(name, title) {
reset();
}
TQCounter::TQCounter(const TString& name, double cnt, double err) : TNamed(name.Data(), "") {
reset();
setCounter(cnt);
setErrorSquared(err * err);
}
TQCounter::TQCounter(const TString& name, double cnt, double err, int raw) : TNamed(name.Data(), "") {
reset();
setCounter(cnt);
setErrorSquared(err * err);
setRawCounter(raw);
}
TQCounter::TQCounter(const TQCounter * counter) : TNamed(counter ? counter->GetName() : "TQCounter", counter ? counter->GetTitle() : "") {
reset();
if (counter) {
add(counter);
}
}
void TQCounter::reset() {
fCounter = 0.;
fErrorSquared = 0.;
fRawCounter = 0;
fWarning = false;
}
TString TQCounter::getAsString(const TString& options) const {
TString flags;
TString localOptions = options;
int precision = -1;
bool hasPrecision = false;
bool stop = false;
while (!stop) {
if (TQStringUtils::readToken(localOptions, flags, "p") > 0) {
TString precisionStr;
if (TQStringUtils::readToken(localOptions, precisionStr,
TQStringUtils::getNumerals()) > 0 && !hasPrecision) {
precision = precisionStr.Atoi();
hasPrecision = true;
continue;
} else {
return "";
}
}
stop = true;
}
if (localOptions.Length() > 0)
return "";
TString cnt = TString::Format("%.*g", precision, (double)getCounter());
TString err = TString::Format("%.*g", precision, (double)getError());
TString raw = TString::Format("%.*g", precision, (double)getRawCounter());
if (precision > 0)
precision += 1;
return TString::Format("%*s +/- %*s [raw: %*s]", precision, cnt.Data(),
precision, err.Data(), precision, raw.Data());
}
void TQCounter::print(const TString& options) const {
this->printCounter(options);
}
void TQCounter::printCounter(const TString& options) const {
std::cout << TString::Format("TQCounter('%s'): %s\n", GetName(),getAsString(options).Data()).Data();
}
double TQCounter::getCounter() const {
return fCounter;
}
void TQCounter::setCounter(double counter) {
fCounter = counter;
}
void TQCounter::setRawCounter(int raw) {
fRawCounter = raw;
}
double TQCounter::getError() const {
return TMath::Sqrt(fErrorSquared);
}
double TQCounter::getErrorSquared() const {
return fErrorSquared;
}
void TQCounter::setErrorSquared(double errorSquared) {
if (errorSquared >= 0.)
fErrorSquared = errorSquared;
}
void TQCounter::setError(double error) {
fErrorSquared = pow(error,2);
}
double TQCounter::getStatError() const {
return 0.;
}
double TQCounter::getStatErrorSquared() const {
return 0.;
}
double TQCounter::getSysError() const {
return 0.;
}
double TQCounter::getSysErrorSquared() const {
return 0.;
}
int TQCounter::getRawCounter() const {
return fRawCounter;
}
void TQCounter::setWarning(bool warning) {
fWarning = warning;
}
bool TQCounter::getWarning() const {
return fWarning;
}
void TQCounter::add(double weight) {
fCounter += weight;
fErrorSquared += pow(weight, 2);
fRawCounter += 1;
}
void TQCounter::add(const TQCounter * counter, double scale, double scaleUncertainty, double correlation, bool includeScaleUncertainty) {
double scaleUncertSq = includeScaleUncertainty ? TMath::Power(scaleUncertainty,2) : 0. ;
if (counter) {
fCounter += scale * counter->getCounter();
fErrorSquared += TMath::Power(scale, 2.) * counter->getErrorSquared() + TMath::Power(counter->getCounter(),2) * scaleUncertSq + 2. * correlation * scale * TMath::Sqrt(counter->getErrorSquared()) * TMath::Sqrt(fErrorSquared) ;
fRawCounter += counter->getRawCounter();
fWarning |= counter->getWarning();
}
}
void TQCounter::add(const TQCounter * counter, TQCounter * scale, double correlation, bool includeScaleUncertainty) {
if (counter) {
this->add(counter, scale->getCounter(), scale->getError(), correlation, includeScaleUncertainty);
}
}
void TQCounter::subtract(const TQCounter * counter, double scale, double scaleUncertainty, double correlation, bool includeScaleUncertainty) {
double scaleUncertSq = includeScaleUncertainty ? TMath::Power(scaleUncertainty,2) : 0.;
if (counter) {
fCounter -= scale * counter->getCounter();
fErrorSquared += TMath::Power(scale, 2.) * counter->getErrorSquared() + TMath::Power(counter->getCounter(),2) * scaleUncertSq - 2. * correlation * scale * TMath::Sqrt(counter->getErrorSquared()) * TMath::Sqrt(fErrorSquared) ;
fRawCounter += counter->getRawCounter();
fWarning |= counter->getWarning();
}
}
void TQCounter::subtract(const TQCounter * counter, TQCounter* scale, double correlation, bool includeScaleUncertainty) {
if (counter) {
this->subtract(counter, scale->getCounter(), scale->getError(), correlation, includeScaleUncertainty);
}
}
void TQCounter::multiply(double factor, double uncertainty, double correlation, bool includeScaleUncertainty) {
double uncertSq = includeScaleUncertainty ? TMath::Power(uncertainty,2) : 0.;
fErrorSquared = uncertSq*TMath::Power(fCounter,2) + TMath::Power(factor,2)*fErrorSquared + 2* correlation * factor * fCounter * TMath::Sqrt(uncertSq*fErrorSquared);
fCounter *= factor;
fRawCounter = -1;
}
void TQCounter::multiply(const TQCounter * counter, double correlation, bool includeScaleUncertainty) {
if (counter) {
this->multiply(counter->getCounter(), counter->getError(), correlation, includeScaleUncertainty);
fWarning |= counter->getWarning();
}
}
void TQCounter::divide(double denominator, double uncertainty, double correlation, bool includeScaleUncertainty) {
double uncertSq = includeScaleUncertainty ? TMath::Power(uncertainty,2) : 0.;
fErrorSquared = TMath::Power(denominator,-2)*fErrorSquared + TMath::Power(fCounter/TMath::Power(denominator,2),2)*uncertSq - 2 * correlation * fCounter * TMath::Power(denominator,3) * TMath::Sqrt(fErrorSquared*uncertSq);
fCounter /= denominator;
fRawCounter = -1;
}
void TQCounter::divide(const TQCounter * counter, double correlation, bool includeScaleUncertainty) {
if (counter) {
this->divide(counter->getCounter(), counter->getError(), correlation, includeScaleUncertainty);
fWarning |= counter->getWarning();
}
}
void TQCounter::scale(double factor, double scaleUncertainty, bool includeScaleUncertainty) {
double uncertSq = includeScaleUncertainty ? TMath::Power(scaleUncertainty,2) : 0.;
fErrorSquared = fErrorSquared * TMath::Power(factor,2) + uncertSq * TMath::Power(fCounter,2);
fCounter *= factor;
}
void TQCounter::scale(const TQCounter * scalefactor, bool includeScaleUncertainty) {
if (scalefactor) {
this->scale(scalefactor->getCounter(), scalefactor->getError(), includeScaleUncertainty);
fWarning |= scalefactor->getWarning();
}
}
TString TQCounter::getComparison(TQCounter * cnt1, TQCounter * cnt2,
bool colored, double order) {
TString comparison;
bool yellow = false;
bool red = false;
if (cnt1)
comparison.Append("(1) ");
else
comparison.Append("( ) ");
if (cnt1 && cnt2) {
if (cnt1->isEqualTo(cnt2, order)) {
comparison.Append("=");
} else if (cnt1->isRawEqualTo(cnt2)) {
comparison.Append("~");
yellow = true;
} else if (cnt1->getCounter() > cnt2->getCounter()) {
comparison.Append(">");
red = true;
} else if (cnt1->getCounter() < cnt2->getCounter()) {
comparison.Append("<");
red = true;
} else {
comparison.Append("?");
red = true;
}
} else {
comparison.Append(" ");
red = true;
}
if (cnt2)
comparison.Append(" (2)");
else
comparison.Append(" ( )");
if (!colored)
return comparison;
else if (yellow)
return TQStringUtils::makeBoldYellow(comparison);
else if (red)
return TQStringUtils::makeBoldRed(comparison);
else
return TQStringUtils::makeBoldGreen(comparison);
}
bool TQCounter::isEqualTo(TQCounter * counter, double order) {
if (!isRawEqualTo(counter))
return false;
if (!TMath::AreEqualRel(getCounter(), counter->getCounter(), order))
return false;
if (!TMath::AreEqualRel(getError(), counter->getError(), order))
return false;
return true;
}
bool TQCounter::isRawEqualTo(TQCounter * counter) {
if (!counter)
return false;
if (getRawCounter() != counter->getRawCounter())
return false;
return true;
}
TQCounter::~TQCounter() {
}