|
[yoda-svn] r575 - in trunk: . include/YODA pyext/yoda pyext/yoda/include srcblackhole at projects.hepforge.org blackhole at projects.hepforge.orgFri 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 |