|
45 | 45 | """ |
46 | 46 |
|
47 | 47 | from . import helpers as hh |
48 | | -import iris.fileformats.pp as pp |
| 48 | + |
49 | 49 | from functools import wraps |
50 | 50 |
|
| 51 | +import iris.fileformats.pp as pp |
| 52 | +import iris.fileformats.cf |
| 53 | + |
51 | 54 |
|
52 | 55 | def _default_rulenamesfunc(func_name): |
53 | 56 | # A simple default function to deduce the rules-name from an action-name. |
@@ -446,6 +449,46 @@ def action_build_label_coordinate(engine, label_fact): |
446 | 449 | hh.build_auxiliary_coordinate(engine, var) |
447 | 450 |
|
448 | 451 |
|
| 452 | +@action_function |
| 453 | +def action_formula_type(engine, formula_root_fact): |
| 454 | + """Register a CFVariable as a formula root.""" |
| 455 | + rule_name = "fc_formula_type" |
| 456 | + (var_name,) = formula_root_fact |
| 457 | + cf_var = engine.cf_var.cf_group[var_name] |
| 458 | + # var.standard_name is a formula type (or we should never get here). |
| 459 | + formula_type = getattr(cf_var, "standard_name", None) |
| 460 | + succeed = True |
| 461 | + if formula_type not in iris.fileformats.cf.reference_terms: |
| 462 | + succeed = False |
| 463 | + rule_name += f"(FAILED - unrecognised formula type = {formula_type!r})" |
| 464 | + if succeed: |
| 465 | + # Check we don't already have one. |
| 466 | + existing_type = engine.requires.get("formula_type") |
| 467 | + if existing_type: |
| 468 | + succeed = False |
| 469 | + rule_name += ( |
| 470 | + f"(FAILED - new formula type ={formula_type!r} " |
| 471 | + f"collided with existing one ={existing_type!r}.)" |
| 472 | + ) |
| 473 | + if succeed: |
| 474 | + rule_name += f"_{formula_type}" |
| 475 | + # Set 'requires' info for iris.fileformats.netcdf._load_aux_factory. |
| 476 | + engine.requires["formula_type"] = formula_type |
| 477 | + |
| 478 | + return rule_name |
| 479 | + |
| 480 | + |
| 481 | +@action_function |
| 482 | +def action_formula_term(engine, formula_term_fact): |
| 483 | + """Register a CFVariable as a formula term.""" |
| 484 | + # Must run AFTER formula root identification. |
| 485 | + (termvar_name, rootvar_name, term_name) = formula_term_fact |
| 486 | + # The rootname is implicit : have only one per cube |
| 487 | + # TODO: change when we adopt cf-1.7 advanced grid-mping syntax |
| 488 | + engine.requires.setdefault("formula_terms", {})[term_name] = termvar_name |
| 489 | + rule_name = f"fc_formula_term({term_name})" |
| 490 | + |
| 491 | + |
449 | 492 | def run_actions(engine): |
450 | 493 | """ |
451 | 494 | Run all actions for a cube. |
@@ -505,3 +548,14 @@ def run_actions(engine): |
505 | 548 | label_facts = engine.fact_list("label") |
506 | 549 | for label_fact in label_facts: |
507 | 550 | action_build_label_coordinate(engine, label_fact) |
| 551 | + |
| 552 | + # formula root variables |
| 553 | + formula_root_facts = engine.fact_list("formula_root") |
| 554 | + for root_fact in formula_root_facts: |
| 555 | + action_formula_type(engine, root_fact) |
| 556 | + |
| 557 | + # formula terms |
| 558 | + # The 'formula_root's must have already been done. |
| 559 | + formula_term_facts = engine.fact_list("formula_term") |
| 560 | + for term_fact in formula_term_facts: |
| 561 | + action_formula_term(engine, term_fact) |
0 commit comments