@@ -862,14 +862,15 @@ def _add_predictor_coords(
862862
863863 Returns:
864864 A cube with the predictor_index and predictor_name
865- coordinates added.
865+ coordinates added. Single value dimension coordinates
866+ are converted to non-dimension coordinates.
866867 """
867868 template_cubes = iris .cube .CubeList ()
868869 fp_names = []
869870 for index , fp in enumerate (forecast_predictors ):
870871 template_cube_copy = template_cube .copy ()
871872 predictor_index = iris .coords .DimCoord (
872- np .array (index , dtype = np .int32 ), long_name = "predictor_index" , units = "1" ,
873+ np .array (index , dtype = np .int8 ), long_name = "predictor_index" , units = "1" ,
873874 )
874875 template_cube_copy .add_aux_coord (predictor_index )
875876 template_cube_copy = iris .util .new_axis (template_cube_copy , predictor_index )
@@ -882,7 +883,7 @@ def _add_predictor_coords(
882883 template_cube .add_aux_coord (
883884 predictor_name , data_dims = template_cube .coord_dims ("predictor_index" ),
884885 )
885- return template_cube
886+ return iris . util . squeeze ( template_cube )
886887
887888 def _create_cubelist (
888889 self ,
@@ -930,7 +931,10 @@ def _create_cubelist(
930931 template_cube = self ._add_predictor_coords (
931932 template_cube , forecast_predictors
932933 )
934+ optimised_coeff = np .reshape (optimised_coeff , template_cube .shape )
933935 replacements += ["predictor_index" , "predictor_name" ]
936+ else :
937+ optimised_coeff = np .array (optimised_coeff )
934938
935939 for coord in coords_to_replace :
936940 template_cube .replace_coord (coord )
@@ -952,9 +956,7 @@ def _create_cubelist(
952956 template_cube ,
953957 generate_mandatory_attributes ([historic_forecasts ]),
954958 optional_attributes = self ._set_attributes (historic_forecasts ),
955- data = np .reshape (optimised_coeff , template_cube .shape )
956- if "beta" == coeff_name
957- else np .array (optimised_coeff ),
959+ data = optimised_coeff ,
958960 )
959961 cubelist .append (cube )
960962 return cubelist
@@ -1021,7 +1023,6 @@ def compute_initial_guess(
10211023 truths : ndarray ,
10221024 forecast_predictor : ndarray ,
10231025 predictor : str ,
1024- number_of_forecast_predictors : int ,
10251026 number_of_realizations : Optional [int ],
10261027 ) -> List [float ]:
10271028 """
@@ -1065,9 +1066,6 @@ def compute_initial_guess(
10651066 the location parameter when estimating the EMOS coefficients.
10661067 Currently the ensemble mean ("mean") and the ensemble
10671068 realizations ("realizations") are supported as the predictors.
1068- number_of_forecast_predictors:
1069- Number of forecast predictors. This includes all additional
1070- fields to include in the calibration.
10711069 number_of_realizations:
10721070 Number of realizations within the forecast predictor. If no
10731071 realizations are present, this option is None.
@@ -1089,7 +1087,7 @@ def compute_initial_guess(
10891087
10901088 if predictor == "mean" and default_initial_guess :
10911089 initial_beta = np .repeat (
1092- 1.0 / number_of_forecast_predictors , number_of_forecast_predictors
1090+ 1.0 / forecast_predictor . shape [ 0 ], forecast_predictor . shape [ 0 ]
10931091 ).tolist ()
10941092 initial_guess = [0 ] + initial_beta + [0 , 1 ]
10951093 elif predictor == "realizations" and default_initial_guess :
@@ -1175,22 +1173,18 @@ def guess_and_minimise(
11751173
11761174 """
11771175 if self .point_by_point and not self .use_default_initial_guess :
1178- index = [
1179- truths .coord (axis = "y" ),
1180- truths .coord (axis = "x" ),
1181- ]
11821176 y_name = truths .coord (axis = "y" ).name ()
11831177 x_name = truths .coord (axis = "x" ).name ()
11841178
11851179 initial_guess = []
1186- for truth_slice in truths .slices_over (index ):
1180+ for truth_slice in truths .slices_over ([ y_name , x_name ] ):
11871181 constr = iris .Constraint (
11881182 coord_values = {
11891183 y_name : lambda cell : any (
1190- np .isclose (cell .point , truth_slice .coord (axis = "y" ).points )
1184+ np .isclose (cell .point , truth_slice .coord (y_name ).points )
11911185 ),
11921186 x_name : lambda cell : any (
1193- np .isclose (cell .point , truth_slice .coord (axis = "x" ).points )
1187+ np .isclose (cell .point , truth_slice .coord (x_name ).points )
11941188 ),
11951189 }
11961190 )
@@ -1209,7 +1203,6 @@ def guess_and_minimise(
12091203 truth_slice .data ,
12101204 forecast_predictors_data ,
12111205 self .predictor ,
1212- len (forecast_predictors ),
12131206 number_of_realizations ,
12141207 )
12151208 )
@@ -1227,7 +1220,6 @@ def guess_and_minimise(
12271220 truths .data ,
12281221 forecast_predictor_data ,
12291222 self .predictor ,
1230- len (forecast_predictors ),
12311223 number_of_realizations ,
12321224 )
12331225 if self .point_by_point :
@@ -1334,14 +1326,14 @@ def process(
13341326 "forecast_reference_time" ,
13351327 "realization" ,
13361328 ]
1337- for af_cube in additional_fields :
1338- if any ([af_cube .coords (c ) for c in disallowed_coords ]):
1329+ for cube in additional_fields :
1330+ if any ([cube .coords (c ) for c in disallowed_coords ]):
13391331 coords = [
1340- af_cube .coord (c ) for c in disallowed_coords if af_cube .coords (c )
1332+ cube .coord (c ) for c in disallowed_coords if cube .coords (c )
13411333 ]
13421334 msg = (
13431335 "Only static additional predictors are supported. "
1344- f"The { af_cube .name ()} cube provided contains { coords } ."
1336+ f"The { cube .name ()} cube provided contains { coords } ."
13451337 )
13461338 raise ValueError (msg )
13471339
@@ -1360,9 +1352,8 @@ def process(
13601352
13611353 number_of_realizations = None
13621354 if self .predictor == "mean" :
1363- forecast_predictors = iris .cube .CubeList ()
1364- forecast_predictors .append (
1365- collapsed (historic_forecasts , "realization" , iris .analysis .MEAN )
1355+ forecast_predictors = iris .cube .CubeList (
1356+ [collapsed (historic_forecasts , "realization" , iris .analysis .MEAN )]
13661357 )
13671358 elif self .predictor == "realizations" :
13681359 number_of_realizations = len (historic_forecasts .coord ("realization" ).points )
@@ -1417,6 +1408,7 @@ def __init__(self, predictor: str = "mean") -> None:
14171408
14181409 self .coefficients_cubelist = None
14191410 self .current_forecast = None
1411+ self .additional_fields = None
14201412
14211413 def __repr__ (self ) -> str :
14221414 """Represent the configured plugin instance as a string."""
@@ -1491,29 +1483,18 @@ def _calculate_location_parameter_from_mean(self) -> ndarray:
14911483 Location parameter calculated using the ensemble mean as the
14921484 predictor.
14931485 """
1494- forecast_predictors = iris .cube .CubeList ()
1495- forecast_predictors .append (
1496- collapsed (self .current_forecast , "realization" , iris .analysis .MEAN )
1486+ forecast_predictors = iris .cube .CubeList (
1487+ [collapsed (self .current_forecast , "realization" , iris .analysis .MEAN )]
14971488 )
14981489 if self .additional_fields :
14991490 forecast_predictors .extend (self .additional_fields )
15001491
1492+ beta_cube = self .coefficients_cubelist .extract_cube ("emos_coefficient_beta" )
1493+
15011494 fp_names = [fp .name () for fp in forecast_predictors ]
1502- if len (forecast_predictors ) != len (
1503- self .coefficients_cubelist .extract_cube ("emos_coefficient_beta" )
1504- .coord ("predictor_index" )
1505- .points
1506- ):
1507- n_coord_points = len (
1508- self .coefficients_cubelist .extract_cube ("emos_coefficient_beta" )
1509- .coord ("predictor_index" )
1510- .points
1511- )
1512- coord_names = (
1513- self .coefficients_cubelist .extract_cube ("emos_coefficient_beta" )
1514- .coord ("predictor_name" )
1515- .points
1516- )
1495+ if len (forecast_predictors ) != len (beta_cube .coord ("predictor_index" ).points ):
1496+ n_coord_points = len (beta_cube .coord ("predictor_index" ).points )
1497+ coord_names = beta_cube .coord ("predictor_name" ).points
15171498 msg = (
15181499 "The number of forecast predictors must equal the number of "
15191500 "beta coefficients in order to create a calibrated forecast. "
@@ -1527,12 +1508,7 @@ def _calculate_location_parameter_from_mean(self) -> ndarray:
15271508 location_parameter = np .zeros (forecast_predictors [0 ].shape )
15281509 for fp in forecast_predictors :
15291510 constr = iris .Constraint (predictor_name = fp .name ())
1530- location_parameter += (
1531- self .coefficients_cubelist .extract_cube ("emos_coefficient_beta" )
1532- .extract (constr )
1533- .data
1534- * fp .data
1535- )
1511+ location_parameter += beta_cube .extract (constr ).data * fp .data
15361512 location_parameter += self .coefficients_cubelist .extract_cube (
15371513 "emos_coefficient_alpha"
15381514 ).data
0 commit comments