Last active
December 19, 2015 18:29
-
-
Save rhattersley/5999202 to your computer and use it in GitHub Desktop.
Iris rule conversion script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# (C) British Crown Copyright 2010 - 2013, Met Office | |
# | |
# This file is part of Iris. | |
# | |
# Iris is free software: you can redistribute it and/or modify it under | |
# the terms of the GNU Lesser General Public License as published by the | |
# Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# Iris is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU Lesser General Public License for more details. | |
# | |
# You should have received a copy of the GNU Lesser General Public License | |
# along with Iris. If not, see <http://www.gnu.org/licenses/>. | |
import re | |
def _write_rule(module_file, conditions, actions): | |
module_file.write('\n') | |
if len(conditions) == 1: | |
module_file.write(' if {}:\n'.format(conditions[0])) | |
else: | |
module_file.write(' if \\\n') | |
for condition in conditions[:-1]: | |
module_file.write(' ({}) and \\\n'.format(condition)) | |
module_file.write(' ({}):\n'.format(conditions[-1])) | |
for action in actions: | |
if action.startswith('CoordAndDims(DimCoord('): | |
match = re.match(r'CoordAndDims\((.*), ([0-1]+)\)$', action) | |
if match: | |
action = 'cube.add_dim_coord({})'.format(action[13:-1]) | |
else: | |
action = 'cube.add_aux_coord({})'.format(action[13:-1]) | |
elif action.startswith('CoordAndDims(AuxCoord('): | |
action = 'cube.add_aux_coord({})'.format(action[13:-1]) | |
elif action.startswith('CellMethod('): | |
action = 'cube.add_cell_method({})'.format(action) | |
elif action.startswith('CMCustomAttribute('): | |
match = re.match(r'CMCustomAttribute\(([\'"0-9a-zA-Z_]+), ?(.+)\)$', | |
action) | |
name = match.group(1) | |
value = match.group(2) | |
action = 'cube.attributes[{}] = {}'.format(name, value) | |
elif action.startswith('CMAttribute('): | |
match = re.match(r'CMAttribute\(([\'"0-9a-zA-Z_]+), (.+)\)$', | |
action) | |
name = eval(match.group(1)) | |
value = match.group(2) | |
# Temporary code to deal with invalid standard names from | |
# the translation table(s). | |
if name == 'standard_name': | |
action = 'cube.rename({})'.format(value) | |
# Temporary code to deal with invalid units in the | |
# translation table(s). | |
elif name == 'units': | |
action = '''units = {} | |
try: | |
setattr(cube, 'units', units) | |
except ValueError: | |
msg = 'Ignoring PP invalid units {{!r}}'.format(units) | |
warnings.warn(msg) | |
cube.attributes['invalid_units'] = units | |
cube.units = iris.unit._UNKNOWN_UNIT_STRING'''.format(value) | |
else: | |
action = 'cube.{} = {}'.format(name, value) | |
elif action.startswith('Factory('): | |
action = 'factories.append({})'.format(action) | |
elif action.startswith('ReferenceTarget('): | |
action = 'references.append({})'.format(action) | |
else: | |
print action | |
module_file.write(' {}\n'.format(action)) | |
def write_rules_module(field_var_name, rules_paths, module_path): | |
# Define state constants | |
IN_CONDITION = 1 | |
IN_ACTION = 2 | |
with open(module_path, 'w') as module_file: | |
header = \ | |
'''# (C) British Crown Copyright 2013, Met Office | |
# | |
# This file is part of Iris. | |
# | |
# Iris is free software: you can redistribute it and/or modify it under | |
# the terms of the GNU Lesser General Public License as published by the | |
# Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# Iris is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU Lesser General Public License for more details. | |
# | |
# You should have received a copy of the GNU Lesser General Public License | |
# along with Iris. If not, see <http://www.gnu.org/licenses/>. | |
import warnings | |
import numpy as np | |
from iris.aux_factory import HybridHeightFactory | |
from iris.coords import AuxCoord, CellMethod, DimCoord | |
from iris.fileformats.mosig_cf_map import MOSIG_STASH_TO_CF | |
from iris.fileformats.rules import Factory, Reference, ReferenceTarget | |
from iris.fileformats.um_cf_map import LBFC_TO_CF, STASH_TO_CF | |
from iris.unit import Unit | |
import iris.fileformats.pp | |
import iris.unit | |
def convert(cube, {}): | |
cm = cube | |
factories = [] | |
references = [] | |
''' | |
module_file.write(header.format(field_var_name)) | |
for rules_path in rules_paths: | |
with open(rules_path, 'r') as rules_file: | |
conditions = [] | |
actions = [] | |
state = None | |
for line in rules_file: | |
line = line.rstrip() | |
if line == "IF": | |
if conditions and actions: | |
_write_rule(module_file, conditions, actions) | |
conditions = [] | |
actions = [] | |
state = IN_CONDITION | |
elif line == "THEN": | |
state = IN_ACTION | |
elif len(line) == 0: | |
pass | |
elif line.strip().startswith('#'): | |
pass | |
elif state == IN_CONDITION: | |
conditions.append(line) | |
elif state == IN_ACTION: | |
actions.append(line) | |
else: | |
raise Exception('Rule file not read correctly at line: ' + line) | |
if conditions and actions: | |
_write_rule(module_file, conditions, actions) | |
module_file.write('\n return factories, references\n') | |
if __name__ == '__main__': | |
write_rules_module('f', ['transition/pp_rules.txt', | |
'transition/pp_cross_reference_rules.txt'], | |
'lib/iris/fileformats/pp_rules.py') | |
write_rules_module('grib', ['transition/grib_rules.txt', | |
'transition/grib_cross_reference_rules.txt'], | |
'lib/iris/fileformats/grib/load_rules.py') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment