00001
00002 #include "CondFormats/L1TObjects/interface/L1GctJetEtCalibrationFunction.h"
00003
00004 #include "CondFormats/L1TObjects/interface/L1CaloEtScale.h"
00005
00006 #include <iostream>
00007 #include <iomanip>
00008 #include <assert.h>
00009 #include <math.h>
00010
00011
00012 const unsigned L1GctJetEtCalibrationFunction::NUMBER_ETA_VALUES = 11;
00013 const unsigned L1GctJetEtCalibrationFunction::N_CENTRAL_ETA_VALUES = 7;
00014
00015 L1GctJetEtCalibrationFunction::L1GctJetEtCalibrationFunction()
00016 : m_corrFunType(POWER_SERIES_CORRECTION),
00017 m_convertToEnergy(false),
00018 m_htScaleLSB(1.0), m_threshold(1.0),
00019 m_jetCalibFunc(), m_tauCalibFunc(), m_energyConversion()
00020 {
00021 }
00022
00023 L1GctJetEtCalibrationFunction::~L1GctJetEtCalibrationFunction()
00024 {
00025 }
00026
00027 void L1GctJetEtCalibrationFunction::setParams(const double& htScale,
00028 const double& threshold,
00029 const std::vector< std::vector<double> >& jetCalibFunc,
00030 const std::vector< std::vector<double> >& tauCalibFunc ) {
00031 assert ((jetCalibFunc.size() == NUMBER_ETA_VALUES) && (tauCalibFunc.size() == N_CENTRAL_ETA_VALUES));
00032 m_htScaleLSB = htScale;
00033 m_threshold = threshold;
00034 m_jetCalibFunc = jetCalibFunc;
00035 m_tauCalibFunc = tauCalibFunc;
00036 }
00037
00039 void L1GctJetEtCalibrationFunction::setConversionToEnergyOn(const std::vector<double>& conversionFunc) {
00040 assert (conversionFunc.size() == NUMBER_ETA_VALUES);
00041 m_convertToEnergy=true;
00042 m_energyConversion = conversionFunc;
00043 }
00044
00045 void L1GctJetEtCalibrationFunction::setConversionToEnergyOff() {
00046 m_convertToEnergy = false;
00047 m_energyConversion.clear();
00048 }
00049
00050 std::ostream& operator << (std::ostream& os, const L1GctJetEtCalibrationFunction& fn)
00051 {
00052 os << "=== Level-1 GCT : Jet Et Calibration Function ===" << std::endl;
00053 os << std::setprecision(2);
00054 os << "LSB for Ht scale is " << std::fixed << fn.m_htScaleLSB << ", jet veto threshold is " << fn.m_threshold << std::endl;
00055 if (fn.m_corrFunType == L1GctJetEtCalibrationFunction::NO_CORRECTION) {
00056 os << "No jet energy corrections applied" << std::endl;
00057 } else {
00058 switch (fn.m_corrFunType)
00059 {
00060 case L1GctJetEtCalibrationFunction::POWER_SERIES_CORRECTION:
00061 os << "Power series energy correction for jets is enabled" << std::endl;
00062 break;
00063 case L1GctJetEtCalibrationFunction::ORCA_STYLE_CORRECTION:
00064 os << "ORCA-style energy correction for jets is enabled" << std::endl;
00065 break;
00066 case L1GctJetEtCalibrationFunction::PIECEWISE_CUBIC_CORRECTION:
00067 os << "Piecewise 3rd-order polynomial energy correction for jets is enabled" << std::endl;
00068 break;
00069 default:
00070 os << "Unrecognised calibration function type" << std::endl;
00071 break;
00072 }
00073 os << "Non-tau jet correction coefficients" << std::endl;
00074 for (unsigned i=0; i<fn.m_jetCalibFunc.size(); i++){
00075 os << "Eta =" << std::setw(2) << i;
00076 if (fn.m_jetCalibFunc.at(i).empty()) {
00077 os << ", no non-linear correction.";
00078 } else {
00079 os << " Coefficients = ";
00080 for (unsigned j=0; j<fn.m_jetCalibFunc.at(i).size();j++){
00081 os << fn.m_jetCalibFunc.at(i).at(j) << " ";
00082 }
00083 }
00084 os << std::endl;
00085 }
00086 os << "Tau jet correction coefficients" << std::endl;
00087 for (unsigned i=0; i<fn.m_tauCalibFunc.size(); i++){
00088 os << "Eta =" << std::setw(2) << i;
00089 if (fn.m_tauCalibFunc.at(i).empty()) {
00090 os << ", no non-linear correction.";
00091 } else {
00092 os << " Coefficients = ";
00093 for (unsigned j=0; j<fn.m_tauCalibFunc.at(i).size();j++){
00094 os << fn.m_tauCalibFunc.at(i).at(j) << " ";
00095 }
00096 }
00097 os << std::endl;
00098 }
00099 }
00100 return os;
00101 }
00102
00103
00104 double L1GctJetEtCalibrationFunction::correctedEt(const double et,
00105 const unsigned eta,
00106 const bool tauVeto) const
00107 {
00108 if ((tauVeto && eta>=NUMBER_ETA_VALUES) || (!tauVeto && eta>=N_CENTRAL_ETA_VALUES)) {
00109 return 0;
00110 } else {
00111 double result=0;
00112 if (tauVeto) {
00113 assert(eta<m_jetCalibFunc.size());
00114 result=findCorrectedEt(et, m_jetCalibFunc.at(eta));
00115 } else {
00116 assert(eta<m_tauCalibFunc.size());
00117 result=findCorrectedEt(et, m_tauCalibFunc.at(eta));
00118 }
00119 if (m_convertToEnergy) { result *= m_energyConversion.at(eta); }
00120 if (result>m_threshold) { return result; }
00121 else { return 0; }
00122 }
00123 }
00124
00125
00126
00127 double L1GctJetEtCalibrationFunction::findCorrectedEt(const double Et, const std::vector<double>& coeffs) const
00128 {
00129 double result=0;
00130 switch (m_corrFunType)
00131 {
00132 case POWER_SERIES_CORRECTION:
00133 result = powerSeriesCorrect(Et, coeffs);
00134 break;
00135 case ORCA_STYLE_CORRECTION:
00136 result = orcaStyleCorrect(Et, coeffs);
00137 break;
00138 case PIECEWISE_CUBIC_CORRECTION:
00139 result = piecewiseCubicCorrect(Et, coeffs);
00140 break;
00141 default:
00142 result = Et;
00143 }
00144 return result;
00145 }
00146
00147 double L1GctJetEtCalibrationFunction::powerSeriesCorrect(const double Et, const std::vector<double>& coeffs) const
00148 {
00149 double corrEt = Et;
00150 for (unsigned i=0; i<coeffs.size();i++) {
00151 corrEt += coeffs.at(i)*pow(Et,(int)i);
00152 }
00153 return corrEt;
00154 }
00155
00156 double L1GctJetEtCalibrationFunction::orcaStyleCorrect(const double Et, const std::vector<double>& coeffs) const
00157 {
00158
00159 std::vector<double>::const_iterator next_coeff=coeffs.begin();
00160 while (next_coeff != coeffs.end()) {
00161 double threshold = *next_coeff++;
00162 double A = *next_coeff++;
00163 double B = *next_coeff++;
00164 double C = *next_coeff++;
00165 if (Et>threshold) {
00166
00167
00168 return 2*(Et-A)/(B+sqrt(B*B-4*A*C+4*Et*C));
00169 }
00170
00171 }
00172 return Et;
00173 }
00174
00175 double L1GctJetEtCalibrationFunction::piecewiseCubicCorrect(const double Et, const std::vector<double>& coeffs) const
00176 {
00177
00178
00179
00180
00181
00182
00183 double etOut = Et;
00184 std::vector<double>::const_iterator next_coeff=coeffs.begin();
00185 while (next_coeff != coeffs.end()) {
00186
00187
00188 double threshold = *next_coeff++;
00189 double A = *next_coeff++;
00190 double B = *next_coeff++;
00191 double C = *next_coeff++;
00192 double D = *next_coeff++;
00193
00194
00195 if (Et>threshold) {
00196 etOut += (A + etOut*(B + etOut*(C + etOut*D))) ;
00197 break;
00198 }
00199
00200 }
00201 return etOut;
00202 }
00203
00205 uint16_t L1GctJetEtCalibrationFunction::calibratedEt(const double correctedEt) const
00206 {
00207 double scaledEt = correctedEt / m_htScaleLSB;
00208
00209 uint16_t jetEtOut = static_cast<uint16_t>(scaledEt);
00210
00211 if(jetEtOut > L1CaloEtScale::linScaleMax) {
00212 return L1CaloEtScale::linScaleMax;
00213 } else {
00214 return jetEtOut;
00215 }
00216 }