Ver código fonte

New Features!

  - FunctionValue: used when you want a value that comes from a function
  w/ no arguments, rather than another value
  - Printer: Container class for printing values to an ostream
  - EfficiencyContainer: Container for results where you want to save
  the proportion of objects passing vs failing some criteria
Caleb Fangmeier 7 anos atrás
pai
commit
262525049e
4 arquivos alterados com 133 adições e 21 exclusões
  1. 14 0
      api.hpp
  2. 39 0
      container.hpp
  3. 57 5
      root/container.hpp
  4. 23 16
      value.hpp

+ 14 - 0
api.hpp

@@ -164,6 +164,7 @@ namespace fv{
             return (Value<type>*)new Apply<Ret(ArgType)>(fn, arg, alias);
     }
 
+
     template <typename Ret, typename... ArgTypes>
     decltype(auto)
     tup_apply(Function<Ret(ArgTypes...)>* fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias=""){
@@ -387,5 +388,18 @@ namespace fv{
         return GenFunction::reg_func(name, f, impl);
     }
 
+    template <typename Ret>
+    decltype(auto)
+    func_value(const std::string& name, std::function<Ret()> f, const std::string&& impl, const std::string& alias=""){
+        typedef Ret type;
+        const std::string& val_name = FunctionValue<Ret>::fmt_name(name);
+        if (check_exists<type>(val_name))
+            return lookup<type>(val_name);
+        else {
+            Function<Ret()>* fn = func(name, f, impl);
+            return (Value<type>*)new FunctionValue<Ret>(name, fn, alias);
+        }
+    }
+
 }
 #endif // API_HPP

+ 39 - 0
container.hpp

@@ -194,5 +194,44 @@ class ContainerMean : public Container<T,T>{
         }
 };
 
+template<typename T>
+std::ostream& operator<< (std::ostream & out, const std::vector<T>& data) {
+    size_t len = data.size();
+    if (len == 0) out << "[]";
+    else {
+        out << "[" << data[0];
+        for (size_t i=1; i<len; i++) out << ", " << data[i];
+        out << "]";
+    }
+    return out ;
+}
+
+/**
+ * Prints out the value registered to it
+ */
+template <typename T>
+class Printer : public Container<std::ostream, T>{
+    private:
+        void _fill(){
+            (*this->container) << "(" << this->get_name() << ")" << " "
+                               << this->value->get_value() << std::endl;
+        }
+    public:
+        Printer(const std::string& name, Value<T>* value, std::ostream* out)
+          :Container<std::ostream,T>(name, value){
+            this->container = out;
+        }
+
+        std::ostream* get_container(){
+            return this->container;
+        }
+
+        GenContainer* clone_as(const std::string& new_name){
+            return new Printer(new_name, this->value, this->container);
+        }
+
+        void save_as(const std::string&, const SaveOption&) { }
+};
+
 }
 #endif // container_hpp

+ 57 - 5
root/container.hpp

@@ -401,11 +401,8 @@ class CounterMany : public _Counter<std::vector<V>,V>{
 
 class PassCount : public Container<int,bool>{
     private:
-
-        void _fill(){
-            if(this->value->get_value()){
-                (*this->container)++;
-            }
+        void _fill() {
+            if(this->value->get_value()) (*this->container)++;
         }
     public:
         PassCount(const std::string& name, Value<bool>* value)
@@ -426,6 +423,61 @@ class PassCount : public Container<int,bool>{
 };
 
 
+template <typename T>
+class EfficiencyContainer : public Container<TH1F, std::vector<T>>{
+    private:
+        std::function<bool(T)>* selector;  // Selects whether object is up for consideration
+        std::function<bool(T)>* predicate; // Says whether the object passes the efficiency criteria
+        std::function<float(T)>* get_val;  // Returns a floating point value from the object that is actually
+                                           // used in the histogram
+        TH1F num;
+        TH1F den;
+        TH1F eff;
+
+        TH1Params params;
+
+        void _fill(){
+            for (auto& obj : this->value->get_value()) {
+                if (selector == nullptr or (*selector)(obj)) {
+                    float val = (*get_val)(obj);
+                    den.Fill(val);
+                    if ((*predicate)(obj)) {
+                        num.Fill(val);
+                    }
+                }
+            }
+        }
+
+    public:
+        EfficiencyContainer(const std::string& name, Value<std::vector<T>>* value, TH1Params params,
+                            std::function<bool(T)>* selector, std::function<bool(T)>* predicate,
+                            std::function<float(T)>* get_val)
+          :Container<TH1F, std::vector<T>>(name, value),
+           num{(name+"_num").c_str(), (name+"_num").c_str(), params.nbins, params.low, params.high},
+           den{(name+"_den").c_str(), (name+"_den").c_str(), params.nbins, params.low, params.high},
+           eff{name.c_str(), name.c_str(), params.nbins, params.low, params.high},
+           selector(selector), predicate(predicate), get_val(get_val), params(params) {
+            num.SetXTitle(params.label_x.c_str()); num.SetYTitle(params.label_y.c_str());
+            den.SetXTitle(params.label_x.c_str()); den.SetYTitle(params.label_y.c_str());
+            eff.SetXTitle(params.label_x.c_str()); eff.SetYTitle(params.label_y.c_str());
+            this->container = &eff;
+           }
+
+        TH1F* get_container() {
+            eff.Sumw2();
+            eff.Divide(&num, &den, 1, 1, "B");
+            return this->container;
+        }
+
+        GenContainer* clone_as(const std::string& new_name){
+            return new EfficiencyContainer<T>(new_name, this->value, this->params, selector, predicate, get_val);
+        }
+
+        void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
+            util::save_as(this->get_container(), fname, option);
+        }
+};
+
 template <typename... ArgTypes>
 class MVA : public Container<TMVA::DataLoader,typename MVAData<ArgTypes...>::type>{
     private:

+ 23 - 16
value.hpp

@@ -751,22 +751,6 @@ class TupMap<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
 
 };
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 template<typename... T> class _Tuple;
 template<>
 class _Tuple<> {
@@ -1338,5 +1322,28 @@ class ConstantValue : public DerivedValue<T>{
             this->value = const_value;
         }
 };
+
+/**
+ * A Value which is the result of calling the specified function which takes
+ * no arguments.
+ */
+template <typename T>
+class FunctionValue : public DerivedValue<T>{
+    Function<T()>* fn;
+    protected:
+        void update_value(){ 
+            this->value = (*fn)();
+        }
+
+    public:
+        static std::string fmt_name(const std::string& name){
+            return name;
+        }
+
+        FunctionValue(const std::string& name, Function<T()>* fn, const std::string alias="")
+          :DerivedValue<T>(fmt_name(name), alias) {
+            this->fn = fn;
+        }
+};
 }
 #endif // value_hpp