Browse Source

Updates to analysis routine, adding additional histograms

Caleb Fangmeier 7 years ago
parent
commit
8e14382b89

+ 2 - 2
analysis/MVA_Creation.cpp

@@ -65,12 +65,12 @@ void enable_branches(MiniTreeDataSet& mt){
 void declare_values(MiniTreeDataSet& mt){
 
     auto event_number = mt.get_current_event_number();
-    auto is_training = fv::apply(fv::GenFunction::register_function<bool(int)>("is_odd",
+    auto is_training = fv::apply(fv::GenFunction::reg_func<bool(int)>("is_odd",
         FUNC(([](int n){
             return (n%2) == 1;
         }))), fv::tuple(event_number));
 
-    auto is_signal = fv::bound(fv::GenFunction::register_function<bool()>("is_signal",
+    auto is_signal = fv::bound(fv::GenFunction::reg_func<bool()>("is_signal",
         FUNC(([mt=&mt](){
             const std::string& label = mt->get_current_event_label();
             return label == "signal";

+ 26 - 14
analysis/TTTT_Analysis.cpp

@@ -70,23 +70,23 @@ void enable_extra_branches(MiniTreeDataSet& mt){
 void declare_values(MiniTreeDataSet& mt){
 
     // Define a couple selections to be used in the top-mass reconstruction.
-    auto& b_pdgid_filter = GenFunction::register_function<bool(Particle)>("b_pdgid_filter",
+    auto& b_pdgid_filter = GenFunction::reg_func<bool(Particle)>("b_pdgid_filter",
         FUNC(([](const Particle& j){
                 return j.genpart.pdgId == 5 || j.genpart.pdgId==-5;
         })));
-    auto& w_mass_filter = GenFunction::register_function<bool(Particle, Particle)>("w_mass_filter",
+    auto& w_mass_filter = GenFunction::reg_func<bool(Particle, Particle)>("w_mass_filter",
         FUNC(([win_l=W_MASS-10, win_h=W_MASS+10](const Particle& j1, const Particle& j2){
             float inv_mass = (j1.v + j2.v).M();
             return inv_mass > win_l && inv_mass < win_h;
         })));
-    auto& dup_filter = GenFunction::register_function<bool(std::tuple<Particle,Particle>,Particle)>("dup_filter",
+    auto& dup_filter = GenFunction::reg_func<bool(std::tuple<Particle,Particle>,Particle)>("dup_filter",
         FUNC(([](const std::tuple<Particle,Particle>& w, const Particle& b){
             int j0 = b.idx;
             int j1 = std::get<0>(w).idx;
             int j2 = std::get<1>(w).idx;
             return (j0 != j1) && (j0 != j2) && (j1 != j2);
         })));
-    auto& qg_id_filter = GenFunction::register_function<bool(Particle, Particle)>("qg_id_filter",
+    auto& qg_id_filter = GenFunction::reg_func<bool(Particle, Particle)>("qg_id_filter",
         FUNC(([](const Particle& j1, const Particle& j2){
             // require both particles be either quarks(not Top) or gluons
             int id1 = abs(j1.genpart.pdgId);
@@ -115,7 +115,7 @@ void declare_values(MiniTreeDataSet& mt){
 
     top_cands = tup_filter(dup_filter, top_cands);
 
-    auto& t_mass = GenFunction::register_function<float(std::tuple<Particle,Particle>,Particle)>("t_mass",
+    auto& t_mass = GenFunction::reg_func<float(std::tuple<Particle,Particle>,Particle)>("t_mass",
         FUNC(([](const std::tuple<Particle,Particle>& w, const Particle& b){
             return (std::get<0>(w).v+std::get<1>(w).v+b.v).M();
         })));
@@ -139,7 +139,7 @@ void declare_values(MiniTreeDataSet& mt){
 
 
     // calculation of di-jet inv-mass spectrum
-    auto& inv_mass2 = GenFunction::register_function<float(Particle, Particle)>("inv_mass2",
+    auto& inv_mass2 = GenFunction::reg_func<float(Particle, Particle)>("inv_mass2",
         FUNC(([] (const Particle& j1, const Particle& j2){
             TLorentzVector sum = j1.v + j2.v;
             return (float)sum.M();
@@ -148,20 +148,20 @@ void declare_values(MiniTreeDataSet& mt){
 
 
 
-    count<float>(GenFunction::register_function<bool(float)>("bJet_Selection",
+    count<float>(GenFunction::reg_func<bool(float)>("bJet_Selection",
         FUNC(([](float x){
             return x>0;
         }))), "Jet_btagCMVA",  "b_jet_count");
 
-    auto &is_electron = GenFunction::register_function<bool(int)>("is_electron",
+    auto &is_electron = GenFunction::reg_func<bool(int)>("is_electron",
         FUNC(([](int pdgId) {
             return abs(pdgId) == 11;
         })));
-    auto &is_muon = GenFunction::register_function<bool(int)>("is_muon",
+    auto &is_muon = GenFunction::reg_func<bool(int)>("is_muon",
         FUNC(([](int pdgId) {
             return abs(pdgId) == 13;
         })));
-    auto &is_lepton = GenFunction::register_function<bool(int)>("is_lepton",
+    auto &is_lepton = GenFunction::reg_func<bool(int)>("is_lepton",
         FUNC(([ie=&is_electron, im=&is_muon](int pdgId) {
             return (*ie)(pdgId) || (*im)(pdgId);
         })));
@@ -179,7 +179,7 @@ void declare_values(MiniTreeDataSet& mt){
     fv::pair<int, int>("genMu_count",  "recMu_count",  "genMu_count_v_recMu_count");
     fv::pair<int, int>("genLep_count", "recLep_count", "genLep_count_v_recLep_count");
 
-    /* auto& sum = GenFunction::register_function<float(std::vector<float>)>("sum", */
+    /* auto& sum = GenFunction::reg_func<float(std::vector<float>)>("sum", */
     /*     FUNC(([](const std::vector<float>& v){ */
     /*         return std::accumulate(v.begin(), v.end(), 0); */
     /*     }))); */
@@ -272,14 +272,26 @@ void declare_containers(MiniTreeDataSet& mt){
     auto jet_count = mt.register_container<ContainerTH1<int>>("jet_count", "B-Jet Multiplicity", lookup<int>("nJet"), 15, 0, 15);
     mt.cut_set(jet_count,{
                {event_selection.trilepton, "jet_count_trilepton"},
+               {event_selection.eem_trilepton, "jet_count_eem_trilepton"},
+               {event_selection.mme_trilepton, "jet_count_mme_trilepton"},
                {event_selection.b_jet3, "jet_count_b_jet3"},
                {event_selection.z_mass_veto, "jet_count_z_mass_veto"},
                {event_selection.base_sel, "jet_count_base_selection"},
+               {event_selection.eem_base_sel, "jet_count_eem_base_selection"},
+               {event_selection.mme_base_sel, "jet_count_mme_base_selection"},
+               });
+    auto b_jet_count = mt.register_container<ContainerTH1<int>>("b_jet_count", "B-Jet Multiplicity", lookup<int>("b_jet_count"), 10, 0, 10);
+    mt.cut_set(b_jet_count,{
+               {event_selection.trilepton, "b_jet_count_trilepton"},
+               {event_selection.eem_trilepton, "b_jet_count_eem_trilepton"},
+               {event_selection.mme_trilepton, "b_jet_count_mme_trilepton"},
+               {event_selection.b_jet3, "b_jet_count_b_jet3"},
+               {event_selection.z_mass_veto, "b_jet_count_z_mass_veto"},
+               {event_selection.base_sel, "b_jet_count_base_selection"},
+               {event_selection.eem_base_sel, "b_jet_count_eem_base_selection"},
+               {event_selection.mme_base_sel, "b_jet_count_mme_base_selection"},
                });
-    mt.register_container<ContainerTH1<int>>("b_jet_count", "B-Jet Multiplicity", lookup<int>("b_jet_count"), 10, 0, 10);
-
 
-    mt.register_container<ContainerTH1<int>>("b_jet_count_base_selection", "B-Jet Multiplicity", lookup<int>("b_jet_count"), 10, 0, 10)->add_filter(event_selection.base_sel);
 
     mt.register_container<ContainerTH1<int>>("jet_count_os_dilepton", "Jet Multiplicity - OS Dilepton Events",
                                                 lookup<int>("nJet"), 14, 0, 14)->add_filter(lookup_obs_filter("os-dilepton"));

+ 9 - 9
analysis/common/obj_types.hpp

@@ -95,7 +95,7 @@ struct Particle{
         p.genpart = genpart;
         return p;
     }
-    
+
     static Particle
     Void(){
         Particle p;
@@ -105,7 +105,7 @@ struct Particle{
 
 };
 
-Function<Particle(std::vector<Particle>)>& leading_particle = GenFunction::register_function<Particle(std::vector<Particle>)>("leading_particle",
+Function<Particle(std::vector<Particle>)>& leading_particle = GenFunction::reg_func<Particle(std::vector<Particle>)>("leading_particle",
     FUNC(([](const std::vector<Particle>& particles){
         if(particles.size() == 0) return Particle::Void();
 
@@ -118,17 +118,17 @@ Function<Particle(std::vector<Particle>)>& leading_particle = GenFunction::regis
         return leading_particle;
     })));
 
-Function<float(Particle)>& particle_pt = GenFunction::register_function<float(Particle)>("particle_pt",
+Function<float(Particle)>& particle_pt = GenFunction::reg_func<float(Particle)>("particle_pt",
         FUNC(([](const Particle& p){
             return p.v.Pt();
         })));
-Function<float(Particle)>& particle_eta = GenFunction::register_function<float(Particle)>("particle_eta",
+Function<float(Particle)>& particle_eta = GenFunction::reg_func<float(Particle)>("particle_eta",
         FUNC(([](const Particle& p){
             return p.v.Eta();
         })));
 
 
-Function<float(Particle)>& lepton_relIso = GenFunction::register_function<float(Particle)>("lepton_relIso",
+Function<float(Particle)>& lepton_relIso = GenFunction::reg_func<float(Particle)>("lepton_relIso",
         FUNC(([](const Particle& p){
             return p.lepton.relIso;
         })));
@@ -144,7 +144,7 @@ construct_jets_value(MiniTreeDataSet& mt){
     auto Jet_4v = lorentz_vectors("Jet_pt", "Jet_eta", "Jet_phi", "Jet_mass", "Jet_4v");
 
 
-    auto jets = apply(GenFunction::register_function<std::vector<Particle>(std::vector<TLorentzVector>,
+    auto jets = apply(GenFunction::reg_func<std::vector<Particle>(std::vector<TLorentzVector>,
                                                                            std::vector<float>,
                                                                            std::vector< int >
                                                                            )>("build_reco_jets",
@@ -169,7 +169,7 @@ construct_jets_value(MiniTreeDataSet& mt){
 
 decltype(auto)
 construct_b_jets_value(MiniTreeDataSet& mt){
-    auto b_jets = fv::filter(GenFunction::register_function<bool(Particle)>("is_b_jet",
+    auto b_jets = fv::filter(GenFunction::reg_func<bool(Particle)>("is_b_jet",
         FUNC(([](const Particle& p){
             if(p.tag != Particle::JET) return false;
             return p.jet.b_cmva > 0;
@@ -188,7 +188,7 @@ construct_leptons_value(MiniTreeDataSet& mt){
     auto LepGood_4v = lorentz_vectors("LepGood_pt", "LepGood_eta", "LepGood_phi", "LepGood_mass", "LepGood_4v");
 
 
-    auto leptons = apply(GenFunction::register_function<std::vector<Particle>(std::vector<TLorentzVector>,
+    auto leptons = apply(GenFunction::reg_func<std::vector<Particle>(std::vector<TLorentzVector>,
                                                                               std::vector<int>,
                                                                               std::vector<int>,
                                                                               std::vector<int>,
@@ -227,7 +227,7 @@ construct_mc_jets_value(MiniTreeDataSet& mt){
     auto Jet_4v = lorentz_vectors("GenPart_pt", "GenPart_eta", "GenPart_phi", "GenPart_mass", "GenPart_4v");
     energies(Jet_4v, "GenPart_energy");
 
-    auto mc_jets = apply(GenFunction::register_function<std::vector<Particle>(std::vector<TLorentzVector>,
+    auto mc_jets = apply(GenFunction::reg_func<std::vector<Particle>(std::vector<TLorentzVector>,
                                                                               std::vector<int>,
                                                                               std::vector<int>,
                                                                               std::vector<int>,

+ 19 - 15
analysis/selection.hpp

@@ -44,12 +44,15 @@
 
 struct EventSelection{
     ObsFilter* trilepton;
-    ObsFilter* trilepton_eemu; // OS electron pair + muon+-
-    ObsFilter* trilepton_mumue; // OS muon pair + electron+-
+    ObsFilter* eem_trilepton; // OS electron pair + muon+-
+    ObsFilter* mme_trilepton; // OS muon pair + electron+-
+
     ObsFilter* b_jet3;
     ObsFilter* z_mass_veto;
 
     ObsFilter* base_sel;
+    ObsFilter* eem_base_sel;
+    ObsFilter* mme_base_sel;
 
     ObsFilter* J4;
     ObsFilter* J5;
@@ -67,13 +70,13 @@ void init_selection(){
     auto jets    = lookup<std::vector<Particle>>("jets");
 
     // Require *exactly* three charged leptons
-    event_selection.trilepton = obs_filter("trilepton",GenFunction::register_function<bool()>("trilepton",
+    event_selection.trilepton = obs_filter("trilepton",GenFunction::reg_func<bool()>("trilepton",
         FUNC(([leptons](){
             return leptons->get_value().size() == 3;
         }))));
 
     // Require OS electron pair and a muon
-    event_selection.trilepton_eemu = obs_filter("trilepton_eemu",GenFunction::register_function<bool()>("trilepton_eemu",
+    event_selection.eem_trilepton = obs_filter("eem_trilepton",GenFunction::reg_func<bool()>("eem_trilepton",
         FUNC(([leptons](){
             std::vector<Particle>& leps = leptons->get_value();
             if(leps.size() != 3) return false;
@@ -92,7 +95,7 @@ void init_selection(){
         }))));
 
     // Require OS muon pair and an electron
-    event_selection.trilepton_mumue = obs_filter("trilepton_mumue",GenFunction::register_function<bool()>("trilepton_mumue",
+    event_selection.mme_trilepton = obs_filter("mme_trilepton",GenFunction::reg_func<bool()>("mme_trilepton",
         FUNC(([leptons](){
             std::vector<Particle>& leps = leptons->get_value();
             if(leps.size() != 3) return false;
@@ -111,7 +114,7 @@ void init_selection(){
         }))));
 
     // Require at least three b-jets
-    event_selection.b_jet3 = obs_filter("b_jet3",GenFunction::register_function<bool()>("b_jet3",
+    event_selection.b_jet3 = obs_filter("b_jet3",GenFunction::reg_func<bool()>("b_jet3",
         FUNC(([jets](){
             int n_b_jets = 0;
             for(auto jet : jets->get_value()){
@@ -123,7 +126,7 @@ void init_selection(){
 
     // Require all same-flavour OS dilepton combinations are outside the Z mass
     // window (70,105)
-    event_selection.z_mass_veto = obs_filter("z_mass_veto",GenFunction::register_function<bool()>("z_mass_veto",
+    event_selection.z_mass_veto = obs_filter("z_mass_veto",GenFunction::reg_func<bool()>("z_mass_veto",
         FUNC(([leptons](){
             auto& leps = leptons->get_value();
             int n = leps.size();
@@ -142,25 +145,26 @@ void init_selection(){
         }))));
 
 
-    event_selection.J4 = obs_filter("4jet_selection",GenFunction::register_function<bool()>("4jet_selection",
+    event_selection.J4 = obs_filter("4jet_selection",GenFunction::reg_func<bool()>("4jet_selection",
         FUNC(([jets](){
             return jets->get_value().size() >= 4;
         }))));
 
-    event_selection.J5 = obs_filter("5jet_selection",GenFunction::register_function<bool()>("5jet_selection",
+    event_selection.J5 = obs_filter("5jet_selection",GenFunction::reg_func<bool()>("5jet_selection",
         FUNC(([jets](){
             return jets->get_value().size() >= 5;
         }))));
 
-    event_selection.J6 = obs_filter("6jet_selection",GenFunction::register_function<bool()>("6jet_selection",
+    event_selection.J6 = obs_filter("6jet_selection",GenFunction::reg_func<bool()>("6jet_selection",
         FUNC(([jets](){
             return jets->get_value().size() >= 6;
         }))));
 
-    /* event_selection.base_sel = ObsFilter::conj(event_selection.z_mass_veto, ObsFilter::conj(event_selection.trilepton, event_selection.b_jet3)); */
-    event_selection.base_sel = all({event_selection.z_mass_veto, event_selection.trilepton_eemu, event_selection.b_jet3});
-    event_selection.SR4j = all(event_selection.base_sel, event_selection.J4);
-    event_selection.SR5j = all(event_selection.base_sel, event_selection.J5);
-    event_selection.SR6j = all(event_selection.base_sel, event_selection.J6);
+    event_selection.base_sel = all({event_selection.z_mass_veto, event_selection.trilepton, event_selection.b_jet3});
+    event_selection.eem_base_sel = all({event_selection.z_mass_veto, event_selection.eem_trilepton, event_selection.b_jet3});
+    event_selection.mme_base_sel = all({event_selection.z_mass_veto, event_selection.mme_trilepton, event_selection.b_jet3});
+    event_selection.SR4j = all({event_selection.base_sel, event_selection.J4});
+    event_selection.SR5j = all({event_selection.base_sel, event_selection.J5});
+    event_selection.SR6j = all({event_selection.base_sel, event_selection.J6});
 }
 #endif // SELECTION_HPP

File diff suppressed because it is too large
+ 0 - 1840
cmake/UseLATEX.cmake


+ 1 - 1
filval/dataset.hpp

@@ -79,7 +79,7 @@ class DataSet{
         }
     public:
         DataSet(){
-            auto& event_check = GenFunction::register_function<int()>("event_number",
+            auto& event_check = GenFunction::reg_func<int()>("event_number",
                 FUNC(([ds=this](){
                     return ds->get_current_event();
                 })));

+ 1 - 13
filval/filter.hpp

@@ -52,7 +52,7 @@ class ObsFilter : public DerivedValue<bool>{
     public:
         ObsFilter(const std::string& name, std::function<bool()> filter_function, const std::string& impl="")
           :DerivedValue<bool>(name),
-           filter_function(GenFunction::register_function<bool()>("filter::"+name, filter_function, impl)){ }
+           filter_function(GenFunction::reg_func<bool()>("filter::"+name, filter_function, impl)){ }
 };
 
 /** Return a new filter that is the conjuction of a vector of source filters
@@ -85,17 +85,5 @@ ObsFilter* any(const std::vector<ObsFilter*>&& fs){
     }
 }
 
-/** Return a new filter that is the conjuction of the two source filters.
- */
-ObsFilter* all(ObsFilter *f1, ObsFilter *f2){
-    return all({f1, f2});
-}
-
-/** Return a new filter that is the conjuction of the two source filters.
- */
-ObsFilter* any(ObsFilter *f1, ObsFilter *f2){
-    return any({f1, f2});
-}
-
 }
 #endif // filter_h

+ 13 - 13
filval/value.hpp

@@ -141,7 +141,7 @@ class GenFunction {
         std::string name;
         std::string impl;
     protected:
-        inline static bool in_register_function=false;
+        inline static bool in_reg_func=false;
 
     public:
         /**
@@ -194,8 +194,8 @@ class GenFunction {
         }
 
         template <typename T>
-        static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
-            in_register_function = true;
+        static Function<T>& reg_func(const std::string& name, std::function<T> f, const std::string& impl){
+            in_reg_func = true;
             Function<T>* func;
             if (GenFunction::function_registry[name] != nullptr){
                 func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
@@ -206,7 +206,7 @@ class GenFunction {
                 func = new Function<T>(name, impl, f);
                 GenFunction::function_registry[name] = func;
             }
-            in_register_function = false;
+            in_reg_func = false;
             return *func;
         }
 
@@ -244,8 +244,8 @@ class Function<R(ArgTypes...)> : public GenFunction {
     public:
         Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
           :GenFunction(name, impl), f(f){
-            if (!in_register_function) {
-                WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
+            if (!in_reg_func) {
+                WARNING("Don't instantiate Function objects directly! Use GenFunction::reg_func instead.");
             }
           }
         Function(const std::string& name, std::function<R(ArgTypes...)> f)
@@ -980,7 +980,7 @@ class Max : public Reduce<T>{
         }
 
         Max(Value<std::vector<T>>* v, const std::string alias)
-          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
+          :Reduce<T>(GenFunction::reg_func<T(std::vector<T>)>("max",
                       FUNC(([](std::vector<T> vec){
                           return *std::max_element(vec.begin(), vec.end());}))),
                       v, alias) { }
@@ -997,7 +997,7 @@ class Min : public Reduce<T>{
         }
 
         Min(Value<std::vector<T>>* v, const std::string alias)
-          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
+          :Reduce<T>(GenFunction::reg_func<T(std::vector<T>)>("min",
                       FUNC(([](std::vector<T> vec){
                          return *std::min_element(vec.begin(), vec.end());}))),
                      v, alias) { }
@@ -1014,7 +1014,7 @@ class Mean : public Reduce<T>{
         }
 
         Mean(Value<std::vector<T>>* v, const std::string alias)
-          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
+          :Reduce<T>(GenFunction::reg_func<T(std::vector<T>)>("mean",
                       FUNC(([](std::vector<T> vec){
                         int n = 0; T sum = 0;
                         for (T e : vec){ n++; sum += e; }
@@ -1033,7 +1033,7 @@ class Range : public Reduce<T>{
         }
 
         Range(Value<std::vector<T>>* v, const std::string alias)
-          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
+          :Reduce<T>(GenFunction::reg_func<T(std::vector<T>)>("range",
                       FUNC(([](std::vector<T> vec){
                         auto minmax = std::minmax_element(vec.begin(), vec.end());
                         return (*minmax.second) - (*minmax.first); }))),
@@ -1047,7 +1047,7 @@ template <typename T>
 class ElementOf : public Reduce<T>{
     public:
         ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
-          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
+          :Reduce<T>(GenFunction::reg_func<T(std::vector<T>)>("elementOf",
                      FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
                      v, alias) { }
 };
@@ -1080,7 +1080,7 @@ template <typename T>
 class MaxIndex : public ReduceIndex<T>{
     public:
         MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
-          :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
+          :ReduceIndex<T>(GenFunction::reg_func<T(std::vector<T>)>("maxIndex",
                           FUNC(([](std::vector<T> vec){
                                auto elptr = std::max_element(vec.begin(), vec.end());
                                return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
@@ -1094,7 +1094,7 @@ template <typename T>
 class MinIndex : public ReduceIndex<T>{
     public:
         MinIndex(Value<std::vector<T>>* v, const std::string alias="")
-          :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
+          :ReduceIndex<T>(GenFunction::reg_func<T(std::vector<T>)>("minIndex",
                           FUNC(([](std::vector<T> vec){
                                auto elptr = std::min_element(vec.begin(), vec.end());
                                return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),

File diff suppressed because it is too large
+ 55 - 135
python/Plotter Testing.ipynb


+ 13 - 23
python/plotter.py

@@ -75,26 +75,15 @@ class StackHist:
             raise ValueError("all histograms must have the same number of bins")
         self.n_bins = n_bins
 
-    def save(self, fname):
-        from matplotlib.transforms import Bbox
-        def full_extent(ax, pad=0.0):
-            """Get the full extent of an axes, including axes labels, tick labels, and
-            titles."""
-            # For text objects, we need to draw the figure first, otherwise the extents
-            # are undefined.
-            ax.figure.canvas.draw()
-            items = ax.get_xticklabels() + ax.get_yticklabels()
-            items += [ax, ax.title, ax.xaxis.label, ax.yaxis.label]
-            # items += [ax, ax.title]
-            bbox = Bbox.union([item.get_window_extent() for item in items])
-
-            return bbox.expanded(1.0 + pad, 1.0 + pad)
-
-        extents = []
-        for axes in self.axeses:
-            extents.append(full_extent(axes).transformed(axes.figure.dpi_scale_trans.inverted()))
-        extent = Bbox.union(extents)
-        axes.figure.savefig('figures/'+fname, bbox_inches=extent)
+    def save(self, filename, **kwargs):
+        import matplotlib.pyplot as plt
+        plt.ioff()
+        fig = plt.figure()
+        ax = fig.gca()
+        self.do_draw(ax, **kwargs)
+        fig.savefig("figures/"+filename, transparent=True)
+        plt.close(fig)
+        plt.ion()
 
     def do_draw(self, axes):
         self.axeses = [axes]
@@ -169,10 +158,12 @@ class StackHist:
         axes.legend(frameon=True, ncol=2)
         add_decorations(axes, self.luminosity, self.energy)
 
-    def draw(self, axes, save=True, **kwargs):
+    def draw(self, axes, save=False, filename=None, **kwargs):
         self.do_draw(axes, **kwargs)
         if save:
-            self.save(self.title+".png")
+            if filename is None:
+                filename = "".join(c for c in self.title if c.isalnum() or c in (' ._+-'))+".png"
+            self.save(filename, **kwargs)
 
 
 class StackHistWithSignificance(StackHist):
@@ -189,7 +180,6 @@ class StackHistWithSignificance(StackHist):
 
         bottom = axes.get_figure().add_axes(bottom_box)
         bottom_rhs = bottom.twinx()
-        self.axeses = [axes, bottom, bottom_rhs]
         bgs = [0]*self.n_bins
         for (_, _, bins, _) in self.backgrounds:
             for i, (left, right, value) in enumerate(bins):

+ 1 - 1
python/utils.py

@@ -171,7 +171,7 @@ class ResultSet:
                 raise RuntimeError(("Failed running analysis code."
                                     " See log file for more information"))
 
-        if run(["make"], cwd=join(PRJ_PATH, "build"), stdout=PIPE, stderr=PIPE).returncode != 0:
+        if run(["make", "main"], cwd=join(PRJ_PATH, "build"), stdout=PIPE, stderr=PIPE).returncode != 0:
             raise RuntimeError("Failed recompiling analysis code")
         if (not os.path.isfile(self.output_filename) or (getctime(EXE_PATH) > getctime(self.output_filename))):
             recompute()