www.mooseframework.org
FileRangeBuilder.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 #include "FileRangeBuilder.h"
8 
9 // MOOSE includes
10 #include "InputParameters.h"
11 
12 #include "pcrecpp.h"
13 #include "tinydir.h"
14 
15 template <>
18 {
20  params.addParam<FileName>("file",
21  "Name of single image file to extract mesh parameters from. "
22  "If provided, a 2D mesh is created.");
23  params.addParam<FileNameNoExtension>("file_base",
24  "Image file base to open, use this option when "
25  "a stack of images must be read (ignored if "
26  "'file' is given)");
27  params.addParam<std::vector<unsigned int>>(
28  "file_range",
29  "Range of images to analyze, used with 'file_base' (ignored if 'file' is given)");
30  params.addParam<std::string>("file_suffix", "Suffix of the file to open, e.g. 'png'");
31  return params;
32 }
33 
35 {
36  bool has_file = params.isParamValid("file"), has_file_base = params.isParamValid("file_base"),
37  has_file_range = params.isParamValid("file_range"),
38  has_file_suffix = params.isParamValid("file_suffix");
39 
40  // Variables to be (possibly) used below...
41  std::string file;
42  std::string file_base;
43  std::vector<unsigned int> file_range;
44 
45  if (has_file)
46  {
47  file = params.get<FileName>("file");
48 
49  // Set the file_suffix parameter in the passed-in params object based on the input filename
50  _file_suffix = file.substr(file.find_last_of(".") + 1);
51  }
52  if (has_file_base)
53  file_base = params.get<FileNameNoExtension>("file_base");
54  if (has_file_range)
55  file_range = params.get<std::vector<unsigned int>>("file_range");
56  if (has_file_suffix)
57  _file_suffix = params.get<std::string>("file_suffix");
58 
59  // Check that the combination of params provided is valid
60 
61  // 1.) Provided both a filename and a file base
62  if (has_file && has_file_base)
63  {
64  _status = 1;
65  return;
66  }
67 
68  // 2.) Provided neither a filename nor a file base
69  if (!has_file && !has_file_base)
70  {
71  _status = 2;
72  return;
73  }
74 
75  // 3.) Provided a file base but not a suffix
76  if (has_file_base && !has_file_suffix)
77  {
78  _status = 3;
79  return;
80  }
81 
82  // 4.) Provided a filename and a range, warn that the range will be ignored.
83  if (has_file && has_file_range)
84  mooseWarning("Warning: file_range was ignored since a filename was provided.");
85 
86  // 5.) Provided a file_base but not a file_range, we'll create one
87  if (has_file_base && !has_file_range)
88  {
89  file_range.push_back(0);
90  file_range.push_back(std::numeric_limits<unsigned int>::max());
91  }
92 
93  // 6.) Provided a file_range with a single entry, so repeat it for
94  // them. This signifies a single image (i.e. 2D Mesh) is to be
95  // used.
96  if (has_file_range && file_range.size() == 1)
97  file_range.push_back(file_range[0]);
98 
99  // 7.) Provided a file_range with too many entries, print a
100  // warning and truncate the extra values.
101  if (has_file_range && file_range.size() != 2)
102  {
103  mooseWarning("A maximum of two values are allowed in the file_range, extra values truncated.");
104  file_range.resize(2);
105  }
106 
107  // Make sure that the range is in ascending order
108  std::sort(file_range.begin(), file_range.end());
109 
110  // Build up the filenames parameter, and inject it into the InputParameters object
111  if (has_file)
112  _filenames.push_back(file);
113 
114  else if (has_file_base)
115  {
116  // Separate the file base from the path
117  std::pair<std::string, std::string> split_file = MooseUtils::splitFileName(file_base);
118 
119  // Create directory object
120  tinydir_dir dir;
121  tinydir_open_sorted(&dir, split_file.first.c_str());
122 
123  // This regex will capture the file_base and any number of digits when used with FullMatch()
124  std::ostringstream oss;
125  oss << "(" << split_file.second << ".*?(\\d+))\\..*";
126  pcrecpp::RE file_base_and_num_regex(oss.str());
127 
128  // Loop through the files in the directory
129  for (int i = 0; i < dir.n_files; i++)
130  {
131  // Update the current file
132  tinydir_file file;
133  tinydir_readfile_n(&dir, &file, i);
134 
135  // Store the file if it has proper extension as in numeric range
136  if (!file.is_dir && MooseUtils::hasExtension(file.name, _file_suffix))
137  {
138  std::string the_base;
139  unsigned int file_num = 0;
140  file_base_and_num_regex.FullMatch(file.name, &the_base, &file_num);
141 
142  if (!the_base.empty() && file_num >= file_range[0] && file_num <= file_range[1])
143  _filenames.push_back(split_file.first + "/" + file.name);
144  }
145  }
146  tinydir_close(&dir);
147  }
148 
149  else
150  mooseError("We'll never get here!");
151 
152  // If we made it here, there were no errors
153 }
154 
155 void
157 {
158  switch (_status)
159  {
160  case 0:
161  return;
162  case 1:
163  mooseError("Cannot provide both file and file_base parameters");
164  break;
165  case 2:
166  mooseError("You must provide a valid value for either the 'file' parameter or the "
167  "'file_base' parameter.");
168  break;
169  case 3:
170  mooseError(
171  "If you provide a 'file_base', you must also provide a valid 'file_suffix', e.g. 'png'.");
172  break;
173  default:
174  mooseError("Unknown error code!");
175  }
176 }
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
InputParameters emptyInputParameters()
std::pair< std::string, std::string > splitFileName(std::string full_file)
Function for splitting path and filename.
Definition: MooseUtils.C:251
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
bool hasExtension(const std::string &filename, std::string ext, bool strip_exodus_ext=false)
Function tests if the supplied filename as the desired extension.
Definition: MooseUtils.C:227
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
FileRangeBuilder(const InputParameters &params)
std::string _file_suffix
InputParameters validParams< FileRangeBuilder >()
To be called in the validParams functions of classes that need to operate on ranges of files...
std::vector< std::string > _filenames
void mooseWarning(Args &&...args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:194