Created pl-vineyard.cpp to compute vineyards given a complex and a sequence of values at each vertex dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Wed, 16 Dec 2009 15:39:38 -0800
branchdev
changeset 180 27508309a680
parent 179 d15c6d144645
child 181 1ee6edc17cb6
Created pl-vineyard.cpp to compute vineyards given a complex and a sequence of values at each vertex
examples/grid/CMakeLists.txt
examples/grid/grid2D.h
examples/grid/lsvineyard.h
examples/grid/lsvineyard.hpp
examples/grid/pl-vineyard.cpp
include/topology/vineyard.h
include/topology/vineyard.hpp
--- a/examples/grid/CMakeLists.txt	Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/CMakeLists.txt	Wed Dec 16 15:39:38 2009 -0800
@@ -17,4 +17,8 @@
         add_executable			(${t} ${t}.cpp)
         target_link_libraries	(${t} ${libraries} ${CGAL_LIBRARY} ${dsrpdb_LIBRARY})
     endforeach 					(t ${targets})
+    
+    # Extra special for program_options
+    add_executable			(pl-vineyard pl-vineyard.cpp)
+    target_link_libraries   (pl-vineyard ${libraries} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
 endif                           (CGAL_FOUND)
--- a/examples/grid/grid2D.h	Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/grid2D.h	Wed Dec 16 15:39:38 2009 -0800
@@ -32,7 +32,7 @@
 {
     public:
         typedef                 RealType                                        ValueType;
-        typedef                 ValueType                                       value_type;
+        typedef                 ValueType                                       result_type;
         
         typedef                 unsigned int                                    CoordinateIndex;
         typedef                 boost::counting_iterator<CoordinateIndex>       iterator;
--- a/examples/grid/lsvineyard.h	Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/lsvineyard.h	Wed Dec 16 15:39:38 2009 -0800
@@ -30,7 +30,7 @@
 
         typedef                     Vertex_                                             Vertex;
         typedef                     VertexEvaluator_                                    VertexEvaluator;
-        typedef                     typename VertexEvaluator::value_type                VertexValue;
+        typedef                     typename VertexEvaluator::result_type               VertexValue;
         
         typedef                     Simplex_                                            Simplex;
         typedef                     Filtration_                                         LSFiltration;
@@ -171,7 +171,7 @@
 { return out << vi->vertex(); }
         
 template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::KineticVertexComparison
+class LSVineyard<V,VE,S,C>::KineticVertexComparison: public std::binary_function<const KineticVertexType&, const KineticVertexType&, bool>
 {
     public:
                                 KineticVertexComparison(const VertexComparison& vcmp):
@@ -204,7 +204,7 @@
 };
 
 template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::Evaluator
+class LSVineyard<V,VE,S,C>::Evaluator: public std::unary_function<Index, RealType>
 {
     public:
         virtual RealType        time() const                                                =0;
@@ -229,7 +229,7 @@
 };
 
 template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::DimensionFromIterator: std::unary_function<Dimension, iterator>
+class LSVineyard<V,VE,S,C>::DimensionFromIterator: std::unary_function<iterator, Dimension>
 {
     public:
                                 DimensionFromIterator(const PFMap& pfmap): pfmap_(pfmap)    {}
--- a/examples/grid/lsvineyard.hpp	Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/lsvineyard.hpp	Wed Dec 16 15:39:38 2009 -0800
@@ -32,9 +32,11 @@
     rLog(rlLSVineyardDebug, "Simplices paired");
 
     vertices_.sort(KineticVertexComparison(vcmp_));     // sort vertices w.r.t. vcmp_
-    std::cout << "Vertex order:" << std::endl;
+#if LOGGING    
+    rLog(rlLSVineyardDebug, "Vertex order:");
     for (VertexIndex cur = vertices_.begin(); cur != vertices_.end(); ++cur)
-        std::cout << "  " << cur->vertex() << std::endl;
+        rLog(rlLSVineyardDebug, "  %d", cur->vertex());
+#endif
 
     // Initialize simplex_index() and attachment
     VertexIndex vi = boost::prior(vertices_.begin());
@@ -85,6 +87,7 @@
     {
         VertexValue val0 = veval_(cur->vertex());
         VertexValue val1 = veval(cur->vertex());
+        rLog(rlLSVineyardDebug, "Vertex %d: %f -> %f", cur->vertex(), val0, val1);
         F x = cf(F::NT(val0), F::NT(val1 - val0));          // x = val0 + (val1 - val0)*t = (1-t)*val0 + t*val1
         Point p(x);
         cur->set_kinetic_key(apt->insert(p));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/grid/pl-vineyard.cpp	Wed Dec 16 15:39:38 2009 -0800
@@ -0,0 +1,169 @@
+#include <utilities/log.h>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "lsvineyard.h"
+
+#include <boost/program_options.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+namespace bl = boost::lambda;
+
+
+typedef     float                                       VertexValue;
+typedef     unsigned                                    Vertex;
+typedef     std::vector<VertexValue>                    VertexVector;
+struct SubscriptFunctor: public std::unary_function<Vertex, VertexValue>
+{
+                                SubscriptFunctor(const VertexVector& v): vec(&v)    {}
+        float                   operator()(Vertex i) const                          { return (*vec)[i]; }
+        SubscriptFunctor&       operator=(const SubscriptFunctor& other)            { vec = other.vec; return *this; }
+        const VertexVector*     vec;
+};
+typedef     SubscriptFunctor                            VertexEvaluator;
+typedef     std::vector<VertexVector>                   VertexVectorVector;
+typedef     LSVineyard<Vertex, VertexEvaluator>         PLVineyard;
+typedef     PLVineyard::Simplex                         Smplx;              // gotta start using namespaces
+
+void        program_options(int argc, char* argv[], std::string& complex_fn, 
+                                                    std::string& values_fn, 
+                                                    std::string& output_prefix, 
+                                                    bool& skip_infinite_vines, 
+                                                    bool& save_vines,
+                                                    bool& explicit_events);
+void        read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices);
+void        read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices); 
+
+
+int main(int argc, char** argv)
+{
+#ifdef LOGGING
+    rlog::RLogInit(argc, argv);
+#endif     
+    
+    std::string                 complex_fn, values_fn, output_prefix;
+    bool                        skip_infinite_vines = false, explicit_events = false, save_vines = false;
+    program_options(argc, argv, complex_fn, values_fn, output_prefix, skip_infinite_vines, save_vines, explicit_events);
+
+
+    // Read in the complex
+    PLVineyard::LSFiltration            simplices;
+    read_simplices(complex_fn, simplices);
+    std::cout << "Complex read, size: " << simplices.size() << std::endl;
+
+    // Read in vertex values
+    VertexVectorVector                  vertices;
+    read_vertices(values_fn, vertices);
+
+    // Setup the vineyard
+    VertexEvaluator                     veval(vertices[0]);
+    PLVineyard::VertexComparison        vcmp(veval);
+    PLVineyard::SimplexComparison       scmp(vcmp);
+    simplices.sort(scmp);
+    PLVineyard                      v(boost::counting_iterator<Vertex>(0),
+                                      boost::counting_iterator<Vertex>(vertices[0].size()), 
+                                      simplices, veval);
+    std::cout << "Pairing computed" << std::endl;
+
+    // Compute vineyard
+    for (size_t i = 1; i < vertices.size(); ++i)
+    {
+        veval = VertexEvaluator(vertices[i]);
+        v.compute_vineyard(veval, explicit_events);
+        std::cout << "Processed frame: " << i << std::endl;
+    }
+    std::cout << "Vineyard computed" << std::endl;
+    
+    if (save_vines)
+        v.vineyard().save_vines(output_prefix, skip_infinite_vines);
+    else
+        v.vineyard().save_edges(output_prefix, skip_infinite_vines);
+}
+
+
+void        read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices)
+{
+    std::ifstream   in(complex_fn.c_str());
+    std::string     line;
+    while (std::getline(in, line))
+    {
+        std::istringstream  strin(line);
+        simplices.push_back(Smplx(std::istream_iterator<Vertex>(strin), std::istream_iterator<Vertex>()));
+    }
+    std::cout << "Simplices read:" << std::endl;
+    std::copy(simplices.begin(), simplices.end(), std::ostream_iterator<Smplx>(std::cout, "\n"));
+}
+
+void        read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices)
+{
+    std::ifstream   in(vertex_fn.c_str());
+    std::string     line;
+    while (std::getline(in, line))
+    {
+        std::istringstream  strin(line);
+        vertices.push_back(VertexVector(std::istream_iterator<VertexValue>(strin), std::istream_iterator<VertexValue>()));
+    }
+    std::cout << "Vertex values read:" << std::endl;
+    for (size_t i = 0; i < vertices.size(); ++i)
+    {
+        std::copy(vertices[i].begin(), vertices[i].end(), std::ostream_iterator<VertexValue>(std::cout, " "));
+        std::cout << std::endl;
+    }
+}
+
+void        program_options(int argc, char* argv[], std::string& complex_fn, 
+                                                    std::string& values_fn, 
+                                                    std::string& output_prefix, 
+                                                    bool& skip_infinite_vines,
+                                                    bool& save_vines,
+                                                    bool& explicit_events)
+{
+    namespace po = boost::program_options;
+
+    po::options_description     hidden("Hidden options");
+    hidden.add_options()
+        ("complex-file",        po::value<std::string>(&complex_fn),            "file listing the simplices of the complex")
+        ("values-file",         po::value<std::string>(&values_fn),             "file listing the values at the vertices")
+        ("output-prefix",       po::value<std::string>(&output_prefix),         "output prefix");
+    
+    po::options_description visible("Allowed options", 100);
+    visible.add_options()
+        ("skip-infinite,s",     po::bool_switch(&skip_infinite_vines),                          "skip infinite vines in the output")
+        ("explicit-events,e",   po::bool_switch(&explicit_events),                              "process kinetic sort events one by one")
+        ("save-vines,v",        po::bool_switch(&save_vines),                                   "save vines instead of edges")
+        ("help,h",                                                                              "produce help message");
+#if LOGGING
+    std::vector<std::string>    log_channels;
+    visible.add_options()
+        ("log,l",               po::value< std::vector<std::string> >(&log_channels),           "log channels to turn on (info, debug, etc)");
+#endif
+
+    po::positional_options_description pos;
+    pos.add("complex-file", 1);
+    pos.add("values-file", 1);
+    pos.add("output-prefix", 1);
+    
+    po::options_description all; all.add(visible).add(hidden);
+
+    po::variables_map vm;
+    po::store(po::command_line_parser(argc, argv).
+                  options(all).positional(pos).run(), vm);
+    po::notify(vm);
+
+#if LOGGING
+    for (std::vector<std::string>::const_iterator cur = log_channels.begin(); cur != log_channels.end(); ++cur)
+        stderrLog.subscribeTo( RLOG_CHANNEL(cur->c_str()) );
+#endif
+
+    if (vm.count("help") || !vm.count("complex-file") || !vm.count("values-file") || !vm.count("output-prefix"))
+    { 
+        std::cout << "Usage: " << argv[0] << " [options] complex-file values-file output-prefix" << std::endl;
+        std::cout << visible << std::endl; 
+        std::abort();
+    }
+}
--- a/include/topology/vineyard.h	Wed Dec 16 15:39:06 2009 -0800
+++ b/include/topology/vineyard.h	Wed Dec 16 15:39:38 2009 -0800
@@ -52,6 +52,7 @@
         void                            set_evaluator(Evaluator* eval)                  { evaluator = eval; }
 
         void                            save_edges(const std::string& filename, bool skip_infinite = false) const;
+        void                            save_vines(const std::string& filename, bool skip_infinite = false) const;
 
     private:
         template<class Iter>
--- a/include/topology/vineyard.hpp	Wed Dec 16 15:39:06 2009 -0800
+++ b/include/topology/vineyard.hpp	Wed Dec 16 15:39:38 2009 -0800
@@ -119,6 +119,33 @@
     }
 }
 
+template<class I, class It, class E>
+void            
+Vineyard<I,It,E>::
+save_vines(const std::string& filename, bool skip_infinite) const
+{
+    for (unsigned int i = 0; i < vines_vector.size(); ++i)
+    {
+        std::ostringstream os; os << i;
+        std::string fn = filename + os.str() + ".vin";
+        std::ofstream out(fn.c_str());
+        for (typename VineList::const_iterator vi = vines_vector[i]->begin(); vi != vines_vector[i]->end(); ++vi)
+        {
+            for (typename Vine::const_iterator ki = vi->begin(); ki != vi->end(); ki++)
+            {
+                if (skip_infinite && ki->is_infinite())
+                {
+                    std::cerr << "Warning: skipping an infinite knee in save_edges() in dimension " << i << std::endl;
+                    continue;
+                }
+                out << ki->birth << ' ' << ki->death << ' ' << ki->time << " ";
+            }
+            out << std::endl;
+        }
+        out.close();
+    }
+}
+
 /// Records a knee for the given simplex
 template<class I, class It, class E>
 template<class Iter>