3. How to Create Your Own Wrapper¶
Create the new wrapper in the METplus/ush directory and name it to reflect the wrapper’s function, e.g.: new_tool_wrapper.py You can copy example_wrapper.py to start
Open the file for editing and change the name of the class to reflect the wrapper’s function (in camel case). Following the example above, you would rename your class:
class NewToolWrapper(CommandBuilder)
Modify the init function to initialize NewExample from its base class (CommandBuilder), and to set the name and path to the MET application you are wrapping:
def __init__(self, p, logger): super(NewToolWrapper, self).__init__(config, logger) self.app_path = os.path.join(self.p.getdir('MET_BIN_DIR', ''), 'new_tool') self.app_name = os.path.basename(self.app_path)
NOTE: ‘new_tool’ is the name of the MET tool being wrapped
Override the run_at_time_once method if you are looping over forecast leads (LEAD_SEQ in the METplus config file) for each initialization time. Otherwise, override the run_at_time method. This is where the logic for building the MET command resides. Utilize the methods your wrapper inherits from the CommandBuilder parent/base class to set information such as input file, output file, param file, etc. Refer to the command_builder.py code in the METplus/ush directory for more information. You can also override some of the methods in command_builder.py or implement your own methods that are specific to your wrapper:
def run_at_time_once(self, valid_time, level, compare_var): ... self.infiles.append(inputfile) self.infiles.append(self.p.getstr('config', 'VERIFICATION_GRID')) ... self.set_output_path(os.path.join(regrid_dir, regrid_file)) ... self.args.append("-field 'name=\"{:s}\";level=\"(*,*)"\";"'.format(field_name)) self.args.append("-method BUDGET") self.args.append("-width 2") self.args.append("-name " + field_name)
Once you have provided all the necessary information to create the MET command, run self.get_command() to verify that the command your wrapper generated is well-formed. You may need to override get_command() in your wrapper if your MET application is different from the example. For instance, some MET tools require flags such as -f to precede the input filename. You can override get_command in the wrapper to prepend the required flag to the filename in your constructed MET command.
Call self.build() to run the command.
# Call self.clear() at the beginning of each loop iteration to prevent inadvertently reusing/re-running commands that were previously created.
Update the METplus/ush/master_metplus.py file to recognize your wrapper by adding an import statement:
from new_tool_wrapper import NewToolWrapper
To allow your use case to use your wrapper, assign the wrapper name to PROCESS_LIST:
[config] PROCESS_LIST = NewExample
NOTE: Do not include the text “Wrapper” at the end of your wrapper name. The PROCESS_LIST is located under the [config] section header in your use case and/or example configuration file.
Your use case/example configuration file is located in a directory structure like the following:
METplus/parm/use_cases/met_tool_wrapper/NewTool/NewTool.conf