diff options
Diffstat (limited to 'src/Persistence_representations/include/gudhi/read_persistence_from_file.h')
-rw-r--r-- | src/Persistence_representations/include/gudhi/read_persistence_from_file.h | 311 |
1 files changed, 137 insertions, 174 deletions
diff --git a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h index a4884314..39d485a9 100644 --- a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h +++ b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h @@ -20,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - #ifndef READ_PERSISTENCE_FROM_FILE_H_ #define READ_PERSISTENCE_FROM_FILE_H_ @@ -30,184 +29,148 @@ #include <vector> #include <algorithm> +namespace Gudhi { +namespace Persistence_representations { +/** + * Universal procedure to read files with persistence. It ignores the lines starting from # (treat them as comments). + * It reads the fist line which is not a comment and assume that there are some numerical entries over there. The + *program assume + * that each other line in the file, which is not a comment, have the same number of numerical entries (2, 3 or 4). + * If there are two numerical entries per line, then the function assume that they are birth/death coordinates. + * If there are three numerical entries per line, then the function assume that they are: dimension and birth/death + *coordinates. + * If there are four numerical entries per line, then the function assume that they are: the characteristic of a filed + *over which + * persistence was computed, dimension and birth/death coordinates. + * The 'inf' string can appear only as a last element of a line. + * The procedure returns vector of persistence pairs. +**/ +std::vector<std::pair<double, double> > read_persistence_intervals_in_one_dimension_from_file( + std::string const& filename, int dimension = -1, double what_to_substitute_for_infinite_bar = -1) { + bool dbg = false; + std::ifstream in; + in.open(filename); + // checking if the file exist: + if (!in.good()) { + std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n"; + throw "The file from which you are trying to read the persistence landscape do not exist. The program will now terminate \n"; + } -namespace Gudhi -{ -namespace Persistence_representations -{ + std::string line; + std::vector<std::pair<double, double> > barcode; -/** - * Universal procedure to read files with persistence. It ignores the lines starting from # (treat them as comments). - * It reads the fist line which is not a comment and assume that there are some numerical entries over there. The program assume - * that each other line in the file, which is not a comment, have the same number of numerical entries (2, 3 or 4). - * If there are two numerical entries per line, then the function assume that they are birth/death coordinates. - * If there are three numerical entries per line, then the function assume that they are: dimension and birth/death coordinates. - * If there are four numerical entries per line, then the function assume that they are: the characteristic of a filed over which - * persistence was computed, dimension and birth/death coordinates. - * The 'inf' string can appear only as a last element of a line. - * The procedure returns vector of persistence pairs. -**/ -std::vector<std::pair<double,double> > read_persistence_intervals_in_one_dimension_from_file(std::string const& filename, int dimension=-1 , double what_to_substitute_for_infinite_bar = -1 ) -{ - bool dbg = false; - std::ifstream in; - in.open( filename ); - //checking if the file exist: - if ( !in.good() ) - { - std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n"; - throw "The file from which you are trying to read the persistence landscape do not exist. The program will now terminate \n"; - } - - - + int number_of_entries_per_line = -1; - std::string line; - std::vector< std::pair<double,double> > barcode; - - int number_of_entries_per_line = -1; + while (!in.eof()) { + getline(in, line); + if (dbg) std::cerr << "Reading line : " << line << std::endl; + if (!(line.length() == 0 || line[0] == '#')) { + // If we do not know how many entries per line we have, we check it in below. + if (number_of_entries_per_line == -1) { + number_of_entries_per_line = 0; + std::string line_copy(line); + if (line_copy.find("inf") != std::string::npos) { + size_t np = line_copy.find("inf"); + // replace symbols 'inf' in line_copy with white spaces: + line_copy[np] = ' '; + line_copy[np + 1] = ' '; + line_copy[np + 2] = ' '; + number_of_entries_per_line = 1; + } + // check how many entries we have in the line. + std::stringstream ss(line_copy); + double number; + std::vector<double> this_line; + while (ss >> number) { + this_line.push_back(number); + } + number_of_entries_per_line += (int)this_line.size(); + if (dbg) { + std::cerr << "number_of_entries_per_line : " << number_of_entries_per_line + << ". This number was obtained by analyzing this line : " << line << std::endl; + } + if ((number_of_entries_per_line < 2) || (number_of_entries_per_line > 4)) { + std::cerr << "The input file you have provided have wrong number of numerical entries per line. The program " + "will now terminate. \n"; + throw "The input file you have provided have wrong number of numerical entries per line. The program will now terminate. \n"; + } + } + // In case there is an 'inf' string in this line, we are dealing with this situation in below. + if (line.find("inf") != std::string::npos) { + if (dbg) { + std::cerr << "This line: " << line << " contains infinite interval. \n"; + } + // first we substitute inf by white spaces: + size_t np = line.find("inf"); + line[np] = ' '; + line[np + 1] = ' '; + line[np + 2] = ' '; + if (what_to_substitute_for_infinite_bar != -1) { + double beginn, field, dim; + std::stringstream lineSS(line); + if (number_of_entries_per_line == 4) lineSS >> field; + if (number_of_entries_per_line >= 3) { + lineSS >> dim; + } else { + dim = dimension; + } + lineSS >> beginn; + if (dim == dimension) { + if (beginn > what_to_substitute_for_infinite_bar) { + barcode.push_back(std::make_pair(what_to_substitute_for_infinite_bar, beginn)); + } else { + barcode.push_back(std::make_pair(beginn, what_to_substitute_for_infinite_bar)); + } + if (dbg) { + std::cerr << "this is the line that is going to the output : " << beginn << " , " + << what_to_substitute_for_infinite_bar << std::endl; + } + } + } else { + // this is a line with infinity. Since the variable what_to_substitute_for_infinite_bar have not been set up, + // it means that this line will be skipped. + if (dbg) { + std::cerr << "We will skip it \n"; + } + } + continue; + } else { + // Then, we read the content of the line. We know that it do not contain 'inf' substring. + std::stringstream lineSS(line); + double beginn, endd, field, dim; + if (number_of_entries_per_line == 4) lineSS >> field; + if (number_of_entries_per_line >= 3) { + lineSS >> dim; + } else { + dim = dimension; + } + lineSS >> beginn; + lineSS >> endd; + if (beginn > endd) { + std::swap(beginn, endd); + } + if (dim == dimension) { + barcode.push_back(std::make_pair(beginn, endd)); + if (dbg) { + std::cerr << "This is a line that is going to the output : " << beginn << " , " << endd << std::endl; + } + } else { + if ((number_of_entries_per_line == 3) && (dimension == -1)) { + barcode.push_back(std::make_pair(beginn, endd)); + } + } + } + } else { + if (dbg) { + std::cerr << "This is a comment line \n"; + } + } + } + in.close(); + if (dbg) std::cerr << "End of reading \n"; - while (!in.eof()) - { - getline(in,line); - if ( dbg )std::cerr << "Reading line : " << line << std::endl; - if ( !(line.length() == 0 || line[0] == '#') ) - { - //If we do not know how many entries per line we have, we check it in below. - if ( number_of_entries_per_line == -1 ) - { - number_of_entries_per_line = 0; - std::string line_copy(line); - if ( line_copy.find("inf") != std::string::npos ) - { - size_t np = line_copy.find("inf"); - //replace symbols 'inf' in line_copy with white spaces: - line_copy[np] = ' '; - line_copy[np+1] = ' '; - line_copy[np+2] = ' '; - number_of_entries_per_line = 1; - } - //check how many entries we have in the line. - std::stringstream ss( line_copy ); - double number; - std::vector<double> this_line; - while ( ss >> number ) - { - this_line.push_back( number ); - } - number_of_entries_per_line += (int)this_line.size(); - if ( dbg ) - { - std::cerr << "number_of_entries_per_line : " << number_of_entries_per_line << ". This number was obtained by analyzing this line : " << line << std::endl; - } - if ( (number_of_entries_per_line < 2) || ( number_of_entries_per_line > 4 ) ) - { - std::cerr << "The input file you have provided have wrong number of numerical entries per line. The program will now terminate. \n"; - throw "The input file you have provided have wrong number of numerical entries per line. The program will now terminate. \n"; - } - } - //In case there is an 'inf' string in this line, we are dealing with this situation in below. - if ( line.find("inf") != std::string::npos ) - { - if ( dbg ) - { - std::cerr << "This line: " << line << " contains infinite interval. \n"; - } - //first we substitute inf by white spaces: - size_t np = line.find("inf"); - line[np] = ' '; - line[np+1] = ' '; - line[np+2] = ' '; - if ( what_to_substitute_for_infinite_bar != -1 ) - { - double beginn, field, dim; - std::stringstream lineSS(line); - if ( number_of_entries_per_line == 4 )lineSS >> field; - if ( number_of_entries_per_line >= 3 ) - { - lineSS >> dim; - } - else - { - dim = dimension; - } - lineSS >> beginn; - if ( dim == dimension ) - { - if ( beginn > what_to_substitute_for_infinite_bar ) - { - barcode.push_back( std::make_pair( what_to_substitute_for_infinite_bar , beginn ) ); - } - else - { - barcode.push_back( std::make_pair( beginn , what_to_substitute_for_infinite_bar ) ); - } - if (dbg) - { - std::cerr << "this is the line that is going to the output : " << beginn << " , " << what_to_substitute_for_infinite_bar << std::endl; - } - } - } - else - { - //this is a line with infinity. Since the variable what_to_substitute_for_infinite_bar have not been set up, it means that this line will be skipped. - if ( dbg ) - { - std::cerr << "We will skip it \n"; - } - } - continue; - } - else - { - //Then, we read the content of the line. We know that it do not contain 'inf' substring. - std::stringstream lineSS(line); - double beginn, endd, field, dim; - if ( number_of_entries_per_line == 4 )lineSS >> field; - if ( number_of_entries_per_line >= 3 ) - { - lineSS >> dim; - } - else - { - dim = dimension; - } - lineSS >> beginn; - lineSS >> endd; - if ( beginn > endd ) - { - std::swap(beginn,endd); - } - if ( dim == dimension ) - { - barcode.push_back( std::make_pair( beginn , endd ) ); - if (dbg) - { - std::cerr << "This is a line that is going to the output : " << beginn << " , " << endd << std::endl; - } - } - else - { - if ( (number_of_entries_per_line==3) && (dimension == -1) ) - { - barcode.push_back( std::make_pair( beginn , endd ) ); - } - } - } - } - else - { - if ( dbg ) - { - std::cerr << "This is a comment line \n"; - } - } - } - in.close(); - if ( dbg )std::cerr << "End of reading \n"; - - return barcode; + return barcode; } // read_persistence_intervals_in_one_dimension_from_file } // namespace Persistence_representations |