Initial addition of tools/diagram-viewer dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Thu, 25 Dec 2008 14:24:02 -0800
branchdev
changeset 99 6c0da7931e4d
parent 98 d81e460e267a
child 100 884f70adc576
Initial addition of tools/diagram-viewer
CMakeLists.txt
include/topology/filtration.h
include/topology/persistence-diagram.h
include/topology/persistence-diagram.hpp
include/topology/static-persistence.hpp
include/utilities/types.h
tools/CMakeLists.txt
tools/diagram-viewer/CMakeLists.txt
tools/diagram-viewer/diagram-viewer-main.cpp
tools/diagram-viewer/diagram.cpp
tools/diagram-viewer/diagram.h
--- a/CMakeLists.txt	Tue Dec 23 11:02:08 2008 -0800
+++ b/CMakeLists.txt	Thu Dec 25 14:24:02 2008 -0800
@@ -104,3 +104,4 @@
 # Process subdirectories
 add_subdirectory			(examples)
 add_subdirectory			(tests)
+add_subdirectory			(tools)
--- a/include/topology/filtration.h	Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/filtration.h	Thu Dec 25 14:24:02 2008 -0800
@@ -10,6 +10,10 @@
 
 // Class: Filtration
 //
+// Filtration keeps track of the ordering of the simplices in a complex. 
+// The most significant function it provides is <boundary()> which converts
+// the boundary of a simplex at a given index into a list of indices.
+//
 // TODO: this is really specialized for an std::vector<> Complex; eventually generalize
 // TODO: should we derive from Order?
 template<class Complex_, 
--- a/include/topology/persistence-diagram.h	Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/persistence-diagram.h	Thu Dec 25 14:24:02 2008 -0800
@@ -15,12 +15,14 @@
  *
  * Stores birth-death pair plus any additional information provided by `Data` template parameter.
  */
-template<class Data_>
+template<class Data_ = Empty>
 class PDPoint
 {
     public:
         typedef                 Data_                                       Data;
 
+                                PDPoint(const PDPoint& other):
+                                    point_(other.point_)                    {}
                                 PDPoint(RealType x = 0, RealType y = 0, const Data& data = Data());
 
         RealType                x() const                                   { return point_.first().first; }
@@ -28,7 +30,7 @@
         const Data&             data() const                                { return point_.second(); }
         Data&                   data()                                      { return point_.second(); }
 
-        std::ostream&           operator<<(std::ostream& out) const         { return (out << x() << " " << y() << " " << data()); }
+        std::ostream&           operator<<(std::ostream& out) const         { return (out << x() << " " << y()); } // << " " << data()); }
         
         struct Visitor
         {
@@ -79,6 +81,9 @@
 
                                 PersistenceDiagram()                        {}
 
+        template<class OtherData>
+                                PersistenceDiagram(const PersistenceDiagram<OtherData>& other);
+
         template<class Iterator, class Evaluator>
                                 PersistenceDiagram(Iterator bg, Iterator end, 
                                                    const Evaluator& eval = Evaluator());
--- a/include/topology/persistence-diagram.hpp	Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/persistence-diagram.hpp	Thu Dec 25 14:24:02 2008 -0800
@@ -12,6 +12,18 @@
     point_.second() = data;
 }
 
+
+template<class D>
+template<class OtherData>
+PersistenceDiagram<D>::
+PersistenceDiagram(const PersistenceDiagram<OtherData>& other)
+{
+    points_.reserve(other.size());
+    for (typename PersistenceDiagram<OtherData>::PointVector::const_iterator cur = points_.begin(); 
+                                                                             cur != points_.end(); ++cur)
+        push_back(Point(cur->x(), cur->y()));
+}
+
 template<class D>
 template<class Iterator, class Evaluator>
 PersistenceDiagram<D>::
--- a/include/topology/static-persistence.hpp	Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/static-persistence.hpp	Thu Dec 25 14:24:02 2008 -0800
@@ -23,7 +23,7 @@
     ocmp_(ocmp)
 { 
     OrderIndex                          ocur = begin();
-    OffsetMap<size_t, OrderIndex>       om(0, ocur);            // TODO: this is customized for std::vector Order
+    OffsetMap<typename Filtration::IntermediateIndex, OrderIndex>       om(0, ocur);            // TODO: this is customized for std::vector Order
     for (typename Filtration::Index cur = filtration.begin(); cur != filtration.end(); ++cur, ++ocur)
     {
         // Convert the Filtration::IndexBoundary into a Cycle, and 
--- a/include/utilities/types.h	Tue Dec 23 11:02:08 2008 -0800
+++ b/include/utilities/types.h	Thu Dec 25 14:24:02 2008 -0800
@@ -17,7 +17,7 @@
 typedef 	const unsigned int&		version_type;
 
 struct      Empty                   {};
-std::ostream& operator<<(std::ostream& out, Empty e) { return out; }
+//std::ostream& operator<<(std::ostream& out, Empty e) { return out; }
 
 enum        SwitchType
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/CMakeLists.txt	Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,11 @@
+find_package                (Qt4 REQUIRED)
+set                         (QT_USE_QTOPENGL TRUE)
+set                         (QT_USE_QTXML TRUE)
+include                     (${QT_USE_FILE})
+
+#find_library                (gle_LIBRARY                NAMES gle)
+#find_library                (QGLViewer_LIBRARY          NAMES QGLViewer)
+#find_path                   (QGLViewer_INCLUDE_DIR      QGLViewer/qglviewer.h)
+#include_directories         (${QGLViewer_INCLUDE_DIR})
+
+add_subdirectory            (diagram-viewer)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/CMakeLists.txt	Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,18 @@
+set                         (diagram-viewerSources
+                             diagram.cpp 
+                             diagram-viewer-main.cpp)
+
+set                         (diagram-viewerHeaders
+                             diagram.h)
+
+qt4_wrap_cpp                (diagram-viewerMocSources       ${diagram-viewerHeaders})
+
+set                         (libraries                      ${libraries} 
+                                                            ${Boost_SERIALIZATION_LIBRARY}
+                                                            ${Boost_PROGRAM_OPTIONS_LIBRARY}
+                                                            ${QT_LIBRARIES})
+
+add_executable              (diagram-viewer                 ${diagram-viewerSources} 
+                                                            ${diagram-viewerMocSources})
+
+target_link_libraries       (diagram-viewer                 ${libraries})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram-viewer-main.cpp	Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,59 @@
+#include <qapplication.h>
+#include <QtGui>
+
+#include "diagram.h"
+
+#include <fstream>
+#include <map>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/serialization/map.hpp>
+
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+
+
+int main (int argc, char *argv[])
+{
+    std::string     diagrams_filename;
+    int dimension;
+
+    po::options_description hidden("Hidden options");
+    hidden.add_options()
+        ("diagrams-file",  po::value<std::string>(&diagrams_filename),  "The collection of persistence diagrams")
+        ("dimension",      po::value<int>(&dimension),                  "Dimension of the diagram to show");
+
+    po::positional_options_description p;
+    p.add("diagrams-file", 1);
+    p.add("dimension", 2);
+    
+    po::options_description all; all.add(hidden);
+
+    po::variables_map vm;
+    po::store(po::command_line_parser(argc, argv).
+                  options(all).positional(p).run(), vm);
+    po::notify(vm);
+
+    if (!vm.count("diagrams-file") || !vm.count("dimension"))
+    { 
+        std::cout << "Usage: " << argv[0] << " diagrams-file dimension" << std::endl;
+        std::cout << hidden << std::endl; 
+        return 1; 
+    }
+
+    std::map<Dimension, PDiagram>       dgms;
+    std::ifstream ifs(diagrams_filename.c_str());
+    boost::archive::binary_iarchive ia(ifs);
+    ia >> dgms;
+    
+    
+    QApplication application(argc, argv);
+
+    std::cout << dimension << std::endl;
+    std::cout << dgms[dimension] << std::endl;
+
+    DgmViewer pd(dgms[dimension]);
+    pd.show();
+
+    // Run main loop.
+    return application.exec();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram.cpp	Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,95 @@
+#include <iostream>
+
+#include <QtGui>
+#include <QRectF>
+
+#include "diagram.h"
+#include <cmath>
+
+//static const double ellipse_size        = 0.035;
+static const double ellipse_size        = 3;
+
+/* DgmViewer Implementation */
+DgmViewer::DgmViewer(const PDiagram& dgm):
+    min_x(0), min_y(0), max_x(0), max_y(0)
+{
+    points.reserve(dgm.size());
+    
+    for (PDiagram::const_iterator cur = dgm.begin(); cur != dgm.end(); ++cur)
+    {
+        min_x = std::min(min_x, cur->x());
+        min_y = std::min(min_y, cur->y());
+        max_x = std::max(max_x, cur->x());
+        max_y = std::max(max_y, cur->y());
+
+        points.push_back(new DgmPoint(*cur, ellipse_size));
+    }
+        
+    addDgmPoints();
+    setWindowTitle(QString("Persistence Diagram"));
+}
+DgmViewer::~DgmViewer()
+{
+    for (PointsVector::iterator cur = points.begin(); cur != points.end(); ++cur)
+        delete *cur;
+}
+
+
+void DgmViewer::addDgmPoints()
+{    
+    RealType min = std::min(min_x, min_y);
+    RealType max = std::max(max_x, max_y);
+
+    QGraphicsLineItem* diagonal = new QGraphicsLineItem(QLineF(min, -min, max, -max));
+    QGraphicsLineItem* y_axis = new QGraphicsLineItem(QLineF(0, -min_y, 0, -max_y));
+    QGraphicsLineItem* x_axis = new QGraphicsLineItem(QLineF(min_x, 0, max_x, 0));
+
+    scene.addItem(diagonal);
+    scene.addItem(y_axis);
+    scene.addItem(x_axis);
+
+    for (PointsVector::const_iterator cur = points.begin(); cur != points.end(); ++cur)
+        scene.addItem(*cur);
+
+    //scale(100,100);
+    setScene(&scene);
+    setRenderHint(QPainter::Antialiasing);
+    ensureVisible(scene.itemsBoundingRect());
+    //setMinimumSize( (int)(maxX - minX)*100 + 100, (int) (maxY - minY)*100 + 100);
+}
+
+
+DgmPoint::DgmPoint(QGraphicsItem* parent): 
+    QGraphicsItem(parent) 
+{
+}
+
+DgmPoint::DgmPoint(const Parent& pt, qreal size, QGraphicsItem *parent):
+    Parent(pt), ellipse_size(size), QGraphicsItem(parent)
+{
+    setToolTip(QString("(%1, %2)").arg(getX()).arg(getY()));
+}
+
+DgmPoint::DgmPoint(RealType b, RealType d, qreal size, QGraphicsItem *parent): 
+    Parent(b, d), ellipse_size(size), QGraphicsItem(parent)
+{
+    setToolTip(QString("(%1, %2)").arg(getX()).arg(getY()));
+}
+
+void DgmPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    //QBrush solidFill(unselectColor);
+    //QBRush selectSolidFill(selectColor);
+    painter->setBrush(Qt::SolidPattern);
+    //painter->setPen(selectColor);
+    painter->drawEllipse(QRectF(getX() - ellipse_size, -getY() - ellipse_size, 2*ellipse_size, 2*ellipse_size));
+}
+
+
+QRectF DgmPoint::boundingRect() const
+{
+    return QRectF(getX() - ellipse_size, -getY() - ellipse_size, 2*ellipse_size, 2*ellipse_size);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram.h	Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,60 @@
+#ifndef __DIAGRAM_H__
+#define __DIAGRAM_H__
+
+#include <QtGui>
+#include <QObject>
+#include <QColor>
+
+#include <map>
+
+#include <utilities/types.h>
+#include <topology/persistence-diagram.h>
+
+typedef         PersistenceDiagram<>                PDiagram;
+typedef         std::map<Dimension, PDiagram>       Diagrams;
+
+class DgmPoint;
+
+class DgmViewer: public QGraphicsView
+{
+    Q_OBJECT
+
+    public:
+        typedef             std::vector<DgmPoint*>          PointsVector;
+
+                            DgmViewer(const PDiagram& dgm);
+                            ~DgmViewer();
+
+        void                addDgmPoints();
+
+    private:
+        PointsVector        points;
+        QGraphicsScene      scene;
+        RealType            min_x, min_y, max_x, max_y;
+};
+
+
+class DgmPoint: public PDPoint<>, public QGraphicsItem
+{
+    public:
+        typedef             PDPoint<>                                       Parent;
+
+                            DgmPoint(QGraphicsItem* parent = 0);
+                            DgmPoint(const Parent& pt, qreal size, QGraphicsItem *parent = 0); 
+                            DgmPoint(RealType b, RealType d, qreal size, QGraphicsItem *parent = 0); 
+        
+        void                paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+        QRectF                 boundingRect() const;
+        
+        qreal               getX() const                    { return Parent::x(); }
+        qreal               getY() const                    { return Parent::y(); }
+
+        int                 type() const                                    { return QGraphicsItem::UserType + 1; }
+
+    private:
+        // size of rectangle containing ellipses
+        qreal                 ellipse_size;
+};
+
+
+#endif // __DIAGRAM_H__