# eoFileSnapshot.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoFileSnapshot.h
    00005 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2001
    00006 /*
    00007     This library is free software; you can redistribute it and/or
    00008     modify it under the terms of the GNU Lesser General Public
    00009     License as published by the Free Software Foundation; either
    00010     version 2 of the License, or (at your option) any later version.
    00011
    00012     This library is distributed in the hope that it will be useful,
    00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015     Lesser General Public License for more details.
    00016
    00017     You should have received a copy of the GNU Lesser General Public
    00018     License along with this library; if not, write to the Free Software
    00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00020
    00021     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
    00022              Marc.Schoenauer@polytechnique.fr
    00023              mkeijzer@dhi.dk
    00024  */
    00025 //-----------------------------------------------------------------------------
    00026
    00027 #ifndef _eoFileSnapshot_h
    00028 #define _eoFileSnapshot_h
    00029
    00030 #include <string>
    00031 #include <fstream>
    00032 #include <utils/eoParam.h>
    00033 #include <utils/eoMonitor.h>
    00034 #include <eoObject.h>
    00035
    00036
    00053 class eoFileSnapshot : public eoMonitor
    00054 {
    00055 public :
    00056   typedef std::vector<double> vDouble;
    00057   typedef eoValueParam<std::vector<double> > vDoubleParam;
    00058
    00059   eoFileSnapshot(std::string _dirname, unsigned _frequency = 1, std::string _filename = "gen",
    00060               std::string _delim = " ", unsigned _counter = 0, bool _rmFiles = true):
    00061     dirname(_dirname), frequency(_frequency),
    00062     filename(_filename), delim(_delim), counter(_counter), boolChanged(true)
    00063   {
    00064     std::string s = "test -d " + dirname;
    00065
    00066     int res = system(s.c_str());
    00067     // test for (unlikely) errors
    00068     if ( (res==-1) || (res==127) )
    00069       throw std::runtime_error("Problem executing test of dir in eoFileSnapshot");
    00070     // now make sure there is a dir without any genXXX file in it
    00071     if (res)                    // no dir present
    00072       {
    00073         s = std::string("mkdir ")+dirname;
    00074       }
    00075     else if (!res && _rmFiles)
    00076       {
    00077         s = std::string("/bin/rm ")+dirname+ "/" + filename + "*";
    00078       }
    00079     else
    00080       s = " ";
    00081
    00082     system(s.c_str());
    00083     // all done
    00084   }
    00085
    00088   virtual bool hasChanged() {return boolChanged;}
    00089
    00092   unsigned getCounter() {return counter;}
    00093
    00096   std::string getFileName() {return currentFileName;}
    00097
    00100   void setCurrentFileName()
    00101   {
    00102       std::ostringstream oscount;
    00103       oscount << counter;
    00104       currentFileName = dirname + "/" + filename + oscount.str();
    00105   }
    00106
    00109   eoMonitor& operator()(void)
    00110   {
    00111     if (counter % frequency)
    00112       {
    00113         boolChanged = false;  // subclass with gnuplot will do nothing
    00114         counter++;
    00115         return (*this);
    00116       }
    00117     counter++;
    00118     boolChanged = true;
    00119     setCurrentFileName();
    00120     std::ofstream os(currentFileName.c_str());
    00121
    00122     if (!os)
    00123       {
    00124         std::string str = "eoFileSnapshot: Could not open " + currentFileName;
    00125         throw std::runtime_error(str);
    00126       }
    00127
    00128     return operator()(os);
    00129   }
    00130
    00133   eoMonitor& operator()(std::ostream& _os)
    00134   {
    00135     const eoValueParam<std::vector<double> >  * ptParam =
    00136       static_cast<const eoValueParam<std::vector<double> >* >(vec[0]);
    00137
    00138     const std::vector<double>  v = ptParam->value();
    00139     if (vec.size() == 1)           // only one std::vector: -> add number in front
    00140       {
    00141         for (unsigned k=0; k<v.size(); k++)
    00142           _os << k << " " << v[k] << "\n" ;
    00143       }
    00144     else                           // need to get all other std::vectors
    00145       {
    00146         std::vector<std::vector<double> > vv(vec.size());
    00147         vv[0]=v;
    00148         for (unsigned i=1; i<vec.size(); i++)
    00149           {
    00150             ptParam = static_cast<const eoValueParam<std::vector<double> >* >(vec[1]);
    00151             vv[i] = ptParam->value();
    00152             if (vv[i].size() != v.size())
    00153               throw std::runtime_error("Dimension error in eoSnapshotMonitor");
    00154           }
    00155         for (unsigned k=0; k<v.size(); k++)
    00156           {
    00157           for (unsigned i=0; i<vec.size(); i++)
    00158             _os << vv[i][k] << " " ;
    00159           _os << "\n";
    00160           }
    00161       }
    00162     return *this;
    00163    }
    00164
    00165   virtual const std::string getDirName()           // for eoGnuPlot
    00166   { return dirname;}
    00167   virtual const std::string baseFileName()         // the title for eoGnuPlot
    00168   { return filename;}
    00169
    00171   void add(const eoParam& _param)
    00172   {
    00173     if (!dynamic_cast<const eoValueParam<std::vector<double> >*>(&_param))
    00174     {
    00175       throw std::logic_error(std::string("eoFileSnapshot: I can only monitor std::vectors of doubles, sorry. The offending parameter name = ") + _param.longName());
    00176     }
    00177     eoMonitor::add(_param);
    00178   }
    00179
    00180 private :
    00181   std::string dirname;
    00182   unsigned frequency;
    00183   std::string filename;
    00184   std::string delim;
    00185   unsigned int counter;
    00186   std::string currentFileName;
    00187   bool boolChanged;
    00188 };
    00189
    00190 #endif