Browse Source

Modifies the way one supplies data files to use the yaml config file

Caleb Fangmeier 6 years ago
parent
commit
74e26df8bf
6 changed files with 96 additions and 144 deletions
  1. 74 3
      config.hpp
  2. 0 127
      datafile.hpp
  3. 3 2
      dataset.hpp
  4. 0 1
      filval.hpp
  5. 14 10
      log.hpp
  6. 5 1
      python/filval/plotter.py

+ 74 - 3
config.hpp

@@ -32,12 +32,52 @@
 #ifndef config_hpp
 #define config_hpp
 #include <string>
-#include <iostream>
 
 #include "yaml-cpp/yaml.h"
 
-namespace fv::util{
+namespace fv::util {
+struct DataFileDescriptor{
+    std::string filename;
+    std::string label;
+    std::string category;
+    int file_number;
 
+    DataFileDescriptor():filename(""), label(""),category(""),file_number(-1) { }
+
+    DataFileDescriptor(const std::string filename, const std::string label, const std::string category)
+      :filename(filename), label(label),category(category),file_number(-1) { }
+
+    DataFileDescriptor(const std::string filename, const std::string label, const std::string category, const int file_number)
+      :filename(filename), label(label),category(category),file_number(file_number) { }
+};
+}
+
+namespace YAML {
+template<>
+struct convert<fv::util::DataFileDescriptor> {
+  static Node encode(const fv::util::DataFileDescriptor& rhs) {
+    Node node;
+    node["filename"] = rhs.filename;
+    node["label"] = rhs.label;
+    node["category"] = rhs.category;
+    return node;
+  }
+
+  static bool decode(const Node& node, fv::util::DataFileDescriptor& rhs) {
+    if(!node.IsMap()) {
+      return false;
+    }
+
+    if(!node["filename"]) return false;
+    rhs.filename = node["filename"].as<std::string>();
+    if(node["label"]) rhs.label = node["label"].as<std::string>();
+    if(node["category"]) rhs.category = node["category"].as<std::string>();
+    return true;
+  }
+};
+}
+
+namespace fv::util {
 class Config{
     private:
         std::string input_filename;
@@ -52,10 +92,41 @@ class Config{
            input_filename(input_filename) { }
 
         template <typename KEY_TYPE>
-        YAML::Node get(const KEY_TYPE& key){
+        YAML::Node get(const KEY_TYPE& key) {
             auto val = root[key];
             return val;
         }
+
+        size_t get_max_events() {
+            YAML::Node max_events = root["max-events"];
+            if(!max_events) {
+                return 0;
+            }
+            return max_events.as<size_t>();
+        }
+
+        std::string get_output_filename() {
+            YAML::Node output_file = root["output-file"];
+            if(output_file) {
+                return output_file.as<std::string>();
+            } else {
+                std::cout << "Must specify output-file in config file." << std::endl;
+                return "";
+            }
+        }
+
+        std::vector<DataFileDescriptor> get_source_files() {
+            std::vector<DataFileDescriptor> source_files;
+            YAML::Node source_files_nd = root["source-files"];
+            if(source_files_nd.IsSequence()) {
+                for (const auto& f : source_files_nd) {
+                    source_files.push_back(f.as<DataFileDescriptor>());
+                }
+            } else {
+                std::cout << "source-files missing or not a sequence" << std::endl;
+            }
+            return source_files;
+        }
 };
 
 Config* the_config = nullptr;

+ 0 - 127
datafile.hpp

@@ -1,127 +0,0 @@
-/**
- * @file
- * @author  Caleb Fangmeier <caleb@fangmeier.tech>
- * @version 0.1
- *
- * @section LICENSE
- *
- *
- * MIT License
- *
- * Copyright (c) 2017 Caleb Fangmeier
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * @section DESCRIPTION
- */
-#ifndef datafile_hpp
-#define datafile_hpp
-
-#include <vector>
-#include <string>
-#include <fstream>
-#include <iostream>
-
-namespace fv::util{
-
-/**
- * Splits input string into substrings based on provided sep char.
- * For example, split("1,2,3", ',') -> {"1","2","3"}.
- */
-std::vector<std::string> split(const std::string& to_split, char sep){
-    std::vector<std::string> substrings;
-    std::string substring;
-
-    for(const char &c : to_split){
-        if(c == sep){
-            substrings.push_back(substring);
-            substring.clear();
-        } else{
-            substring.push_back(c);
-        }
-    }
-    if(substring.size() > 0){
-        substrings.push_back(substring);
-    }
-    return substrings;
-}
-
-/**
- * Removes leading and trailing whitespace from s
- */
-std::string& strip(std::string& s){
-    int idx;
-    //strip left side whitespace
-    for(idx=0; idx<s.size(); idx++){
-        char& c = s[idx];
-        if(c == ' ' || c == '\t') continue;
-        break;
-    }
-    s.erase(0,idx);
-    //strip right side whitespace
-    for(idx=s.size()-1; idx>=0; idx--){
-        char& c = s[idx];
-        if(c == ' ' || c == '\t') continue;
-        break;
-    }
-    s.erase(idx+1,s.size()-idx-1);
-    return s;
-}
-
-struct DataFileDescriptor{
-    std::string filename;
-    std::string label;
-    std::string category;
-    int file_number;
-
-    DataFileDescriptor():filename(""), label(""),category(""),file_number(-1) { }
-
-    DataFileDescriptor(const std::string filename, const std::string label, const std::string category, const int file_number)
-      :filename(filename), label(label),category(category),file_number(file_number) { }
-
-    DataFileDescriptor(const std::string filename, const std::string label, const std::string category)
-      :filename(filename), label(label),category(category),file_number(-1) { }
-
-    DataFileDescriptor(const std::string line)
-      :filename(""),label(""),category(""),file_number(-1){
-        auto fields = split(line, ':');
-        filename = strip(fields[0]);
-        if(fields.size()>1) label=strip(fields[1]);
-        if(fields.size()>2) label=strip(fields[2]);
-    }
-
-};
-
-// input list should be a file containing line-delineated filename for all Data
-// Files with an optional label separated by a comma.
-std::vector<DataFileDescriptor> read_input_list(const std::string &filename){
-    std::ifstream istrm(filename, std::ios::in);
-
-    std::string line;
-    std::vector<DataFileDescriptor> dfds;
-    std::string prefix = filename.substr(0, filename.find_last_of("/")+1);
-    while(std::getline(istrm, line)){
-        strip(line);
-        if(line[0] != '#')
-        dfds.push_back(DataFileDescriptor(prefix+line));
-    }
-    return dfds;
-}
-}
-#endif // datafile_hpp

+ 3 - 2
dataset.hpp

@@ -34,7 +34,7 @@
 #include "value.hpp"
 #include "container.hpp"
 #include "memtrack.hpp"
-#include "datafile.hpp"
+#include "config.hpp"
 #include "log.hpp"
 
 namespace fv{
@@ -80,12 +80,13 @@ class DataSet{
             return impl_map;
         }
     public:
-        DataSet():max_events(0){
+        DataSet() {
             auto event_check = GenFunction::reg_func<int()>("event_number",
                 FUNC(([ds=this](){
                     return ds->get_current_event();
                 })));
             current_event_number = new BoundValue<int>(event_check);
+            set_max_events(fv::util::the_config->get_max_events());
         }
 
         void process(bool silent=false){

+ 0 - 1
filval.hpp

@@ -9,7 +9,6 @@
 #include "log.hpp"
 #include "argparse.hpp"
 #include "config.hpp"
-#include "datafile.hpp"
 #include "memtrack.hpp"
 #include "api.hpp"
 #endif // filval_hpp

+ 14 - 10
log.hpp

@@ -38,6 +38,8 @@
 #include <cstring>
 #include <map>
 
+#include "config.hpp"
+
 namespace fv::util{
 enum LogPriority {
     kLogEmergency = 7,  // system is unusable
@@ -68,7 +70,6 @@ private:
     std::ofstream logfile;
     LogPriority priority_curr;
     LogPriority priority_set;
-    inline static Log* singleton = nullptr;
     const std::map<LogPriority,std::string> name_map = {{kLogEmergency, "EMERGENCY"},
                                                         {kLogAlert,     "ALERT"},
                                                         {kLogCritical,  "CRITICAL"},
@@ -102,20 +103,23 @@ protected:
         return c;
     }
 public:
-    explicit Log(std::string filename, LogPriority priority)
+    explicit Log(const std::string& filename, LogPriority priority)
       :logfile(filename, std::ofstream::out){
         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;
-    }
 };
+
+Log* the_log = nullptr;
+void init_log(LogPriority priority){
+    if(the_config == nullptr)
+        std::cerr << "Must initialize config before setting up logging!" << std::endl;
+    std::string out = the_config->get_output_filename();
+    std::string filename = out.substr(0, out.find_last_of(".")) + ".log";
+    the_log = new Log(filename, priority);
+    std::cout << "Writing log data to " << filename << std::endl;
+    std::clog.rdbuf(the_log);
+}
 }
 #endif // log_hpp

+ 5 - 1
python/filval/plotter.py

@@ -81,7 +81,8 @@ def decl_plot(fn):
 
 def generate_dashboard(plots, title, output='dashboard.html', template='dashboard.j2', source_file=None):
     from jinja2 import Environment, PackageLoader, select_autoescape
-    from os.path import join
+    from os.path import join, isdir
+    from os import mkdir
     from urllib.parse import quote
 
     env = Environment(
@@ -105,6 +106,9 @@ def generate_dashboard(plots, title, output='dashboard.html', template='dashboar
     else:
         source = "# Not supplied!!"
 
+    if not isdir('output'):
+        mkdir('output')
+
     with open(join('output', output), 'w') as tempout:
         templ = env.get_template(template)
         tempout.write(templ.render(