[yoda-svn] r575 - in trunk: . include/YODA pyext/yoda pyext/yoda/include src

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Fri Mar 15 09:52:27 GMT 2013


Author: buckley
Date: Fri Mar 15 09:52:27 2013
New Revision: 575

Log:
Adding auto-format read and write functions. I will probably change the API. Python mappings have been provided, but the string workarounds were too much of a pain with Cython 0.16 so I have updated the Cython version requirement to 0.17 where it is automatic and hence much cleaner.

Added:
   trunk/src/Reader.cc
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/include/YODA/Reader.h
   trunk/include/YODA/Writer.h
   trunk/pyext/yoda/declarations.pxd
   trunk/pyext/yoda/include/IO.pyx
   trunk/src/Makefile.am
   trunk/src/Writer.cc

Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/ChangeLog	Fri Mar 15 09:52:27 2013	(r575)
@@ -1,3 +1,11 @@
+2013-03-15  Andy Buckley  <andy.buckley at cern.ch>
+
+	* Adding auto-format read and write functions. I will probably
+	change the API. Python mappings have been provided, but the string
+	workarounds were too much of a pain with Cython 0.16 so I have
+	updated the Cython version requirement to 0.17 where it is
+	automatic and hence much cleaner.
+
 2013-03-08  Andy Buckley  <andy.buckley at cern.ch>
 
 	* Making the x2y converter scripts write a copy into the *current*

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/configure.ac	Fri Mar 15 09:52:27 2013	(r575)
@@ -74,10 +74,11 @@
 fi
 
 ## Cython checks (Probably need some help...)
+# TODO: "Tarball users" should ideally not need to have Cython installed
 if test x$enable_pyext == xyes; then
-  AM_CHECK_CYTHON([0.16], [:], [:])
+  AM_CHECK_CYTHON([0.17], [:], [:])
   if test x$CYTHON_FOUND != xyes; then
-    AC_MSG_ERROR([Can't build Python extension since Cython >= 0.16 could not be found])
+    AC_MSG_ERROR([Can't build Python extension since Cython >= 0.17 could not be found])
     enable_pyext=no
   else
     cython_compiler=$CXX

Modified: trunk/include/YODA/Reader.h
==============================================================================
--- trunk/include/YODA/Reader.h	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/include/YODA/Reader.h	Fri Mar 15 09:52:27 2013	(r575)
@@ -32,6 +32,8 @@
     ///
     /// This version fills (actually, appends to) a supplied vector, avoiding copying,
     /// and is hence CPU efficient.
+    ///
+    /// @todo Use SFINAE magic to allow ~arbitrary collection<AnalysisObject*> (with push_back()?) to be passed
     virtual void read(std::istream& stream, std::vector<AnalysisObject*>& aos) = 0;
 
     /// @brief Read in a collection of objects from output stream @a stream.
@@ -48,6 +50,8 @@
     ///
     /// This version fills (actually, appends to) a supplied vector, avoiding copying,
     /// and is hence CPU efficient.
+    ///
+    /// @todo Use SFINAE magic to allow ~arbitrary collection<AnalysisObject*> (with push_back()?) to be passed
     void read(const std::string& filename, std::vector<AnalysisObject*>& aos) {
       std::ifstream instream;
       instream.open(filename.c_str());
@@ -65,6 +69,43 @@
       return rtn;
     }
 
+    //@}
+
+
+    /// @name Static functions with automatic format detection
+    //@{
+
+    /// Factory function to make a writer object by format name or a filename
+    static Reader& makeReader(const std::string& format_name);
+
+    /// @brief Read in a collection of objects @a objs from file @a filename.
+    ///
+    /// This version fills (actually, appends to) a supplied vector, avoiding
+    /// copying, and is hence CPU efficient. The appropriate format reader will
+    /// be determined from the filename.
+    ///
+    /// @todo Use SFINAE magic to allow ~arbitrary collection<AnalysisObject*> (with push_back()?) to be passed
+    ///
+    /// @todo Better naming?
+    static void readFrom(const std::string& filename, std::vector<AnalysisObject*>& aos) {
+      Reader& r = makeReader(filename);
+      r.read(filename, aos);
+    }
+
+    /// @brief Read in a collection of objects from output stream @a stream.
+    ///
+    /// This version returns a vector by value, involving copying, and is hence
+    /// less CPU efficient than the alternative version where a vector is filled
+    /// by reference. The appropriate format reader will be determined from the
+    /// filename.
+    ///
+    /// @todo Better naming?
+    static std::vector<AnalysisObject*> readFrom(const std::string& filename) {
+      std::vector<AnalysisObject*> rtn;
+      readFrom(filename, rtn);
+      return rtn;
+    }
+
     //@}
 
   };

Modified: trunk/include/YODA/Writer.h
==============================================================================
--- trunk/include/YODA/Writer.h	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/include/YODA/Writer.h	Fri Mar 15 09:52:27 2013	(r575)
@@ -89,19 +89,23 @@
     //@}
 
 
-    /// @name Static functions with automatic file extension detection
+    /// @name Static functions with automatic format detection
     //@{
 
-    /// Factory function to make a writer object by format name or a filename (upper or lower case).
+    /// Factory function to make a writer object by format name or a filename
     static Writer& makeWriter(const std::string& format_name);
 
     /// Write out object @a ao to file @a filename
+    ///
+    /// @todo Better naming?
     static void writeTo(const std::string& filename, const AnalysisObject& ao) {
       Writer& w = makeWriter(filename);
       w.write(filename, ao);
     }
 
     /// Write out a collection of objects @a objs to file @a filename.
+    ///
+    /// @todo Better naming?
     template <typename RANGE>
     static void writeTo(const std::string& filename, const RANGE& aos) {
       Writer& w = makeWriter(filename);
@@ -110,6 +114,8 @@
 
     /// Write out the objects specified by start iterator @a begin and end
     /// iterator @a end to file @a filename.
+    ///
+    /// @todo Better naming?
     template <typename AOITER>
     static void writeTo(const std::string& filename, const AOITER& begin, const AOITER& end) {
       Writer& w = makeWriter(filename);

Modified: trunk/pyext/yoda/declarations.pxd
==============================================================================
--- trunk/pyext/yoda/declarations.pxd	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/pyext/yoda/declarations.pxd	Fri Mar 15 09:52:27 2013	(r575)
@@ -26,7 +26,6 @@
         void scaleW(double)
         void scaleX(double)
 
-
         double xMean() except+ err
         double xVariance() except+ err
         double xStdDev() except+ err
@@ -46,6 +45,7 @@
         Dbn1D operator- (Dbn1D) except+ err
 #}}} Dbn1D
 
+
 # Dbn2D {{{
 cdef extern from "YODA/Dbn2D.h" namespace "YODA":
     cdef cppclass Dbn2D:
@@ -92,6 +92,7 @@
         # TODO: += and -= operators in Cython (maybe 0.17?)
 #}}} Dbn2D
 
+
 # Dbn3D {{{
 cdef extern from "YODA/Dbn3D.h" namespace "YODA":
     cdef cppclass Dbn3D:
@@ -126,7 +127,6 @@
         double zStdErr()
         double zRMS()
 
-
         # Raw distribution running sums
         unsigned long numEntries()
         double effNumEntries()
@@ -162,6 +162,7 @@
         # TODO: += and -= operators in Cython (maybe 0.17?)
 #}}} Dbn3D
 
+
 # Points
 
 # Point2D {{{
@@ -197,6 +198,7 @@
         bool operator >= (Point2D b) except+ err
 # }}} Point2D
 
+
 # Point3D {{{
 cdef extern from "YODA/Point3D.h" namespace "YODA":
     cdef cppclass Point3D:
@@ -239,6 +241,7 @@
         bool operator >= (Point3D b)
 #}}} Point3D
 
+
 # Bins
 
 # Bin {{{
@@ -247,6 +250,7 @@
         pass
 # }}} Bin
 
+
 #Bin1D {{{
 cdef extern from "YODA/Bin1D.h" namespace "YODA":
     cdef cppclass Bin1D[DBN](Bin):
@@ -295,6 +299,7 @@
 ctypedef Bin1D[Dbn3D] Bin1D_Dbn3D
 #}}} Bin1D
 
+
 # Bin2D {{{
 cdef extern from "YODA/Bin2D.h" namespace "YODA":
     cdef cppclass Bin2D[DBN](Bin):
@@ -354,6 +359,7 @@
 ctypedef Bin2D[Dbn3D] Bin2D_Dbn3D
 # }}} Bin2D
 
+
 # ProfileBin1D {{{
 cdef extern from "YODA/ProfileBin1D.h" namespace "YODA":
 
@@ -417,7 +423,6 @@
         HistoBin1D operator+(HistoBin1D) except +err
         HistoBin1D operator-(HistoBin1D) except +err
 
-
 #}}} HistoBin1D
 
 
@@ -478,6 +483,7 @@
         string type() except +err
 # }}} AnalysisObject
 
+
 cdef extern from "YODA/Utils/sortedvector.h" namespace "YODA::Utils":
     cdef cppclass sortedvector[T](vector):
         sortedvector(vector[T]) except +err
@@ -485,6 +491,7 @@
 
 # TODO: forward declarations for bin-copying constructors
 
+
 # Scatter2D {{{
 cdef extern from "YODA/Scatter2D.h" namespace "YODA":
     cdef cppclass Scatter2D(AnalysisObject):
@@ -520,6 +527,7 @@
 
 #}}} Scatter2D
 
+
 # Scatter3D {{{
 cdef extern from "YODA/Scatter3D.h" namespace "YODA":
     cdef cppclass Scatter3D(AnalysisObject):
@@ -551,6 +559,7 @@
         Scatter3D combineWith(vector[Scatter3D])
 #}}} Scatter3D
 
+
 # Profile1D {{{
 cdef extern from "YODA/Profile1D.h" namespace "YODA":
     cdef cppclass Profile1D(AnalysisObject):
@@ -603,6 +612,7 @@
 
 #}}} Profile1D
 
+
 # Profile2D {{{
 cdef extern from "YODA/Profile2D.h" namespace "YODA":
     cdef cppclass Profile2D(AnalysisObject):
@@ -655,6 +665,7 @@
 
 #}}} Profile2D
 
+
 # Histo1D#{{{
 cdef extern from "YODA/Histo1D.h" namespace "YODA":
     cdef cppclass Histo1D(AnalysisObject):
@@ -700,6 +711,7 @@
         void eraseBin(size_t index) except+ err
 #}}} Histo1D
 
+
 # Histo2D {{{
 cdef extern from "YODA/Histo2D.h" namespace "YODA":
     cdef cppclass Histo2D(AnalysisObject):
@@ -753,8 +765,6 @@
         double highEdgeX() except+ err
         double highEdgeY() except+ err
 
-
-
         int findBinIndex(double, double)
         size_t numBinsX()
         size_t numBinsY()
@@ -779,7 +789,9 @@
         operator / (Histo2D)
 # Histo2D }}}
 
+
 # Streams {{{
+
 cdef extern from "<sstream>" namespace "std":
     cdef cppclass ostringstream:
         ostringstream()
@@ -790,6 +802,7 @@
         istringstream()
         string& str(string &)
 
+
 cdef extern from "YODA/Reader.h" namespace "YODA":
     cdef cppclass Reader:
         void read(istringstream &, vector[AnalysisObject*] &) except +err
@@ -800,6 +813,9 @@
 cdef extern from "YODA/ReaderAIDA.h" namespace "YODA":
     Reader& ReaderAIDA_create "YODA::ReaderAIDA::create" ()
 
+cdef extern from "YODA/Reader.h" namespace "YODA":
+    Reader& Reader_create "YODA::Reader::makeReader" (string& filename)
+
 
 cdef extern from "YODA/Writer.h" namespace "YODA":
     cdef cppclass Writer:
@@ -813,8 +829,13 @@
 
 cdef extern from "YODA/WriterAIDA.h" namespace "YODA":
     Writer& WriterAIDA_create "YODA::WriterAIDA::create" ()
+
+cdef extern from "YODA/Reader.h" namespace "YODA":
+    Writer& Writer_create "YODA::Writer::makeWriter" (string& filename)
+
 # Streams }}}
 
+
 # Axis1D {{{
 cdef extern from "YODA/Axis1D.h" namespace "YODA":
     cdef cppclass Axis1D[BIN1D, DBN]:

Modified: trunk/pyext/yoda/include/IO.pyx
==============================================================================
--- trunk/pyext/yoda/include/IO.pyx	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/pyext/yoda/include/IO.pyx	Fri Mar 15 09:52:27 2013	(r575)
@@ -27,6 +27,22 @@
 ## Readers
 ##
 
+def readFrom(filename):
+    """
+    Read data objects from the provided filename,
+    auto-determining the format from the file extension.
+    Returns a list of analysis objects
+    """
+    cdef c.istringstream iss
+    cdef vector[c.AnalysisObject*] aobjects
+    with open(filename) as f:
+        s = f.read()
+    make_iss(iss, s)
+    c.Reader_create(filename).read(iss, aobjects)
+    # Not as expensive as it looks!
+    return aobjects_to_list(&aobjects)
+
+
 def readYODA(file_or_filename):
     """
     Read data objects from the provided YODA-format file.
@@ -73,6 +89,21 @@
 ## Writers
 ##
 
+def writeTo(ana_objs, filename):
+    """
+    Write data objects to the provided filename,
+    auto-determining the format from the file extension.
+    """
+    cdef c.ostringstream oss
+    cdef vector[c.AnalysisObject*] vec
+    cdef AnalysisObject a
+    for a in ana_objs:
+        vec.push_back(a._AnalysisObject())
+    c.Writer_create(filename).write(oss, vec)
+    with open(filename, 'w') as f:
+        f.write(oss.str())
+
+
 def writeYODA(ana_objs, file_or_filename):
     """
     Write data objects to the provided file in YODA format.

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/src/Makefile.am	Fri Mar 15 09:52:27 2013	(r575)
@@ -4,6 +4,7 @@
 
 ## Compile ReaderYODA first: since it takes longest, this speeds up -jN compilation!
 libYODA_la_SOURCES = \
+    Reader.cc \
     ReaderYODA.cc \
     ReaderAIDA.cc \
     Writer.cc \

Added: trunk/src/Reader.cc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/Reader.cc	Fri Mar 15 09:52:27 2013	(r575)
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+//
+// This file is part of YODA -- Yet more Objects for Data Analysis
+// Copyright (C) 2008-2013 The YODA collaboration (see AUTHORS for details)
+//
+#include "YODA/Reader.h"
+#include "YODA/ReaderYODA.h"
+#include "YODA/ReaderAIDA.h"
+
+using namespace std;
+
+namespace YODA {
+
+
+  Reader& Reader::makeReader(const string& name) {
+    const size_t lastdot = name.find_last_of(".");
+    const string fmt = boost::to_lower_copy((lastdot == string::npos) ? name : name.substr(lastdot+1));
+    if (fmt == "yoda") return ReaderYODA::create();
+    if (fmt == "aida") return ReaderAIDA::create();
+    throw UserError("Format cannot be identified from string '" + name + "'");
+  }
+
+
+}

Modified: trunk/src/Writer.cc
==============================================================================
--- trunk/src/Writer.cc	Fri Mar  8 17:25:00 2013	(r574)
+++ trunk/src/Writer.cc	Fri Mar 15 09:52:27 2013	(r575)
@@ -3,7 +3,6 @@
 // This file is part of YODA -- Yet more Objects for Data Analysis
 // Copyright (C) 2008-2013 The YODA collaboration (see AUTHORS for details)
 //
-
 #include "YODA/Writer.h"
 #include "YODA/WriterYODA.h"
 #include "YODA/WriterAIDA.h"
@@ -45,6 +44,9 @@
 
   void Writer::writeBody(std::ostream& stream, const AnalysisObject& ao) {
     const string aotype = ao.type();
+    // if (aotype == "Counter") {
+    //   writeCounter(stream, dynamic_cast<const Counter&>(ao));
+    // } else
     if (aotype == "Histo1D") {
       writeHisto1D(stream, dynamic_cast<const Histo1D&>(ao));
     } else if (aotype == "Histo2D") {
@@ -53,6 +55,8 @@
       writeProfile1D(stream, dynamic_cast<const Profile1D&>(ao));
     // } else if (aotype == "Profile2D") {
     //   writeProfile2D(stream, dynamic_cast<const Profile2D&>(ao));
+    // } else if (aotype == "Scatter1D") {
+    //   writeScatter1D(stream, dynamic_cast<const Scatter1D&>(ao));
     } else if (aotype == "Scatter2D") {
       writeScatter2D(stream, dynamic_cast<const Scatter2D&>(ao));
     // } else if (aotype == "Scatter3D") {


More information about the yoda-svn mailing list