Pārlūkot izejas kodu

Introduces the filval analysis fromwork wip

Caleb Fangmeier 8 gadi atpakaļ
revīzija
c778e95685
9 mainītis faili ar 392 papildinājumiem un 0 dzēšanām
  1. 16 0
      README.md
  2. 72 0
      container.hpp
  3. 36 0
      dataset.hpp
  4. 101 0
      filter.hpp
  5. 7 0
      filval.hpp
  6. BIN
      main
  7. 45 0
      main.cpp
  8. BIN
      out
  9. 115 0
      value.hpp

+ 16 - 0
README.md

@@ -0,0 +1,16 @@
+A FILter-VALue System
+=====================
+This is a header-only, generic, data analysis system that allows for creating performant generation of *Plots*. *Plots* contain *Values* and can make use of *Filters*.
+*Filters* can also depend of *Values*, and *Values* can depend on other *Values*. A *Dataset* is a generic object that contains a series of observations. The individual observations
+consist of a series of *Observed Values*. One can also define *Derived Values* which are calculated from *Observed Values* or other *Derived Values*. Care is taken automatically 
+so *Derived Values* are calculated at most once per observation.
+
+
+
+```C++
+MyDataSet myDataSet("somefile.root", "tree"); // MyDataSet subclasses DataSet
+TTreeValue<int> countmyDataSet;
+myDataSet.addValue
+
+Hist1D myplot(count, myDataSet, ); // Hist1D subclasses Plot
+```

+ 72 - 0
container.hpp

@@ -0,0 +1,72 @@
+#ifndef container_hpp
+#define container_hpp
+#include "value.hpp"
+#include "filter.hpp"
+#include <vector>
+
+namespace filval{
+class GenContainer{
+    private:
+        std::string name;
+        std::string desc;
+        std::vector<Filter*> filters;
+    protected:
+        virtual void _fill() = 0;
+    public:
+        GenContainer(const std::string name)
+          :name(name){ }
+        void add_filter(GenValue* filter){
+            filters.push_back(dynamic_cast<Filter*>(filter));
+        }
+        void fill(){
+            for (auto filter : filters){
+                if (!filter->get_value()){
+                    return;
+                }
+            }
+            _fill();
+        }
+        void set_description(const std::string& description){
+            desc = description;
+        }
+        const std::string& get_name(){
+            return name;
+        }
+};
+typedef std::map<std::string, GenContainer*> ContainerSet;
+
+template <typename H>
+class Container : public GenContainer{
+    protected:
+        H* container;
+    public:
+        Container(H* container, const std::string name)
+          :GenContainer(name),
+           container(container){ }
+        virtual H* get_container(){
+            return container;
+        }
+
+};
+
+template <typename T>
+class ContainerVector : public Container<std::vector<T> >{
+    private:
+        Value<T>* value;
+
+        void _fill(){
+            this->container->push_back(value->get_value());
+        }
+    public:
+        ContainerVector(std::vector<T> *container, Value<T>* value, const std::string name)
+          :Container<std::vector<T> >(container, name),
+           value(value){ }
+        ContainerVector(Value<T>* value, const std::string name)
+          :Container<std::vector<T> >(NULL, name),
+           value(value){
+            this->container = new std::vector<T>();
+        }
+};
+
+}
+#endif // container_hpp

+ 36 - 0
dataset.hpp

@@ -0,0 +1,36 @@
+#ifndef dataset_hpp
+#define dataset_hpp
+#include "value.hpp"
+#include "container.hpp"
+
+namespace filval{
+class DataSet{
+    protected:
+        ValueSet values;
+        ContainerSet containers;
+        virtual bool load_next() = 0;
+    public:
+        void process(){
+            while( load_next() ){
+                for(auto val : values)
+                    val.second->reset();
+                for(auto con : containers)
+                    con.second->fill();
+            }
+        }
+        void add_value(GenValue *value, const std::string& value_name ){
+            values[value_name] = value;
+        }
+        GenValue* get_value(std::string value_name){
+            return values[value_name];
+        }
+
+        void add_container(GenContainer *container){
+            containers[container->get_name()] = container;
+        }
+        GenContainer* get_container(std::string container_name){
+            return containers[container_name];
+        }
+};
+}
+#endif // dataset_hpp

+ 101 - 0
filter.hpp

@@ -0,0 +1,101 @@
+#ifndef filter_h
+#define filter_h
+#include <iostream>
+#include "value.hpp"
+/* A Filter is a special type of derived value that can only return a boolean.
+ * Container objects have a vector of filters that control if a "fill" call
+ * actually places data into the container or not.
+ */
+namespace filval {
+
+class Filter : public DerivedValue<bool>{ };
+
+
+class FilterAnd : public Filter {
+    protected:
+        Filter *filterA;
+        Filter *filterB;
+    void update_value(){
+        value = filterA->get_value() && filterB->get_value();
+    }
+    public:
+        FilterAnd(Filter *filterA, Filter *filterB)
+            :filterA(filterA), filterB(filterB){ }
+};
+
+class FilterOr : public Filter {
+    private:
+        Filter *filterA;
+        Filter *filterB;
+    void update_value(){
+        value = filterA->get_value() || filterB->get_value();
+    }
+    public:
+        FilterOr(Filter *filterA, Filter *filterB)
+            :filterA(filterA), filterB(filterB){ }
+};
+
+class FilterInv : public Filter {
+    private:
+        Filter *filter;
+    void update_value(){
+        value = !filter->get_value();
+    }
+    public:
+        FilterInv(Filter *filter)
+            :filter(filter){ }
+};
+
+template <typename T>
+class FilterGreaterThan : public Filter {
+    private:
+        Value<T> *filter_value;
+        Value<T> *range_low;
+        void update_value(){
+            value = filter_value->get_value() > range_low->get_value();
+        }
+    public:
+        FilterGreaterThan(GenValue* filter_value, GenValue* range_low)
+            :filter_value(dynamic_cast<Value<T>*>(filter_value)),
+             range_low(dynamic_cast<Value<T>*>(range_low)) { }
+
+        FilterGreaterThan(GenValue* filter_value, T range_low)
+            :filter_value(dynamic_cast<Value<T>*>(filter_value)){
+            this->range_low = new ConstantValue<T>(range_low);
+        }
+};
+
+template <typename T>
+class FilterLessThan : public Filter {
+    private:
+        Value<T> *filter_value;
+        Value<T> *range_high;
+        void update_value(){
+            value = filter_value->get_value() < range_high->get_value();
+        }
+    public:
+        FilterLessThan(GenValue* filter_value, GenValue* range_high)
+            :filter_value(dynamic_cast<Value<T>*>(filter_value)),
+             range_high(dynamic_cast<Value<T>*>(range_high)) { }
+
+        FilterLessThan(GenValue* filter_value, T range_high)
+            :filter_value(dynamic_cast<Value<T>*>(filter_value)){
+            this->range_high = new ConstantValue<T>(range_high);
+        }
+};
+
+
+template <typename T>
+class RangeFilter : public FilterAnd {
+    public:
+        RangeFilter(Value<T> *filter_value, Value<T> *range_low, Value<T> *range_high){
+            this->filterA = new FilterLessThan<T>(filter_value, range_high);
+            this->filterB = new FilterGreaterThan<T>(filter_value, range_low);
+         }
+        RangeFilter(Value<T> *filter_value, T range_low, T range_high){
+            this->filterA = new FilterLessThan<T>(filter_value, range_high);
+            this->filterB = new FilterGreaterThan<T>(filter_value, range_low);
+        }
+};
+}
+#endif // filter_h

+ 7 - 0
filval.hpp

@@ -0,0 +1,7 @@
+#ifndef filval_hpp
+#define filval_hpp
+#include "value.hpp"
+#include "filter.hpp"
+#include "container.hpp"
+#include "dataset.hpp"
+#endif // filval_hpp

BIN
main


+ 45 - 0
main.cpp

@@ -0,0 +1,45 @@
+#include <iostream>
+#include <vector>
+#include <utility>
+
+#include "value.hpp"
+
+using namespace std;
+
+
+void print_pair(DerivedPair<double, double> p){
+    pair<double, double> pr = p.get_value();
+    cout << "(" << pr.first << ", " << pr.second << ")\n";
+}
+
+int main(int argc, const char* argv[]){
+    /* Value<int, int> v; */
+    double x = 12;
+    double y = 12;
+
+    ObservedValue<double> x_val(&x);
+    ObservedValue<double> y_val(&y);
+
+    DerivedPair<double, double> dp(&x_val, &y_val);
+    print_pair(dp);
+    x = 2;
+    y = 2;
+    print_pair(dp);
+
+    ContainerVector<double> cont(&x_val);
+    x = 12;
+    cont.fill();
+    x = 2;
+    cont.fill();
+    auto *container = cont.get_container();
+
+    for( auto v: *container )
+        cout << v << ", ";
+    cout << endl;
+    /* ValA val; */
+    /* val.reset(); */
+    /* Address x = val.get_value(); */
+    /* cout << "Hello World " << x.street_address << "\n"; */
+    /* x = val.get_value(); */
+    /* cout << "Hello World " << x.street_address << "\n"; */
+}

BIN
out


+ 115 - 0
value.hpp

@@ -0,0 +1,115 @@
+#ifndef value_hpp
+#define value_hpp
+#include <iostream>
+#include <utility>
+#include <map>
+
+namespace filval{
+
+class GenValue{
+    public:
+        virtual void reset() = 0;
+};
+typedef std::map<std::string, GenValue*> ValueSet;
+
+/* class ValueSet: public std::map<std::string, GenValue*>{ */
+/*     public: */
+/*         GenValue*& operator[](const std::string& key){ */
+/*             GenValue*& value = (*this)[key]; */
+/*             if (value == NULL){ */
+/*                 std::cerr << "ERROR: key \""<<key */
+/*                     <<"\" not in valueset" << std::endl; */
+/*             } */
+/*             return value; */
+/*         } */
+/* }; */
+
+
+template <typename V>
+class Value : public GenValue{
+    public:
+        virtual V& get_value() = 0;
+};
+
+
+template <typename V>
+class ObservedValue : public Value<V>{
+    /* For "observed" values, there is nothing to calculate since this is
+     * merely a wrapper around a field in the observation. A pointer to the
+     * value is kept and it's value is read when requested.
+     */
+    private:
+        V *val_ref;
+    public:
+        ObservedValue(V *val_ref)
+            : val_ref(val_ref){}
+        V& get_value(){
+            return *val_ref;
+        }
+        void reset(){ }
+};
+
+
+template <typename V>
+class DerivedValue : public Value<V>{
+    /* A "derived" value is the result of some sort of calculation. Since it is
+     * desireable for the calculation to occur at most a single time for each
+     * observation, the result of the calculation is stored in the object. be
+     * sure that "reset" is called between processing observations to force a
+     * re-calculation.
+     */
+    protected:
+        V value; // The value to be calculated
+        bool value_valid;
+
+        virtual void update_value() = 0;
+    public:
+        V& get_value(){
+            if (!value_valid){
+                /* std::cout << "updating value!\n"; */
+                update_value();
+                value_valid = true;
+            }
+            return value;
+        }
+
+        void reset(){
+            value_valid = false;
+        }
+};
+
+
+template <typename T1, typename T2>
+class DerivedPair : public DerivedValue<std::pair<T1, T2> >{
+    protected:
+        std::pair<Value<T1>*, Value<T2>* > value_pair;
+        void update_value(){
+            this->value.first = value_pair.first->get_value();
+            this->value.second = value_pair.second->get_value();
+        }
+    public:
+        DerivedPair(ValueSet *values, const std::string &label1, const std::string &label2){
+            ValueSet &valueSet = *values;
+            value_pair.first  = (Value<T1>*) valueSet[label1];
+            value_pair.second = (Value<T2>*) valueSet[label2];
+         }
+        DerivedPair(Value<T1> *value1, Value<T2> *value2){
+            value_pair.first  = value1;
+            value_pair.second = value2;
+         }
+
+};
+
+template <typename V>
+class ConstantValue : public DerivedValue<V>{
+    protected:
+        V const_value;
+        void update_value(){
+            this->value = const_value;
+        }
+    public:
+        ConstantValue(V const_value)
+            :const_value(const_value) { }
+};
+}
+#endif // value_hpp