Browse Source

changes MapOver to no longer require template arguments to be wrapped in tuple

Caleb Fangmeier 7 years ago
parent
commit
2536eec791

+ 1 - 2
CMakeLists.txt

@@ -52,8 +52,7 @@ ENDIF(DOXYGEN_FOUND)
 FIND_PACKAGE(ROOT REQUIRED)
 INCLUDE_DIRECTORIES(SYSTEM ${ROOT_INCLUDE_DIR}
                            ${CMAKE_CURRENT_SOURCE_DIR}
-                           ${CMAKE_CURRENT_SOURCE_DIR}/filval
-                           ${CMAKE_CURRENT_SOURCE_DIR}/filval_root)
+                           )
 LINK_LIBRARIES(${ROOT_LIBRARIES})
 
 

+ 1 - 1
analysis/MiniTreeDataSet.hpp

@@ -81,7 +81,7 @@ class MiniTreeDataSet : public DataSet,
         template <typename T>
         WrapperVector<T>* track_branch_vec(const std::string& size_bname, const std::string& bname){
             track_branch_ptr<T>(bname);
-            return new WrapperVector<T>(size_bname, bname, bname);
+            return new WrapperVector<T>(lookup<int>(size_bname), lookup<T*>(bname), bname);
         }
 
         void save_all(){

+ 56 - 67
analysis/TTTT_Analysis.cpp

@@ -39,22 +39,13 @@
 #include <tuple>
 #include <utility>
 
-#include "filval.hpp"
-#include "filval_root.hpp"
+#include "filval/filval.hpp"
+#include "filval_root/filval_root.hpp"
 
 #include "MiniTreeDataSet.hpp"
 
 using namespace std;
 using namespace fv;
-using namespace fv::root;
-using namespace fv::util;
-
-GenValue* lookup(const string& name){
-    return GenValue::get_value(name);
-}
-Filter* lookup_filter(const string& name){
-    return dynamic_cast<Filter*>(GenValue::get_value(name));
-}
 
 void enable_branches(MiniTreeDataSet& mt){
     mt.fChain->SetBranchStatus("*", false);
@@ -84,87 +75,85 @@ void enable_branches(MiniTreeDataSet& mt){
     mt.track_branch<int>("nVert");
 }
 
+
 void declare_values(MiniTreeDataSet& mt){
-    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();
-            })));
 
-    new ZipMapFour<float, float>(get_energy, "LepGood_pt", "LepGood_eta", "LepGood_phi", "LepGood_mass",
-                                 "lepton_energy");
-
-    typedef tuple<float,float,float,float> PtEtaPhiM;
-    auto& get_energy2 = GenFunction::register_function<float(PtEtaPhiM)>("get_energy",
-            FUNC(([](PtEtaPhiM ptetaphim){
-                float pt, eta, phi, m;
-                tie(pt, eta, phi, m) = ptetaphim;
-                TLorentzVector t;
-                t.SetPtEtaPhiM(pt, eta, phi, m);
-                return t.E();
+    auto& get_energy = GenFunction::register_function<float(float, float, float, float)>("get_energy",
+            FUNC(([](float pt, float eta, float phi, float mass){
+                TLorentzVector lv;
+                lv.SetPtEtaPhiM(pt, eta, phi, mass);
+                return lv.E();
             })));
 
-    new Zip<float,float,float,float>(dynamic_cast<Value<vector<float>>*>(lookup("LepGood_pt")),
-                                     dynamic_cast<Value<vector<float>>*>(lookup("LepGood_eta")),
-                                     dynamic_cast<Value<vector<float>>*>(lookup("LepGood_phi")),
-                                     dynamic_cast<Value<vector<float>>*>(lookup("LepGood_mass")),
-                                     "lepton_kinematics");
+    /* lorentz_vectors("LepGood_pt", "LepGood_eta", "LepGood_phi", "LepGood_mass", "LepGood_4v") */
+    auto lk = zip<float,float,float,float>(lookup<vector<float>>("LepGood_pt"),
+                                           lookup<vector<float>>("LepGood_eta"),
+                                           lookup<vector<float>>("LepGood_phi"),
+                                           lookup<vector<float>>("LepGood_mass"),
+                                           "lepton_kinematics");
+    map_over(get_energy, lk, "lepton_energy");
 
-    new Pair<vector<float>,vector<float>>("lepton_energy", "LepGood_pt", "lepton_energy_lepton_pt");
+    fv::pair<vector<float>,vector<float>>("lepton_energy", "LepGood_pt", "lepton_energy_lepton_pt");
 
-    new Max<float>("lepton_energy", "lepton_energy_max");
-    new Min<float>("lepton_energy", "lepton_energy_min");
-    new Range<float>("lepton_energy", "lepton_energy_range");
-    new Mean<float>("lepton_energy", "lepton_energy_mean");
+    max<float>("lepton_energy", "lepton_energy_max");
+    min<float>("lepton_energy", "lepton_energy_min");
+    range<float>("lepton_energy", "lepton_energy_range");
+    mean<float>("lepton_energy", "lepton_energy_mean");
 
-    new Count<float>(GenFunction::register_function<bool(float)>("bJet_Selection", FUNC(([](float x){return x>0;}))),
+    count<float>(GenFunction::register_function<bool(float)>("bJet_Selection", FUNC(([](float x){return x>0;}))),
                      "Jet_btagCMVA",  "b_jet_count");
 
-    
-
-
-    new Filter("trilepton", FUNC(([nLepGood=lookup("nLepGood")](){
-            return dynamic_cast<Value<int>*>(nLepGood)->get_value() == 3;})));
+    filter("trilepton", FUNC(([nLepGood=lookup<int>("nLepGood")](){
+                return dynamic_cast<Value<int>*>(nLepGood)->get_value() == 3;})));
 
-    new Filter("os-dilepton", FUNC(([LepGood_charge=lookup("LepGood_charge")](){
-                    auto& charges = static_cast<Value<vector<int>>*>(LepGood_charge)->get_value();
-                    return charges.size()==2 && (charges[0] != charges[1]);})));
+    filter("os-dilepton", FUNC(([LepGood_charge=lookup<vector<int>>("LepGood_charge")](){
+               auto& charges = LepGood_charge->get_value();
+               return charges.size()==2 && (charges[0] != charges[1]);})));
 
-    new Filter("ss-dilepton", FUNC(([LepGood_charge=lookup("LepGood_charge")](){
-                    auto& charges = static_cast<Value<vector<int>>*>(LepGood_charge)->get_value();
-                    return charges.size()==2 && (charges[0] == charges[1]);})));
+    filter("ss-dilepton", FUNC(([LepGood_charge=lookup<vector<int>>("LepGood_charge")](){
+               auto& charges = LepGood_charge->get_value();
+               return charges.size()==2 && (charges[0] == charges[1]); })));
 
 }
 
 void declare_containers(MiniTreeDataSet& mt){
-    mt.register_container(new ContainerTH1<int>("lepton_count", "Lepton Multiplicity", lookup("nLepGood"), 8, 0, 8));
-    mt.register_container(new ContainerTH1<int>("top_quark_count", "Top Quark Multiplicity", lookup("nGenTop"), 8, 0, 8));
+    mt.register_container(new ContainerTH1<int>("lepton_count", "Lepton Multiplicity", lookup<int>("nLepGood"), 8, 0, 8));
+    mt.register_container(new ContainerTH1<int>("top_quark_count", "Top Quark Multiplicity", lookup<int>("nGenTop"), 8, 0, 8));
 
-    mt.register_container(new ContainerTH1Many<float>("lepton_energy_all", "Lepton Energy - All", lookup("lepton_energy"), 50, 0, 500));
-    mt.register_container(new ContainerTH1<float>("lepton_energy_max", "Lepton Energy - Max", lookup("lepton_energy_max"), 50, 0, 500));
-    mt.register_container(new ContainerTH1<float>("lepton_energy_min", "Lepton Energy - Min", lookup("lepton_energy_min"), 50, 0, 500));
-    mt.register_container(new ContainerTH1<float>("lepton_energy_rng", "Lepton Energy - Range", lookup("lepton_energy_range"), 50, 0, 500));
+    mt.register_container(new ContainerTH1Many<float>("lepton_energy_all", "Lepton Energy - All",
+                                                      lookup<vector<float>>("lepton_energy"), 50, 0, 500));
+    mt.register_container(new ContainerTH1<float>("lepton_energy_max", "Lepton Energy - Max",
+                                                  lookup<float>("lepton_energy_max"), 50, 0, 500));
+    mt.register_container(new ContainerTH1<float>("lepton_energy_min", "Lepton Energy - Min",
+                                                  lookup<float>("lepton_energy_min"), 50, 0, 500));
+    mt.register_container(new ContainerTH1<float>("lepton_energy_rng", "Lepton Energy - Range",
+                                                  lookup<float>("lepton_energy_range"), 50, 0, 500));
 
 
-    mt.register_container(new ContainerTGraph("nLepvsnJet", "Number of Leptons vs Number of Jets", new Pair<int, int>("nLepGood", "nJet") ));
+    mt.register_container(new ContainerTGraph("nLepvsnJet", "Number of Leptons vs Number of Jets",
+                                              fv::pair<int, int>("nLepGood", "nJet") ));
 
-    mt.register_container(new ContainerTH2Many<float>("lepton_energy_vs_pt", "Lepton Energy - Range", lookup("lepton_energy_lepton_pt"),
-                                                50, 0, 500, 50, 0, 500));
+    mt.register_container(new ContainerTH2Many<float>("lepton_energy_vs_pt", "Lepton Energy - Range",
+                                                      lookup<std::pair<std::vector<float>,std::vector<float>>>("lepton_energy_lepton_pt"),
+                                                      50, 0, 500, 50, 0, 500));
 
-    mt.register_container(new ContainerTH1<int>("b_jet_count", "B-Jet Multiplicity", lookup("b_jet_count"), 10, 0, 10));
+    mt.register_container(new ContainerTH1<int>("b_jet_count", "B-Jet Multiplicity", lookup<int>("b_jet_count"), 10, 0, 10));
 
 
-    mt.register_container(new ContainerTH1<int>("jet_count_os_dilepton", "Jet Multiplicity - OS Dilepton Events", lookup("nJet"), 14, 0, 14));
+    mt.register_container(new ContainerTH1<int>("jet_count_os_dilepton", "Jet Multiplicity - OS Dilepton Events",
+                                                lookup<int>("nJet"), 14, 0, 14));
     mt.get_container("jet_count_os_dilepton")->add_filter(lookup_filter("os-dilepton"));
-    mt.register_container(new ContainerTH1<int>("jet_count_ss_dilepton", "Jet Multiplicity - SS Dilepton Events", lookup("nJet"), 14, 0, 14));
+    mt.register_container(new ContainerTH1<int>("jet_count_ss_dilepton", "Jet Multiplicity - SS Dilepton Events",
+                lookup<int>("nJet"), 14, 0, 14));
     mt.get_container("jet_count_ss_dilepton")->add_filter(lookup_filter("ss-dilepton"));
-    mt.register_container(new ContainerTH1<int>("jet_count_trilepton", "Jet Multiplicity - Trilepton Events",     lookup("nJet"), 14, 0, 14));
+    mt.register_container(new ContainerTH1<int>("jet_count_trilepton", "Jet Multiplicity - Trilepton Events",
+                lookup<int>("nJet"), 14, 0, 14));
     mt.get_container("jet_count_trilepton")->add_filter(lookup_filter("trilepton"));
 
-    mt.register_container(new ContainerTH1<int>("primary_vert_count", "Number of Primary Vertices", lookup("nVert"), 50, 0, 50));
+    mt.register_container(new ContainerTH1<int>("primary_vert_count", "Number of Primary Vertices",
+                lookup<int>("nVert"), 50, 0, 50));
 
-    mt.register_container(new CounterMany<int>("GenTop_pdg_id", lookup("GenTop_pdgId")));
+    mt.register_container(new CounterMany<int>("GenTop_pdg_id", lookup<vector<int>>("GenTop_pdgId")));
 }
 
 
@@ -173,7 +162,7 @@ void run_analysis(const std::string& input_filename, bool silent){
         return input.substr(0, input.find_last_of(".")) + new_suffix;
     };
     string log_filename = replace_suffix(input_filename, "_result.log");
-    Log::init_logger(log_filename, LogPriority::kLogDebug);
+    fv::util::Log::init_logger(log_filename, fv::util::LogPriority::kLogDebug);
 
     string output_filename = replace_suffix(input_filename, "_result.root");
     MiniTreeDataSet mt(input_filename, output_filename);
@@ -188,7 +177,7 @@ void run_analysis(const std::string& input_filename, bool silent){
 
 int main(int argc, char * argv[])
 {
-    ArgParser args(argc, argv);
+    fv::util::ArgParser args(argc, argv);
     if(!args.cmdOptionExists("-f")) {
         cout << "Usage: ./main -f input_minitree.root" << endl;
         return -1;

+ 101 - 0
filval/api.hpp

@@ -0,0 +1,101 @@
+#ifndef API_HPP
+#define API_HPP
+#include <string>
+#include <vector>
+#include "filval/value.hpp"
+namespace fv{
+
+    template<typename T>
+    Value<T>* lookup(const std::string& name){
+        GenValue* gv = GenValue::get_value(name);
+        Value<T>* tv = dynamic_cast<Value<T>*>(gv);
+        if(tv == nullptr){
+            CRITICAL("Value: "+gv->get_name() + "has improper type.",-1);
+        }
+        return tv;
+    }
+
+    Filter* lookup_filter(const std::string& name){
+        Filter* f =  dynamic_cast<Filter*>(GenValue::get_value(name));
+        if(f == nullptr){
+            CRITICAL("Filter: "+f->get_name() + "has improper type.",-1);
+        }
+        return f;
+    }
+
+    template <typename... ArgTypes>
+    Zip<ArgTypes...>* zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias=""){
+        return new Zip<ArgTypes...>(args..., alias);
+    }
+
+    template <typename T1, typename T2>
+    Pair<T1, T2>* pair(Value<T1>* val1, Value<T2>* val2, const std::string& alias=""){
+        return new Pair<T1,T2>(val1, val2, alias);
+    }
+
+    template <typename T1, typename T2>
+    Pair<T1, T2>* pair(const std::string& name1, const std::string& name2, const std::string& alias=""){
+        return pair<T1,T2>(lookup<T1>(name1), lookup<T2>(name2), alias);
+    }
+
+    template <typename Ret, typename... ArgTypes>
+    MapOver<Ret(ArgTypes...)>* map_over(Function<Ret(ArgTypes...)>& fn,
+                                        Zip<ArgTypes...>* arg, const std::string& alias=""){
+        return new MapOver<Ret(ArgTypes...)>(fn, arg, alias);
+    }
+
+    template <typename T>
+    Max<T>* max(Value<std::vector<T>>* v, const std::string alias){
+        return new Max<T>(v, alias);
+    }
+
+    template <typename T>
+    Max<T>* max(const std::string& v_name, const std::string alias){
+        return max(lookup<std::vector<T>>(v_name), alias);
+    }
+
+    template <typename T>
+    Min<T>* min(Value<std::vector<T>>* v, const std::string alias){
+        return new Min<T>(v, alias);
+    }
+
+    template <typename T>
+    Min<T>* min(const std::string& v_name, const std::string alias){
+        return min(lookup<std::vector<T>>(v_name), alias);
+    }
+
+    template <typename T>
+    Range<T>* range(Value<std::vector<T>>* v, const std::string alias){
+        return new Range<T>(v, alias);
+    }
+
+    template <typename T>
+    Range<T>* range(const std::string& v_name, const std::string alias){
+        return range(lookup<std::vector<T>>(v_name), alias);
+    }
+
+    template <typename T>
+    Mean<T>* mean(Value<std::vector<T>>* v, const std::string alias){
+        return new Mean<T>(v, alias);
+    }
+
+    template <typename T>
+    Mean<T>* mean(const std::string& v_name, const std::string alias){
+        return mean(lookup<std::vector<T>>(v_name), alias);
+    }
+
+    template <typename T>
+    Count<T>* count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias){
+        return new Count<T>(selector, v, alias);
+    }
+
+    template <typename T>
+    Count<T>* count(Function<bool(T)>& selector, const std::string& v_name, const std::string alias){
+        return count<T>(selector, lookup<std::vector<T>>(v_name), alias);
+    }
+
+    Filter* filter(const std::string& name, std::function<bool()> filter_function, const std::string& impl=""){
+        return new Filter(name, filter_function, impl);
+    }
+}
+#endif // API_HPP

+ 1 - 0
filval/filval.hpp

@@ -8,4 +8,5 @@
 #include "dataset.hpp"
 #include "log.hpp"
 #include "argparse.hpp"
+#include "api.hpp"
 #endif // filval_hpp

+ 108 - 159
filval/value.hpp

@@ -60,7 +60,32 @@
  */
 namespace fv{
 
-/* bool in_register_function = false; */
+template <typename F, typename Tuple, bool Done, int Total, int... N>
+struct call_impl
+{
+    static auto call(F f, Tuple && t)
+    {
+        return call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<Tuple>(t));
+    }
+};
+
+template <typename F, typename Tuple, int Total, int... N>
+struct call_impl<F, Tuple, true, Total, N...>
+{
+    static auto call(F f, Tuple && t)
+    {
+        return f(std::get<N>(std::forward<Tuple>(t))...);
+    }
+};
+
+// This calls a function of type F with the contents of the tuple as arguments
+template <typename F, typename Tuple>
+auto call(F f, Tuple && t)
+{
+    typedef typename std::decay<Tuple>::type ttype;
+    return call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
+}
+
 template<typename> class Function; // undefined
 /**
  * Parent class to all Function classes. Holds a class-level collection of all
@@ -81,7 +106,8 @@ class GenFunction {
         inline static std::map<const std::string, GenFunction*> function_registry;
 
         GenFunction(const std::string& name, const std::string& impl)
-          :impl(impl), name(name){ }
+          :name(name),
+           impl(impl){ }
 
         virtual ~GenFunction() { };
 
@@ -215,16 +241,6 @@ class GenValue{
          */
         inline static std::map<const std::string, GenValue*> aliases;
 
-        /**
-         * This function serves to check that this Value has been created with
-         * real, i.e. non null, arguments. This is to avoid segfaulting when a
-         * dynamic_cast fails. If no checks need to be made, simple override
-         * this method with a no-op. If checks fail, the function should
-         * utilize the CRITICAL macro with a meaningfull error message stating
-         * what failed and especially the name of the current value.
-         */
-        virtual void verify_integrity() = 0;
-
     public:
         GenValue(const std::string& name, const std::string& alias)
           :name(name){
@@ -237,9 +253,17 @@ class GenValue{
             return name;
         }
 
+        void set_name(const std::string& new_name){
+            values[name] = nullptr;
+            name = new_name;
+            values[name] = this;
+        }
+
         static void reset(){
             for (auto val : values){
-                val.second->_reset();
+                if (val.second != nullptr){
+                    val.second->_reset();
+                }
             }
         }
 
@@ -333,11 +357,6 @@ class ObservedValue : public Value<T>{
         T *val_ref;
         void _reset(){ }
 
-        void verify_integrity() {
-            if (val_ref == nullptr)
-                CRITICAL("ObservedValue " << this->get_name() << " created with null pointer",-1);
-        }
-
     public:
         ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
           :Value<T>(name, alias),
@@ -388,6 +407,7 @@ class DerivedValue : public Value<T>{
            value_valid(false) { }
 
         T& get_value(){
+            /* std::cout << "getting value of " << this->get_name() << std::endl; */
             if (!value_valid){
                 update_value();
                 value_valid = true;
@@ -418,21 +438,10 @@ class WrapperVector : public DerivedValue<std::vector<T> >{
             this->value.assign(data_ref, data_ref+n);
         }
 
-        void verify_integrity() {
-            if (size == nullptr)
-                CRITICAL("WrapperVector " << this->get_name() << " created with invalid size.",-1);
-            if (data == nullptr)
-                CRITICAL("WrapperVector " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
         WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
           :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
            size(size), data(data){ }
-
-        WrapperVector(const std::string &label_size, const std::string &label_data, const std::string& alias="")
-          :WrapperVector(dynamic_cast<Value<int>*>(GenValue::get_value(label_size)),
-                         dynamic_cast<Value<T*>*>(GenValue::get_value(label_data)), alias) { }
 };
 
 /**
@@ -447,21 +456,10 @@ class Pair : public DerivedValue<std::pair<T1, T2> >{
             this->value.second = value_pair.second->get_value();
         }
 
-        void verify_integrity() {
-            if (value_pair.first == nullptr)
-                CRITICAL("Pair " << this->get_name() << " created with invalid first value.",-1);
-            if (value_pair.second == nullptr)
-                CRITICAL("Pair " << this->get_name() << " created with invalid second value.",-1);
-        }
-
     public:
         Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
           :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
            value_pair(value1, value2){ }
-        Pair(const std::string& label1, const std::string& label2, const std::string alias="")
-          :Pair(dynamic_cast<Value<T1>*>(GenValue::get_value(label1)),
-                dynamic_cast<Value<T1>*>(GenValue::get_value(label2)),
-                alias){ }
 };
 
 template<typename... T> class _Zip;
@@ -476,6 +474,15 @@ class _Zip<> {
         std::tuple<> _get_at(int idx){
             return std::make_tuple();
         }
+
+        bool _verify_integrity() {
+            return true;
+         }
+
+        std::string _get_name(){
+            return "";
+        }
+
     public:
         _Zip() { }
 };
@@ -495,6 +502,15 @@ class _Zip<Head, Tail...> : private _Zip<Tail...> {
             auto tail_tuple = _Zip<Tail...>::_get_at(idx);
             return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
         }
+
+        bool _verify_integrity() {
+            return (head != nullptr) &&_Zip<Tail...>::_verify_integrity();
+         }
+
+        std::string _get_name(){
+            return head->get_name()+","+_Zip<Tail...>::_get_name();
+        }
+
     public:
         _Zip() { }
 
@@ -511,7 +527,6 @@ class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
              private _Zip<ArgTypes...>{
     protected:
         void update_value(){
-            /* auto tuple_of_vectors this->_get_value(); */
             this->value.clear();
             int size = _Zip<ArgTypes...>::_get_size();
             for(int i=0; i<size; i++){
@@ -519,15 +534,37 @@ class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
             }
         }
 
-        /**
-         * /todo Implement this.
-         */
-        void verify_integrity() { }
+        std::string _get_name(){
+            return "zip("+_Zip<ArgTypes...>::_get_name()+")";
+        }
 
     public:
-        Zip(Value<std::vector<ArgTypes>>*... args, const std::string alias="")
-          :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("a kickin zip", ""),
-           _Zip<ArgTypes...>(args...) { }
+        Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
+          :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
+           _Zip<ArgTypes...>(args...) {
+            this->set_name(_get_name());
+        }
+};
+
+template<typename> class MapOver; // undefined
+template <typename Ret, typename... ArgTypes>
+class MapOver<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
+    private:
+        Function<Ret(ArgTypes...)>& fn;
+        Zip<ArgTypes...>* arg;
+
+        void update_value(){
+            this->value.clear();
+            for(auto tup : arg->get_value()){
+                this->value.push_back(call(fn,tup));
+            }
+        }
+
+    public:
+        MapOver(Function<Ret(ArgTypes...)>& fn, Zip<ArgTypes...>* arg, const std::string& alias)
+          :DerivedValue<std::vector<Ret>>("map_over("+fn.get_name()+":"+arg->get_name()+")", alias),
+           fn(fn), arg(arg){ }
+
 };
 
 /**
@@ -566,28 +603,17 @@ class ZipMapFour : public DerivedValue<std::vector<R> >{
             }
         }
 
-        void verify_integrity() {
-            if (v1 == nullptr)
-                CRITICAL("ZipMapFour " << this->get_name() << " created with invalid first value.",-1);
-            if (v2 == nullptr)
-                CRITICAL("ZipMapFour " << this->get_name() << " created with invalid second value.",-1);
-            if (v3 == nullptr)
-                CRITICAL("ZipMapFour " << this->get_name() << " created with invalid third value.",-1);
-            if (v4 == nullptr)
-                CRITICAL("ZipMapFour " << this->get_name() << " created with invalid fourth value.",-1);
-        }
-
     public:
         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, const std::string alias="")
+                   Value<std::vector<T> >* v3, Value<std::vector<T> >* v4, const std::string alias)
           :DerivedValue<std::vector<R> >("zipmap("+f.get_name()+":"+v1->get_name()+","+v2->get_name()+","+
                                                                     v3->get_name()+","+v4->get_name()+")", alias),
            f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
 
         ZipMapFour(Function<R(T, T, T, T)>& f,
                    const std::string& label1, const std::string& label2,
-                   const std::string& label3, const std::string& label4, const std::string alias="")
+                   const std::string& label3, const std::string& label4, const std::string alias)
           :ZipMapFour(f,
                       dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label1)),
                       dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label2)),
@@ -613,18 +639,10 @@ class Count : public DerivedValue<int>{
             }
         }
 
-        void verify_integrity() {
-            if (v == nullptr)
-                CRITICAL("Count " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias="")
+        Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
           :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
            selector(selector), v(v) { }
-
-        Count(Function<bool(T)>& selector, const std::string& v_name, const std::string alias="")
-          :Count(selector, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
 };
 
 
@@ -643,21 +661,13 @@ class Reduce : public DerivedValue<T>{
             this->value = reduce(v->get_value());
         }
 
-        virtual void verify_integrity() {
-            if (v == nullptr)
-                CRITICAL("Reduce " << this->get_name() << " created with invalid value.",-1);
-        }
-
     protected:
         Value<std::vector<T> >* v;
 
     public:
-        Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
+        Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
           :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
            reduce(reduce), v(v) { }
-
-        Reduce(Function<T(std::vector<T>)>& reduce, const std::string& v_name, const std::string alias="")
-          :Reduce(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
 };
 
 /**
@@ -665,17 +675,12 @@ class Reduce : public DerivedValue<T>{
  */
 template <typename T>
 class Max : public Reduce<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("Max " << this->get_name() << " created with invalid value.",-1);
-        }
     public:
-        Max(const std::string& v_name, const std::string alias="")
+        Max(Value<std::vector<T>>* v, const std::string alias)
           :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, alias) { }
+                      v, alias) { }
 };
 
 /**
@@ -683,17 +688,12 @@ class Max : public Reduce<T>{
  */
 template <typename T>
 class Min : public Reduce<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("Min " << this->get_name() << " created with invalid value.",-1);
-        }
     public:
-        Min(const std::string& v_name, const std::string alias="")
+        Min(Value<std::vector<T>>* v, const std::string alias)
           :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
                       FUNC(([](std::vector<T> vec){
                          return *std::min_element(vec.begin(), vec.end());}))),
-                     v_name, alias) { }
+                     v, alias) { }
 };
 
 /**
@@ -701,20 +701,14 @@ class Min : public Reduce<T>{
  */
 template <typename T>
 class Mean : public Reduce<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("Mean " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        Mean(const std::string& v_name, const std::string alias="")
+        Mean(Value<std::vector<T>>* v, const std::string alias)
           :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
                       FUNC(([](std::vector<T> vec){
                         int n = 0; T sum = 0;
                         for (T e : vec){ n++; sum += e; }
                         return n>0 ? sum / n : 0; }))),
-                     v_name, alias) { }
+                     v, alias) { }
 };
 
 /**
@@ -722,19 +716,13 @@ class Mean : public Reduce<T>{
  */
 template <typename T>
 class Range : public Reduce<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("Range " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        Range(const std::string& v_name, const std::string alias="")
+        Range(Value<std::vector<T>>* v, const std::string alias)
           :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
                       FUNC(([](std::vector<T> vec){
                         auto minmax = std::minmax_element(vec.begin(), vec.end());
                         return (*minmax.second) - (*minmax.first); }))),
-                     v_name, alias) { }
+                     v, alias) { }
 };
 
 /**
@@ -742,19 +730,11 @@ class Range : public Reduce<T>{
  */
 template <typename T>
 class ElementOf : public Reduce<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("ElementOf " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        ElementOf(Value<int>* index, const std::string& v_name, const std::string alias="")
+        ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
           :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
-                      FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
-                     v_name, alias) { }
-        ElementOf(const std::string& name, int index, const std::string& v_name, const std::string alias="")
-          :Reduce<T>(name, [index](std::vector<T> vec){return vec[index];}, v_name, alias) { }
+                     FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
+                     v, alias) { }
 };
 
 /**
@@ -772,18 +752,10 @@ class ReduceIndex : public DerivedValue<std::pair<T, int> >{
             this->value = reduce(v->get_value());
         }
 
-        virtual void verify_integrity() {
-            if (v == nullptr)
-                CRITICAL("ReduceIndex " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
         ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
           :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
            reduce(reduce), v(v) { }
-
-        ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, const std::string& v_name, const std::string alias="")
-          :ReduceIndex(reduce, dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(v_name)), alias) { }
 };
 
 /**
@@ -791,19 +763,13 @@ class ReduceIndex : public DerivedValue<std::pair<T, int> >{
  */
 template <typename T>
 class MaxIndex : public ReduceIndex<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("MaxIndex " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        MaxIndex(const std::string& v_name, const std::string alias="")
+        MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
           :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
-                      FUNC(([](std::vector<T> vec){
+                          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, alias) { }
+                               return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
+                          v, alias) { }
 };
 
 /**
@@ -811,19 +777,13 @@ class MaxIndex : public ReduceIndex<T>{
  */
 template <typename T>
 class MinIndex : public ReduceIndex<T>{
-    private:
-        void verify_integrity() {
-            if (this->v == nullptr)
-                CRITICAL("MinIndex " << this->get_name() << " created with invalid value.",-1);
-        }
-
     public:
-        MinIndex(const std::string& v_name, const std::string alias="")
+        MinIndex(Value<std::vector<T>>* v, const std::string alias="")
           :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
-                      FUNC(([](std::vector<T> vec){
+                          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, alias) { }
+                               return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
+                          v, alias) { }
 };
 
 /**
@@ -833,8 +793,6 @@ class MinIndex : public ReduceIndex<T>{
  */
 template <typename T>
 class BoundValue : public DerivedValue<T>{
-    private:
-        void verify_integrity() { }
     protected:
         Function<T()>& f;
         void update_value(){
@@ -852,12 +810,6 @@ class BoundValue : public DerivedValue<T>{
  */
 template <typename T>
 class PointerValue : public DerivedValue<T*>{
-    private:
-        void verify_integrity() {
-            if(this->value == nullptr)
-                CRITICAL("PointerValue " << this->get_name() << " created with null pointer",-1);
-        }
-
     protected:
         void update_value(){ }
 
@@ -873,9 +825,6 @@ class PointerValue : public DerivedValue<T*>{
  */
 template <typename T>
 class ConstantValue : public DerivedValue<T>{
-    private:
-        void verify_integrity() { }
-
     protected:
         void update_value(){ }
 

+ 24 - 0
filval_root/api.hpp

@@ -0,0 +1,24 @@
+#ifndef ROOT_API_HPP
+#define ROOT_API_HPP
+#include <string>
+#include <vector>
+#include <tuple>
+#include "filval/api.hpp"
+namespace fv{
+
+LorentzVectors* lorentz_vectors(Value<std::vector<float>>* pt, Value<std::vector<float>>* eta,
+                                Value<std::vector<float>>* phi, Value<std::vector<float>>* mass,
+                                const std::string& alias=""){
+    return new LorentzVectors(pt, eta, phi, mass, alias);
+}
+
+LorentzVectors* lorentz_vectors(const std::string& pt_name, const std::string& eta_name,
+                                const std::string& phi_name, const std::string& mass_name,
+                                const std::string& alias=""){
+    return lorentz_vectors(lookup<std::vector<float>>(pt_name), lookup<std::vector<float>>(eta_name),
+                           lookup<std::vector<float>>(phi_name), lookup<std::vector<float>>(mass_name),
+                           alias);
+}
+
+}
+#endif // ROOT_API_HPP

+ 9 - 9
filval_root/container.hpp

@@ -11,7 +11,7 @@
 #include "TH1.h"
 #include "TH2.h"
 
-#include "filval.hpp"
+#include "filval/container.hpp"
 
 namespace fv::root::util{
 
@@ -101,11 +101,11 @@ class _ContainerTH1 : public Container<TH1>{
         virtual void _do_fill() = 0;
 
     public:
-        explicit _ContainerTH1(const std::string &name, const std::string& title, GenValue *value,
+        explicit _ContainerTH1(const std::string &name, const std::string& title, Value<V>* value,
                                int nbins, double low, double high)
           :Container<TH1>(name, nullptr),
            title(title), nbins(nbins), low(low), high(high),
-           value(dynamic_cast<Value<V>*>(value)) { }
+           value(value) { }
 
         void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
             util::save_as(get_container(), fname, option);
@@ -161,13 +161,13 @@ class _ContainerTH2 : public Container<TH2>{
 
     public:
         explicit _ContainerTH2(const std::string& name, const std::string& title,
-                               GenValue* value,
+                               Value<std::pair<V, V>>* value,
                                int nbins_x, double low_x, double high_x,
                                int nbins_y, double low_y, double high_y)
           :Container<TH2>(name, nullptr),
            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<std::pair<V, V>>*>(value)) { }
+           value(value) { }
 
         void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
             util::save_as(get_container(), fname, option);
@@ -206,9 +206,9 @@ class ContainerTGraph : public Container<TGraph>{
             data_modified = true;
         }
     public:
-        ContainerTGraph(const std::string& name, const std::string& title, GenValue* value)
+        ContainerTGraph(const std::string& name, const std::string& title, Value<std::pair<int, int>>* value)
           :Container<TGraph>(name, new TGraph()),
-           value(dynamic_cast<Value<std::pair<int, int> >*>(value)),
+           value(value),
            data_modified(false){ }
 
         TGraph* get_container(){
@@ -232,9 +232,9 @@ class _Counter : public Container<std::map<D,int>>{
     protected:
         Value<V>* value;
     public:
-        explicit _Counter(const std::string& name, GenValue* value)
+        explicit _Counter(const std::string& name, Value<V>* value)
           :Container<std::map<D,int>>(name, new std::map<D,int>()),
-           value(dynamic_cast<Value<V>*>(value)) { }
+           value(value) { }
 
         void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
             std::string type_name = "std::map<"+fv::util::get_type_name(typeid(D))+",int>";

+ 2 - 2
filval_root/filval_root.hpp

@@ -1,6 +1,6 @@
 #ifndef filval_root_hpp
 #define filval_root_hpp
-#include "value.hpp"
-#include "container.hpp"
+#include "filval_root/value.hpp"
+#include "filval_root/container.hpp"
 /* #include "dataset.hpp" */
 #endif // filval_root_hpp

+ 25 - 58
filval_root/value.hpp

@@ -1,74 +1,41 @@
 #ifndef root_value_hpp
 #define root_value_hpp
-#include "value.hpp"
+#include "filval/value.hpp"
 #include "TLorentzVector.h"
 
 namespace fv::root{
 
-class LorentzVector : public DerivedValue<TLorentzVector>{
+class LorentzVectors : public DerivedValue<std::vector<TLorentzVector>>{
     protected:
-        Value<double> *pt;
-        Value<double> *eta;
-        Value<double> *phi;
-        Value<double> *m;
+        Value<std::vector<float>> *pt_val;
+        Value<std::vector<float>> *eta_val;
+        Value<std::vector<float>> *phi_val;
+        Value<std::vector<float>> *mass_val;
 
         void update_value(){
-            value.SetPtEtaPhiM(pt->get_value(), eta->get_value(), phi->get_value(), m->get_value());
-        }
-
-        void verify_integrity(){
-            if (pt == nullptr)
-                CRITICAL("LorentzVector " << this->get_name() << " created with invalid pt", -1);
-            if (eta == nullptr)
-                CRITICAL("LorentzVector " << this->get_name() << " created with invalid eta", -1);
-            if (phi == nullptr)
-                CRITICAL("LorentzVector " << this->get_name() << " created with invalid phi", -1);
-            if (m == nullptr)
-                CRITICAL("LorentzVector " << this->get_name() << " created with invalid mass", -1);
+            auto pt = pt_val->get_value();
+            auto eta = eta_val->get_value();
+            auto phi = phi_val->get_value();
+            auto mass = mass_val->get_value();
+            std::vector<int> sizes = {pt.size(), eta.size(), phi.size(), mass.size()};
+            int size = *std::min_element(sizes.begin(), sizes.end());
+            this->value.clear();
+            TLorentzVector lv;
+            for (int i =0; i<size; i++){
+                lv.SetPtEtaPhiM(pt[i], eta[i], phi[i], mass[i]);
+                this->value.push_back(lv);
+            }
         }
 
     public:
-        LorentzVector(const std::string& name,
-                      Value<double>* pt,
-                      Value<double>* eta,
-                      Value<double>* phi,
-                      Value<double>* m)
-          :DerivedValue<TLorentzVector>(name),
-           pt(pt), eta(eta),
-           phi(phi), m(m) { }
-
-        LorentzVector(const std::string& name,
-                      const std::string &pt_label,
-                      const std::string &eta_label,
-                      const std::string &phi_label,
-                      const std::string &m_label)
-          :LorentzVector(name,
-                         dynamic_cast<Value<double>*>(GenValue::get_value(pt_label)),
-                         dynamic_cast<Value<double>*>(GenValue::get_value(eta_label)),
-                         dynamic_cast<Value<double>*>(GenValue::get_value(phi_label)),
-                         dynamic_cast<Value<double>*>(GenValue::get_value(m_label))){ }
+        LorentzVectors(const std::string& name,
+                      Value<std::vector<float>>* pt,
+                      Value<std::vector<float>>* eta,
+                      Value<std::vector<float>>* phi,
+                      Value<std::vector<float>>* mass)
+          :DerivedValue<std::vector<TLorentzVector>>(name),
+           pt_val(pt), eta_val(eta), phi_val(phi), mass_val(mass) { }
 };
 
-class LorentzVectorEnergy : public DerivedValue<double>{
-    protected:
-        Value<TLorentzVector>* vector;
-        void update_value(){
-            value = vector->get_value().E();
-        }
-
-        void verify_integrity(){
-            if (vector == nullptr)
-                CRITICAL("LorentzVectorEnergy " << this->get_name() << " created with invalid vector", -1);
-        }
-
-    public:
-        LorentzVectorEnergy(const std::string& name, Value<TLorentzVector>* vector)
-          :DerivedValue<double>(name),
-           vector(vector){ }
-
-        LorentzVectorEnergy(const std::string& name, const std::string& vector_label)
-          :LorentzVectorEnergy(name,
-                               dynamic_cast<Value<TLorentzVector>*>(GenValue::get_value(vector_label))){ }
-};
 }
 #endif // root_value_hpp