diff --git a/crlcore/etc/display.xml b/crlcore/etc/display.xml
index 72579b15..74a315f7 100644
--- a/crlcore/etc/display.xml
+++ b/crlcore/etc/display.xml
@@ -171,7 +171,7 @@
-
+
diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt
index e494a187..e35831ac 100644
--- a/crlcore/src/ccore/CMakeLists.txt
+++ b/crlcore/src/ccore/CMakeLists.txt
@@ -42,6 +42,7 @@
set ( includes crlcore/Utilities.h
crlcore/Memory.h
crlcore/Banner.h
+ crlcore/Histogram.h
crlcore/COptions.h
crlcore/XmlParser.h
crlcore/GdsDriver.h
@@ -83,6 +84,7 @@
Memory.cpp
Banner.cpp
COptions.cpp
+ Histogram.cpp
XmlParser.cpp
GdsDriver.cpp
OAParserDriver.cpp
diff --git a/crlcore/src/ccore/Catalog.cpp b/crlcore/src/ccore/Catalog.cpp
index 704cb9c5..b25e1ca1 100644
--- a/crlcore/src/ccore/Catalog.cpp
+++ b/crlcore/src/ccore/Catalog.cpp
@@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
+// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
diff --git a/crlcore/src/ccore/Histogram.cpp b/crlcore/src/ccore/Histogram.cpp
new file mode 100644
index 00000000..a19c7232
--- /dev/null
+++ b/crlcore/src/ccore/Histogram.cpp
@@ -0,0 +1,204 @@
+
+// -*- C++ -*-
+//
+// This file is part of the Coriolis Software.
+// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
+//
+// ===================================================================
+//
+// $Id$
+//
+// x-----------------------------------------------------------------x
+// | |
+// | C O R I O L I S |
+// | Alliance / Hurricane Interface |
+// | |
+// | Author : Jean-Paul CHAPUT |
+// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+// | =============================================================== |
+// | C++ Module : "./Histogram.cpp" |
+// | *************************************************************** |
+// | U p d a t e s |
+// | |
+// x-----------------------------------------------------------------x
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+namespace bfs = boost::filesystem;
+
+#include "crlcore/Histogram.h"
+
+
+
+namespace CRL {
+
+ using std::string;
+ using std::ostream;
+ using std::ofstream;
+ using std::ostringstream;
+ using std::setprecision;
+ using std::vector;
+ using Hurricane::Record;
+
+
+ Histogram::Histogram ( double range, double step, size_t nbSets )
+ : _range (range)
+ , _step (step)
+ , _mainTitle ()
+ , _titles (nbSets)
+ , _colors (nbSets)
+ , _sets (nbSets)
+ , _totalSamples (nbSets)
+ , _fileExtension()
+ {
+ size_t binSize = (size_t)rint ( _range / _step );
+ for ( size_t iset=0 ; iset(binSize);
+ }
+ }
+
+
+ Histogram::~Histogram ()
+ { }
+
+
+ void Histogram::addSample ( double sample, size_t iset )
+ {
+ if ( iset > _sets.size() ) return;
+
+ size_t binIndex = (size_t)rint ( sample / _step );
+ if ( binIndex > _sets.front().size() ) binIndex = _sets.front().size() - 1;
+
+ _sets [iset][binIndex] += 1.0;
+ _totalSamples[iset]++;
+ }
+
+
+ float Histogram::getYRange () const
+ {
+ float yrange = 0.0;
+
+ for ( size_t iset=0 ; iset<_sets.size() ; ++iset ) {
+ for ( size_t i=0 ; i<_sets[iset].size() ; ++i )
+ yrange = std::max ( yrange, _sets[iset][i] );
+ }
+
+ return ceil(yrange*10.0) / 10.0;
+ }
+
+
+ void Histogram::normalize ( size_t iset )
+ {
+ if ( iset > _sets.size() ) return;
+ for ( size_t i=0 ; i<_sets[iset].size() ; ++i ) _sets[iset][i] /= (float)_totalSamples[iset];
+ }
+
+
+ void Histogram::toStream ( ostream& o )
+ {
+ o << setprecision(3);
+
+ for ( size_t i=0 ; i<_sets.front().size() ; ++i ) {
+ for ( size_t iset=0 ; iset<_sets.size() ; ++iset ) {
+ o << _sets[iset][i] << " ";
+ }
+ o << "\n";
+ }
+ }
+
+
+ void Histogram::toFile ( const string& path )
+ {
+ ofstream fd ( path.c_str() );
+ toStream ( fd );
+ fd.close ();
+ }
+
+
+ void Histogram::toGnuplot ( const string& basename )
+ {
+ bfs::path datFile = basename + _fileExtension + ".dat";
+ toFile ( datFile.string() );
+
+ bfs::path pltFile = basename + _fileExtension + ".plt";
+ bfs::ofstream fd ( pltFile );
+
+ if ( not _mainTitle.empty() )
+ fd << "set title \"" << _mainTitle << "\"\n";
+
+ fd << "set grid\n";
+ fd << "set grid noxtics\n";
+ fd << "set xrange [-0.5:9.5]\n";
+ fd << "set xtics ( ";
+ for ( size_t i=0 ; i<10 ; ++i ) {
+ fd << ((i) ? " ," : "") << "\"<" << ((i+1)*10) << "%%\" " << i;
+ }
+ fd << " )\n";
+
+ fd << "set yrange [0:" << setprecision(3) << getYRange() << "]\n";
+ fd << "set ytics ( ";
+ for ( float i=0.0 ; i<=40.0 ; i+=10.0 ) {
+ fd << ((i != 0.0) ? " ," : "") << "\"" << i << "%%\" " << (i/100.0);
+ }
+ fd << " )\n";
+
+ fd << "set style histogram cluster gap 1\n";
+ fd << "set style fill solid noborder\n";
+ fd << "set boxwidth 1\n";
+
+ for ( size_t iset=0 ; iset<_sets.size() ; ++iset ) {
+ fd << ((iset) ? " " : "plot ");
+ fd << "\"" << datFile.string() << "\" using " << (iset+1);
+
+ if ( not _titles[iset].empty() ) fd << " title \"" << _titles[iset] << "\"";
+
+ fd << " with histogram";
+
+ if ( not _colors[iset].empty() ) fd << " linecolor rgb \"" << _colors[iset] << "\"";
+
+ fd << ((iset+1==_sets.size()) ? "\n" : ", \\\n");
+ }
+
+ fd.close ();
+ }
+
+
+ string Histogram::_getString () const
+ {
+ ostringstream s;
+ s << "";
+ return s.str();
+ }
+
+
+ Record* Histogram::_getRecord () const
+ {
+ Record* record = new Record ( _getString() );
+ if ( record ) {
+ record->add ( getSlot("_mainTitle",_mainTitle) );
+ for ( size_t iset=0 ; iset<_sets.size() ; ++iset ) {
+ ostringstream attributeName;
+ attributeName << "_titles[" << iset << "]";
+ record->add ( getSlot(attributeName.str(),&_titles[iset]) );
+
+ attributeName.str("");
+ attributeName << "_colors[" << iset << "]";
+ record->add ( getSlot(attributeName.str(),&_colors[iset]) );
+
+ attributeName.str("");
+ attributeName << "_sets[" << iset << "]";
+ record->add ( getSlot(attributeName.str(),&_sets[iset]) );
+ }
+ record->add ( getSlot("_fileExtension",_fileExtension) );
+ }
+
+ return record;
+ }
+
+
+} // End of CRL namespace.
diff --git a/crlcore/src/ccore/crlcore/Histogram.h b/crlcore/src/ccore/crlcore/Histogram.h
new file mode 100644
index 00000000..bf8e2183
--- /dev/null
+++ b/crlcore/src/ccore/crlcore/Histogram.h
@@ -0,0 +1,126 @@
+
+// -*- C++ -*-
+//
+// This file is part of the Coriolis Software.
+// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
+//
+// ===================================================================
+//
+// $Id$
+//
+// x-----------------------------------------------------------------x
+// | |
+// | C O R I O L I S |
+// | Alliance / Hurricane Interface |
+// | |
+// | Author : Jean-Paul Chaput |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
+// | =============================================================== |
+// | C++ Header : "./Histogram.h" |
+// | *************************************************************** |
+// | U p d a t e s |
+// | |
+// x-----------------------------------------------------------------x
+
+
+#ifndef __CRL_HISTOGRAM__
+#define __CRL_HISTOGRAM__
+
+#include
+#include
+#include
+#include "hurricane/Commons.h"
+#include "crlcore/Measures.h"
+
+
+namespace CRL {
+
+
+ class Histogram {
+ public:
+ Histogram ( double range, double step, size_t nbSets );
+ ~Histogram ();
+ inline void setMainTitle ( const std::string& );
+ inline void setTitle ( const std::string&, size_t iset );
+ inline void setColor ( const std::string&, size_t iset );
+ void addSample ( double, size_t iset );
+ inline void setFileExtension ( const std::string& );
+ float getYRange () const;
+ void toStream ( std::ostream& );
+ void toFile ( const std::string& );
+ void toGnuplot ( const std::string& basename );
+ void normalize ( size_t iset );
+ std::string _getString () const;
+ Hurricane::Record* _getRecord () const;
+ private:
+ double _range;
+ double _step;
+ std::string _mainTitle;
+ std::vector< std::string > _titles;
+ std::vector< std::string > _colors;
+ std::vector< std::vector > _sets;
+ std::vector< int > _totalSamples;
+ std::string _fileExtension;
+ };
+
+
+// Inline Functions.
+ inline void Histogram::setMainTitle ( const std::string& title ) { _mainTitle=title; }
+ inline void Histogram::setTitle ( const std::string& title, size_t iset ) { if (iset<_titles.size()) _titles[iset] = title; }
+ inline void Histogram::setColor ( const std::string& color, size_t iset ) { if (iset<_colors.size()) _colors[iset] = color; }
+ inline void Histogram::setFileExtension ( const std::string& extension ) { _fileExtension=extension; }
+
+
+ template<>
+ class Measure : public BaseMeasure {
+ public:
+ inline Measure ( const Name&, Histogram* );
+ virtual ~Measure ();
+ virtual bool isSimpleData () const;
+ inline Histogram* getData () const;
+ inline void setData ( Histogram* );
+ virtual std::string toString () const;
+ virtual void toGnuplot ( const std::string& basename ) const;
+ virtual std::string _getString () const;
+ virtual Record* _getRecord () const;
+ private:
+ Histogram* _data;
+ };
+
+
+ inline Measure::Measure ( const Name& name, Histogram* data )
+ : BaseMeasure(name,0), _data(data) { }
+
+ Measure::~Measure () { delete _data; }
+
+ bool Measure::isSimpleData () const { return false; }
+
+ inline Histogram* Measure::getData () const { return _data; }
+
+ inline void Measure::setData ( Histogram* data ) { _data=data; }
+
+ std::string Measure::toString () const
+ { return "Unsupported"; }
+
+ void Measure::toGnuplot ( const std::string& basename ) const
+ { _data->toGnuplot ( basename ); }
+
+ std::string Measure::_getString () const
+ { return ""; }
+
+ Record* Measure::_getRecord () const
+ {
+ Record* record = new Record ( _getString() );
+ if ( record ) {
+ record->add ( getSlot("_data",_data) );
+ }
+ return record;
+ }
+
+
+} // End of CRL namespace.
+
+
+INSPECTOR_P_SUPPORT(CRL::Histogram)
+
+#endif // __CRL_HISTOGRAM__
diff --git a/crlcore/src/ccore/crlcore/Measures.h b/crlcore/src/ccore/crlcore/Measures.h
index 7b60ac13..40148bd5 100644
--- a/crlcore/src/ccore/crlcore/Measures.h
+++ b/crlcore/src/ccore/crlcore/Measures.h
@@ -23,8 +23,8 @@
// x-----------------------------------------------------------------x
-#ifndef __STATISTICS_PROPERTY__
-#define __STATISTICS_PROPERTY__
+#ifndef __CRL_MEASURES_PROPERTY__
+#define __CRL_MEASURES_PROPERTY__
#include
#include
@@ -55,9 +55,13 @@ namespace CRL {
public:
inline BaseMeasure ( const Name&, unsigned int width );
virtual ~BaseMeasure ();
+ virtual bool isSimpleData () const;
inline const Name& getName () const;
inline unsigned int getFieldWidth () const;
virtual std::string toString () const = 0;
+ virtual void toGnuplot ( const std::string& basename ) const;
+ virtual std::string _getString () const;
+ virtual Record* _getRecord () const;
private:
Name _name;
unsigned int _fieldWidth;
@@ -72,10 +76,12 @@ namespace CRL {
template
class Measure : public BaseMeasure {
public:
- inline Measure ( const Name&, const Data&, unsigned int width );
- inline const Data& getData () const;
- inline void setData ( const Data& );
- virtual std::string toString () const;
+ inline Measure ( const Name&, const Data&, unsigned int width );
+ inline const Data& getData () const;
+ inline void setData ( const Data& );
+ virtual std::string toString () const;
+ virtual std::string _getString () const;
+ virtual Record* _getRecord () const;
private:
Data _data;
};
@@ -85,7 +91,6 @@ namespace CRL {
inline Measure::Measure ( const Name& name, const Data& data, unsigned int width )
: BaseMeasure(name,width), _data(data) { }
-
template
inline const Data& Measure::getData () const { return _data; }
@@ -96,12 +101,29 @@ namespace CRL {
std::string Measure::toString () const
{ std::ostringstream s; s << std::fixed << std::setprecision(2) << _data; return s.str(); }
+ template
+ std::string Measure::_getString () const
+ { return ""; }
+
+ template
+ Record* Measure::_getRecord () const
+ {
+ Record* record = new Record ( _getString() );
+ if ( record ) {
+ record->add ( getSlot("_data",&_data) );
+ }
+ return record;
+ }
+
class MeasuresSet : public std::map {
public:
~MeasuresSet ();
std::string toStringHeaders ( const std::vector& ) const;
std::string toStringDatas ( const std::vector& ) const;
+ void toGnuplot ( Name, const std::string& ) const;
+ std::string _getString () const;
+ Record* _getRecord () const;
};
@@ -112,19 +134,18 @@ namespace CRL {
class MeasuresDatas {
public:
MeasuresDatas ();
+ MeasuresDatas ( const MeasuresDatas& );
inline std::string _getTypeName () const;
inline std::string _getString () const;
inline Record* _getRecord () const;
public:
MeasuresSet _measures;
- private:
- MeasuresDatas ( const MeasuresDatas& );
};
inline std::string MeasuresDatas::_getTypeName () const { return "MeasuresDatas"; }
inline std::string MeasuresDatas::_getString () const { return ""; }
- inline Record* MeasuresDatas::_getRecord () const { return NULL; }
+ inline Record* MeasuresDatas::_getRecord () const { return _measures._getRecord(); }
// -------------------------------------------------------------------
@@ -133,9 +154,10 @@ namespace CRL {
class Measures {
public:
- typedef StandardPrivateProperty Extension;
+ typedef StandardPrivateProperty Extension;
public:
template friend inline void addMeasure ( DBo*, const Name&, const Data&, unsigned int width=8 );
+ template friend inline void addMeasure ( DBo*, const Name&, Data* );
template friend inline const Measure* getMeasure ( DBo*, const Name& );
static const MeasuresSet* get ( const DBo* );
private:
@@ -147,7 +169,15 @@ namespace CRL {
inline void addMeasure ( DBo* object, const Name& name, const Data& data, unsigned int width )
{
Measures::Extension* extension = Measures::_getOrCreate ( object );
- extension->getValue()->_measures.insert ( std::make_pair(name,new Measure(name,data,width)) );
+ extension->getValue()._measures.insert ( std::make_pair(name,new Measure(name,data,width)) );
+ }
+
+
+ template
+ inline void addMeasure ( DBo* object, const Name& name, Data* data )
+ {
+ Measures::Extension* extension = Measures::_getOrCreate ( object );
+ extension->getValue()._measures.insert ( std::make_pair(name,new Measure(name,data)) );
}
@@ -155,9 +185,9 @@ namespace CRL {
inline const Measure* getMeasure ( DBo* object, const Name& name )
{
Measures::Extension* extension = Measures::_getOrCreate ( object );
- MeasuresSet::iterator imeasure = extension->getValue()->_measures.find(name);
+ MeasuresSet::iterator imeasure = extension->getValue()._measures.find(name);
- if ( imeasure != extension->getValue()->_measures.end() )
+ if ( imeasure != extension->getValue()._measures.end() )
return static_cast< Measure* >( (*imeasure).second );
return NULL;
@@ -167,7 +197,8 @@ namespace CRL {
} // End of CRL namespace.
+INSPECTOR_P_SUPPORT(CRL::BaseMeasure);
INSPECTOR_P_SUPPORT(CRL::MeasuresDatas);
-#endif // __STATISTICS_PROPERTY__
+#endif // __CRL_MEASURES_PROPERTY__
diff --git a/crlcore/src/ccore/properties/Measures.cpp b/crlcore/src/ccore/properties/Measures.cpp
index c7832465..e9805477 100644
--- a/crlcore/src/ccore/properties/Measures.cpp
+++ b/crlcore/src/ccore/properties/Measures.cpp
@@ -37,6 +37,8 @@ namespace CRL {
using std::string;
using std::vector;
using std::ostringstream;
+ using std::cerr;
+ using std::endl;
using std::setw;
using std::right;
using Hurricane::Error;
@@ -44,23 +46,24 @@ namespace CRL {
// -------------------------------------------------------------------
-// Class : "CRL::MeasuresSet".
+// Class : "CRL::BaseMeasure".
- BaseMeasure::~BaseMeasure () {}
-
-
- const char* MissingMeasures = "Measures::%s(): %s missing the Measures extension.";
-
-
- template<>
- Name StandardPrivateProperty::_name = "CRL::Measures";
+ BaseMeasure::~BaseMeasure () {}
+ bool BaseMeasure::isSimpleData () const { return true; }
+ void BaseMeasure::toGnuplot ( const string& ) const {}
+ string BaseMeasure::_getString () const { return ""; }
+ Record* BaseMeasure::_getRecord () const { return NULL; }
// -------------------------------------------------------------------
// Class : "CRL::MeasuresSet".
+ template<>
+ Name StandardPrivateProperty::_name = "CRL::Measures";
+
+
MeasuresSet::~MeasuresSet ()
{
iterator imeasure = begin();
@@ -79,7 +82,8 @@ namespace CRL {
if ( imeasure == end() ) continue;
const BaseMeasure* measure = (*imeasure).second;
- out << setw(measure->getFieldWidth()) << right << measure->getName();
+ if ( measure->isSimpleData() )
+ out << setw(measure->getFieldWidth()) << right << measure->getName();
}
return out.str();
@@ -96,12 +100,46 @@ namespace CRL {
if ( imeasure == end() ) continue;
const BaseMeasure* measure = (*imeasure).second;
- out << setw(measure->getFieldWidth()) << right << measure->toString();
+ if ( measure->isSimpleData() )
+ out << setw(measure->getFieldWidth()) << right << measure->toString();
}
return out.str();
}
+
+ void MeasuresSet::toGnuplot ( Name name, const string& basename ) const
+ {
+ const_iterator imeasure = find ( name );
+ if ( imeasure == end() ) return;
+
+ const BaseMeasure* measure = (*imeasure).second;
+ if ( measure->isSimpleData() ) return;
+
+ measure->toGnuplot ( basename );
+ }
+
+
+ string MeasuresSet::_getString () const
+ {
+ ostringstream s;
+ s << "";
+ return s.str();
+ }
+
+
+ Record* MeasuresSet::_getRecord () const
+ {
+ Record* record = new Record ( _getString() );
+ if ( record ) {
+ const_iterator imeasure = begin();
+ for ( ; imeasure != end() ; ++imeasure ) {
+ record->add ( getSlot ( getString((*imeasure).first), ((*imeasure).second) ) );
+ }
+ }
+ return record;
+ }
+
// -------------------------------------------------------------------
// Class : "CRL::MeasuresDatas".
@@ -112,15 +150,28 @@ namespace CRL {
{ }
+ MeasuresDatas::MeasuresDatas ( const MeasuresDatas& other )
+ : _measures()
+ {
+ // if ( not other._measures.empty() ) {
+ // cerr << Error("MeasuresDatas copy constructor called on non-empty MeasuresDatas is forbidden.\n"
+ // "(source has %u elements)", other._measures.size() ) << endl;
+ // }
+ }
+
+
// -------------------------------------------------------------------
// Class : "CRL::Measures".
+ const char* MissingMeasures = "Measures::%s(): %s missing the Measures extension.";
+
+
const MeasuresSet* Measures::get ( const DBo* object )
{
Extension* extension = Extension::get ( object );
if ( extension != NULL )
- return &extension->getValue()->_measures;
+ return &extension->getValue()._measures;
return NULL;
}
@@ -130,7 +181,7 @@ namespace CRL {
{
Extension* extension = Extension::get ( object );
if ( extension == NULL ) {
- extension = Extension::create ( new MeasuresDatas() );
+ extension = Extension::create ( MeasuresDatas() );
object->put ( extension );
}
return extension;