/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PhysicsTools/IsolationUtils/src/IntegralOverPhiFunction.cc
275 строк
10 KB
Cms Build
Clang-Format
03 июн 2019, 06:45
03 июн 2019, 06:45
d4f6565
Код
Авторство
О чём код?
#include "PhysicsTools/IsolationUtils/interface/IntegralOverPhiFunction.h" // -*- C++ -*- // // Package: IntegralOverPhiFunction // Class: IntegralOverPhiFunction // /**\class IntegralOverPhiFunction IntegralOverPhiFunction.cc PhysicsTools/IsolationUtils/src/IntegralOverPhiFunction.cc Description: auxialiary class for fixed area isolation cone computation (this class performs the integration over the azimuthal angle) Implementation: imported into CMSSW on 05/18/2007 */ // // Original Author: Christian Veelken, UC Davis // Created: Thu Nov 2 13:47:40 CST 2006 // // // system include files #include <iostream> #include <iomanip> #include <vector> // ROOT include files #include <TMath.h> // CMSSW include files #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "DataFormats/Math/interface/normalizedPhi.h" // // declaration of auxiliary functions // void checkSolutions(unsigned int i, unsigned int& numSolution1, unsigned int& numSolution2, unsigned int& numSolution3, unsigned int& numSolution4); // // constructors and destructor // IntegralOverPhiFunction::IntegralOverPhiFunction() : ROOT::Math::ParamFunction<ROOT::Math::IParametricGradFunctionOneDim>(3) { theta0_ = 0.; phi0_ = 0.; alpha_ = 0.; // !!! ONLY FOR TESTING numSolutionMin1_ = 0; numSolutionMax1_ = 0; numSolutionMin2_ = 0; numSolutionMax2_ = 0; numSolutionMin3_ = 0; numSolutionMax3_ = 0; numSolutionMin4_ = 0; numSolutionMax4_ = 0; // FOR TESTING ONLY !!! } IntegralOverPhiFunction::~IntegralOverPhiFunction() { // !!! ONLY FOR TESTING if (debugLevel_ > 0) { edm::LogVerbatim("") << "<IntegralOverPhiFunction::~IntegralOverPhiFunction>:" << std::endl << " numSolutionMin1 = " << numSolutionMin1_ << std::endl << " numSolutionMax1 = " << numSolutionMax1_ << std::endl << " numSolutionMin2 = " << numSolutionMin2_ << std::endl << " numSolutionMax2 = " << numSolutionMax2_ << std::endl << " numSolutionMin3 = " << numSolutionMin3_ << std::endl << " numSolutionMax3 = " << numSolutionMax3_ << std::endl << " numSolutionMin4 = " << numSolutionMin4_ << std::endl << " numSolutionMax4 = " << numSolutionMax4_ << std::endl; } // FOR TESTING ONLY !!! } // // member functions // void IntegralOverPhiFunction::SetParameterTheta0(double theta0) { theta0_ = theta0; } void IntegralOverPhiFunction::SetParameterPhi0(double phi0) { phi0_ = normalizedPhi(phi0); // map azimuth angle into interval [-pi,+pi] } void IntegralOverPhiFunction::SetParameterAlpha(double alpha) { alpha_ = alpha; } void IntegralOverPhiFunction::SetParameters(const double* param) { theta0_ = param[0]; phi0_ = param[1]; alpha_ = param[2]; } double IntegralOverPhiFunction::DoEvalPar( double x, const double* param) const //FIXME: in the current implementation const is not entirely true { theta0_ = param[0]; phi0_ = param[1]; alpha_ = param[2]; return DoEval(x); } double IntegralOverPhiFunction::DoEval(double x) const { //--- return zero if theta either close to zero or close to Pi // (phi not well-defined in that case; // numerical expressions might become "NaN"s) const double epsilon = 1.e-3; if (x < epsilon || x > (TMath::Pi() - epsilon)) return 0.; //--- calculate trigonometric expressions // (dependend on angle theta0; // polar angle of cone axis); // avoid theta0 exactly zero or exactly Pi // (numerical expressions become "NaN"s) double theta0 = theta0_; if (theta0 < epsilon) theta0 = epsilon; if (theta0 > (TMath::Pi() - epsilon)) theta0 = (TMath::Pi() - epsilon); double cosTheta0 = TMath::Cos(theta0); double cos2Theta0 = TMath::Cos(2 * theta0); double sinTheta0 = TMath::Sin(theta0); double cotTheta0 = 1. / TMath::Tan(theta0); double cscTheta0 = 1. / TMath::Sin(theta0); // (dependend on angle phi0; // azimuth angle of cone axis) double cosPhi0 = TMath::Cos(phi0_); double tanPhi0 = TMath::Tan(phi0_); // (dependend on angle theta; // polar angle of point within cone) double cosTheta = TMath::Cos(x); double cos2Theta = TMath::Cos(2 * x); double sinTheta = TMath::Sin(x); double cotTheta = 1. / TMath::Tan(x); double cscTheta = 1. / TMath::Sin(x); // (dependent on angle alpha; // opening angle of cone, measured from cone axis) double cosAlpha = TMath::Cos(alpha_); double s = -cosPhi0 * cosPhi0 * (2 * cosAlpha * cosAlpha + cos2Theta - 4 * cosAlpha * cosTheta * cosTheta0 + cos2Theta0) * sinTheta * sinTheta * sinTheta0 * sinTheta0; //--- return either zero or 2 Pi // in case argument of square-root is zero or negative // (negative values solely arise from rounding errors); // check whether to return zero or 2 Pi: // o return zero // if |theta- theta0| > alpha, // (theta outside cone of opening angle alpha, so vanishing integral over phi) // o return 2 Pi // if |theta- theta0| < alpha // (theta within cone of opening angle alpha; // actually theta0 < alpha in forward/backward direction, // so that integral includes all phi values, hence yielding 2 Pi) if (s <= 0) { if (TMath::Abs(x - theta0) > alpha_) return 0; if (TMath::Abs(x - theta0) <= alpha_) return 2 * TMath::Pi(); std::cerr << "Error in <IntegralOverPhiFunction::operator()>: failed to compute return value !" << std::endl; } double r = (1. / TMath::Sqrt(2.)) * (cscTheta * cscTheta * cscTheta0 * cscTheta0 * TMath::Sqrt(s) * tanPhi0); double t = cosPhi0 * (-cotTheta * cotTheta0 + cosAlpha * cscTheta * cscTheta0); double phi[4]; phi[0] = -TMath::ACos(t - r); phi[1] = TMath::ACos(t - r); phi[2] = -TMath::ACos(t + r); phi[3] = TMath::ACos(t + r); if (debugLevel_ > 0) { edm::LogVerbatim("") << "phi0 = " << phi0_ << std::endl << "phi[0] = " << phi[0] << " (phi[0] - phi0 = " << (phi[0] - phi0_) * 180 / TMath::Pi() << ")" << std::endl << "phi[1] = " << phi[1] << " (phi[1] - phi0 = " << (phi[1] - phi0_) * 180 / TMath::Pi() << ")" << std::endl << "phi[2] = " << phi[2] << " (phi[2] - phi0 = " << (phi[2] - phi0_) * 180 / TMath::Pi() << ")" << std::endl << "phi[3] = " << phi[3] << " (phi[3] - phi0 = " << (phi[3] - phi0_) * 180 / TMath::Pi() << ")" << std::endl; } double phiMin = 0.; double phiMax = 0.; for (unsigned int i = 0; i < 4; ++i) { for (unsigned int j = (i + 1); j < 4; ++j) { //--- search for the two solutions for phi // that have an equal distance to phi0 // and are on either side double dPhi_i = phi[i] - phi0_; double dPhi_j = phi0_ - phi[j]; if (TMath::Abs(normalizedPhi(dPhi_i - dPhi_j)) < epsilon) { // map difference in azimuth angle into interval [-pi,+pi] and require it to be negligible //if ( TMath::Abs((phi[i] - phi0_) - (phi0_ - phi[j])) < epsilon ) { // map difference in azimuth angle into interval [-pi,+pi] and require it to be negligible phiMin = TMath::Min(phi[i], phi[j]); phiMax = TMath::Max(phi[i], phi[j]); // !!! ONLY FOR TESTING if (phi[i] == phiMin) checkSolutions(i, numSolutionMin1_, numSolutionMin2_, numSolutionMin3_, numSolutionMin4_); if (phi[i] == phiMax) checkSolutions(i, numSolutionMax1_, numSolutionMax2_, numSolutionMax3_, numSolutionMax4_); if (phi[j] == phiMin) checkSolutions(j, numSolutionMin1_, numSolutionMin2_, numSolutionMin3_, numSolutionMin4_); if (phi[j] == phiMax) checkSolutions(j, numSolutionMax1_, numSolutionMax2_, numSolutionMax3_, numSolutionMax4_); // FOR TESTING ONLY !!! } } } if (phiMin == 0 && phiMax == 0) { edm::LogError("") << "failed to compute Return Value !" << std::endl; } return TMath::Abs(normalizedPhi(phi0_ - phiMin)) + TMath::Abs(normalizedPhi(phiMax - phi0_)); } double IntegralOverPhiFunction::DoDerivative(double x) const { //--- virtual function inherited from ROOT::Math::ParamFunction base class; // not implemented, because not neccessary, but needs to be defined to make code compile... edm::LogWarning("") << "Function not implemented yet !" << std::endl; return 0.; } double IntegralOverPhiFunction::DoParameterDerivative(double, const double*, unsigned int) const { //--- virtual function inherited from ROOT::Math::ParamFunction base class; // not implemented, because not neccessary, but needs to be defined to make code compile... edm::LogWarning("") << "Function not implemented yet !" << std::endl; return 0.; } void IntegralOverPhiFunction::DoParameterGradient(double x, double* paramGradient) const { //--- virtual function inherited from ROOT::Math::ParamFunction base class; // not implemented, because not neccessary, but needs to be defined to make code compile... edm::LogWarning("") << "Function not implemented yet !" << std::endl; } // // definition of auxiliary functions // void checkSolutions(unsigned int i, unsigned int& numSolution1, unsigned int& numSolution2, unsigned int& numSolution3, unsigned int& numSolution4) { switch (i) { case 0: ++numSolution1; break; case 1: ++numSolution2; break; case 2: ++numSolution3; break; case 3: ++numSolution4; break; } }