ʻOhana
Population structure, admixture history, and selection using learning methods.
filter/jade.main.cpp
1 /* -------------------------------------------------------------------------
2  Ohana
3  Copyright (c) 2015-2020 Jade Cheng (\___/)
4  Jade Cheng <info@jade-cheng.com> (='.'=)
5  ------------------------------------------------------------------------- */
6 
7 #include "jade.args.hpp"
8 #include "jade.version.hpp"
9 #include "jade.rema.hpp"
10 
11 namespace
12 {
13  char const * const usage = R"(USAGE
14  filter <command> ... [<input> <output>]
15 
16 ARGUMENTS
17  command one of the following conversion types:
18 
19  rema Reduces the number of markers in a matrix.
20 
21 COMMANDS
22  rema
23 
24  USAGE
25  filter rema [options] <column-count> [<input> <output>]
26 
27  DESCRIPTION
28  This filter reduces the number of markers in a matrix. The number of
29  columns written to the output matrix is specified as a required argument.
30  The filter chooses the columns to remove at random, but their relative
31  order is not changed. It is possible to provide a random number seed as
32  an option; if unspecified, the program uses a time-dependent default
33  seed.
34 
35  OPTIONS
36  --seed,-s indicates the next argument is the random number seed; if
37  unspecified, the program uses a time-dependent default seed
38 
39  EXAMPLE
40  $ filter rema 1000 in.lgm out.lgm
41  $ cat in.lgm | filter rema --seed 1864 1000 > out.lgm
42 
43 OPTIONS
44  --help,-h shows this help message and exits
45  --version,-v prints version information and exits
46 
47 DESCRIPTION
48  Filters input given to the program. Further details are provided in the
49  section above describing the various commands.
50 
51  For all commands, if no arguments are given, the source data is read from
52  standard input and the output data is written to standard output. Otherwise,
53  the path to the input file and output file must be specified after the
54  filter arguments.
55 
56 EXAMPLE
57  $ filter rema 1000 in.lgm out.lgm
58  $ cat in.lgm | filter rema --seed 1864 1000 > out.lgm
59 
60 BUGS
61  Report any bugs to Jade Cheng <info@jade-cheng.com>.
62 
63 Copyright (c) 2015-2020 Jade Cheng
64 )";
65 
66  ///
67  /// Executes the program based on the specified options.
68  ///
69  template <typename TController>
70  int execute(
71  jade::args & a) ///< The command-line arguments.
72  {
73  //
74  // Create a new controller instance, allowing it to process the
75  // arguments for additional options and values.
76  //
77  typedef TController controller_type;
78  controller_type controller (a);
79 
80  //
81  // If input and output arguments were provided, read from and write to
82  // the corresponding files; otherwise, read from and write to the
83  // standard streams.
84  //
85  if (a.is_empty())
86  {
87  controller.execute(std::cin, std::cout);
88  }
89  else
90  {
91  const auto src = a.pop<std::string>();
92  const auto dst = a.pop<std::string>();
93  a.validate_empty();
94 
95  std::ifstream in (src);
96  if (!in.good())
97  throw jade::error() << "failed to open '" << src << "'";
98 
99  std::ofstream out (dst);
100  if (!out.good())
101  throw jade::error() << "failed to create '" << dst << "'";
102 
103  controller.execute(in, out);
104  }
105 
106  return EXIT_SUCCESS;
107  }
108 }
109 
110 ///
111 /// The main entry point of the program.
112 /// \param argc The argument count.
113 /// \param argv The argument values.
114 /// \return EXIT_SUCCESS or EXIT_FAILURE.
115 ///
116 int main(const int argc, const char * argv[])
117 {
118  try
119  {
120  jade::args args (argc, argv);
121 
122  if (args.read_flag("--help", "-h"))
123  {
124  std::cout << ::usage;
125  return EXIT_SUCCESS;
126  }
127 
128  if (args.read_flag("--version", "-v"))
129  {
130  jade::version::write("filter", std::cout);
131  return EXIT_SUCCESS;
132  }
133 
134  typedef jade::rema rema_type;
135 
136  const auto command = args.pop<std::string>();
137 
138  if (command == "rema") return ::execute<rema_type>(args);
139 
140  throw jade::error() << "unsupported command '" << command << "'";
141  }
142  catch (const std::exception & e)
143  {
144  std::cerr << e.what() << std::endl;
145  return EXIT_FAILURE;
146  }
147 }
jade::basic_args::validate_empty
void validate_empty() const
Throws an exception if there are more arguments to be processed.
Definition: jade.args.hpp:161
jade::basic_error::what
virtual const char * what() const
jade::basic_args::is_empty
bool is_empty() const
Definition: jade.args.hpp:86
jade::basic_args::pop
TValue pop()
Definition: jade.args.hpp:96
jade::basic_rema
A template for a class that reduces columns of matrices given to it. The columns to keep are chosen a...
Definition: jade.rema.hpp:22
jade::basic_args
A template for a class that helps process command-line arguments.
Definition: jade.args.hpp:19
jade::basic_version::write
static void write(char_type const *const title, ostream_type &out)
Writes the string displayed to the user.
Definition: jade.version.hpp:29
jade::basic_error
A template for a class representing an exception thrown from this namespace.
Definition: jade.error.hpp:20