Skip to content

Commit 64e1075

Browse files
committed
Merge pull request #625 from ajgilbert/ch-april
Planned developments for CombineHarvester (April)
2 parents a7e0452 + 995b5fc commit 64e1075

28 files changed

+729
-169
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
SUBDIRS :=
22
LIB_DEPS := CombineTools
3-
LIB_EXTRA := -lHiggsAnalysisCombinedLimit
3+
LIB_EXTRA := -L$(CMSSW_BASE)/lib/$(SCRAM_ARCH) -lHiggsAnalysisCombinedLimit
44
DICTIONARY :=

CombineHarvester/CombinePdfs/src/MorphFunctions.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void BuildRooMorphing(RooWorkspace& ws, CombineHarvester& cb,
3838
CombineHarvester cb_bp =
3939
std::move(cb.cp().bin({bin}).process({process}));
4040

41-
vector<string> masses_all = Set2Vec(cb_bp.GenerateSetFromProcs<string>(
41+
vector<string> masses_all = Set2Vec(cb_bp.SetFromProcs(
4242
std::mem_fn(&ch::Process::mass)));
4343

4444
std::sort(masses_all.begin(), masses_all.end(),

CombineHarvester/CombinePdfs/test/ParametricMSSM.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ int main() {
107107
std::cout << " done\n";
108108

109109
// cb.era({"8TeV"}).bin_id({8});
110-
set<string> lm_bins =
111-
cb.GenerateSetFromObs<string>(mem_fn(&ch::Observation::bin));
110+
set<string> lm_bins = cb.SetFromObs(mem_fn(&ch::Observation::bin));
112111

113112
if (create_asimov) {
114113
for (auto const& b : lm_bins) {
@@ -140,11 +139,7 @@ int main() {
140139
in->set_bin(in->bin() + "_hm");
141140
});
142141

143-
set<string> hm_bins =
144-
cb_hm.GenerateSetFromObs<string>(mem_fn(&ch::Observation::bin));
145-
146-
147-
142+
set<string> hm_bins = cb_hm.SetFromObs(mem_fn(&ch::Observation::bin));
148143

149144
cb.cp().bin_id({8}).VariableRebin(
150145
{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
SUBDIRS :=
22
LIB_DEPS :=
33
LIB_EXTRA := -lboost_python -L$(shell scramv1 tool tag python LIBDIR) -l$(shell scramv1 tool tag python LIB) -lPyROOT
4+
5+
$(d)/interface/GitVersion.h: $(TOP)/../.git/logs/HEAD
6+
@echo -e "Updating $@"
7+
@echo -e "namespace ch { inline std::string GitVersion() { return \""$(shell git describe --dirty)"\"; } }\n" > $@
8+
9+
clean_$(d)/interface/GitVersion.h :
10+
rm -f $(subst clean_,,$@)
11+
12+
clean_$(d) : clean_$(d)/interface/GitVersion.h
13+
14+
dir_$(d) : | $(d)/interface/GitVersion.h
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GitVersion.h
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#ifndef CombineTools_CardWriter_h
2+
#define CombineTools_CardWriter_h
3+
#include <string>
4+
#include <map>
5+
#include <vector>
6+
#include <set>
7+
#include "CombineTools/interface/CombineHarvester.h"
8+
#include "CombineTools/interface/Object.h"
9+
10+
namespace ch {
11+
12+
/**
13+
* Automates the writing of datacards into directory structures
14+
*
15+
* A CardWriter is constructed with two strings which give patterns for where
16+
* the datacard text and ROOT files should be located and how they should be
17+
* named. These patterns can contain placeholders for the object metadata,
18+
* e.g.:
19+
*
20+
* ch::CardWriter writer(
21+
* "$TAG/$MASS/$ANALYSIS_$CHANNEL_$BINID_$ERA.txt",
22+
* "$TAG/common/$ANALYSIS_$CHANNEL.input_$ERA.root");
23+
*
24+
* All of the standard metadata placeholders are supported. Then, assuming a
25+
* CombineHarvester instance `cb` has already been configured, the cards are
26+
* written with:
27+
*
28+
* writer.WriteCards("LIMITS/cmb", cb);
29+
*
30+
* The CardWriter will determine the sets of root files and datacards to
31+
* create given the metadata of the objects in `cb`. The first argument of
32+
* `WriteCards` is substituted into the `$TAG` placeholder. In this way
33+
* multiple calls to \ref WriteCards can produce output in different folders.
34+
*
35+
* By default CardWriter will create any directories that are needed, but this
36+
* behaviour can be switched off with the `CreateDirectories` method. Also
37+
* note that any existing files with the same name will be over-written.
38+
*
39+
* \note The $MASS variable is treated differently than the others when
40+
* constructing the list of output files. It is anticipated that a mass value
41+
* of `*` should not give rise to actual files containing the `*` character,
42+
* but rather implies an Object that is valid for any mass-point. It is
43+
* commonly used to denote background processes that do not depend on the
44+
* signal mass hypothesis. Therefore this class ignores objects with a mass
45+
* value of `*` when determining which files to create, and when creating the
46+
* files treats this object as matching any mass value. It is possible to
47+
* alter or remove this behaviour by supplying a new list of wildcard values
48+
* with the \ref SetWildcardMasses method.
49+
*/
50+
class CardWriter {
51+
public:
52+
/// Must be constructed with text and ROOT file patterns
53+
CardWriter(std::string const& text_pattern, std::string const& root_pattern);
54+
/// Write datacards according to patterns, substituting `$TAG` for `tag`
55+
void WriteCards(std::string const& tag, ch::CombineHarvester& cmb) const;
56+
/// Set >= 1 for verbose output, otherwise silent
57+
CardWriter& SetVerbosity(unsigned v);
58+
/// Control whether directories can be created if missing
59+
CardWriter& CreateDirectories(bool flag);
60+
/// Redefine the mass values that should be treated as wildcards
61+
CardWriter& SetWildcardMasses(std::vector<std::string> const& masses);
62+
63+
private:
64+
typedef std::map<std::string, std::set<std::string>> PatternMap;
65+
std::string text_pattern_;
66+
std::string root_pattern_;
67+
mutable std::string tag_;
68+
std::vector<std::string> wildcard_masses_;
69+
unsigned v_;
70+
bool create_dirs_;
71+
72+
std::string Compile(std::string pattern, ch::Object const* obj,
73+
bool skip_mass = false) const;
74+
PatternMap BuildMap(std::string const& pattern,
75+
ch::CombineHarvester& cmb) const;
76+
void MakeDirs(PatternMap const& map) const;
77+
};
78+
}
79+
80+
#endif

CombineHarvester/CombineTools/interface/CombineHarvester.h

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,6 @@ class CombineHarvester {
164164
*/
165165
/**@{*/
166166
// Set generation
167-
template <typename T>
168-
std::set<T> GenerateSetFromProcs(
169-
std::function<T(ch::Process const*)> func);
170-
171-
template<typename T>
172-
std::set<T> GenerateSetFromObs(
173-
std::function<T(ch::Observation const*)> func);
174-
175-
template <typename T>
176-
std::set<T> GenerateSetFromSysts(
177-
std::function<T(ch::Systematic const*)> func);
178-
179167
std::set<std::string> bin_set();
180168
std::set<int> bin_id_set();
181169
std::set<std::string> process_set();
@@ -185,18 +173,55 @@ class CombineHarvester {
185173
std::set<std::string> mass_set();
186174
std::set<std::string> syst_name_set();
187175
std::set<std::string> syst_type_set();
188-
/**@}*/
189176

190-
// An alternative way to do the set generation
191-
// template<typename T>
192-
// T unwind(T const& x) { return x; }
177+
/**
178+
* Fill an std::set with the return values from an arbitrary function
179+
*
180+
* This method will loop through all ch::Observation, ch::Process and
181+
* ch::Systematic entries and call the user-supplied function `func`. The
182+
* return value is then inserted into the set.
183+
*
184+
* @tparam T A function (or other callable) that must have a single
185+
* `ch::Object const*` argument.
186+
* @tparam R The return type of the function, which is deduced by using
187+
* `std::result_of`, then `std::decay`. The latter is needed to handle
188+
* functions that return by reference, i.e. turning a type R& into a type R.
189+
*/
190+
template <typename T,
191+
typename R = typename std::decay<
192+
typename std::result_of<T(Object const*)>::type>::type>
193+
std::set<R> SetFromAll(T func);
194+
195+
/**
196+
* Fill an std::set using only the Observation entries
197+
*
198+
* \sa SetFromAll
199+
*/
200+
template <typename T,
201+
typename R = typename std::decay<
202+
typename std::result_of<T(Observation const*)>::type>::type>
203+
std::set<R> SetFromObs(T func);
204+
205+
/**
206+
* Fill an std::set using only the Process entries
207+
*
208+
* \sa SetFromAll
209+
*/
210+
template <typename T,
211+
typename R = typename std::decay<
212+
typename std::result_of<T(Process const*)>::type>::type>
213+
std::set<R> SetFromProcs(T func);
193214

194-
// template<typename T>
195-
// auto SetFromProcs(T func) -> std::set<decltype(unwind(func(nullptr)))> {
196-
// std::set<decltype(unwind(func(nullptr)))> ret;
197-
// for (auto const& item : procs_) ret.insert(func(item.get()));
198-
// return ret;
199-
// };
215+
/**
216+
* Fill an std::set using only the Systematic entries
217+
*
218+
* \sa SetFromAll
219+
*/
220+
template <typename T,
221+
typename R = typename std::decay<
222+
typename std::result_of<T(Systematic const*)>::type>::type>
223+
std::set<R> SetFromSysts(T func);
224+
/**@}*/
200225

201226
/**
202227
* \name Modification
@@ -446,29 +471,35 @@ void FillHistMappings(std::vector<HistMapping> & mappings);
446471
// ---------------------------------------------------------------
447472
// Template method implementation
448473
// ---------------------------------------------------------------
449-
template<typename T>
450-
std::set<T> CombineHarvester::GenerateSetFromProcs(
451-
std::function<T (ch::Process const*)> func) {
452-
std::set<T> ret;
474+
template <typename T, typename R>
475+
std::set<R> CombineHarvester::SetFromAll(T func) {
476+
std::set<R> ret;
477+
for (auto const& item : obs_) ret.insert(func(item.get()));
453478
for (auto const& item : procs_) ret.insert(func(item.get()));
479+
for (auto const& item : systs_) ret.insert(func(item.get()));
454480
return ret;
455-
}
481+
};
456482

457-
template<typename T>
458-
std::set<T> CombineHarvester::GenerateSetFromObs(
459-
std::function<T (ch::Observation const*)> func) {
460-
std::set<T> ret;
483+
template <typename T, typename R>
484+
std::set<R> CombineHarvester::SetFromObs(T func) {
485+
std::set<R> ret;
461486
for (auto const& item : obs_) ret.insert(func(item.get()));
462487
return ret;
463-
}
488+
};
489+
490+
template <typename T, typename R>
491+
std::set<R> CombineHarvester::SetFromProcs(T func) {
492+
std::set<R> ret;
493+
for (auto const& item : procs_) ret.insert(func(item.get()));
494+
return ret;
495+
};
464496

465-
template<typename T>
466-
std::set<T> CombineHarvester::GenerateSetFromSysts(
467-
std::function<T (ch::Systematic const*)> func) {
468-
std::set<T> ret;
497+
template <typename T, typename R>
498+
std::set<R> CombineHarvester::SetFromSysts(T func) {
499+
std::set<R> ret;
469500
for (auto const& item : systs_) ret.insert(func(item.get()));
470501
return ret;
471-
}
502+
};
472503

473504
template<typename Function>
474505
void CombineHarvester::ForEachObj(Function func) {

CombineHarvester/CombineTools/interface/Logging.h

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
#define CombineTools_Logging_h
33
#include <string>
44
#include <iostream>
5+
#include <chrono>
56

67
namespace ch {
78

89
#define FNERROR(x) FnError(x, __FILE__, __LINE__, __PRETTY_FUNCTION__)
910

1011
#define LOGLINE(x, y) LogLine(x, __func__, y)
1112

13+
#define FNLOG(x) x << "[" << __func__ << "]"
14+
#define FNLOGC(x, y) if (y) x << "[" << __func__ << "] "
1215
/**
1316
* \brief Writes a logging message to a given ostream
1417
* \details Should be used with the macro LOGLINE which will call this function
@@ -33,7 +36,6 @@ void LogLine(std::ostream& stream, std::string const& func,
3336
*/
3437
std::string FnError(std::string const& message, std::string const& file,
3538
unsigned line, std::string const& fn);
36-
}
3739

3840
/**
3941
* \brief Extracts the fully-qualified function name from a complete function
@@ -49,4 +51,60 @@ std::string FnError(std::string const& message, std::string const& file,
4951
*/
5052
std::string GetQualififedName(std::string const& str);
5153

54+
/**
55+
* Conveniently initialise a ch::FnTimer instance
56+
*
57+
* This macro should be placed at the start of a function, e.g.:
58+
*
59+
* void MyFunction() {
60+
* LAUNCH_FUNCTION_TIMER(__timer__, __token__)
61+
* }
62+
*
63+
* The arguments are the names of two objects (a ch::FnTimer and a
64+
* ch::FnTimer::Token) that will be created by this macro. Note that the
65+
* ch::FnTimer will be assigned the current function name automatically.
66+
*/
67+
#define LAUNCH_FUNCTION_TIMER(x, y) \
68+
static FnTimer x(ch::GetQualififedName(__PRETTY_FUNCTION__)); \
69+
auto y = x.Inc();
70+
71+
/**
72+
* Determine the total amount of time spent in a function
73+
*
74+
* An FnTimer instance should typically be declared as a static variable at
75+
* the beginning of a function, follwed by a call to the Inc() method, which
76+
* will increment the counter. The Inc() method also returns an FnTimer::Token
77+
* object that records the time at which it is constructed and then destroyed,
78+
* the latter occurring automatically at the end of the function. At the end
79+
* of the program the FnTimer destructor will write a message to the screen
80+
* summarising the number of calls and the time information.
81+
*
82+
* \note A simple way of using this class is via the LAUNCH_FUNCTION_TIMER(x,y)
83+
* macro
84+
*/
85+
class FnTimer {
86+
public:
87+
class Token {
88+
public:
89+
explicit Token(FnTimer *src);
90+
~Token();
91+
private:
92+
FnTimer *src_;
93+
};
94+
95+
explicit FnTimer(std::string name);
96+
~FnTimer();
97+
Token Inc();
98+
void StartTimer();
99+
void StopTimer();
100+
101+
private:
102+
std::string name_;
103+
unsigned calls_;
104+
std::chrono::time_point<std::chrono::system_clock> start_;
105+
std::chrono::time_point<std::chrono::system_clock> end_;
106+
double elapsed_;
107+
};
108+
}
109+
52110
#endif

CombineHarvester/CombineTools/interface/TFileIO.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ T OpenFromTFile(TFile* file, std::string const& path);
2929
// ------------------------------------------------------------------
3030
template <class T>
3131
void ch::WriteToTFile(T const* ptr, TFile* file, std::string const& path) {
32+
#ifdef TIME_FUNCTIONS
33+
LAUNCH_FUNCTION_TIMER(__timer__, __token__)
34+
#endif
3235
file->cd();
3336
std::vector<std::string> as_vec;
3437
boost::split(as_vec, path, boost::is_any_of("/"));

0 commit comments

Comments
 (0)