Parcourir la source

Merge branch 'master' of git.fangmeier.tech:caleb/filval

Caleb Fangmeier il y a 6 ans
Parent
commit
be12583a22
9 fichiers modifiés avec 121 ajouts et 152 suppressions
  1. 84 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 4
      python/filval/histogram_utils.py
  7. 6 2
      python/filval/plotter.py
  8. 0 2
      python/setup.py
  9. 9 1
      value.hpp

+ 84 - 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,16 +92,57 @@ 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>();
+        }
+
+        bool get_debug() {
+            YAML::Node debug_node = root["debug"];
+            if(!debug_node) {
+                return false;
+            }
+            return debug_node.as<bool>();
+        }
+
+        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;
+bool debug_on = false;
 void init_config(const std::string& input_filename){
     if(the_config) delete the_config;
     the_config = new Config(input_filename);
+    debug_on = the_config->get_debug();
 }
 
 }

+ 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 - 4
python/filval/histogram_utils.py

@@ -42,6 +42,7 @@ def hist2d(th2, rescale_x=1.0, rescale_y=1.0, rescale_z=1.0):
     """
     nbins_x = th2.GetNbinsX()
     nbins_y = th2.GetNbinsY()
+    print(nbins_x, nbins_y)
     xs = np.zeros((nbins_y+1, nbins_x+1), np.float32)
     ys = np.zeros((nbins_y+1, nbins_x+1), np.float32)
     values = np.zeros((nbins_y, nbins_x), np.float32)
@@ -52,11 +53,11 @@ def hist2d(th2, rescale_x=1.0, rescale_y=1.0, rescale_z=1.0):
             ys[j][i] = th2.GetYaxis().GetBinLowEdge(j+1)
             values[j][i] = th2.GetBinContent(i+1, j+1)
             errors[j][i] = th2.GetBinError(i+1, j+1)
-        xs[nbins_y][i] = th2.GetXaxis().GetBinUpEdge(i+1)
-        ys[nbins_y][i] = th2.GetYaxis().GetBinUpEdge(nbins_y+1)
+        xs[nbins_y][i] = th2.GetXaxis().GetBinUpEdge(i)
+        ys[nbins_y][i] = th2.GetYaxis().GetBinUpEdge(nbins_y)
     for j in range(nbins_y+1):
-        xs[j][nbins_x] = th2.GetXaxis().GetBinUpEdge(nbins_x+1)
-        ys[j][nbins_x] = th2.GetYaxis().GetBinUpEdge(j+1)
+        xs[j][nbins_x] = th2.GetXaxis().GetBinUpEdge(nbins_x)
+        ys[j][nbins_x] = th2.GetYaxis().GetBinUpEdge(j)
 
     xs *= rescale_x
     ys *= rescale_y

+ 6 - 2
python/filval/plotter.py

@@ -87,7 +87,8 @@ def decl_plot(fn):
 
 def generate_dashboard(plots, title, output='dashboard.html', template='dashboard.j2', source_file=None, ana_source=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(
@@ -111,6 +112,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(
@@ -212,7 +216,7 @@ def render_plots(plots, exts=('png',), scale=1.0, to_disk=True):
         print(f'Building plot {plot.name}')
         plot.data = None
         if to_disk:
-            with lp.figure(plot.name, directory='output/figures',
+            with lp.figure(plot.name.replace(' ', '_'), directory='output/figures',
                            exts=exts,
                            size=(scale * 10, scale * 10)):
                 argdicts, docs, txts = grid_plot(plot.subplots)

+ 0 - 2
python/setup.py

@@ -3,8 +3,6 @@ from setuptools import setup
 with open('requirements.txt') as req:
     install_requires = [l.strip() for l in req.readlines()]
 
-print(install_requires)
-
 setup(
     name='filval',
     version='0.1',

+ 9 - 1
value.hpp

@@ -55,6 +55,7 @@
 #include <vector>
 
 #include "log.hpp"
+#include "config.hpp"
 
 /**
  * The namespace containing all filval classes and functions.
@@ -334,7 +335,7 @@ class GenValue{
         /**
          * 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 alot of
+         * entry in the log file. Useful for debugging, but may produce a lot of
          * output.
          */
         virtual void log() = 0;
@@ -423,6 +424,7 @@ class Value : public GenValue{
         Value(const std::string& name, const std::string& alias="")
           :value_to_string([](T){return "";}),
            GenValue(typeid(T), name, alias){ }
+
         /** Calculate, if necessary, and return the value held by this object.
          */
         virtual T& get_value() = 0;
@@ -458,6 +460,9 @@ class ObservedValue : public Value<T>{
            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));
             }
@@ -511,6 +516,9 @@ class DerivedValue : public Value<T>{
           :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));
             }