Skip to content

Commit 4a5a25e

Browse files
authored
Improve SimpleCut comparison (#140)
* add helper functions * add Cuts SetName(); get rid of not needed variadic Cuts constructor try * improve SimpleCut comparison (still not perfect; if possible to deal with rest?) * add tests for SimpleCut compare; fix test for particle mass by pdg * print files from filelist when creating chain * address std::ostringstream has incomplete type error
1 parent 75f4401 commit 4a5a25e

7 files changed

Lines changed: 94 additions & 22 deletions

File tree

core/Particle.test.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "Particle.hpp"
1010

11+
#include "TDatabasePDG.h"
12+
1113
namespace {
1214

1315
using namespace AnalysisTree;
@@ -28,7 +30,7 @@ TEST(Particle, Basics) {
2830
EXPECT_EQ(particle.GetSize<bool>(), 0);
2931

3032
EXPECT_EQ(particle.GetPid(), 211);
31-
EXPECT_FLOAT_EQ(particle.GetMass(), 0.13957);
33+
EXPECT_FLOAT_EQ(particle.GetMass(), TDatabasePDG::Instance()->GetParticle(211)->Mass());
3234
}
3335
}// namespace
3436

infra/Chain.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void Chain::InitChain() {
3737

3838
TFileCollection fc("fc", "", filelists_[0].c_str());
3939
this->AddFileInfoList(reinterpret_cast<TCollection*>(fc.GetList()));
40+
this->ls();
4041

4142
std::vector<std::string> aliases;
4243
aliases.reserve(treenames_.size());

infra/Cuts.hpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,6 @@ class Cuts {
5252

5353
void AddCuts(const std::vector<SimpleCut>& cuts);
5454

55-
// // Base case for variadic recursion (handles when there's just one argument left)
56-
// template<typename T>
57-
// void AddCuts(const T& t) {
58-
// AddCuts(t); // Call the appropriate overload for a single argument (like std::vector<SimpleCut>)
59-
// }
60-
//
61-
// // Recursive case for variadic template (multiple arguments)
62-
// template<typename T, typename... Args>
63-
// void AddCuts(const T& t, const Args&... args) {
64-
// AddCuts(t);
65-
// AddCuts(args...);
66-
// }
67-
//
68-
// template<typename... Args> // TODO this constructor hangs. Needs debugging
69-
// Cuts(std::string name, Args... args) : name_(std::move(name)) {
70-
// AddCuts(args...);
71-
// }
72-
7355
/**
7456
* @brief Evaluates all SimpleCuts
7557
* @tparam T type of data-object associated with TTree
@@ -107,6 +89,8 @@ class Cuts {
10789
ANALYSISTREE_ATTR_NODISCARD std::set<size_t> GetBranchIds() const { return branch_ids_; }
10890
ANALYSISTREE_ATTR_NODISCARD const std::string& GetName() const { return name_; }
10991

92+
void SetName(const std::string& name) { name_ = name; }
93+
11094
std::vector<SimpleCut>& GetCuts() { return cuts_; }
11195

11296
friend bool operator==(const Cuts& that, const Cuts& other);

infra/HelperFunctions.hpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "SimpleCut.hpp"
55

6+
#include <sstream>
67
#include <string>
78
#include <vector>
89

@@ -16,15 +17,38 @@ inline std::string ToStringWithPrecision(const T a_value, const int n) {
1617
return out.str();
1718
}
1819

19-
inline std::vector<AnalysisTree::SimpleCut> CreateSliceCuts(const std::vector<float>& ranges, const std::string& cutNamePrefix, const std::string& branchFieldName) {
20+
template<typename T>
21+
inline std::string ToStringWithSignificantFigures(const T a_value, const int n) {
22+
if(a_value == 0) return "0";
23+
24+
const double dMag = std::log10(std::abs(a_value)); // scale of the a_value (e.g 1.* for 1.2345, 2.* for 12.345 etc)
25+
const int iMag = static_cast<int>(dMag-n+1 > 0 ? dMag-n+1 : dMag-n);
26+
const T shifted_value = a_value/std::pow(10, iMag); // shift decimal point to have all required digits to l.h.s. from it
27+
const T rounded_value = static_cast<T>(std::round(shifted_value)); // get rid of r.h.s. from decimal point
28+
const T reshifted_value = rounded_value*std::pow(10, iMag); // return decimal point to its original place
29+
const int precision = iMag < 0 ? -iMag : 0; // determine how many digits after decimal point one needs
30+
return ToStringWithPrecision(reshifted_value, precision);
31+
}
32+
33+
inline std::vector<AnalysisTree::SimpleCut> CreateRangeCuts(const std::vector<float>& ranges, const std::string& cutNamePrefix, const std::string& branchFieldName, int precision=2) {
2034
std::vector<AnalysisTree::SimpleCut> sliceCuts;
2135
for (int iRange = 0; iRange < ranges.size() - 1; iRange++) {
22-
const std::string cutName = cutNamePrefix + ToStringWithPrecision(ranges.at(iRange), 2) + "_" + ToStringWithPrecision(ranges.at(iRange + 1), 2);
36+
const std::string cutName = cutNamePrefix + ToStringWithPrecision(ranges.at(iRange), 2) + "_" + ToStringWithPrecision(ranges.at(iRange + 1), precision);
2337
sliceCuts.emplace_back(AnalysisTree::RangeCut(branchFieldName, ranges.at(iRange), ranges.at(iRange + 1), cutName));
2438
}
2539

2640
return sliceCuts;
2741
}
2842

43+
inline std::vector<AnalysisTree::SimpleCut> CreateEqualCuts(const std::vector<float>& values, const std::string& cutNamePrefix, const std::string& branchFieldName, int precision=2) {
44+
std::vector<AnalysisTree::SimpleCut> sliceCuts;
45+
for (int iValue = 0; iValue < values.size(); iValue++) {
46+
const std::string cutName = cutNamePrefix + ToStringWithPrecision(values.at(iValue), precision);
47+
sliceCuts.emplace_back(AnalysisTree::EqualsCut(branchFieldName, values.at(iValue), cutName));
48+
}
49+
50+
return sliceCuts;
51+
}
52+
2953
}// namespace HelperFunctions
3054
#endif// ANALYSISTREE_INFRA_HELPER_FUNCTIONS_HPP

infra/SimpleCut.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Authors: Viktor Klochkov, Ilya Selyuzhenkov */
44
#include "SimpleCut.hpp"
55

6+
#include "HelperFunctions.hpp"
7+
68
#include <iostream>
79

810
namespace AnalysisTree {
@@ -22,7 +24,9 @@ bool operator==(const SimpleCut& that, const SimpleCut& other) {
2224
if (&that == &other) {
2325
return true;
2426
}
25-
return that.vars_ == other.vars_ && that.title_ == other.title_;
27+
// if both SimpleCuts were defined via lambda, they're assumed not equal (unless they're in the same memory place)
28+
if(that.hash_ == 1 && other.hash_ == 1) return false;
29+
return that.vars_ == other.vars_ && that.title_ == other.title_ && that.hash_ == other.hash_;
2630
}
2731

2832
SimpleCut RangeCut(const std::string& variable_name, double lo, double hi, const std::string& title) {
@@ -45,12 +49,18 @@ SimpleCut::SimpleCut(const Variable& var, int value, std::string title) : title_
4549
vars_.emplace_back(var);
4650
lambda_ = [value](std::vector<double>& vars) { return vars[0] <= value + SmallNumber && vars[0] >= value - SmallNumber; };
4751
FillBranchNames();
52+
const std::string stringForHash = var.GetName() + HelperFunctions::ToStringWithPrecision(value, 6) + title_;
53+
std::hash<std::string> hasher;
54+
hash_ = hasher(stringForHash);
4855
}
4956

5057
SimpleCut::SimpleCut(const Variable& var, double min, double max, std::string title) : title_(std::move(title)) {
5158
vars_.emplace_back(var);
5259
lambda_ = [max, min](std::vector<double>& vars) { return vars[0] <= max && vars[0] >= min; };
5360
FillBranchNames();
61+
const std::string stringForHash = var.GetName() + HelperFunctions::ToStringWithPrecision(min, 6) + HelperFunctions::ToStringWithPrecision(max, 6) + title_;
62+
std::hash<std::string> hasher;
63+
hash_ = hasher(stringForHash);
5464
}
5565

5666
bool SimpleCut::Apply(std::vector<const BranchChannel*>& bch, std::vector<size_t>& id) const {

infra/SimpleCut.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class SimpleCut {
4141
[](const std::string& arg_name) { return Variable::FromString(arg_name); });
4242

4343
FillBranchNames();
44+
hash_ = 1; // Impossible to calculate for lambda_
4445
}
4546

4647
SimpleCut(const std::vector<Variable>& vars, std::function<bool(std::vector<double>&)> lambda, std::string title = "") : title_(std::move(title)),
@@ -49,6 +50,7 @@ class SimpleCut {
4950
vars_.emplace_back(var);
5051
}
5152
FillBranchNames();
53+
hash_ = 1; // Impossible to calculate for lambda_
5254
}
5355

5456
/**
@@ -121,6 +123,7 @@ class SimpleCut {
121123
std::vector<Variable> vars_{};
122124
std::set<std::string> branch_names_{};
123125
std::function<bool(std::vector<double>&)> lambda_;///< function used to evaluate the cut.
126+
size_t hash_;
124127

125128
ClassDef(SimpleCut, 1);
126129
};

infra/SimpleCut.test.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,58 @@
77
#include "SimpleCut.hpp"
88
#include <gtest/gtest.h>
99

10+
#include <vector>
11+
1012
namespace {
1113

1214
using namespace AnalysisTree;
1315

16+
TEST(SimpleCut, Basics) {
17+
SimpleCut ecut1 = EqualsCut(Variable::FromString("BranchName.FieldName"), 1);
18+
SimpleCut ecut1same = EqualsCut(Variable::FromString("BranchName.FieldName"), 1);
19+
SimpleCut ecut2 = EqualsCut(Variable::FromString("BranchName.FieldName"), 2);
20+
SimpleCut ecut3 = EqualsCut(Variable::FromString("BranchName3.FieldName3"), 1);
21+
SimpleCut ecut1copy = ecut1;
22+
SimpleCut& ecut1ref = ecut1;
23+
24+
EXPECT_TRUE(ecut1 == ecut1);
25+
EXPECT_TRUE(ecut1 == ecut1same);
26+
EXPECT_TRUE(ecut1 == ecut1copy);
27+
EXPECT_TRUE(ecut1 == ecut1ref);
28+
EXPECT_FALSE(ecut1 == ecut2);
29+
EXPECT_FALSE(ecut1 == ecut3);
30+
EXPECT_FALSE(ecut2 == ecut3);
31+
32+
SimpleCut rcut1 = RangeCut(Variable::FromString("BranchName.FieldName"), 1, 2);
33+
SimpleCut rcut1same = RangeCut(Variable::FromString("BranchName.FieldName"), 1, 2);
34+
SimpleCut rcut2 = RangeCut(Variable::FromString("BranchName.FieldName"), 2, 5);
35+
SimpleCut rcut3 = RangeCut(Variable::FromString("BranchName3.FieldName3"), 1, 2);
36+
SimpleCut rcut1copy = rcut1;
37+
SimpleCut& rcut1ref = rcut1;
38+
39+
EXPECT_TRUE(rcut1 == rcut1);
40+
EXPECT_TRUE(rcut1 == rcut1same);
41+
EXPECT_TRUE(rcut1 == rcut1copy);
42+
EXPECT_TRUE(rcut1 == rcut1ref);
43+
EXPECT_FALSE(rcut1 == rcut2);
44+
EXPECT_FALSE(rcut1 == rcut3);
45+
EXPECT_FALSE(rcut2 == rcut3);
46+
47+
SimpleCut lcut1 = SimpleCut((std::vector<std::string>){"B1.f1", "B2.f2", "B3.f3"}, [](std::vector<double> par){ return par[0]/par[1]*par[2] < 10; });
48+
SimpleCut lcut1same = SimpleCut((std::vector<std::string>){"B1.f1", "B2.f2", "B3.f3"}, [](std::vector<double> par){ return par[0]/par[1]*par[2] < 10; });
49+
SimpleCut lcut2 = SimpleCut((std::vector<std::string>){"B11.f11", "B22.f22", "B33.f33"}, [](std::vector<double> par){ return par[0]/par[1]*par[2] < 5; });
50+
SimpleCut lcut1copy = lcut1;
51+
SimpleCut& lcut1ref = lcut1;
52+
53+
EXPECT_TRUE(lcut1 == lcut1);
54+
EXPECT_FALSE(lcut1 == lcut1same); // it should not be like that, but this is a concession
55+
EXPECT_FALSE(lcut1 == lcut1copy); // it should not be like that, but this is a concession
56+
EXPECT_TRUE(lcut1 == lcut1ref);
57+
EXPECT_FALSE(lcut1 == lcut2);
58+
EXPECT_FALSE(lcut1 == ecut1);
59+
EXPECT_FALSE(lcut1 == rcut1);
60+
}
61+
1462
}
1563

1664
#endif//ANALYSISTREE_INFRA_SIMPLECUT_TEST_HPP_

0 commit comments

Comments
 (0)