Explorar o código

Adds function registry to keep track of declared lambda functions used
in various calculations. Adds ability to save containers.

Caleb Fangmeier %!s(int64=7) %!d(string=hai) anos
pai
achega
ccda3cb42d

+ 2 - 0
CMakeLists.txt

@@ -7,6 +7,8 @@ PROJECT (TTTT CXX)
 SET(FILVAL_VERSION_MAJOR 0)
 SET(FILVAL_VERSION_MINOR 1)
 SET(FILVAL_VERSION_PATCH 0)
+SET(CMAKE_BUILD_TYPE "Debug")
+
 CONFIGURE_FILE (
   "${PROJECT_SOURCE_DIR}/filval/filval.hpp"
   "${PROJECT_BINARY_DIR}/filval/filval.hpp"

+ 2 - 2
analysis/MiniTreeDataSet.hpp

@@ -9,8 +9,8 @@
 #include "MiniTree.hpp"
 
 using namespace std;
-using namespace filval;
-using namespace filval::root;
+using namespace fv;
+using namespace fv::root;
 
 class MiniTreeDataSet : public DataSet,
                         public MiniTree{

+ 39 - 29
analysis/TTTT_Analysis.cpp

@@ -13,9 +13,9 @@
 #include "MiniTreeDataSet.hpp"
 
 using namespace std;
-using namespace filval;
-using namespace filval::root;
-using namespace filval::util;
+using namespace fv;
+using namespace fv::root;
+using namespace fv::util;
 
 GenValue* lookup(const string& name){
     return GenValue::get_value(name);
@@ -24,18 +24,18 @@ Filter* lookup_filter(const string& name){
     return dynamic_cast<Filter*>(GenValue::get_value(name));
 }
 
-void enable_branches(MiniTreeDataSet* mt){
-    mt->fChain->SetBranchStatus("*", false);
-    mt->track_branch<int>("nJet");
-    mt->track_branch<int>("nLepGood");
-    mt->track_branch_ptr<float>("LepGood_pt");
-    mt->track_branch_ptr<float>("LepGood_eta");
-    mt->track_branch_ptr<float>("LepGood_phi");
-    mt->track_branch_ptr<float>("LepGood_mass");
+void enable_branches(MiniTreeDataSet& mt){
+    mt.fChain->SetBranchStatus("*", false);
+    mt.track_branch<int>("nJet");
+    mt.track_branch<int>("nLepGood");
+    mt.track_branch_ptr<float>("LepGood_pt");
+    mt.track_branch_ptr<float>("LepGood_eta");
+    mt.track_branch_ptr<float>("LepGood_phi");
+    mt.track_branch_ptr<float>("LepGood_mass");
 }
 
-void declare_values(MiniTreeDataSet* mt){
-    auto mean = Function<float(vector<float>)>("mean", [](vector<float> v){
+void declare_values(MiniTreeDataSet& mt){
+    auto& mean = GenFunction::register_function<float(vector<float>)>("mean", FUNC(([](vector<float> v){
             int n = 0;
             float sum = 0;
             for (float e : v){
@@ -43,18 +43,19 @@ void declare_values(MiniTreeDataSet* mt){
                 sum += e;
             }
             return n>0 ? sum / n : 0;
-            });
+            })));
 
     auto pt_wrapper  = new WrapperVector<float>("nLepGood", "LepGood_pt");
     auto eta_wrapper = new WrapperVector<float>("nLepGood", "LepGood_eta");
     auto phi_wrapper = new WrapperVector<float>("nLepGood", "LepGood_phi");
     auto m_wrapper   = new WrapperVector<float>("nLepGood", "LepGood_mass");
 
-    auto get_energy = Function<float(float,float,float,float)>("get_energy", [](float pt, float eta, float phi, float m){
+    auto& get_energy = GenFunction::register_function<float(float,float,float,float)>("get_energy", FUNC(([](float pt, float eta, float phi, float m){
         TLorentzVector t;
         t.SetPtEtaPhiM(pt, eta, phi, m);
         return t.E();
-    });
+    })));
+
     auto lepton_energy = new ZipMapFour<float, float>(get_energy, pt_wrapper, eta_wrapper, phi_wrapper, m_wrapper);
     GenValue::alias("lepton_energy", lepton_energy);
 
@@ -70,31 +71,40 @@ void declare_values(MiniTreeDataSet* mt){
     new RangeFilter<int>("3<=nLepGood<5", dynamic_cast<Value<int>*>(lookup("nLepGood")), 3, 5);
 }
 
-void declare_containers(MiniTreeDataSet* mt){
-    mt->add_container(new ContainerTH1I("nLepGood", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
+void declare_containers(MiniTreeDataSet& mt){
+    mt.add_container(new ContainerTH1I("nLepGood", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
+
+    mt.add_container(new ContainerTH1I("nLepGood2", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
+    mt.get_container("nLepGood2")->add_filter(lookup_filter("3<=nLepGood<5"));
 
-    mt->add_container(new ContainerTH1I("nLepGood2", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
-    mt->get_container("nLepGood2")->add_filter(lookup_filter("3<=nLepGood<5"));
+    mt.add_container(new ContainerTH1I("nLepGood3", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
+    mt.get_container("nLepGood3")->add_filter(!(*lookup_filter("3<=nLepGood<5")));
 
-    mt->add_container(new ContainerTH1I("nLepGood3", "Lepton Multiplicity", lookup("nLepGood"), 10, 0, 10));
-    mt->get_container("nLepGood3")->add_filter(!(*lookup_filter("3<=nLepGood<5")));
+    mt.add_container(new ContainerTGraph("nLepvsnJet", new Pair<int, int>("nLepGood", "nJet") ));
 
-    mt->add_container(new ContainerTGraph("nLepvsnJet", new Pair<int, int>("nLepGood", "nJet") ));
+    mt.add_container(new ContainerTH1F("avg_lepton_energy", "Average Lepton Energy", lookup("avg_lepton_energy"), 50, 0, 500));
+    mt.add_container(new ContainerTH1F("max_lepton_energy", "Maximum Lepton Energy", lookup("max_lepton_energy"), 50, 0, 500));
 
-    mt->add_container(new ContainerTH1F("avg_lepton_energy", "Average Lepton Energy", lookup("avg_lepton_energy"), 50, 0, 500));
-    mt->add_container(new ContainerTH1F("max_lepton_energy", "Maximum Lepton Energy", lookup("max_lepton_energy"), 50, 0, 500));
+}
 
+void save_containers(MiniTreeDataSet& mt){
+    mt.get_container("nLepGood")->save();
+    mt.get_container("nLepGood2")->save();
+    mt.get_container("nLepGood3")->save();
+    mt.get_container("avg_lepton_energy")->save();
+    mt.get_container("max_lepton_energy")->save();
 }
 
 void run_analysis(const std::string& filename){
     TFile *f = TFile::Open(filename.c_str());
     TTree *tree = (TTree*) f->Get("tree");
     MiniTreeDataSet mt(tree);
-    enable_branches(&mt);
-    declare_values(&mt);
-    declare_containers(&mt);
-    DEBUG(GenValue::summary());
+    enable_branches(mt);
+    declare_values(mt);
+    declare_containers(mt);
+    /* DEBUG(GenValue::summary()); */
     mt.process();
+    save_containers(mt);
 }
 
 int main(int argc, char * argv[])

+ 1 - 1
filval/argparse.hpp

@@ -35,7 +35,7 @@
 #include <algorithm>
 #include <string>
 #include <vector>
-namespace filval::util{
+namespace fv::util{
 /// \see http://stackoverflow.com/questions/865668/how-to-parse-command-line-arguments-in-c#868894
 class ArgParser{
     private:

+ 7 - 1
filval/container.hpp

@@ -4,7 +4,7 @@
 #include "filter.hpp"
 #include <vector>
 
-namespace filval{
+namespace fv{
 class GenContainer{
     private:
         std::string name;
@@ -36,6 +36,8 @@ class GenContainer{
         const std::string& get_name(){
             return name;
         }
+        virtual void save_as(const std::string& fname) = 0;
+        virtual void save() = 0;
 };
 typedef std::map<std::string, GenContainer*> ContainerSet;
 
@@ -70,6 +72,8 @@ class ContainerVector : public Container<std::vector<T> >{
            value(value){
             this->container = new std::vector<T>();
         }
+        void save_as(const std::string& fname) { }
+        virtual void save() { }
 };
 
 template <typename T>
@@ -94,6 +98,8 @@ class ContainerMean : public Container<T>{
             *(this->container) = sum/count;
             return (this->container);
         }
+        void save_as(const std::string& fname) { }
+        virtual void save() { }
 };
 
 }

+ 1 - 1
filval/dataset.hpp

@@ -5,7 +5,7 @@
 #include "container.hpp"
 #include "log.hpp"
 
-namespace filval{
+namespace fv{
 class DataSet{
     private:
         void summary(){

+ 1 - 1
filval/filter.hpp

@@ -7,7 +7,7 @@
  * Container objects have a vector of filters that control if a "fill" call
  * actually places data into the container or not.
  */
-namespace filval {
+namespace fv {
 
 class Filter : public DerivedValue<bool>{
     private:

+ 6 - 6
filval/log.hpp

@@ -38,7 +38,7 @@
 #include <cstring>
 #include <map>
 
-namespace filval::util{
+namespace fv::util{
 enum LogPriority {
     kLogEmergency = 7,  // system is unusable
     kLogAlert     = 6,  // action must be taken immediately
@@ -50,11 +50,11 @@ enum LogPriority {
     kLogDebug     = 0   // debug-level message
 };
 
-#define CRITICAL(x,y) std::clog << filval::util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; exit(y)
-#define ERROR(x) std::clog << filval::util::LogPriority::kLogError << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
-#define WARNING(x) std::clog << filval::util::LogPriority::kLogWarning << x << std::flush
-#define INFO(x) std::clog << filval::util::LogPriority::kLogInfo << x << std::flush
-#define DEBUG(x) std::clog << filval::util::LogPriority::kLogDebug << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
+#define CRITICAL(x,y) std::clog << fv::util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; exit(y)
+#define ERROR(x) std::clog << fv::util::LogPriority::kLogError << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
+#define WARNING(x) std::clog << fv::util::LogPriority::kLogWarning << x << std::flush
+#define INFO(x) std::clog << fv::util::LogPriority::kLogInfo << x << std::flush
+#define DEBUG(x) std::clog << fv::util::LogPriority::kLogDebug << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
 
 /**
  * /see http://stackoverflow.com/questions/2638654/redirect-c-stdclog-to-syslog-on-unix

+ 78 - 59
filval/value.hpp

@@ -56,43 +56,74 @@
 /**
  * The namespace containing all filval classes and functions.
  */
-namespace filval{
+namespace fv{
 
+bool in_register_function = false;
+template<typename> class Function; // undefined
 /**
  * Parent class to all Function classes. Holds a class-level collection of all
  * created function objects.
  */
 class GenFunction {
-    protected:
+    private:
         std::string name;
         std::string impl;
+    protected:
+        /* virtual void _() = 0; */
+
 
+    public:
         /**
          * Static mapping of functions from their name to the object wrapper of
          * the function.
          */
-        inline static std::map<std::string, GenFunction*> function_registry;
+        inline static std::map<const std::string, GenFunction*> function_registry;
 
-    public:
         GenFunction(const std::string& name, const std::string& impl)
-          :name("func::"+name),impl(impl){
-            function_registry[name] = this;
+          :impl(impl),
+           name(name){
         }
+        virtual ~GenFunction() { };
 
         std::string& get_name(){
             return name;
         }
 
-        static std::string& summary(){
+        static std::string summary(){
             std::stringstream ss;
             for(auto p : function_registry){
-                ss << p.first << std::endl;
-                ss << p.second->impl << std::endl;
-                ss << "*****************************************" << std::endl;
+                if (p.second == nullptr) continue;
+                ss << p.second->name << std::endl;
+                ss << "\t" << p.second->impl << std::endl;
+                ss << "##############################" << std::endl;
+            }
+            return ss.str();
+        }
+
+        /* template <typename R, typename... ArgTypes> */
+        template <typename T>
+        static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
+            in_register_function = true;
+            Function<T>* func;
+            if (GenFunction::function_registry[name] != nullptr){
+                func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
+                if (func == nullptr){
+                    ERROR("Trying to register function which has already been registerd with a different type");
+                }
+            } else {
+                func = new Function<T>(name, impl, f);
+                GenFunction::function_registry[name] = func;
             }
+            in_register_function = false;
+            return *func;
         }
+
+        /* static Function<R(ArgTypes...)>& register_function(const std::string& name, std::function<R(ArgTypes...)> f){ */
+        /*     return Function<R(ArgTypes...)>::register_function(name, f, "N/A"); */
+        /* } */
 };
 
+
 /**
  * In order to enable proper provenance tracking, and at the same time keep
  * the ability to embed functions into values, the Function class should be
@@ -104,7 +135,6 @@ class GenFunction {
  * user to find where that function is defined in the source code to inspect
  * what it is doing. But hopefully this isn't too onerous by just using grep.
  */
-template<typename> class Function; // undefined
 template <typename R, typename... ArgTypes>
 class Function<R(ArgTypes...)> : public GenFunction {
     private:
@@ -112,16 +142,23 @@ 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){ }
+          :GenFunction(name, impl), f(f){
+            if (!in_register_function) {
+                WARNING("Don't instantiate Function objects directly! Use register_function instead.");
+            }
+          }
         Function(const std::string& name, std::function<R(ArgTypes...)> f)
           :Function(name, "N/A", f){ }
+        ~Function() { }
 
         R operator()(ArgTypes ...args){
             return f(args...);
         }
+
 };
 
-#define FUNC(t, n, f) Function<t>(n, #f, f)
+
+#define FUNC(f) f, #f
 
 /**
  * A type-agnostic value.
@@ -386,7 +423,7 @@ class Pair : public DerivedValue<std::pair<T1, T2> >{
 template <typename R, typename T>
 class ZipMapFour : public DerivedValue<std::vector<R> >{
     private:
-        Function<R(T, T, T, T)> f;
+        Function<R(T, T, T, T)>& f;
         Value<std::vector<T> >* v1;
         Value<std::vector<T> >* v2;
         Value<std::vector<T> >* v3;
@@ -407,13 +444,13 @@ class ZipMapFour : public DerivedValue<std::vector<R> >{
         }
 
     public:
-        ZipMapFour(Function<R(T, T, T, T)> f,
+        ZipMapFour(Function<R(T, T, T, T)>& f,
                    Value<std::vector<T> >* v1, Value<std::vector<T> >* v2,
                    Value<std::vector<T> >* v3, Value<std::vector<T> >* v4)
           :DerivedValue<std::vector<R> >("zipmap("+f.get_name()+":"+v1->get_name()+","+v2->get_name()+","+v3->get_name()+","+v4->get_name()+")"),
            f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
 
-        ZipMapFour(Function<R(T, T, T, T)> f,
+        ZipMapFour(Function<R(T, T, T, T)>* f,
                    const std::string &label1, const std::string &label2,
                    const std::string &label3, const std::string &label4)
           :ZipMapFour(f,
@@ -432,17 +469,17 @@ class ZipMapFour : public DerivedValue<std::vector<R> >{
 template <typename T>
 class Reduce : public DerivedValue<T>{
     private:
-        Function<T(std::vector<T>)> reduce;
+        Function<T(std::vector<T>)>& reduce;
         Value<std::vector<T> >* v;
         void update_value(){
             this->value = reduce(v->get_value());
         }
     public:
-        Reduce(Function<T(std::vector<T>)> reduce, Value<std::vector<T> >* v)
+        Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v)
           :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")"),
            reduce(reduce), v(v) { }
 
-        Reduce(Function<T(std::vector<T>)> reduce, const std::string& v_name)
+        Reduce(Function<T(std::vector<T>)>& reduce, const std::string& v_name)
           :Reduce(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name))) { }
 };
 
@@ -453,9 +490,10 @@ template <typename T>
 class Max : public Reduce<T>{
     public:
         Max(const std::string& v_name)
-          :Reduce<T>(Function<T(std::vector<T>)>("max", [](std::vector<T> vec){
-                         return *std::max_element(vec.begin(), vec.end());}),
-                     v_name) { }
+          :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
+                      FUNC(([](std::vector<T> vec){
+                          return *std::max_element(vec.begin(), vec.end());}))),
+                      v_name) { }
 };
 
 /**
@@ -465,7 +503,7 @@ template <typename T>
 class Min : public Reduce<T>{
     public:
         Min(const std::string& v_name)
-          :Reduce<T>(Function<T(std::vector<T>)>("min", [](std::vector<T> vec){
+          :Reduce<T>(new Function<T(std::vector<T>)>("min", [](std::vector<T> vec){
                          return *std::min_element(vec.begin(), vec.end());}),
                      v_name) { }
 };
@@ -477,7 +515,7 @@ template <typename T>
 class Mean : public Reduce<T>{
     public:
         Mean(const std::string& v_name)
-          :Reduce<T>(Function<T(std::vector<T>)>("mean", [](std::vector<T> vec){
+          :Reduce<T>(new Function<T(std::vector<T>)>("mean", [](std::vector<T> vec){
                         int n = 0; T sum = 0;
                         for (T e : vec){ n++; sum += e; }
                         return n>0 ? sum / n : 0; }),
@@ -491,7 +529,7 @@ template <typename T>
 class ElementOf : public Reduce<T>{
     public:
         ElementOf(Value<int>* index, const std::string& v_name)
-          :Reduce<T>(Function<T(std::vector<T>)>("elementOf", [index](std::vector<T> vec){return vec[index->get_value()];}),
+          :Reduce<T>(new Function<T(std::vector<T>)>("elementOf", [index](std::vector<T> vec){return vec[index->get_value()];}),
                      v_name) { }
         ElementOf(const std::string& name, int index, const std::string& v_name)
           :Reduce<T>(name, [index](std::vector<T> vec){return vec[index];}, v_name) { }
@@ -505,17 +543,17 @@ class ElementOf : public Reduce<T>{
 template <typename T>
 class ReduceIndex : public DerivedValue<std::pair<T, int> >{
     private:
-        Function<std::pair<T,int>(std::vector<T>)> reduce;
+        Function<std::pair<T,int>(std::vector<T>)>& reduce;
         Value<std::vector<T> >* v;
         void update_value(){
             this->value = reduce(v->get_value());
         }
     public:
-        ReduceIndex(Function<std::pair<T,int>(std::vector<T>)> reduce, Value<std::vector<T> >* v)
+        ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v)
           :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")"),
            reduce(reduce), v(v) { }
 
-        ReduceIndex(Function<std::pair<T,int>(std::vector<T>)> reduce, const std::string& v_name)
+        ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, const std::string& v_name)
           :ReduceIndex(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name))) { }
 };
 
@@ -526,10 +564,11 @@ template <typename T>
 class MaxIndex : public ReduceIndex<T>{
     public:
         MaxIndex(const std::string& v_name)
-          :ReduceIndex<T>(Function<T(std::vector<T>)>("maxIndex", [](std::vector<T> vec){
-                              auto elptr = std::max_element(vec.begin(), vec.end());
-                              return std::pair<T,int>(*elptr, int(elptr-vec.begin()));}),
-                          v_name) { }
+          :ReduceIndex<T>(GenFunction::register_function<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())); }
+                          ))), v_name) { }
 };
 
 /**
@@ -539,33 +578,13 @@ template <typename T>
 class MinIndex : public ReduceIndex<T>{
     public:
         MinIndex(const std::string& v_name)
-          :ReduceIndex<T>(Function<T(std::vector<T>)>("minIndex", [](std::vector<T> vec){
-                              auto elptr = std::min_element(vec.begin(), vec.end());
-                              return std::pair<T,int>(*elptr, int(elptr-vec.begin()));}),
-                          v_name) { }
+          :ReduceIndex<T>(GenFunction::register_function<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())); }
+                          ))), v_name) { }
 };
 
-
-/**
- * A variadic
- */
-/* template <typename R, typename... T> */
-/* class MultiFunc : public DerivedValue<R>{ */
-/*     private: */
-/*         Function<R(T...)> f; */
-/*         std::tuple<T...> value_tuple; */
-
-/*         void update_value(){ */
-/*             this->value = f(value_tuple); */
-/*         } */
-
-/*     public: */
-/*         MultiFunc(const std::string& name, Function<R(std::tuple<T...>)> f, T... varargs) */
-/*           :DerivedValue<R>(name), */
-/*            f(f), */
-/*            value_tuple(varargs...){ } */
-/* }; */
-
 /**
  * A generic value owning only a function object.
  * All necessary values upon which this value depends must be bound to the
@@ -574,12 +593,12 @@ class MinIndex : public ReduceIndex<T>{
 template <typename T>
 class BoundValue : public DerivedValue<T>{
     protected:
-        Function<T()> f;
+        Function<T()>& f;
         void update_value(){
             this->value = f();
         }
     public:
-        BoundValue(Function<T()> f)
+        BoundValue(Function<T()>& f)
           :DerivedValue<T>(f.get_name()+"(<bound>)"),
            f(f) { }
 };

+ 24 - 1
filval_root/container.hpp

@@ -7,7 +7,7 @@
 #include "TGraph.h"
 #include <iostream>
 
-namespace filval::root {
+namespace fv::root {
 
 template <typename T>
 class ContainerTH1 : public Container<TH1>{
@@ -31,6 +31,17 @@ class ContainerTH1 : public Container<TH1>{
           :Container<TH1>(name, nullptr),
            title(title), nbins(nbins), low(low), high(high),
            value(dynamic_cast<Value<T>*>(value)) { }
+
+        void save_as(const std::string& fname) {
+            TCanvas* c1 = new TCanvas("c1");
+            container->Draw();
+            c1->Draw();
+            c1->SaveAs(fname.c_str());
+            delete c1;
+        }
+        virtual void save() {
+            save_as(this->get_name() + ".png");
+        }
 };
 
 class ContainerTH1D : public ContainerTH1<double>{
@@ -84,6 +95,16 @@ class ContainerTH2 : public Container<TH2>{
            nbins_x(nbins_x), low_x(low_x), high_x(high_x),
            nbins_y(nbins_y), low_y(low_y), high_y(high_y),
            value(dynamic_cast<Value<T>*>(value)) { }
+        void save_as(const std::string& fname) {
+            TCanvas* c1 = new TCanvas("c1");
+            container->Draw();
+            c1->Draw();
+            c1->SaveAs(fname.c_str());
+            delete c1;
+        }
+        virtual void save() {
+            save_as(this->get_name() + ".png");
+        }
 };
 
 class ContainerTH2D : public ContainerTH2<double>{
@@ -134,6 +155,8 @@ class ContainerTGraph : public Container<TGraph>{
             }
             return container;
         }
+        void save_as(const std::string& fname) { }
+        virtual void save() { }
 };
 
 }

+ 1 - 1
filval_root/filter.hpp

@@ -3,7 +3,7 @@
 #include "value.hpp"
 #include "TLorentzVector.h"
 
-namespace filval::root{
+namespace fv::root{
 
 class MassFilter : public Filter {
     private:

+ 1 - 1
filval_root/value.hpp

@@ -3,7 +3,7 @@
 #include "value.hpp"
 #include "TLorentzVector.h"
 
-namespace filval::root{
+namespace fv::root{
 
 class LorentzVector : public DerivedValue<TLorentzVector>{
     protected: