Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:00

0001 #include <cppunit/extensions/HelperMacros.h>
0002 #include <algorithm>
0003 #include <iterator>
0004 #include <iostream>
0005 #include <iomanip>
0006 #include <TMath.h>
0007 
0008 #include "DataFormats/PatCandidates/interface/ParametrizationHelper.h"
0009 #include "DataFormats/PatCandidates/interface/ResolutionHelper.h"
0010 
0011 class testKinResolutions : public CppUnit::TestFixture {
0012   CPPUNIT_TEST_SUITE(testKinResolutions);
0013 
0014   CPPUNIT_TEST(testTrivialMatrix_Cart);
0015   CPPUNIT_TEST(testTrivialMatrix_ECart);
0016   CPPUNIT_TEST(testTrivialMatrix_Spher);
0017   CPPUNIT_TEST(testTrivialMatrix_ESpher);
0018   CPPUNIT_TEST(testTrivialMatrix_MomDev);
0019   CPPUNIT_TEST(testTrivialMatrix_EMomDev);
0020   CPPUNIT_TEST(testTrivialMatrix_MCCart);
0021   CPPUNIT_TEST(testTrivialMatrix_MCSpher);
0022   CPPUNIT_TEST(testTrivialMatrix_MCPInvSpher);
0023   CPPUNIT_TEST(testTrivialMatrix_EtEtaPhi);
0024   CPPUNIT_TEST(testTrivialMatrix_EtThetaPhi);
0025   CPPUNIT_TEST(testTrivialMatrix_MCMomDev);
0026   CPPUNIT_TEST(testTrivialMatrix_EScaledMomDev);
0027 
0028   CPPUNIT_TEST(testIndependentVars_Cart);
0029   CPPUNIT_TEST(testIndependentVars_ECart);
0030   CPPUNIT_TEST(testIndependentVars_Spher);
0031   CPPUNIT_TEST(testIndependentVars_ESpher);
0032   CPPUNIT_TEST(testIndependentVars_MomDev);
0033   CPPUNIT_TEST(testIndependentVars_EMomDev);
0034   CPPUNIT_TEST(testIndependentVars_MCCart);
0035   CPPUNIT_TEST(testIndependentVars_MCSpher);
0036   CPPUNIT_TEST(testIndependentVars_MCPInvSpher);
0037   CPPUNIT_TEST(testIndependentVars_EtEtaPhi);
0038   CPPUNIT_TEST(testIndependentVars_EtThetaPhi);
0039   CPPUNIT_TEST(testIndependentVars_MCMomDev);
0040   CPPUNIT_TEST(testIndependentVars_EScaledMomDev);
0041 
0042   CPPUNIT_TEST(testDependentVars_Cart);
0043   CPPUNIT_TEST(testDependentVars_ECart);
0044   CPPUNIT_TEST(testDependentVars_Spher);
0045   CPPUNIT_TEST(testDependentVars_ESpher);
0046   CPPUNIT_TEST(testDependentVars_MomDev);
0047   CPPUNIT_TEST(testDependentVars_EMomDev);
0048   CPPUNIT_TEST(testDependentVars_MCCart);
0049   CPPUNIT_TEST(testDependentVars_MCSpher);
0050   CPPUNIT_TEST(testDependentVars_MCPInvSpher);
0051   CPPUNIT_TEST(testDependentVars_EtEtaPhi);
0052   CPPUNIT_TEST(testDependentVars_EtThetaPhi);
0053   CPPUNIT_TEST(testDependentVars_MCMomDev);
0054   CPPUNIT_TEST(testDependentVars_EScaledMomDev);
0055 
0056   CPPUNIT_TEST_SUITE_END();
0057 
0058 public:
0059   void setUp() {}
0060   void tearDown() {}
0061 
0062   void testTrivialMatrix_Cart();
0063   void testTrivialMatrix_ECart();
0064   void testTrivialMatrix_Spher();
0065   void testTrivialMatrix_ESpher();
0066   void testTrivialMatrix_MomDev();
0067   void testTrivialMatrix_EMomDev();
0068   void testTrivialMatrix_MCCart();
0069   void testTrivialMatrix_MCSpher();
0070   void testTrivialMatrix_MCPInvSpher();
0071   void testTrivialMatrix_EtEtaPhi();
0072   void testTrivialMatrix_EtThetaPhi();
0073   void testTrivialMatrix_MCMomDev();
0074   void testTrivialMatrix_EScaledMomDev();
0075 
0076   void testIndependentVars_Cart();
0077   void testIndependentVars_ECart();
0078   void testIndependentVars_Spher();
0079   void testIndependentVars_ESpher();
0080   void testIndependentVars_MomDev();
0081   void testIndependentVars_EMomDev();
0082   void testIndependentVars_MCCart();
0083   void testIndependentVars_MCSpher();
0084   void testIndependentVars_MCPInvSpher();
0085   void testIndependentVars_EtEtaPhi();
0086   void testIndependentVars_EtThetaPhi();
0087   void testIndependentVars_MCMomDev();
0088   void testIndependentVars_EScaledMomDev();
0089 
0090   void testDependentVars_Cart();
0091   void testDependentVars_ECart();
0092   void testDependentVars_Spher();
0093   void testDependentVars_ESpher();
0094   void testDependentVars_MomDev();
0095   void testDependentVars_EMomDev();
0096   void testDependentVars_MCCart();
0097   void testDependentVars_MCSpher();
0098   void testDependentVars_MCPInvSpher();
0099   void testDependentVars_EtEtaPhi();
0100   void testDependentVars_EtThetaPhi();
0101   void testDependentVars_MCMomDev();
0102   void testDependentVars_EScaledMomDev();
0103 
0104   typedef math::XYZTLorentzVector P4C;
0105   typedef math::PtEtaPhiMLorentzVector P4P;
0106   typedef AlgebraicVector4 V4;
0107   typedef AlgebraicSymMatrix44 M4;
0108 
0109 private:
0110   typedef pat::CandKinResolution::Parametrization Parametrization;
0111 
0112   /// check if resol 'f' for param 'p' throws an exception or not
0113   /// it won't even look at the value
0114   template <typename Func>
0115   bool testIfThrows(Parametrization p, Func f);
0116 
0117   /// check that resol 'f' for param 'p' is the square root of covariance(index,index)
0118   template <typename Func>
0119   bool testTrivialMatrix(Parametrization p, Func f, int index, int tries = 10);
0120 
0121   /// check that resol 'f' for param p is independent from the coordinate 'index'
0122   /// that is, if covariance(i,j) is null except for (index,index), resol 'f' must be zero
0123   template <typename Func>
0124   bool testIsIndependent(Parametrization p, Func f, int index, int tries = 10);
0125 
0126   /// check that resol 'f' for param p is independent from any coordinate index except 'self'
0127   template <typename Func>
0128   bool testFullyIndependent(Parametrization p, Func f, int self, int tries = 10);
0129 
0130   /// check the correctness of the derivative of some var the parameter, with respect to the numerical derivative
0131   /// computed symmetrically with step 'eps'.
0132   bool testDiagonalDerivativeM(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0133   bool testDiagonalDerivativeEta(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0134   bool testDiagonalDerivativeTheta(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0135   bool testDiagonalDerivativePhi(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0136   bool testDiagonalDerivativeEt(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0137   bool testDiagonalDerivativeE(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0138   bool testDiagonalDerivativeP(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0139   bool testDiagonalDerivativePt(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0140   bool testDiagonalDerivativePx(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0141   bool testDiagonalDerivativePy(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0142   bool testDiagonalDerivativePz(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0143   bool testDiagonalDerivativePInv(Parametrization p, int index, double eps = 1e-5, int tries = 200);
0144 
0145   /// check the correctness of the relative signs of two derivative of some var the parameter
0146   bool testOffDiagonalDerivativeM(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0147   bool testOffDiagonalDerivativeEta(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0148   bool testOffDiagonalDerivativeTheta(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0149   bool testOffDiagonalDerivativePhi(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0150   bool testOffDiagonalDerivativeEt(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0151   bool testOffDiagonalDerivativeE(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0152   bool testOffDiagonalDerivativeP(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0153   bool testOffDiagonalDerivativePt(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0154   bool testOffDiagonalDerivativePx(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0155   bool testOffDiagonalDerivativePy(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0156   bool testOffDiagonalDerivativePz(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0157   bool testOffDiagonalDerivativePInv(Parametrization p, int i, int j, double eps = 1e-5, int tries = 200);
0158 
0159   double getVarEta(P4P &p4) const { return p4.Eta(); }
0160   double getVarTheta(P4P &p4) const { return p4.Theta(); }
0161   double getVarPhi(P4P &p4) const { return p4.Phi(); }
0162   double getVarEt(P4P &p4) const { return p4.Et(); }
0163   double getVarE(P4P &p4) const { return p4.E(); }
0164   double getVarP(P4P &p4) const { return p4.P(); }
0165   double getVarPt(P4P &p4) const { return p4.Pt(); }
0166   double getVarPx(P4P &p4) const { return p4.Px(); }
0167   double getVarPy(P4P &p4) const { return p4.Py(); }
0168   double getVarPz(P4P &p4) const { return p4.Pz(); }
0169   double getVarM(P4P &p4) const { return p4.M(); }
0170   double getVarPInv(P4P &p4) const { return 1.0 / p4.P(); }
0171 
0172   // Utilities
0173   static double r(double val = 1.0) { return rand() * val / double(RAND_MAX); }
0174   static double r(double from, double to) { return rand() * (to - from) / double(RAND_MAX) + from; }
0175   static P4P r4(double m = -1) {
0176     double mass = (m != -1 ? m : (r() > .3 ? r(.1, 30) : 0));
0177     return P4P(r(5, 25), r(-2.5, 5), r(-M_PI, M_PI), mass);
0178   }
0179   static M4 diag(size_t dim) {
0180     M4 ret;
0181     for (size_t i = 0; i < dim; ++i)
0182       ret(i, i) = r(.1, 10);
0183     return ret;
0184   }
0185 };
0186 
0187 CPPUNIT_TEST_SUITE_REGISTRATION(testKinResolutions);
0188 
0189 template <typename Func>
0190 bool testKinResolutions::testIfThrows(Parametrization p, Func f) {
0191   srand(37);
0192   P4C p4;
0193   M4 mat = diag(pat::helper::ParametrizationHelper::dimension(p));
0194   double y = f(p, mat, p4);
0195   return (y != 1e37);  // so that it doesn't count as unused
0196 }
0197 
0198 using pat::helper::ParametrizationHelper::name;
0199 
0200 template <typename Func>
0201 bool testKinResolutions::testTrivialMatrix(Parametrization p, Func f, int index, int tries) {
0202   srand(37);
0203   using namespace pat::helper::ParametrizationHelper;
0204   for (int i = 0; i < tries; ++i) {
0205     P4C p4;
0206     M4 mat = diag(dimension(p));
0207     double x = sqrt(mat(index, index));
0208     double y = f(p, mat, p4);
0209     if (std::abs(x - y) > (std::abs(x) + std::abs(y) + 1) * 1e-6) {
0210       std::cerr << "Error for parametrization " << name(p) << ", index = " << index << "\n x = " << x << ", y = " << y
0211                 << std::endl;
0212       return false;
0213     }
0214   }
0215   return true;
0216 }
0217 
0218 template <typename Func>
0219 bool testKinResolutions::testIsIndependent(Parametrization par, Func f, int index, int tries) {
0220   double delta = 0.001;
0221   using namespace pat::helper::ParametrizationHelper;
0222   srand(37);
0223   for (int i = 0; i < tries; ++i) {
0224     P4P p1 = r4(isAlwaysMassless(par) ? 0 : (isAlwaysMassive(par) ? r(.1, 30) : (r() > .3 ? r(.1, 30) : 0)));
0225     //         V4  v1  = parametersFromP4(par, p1), v2; // warning from gcc461: variable 'v1' set but not used [-Wunused-but-set-variable]
0226     M4 mat;
0227     mat(index, index) = delta * delta;
0228     double exp = f(par, mat, P4C(p1));
0229     if (exp != 0)
0230       return false;
0231   }
0232   return true;
0233 }
0234 template <typename Func>
0235 bool testKinResolutions::testFullyIndependent(Parametrization par, Func f, int self, int tries) {
0236   for (int i = 0; i <= 3; ++i) {
0237     if (i == self)
0238       continue;
0239     if (!testIsIndependent(par, f, i, tries))
0240       return false;
0241   }
0242   return true;
0243 }
0244 
0245 #define IMPL_testDiagonalDerivative(VAR)                                                                            \
0246   bool testKinResolutions::testDiagonalDerivative##VAR(Parametrization par, int index, double delta, int tries) {   \
0247     using namespace pat::helper::ParametrizationHelper;                                                             \
0248     using namespace pat::helper::ResolutionHelper;                                                                  \
0249     srand(37);                                                                                                      \
0250     int skips = 0, glitches = 0;                                                                                    \
0251     for (int i = 0; i < tries; ++i) {                                                                               \
0252       P4P p1 = r4(isAlwaysMassless(par) ? 0 : r(.1, 30));                                                           \
0253       M4 mat;                                                                                                       \
0254       mat(index, index) = 1;                                                                                        \
0255       double exp = getResol##VAR(                                                                                   \
0256           par, mat, P4C(p1)); /* should be |dV/dX_i|, where V is the variable on which 'f' gets the resolution */   \
0257       /* now let's compute the derivative numerically */                                                            \
0258       V4 v = parametersFromP4(par, p1), vplus = v, vminus = v;                                                      \
0259       vplus[index] += delta;                                                                                        \
0260       vminus[index] -= delta;                                                                                       \
0261       if (isPhysical(par, vplus, p1) && (isPhysical(par, vminus, p1))) {                                            \
0262         P4P pplus = polarP4fromParameters(par, vplus, p1);                                                          \
0263         P4P pminus = polarP4fromParameters(par, vminus, p1);                                                        \
0264         double yplus = getVar##VAR(pplus), yminus = getVar##VAR(pminus);                                            \
0265         double num = (yplus - yminus) / (2 * delta);                                                                \
0266         double diff = std::abs(std::abs(num) - exp) / (std::abs(num) + std::abs(exp) + 1);                          \
0267         if (diff > 2e-4) {                                                                                          \
0268           std::cout << "\nError for  " #VAR "\n"                                                                    \
0269                     << "  par = " << name(par) << ", index = " << index << "\n"                                     \
0270                     << "  p4 = " << p1 << ",\n  expected = " << exp << ", numeric = " << num << ", diff = " << diff \
0271                     << std::endl;                                                                                   \
0272           glitches++;                                                                                               \
0273           if ((diff > 3e-2) || (glitches > std::max(tries / 10, 10)))                                               \
0274             return false;                                                                                           \
0275         }                                                                                                           \
0276       } else                                                                                                        \
0277         skips++;                                                                                                    \
0278     }                                                                                                               \
0279     if (double(skips) / tries >= 0.1) {                                                                             \
0280       std::cout << "Error for  " #VAR "\n"                                                                          \
0281                 << "  par = " << name(par) << ", index = " << index                                                 \
0282                 << "\n"                                                                                             \
0283                    "Unphysical momenta "                                                                            \
0284                 << skips << " over " << tries << std::endl;                                                         \
0285     }                                                                                                               \
0286     return (double(skips) / tries < 0.1);                                                                           \
0287   }
0288 IMPL_testDiagonalDerivative(M) IMPL_testDiagonalDerivative(Eta) IMPL_testDiagonalDerivative(Theta)
0289     IMPL_testDiagonalDerivative(Phi) IMPL_testDiagonalDerivative(Et) IMPL_testDiagonalDerivative(E)
0290         IMPL_testDiagonalDerivative(P) IMPL_testDiagonalDerivative(Pt) IMPL_testDiagonalDerivative(Px)
0291             IMPL_testDiagonalDerivative(Py) IMPL_testDiagonalDerivative(Pz) IMPL_testDiagonalDerivative(PInv)
0292 
0293 #define IMPL_testOffDiagonalDerivative(VAR)                                                                         \
0294   bool testKinResolutions::testOffDiagonalDerivative##VAR(                                                          \
0295       Parametrization par, int i, int j, double delta, int tries) {                                                 \
0296     using namespace pat::helper::ParametrizationHelper;                                                             \
0297     using namespace pat::helper::ResolutionHelper;                                                                  \
0298     srand(37);                                                                                                      \
0299     int skips = 0, glitches = 0;                                                                                    \
0300     for (int it = 0; it < tries; ++it) {                                                                            \
0301       P4P p1 = r4(isAlwaysMassless(par) ? 0 : r(.1, 30));                                                           \
0302       M4 mat;                                                                                                       \
0303       mat(i, i) = 1;                                                                                                \
0304       double vi = getResol##VAR(                                                                                    \
0305           par, mat, P4C(p1)); /* should be |dV/dX_i|, where V is the variable on which 'f' gets the resolution */   \
0306       mat(i, i) = 0;                                                                                                \
0307       mat(j, j) = 1;                                                                                                \
0308       double vj = getResol##VAR(                                                                                    \
0309           par, mat, P4C(p1)); /* should be |dV/dX_j|, where V is the variable on which 'f' gets the resolution */   \
0310       mat(i, i) = 2;                                                                                                \
0311       mat(j, j) = 2;                                                                                                \
0312       mat(i, j) = 1;                                                                                                \
0313       double vij =                                                                                                  \
0314           getResol##VAR(par, mat, P4C(p1)); /* should be sqrt(2)*(|dV/dX_i|^2+|dV/dx_j|^2 + 2 dV/dX_i dV_dX_j ) */  \
0315       /* now let's compute the derivative numerically */                                                            \
0316       V4 v = parametersFromP4(par, p1), vplus_i = v, vminus_i = v, vplus_j = v, vminus_j = v;                       \
0317       vplus_i[i] += delta;                                                                                          \
0318       vminus_i[i] -= delta;                                                                                         \
0319       vplus_j[j] += delta;                                                                                          \
0320       vminus_j[j] -= delta;                                                                                         \
0321       if (isPhysical(par, vplus_i, p1) && (isPhysical(par, vminus_i, p1)) && isPhysical(par, vplus_j, p1) &&        \
0322           (isPhysical(par, vminus_j, p1))) {                                                                        \
0323         P4P pplus_i = polarP4fromParameters(par, vplus_i, p1);                                                      \
0324         P4P pplus_j = polarP4fromParameters(par, vplus_j, p1);                                                      \
0325         P4P pminus_i = polarP4fromParameters(par, vminus_i, p1);                                                    \
0326         P4P pminus_j = polarP4fromParameters(par, vminus_j, p1);                                                    \
0327         double yplus_i = getVar##VAR(pplus_i), yminus_i = getVar##VAR(pminus_i);                                    \
0328         double yplus_j = getVar##VAR(pplus_j), yminus_j = getVar##VAR(pminus_j);                                    \
0329         double num_i = (yplus_i - yminus_i) / (2 * delta);                                                          \
0330         double num_j = (yplus_j - yminus_j) / (2 * delta);                                                          \
0331         if (num_i < 0)                                                                                              \
0332           vi = -vi;                                                                                                 \
0333         if (num_j < 0)                                                                                              \
0334           vj = -vj;                                                                                                 \
0335         double num = std::sqrt(2 * (vi * vi + vj * vj + vi * vj));                                                  \
0336         double diff = std::abs(std::abs(num) - vij) / (std::abs(num) + std::abs(vij) + 1);                          \
0337         if (diff > 1e-4) {                                                                                          \
0338           std::cout << "\nError for  " #VAR "\n"                                                                    \
0339                     << "  par = " << name(par) << ", i = " << i << ", j= " << j << "\n"                             \
0340                     << "  p4 = " << p1 << ",\n  expected = " << vij << ", numeric = " << num << ", diff = " << diff \
0341                     << std::endl;                                                                                   \
0342           glitches++;                                                                                               \
0343           if ((diff > 3e-2) || (glitches > std::max(tries / 10, 10)))                                               \
0344             return false;                                                                                           \
0345         }                                                                                                           \
0346       } else                                                                                                        \
0347         skips++;                                                                                                    \
0348     }                                                                                                               \
0349     if (double(skips) / tries >= 0.1) {                                                                             \
0350       std::cout << "Error for  " #VAR "\n"                                                                          \
0351                 << "  par = " << name(par) << ", i = " << i << ", j= " << j                                         \
0352                 << "\n"                                                                                             \
0353                    "Unphysical momenta "                                                                            \
0354                 << skips << " over " << tries << std::endl;                                                         \
0355     }                                                                                                               \
0356     return (double(skips) / tries < 0.1);                                                                           \
0357   }
0358                 IMPL_testOffDiagonalDerivative(M) IMPL_testOffDiagonalDerivative(Eta)
0359                     IMPL_testOffDiagonalDerivative(Theta) IMPL_testOffDiagonalDerivative(Phi)
0360                         IMPL_testOffDiagonalDerivative(Et) IMPL_testOffDiagonalDerivative(E)
0361                             IMPL_testOffDiagonalDerivative(P) IMPL_testOffDiagonalDerivative(Pt)
0362                                 IMPL_testOffDiagonalDerivative(Px) IMPL_testOffDiagonalDerivative(Py)
0363                                     IMPL_testOffDiagonalDerivative(Pz) IMPL_testOffDiagonalDerivative(PInv)
0364 
0365 #define ASSERT_DIAGONAL(PARAM, RESOL, INDEX)                                                                    \
0366   if (!testTrivialMatrix(pat::CandKinResolution::PARAM, RESOL, INDEX)) {                                        \
0367     CPPUNIT_NS::Asserter::fail("Resolution " #RESOL " for Parametrization " #PARAM " is not covariance(" #INDEX \
0368                                "," #INDEX ")",                                                                  \
0369                                CPPUNIT_SOURCELINE());                                                           \
0370   }
0371 
0372 #define ASSERT_FULLY_INDEPENDENT(PARAM, RESOL, INDEX)                                                                  \
0373   if (!testFullyIndependent(pat::CandKinResolution::PARAM, RESOL, INDEX)) {                                            \
0374     CPPUNIT_NS::Asserter::fail("Resolution " #RESOL " for Parametrization " #PARAM " is not only function of " #INDEX, \
0375                                CPPUNIT_SOURCELINE());                                                                  \
0376   }
0377 
0378 // Derivatives must not throw exceptions
0379 #define ASSERT_HAS_DERIVATIVE(PARAM, RESOL) CPPUNIT_ASSERT_NO_THROW(testIfThrows(pat::CandKinResolution::PARAM, RESOL));
0380 // And we can check their independence from some coordinate
0381 #define ASSERT_HAS_INDEP_DERIVATIVE(PARAM, RESOL, INDEX)                                                        \
0382   if (!testIsIndependent(pat::CandKinResolution::PARAM, RESOL, INDEX)) {                                        \
0383     CPPUNIT_NS::Asserter::fail("Resolution " #RESOL " for Parametrization " #PARAM " is correlated to " #INDEX, \
0384                                CPPUNIT_SOURCELINE());                                                           \
0385   }
0386 #define ASSERT_CHECK_DERIVATIVE(PARAM, VAR, INDEX)                                  \
0387   if (!testDiagonalDerivative##VAR(pat::CandKinResolution::PARAM, INDEX)) {         \
0388     CPPUNIT_NS::Asserter::fail("Resolution on " #VAR " for Parametrization " #PARAM \
0389                                " has wrong derivative w.r.t. " #INDEX,              \
0390                                CPPUNIT_SOURCELINE());                               \
0391   }
0392 #define ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, I, J)                                                                     \
0393   if (!testOffDiagonalDerivative##VAR(pat::CandKinResolution::PARAM, I, J)) {                                          \
0394     CPPUNIT_NS::Asserter::fail("Resolution on " #VAR " for Parametrization " #PARAM " has wrong derivative w.r.t. " #I \
0395                                "," #J,                                                                                 \
0396                                CPPUNIT_SOURCELINE());                                                                  \
0397   }
0398 
0399 #define ASSERT_CHECK_DERIVATIVES(PARAM, VAR)           \
0400   ASSERT_CHECK_DERIVATIVE(PARAM, VAR, 0)               \
0401   ASSERT_CHECK_DERIVATIVE(PARAM, VAR, 1)               \
0402   ASSERT_CHECK_DERIVATIVE(PARAM, VAR, 2)               \
0403   ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 0, 1)           \
0404   ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 0, 2)           \
0405   ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 1, 2)           \
0406   if (dimension(pat::CandKinResolution::PARAM) == 4) { \
0407     ASSERT_CHECK_DERIVATIVE(PARAM, VAR, 3)             \
0408     ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 0, 3)         \
0409     ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 1, 3)         \
0410     ASSERT_CHECK_DERIVATIVE2(PARAM, VAR, 2, 3)         \
0411   }
0412 
0413 #define ASSERT_NOT_IMPLEMENTED(PARAM, RESOL)                                       \
0414   do {                                                                             \
0415     bool cpputExceptionThrown_ = false;                                            \
0416     try {                                                                          \
0417       testTrivialMatrix(pat::CandKinResolution::PARAM, RESOL, 0, 1);               \
0418     } catch (const cms::Exception &e) {                                            \
0419       if (e.category() == "Not Implemented")                                       \
0420         cpputExceptionThrown_ = true;                                              \
0421     }                                                                              \
0422                                                                                    \
0423     if (cpputExceptionThrown_)                                                     \
0424       break;                                                                       \
0425                                                                                    \
0426     CPPUNIT_NS::Asserter::fail("Resolution " #RESOL " for Parametrization " #PARAM \
0427                                " Not implemented but not throwing",                \
0428                                CPPUNIT_SOURCELINE());                              \
0429   } while (false)
0430 
0431                                         using namespace pat::helper::ResolutionHelper;
0432 using pat::helper::ParametrizationHelper::dimension;
0433 
0434 void testKinResolutions::testTrivialMatrix_Cart() {
0435   ASSERT_DIAGONAL(Cart, getResolPx, 0);
0436   ASSERT_DIAGONAL(Cart, getResolPy, 1);
0437   ASSERT_DIAGONAL(Cart, getResolPz, 2);
0438   ASSERT_DIAGONAL(Cart, getResolM, 3);
0439   ASSERT_HAS_DERIVATIVE(Cart, getResolEta);
0440   ASSERT_HAS_DERIVATIVE(Cart, getResolTheta);
0441   ASSERT_HAS_DERIVATIVE(Cart, getResolPhi);
0442   ASSERT_HAS_DERIVATIVE(Cart, getResolEt);
0443   ASSERT_HAS_DERIVATIVE(Cart, getResolE);
0444   ASSERT_HAS_DERIVATIVE(Cart, getResolP);
0445   ASSERT_HAS_DERIVATIVE(Cart, getResolPt);
0446   ASSERT_HAS_DERIVATIVE(Cart, getResolPInv);
0447 }
0448 void testKinResolutions::testTrivialMatrix_ECart() {
0449   ASSERT_DIAGONAL(ECart, getResolPx, 0);
0450   ASSERT_DIAGONAL(ECart, getResolPy, 1);
0451   ASSERT_DIAGONAL(ECart, getResolPz, 2);
0452   ASSERT_DIAGONAL(ECart, getResolE, 3);
0453   ASSERT_HAS_DERIVATIVE(ECart, getResolEta);
0454   ASSERT_HAS_DERIVATIVE(ECart, getResolTheta);
0455   ASSERT_HAS_DERIVATIVE(ECart, getResolPhi);
0456   ASSERT_HAS_DERIVATIVE(ECart, getResolEt);
0457   ASSERT_HAS_DERIVATIVE(ECart, getResolM);
0458   ASSERT_HAS_DERIVATIVE(ECart, getResolP);
0459   ASSERT_HAS_DERIVATIVE(ECart, getResolPt);
0460   ASSERT_HAS_DERIVATIVE(ECart, getResolPInv);
0461 }
0462 
0463 void testKinResolutions::testTrivialMatrix_Spher() {
0464   ASSERT_DIAGONAL(Spher, getResolP, 0);
0465   ASSERT_DIAGONAL(Spher, getResolTheta, 1);
0466   ASSERT_DIAGONAL(Spher, getResolPhi, 2);
0467   ASSERT_DIAGONAL(Spher, getResolM, 3);
0468   ASSERT_HAS_DERIVATIVE(Spher, getResolEta);
0469   ASSERT_HAS_DERIVATIVE(Spher, getResolEt);
0470   ASSERT_HAS_DERIVATIVE(Spher, getResolE);
0471   ASSERT_HAS_DERIVATIVE(Spher, getResolPt);
0472   ASSERT_HAS_DERIVATIVE(Spher, getResolPInv);
0473   ASSERT_HAS_DERIVATIVE(Spher, getResolPx);
0474   ASSERT_HAS_DERIVATIVE(Spher, getResolPy);
0475   ASSERT_HAS_DERIVATIVE(Spher, getResolPz);
0476 }
0477 
0478 void testKinResolutions::testTrivialMatrix_ESpher() {
0479   ASSERT_DIAGONAL(ESpher, getResolP, 0);
0480   ASSERT_DIAGONAL(ESpher, getResolTheta, 1);
0481   ASSERT_DIAGONAL(ESpher, getResolPhi, 2);
0482   ASSERT_DIAGONAL(ESpher, getResolE, 3);
0483   ASSERT_HAS_DERIVATIVE(ESpher, getResolEta);
0484   ASSERT_HAS_DERIVATIVE(ESpher, getResolEt);
0485   ASSERT_HAS_DERIVATIVE(ESpher, getResolM);
0486   ASSERT_HAS_DERIVATIVE(ESpher, getResolPt);
0487   ASSERT_HAS_DERIVATIVE(ESpher, getResolPInv);
0488   ASSERT_HAS_DERIVATIVE(ESpher, getResolPx);
0489   ASSERT_HAS_DERIVATIVE(ESpher, getResolPy);
0490   ASSERT_HAS_DERIVATIVE(ESpher, getResolPz);
0491 }
0492 
0493 void testKinResolutions::testTrivialMatrix_MomDev() {
0494   ASSERT_NOT_IMPLEMENTED(MomDev, getResolEta);
0495   ASSERT_NOT_IMPLEMENTED(MomDev, getResolTheta);
0496   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPhi);
0497   ASSERT_NOT_IMPLEMENTED(MomDev, getResolEt);
0498   ASSERT_NOT_IMPLEMENTED(MomDev, getResolE);
0499   ASSERT_NOT_IMPLEMENTED(MomDev, getResolP);
0500   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPt);
0501   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPInv);
0502   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPx);
0503   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPy);
0504   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPz);
0505   ASSERT_NOT_IMPLEMENTED(MomDev, getResolM);
0506 }
0507 
0508 void testKinResolutions::testTrivialMatrix_EMomDev() {
0509   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolEta);
0510   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolTheta);
0511   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPhi);
0512   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolEt);
0513   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolE);
0514   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolP);
0515   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPt);
0516   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPInv);
0517   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPx);
0518   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPy);
0519   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPz);
0520   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolM);
0521 }
0522 
0523 void testKinResolutions::testTrivialMatrix_MCCart() {
0524   ASSERT_DIAGONAL(MCCart, getResolPx, 0);
0525   ASSERT_DIAGONAL(MCCart, getResolPy, 1);
0526   ASSERT_DIAGONAL(MCCart, getResolPz, 2);
0527   ASSERT_HAS_DERIVATIVE(MCCart, getResolEta);
0528   ASSERT_HAS_DERIVATIVE(MCCart, getResolTheta);
0529   ASSERT_HAS_DERIVATIVE(MCCart, getResolPhi);
0530   ASSERT_HAS_DERIVATIVE(MCCart, getResolEt);
0531   ASSERT_HAS_DERIVATIVE(MCCart, getResolE);
0532   ASSERT_HAS_DERIVATIVE(MCCart, getResolP);
0533   ASSERT_HAS_DERIVATIVE(MCCart, getResolPt);
0534   ASSERT_HAS_DERIVATIVE(MCCart, getResolPInv);
0535 }
0536 
0537 void testKinResolutions::testTrivialMatrix_MCSpher() {
0538   ASSERT_DIAGONAL(MCSpher, getResolP, 0);
0539   ASSERT_DIAGONAL(MCSpher, getResolTheta, 1);
0540   ASSERT_DIAGONAL(MCSpher, getResolPhi, 2);
0541   ASSERT_HAS_DERIVATIVE(MCSpher, getResolEta);
0542   ASSERT_HAS_DERIVATIVE(MCSpher, getResolEt);
0543   ASSERT_HAS_DERIVATIVE(MCSpher, getResolE);
0544   ASSERT_HAS_DERIVATIVE(MCSpher, getResolPt);
0545   ASSERT_HAS_DERIVATIVE(MCSpher, getResolPInv);
0546   ASSERT_HAS_DERIVATIVE(MCSpher, getResolPx);
0547   ASSERT_HAS_DERIVATIVE(MCSpher, getResolPy);
0548   ASSERT_HAS_DERIVATIVE(MCSpher, getResolPz);
0549 }
0550 
0551 void testKinResolutions::testTrivialMatrix_MCPInvSpher() {
0552   ASSERT_DIAGONAL(MCPInvSpher, getResolPInv, 0);
0553   ASSERT_DIAGONAL(MCPInvSpher, getResolTheta, 1);
0554   ASSERT_DIAGONAL(MCPInvSpher, getResolPhi, 2);
0555   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolEta);
0556   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolEt);
0557   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolE);
0558   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolP);
0559   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolPt);
0560   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolPx);
0561   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolPy);
0562   ASSERT_HAS_DERIVATIVE(MCPInvSpher, getResolPz);
0563 }
0564 
0565 void testKinResolutions::testTrivialMatrix_EtEtaPhi() {
0566   ASSERT_DIAGONAL(EtEtaPhi, getResolEt, 0);
0567   ASSERT_DIAGONAL(EtEtaPhi, getResolPt, 0);  // Et == Pt
0568   ASSERT_DIAGONAL(EtEtaPhi, getResolEta, 1);
0569   ASSERT_DIAGONAL(EtEtaPhi, getResolPhi, 2);
0570   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolTheta);
0571   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolE);
0572   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolP);
0573   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolPInv);
0574   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolPx);
0575   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolPy);
0576   ASSERT_HAS_DERIVATIVE(EtEtaPhi, getResolPz);
0577 }
0578 
0579 void testKinResolutions::testTrivialMatrix_EtThetaPhi() {
0580   ASSERT_DIAGONAL(EtThetaPhi, getResolEt, 0);
0581   ASSERT_DIAGONAL(EtThetaPhi, getResolPt, 0);  // Et == Pt
0582   ASSERT_DIAGONAL(EtThetaPhi, getResolTheta, 1);
0583   ASSERT_DIAGONAL(EtThetaPhi, getResolPhi, 2);
0584   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolEta);
0585   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolE);
0586   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolP);
0587   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolPInv);
0588   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolPx);
0589   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolPy);
0590   ASSERT_HAS_DERIVATIVE(EtThetaPhi, getResolPz);
0591 }
0592 
0593 void testKinResolutions::testTrivialMatrix_MCMomDev() {
0594   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolEta);
0595   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolTheta);
0596   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPhi);
0597   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolEt);
0598   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolE);
0599   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolP);
0600   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPt);
0601   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPInv);
0602   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPx);
0603   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPy);
0604   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPz);
0605 }
0606 
0607 void testKinResolutions::testTrivialMatrix_EScaledMomDev() {
0608   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolEta);
0609   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolTheta);
0610   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPhi);
0611   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolEt);
0612   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolE);
0613   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolP);
0614   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPt);
0615   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPInv);
0616   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPx);
0617   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPy);
0618   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPz);
0619   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolM);
0620 }
0621 
0622 void testKinResolutions::testIndependentVars_Cart() {
0623   ASSERT_FULLY_INDEPENDENT(Cart, getResolPx, 0);
0624   ASSERT_FULLY_INDEPENDENT(Cart, getResolPy, 1);
0625   ASSERT_FULLY_INDEPENDENT(Cart, getResolPz, 2);
0626   ASSERT_FULLY_INDEPENDENT(Cart, getResolM, 3);
0627   ASSERT_HAS_INDEP_DERIVATIVE(Cart, getResolEta, 3);    // Angles Don't
0628   ASSERT_HAS_INDEP_DERIVATIVE(Cart, getResolTheta, 3);  // depend on
0629   ASSERT_HAS_INDEP_DERIVATIVE(Cart, getResolPhi, 3);    // the mass
0630 }
0631 void testKinResolutions::testIndependentVars_ECart() {
0632   ASSERT_FULLY_INDEPENDENT(ECart, getResolPx, 0);
0633   ASSERT_FULLY_INDEPENDENT(ECart, getResolPy, 1);
0634   ASSERT_FULLY_INDEPENDENT(ECart, getResolPz, 2);
0635   ASSERT_FULLY_INDEPENDENT(ECart, getResolE, 3);
0636   ASSERT_HAS_INDEP_DERIVATIVE(ECart, getResolEta, 3);    // Angles
0637   ASSERT_HAS_INDEP_DERIVATIVE(ECart, getResolTheta, 3);  // Don't depend
0638   ASSERT_HAS_INDEP_DERIVATIVE(ECart, getResolPhi, 3);    // on the energy
0639 }
0640 
0641 void testKinResolutions::testIndependentVars_Spher() {
0642   ASSERT_FULLY_INDEPENDENT(Spher, getResolP, 0);
0643   ASSERT_FULLY_INDEPENDENT(Spher, getResolTheta, 1);
0644   ASSERT_FULLY_INDEPENDENT(Spher, getResolPhi, 2);
0645   ASSERT_FULLY_INDEPENDENT(Spher, getResolM, 3);
0646 
0647   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolEta, 0);  // Eta
0648   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolEta, 2);  // Depends
0649   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolEta, 3);  // Only On Theta
0650 
0651   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolEt, 2);  // E, Et
0652   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolE, 2);   // Don't depend on Phi
0653 
0654   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPt, 2);  // Pt indep from
0655   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPt, 3);  // Phi and M
0656 
0657   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPInv, 1);  // PInv dep
0658   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPInv, 2);  // Only on
0659   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPInv, 3);  // P
0660 
0661   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPx, 3);  // Px, Py, Pz
0662   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPy, 3);  // Indep from
0663   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPz, 3);  // Mass
0664   ASSERT_HAS_INDEP_DERIVATIVE(Spher, getResolPz, 3);  // Pz also on Phi
0665 }
0666 
0667 void testKinResolutions::testIndependentVars_ESpher() {
0668   ASSERT_FULLY_INDEPENDENT(ESpher, getResolP, 0);
0669   ASSERT_FULLY_INDEPENDENT(ESpher, getResolTheta, 1);
0670   ASSERT_FULLY_INDEPENDENT(ESpher, getResolPhi, 2);
0671   ASSERT_FULLY_INDEPENDENT(ESpher, getResolE, 3);
0672 
0673   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolEta, 0);  // Eta
0674   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolEta, 2);  // Depends
0675   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolEta, 3);  // Only On Theta
0676 
0677   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolEt, 2);  // Et indep from Phi
0678   //ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolEt,  2); // FIXME And from P??
0679 
0680   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolM, 2);  // Don't depend on Phi
0681   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolM, 1);  // Nor on Theta
0682 
0683   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPt, 2);  // Pt indep from
0684   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPt, 3);  // Phi and E
0685 
0686   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPInv, 1);  // PInv dep
0687   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPInv, 2);  // Only on
0688   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPInv, 3);  // P
0689 
0690   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPx, 3);  // Px, Py, Pz
0691   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPy, 3);  // Indep from
0692   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPz, 3);  // Energy
0693   ASSERT_HAS_INDEP_DERIVATIVE(ESpher, getResolPz, 3);  // Pz also on Phi
0694 }
0695 
0696 void testKinResolutions::testIndependentVars_MomDev() {
0697   ASSERT_NOT_IMPLEMENTED(MomDev, getResolEta);
0698   ASSERT_NOT_IMPLEMENTED(MomDev, getResolTheta);
0699   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPhi);
0700   ASSERT_NOT_IMPLEMENTED(MomDev, getResolEt);
0701   ASSERT_NOT_IMPLEMENTED(MomDev, getResolE);
0702   ASSERT_NOT_IMPLEMENTED(MomDev, getResolP);
0703   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPt);
0704   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPInv);
0705   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPx);
0706   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPy);
0707   ASSERT_NOT_IMPLEMENTED(MomDev, getResolPz);
0708   ASSERT_NOT_IMPLEMENTED(MomDev, getResolM);
0709 }
0710 
0711 void testKinResolutions::testIndependentVars_EMomDev() {
0712   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolEta);
0713   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolTheta);
0714   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPhi);
0715   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolEt);
0716   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolE);
0717   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolP);
0718   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPt);
0719   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPInv);
0720   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPx);
0721   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPy);
0722   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolPz);
0723   ASSERT_NOT_IMPLEMENTED(EMomDev, getResolM);
0724 }
0725 
0726 void testKinResolutions::testIndependentVars_MCCart() {
0727   ASSERT_FULLY_INDEPENDENT(MCCart, getResolPx, 0);
0728   ASSERT_FULLY_INDEPENDENT(MCCart, getResolPy, 1);
0729   ASSERT_FULLY_INDEPENDENT(MCCart, getResolPz, 2);
0730 
0731   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolPhi, 2);  // Phi doesn't depend on Pz
0732 
0733   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolEta, 3);    // nothing
0734   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolTheta, 3);  // depends
0735   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolPhi, 3);    // on M
0736   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolEt, 3);
0737   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolE, 3);
0738   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolP, 3);
0739   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolPt, 3);
0740   ASSERT_HAS_INDEP_DERIVATIVE(MCCart, getResolPInv, 3);
0741 }
0742 
0743 void testKinResolutions::testIndependentVars_MCSpher() {
0744   ASSERT_FULLY_INDEPENDENT(MCSpher, getResolP, 0);
0745   ASSERT_FULLY_INDEPENDENT(MCSpher, getResolTheta, 1);
0746   ASSERT_FULLY_INDEPENDENT(MCSpher, getResolPhi, 2);
0747 
0748   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEta, 3);  // everything
0749   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEt, 3);   // indep from
0750   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 3);    // mass
0751   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPt, 3);
0752   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPInv, 3);
0753   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPx, 3);
0754   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPy, 3);
0755   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPz, 3);
0756 
0757   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEta, 2);  // Most things
0758   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEt, 2);   // Indep from Phi
0759   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 2);
0760   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPt, 2);
0761   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPInv, 2);
0762   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPz, 2);
0763 
0764   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 1);     // E, 1/P
0765   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPInv, 1);  // dep only on P
0766 }
0767 
0768 void testKinResolutions::testIndependentVars_MCPInvSpher() {
0769   ASSERT_FULLY_INDEPENDENT(MCPInvSpher, getResolPInv, 0);
0770   ASSERT_FULLY_INDEPENDENT(MCPInvSpher, getResolTheta, 1);
0771   ASSERT_FULLY_INDEPENDENT(MCPInvSpher, getResolPhi, 2);
0772 
0773   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEta, 3);  // everything
0774   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEt, 3);   // indep from
0775   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 3);    // mass
0776   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPt, 3);
0777   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolP, 3);
0778   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPx, 3);
0779   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPy, 3);
0780   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPz, 3);
0781 
0782   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEta, 2);  // Most things
0783   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolEt, 2);   // Indep from Phi
0784   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 2);
0785   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPt, 2);
0786   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolP, 2);
0787   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolPz, 2);
0788 
0789   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolE, 1);  // E, P
0790   ASSERT_HAS_INDEP_DERIVATIVE(MCSpher, getResolP, 1);  // dep only on 1/P
0791 }
0792 
0793 void testKinResolutions::testIndependentVars_EtEtaPhi() {
0794   ASSERT_FULLY_INDEPENDENT(EtEtaPhi, getResolEt, 0);
0795   ASSERT_FULLY_INDEPENDENT(EtEtaPhi, getResolPt, 0);  // Et == Pt
0796   ASSERT_FULLY_INDEPENDENT(EtEtaPhi, getResolEta, 1);
0797   ASSERT_FULLY_INDEPENDENT(EtEtaPhi, getResolPhi, 2);
0798 
0799   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolTheta, 3);  // All indep
0800   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolE, 3);      // From the mass
0801   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolP, 3);      // (which is also
0802   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPInv, 3);   // always zero)
0803   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPx, 3);
0804   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPy, 3);
0805   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPz, 3);
0806 
0807   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolTheta, 2);  // Most things
0808   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolE, 2);      // Indep from
0809   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolP, 2);      // Phi
0810   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPInv, 2);
0811   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPz, 2);
0812 
0813   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPx, 1);  // Px, Py
0814   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPy, 1);  // Indep from Eta
0815 
0816   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolTheta, 0);  // Theta indep from Et
0817 }
0818 
0819 void testKinResolutions::testIndependentVars_EtThetaPhi() {
0820   ASSERT_FULLY_INDEPENDENT(EtThetaPhi, getResolEt, 0);
0821   ASSERT_FULLY_INDEPENDENT(EtThetaPhi, getResolPt, 0);  // Et == Pt
0822   ASSERT_FULLY_INDEPENDENT(EtThetaPhi, getResolTheta, 1);
0823   ASSERT_FULLY_INDEPENDENT(EtThetaPhi, getResolPhi, 2);
0824 
0825   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolEta, 3);   // All indep
0826   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolE, 3);     // From the mass
0827   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolP, 3);     // (which is also
0828   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPInv, 3);  // always zero)
0829   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPx, 3);
0830   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPy, 3);
0831   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPz, 3);
0832 
0833   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolEta, 2);  // Most things
0834   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolE, 2);    // Indep from
0835   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolP, 2);    // Phi
0836   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPInv, 2);
0837   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPz, 2);
0838 
0839   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPx, 1);  // Px, Py
0840   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolPy, 1);  // Indep from Theta
0841 
0842   ASSERT_HAS_INDEP_DERIVATIVE(EtEtaPhi, getResolEta, 0);  // Eta indep from Et
0843 }
0844 
0845 void testKinResolutions::testIndependentVars_MCMomDev() {
0846   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolEta);
0847   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolTheta);
0848   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPhi);
0849   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolEt);
0850   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolE);
0851   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolP);
0852   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPt);
0853   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPInv);
0854   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPx);
0855   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPy);
0856   ASSERT_NOT_IMPLEMENTED(MCMomDev, getResolPz);
0857 }
0858 
0859 void testKinResolutions::testIndependentVars_EScaledMomDev() {
0860   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolEta);
0861   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolTheta);
0862   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPhi);
0863   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolEt);
0864   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolE);
0865   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolP);
0866   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPt);
0867   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPInv);
0868   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPx);
0869   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPy);
0870   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolPz);
0871   ASSERT_NOT_IMPLEMENTED(EScaledMomDev, getResolM);
0872 }
0873 
0874 #define IMPL_testDependentVars(PAR)                    \
0875   void testKinResolutions::testDependentVars_##PAR() { \
0876     ASSERT_CHECK_DERIVATIVES(PAR, Eta)                 \
0877     ASSERT_CHECK_DERIVATIVES(PAR, Theta)               \
0878     ASSERT_CHECK_DERIVATIVES(PAR, Phi)                 \
0879     ASSERT_CHECK_DERIVATIVES(PAR, Et)                  \
0880     ASSERT_CHECK_DERIVATIVES(PAR, E)                   \
0881     ASSERT_CHECK_DERIVATIVES(PAR, P)                   \
0882     ASSERT_CHECK_DERIVATIVES(PAR, Pt)                  \
0883     ASSERT_CHECK_DERIVATIVES(PAR, PInv)                \
0884     ASSERT_CHECK_DERIVATIVES(PAR, Px)                  \
0885     ASSERT_CHECK_DERIVATIVES(PAR, Py)                  \
0886     ASSERT_CHECK_DERIVATIVES(PAR, Pz)                  \
0887     ASSERT_CHECK_DERIVATIVES(PAR, M)                   \
0888   }
0889 
0890 IMPL_testDependentVars(Cart) IMPL_testDependentVars(ECart) IMPL_testDependentVars(Spher) IMPL_testDependentVars(ESpher)
0891     IMPL_testDependentVars(MCCart) IMPL_testDependentVars(MCSpher) IMPL_testDependentVars(MCPInvSpher)
0892         IMPL_testDependentVars(EtEtaPhi) IMPL_testDependentVars(EtThetaPhi)
0893     //IMPL_testDependentVars(MomDev)
0894     //IMPL_testDependentVars(EMomDev)
0895     //IMPL_testDependentVars(MCMomDev)
0896     //IMPL_testDependentVars(EScaledMomDev)
0897     void testKinResolutions::testDependentVars_MomDev() {}
0898 void testKinResolutions::testDependentVars_EMomDev() {}
0899 void testKinResolutions::testDependentVars_MCMomDev() {}
0900 void testKinResolutions::testDependentVars_EScaledMomDev() {}