Browse Source

Modifies Printer class to output to log file, Adds FuncLogger

Caleb Fangmeier 6 years ago
parent
commit
2fbcc1b095
4 changed files with 80 additions and 59 deletions
  1. 0 1
      api.hpp
  2. 62 7
      container.hpp
  3. 7 2
      root/container.hpp
  4. 11 49
      value.hpp

+ 0 - 1
api.hpp

@@ -400,6 +400,5 @@ namespace fv{
             return (Value<type>*)new FunctionValue<Ret>(name, fn, alias);
         }
     }
-
 }
 #endif // API_HPP

+ 62 - 7
container.hpp

@@ -93,7 +93,7 @@ class GenContainer{
           :GenContainer(name,"N/A"){ }
 
         GenContainer* add_filter(GenValue* filter){
-            filters.push_back(dynamic_cast<ObsFilter*>(filter));
+            filters.push_back(static_cast<ObsFilter*>(filter));
             return this;
         }
 
@@ -210,15 +210,32 @@ std::ostream& operator<< (std::ostream & out, const std::vector<T>& data) {
  * Prints out the value registered to it
  */
 template <typename T>
-class Printer : public Container<std::ostream, T>{
+class Logger : public Container<std::ostream, T>{
     private:
+    using to_str_t = std::function<void(T, std::ostream&)>;
+    to_str_t value_to_string;
+
+        static void default_to_string(T& t, std::ostream& os) {
+            os << t;
+        }
+
         void _fill(){
-            (*this->container) << "(" << this->get_name() << ")" << " "
-                               << this->value->get_value() << std::endl;
+            auto& os = (*this->container);
+            std::stringstream vs;
+            os << this->get_name() << std::endl;
+            if (value_to_string != nullptr) value_to_string(this->value->get_value(), vs);
+            else                            default_to_string(this->value->get_value(), vs);
+            for (const char& c : vs.str()) {
+                if (c == '\n') os << std::endl << "  ";
+                else           os << c;
+            }
+            os << std::endl;
         }
+
     public:
-        Printer(const std::string& name, Value<T>* value, std::ostream* out)
-          :Container<std::ostream,T>(name, value){
+        Logger(Value<T>* value, std::ostream* out, to_str_t value_to_string = nullptr)
+          :Container<std::ostream,T>("Logger:" + value->get_name(), value),
+           value_to_string(value_to_string) {
             this->container = out;
         }
 
@@ -227,7 +244,45 @@ class Printer : public Container<std::ostream, T>{
         }
 
         GenContainer* clone_as(const std::string& new_name){
-            return new Printer(new_name, this->value, this->container);
+            return new Logger(this->value, this->container, value_to_string);
+        }
+
+        void save_as(const std::string&, const SaveOption&) { }
+};
+
+/**
+ * Prints out the value registered to it
+ */
+class FuncLogger : public GenContainer {
+    private:
+    std::ostream* os;
+    using to_str_t = std::function<void(std::ostream&)>;
+    to_str_t value_to_string;
+
+        void _fill(){
+            auto& os_ref = (*this->os);
+            std::stringstream vs;
+            os_ref << this->get_name() << std::endl << "  ";
+            value_to_string(vs);
+            for (const char& c : vs.str()) {
+                if (c == '\n') os_ref << std::endl << "  ";
+                else           os_ref << c;
+            }
+            os_ref << std::endl;
+        }
+
+    public:
+        FuncLogger(const std::string& name, std::ostream* os, to_str_t value_to_string)
+          :GenContainer("Logger:" + name),
+           value_to_string(value_to_string),
+           os(os) { }
+
+        std::ostream* get_container(){
+            return os;
+        }
+
+        GenContainer* clone_as(const std::string& new_name){
+            return new FuncLogger(new_name, this->os, value_to_string);
         }
 
         void save_as(const std::string&, const SaveOption&) { }

+ 7 - 2
root/container.hpp

@@ -430,6 +430,7 @@ class EfficiencyContainer : public Container<TH1F, std::vector<T>>{
         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
+        bool write_num_den;
         TH1F num;
         TH1F den;
         TH1F eff;
@@ -451,12 +452,12 @@ class EfficiencyContainer : public Container<TH1F, std::vector<T>>{
     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)
+                            std::function<float(T)>* get_val, bool write_num_den=false)
           :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) {
+           selector(selector), predicate(predicate), get_val(get_val), params(params), write_num_den(write_num_den) {
             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());
@@ -475,6 +476,10 @@ class EfficiencyContainer : public Container<TH1F, std::vector<T>>{
 
         void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
             util::save_as(this->get_container(), fname, option);
+            if (write_num_den) {
+                util::save_as(&num, fname, option);
+                util::save_as(&den, fname, option);
+            }
         }
 };
 

+ 11 - 49
value.hpp

@@ -273,7 +273,7 @@ class Value;
  */
 class GenValue;
 typedef std::map<std::string, GenValue*> ValueSet;
-class GenValue{
+class GenValue {
     private:
         /**
          * The name of the value.
@@ -313,11 +313,9 @@ class GenValue{
          */
         inline static std::map<std::pair<const std::type_index, const std::string>, GenValue*> aliases;
 
-        bool logging_enabled;
-
     public:
         GenValue(const std::type_index&& ti, const std::string& name, const std::string& alias)
-          :name(name), value_valid(false), logging_enabled(false){
+          :name(name), value_valid(false) {
             if (alias != "")
                 INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
             else
@@ -331,15 +329,6 @@ class GenValue{
             return name;
         }
 
-
-        /**
-         * If logging is enabled for this value, this function should be
-         * implemented to format the value to a string and place it as an INFO
-         * entry in the log file. Useful for debugging, but may produce a lot of
-         * output.
-         */
-        virtual void log() = 0;
-
         static void reset(){
             for (auto val : values){
                 if (val.second != nullptr){
@@ -416,27 +405,14 @@ std::ostream& operator<<(std::ostream& os, GenValue& gv){
  * calling get_value().
  */
 template <typename T>
-class Value : public GenValue{
-    protected:
-        std::function<std::string(T)> value_to_string;
-
+class Value : public GenValue {
     public:
         Value(const std::string& name, const std::string& alias="")
-          :value_to_string([](T){return "";}),
-           GenValue(typeid(T), name, alias){ }
+          :GenValue(typeid(T), name, alias){ }
 
         /** Calculate, if necessary, and return the value held by this object.
          */
         virtual T& get_value() = 0;
-
-        void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
-            logging_enabled = true;
-            this->value_to_string = value_to_string;
-        }
-
-        void disable_logging(){
-            logging_enabled = false;
-        }
 };
 
 
@@ -459,23 +435,16 @@ class ObservedValue : public Value<T>{
           :Value<T>(name, alias),
            val_ref(val_ref){ }
 
-        void log(){
-            if (util::debug_on) {
-                std::cout << "Calculating Value: " << this->get_name() << std::endl;
-            }
-            if(this->logging_enabled){
-                INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
-            }
-        }
-
         static std::string fmt_name(const std::string& name){
             return name;
         }
 
         T& get_value(){
             if (!this->value_valid){
+                if (util::debug_on) {
+                    std::cout << "Calculating Value: " << this->get_name() << std::endl;
+                }
                 this->value_valid = true;
-                this->log();
             }
             return *val_ref;
         }
@@ -515,21 +484,13 @@ class DerivedValue : public Value<T>{
         DerivedValue(const std::string& name, const std::string& alias="")
           :Value<T>(name, alias){ }
 
-        void log(){
-            if (util::debug_on) {
-                std::cout << "Calculating Value: " << this->get_name() << std::endl;
-            }
-            if(this->logging_enabled){
-                INFO(this->get_name() << ": " << this->value_to_string(value));
-            }
-        }
-
         T& get_value(){
-            DEBUG("Getting Value: " << this->get_name());
             if (!this->value_valid){
+                if (util::debug_on) {
+                    std::cout << "Calculating Value: " << this->get_name() << std::endl;
+                }
                 update_value();
                 this->value_valid = true;
-                this->log();
             }
             return value;
         }
@@ -653,6 +614,7 @@ namespace impl {
         return head1->get_name() + "," + zip_fmt_name<Head2, Tail...>(head2, tail...);
     }
 }
+
 /**
  * Zips a series of vectors together. Can be combined with Map to
  * yield a Value whose elements are individually a function of the