@@ -853,6 +853,60 @@ def _spatial_plot(
853
853
_make_plot_html_page (complete_plot_index )
854
854
855
855
856
+ def _calculate_CFAD (
857
+ cube : iris .cube .Cube , vertical_coordinate : str , bin_edges : list [float ]
858
+ ) -> iris .cube .Cube :
859
+ """Calculate a Contour Frequency by Altitude Diagram (CFAD).
860
+
861
+ Parameters
862
+ ----------
863
+ cube: iris.cube.Cube
864
+ A cube of the data to be turned into a CFAD. It should be a minimum
865
+ of two dimensions with one being a user specified vertical coordinate.
866
+ vertical_coordinate: str
867
+ The vertical coordinate of the cube for the CFAD to be calculated over.
868
+ bin_edges: list[float]
869
+ The bin edges for the histogram. The bins need to be specified to
870
+ ensure consistency across the CFAD, otherwise it cannot be interpreted.
871
+ """
872
+ # Setup empty array for containing the CFAD data.
873
+ CFAD_values = np .zeros (
874
+ (len (cube .coord (vertical_coordinate ).points ), len (bin_edges ) - 1 )
875
+ )
876
+
877
+ # Set iterator for CFAD values.
878
+ i = 0
879
+
880
+ # Calculate the CFAD as a histogram summing to one for each level.
881
+ for level_cube in cube .slices_over (vertical_coordinate ):
882
+ # Note setting density to True does not produce the correct
883
+ # normalization for a CFAD, where each row must sum to one.
884
+ CFAD_values [i , :] = (
885
+ np .histogram (level_cube .data .reshape (level_cube .data .size ), bins = bin_edges )[
886
+ 0
887
+ ]
888
+ / level_cube .data .size
889
+ )
890
+ i += 1
891
+ # calculate central points for bins
892
+ bins = (np .array (bin_edges [:- 1 ]) + np .array (bin_edges [1 :])) / 2.0
893
+ bin_bounds = np .array ((bin_edges [:- 1 ], bin_edges [1 :])).T
894
+ # Now construct the coordinates for the cube.
895
+ vert_coord = cube .coord (vertical_coordinate )
896
+ bin_coord = iris .coords .DimCoord (
897
+ bins , bounds = bin_bounds , standard_name = cube .standard_name , units = cube .units
898
+ )
899
+ # Now construct the cube that is to be output.
900
+ CFAD = iris .cube .Cube (
901
+ CFAD_values ,
902
+ dim_coords_and_dims = [(vert_coord , 0 ), (bin_coord , 1 )],
903
+ standard_name = cube .standard_name ,
904
+ units = "1" ,
905
+ )
906
+ CFAD .attributes ["type" ] = "Contour Frequency by Altitude Diagram (CFAD)"
907
+ return CFAD
908
+
909
+
856
910
####################
857
911
# Public functions #
858
912
####################
0 commit comments