File indexing completed on 2023-03-17 10:45:44
0001 #include <cppunit/extensions/HelperMacros.h>
0002 #include "CommonTools/Utils/interface/expressionParser.h"
0003 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0004 #include "DataFormats/TrackReco/interface/Track.h"
0005 #include "DataFormats/TrackReco/interface/TrackExtra.h"
0006 #include "DataFormats/Candidate/interface/CompositeCandidate.h"
0007 #include "DataFormats/Candidate/interface/LeafCandidate.h"
0008 #include "DataFormats/PatCandidates/interface/Jet.h"
0009 #include "DataFormats/PatCandidates/interface/Muon.h"
0010 #include "CommonTools/Utils/interface/StringToEnumValue.h"
0011
0012 #include <iostream>
0013 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0014 #include "FWCore/Reflection/interface/TypeWithDict.h"
0015 #include <typeinfo>
0016 #include "DataFormats/Common/interface/TestHandle.h"
0017
0018 class testExpressionParser : public CppUnit::TestFixture {
0019 CPPUNIT_TEST_SUITE(testExpressionParser);
0020 CPPUNIT_TEST(testStringToEnum);
0021 CPPUNIT_TEST(checkAll);
0022 CPPUNIT_TEST_SUITE_END();
0023
0024 public:
0025 void setUp() {}
0026 void tearDown() {}
0027 void checkAll();
0028 void testStringToEnum();
0029 void checkTrack(const std::string &, double);
0030 void checkCandidate(const std::string &, double, bool lazy = false);
0031 void checkJet(const std::string &, double);
0032 void checkMuon(const std::string &, double);
0033 reco::Track trk;
0034 reco::CompositeCandidate cand;
0035 edm::ObjectWithDict o;
0036 reco::parser::ExpressionPtr expr;
0037 pat::Jet jet;
0038 pat::Muon muon;
0039 };
0040
0041 CPPUNIT_TEST_SUITE_REGISTRATION(testExpressionParser);
0042
0043 void testExpressionParser::checkTrack(const std::string &expression, double x) {
0044 for (int lazyMode = 0; lazyMode <= 1; ++lazyMode) {
0045 std::cerr << "checking " << (lazyMode ? "lazy " : "") << "expression: \"" << expression << "\"" << std::flush;
0046 expr.reset();
0047 CPPUNIT_ASSERT(reco::parser::expressionParser<reco::Track>(expression, expr, lazyMode));
0048 CPPUNIT_ASSERT(expr.get() != 0);
0049 double res = expr->value(o);
0050 StringObjectFunction<reco::Track> f(expression, lazyMode);
0051 CPPUNIT_ASSERT(fabs(f(trk) - res) < 1.e-6);
0052 CPPUNIT_ASSERT(fabs(f(trk) - x) < 1.e-6);
0053 std::cerr << " = " << res << std::endl;
0054 }
0055 }
0056
0057 void testExpressionParser::checkCandidate(const std::string &expression, double x, bool lazyMode) {
0058 std::cerr << "checking " << (lazyMode ? "lazy " : "") << "expression: \"" << expression << "\"" << std::flush;
0059 expr.reset();
0060 CPPUNIT_ASSERT(reco::parser::expressionParser<reco::Candidate>(expression, expr, lazyMode));
0061 CPPUNIT_ASSERT(expr.get() != 0);
0062 double res = 0;
0063 CPPUNIT_ASSERT_NO_THROW(res = expr->value(o));
0064 StringObjectFunction<reco::Candidate> f(expression, lazyMode);
0065 CPPUNIT_ASSERT(fabs(f(cand) - res) < 1.e-6);
0066 CPPUNIT_ASSERT(fabs(f(cand) - x) < 1.e-6);
0067 std::cerr << " = " << res << std::endl;
0068 }
0069
0070 void testExpressionParser::checkJet(const std::string &expression, double x) {
0071 for (int lazyMode = 0; lazyMode <= 1; ++lazyMode) {
0072 std::cerr << "checking " << (lazyMode ? "lazy " : "") << "expression: \"" << expression << "\"" << std::flush;
0073 expr.reset();
0074 CPPUNIT_ASSERT(reco::parser::expressionParser<pat::Jet>(expression, expr, lazyMode));
0075 CPPUNIT_ASSERT(expr.get() != 0);
0076 double res = expr->value(o);
0077 StringObjectFunction<pat::Jet> f(expression, lazyMode);
0078 CPPUNIT_ASSERT(fabs(f(jet) - res) < 1.e-6);
0079 CPPUNIT_ASSERT(fabs(f(jet) - x) < 1.e-6);
0080 std::cerr << " = " << res << std::endl;
0081 }
0082 }
0083
0084 void testExpressionParser::checkMuon(const std::string &expression, double x) {
0085 for (int lazyMode = 0; lazyMode <= 1; ++lazyMode) {
0086 std::cerr << "checking " << (lazyMode ? "lazy " : "") << "expression: \"" << expression << "\"" << std::flush;
0087 expr.reset();
0088 CPPUNIT_ASSERT(reco::parser::expressionParser<pat::Muon>(expression, expr, lazyMode));
0089 CPPUNIT_ASSERT(expr.get() != 0);
0090 double res = expr->value(o);
0091 StringObjectFunction<pat::Muon> f(expression, lazyMode);
0092 std::cerr << " = " << x << " (reference), " << res << " (bare), " << f(muon) << " (full)" << std::endl;
0093 CPPUNIT_ASSERT(fabs(f(muon) - res) < 1.e-6);
0094 CPPUNIT_ASSERT(fabs(f(muon) - x) < 1.e-6);
0095 }
0096 }
0097
0098 void testExpressionParser::testStringToEnum() {
0099 std::cout << "Testing reco::Muon::ArbitrationType SegmentArbitration" << std::endl;
0100 CPPUNIT_ASSERT_EQUAL(StringToEnumValue<reco::Muon::ArbitrationType>("SegmentArbitration"),
0101 int(reco::Muon::SegmentArbitration));
0102 std::cout << "Testing reco::TrackBase::TrackQuality (tight, highPurity)" << std::endl;
0103 std::vector<std::string> algos;
0104 algos.push_back("tight");
0105 algos.push_back("highPurity");
0106 std::vector<int> algoValues = StringToEnumValue<reco::TrackBase::TrackQuality>(algos);
0107 CPPUNIT_ASSERT(algoValues.size() == 2);
0108 CPPUNIT_ASSERT_EQUAL(algoValues[0], int(reco::TrackBase::tight));
0109 CPPUNIT_ASSERT_EQUAL(algoValues[1], int(reco::TrackBase::highPurity));
0110 }
0111
0112 void testExpressionParser::checkAll() {
0113 using namespace reco;
0114 const double chi2 = 20.0;
0115 const int ndof = 10;
0116 reco::Track::Point v(1, 2, 3);
0117 reco::Track::Vector p(5, 3, 10);
0118 double e[] = {1.1, 1.2, 2.2, 1.3, 2.3, 3.3, 1.4, 2.4, 3.4, 4.4, 1.5, 2.5, 3.5, 4.5, 5.5};
0119 reco::TrackBase::CovarianceMatrix cov(e, e + 15);
0120 cov(0, 0) = 1.2345;
0121 cov(1, 0) = 123.456;
0122 cov(1, 1) = 5.4321;
0123 trk = reco::Track(chi2, ndof, v, p, -1, cov);
0124
0125 edm::ProductID const pid(1);
0126 reco::TrackExtraCollection trkExtras;
0127 reco::Track::Point outerV(100, 200, 300), innerV(v);
0128 reco::Track::Vector outerP(0.5, 3.5, 10.5), innerP(p);
0129 reco::Track::CovarianceMatrix outerC, innerC;
0130 unsigned int outerId = 123, innerId = 456;
0131 reco::TrackExtra trkExtra(outerV, outerP, true, innerV, innerP, true, outerC, outerId, innerC, innerId, anyDirection);
0132 trkExtras.push_back(trkExtra);
0133 edm::TestHandle<reco::TrackExtraCollection> h(&trkExtras, pid);
0134 reco::TrackExtraRef trkExtraRef(h, 0);
0135 trk.setExtra(trkExtraRef);
0136 trk.setAlgorithm(reco::Track::pixelPairStep);
0137 {
0138 edm::TypeWithDict t(typeid(reco::Track));
0139 o = edm::ObjectWithDict(t, &trk);
0140 checkTrack("pt", trk.pt());
0141 checkTrack("charge", trk.charge());
0142 checkTrack("pt/3", trk.pt() / 3);
0143 checkTrack("covariance(0, 0)", trk.covariance(0, 0));
0144 checkTrack("covariance(1, 0)", trk.covariance(1, 0));
0145 checkTrack("covariance(1, 1)", trk.covariance(1, 1));
0146 checkTrack("momentum.x", trk.momentum().x());
0147 checkTrack("hitPattern.numberOfValidHits", trk.hitPattern().numberOfValidHits());
0148 checkTrack("extra.outerPhi", trk.extra()->outerPhi());
0149 checkTrack("referencePoint.R", trk.referencePoint().R());
0150 checkTrack("algo", reco::Track::pixelPairStep);
0151 checkTrack("quality('highPurity')", trk.quality(reco::TrackBase::highPurity));
0152 checkTrack("cosh(theta)", cosh(trk.theta()));
0153 checkTrack("hypot(px, py)", hypot(trk.px(), trk.py()));
0154 checkTrack("?ndof<0?1:0", trk.ndof() < 0 ? 1 : 0);
0155 checkTrack("?ndof=10?1:0", trk.ndof() == 10 ? 1 : 0);
0156 }
0157 reco::Candidate::LorentzVector p1(1, 2, 3, 4);
0158 reco::Candidate::LorentzVector p2(1.1, -2.5, 4.3, 13.7);
0159 reco::LeafCandidate c1(+1, p1);
0160 reco::LeafCandidate c2(-1, p2);
0161 cand.addDaughter(c1);
0162 cand.addDaughter(c2);
0163 CPPUNIT_ASSERT(cand.numberOfDaughters() == 2);
0164 CPPUNIT_ASSERT(cand.daughter(0) != 0);
0165 CPPUNIT_ASSERT(cand.daughter(1) != 0);
0166 {
0167 edm::TypeWithDict t(typeid(reco::Candidate));
0168 o = edm::ObjectWithDict(t, &cand);
0169
0170 for (int lazyMode = 0; lazyMode <= 1; ++lazyMode) {
0171 checkCandidate("numberOfDaughters", cand.numberOfDaughters(), lazyMode);
0172 checkCandidate("daughter(0).isStandAloneMuon", cand.daughter(0)->isStandAloneMuon(), lazyMode);
0173 checkCandidate("daughter(1).isStandAloneMuon", cand.daughter(1)->isStandAloneMuon(), lazyMode);
0174 checkCandidate("daughter(0).pt", cand.daughter(0)->pt(), lazyMode);
0175 checkCandidate("daughter(1).pt", cand.daughter(1)->pt(), lazyMode);
0176 checkCandidate(
0177 "min(daughter(0).pt, daughter(1).pt)", std::min(cand.daughter(0)->pt(), cand.daughter(1)->pt()), lazyMode);
0178 checkCandidate(
0179 "max(daughter(0).pt, daughter(1).pt)", std::max(cand.daughter(0)->pt(), cand.daughter(1)->pt()), lazyMode);
0180 checkCandidate("deltaPhi(daughter(0).phi, daughter(1).phi)",
0181 reco::deltaPhi(cand.daughter(0)->phi(), cand.daughter(1)->phi()));
0182
0183 checkCandidate("deltaPhi(daughter(1).phi, daughter(0).phi)",
0184 reco::deltaPhi(cand.daughter(1)->phi(), cand.daughter(0)->phi()));
0185 checkCandidate("deltaR(daughter(0).eta, daughter(0).phi, daughter(1).eta, daughter(1).phi)",
0186 reco::deltaR(*cand.daughter(0), *cand.daughter(1)));
0187 }
0188
0189 checkCandidate("name.empty()", true, true);
0190 checkCandidate("roles.size()", 0, true);
0191 }
0192
0193 std::vector<reco::LeafCandidate> cands;
0194 cands.push_back(c1);
0195 cands.push_back(c2);
0196 edm::TestHandle<std::vector<reco::LeafCandidate> > constituentsHandle(&cands, edm::ProductID(42));
0197 reco::Jet::Constituents constituents;
0198 constituents.push_back(reco::Jet::Constituent(constituentsHandle, 0));
0199 constituents.push_back(reco::Jet::Constituent(constituentsHandle, 1));
0200 reco::CaloJet::Specific caloSpecific;
0201 caloSpecific.mMaxEInEmTowers = 0.5;
0202 jet = pat::Jet(reco::CaloJet(p1 + p2, reco::Jet::Point(), caloSpecific, constituents));
0203 CPPUNIT_ASSERT(jet.nConstituents() == 2);
0204 CPPUNIT_ASSERT(jet.nCarrying(1.0) == 2);
0205 CPPUNIT_ASSERT(jet.nCarrying(0.1) == 1);
0206 {
0207 edm::TypeWithDict t(typeid(pat::Jet));
0208 o = edm::ObjectWithDict(t, &jet);
0209 checkJet("nCarrying(1.0)", jet.nCarrying(1.0));
0210 checkJet("nCarrying(0.1)", jet.nCarrying(0.1));
0211 }
0212 {
0213
0214 CPPUNIT_ASSERT(jet.maxEInEmTowers() == 0.5);
0215 checkJet("maxEInEmTowers", jet.maxEInEmTowers());
0216 }
0217
0218 std::pair<std::string, float> bp;
0219 bp = std::pair<std::string, float>("aaa", 1.0);
0220 jet.addBDiscriminatorPair(bp);
0221 bp = std::pair<std::string, float>("b c", 2.0);
0222 jet.addBDiscriminatorPair(bp);
0223 bp = std::pair<std::string, float>("d ", 3.0);
0224 jet.addBDiscriminatorPair(bp);
0225 CPPUNIT_ASSERT(jet.bDiscriminator("aaa") == 1.0);
0226 CPPUNIT_ASSERT(jet.bDiscriminator("b c") == 2.0);
0227 CPPUNIT_ASSERT(jet.bDiscriminator("d ") == 3.0);
0228 CPPUNIT_ASSERT(jet.getPairDiscri().size() == 3);
0229 {
0230 edm::TypeWithDict t(typeid(pat::Jet));
0231 o = edm::ObjectWithDict(t, &jet);
0232 checkJet("bDiscriminator(\"aaa\")", jet.bDiscriminator("aaa"));
0233 checkJet("bDiscriminator('aaa')", jet.bDiscriminator("aaa"));
0234 checkJet("bDiscriminator(\"b c\")", jet.bDiscriminator("b c"));
0235 checkJet("bDiscriminator(\"d \")", jet.bDiscriminator("d "));
0236 }
0237
0238 muon = pat::Muon(reco::Muon(+1, p1 + p2));
0239 muon.setUserIso(2.0);
0240 muon.setUserIso(42.0, 1);
0241 CPPUNIT_ASSERT(muon.userIso() == 2.0);
0242 CPPUNIT_ASSERT(muon.userIso(0) == 2.0);
0243 CPPUNIT_ASSERT(muon.userIso(1) == 42.0);
0244 reco::IsoDeposit dep;
0245 dep.addCandEnergy(2.0);
0246 CPPUNIT_ASSERT(dep.candEnergy() == 2.0);
0247 muon.setIsoDeposit(pat::TrackIso, dep);
0248 CPPUNIT_ASSERT(muon.trackIsoDeposit() != 0);
0249 CPPUNIT_ASSERT(muon.trackIsoDeposit()->candEnergy() == 2.0);
0250 pat::TriggerObjectStandAlone tosa;
0251 tosa.addPathName("HLT_Something");
0252 muon.addTriggerObjectMatch(tosa);
0253 {
0254 edm::TypeWithDict t(typeid(pat::Muon));
0255 o = edm::ObjectWithDict(t, &muon);
0256 checkMuon("userIso", muon.userIso());
0257 checkMuon("userIso()", muon.userIso());
0258 checkMuon("userIso(0)", muon.userIso(0));
0259 checkMuon("userIso(1)", muon.userIso(1));
0260 checkMuon("trackIsoDeposit.candEnergy", muon.trackIsoDeposit()->candEnergy());
0261
0262 checkMuon("triggerObjectMatchesByPath('HLT_Something').size()", 1);
0263 for (int b = 0; b <= 1; ++b) {
0264 std::cout << "Check for leaks in the " << (b ? "Lazy" : "standard") << " string parser" << std::endl;
0265 expr.reset();
0266 reco::parser::expressionParser<pat::Muon>("triggerObjectMatchesByPath('HLT_Something').size()", expr, b);
0267 expr->value(o);
0268 }
0269 }
0270 reco::CandidatePtrVector ptrOverlaps;
0271 ptrOverlaps.push_back(reco::CandidatePtr(constituentsHandle, 0));
0272 muon.setOverlaps("test", ptrOverlaps);
0273 CPPUNIT_ASSERT(muon.hasOverlaps("test"));
0274 CPPUNIT_ASSERT(muon.overlaps("test").size() == 1);
0275 CPPUNIT_ASSERT(muon.overlaps("test")[0]->pt() == c1.pt());
0276 {
0277 edm::TypeWithDict t(typeid(pat::Muon));
0278 o = edm::ObjectWithDict(t, &muon);
0279 checkMuon("overlaps('test')[0].pt", muon.overlaps("test")[0]->pt());
0280 }
0281 }