| dmitriy@179 | 1 | #include <utilities/log.h> |
| dmitriy@179 | 2 | |
| dmitriy@179 | 3 | #include <iostream> |
| dmitriy@179 | 4 | #include <fstream> |
| dmitriy@180 | 5 | #include <string> |
| dmitriy@180 | 6 | #include <vector> |
| dmitriy@179 | 7 | |
| dmitriy@183 | 8 | #include <topology/lsvineyard.h> |
| dmitriy@180 | 9 | |
| dmitriy@180 | 10 | #include <boost/program_options.hpp> |
| dmitriy@180 | 11 | #include <boost/iterator/counting_iterator.hpp> |
| dmitriy@180 | 12 | #include <boost/function.hpp> |
| dmitriy@180 | 13 | #include <boost/bind.hpp> |
| dmitriy@180 | 14 | #include <boost/lambda/lambda.hpp> |
| dmitriy@180 | 15 | namespace bl = boost::lambda; |
| dmitriy@180 | 16 | |
| dmitriy@180 | 17 | |
| dmitriy@199 | 18 | typedef double VertexValue; |
| dmitriy@180 | 19 | typedef unsigned Vertex; |
| dmitriy@180 | 20 | typedef std::vector<VertexValue> VertexVector; |
| dmitriy@180 | 21 | struct SubscriptFunctor: public std::unary_function<Vertex, VertexValue> |
| dmitriy@180 | 22 | { |
| dmitriy@180 | 23 | SubscriptFunctor(const VertexVector& v): vec(&v) {} |
| dmitriy@180 | 24 | float operator()(Vertex i) const { return (*vec)[i]; } |
| dmitriy@180 | 25 | SubscriptFunctor& operator=(const SubscriptFunctor& other) { vec = other.vec; return *this; } |
| dmitriy@180 | 26 | const VertexVector* vec; |
| dmitriy@180 | 27 | }; |
| dmitriy@180 | 28 | typedef SubscriptFunctor VertexEvaluator; |
| dmitriy@180 | 29 | typedef std::vector<VertexVector> VertexVectorVector; |
| dmitriy@180 | 30 | typedef LSVineyard<Vertex, VertexEvaluator> PLVineyard; |
| dmitriy@180 | 31 | typedef PLVineyard::Simplex Smplx; // gotta start using namespaces |
| dmitriy@180 | 32 | |
| dmitriy@180 | 33 | void program_options(int argc, char* argv[], std::string& complex_fn, |
| dmitriy@180 | 34 | std::string& values_fn, |
| dmitriy@180 | 35 | std::string& output_prefix, |
| dmitriy@180 | 36 | bool& skip_infinite_vines, |
| dmitriy@180 | 37 | bool& save_vines, |
| dmitriy@180 | 38 | bool& explicit_events); |
| dmitriy@180 | 39 | void read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices); |
| dmitriy@180 | 40 | void read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices); |
| dmitriy@180 | 41 | |
| dmitriy@179 | 42 | |
| dmitriy@179 | 43 | int main(int argc, char** argv) |
| dmitriy@179 | 44 | { |
| dmitriy@179 | 45 | #ifdef LOGGING |
| dmitriy@179 | 46 | rlog::RLogInit(argc, argv); |
| dmitriy@179 | 47 | #endif |
| dmitriy@180 | 48 | |
| dmitriy@180 | 49 | std::string complex_fn, values_fn, output_prefix; |
| dmitriy@180 | 50 | bool skip_infinite_vines = false, explicit_events = false, save_vines = false; |
| dmitriy@180 | 51 | program_options(argc, argv, complex_fn, values_fn, output_prefix, skip_infinite_vines, save_vines, explicit_events); |
| dmitriy@179 | 52 | |
| dmitriy@180 | 53 | |
| dmitriy@180 | 54 | // Read in the complex |
| dmitriy@180 | 55 | PLVineyard::LSFiltration simplices; |
| dmitriy@180 | 56 | read_simplices(complex_fn, simplices); |
| dmitriy@180 | 57 | std::cout << "Complex read, size: " << simplices.size() << std::endl; |
| dmitriy@180 | 58 | |
| dmitriy@180 | 59 | // Read in vertex values |
| dmitriy@180 | 60 | VertexVectorVector vertices; |
| dmitriy@180 | 61 | read_vertices(values_fn, vertices); |
| dmitriy@180 | 62 | |
| dmitriy@180 | 63 | // Setup the vineyard |
| dmitriy@180 | 64 | VertexEvaluator veval(vertices[0]); |
| dmitriy@180 | 65 | PLVineyard::VertexComparison vcmp(veval); |
| dmitriy@180 | 66 | PLVineyard::SimplexComparison scmp(vcmp); |
| dmitriy@179 | 67 | simplices.sort(scmp); |
| dmitriy@180 | 68 | PLVineyard v(boost::counting_iterator<Vertex>(0), |
| dmitriy@180 | 69 | boost::counting_iterator<Vertex>(vertices[0].size()), |
| dmitriy@180 | 70 | simplices, veval); |
| dmitriy@179 | 71 | std::cout << "Pairing computed" << std::endl; |
| dmitriy@179 | 72 | |
| dmitriy@179 | 73 | // Compute vineyard |
| dmitriy@180 | 74 | for (size_t i = 1; i < vertices.size(); ++i) |
| dmitriy@180 | 75 | { |
| dmitriy@180 | 76 | veval = VertexEvaluator(vertices[i]); |
| dmitriy@199 | 77 | v.compute_vineyard(veval); |
| dmitriy@180 | 78 | std::cout << "Processed frame: " << i << std::endl; |
| dmitriy@180 | 79 | } |
| dmitriy@179 | 80 | std::cout << "Vineyard computed" << std::endl; |
| dmitriy@179 | 81 | |
| dmitriy@180 | 82 | if (save_vines) |
| dmitriy@180 | 83 | v.vineyard().save_vines(output_prefix, skip_infinite_vines); |
| dmitriy@180 | 84 | else |
| dmitriy@180 | 85 | v.vineyard().save_edges(output_prefix, skip_infinite_vines); |
| dmitriy@180 | 86 | } |
| dmitriy@179 | 87 | |
| dmitriy@180 | 88 | |
| dmitriy@180 | 89 | void read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices) |
| dmitriy@180 | 90 | { |
| dmitriy@180 | 91 | std::ifstream in(complex_fn.c_str()); |
| dmitriy@180 | 92 | std::string line; |
| dmitriy@180 | 93 | while (std::getline(in, line)) |
| dmitriy@180 | 94 | { |
| dmitriy@180 | 95 | std::istringstream strin(line); |
| dmitriy@180 | 96 | simplices.push_back(Smplx(std::istream_iterator<Vertex>(strin), std::istream_iterator<Vertex>())); |
| dmitriy@180 | 97 | } |
| dmitriy@180 | 98 | std::cout << "Simplices read:" << std::endl; |
| dmitriy@180 | 99 | std::copy(simplices.begin(), simplices.end(), std::ostream_iterator<Smplx>(std::cout, "\n")); |
| dmitriy@179 | 100 | } |
| dmitriy@180 | 101 | |
| dmitriy@180 | 102 | void read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices) |
| dmitriy@180 | 103 | { |
| dmitriy@180 | 104 | std::ifstream in(vertex_fn.c_str()); |
| dmitriy@180 | 105 | std::string line; |
| dmitriy@180 | 106 | while (std::getline(in, line)) |
| dmitriy@180 | 107 | { |
| dmitriy@180 | 108 | std::istringstream strin(line); |
| dmitriy@180 | 109 | vertices.push_back(VertexVector(std::istream_iterator<VertexValue>(strin), std::istream_iterator<VertexValue>())); |
| dmitriy@180 | 110 | } |
| dmitriy@180 | 111 | std::cout << "Vertex values read:" << std::endl; |
| dmitriy@180 | 112 | for (size_t i = 0; i < vertices.size(); ++i) |
| dmitriy@180 | 113 | { |
| dmitriy@180 | 114 | std::copy(vertices[i].begin(), vertices[i].end(), std::ostream_iterator<VertexValue>(std::cout, " ")); |
| dmitriy@180 | 115 | std::cout << std::endl; |
| dmitriy@180 | 116 | } |
| dmitriy@180 | 117 | } |
| dmitriy@180 | 118 | |
| dmitriy@180 | 119 | void program_options(int argc, char* argv[], std::string& complex_fn, |
| dmitriy@180 | 120 | std::string& values_fn, |
| dmitriy@180 | 121 | std::string& output_prefix, |
| dmitriy@180 | 122 | bool& skip_infinite_vines, |
| dmitriy@180 | 123 | bool& save_vines, |
| dmitriy@180 | 124 | bool& explicit_events) |
| dmitriy@180 | 125 | { |
| dmitriy@180 | 126 | namespace po = boost::program_options; |
| dmitriy@180 | 127 | |
| dmitriy@180 | 128 | po::options_description hidden("Hidden options"); |
| dmitriy@180 | 129 | hidden.add_options() |
| dmitriy@180 | 130 | ("complex-file", po::value<std::string>(&complex_fn), "file listing the simplices of the complex") |
| dmitriy@180 | 131 | ("values-file", po::value<std::string>(&values_fn), "file listing the values at the vertices") |
| dmitriy@180 | 132 | ("output-prefix", po::value<std::string>(&output_prefix), "output prefix"); |
| dmitriy@180 | 133 | |
| dmitriy@180 | 134 | po::options_description visible("Allowed options", 100); |
| dmitriy@180 | 135 | visible.add_options() |
| dmitriy@180 | 136 | ("skip-infinite,s", po::bool_switch(&skip_infinite_vines), "skip infinite vines in the output") |
| dmitriy@180 | 137 | ("explicit-events,e", po::bool_switch(&explicit_events), "process kinetic sort events one by one") |
| dmitriy@180 | 138 | ("save-vines,v", po::bool_switch(&save_vines), "save vines instead of edges") |
| dmitriy@180 | 139 | ("help,h", "produce help message"); |
| dmitriy@180 | 140 | #if LOGGING |
| dmitriy@180 | 141 | std::vector<std::string> log_channels; |
| dmitriy@180 | 142 | visible.add_options() |
| dmitriy@180 | 143 | ("log,l", po::value< std::vector<std::string> >(&log_channels), "log channels to turn on (info, debug, etc)"); |
| dmitriy@180 | 144 | #endif |
| dmitriy@180 | 145 | |
| dmitriy@180 | 146 | po::positional_options_description pos; |
| dmitriy@180 | 147 | pos.add("complex-file", 1); |
| dmitriy@180 | 148 | pos.add("values-file", 1); |
| dmitriy@180 | 149 | pos.add("output-prefix", 1); |
| dmitriy@180 | 150 | |
| dmitriy@180 | 151 | po::options_description all; all.add(visible).add(hidden); |
| dmitriy@180 | 152 | |
| dmitriy@180 | 153 | po::variables_map vm; |
| dmitriy@180 | 154 | po::store(po::command_line_parser(argc, argv). |
| dmitriy@180 | 155 | options(all).positional(pos).run(), vm); |
| dmitriy@180 | 156 | po::notify(vm); |
| dmitriy@180 | 157 | |
| dmitriy@180 | 158 | #if LOGGING |
| dmitriy@180 | 159 | for (std::vector<std::string>::const_iterator cur = log_channels.begin(); cur != log_channels.end(); ++cur) |
| dmitriy@180 | 160 | stderrLog.subscribeTo( RLOG_CHANNEL(cur->c_str()) ); |
| dmitriy@180 | 161 | #endif |
| dmitriy@180 | 162 | |
| dmitriy@180 | 163 | if (vm.count("help") || !vm.count("complex-file") || !vm.count("values-file") || !vm.count("output-prefix")) |
| dmitriy@180 | 164 | { |
| dmitriy@180 | 165 | std::cout << "Usage: " << argv[0] << " [options] complex-file values-file output-prefix" << std::endl; |
| dmitriy@180 | 166 | std::cout << visible << std::endl; |
| dmitriy@180 | 167 | std::abort(); |
| dmitriy@180 | 168 | } |
| dmitriy@180 | 169 | } |