ソースを参照

Adds ability to save fv::root containers to root files.

Caleb Fangmeier 8 年 前
コミット
d050852cda
共有5 個のファイルを変更した71 個の追加30 個の削除を含む
  1. 1 1
      argparse.hpp
  2. 9 2
      container.hpp
  3. 10 3
      dataset.hpp
  4. 20 10
      log.hpp
  5. 31 14
      value.hpp

+ 1 - 1
argparse.hpp

@@ -29,6 +29,7 @@
  * SOFTWARE.
  *
  * @section DESCRIPTION
+ * \see http://stackoverflow.com/questions/865668/how-to-parse-command-line-arguments-in-c#868894
  */
 #ifndef argparse_hpp
 #define argparse_hpp
@@ -36,7 +37,6 @@
 #include <string>
 #include <vector>
 namespace fv::util{
-/// \see http://stackoverflow.com/questions/865668/how-to-parse-command-line-arguments-in-c#868894
 class ArgParser{
     private:
         std::vector <std::string> tokens;

+ 9 - 2
container.hpp

@@ -5,6 +5,13 @@
 #include <vector>
 
 namespace fv{
+
+enum SaveOption{
+    PNG = 0,
+    PDF = 1,
+    ROOT = 2
+};
+
 class GenContainer{
     private:
         std::string name;
@@ -36,8 +43,8 @@ class GenContainer{
         const std::string& get_name(){
             return name;
         }
-        virtual void save_as(const std::string& fname) = 0;
-        virtual void save() = 0;
+        virtual void save_as(const std::string& fname, const SaveOption& option) = 0;
+        virtual void save(const SaveOption& option=SaveOption::PNG) = 0;
 };
 typedef std::map<std::string, GenContainer*> ContainerSet;
 

+ 10 - 3
dataset.hpp

@@ -36,15 +36,22 @@ class DataSet{
             std::cout << " Finished!" << std::endl;
         }
 
-        void add_container(GenContainer *container){
+        virtual void save_all(){
+            for(auto container : containers)
+                container.second->save();
+        }
+
+        void register_container(GenContainer *container){
+            if (containers[container->get_name()] != nullptr){
+                CRITICAL("Container with name \""+container->get_name()+"\" already exists.", -1);
+            }
             containers[container->get_name()] = container;
         }
 
         GenContainer* get_container(std::string container_name){
             GenContainer* c = containers[container_name];
             if (c == nullptr){
-                std::cout << "Request for container \"" << container_name << "\" failed. Doesn't exist." << std::endl;
-                exit(-1);
+                CRITICAL("Request for container \"" << container_name << "\" failed. Doesn't exist.", -1);
             }
             return c;
         }

+ 20 - 10
log.hpp

@@ -50,7 +50,7 @@ enum LogPriority {
     kLogDebug     = 0   // debug-level message
 };
 
-#define CRITICAL(x,y) std::clog << fv::util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; exit(y)
+#define CRITICAL(x,y) std::clog << fv::util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; std::cout << "Errors encountered! See log file for details."<<std::endl;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
@@ -67,14 +67,15 @@ private:
     std::ofstream logfile;
     LogPriority priority_curr;
     LogPriority priority_set;
-    std::map<LogPriority,std::string> name_map = {{kLogEmergency, "EMERGENCY"},
-                                                  {kLogAlert,     "ALERT"},
-                                                  {kLogCritical,  "CRITICAL"},
-                                                  {kLogError,     "ERROR"},
-                                                  {kLogWarning,   "WARNING"},
-                                                  {kLogNotice,    "NOTICE"},
-                                                  {kLogInfo,      "INFO"},
-                                                  {kLogDebug,     "DEBUG"}};
+    inline static Log* singleton = nullptr;
+    const std::map<LogPriority,std::string> name_map = {{kLogEmergency, "EMERGENCY"},
+                                                        {kLogAlert,     "ALERT"},
+                                                        {kLogCritical,  "CRITICAL"},
+                                                        {kLogError,     "ERROR"},
+                                                        {kLogWarning,   "WARNING"},
+                                                        {kLogNotice,    "NOTICE"},
+                                                        {kLogInfo,      "INFO"},
+                                                        {kLogDebug,     "DEBUG"}};
 
     friend std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority){
         static_cast<Log *>(os.rdbuf())->priority_curr = log_priority;
@@ -84,7 +85,7 @@ protected:
     int sync(){
         if (buffer_.length()) {
             if (priority_curr >= priority_set){
-                logfile << name_map[priority_curr] << ": " <<  buffer_ << std::endl << std::flush;
+                logfile << name_map.at(priority_curr) << ": " <<  buffer_ << std::endl << std::flush;
             }
             buffer_.erase();
             /* priority_curr = kLogDebug; // default to debug for each message */
@@ -105,6 +106,15 @@ public:
         priority_set = priority;
         priority_curr = kLogDebug;
     }
+
+    static Log& init_logger(std::string filename, LogPriority priority){
+        if (singleton == nullptr){
+            singleton = new Log(filename, priority);
+            std::cout << "Writing log data to " << filename << std::endl;
+            std::clog.rdbuf(singleton);
+        }
+        return *singleton;
+    }
 };
 }
 #endif // log_hpp

+ 31 - 14
value.hpp

@@ -41,6 +41,7 @@
  */
 #ifndef value_hpp
 #define value_hpp
+#include <iomanip>
 #include <iostream>
 #include <sstream>
 #include <utility>
@@ -68,9 +69,6 @@ class GenFunction {
     private:
         std::string name;
         std::string impl;
-    protected:
-        /* virtual void _() = 0; */
-
 
     public:
         /**
@@ -89,18 +87,35 @@ class GenFunction {
             return name;
         }
 
+        /**
+         * Attempt to invoke clang-format for the purpose of printing out
+         * nicely formatted functions to the log file. If clang-format is not
+         * present, this function just passes through the code unmodified.
+         */
+        static std::string format_code(const std::string& code){
+            std::stringstream code_out("");
+            std::string command("echo \""+code+"\" | clang-format");
+            char buffer[255];
+            FILE *stream = popen(command.c_str(), "r");
+            while (fgets(buffer, 255, stream) != NULL)
+                code_out << buffer;
+            if (pclose(stream) == 0)
+                return code_out.str();
+            else
+                return code;
+        }
+
         static std::string summary(){
             std::stringstream ss;
+            ss << "The following functions have been registered" << std::endl;
             for(auto p : function_registry){
                 if (p.second == nullptr) continue;
-                ss << p.second->name << std::endl;
-                ss << "\t" << p.second->impl << std::endl;
-                ss << "##############################" << std::endl;
+                ss << "-->" << p.second->name << std::endl;
+                ss << format_code(p.second->impl);
             }
             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;
@@ -117,10 +132,6 @@ class GenFunction {
             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"); */
-        /* } */
 };
 
 
@@ -215,7 +226,7 @@ class GenValue{
             else if (values[name] != nullptr)
                 return values[name];
             else{
-                ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about."
+                ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
                         << summary());
                 CRITICAL("Aborting... :(", -1);
             }
@@ -256,7 +267,12 @@ class GenValue{
             }
             return ss.str();
         }
+        friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
 };
+std::ostream& operator<<(std::ostream& os, GenValue& gv){
+    os << gv.get_name();
+    return os;
+}
 
 
 /**
@@ -383,8 +399,8 @@ class WrapperVector : public DerivedValue<std::vector<T> >{
            size(size), data(data){ }
 
         WrapperVector(const std::string &label_size, const std::string &label_data)
-          :WrapperVector(dynamic_cast<Value<int>*>(GenValue::values.at(label_size)),
-                         dynamic_cast<Value<T*>*>(GenValue::values.at(label_data))) { }
+          :WrapperVector(dynamic_cast<Value<int>*>(GenValue::get_value(label_size)),
+                         dynamic_cast<Value<T*>*>(GenValue::get_value(label_data))) { }
 };
 
 /**
@@ -460,6 +476,7 @@ class ZipMapFour : public DerivedValue<std::vector<R> >{
                       dynamic_cast<Value<std::vector<T> >*>(GenValue::values.at(label4))){ }
 };
 
+
 /**
  * Reduce a Value of type vector<T> to just a T.
  * This is useful functionality to model, for instance, calculating the maximum