Xmipp  v3.23.11-Nereus
Functions
selfile.cpp File Reference
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <core/xmipp_funcs.h>
#include "selfile.h"
#include <core/xmipp_image.h>
Include dependency graph for selfile.cpp:

Go to the source code of this file.

Functions

bool operator< (const SelLine &l1, const SelLine &l2)
 
std::ostream & operator<< (std::ostream &o, const SelLine &SFL)
 
std::istream & operator>> (std::istream &o, SelLine &SFL)
 
std::ostream & operator<< (std::ostream &o, const SelFile &SF)
 
std::vector< SelLine >::iterator find (std::vector< SelLine > &text, const std::string &img_name)
 
SelFile compare (SelFile &SF1, SelFile &SF2, const int mode)
 

Function Documentation

◆ compare()

SelFile compare ( SelFile SF1,
SelFile SF2,
const int  mode 
)

Compare two selection files.

The result is another selection file. At the beginning of it there is information about the number of active and discarded images on both input selection files, about the number of matching files (a file is said to match if it is active in both selection files), the number of active files which are only in the first selection file, and the number of active files which are only in the second. Then goes the list of matching files, the list of files only in SF1 and the list of files only in SF2. There are comments enough to know where things start and finish, and what the numbers are at the beginning. If a file is active in a file and discarded in the other, then it is said to match and it is kept as active, a preceding comment warns of this situation.

if mode<0, output file will contain all information if mode=0, output will be selfile with overlapping images if mode=1, output will be selfile with images only in file 1 if mode=2, output will be selfile with images only in file 2

sel3 = compare(sel1, sel2);

Definition at line 872 of file selfile.cpp.

873 {
874  std::vector<SelLine> only_in_SF1;
875  std::vector<SelLine> only_in_SF2;
876  std::vector<SelLine> in_both;
877  SelFile result;
878  SelLine temp;
879  int SF1_discarded = 0, SF2_discarded = 0;
880  int maxLen = 15;
881  char str[maxLen + 1]; // + terminating null character
882 
883  // Search in File 1
884  std::vector<SelLine>::iterator current = SF1.text_line.begin();
885  std::vector<SelLine>::iterator last = SF1.text_line.end();
886  std::vector<SelLine>::iterator last_SF = SF2.text_line.end();
887  std::vector<SelLine>::iterator found;
888 
889  while (current != last)
890  {
891  // Skip if not active
892  if ((*current).line_type != SelLine::DATALINE)
893  {
894  current++;
895  continue;
896  }
897  if ((*current).label == SelLine::DISCARDED)
898  {
899  SF1_discarded++;
900  current++;
901  continue;
902  }
903 
904  // Try to find this archive into Sel File 2
905  found = SF2.find((*current).text);
906  if (found == last_SF)
907  only_in_SF1.push_back(*current);
908  else
909  if ((*found).label == SelLine::DISCARDED)
910  only_in_SF1.push_back(*current);
911  else
912  in_both.push_back(*current);
913  current++;
914  }
915 
916  // Search in File 2
917  current = SF2.text_line.begin();
918  last = SF2.text_line.end();
919 
920  while (current != last)
921  {
922  // Skip if not active
923  if ((*current).line_type != SelLine::DATALINE)
924  {
925  current++;
926  continue;
927  }
928  if ((*current).label == SelLine::DISCARDED)
929  {
930  SF2_discarded++;
931  current++;
932  continue;
933  }
934 
935  // Try to find this archive into Sel File 2
936  found = find(in_both, (*current).text);
937  if (found != in_both.end())
938  {
939  current++;
940  continue;
941  }
942  only_in_SF2.push_back(*current);
943  current++;
944  }
945 
946  // Write Statistics
947  if (mode < 0)
948  {
949  temp.line_type = SelLine::COMMENT;
950  temp.label = SelLine::DISCARDED;
951  temp.text = "# Statistics of comparison";
952  result.text_line.push_back(temp);
953  temp.text = "# -------------------------------------------------------------";
954  result.text_line.push_back(temp);
955  snprintf(str, maxLen, "%6d", SF1.no_imgs);
956  temp.text = "# File 1: " + SF1.fn_sel + "(VALID: " + str;
957  snprintf(str, maxLen, "%6d", SF1_discarded);
958  temp.text += (std::string) " DISCARDED: " + str + ")";
959  result.text_line.push_back(temp);
960  snprintf(str, maxLen, "%6d", SF2.no_imgs);
961  temp.text = "# File 2: " + SF2.fn_sel + "(VALID: " + str;
962  snprintf(str, maxLen, "%6d", SF2_discarded);
963  temp.text += (std::string) " DISCARDED: " + str + ")";
964  result.text_line.push_back(temp);
965  temp.text = "";
966  result.text_line.push_back(temp);
967  snprintf(str, maxLen, "%6lu", (unsigned long int)in_both.size());
968  temp.text = (std::string)"# Matching Files: " + str;
969  result.text_line.push_back(temp);
970  snprintf(str, maxLen, "%6lu", (unsigned long int)only_in_SF1.size());
971  temp.text = (std::string)"# Only in file 1: " + str;
972  result.text_line.push_back(temp);
973  snprintf(str, maxLen, "%6lu", (unsigned long int)only_in_SF2.size());
974  temp.text = (std::string)"# Only in file 2: " + str;
975  result.text_line.push_back(temp);
976  temp.text = "# -------------------------------------------------------------";
977  result.text_line.push_back(temp);
978 
979  // Write files in both
980  temp.text = "";
981  result.text_line.push_back(temp);
982  temp.text = "# Files in both .sel files";
983  result.text_line.push_back(temp);
984  }
985  if (mode<0 || mode==0)
986  {
987  current = in_both.begin();
988  last = in_both.end();
989  while (current != last)
990  result.text_line.push_back(*current++);
991  }
992 
993  if (mode<0)
994  {
995  // Write files only in Sel File 1
996  temp.text = "";
997  result.text_line.push_back(temp);
998  temp.text = "# Files only in the first file";
999  result.text_line.push_back(temp);
1000  }
1001  if (mode<0 || mode==1)
1002  {
1003  current = only_in_SF1.begin();
1004  last = only_in_SF1.end();
1005  while (current != last)
1006  result.text_line.push_back(*current++);
1007  }
1008 
1009  if (mode<0)
1010  {
1011  // Write files only in Sel File 2
1012  temp.text = "";
1013  result.text_line.push_back(temp);
1014  temp.text = "# Files only in the second file";
1015  result.text_line.push_back(temp);
1016  }
1017  if (mode<0 || mode==2)
1018  {
1019  current = only_in_SF2.begin();
1020  last = only_in_SF2.end();
1021  while (current != last)
1022  result.text_line.push_back(*current++);
1023  }
1024  // Adjust the remaining fields
1025  if (mode<0)
1026  result.no_imgs = in_both.size() + only_in_SF1.size() + only_in_SF2.size();
1027  else if (mode==0)
1028  result.no_imgs = in_both.size();
1029  else if (mode==1)
1030  result.no_imgs = only_in_SF1.size();
1031  else if (mode==2)
1032  result.no_imgs = only_in_SF2.size();
1033  result.current_line = result.text_line.begin();
1034 
1035  return result;
1036 }
std::vector< SelLine >::iterator find(std::vector< SelLine > &text, const std::string &img_name)
Definition: selfile.cpp:553
void mode

◆ find()

std::vector<SelLine>::iterator find ( std::vector< SelLine > &  text,
const std::string &  img_name 
)

Definition at line 553 of file selfile.cpp.

555 {
556  std::vector<SelLine>::iterator current = text.begin();
557  std::vector<SelLine>::iterator last = text.end();
558 
559  while (current != last)
560  {
561  if ((*current).line_type == SelLine::DATALINE &&
562  (*current).text == img_name)
563  return current;
564  current++;
565  }
566  return current;
567 }

◆ operator<()

bool operator< ( const SelLine l1,
const SelLine l2 
)

Lesser than. l1 is lesser than l2 if line_type(l1)<line_type(l2) or if they are equal if the text of l1 is lesser than the text of l2. The order of the line types are NOT_CONSIDERED, NOT_ASSIGNED, DATALINE, COMMENT

Definition at line 49 of file selfile.cpp.

50 {
51  if (l1.line_type < l2.line_type)
52  return 1;
53  else if (l1.line_type > l2.line_type)
54  return 0;
55  else
56  return l1.text < l2.text;
57 }

◆ operator<<() [1/2]

std::ostream& operator<< ( std::ostream &  o,
const SelLine SFL 
)

Show a SelLine.

Definition at line 59 of file selfile.cpp.

60 {
61  switch (SFL.line_type)
62  {
63  case SelLine::DATALINE:
64  o << SFL.text << " " << SFL.label << std::endl;
65  break;
66  case SelLine::COMMENT:
67  o << SFL.text << std::endl;
68  break;
69  default:
70  break;
71  }
72  return o;
73 }

◆ operator<<() [2/2]

std::ostream& operator<< ( std::ostream &  o,
const SelFile SF 
)

Show a selection file.

Shows all the lines either they are comments, active images or discarded images. A new line is printed at the end.

std::cout << sel;

Definition at line 145 of file selfile.cpp.

146 {
147  std::vector<SelLine>::const_iterator current = SF.text_line.begin();
148  std::vector<SelLine>::const_iterator last = SF.text_line.end();
149  while (current != last)
150  {
151  o << *current;
152  current++;
153  }
154  return o;
155 }

◆ operator>>()

std::istream& operator>> ( std::istream &  o,
SelLine SFL 
)

Read a Selection Line.

An exception is thrown if the line doesn't meet the SelFile specifications.

Definition at line 75 of file selfile.cpp.

76 {
77  std::string line;
78  char img_name[1024];
79  int no_elements_read;
80  int label;
81 
82  // Get line
83  getline(o, line);
84 
85  // Initialise target
86  SFL.line_type = SelLine::NOT_ASSIGNED;
87  SFL.text = "";
88  SFL.label = SelLine::DISCARDED;
89  if (line.length() == 0)
90  return o;
91 
92  // Check if comment or empty line
93  if (line[0] == '#' || line[0] == '\0' || line[0] == ';')
94  {
95  line[line.length()-1] = '\0';
96  SFL.line_type = SelLine::COMMENT;
97  SFL.text = line;
98 
99  // Check if a true "filename label" line
100  }
101  else
102  {
103  no_elements_read = sscanf(line.c_str(), "%s %d", img_name, &label);
104  // *** THE SSCANF CAN BE REPLACED BY A STRING I/O OPERATION
105  if (no_elements_read == 2)
106  {
107  SFL.line_type = SelLine::DATALINE;
108  SFL.text = img_name;
109  SFL.label = (label >= 0) ? SelLine::ACTIVE : SelLine::DISCARDED;
110  SFL.number = label;
111  }
112  else
113  REPORT_ERROR(ERR_SELFILE, "Format error when reading Selection line");
114  }
115  return o;
116 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Error in docfile format.
Definition: xmipp_error.h:186