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