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