Bladeren bron

Adds tup_map as a variation of map to automatically unpack tuple-type
arguments. Adds more sophisticated parsing of the input file listings
including re-incorporating category specifications.

Caleb Fangmeier 7 jaren geleden
bovenliggende
commit
7ff47d4d36
5 gewijzigde bestanden met toevoegingen van 126 en 15 verwijderingen
  1. 11 0
      api.hpp
  2. 54 12
      datafile.hpp
  3. 2 2
      root/container.hpp
  4. 7 1
      root/dataset.hpp
  5. 52 0
      value.hpp

+ 11 - 0
api.hpp

@@ -104,6 +104,17 @@ namespace fv{
             return (Value<type>*)new Map<Ret(ArgType)>(fn, arg, alias);
     }
 
+    template <typename Ret, typename... ArgTypes>
+    decltype(auto)
+    tup_map(Function<Ret(ArgTypes...)>& fn, Value<std::vector<std::tuple<ArgTypes...>>>* arg, const std::string& alias=""){
+        typedef std::vector<Ret> type;
+        const std::string& name = TupMap<Ret(ArgTypes...)>::fmt_name(fn, arg);
+        if (check_exists<type>(name))
+            return lookup<type>(name);
+        else
+            return (Value<type>*)new TupMap<Ret(ArgTypes...)>(fn, arg, alias);
+    }
+
     template <typename... ArgTypes>
     decltype(auto)
     tuple(Value<ArgTypes>*... args){

+ 54 - 12
datafile.hpp

@@ -40,23 +40,64 @@
 
 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; //TODO: Populate this
+    std::string category;
 
-    DataFileDescriptor(const std::string filename, const std::string label)
-      :filename(filename), label(label),category("") { }
+    DataFileDescriptor(const std::string filename, const std::string label, const std::string category)
+      :filename(filename), label(label),category(category) { }
 
-    DataFileDescriptor(const std::string line):category(""){
-        std::string::size_type col_pos = line.find(":");
-        if(col_pos == std::string::npos){
-            this->filename = line;
-            this->label = "";
-        } else{
-            this->filename = line.substr(0, col_pos);
-            this->label = line.substr(col_pos+1);
-        }
+    DataFileDescriptor(const std::string line)
+      :filename(""),label(""),category(""){
+        auto fields = split(line, ':');
+        filename = strip(fields[0]);
+        if(fields.size()>1) label=strip(fields[1]);
+        if(fields.size()>2) label=strip(fields[2]);
     }
 
 };
@@ -70,6 +111,7 @@ std::vector<DataFileDescriptor> read_input_list(const std::string &filename){
     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));
     }

+ 2 - 2
root/container.hpp

@@ -118,7 +118,7 @@ class _ContainerTH1 : public Container<TH1,V>{
     public:
         explicit _ContainerTH1(const std::string& name, Value<V>* value,
                                const std::string& title,
-                               TH1Params params)
+                               const TH1Params& params)
           :Container<TH1,V>(name, value),
            title(title),
            params(params) { }
@@ -210,7 +210,7 @@ class ContainerTH2 : public _ContainerTH2<V>{
     }
     public:
         GenContainer* clone_as(const std::string& new_name){
-            return new ContainerTH2<V>(new_name, this->title, this->value, this->params);
+            return new ContainerTH2<V>(new_name, this->value, this->title, this->params);
         }
 };
 

+ 7 - 1
root/dataset.hpp

@@ -121,11 +121,17 @@ class TreeDataSet : public DataSet{
         }
 
         const std::string& get_current_event_category() const{
-            TFile* file = tree_obj->fChain->GetFile();
+            TFile* file = tree_obj->fChain->GetCurrentFile();
             std::string filename = file->GetName();
             return input_categories.at(filename);
         }
 
+        const std::string& get_current_event_label() const{
+            TFile* file = tree_obj->fChain->GetCurrentFile();
+            std::string filename = file->GetName();
+            return input_labels.at(filename);
+        }
+
         template <typename T>
         Value<T>* track_branch(const std::string& bname){
             TBranch* branch = tree_obj->fChain->GetBranch(bname.c_str());

+ 52 - 0
value.hpp

@@ -713,6 +713,58 @@ class Map<Ret(ArgType)> : public DerivedValue<std::vector<Ret>>{
 
 };
 
+
+
+
+template<typename> class TupMap; // undefined
+/**
+ * Maps a function over an input vector. The input vector must be a vector of
+ * tuples, where the the elements of the tuple match the arguments of the
+ * function. For example if the function takes two floats as arguments, the
+ * tuple should contain two floats. The Value object required by Map will
+ * typically be created as a Zip.
+ */
+template <typename Ret, typename... ArgTypes>
+class TupMap<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
+    private:
+        typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
+        Function<Ret(ArgTypes...)>& fn;
+        arg_type* arg;
+
+        void update_value(){
+            this->value.clear();
+            for(auto tup : arg->get_value()){
+                this->value.push_back(call(fn,tup));
+            }
+        }
+
+    public:
+        static std::string fmt_name(Function<Ret(ArgTypes...)>& fn, arg_type* arg){
+            return "tup_map("+fn.get_name()+":"+arg->get_name()+")";
+        }
+
+        TupMap(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
+          :DerivedValue<std::vector<Ret>>(fmt_name(fn, arg), alias),
+           fn(fn), arg(arg){ }
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 template<typename... T> class _Tuple;
 template<>
 class _Tuple<> {