Go to the documentation of this file.00001 #include "PhysicsTools/IsolationUtils/interface/IntegralOverPhiFunction.h"
00002
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <iostream>
00025 #include <iomanip>
00026 #include <vector>
00027
00028
00029 #include <TMath.h>
00030
00031
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033
00034 #include "DataFormats/Math/interface/normalizedPhi.h"
00035
00036
00037
00038
00039
00040 void checkSolutions(unsigned int i, unsigned int& numSolution1, unsigned int& numSolution2, unsigned int& numSolution3, unsigned int& numSolution4);
00041
00042
00043
00044
00045
00046 IntegralOverPhiFunction::IntegralOverPhiFunction()
00047 : ROOT::Math::ParamFunction<ROOT::Math::IParametricGradFunctionOneDim>(3)
00048 {
00049 theta0_ = 0.;
00050 phi0_ = 0.;
00051 alpha_ = 0.;
00052
00053
00054 numSolutionMin1_ = 0;
00055 numSolutionMax1_ = 0;
00056 numSolutionMin2_ = 0;
00057 numSolutionMax2_ = 0;
00058 numSolutionMin3_ = 0;
00059 numSolutionMax3_ = 0;
00060 numSolutionMin4_ = 0;
00061 numSolutionMax4_ = 0;
00062
00063 }
00064
00065 IntegralOverPhiFunction::~IntegralOverPhiFunction()
00066 {
00067
00068 if ( debugLevel_ > 0 ) {
00069 edm::LogVerbatim("") << "<IntegralOverPhiFunction::~IntegralOverPhiFunction>:" << std::endl
00070 << " numSolutionMin1 = " << numSolutionMin1_ << std::endl
00071 << " numSolutionMax1 = " << numSolutionMax1_ << std::endl
00072 << " numSolutionMin2 = " << numSolutionMin2_ << std::endl
00073 << " numSolutionMax2 = " << numSolutionMax2_ << std::endl
00074 << " numSolutionMin3 = " << numSolutionMin3_ << std::endl
00075 << " numSolutionMax3 = " << numSolutionMax3_ << std::endl
00076 << " numSolutionMin4 = " << numSolutionMin4_ << std::endl
00077 << " numSolutionMax4 = " << numSolutionMax4_ << std::endl;
00078 }
00079
00080 }
00081
00082
00083
00084
00085
00086 void IntegralOverPhiFunction::SetParameterTheta0(double theta0)
00087 {
00088 theta0_ = theta0;
00089 }
00090
00091 void IntegralOverPhiFunction::SetParameterPhi0(double phi0)
00092 {
00093 phi0_ = normalizedPhi(phi0);
00094 }
00095
00096 void IntegralOverPhiFunction::SetParameterAlpha(double alpha)
00097 {
00098 alpha_ = alpha;
00099 }
00100
00101 void IntegralOverPhiFunction::SetParameters(double* param)
00102 {
00103 theta0_ = param[0];
00104 phi0_ = param[1];
00105 alpha_ = param[2];
00106 }
00107
00108 double IntegralOverPhiFunction::DoEvalPar(double x, const double* param) const
00109 {
00110 theta0_ = param[0];
00111 phi0_ = param[1];
00112 alpha_ = param[2];
00113
00114 return DoEval(x);
00115 }
00116
00117
00118
00119 double IntegralOverPhiFunction::DoEval(double x) const
00120 {
00121
00122
00123
00124 const double epsilon = 1.e-3;
00125 if ( x < epsilon || x > (TMath::Pi() - epsilon) ) return 0.;
00126
00127
00128
00129
00130
00131
00132 double theta0 = theta0_;
00133 if ( theta0 < epsilon ) theta0 = epsilon;
00134 if ( theta0 > (TMath::Pi() - epsilon)) theta0 = (TMath::Pi() - epsilon);
00135 double cosTheta0 = TMath::Cos(theta0);
00136 double cos2Theta0 = TMath::Cos(2*theta0);
00137 double sinTheta0 = TMath::Sin(theta0);
00138 double cotTheta0 = 1./TMath::Tan(theta0);
00139 double cscTheta0 = 1./TMath::Sin(theta0);
00140
00141
00142 double cosPhi0 = TMath::Cos(phi0_);
00143 double tanPhi0 = TMath::Tan(phi0_);
00144
00145
00146 double cosTheta = TMath::Cos(x);
00147 double cos2Theta = TMath::Cos(2*x);
00148 double sinTheta = TMath::Sin(x);
00149 double cotTheta = 1./TMath::Tan(x);
00150 double cscTheta = 1./TMath::Sin(x);
00151
00152
00153 double cosAlpha = TMath::Cos(alpha_);
00154
00155 double s = -cosPhi0*cosPhi0*(2*cosAlpha*cosAlpha + cos2Theta - 4*cosAlpha*cosTheta*cosTheta0 + cos2Theta0)*sinTheta*sinTheta*sinTheta0*sinTheta0;
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 if ( s <= 0 ) {
00170 if ( TMath::Abs(x - theta0) > alpha_ ) return 0;
00171 if ( TMath::Abs(x - theta0) <= alpha_ ) return 2*TMath::Pi();
00172 std::cerr << "Error in <IntegralOverPhiFunction::operator()>: failed to compute return value !" << std::endl;
00173 }
00174
00175 double r = (1./TMath::Sqrt(2.))*(cscTheta*cscTheta*cscTheta0*cscTheta0*TMath::Sqrt(s)*tanPhi0);
00176 double t = cosPhi0*(-cotTheta*cotTheta0 + cosAlpha*cscTheta*cscTheta0);
00177
00178 double phi[4];
00179 phi[0] = -TMath::ACos(t - r);
00180 phi[1] = TMath::ACos(t - r);
00181 phi[2] = -TMath::ACos(t + r);
00182 phi[3] = TMath::ACos(t + r);
00183
00184 if ( debugLevel_ > 0 ) {
00185 edm::LogVerbatim("") << "phi0 = " << phi0_ << std::endl
00186 << "phi[0] = " << phi[0] << " (phi[0] - phi0 = " << (phi[0] - phi0_)*180/TMath::Pi() << ")" << std::endl
00187 << "phi[1] = " << phi[1] << " (phi[1] - phi0 = " << (phi[1] - phi0_)*180/TMath::Pi() << ")" << std::endl
00188 << "phi[2] = " << phi[2] << " (phi[2] - phi0 = " << (phi[2] - phi0_)*180/TMath::Pi() << ")" << std::endl
00189 << "phi[3] = " << phi[3] << " (phi[3] - phi0 = " << (phi[3] - phi0_)*180/TMath::Pi() << ")" << std::endl;
00190 }
00191
00192 double phiMin = 0.;
00193 double phiMax = 0.;
00194 for ( unsigned int i = 0; i < 4; ++i ) {
00195 for ( unsigned int j = (i + 1); j < 4; ++j ) {
00196
00197
00198
00199 double dPhi_i = phi[i] - phi0_;
00200 double dPhi_j = phi0_ - phi[j];
00201 if ( TMath::Abs(normalizedPhi(dPhi_i - dPhi_j)) < epsilon ) {
00202
00203 phiMin = TMath::Min(phi[i], phi[j]);
00204 phiMax = TMath::Max(phi[i], phi[j]);
00205
00206
00207 if ( phi[i] == phiMin ) checkSolutions(i, numSolutionMin1_, numSolutionMin2_, numSolutionMin3_, numSolutionMin4_);
00208 if ( phi[i] == phiMax ) checkSolutions(i, numSolutionMax1_, numSolutionMax2_, numSolutionMax3_, numSolutionMax4_);
00209 if ( phi[j] == phiMin ) checkSolutions(j, numSolutionMin1_, numSolutionMin2_, numSolutionMin3_, numSolutionMin4_);
00210 if ( phi[j] == phiMax ) checkSolutions(j, numSolutionMax1_, numSolutionMax2_, numSolutionMax3_, numSolutionMax4_);
00211
00212 }
00213 }
00214 }
00215
00216 if ( phiMin == 0 && phiMax == 0 ) {
00217 edm::LogError("") << "failed to compute Return Value !" << std::endl;
00218 }
00219
00220 return TMath::Abs(normalizedPhi(phi0_ - phiMin)) + TMath::Abs(normalizedPhi(phiMax - phi0_));
00221 }
00222
00223 double IntegralOverPhiFunction::DoDerivative(double x) const
00224 {
00225
00226
00227 edm::LogWarning("") << "Function not implemented yet !" << std::endl;
00228
00229 return 0.;
00230 }
00231
00232 double IntegralOverPhiFunction::DoParameterDerivative(double, const double*, unsigned int) const
00233 {
00234
00235
00236 edm::LogWarning("") << "Function not implemented yet !" << std::endl;
00237
00238 return 0.;
00239 }
00240
00241 void IntegralOverPhiFunction::DoParameterGradient(double x, double* paramGradient) const
00242 {
00243
00244
00245 edm::LogWarning("") << "Function not implemented yet !" << std::endl;
00246 }
00247
00248
00249
00250
00251
00252 void checkSolutions(unsigned int i, unsigned int& numSolution1, unsigned int& numSolution2, unsigned int& numSolution3, unsigned int& numSolution4)
00253 {
00254 switch ( i ) {
00255 case 0 :
00256 ++numSolution1;
00257 break;
00258 case 1 :
00259 ++numSolution2;
00260 break;
00261 case 2 :
00262 ++numSolution3;
00263 break;
00264 case 3 :
00265 ++numSolution4;
00266 break;
00267 }
00268 }