contrib/mul/mbl/tools/mbl_masked_file_merge.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Tool to apply mask-based merge operation between two value files
00004 
00005 #include <vcl_string.h>
00006 #include <vul/vul_arg.h>
00007 #include <vcl_exception.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_algorithm.h>
00010 #include <mbl/mbl_mask.h>
00011 #include <vcl_fstream.h>
00012 
00013 // IO helpers - see below for definition
00014 bool load_values(const vcl_string & filename, vcl_vector<vcl_string> & values, bool ignore_blanks = true);
00015 void write_vals(const vcl_vector<vcl_string> & values, vcl_ostream & os);
00016 
00017 int main(int argc, char **argv)
00018 {
00019   vul_arg_base::set_help_description(
00020     "Merge two files according to a mask.\n"
00021     "------------------------------------\n"
00022     "The two value files and the mask must be the same length N\n"
00023     "The value files will be merged as follows:\n\n"
00024     "  For every entry index i in the file (0..N-1)\n"
00025     "    If i'th mask value is false use i'th entry from first value file\n"
00026     "    Else use i'th entry from second value file\n\n"
00027     "The output will also be of length N\n\n"
00028     "Note: blank lines in the values files will be ignored unless -b flag is set\n"
00029     "      blank lines in the mask are always ignored\n"
00030     "\n"
00031   );
00032 
00033   vul_arg<vcl_string> valueA_filename(0,"Filename of values file A");
00034   vul_arg<vcl_string> valueB_filename(0,"Filename of values file B");
00035   vul_arg<vcl_string> mask_filename(0,"Filename of mask");
00036   vul_arg<vcl_string> output_filename("-out","Filename for output - sent to standard out if not set");
00037   vul_arg<bool> use_blanks("-b", "Keep blank lines in values files (they are stripped by default)");
00038   vul_arg_parse(argc, argv);
00039 
00040   mbl_mask mask;
00041   mbl_load_mask(mask, mask_filename().c_str());
00042 
00043   vcl_vector<vcl_string> valuesA, valuesB;
00044   if (!load_values(valueA_filename(), valuesA, !use_blanks.set()))
00045   {
00046     vcl_cout << "Unable to load values from file " << valueA_filename() << vcl_endl;
00047     return 1;
00048   }
00049   if (!load_values(valueB_filename(), valuesB, !use_blanks.set()))
00050   {
00051     vcl_cout << "Unable to load values from file " << valueB_filename() << vcl_endl;
00052     return 1;
00053   }
00054 
00055   try {
00056     mbl_mask_merge_values(mask, valuesA.begin(), valuesA.end(), valuesB.begin(), valuesB.end(), valuesB.begin());
00057   }
00058   catch (vcl_exception & e)
00059   {
00060     vcl_cout << "An error occurred while merging the data.\n" << e.what() << vcl_endl;
00061     return 1;
00062   }
00063   catch (...)
00064   {
00065     vcl_cout << "An unknown error occurred while merging the data." << vcl_endl;
00066     return 1;
00067   }
00068 
00069   if (output_filename.set())
00070   {
00071     vcl_ofstream val_out(output_filename().c_str());
00072     if (!val_out)
00073     {
00074       vcl_cout << "Unable to save output data to " << output_filename() << vcl_endl;
00075       return 1;
00076     }
00077     write_vals(valuesB, val_out);
00078     val_out.close();
00079   }
00080   else
00081     write_vals(valuesB, vcl_cout);
00082 }
00083 
00084 
00085 // io helpers
00086 
00087 bool load_values(const vcl_string & filename, vcl_vector<vcl_string> & values, bool ignore_blanks)
00088 {
00089   vcl_ifstream fin(filename.c_str());
00090   if (!fin) return false;
00091 
00092   values.clear();
00093 
00094   vcl_string line;
00095   while (vcl_getline(fin, line))
00096   {
00097     if (line.empty() && ignore_blanks) continue;
00098     values.push_back(line);
00099   }
00100   return true;
00101 }
00102 
00103 void write_vals(const vcl_vector<vcl_string> & values, vcl_ostream & os)
00104 {
00105   vcl_copy(values.begin(), values.end(), vcl_ostream_iterator<vcl_string>(os, "\n"));
00106 }