rachellevanger / tda-persistence-explorer

A Python-based tool for interacting with and visualizing the persistence diagrams of 2D grayscale images.
MIT License
5 stars 1 forks source link

Add infinite generators to phat interface #2

Open rachellevanger opened 7 years ago

rachellevanger commented 7 years ago

Right now the phat interface only outputs finite generators, which is incomplete. We need to add the infinite generator output.

shaunharker commented 7 years ago

This hasn't been handled yet. However, the phat interface code has been refactored so it is now much easier to work with and extend as of d653190b79e80a2d9a71d61f901180692d0bcc2c. In particular main and SavePersistenceResults (see source/ImagePersistence/ImagePersistence.cpp for full context) are much easier to understand:

/// SavePersistenceResults
///   Overview:
///     Save computed persistence results of a filtration to a file
///     This is a specialized function which assumes the associated complex
///     is an "ImageComplex" and saves feature data related to x and y coordinates.
///   Inputs:
///     filtration   : a filtration of a complex
///     pairs        : PHAT output of birth-death cell persistence pairs
///     outfile_name : the name of the file in which to save the results of the calculation
void
SavePersistenceResults ( Filtration const& filtration,
                         phat::persistence_pairs const& pairs, 
                         std::string const& outfile_name ) {
  // Output result
  std::ofstream outfile ( outfile_name );
  outfile << "dim,birth,b_x,b_y,b_z,death,d_x,d_y,d_z\n" ;
  for( int i = 0; i < pairs.get_num_pairs(); ++ i ){
    auto birth_cell_index = pairs.get_pair(i).first;
    auto death_cell_index = pairs.get_pair(i).second;
    auto birth_cell = filtration.cell(birth_cell_index);
    auto birth_value = filtration.value(birth_cell_index);
    auto death_cell = filtration.cell(death_cell_index);
    auto death_value = filtration.value(death_cell_index);
    if ( birth_value == death_value ) continue;
    outfile << birth_cell.dimension() << ", "
            << birth_value << ", "
            << birth_cell.x() << ", "
            << birth_cell.y() << ", "
            << "0" << ", "
            << death_value << ", "
            << death_cell.x() << ", "
            << death_cell.y() << ", "
            << "0" << "\n";
  }
}

/// main
///  Usage: ImagePersistence <image_filename> <output_filename> <mode>
///   <image_filename>  : input image filename
///   <output_filename> : output filename (a CSV file)
///   <mode>            : A mode of execution (either "sub" or "super")
///                       to indicate whether to compute
///                       sublevel or superlevel persistence.
int main(int argc, char *argv[]) {
  // Check command line arguments
  if ( argc != 4 ) {
    std::cerr << help_string << "\n";
    return 1;
  }

  // Read arguments
  std::string infile_name(argv[1]);
  std::string outfile_name(argv[2]);
  std::string mode(argv[3]);

  // Check mode argument
  if ( mode != "sub" && mode != "super" ) {
    std::cerr << help_string << "\n";
    return 1;
  }

  // Load image file
  Image image ( infile_name );

  // Construct filtration, an object that stores an ordering of cells in a complex
  Filtration filtration;
  if ( mode == "sub" ) filtration = SublevelFiltration(image);
  if ( mode == "super" ) filtration = SuperlevelFiltration(image);

  // Compute persistence given filtration
  phat::persistence_pairs pairs = PersistenceViaPHAT(filtration);

  // Save results to file
  SavePersistenceResults ( filtration, pairs, outfile_name );

  return 0;
}

This should allow work to be done to extend the command line interface. In fact this will be fairly easy; in fact the hard part will be the side-tasks to make sure to keep the READMEs and python tutorials up to date with any command-line-interface updates.