@@ -932,6 +932,60 @@ def _spatial_plot(
932932 _make_plot_html_page (complete_plot_index )
933933
934934
935+ def _calculate_CFAD (
936+ cube : iris .cube .Cube , vertical_coordinate : str , bin_edges : list [float ]
937+ ) -> iris .cube .Cube :
938+ """Calculate a Contour Frequency by Altitude Diagram (CFAD).
939+
940+ Parameters
941+ ----------
942+ cube: iris.cube.Cube
943+ A cube of the data to be turned into a CFAD. It should be a minimum
944+ of two dimensions with one being a user specified vertical coordinate.
945+ vertical_coordinate: str
946+ The vertical coordinate of the cube for the CFAD to be calculated over.
947+ bin_edges: list[float]
948+ The bin edges for the histogram. The bins need to be specified to
949+ ensure consistency across the CFAD, otherwise it cannot be interpreted.
950+ """
951+ # Setup empty array for containing the CFAD data.
952+ CFAD_values = np .zeros (
953+ (len (cube .coord (vertical_coordinate ).points ), len (bin_edges ) - 1 )
954+ )
955+
956+ # Set iterator for CFAD values.
957+ i = 0
958+
959+ # Calculate the CFAD as a histogram summing to one for each level.
960+ for level_cube in cube .slices_over (vertical_coordinate ):
961+ # Note setting density to True does not produce the correct
962+ # normalization for a CFAD, where each row must sum to one.
963+ CFAD_values [i , :] = (
964+ np .histogram (level_cube .data .reshape (level_cube .data .size ), bins = bin_edges )[
965+ 0
966+ ]
967+ / level_cube .data .size
968+ )
969+ i += 1
970+ # calculate central points for bins
971+ bins = (np .array (bin_edges [:- 1 ]) + np .array (bin_edges [1 :])) / 2.0
972+ bin_bounds = np .array ((bin_edges [:- 1 ], bin_edges [1 :])).T
973+ # Now construct the coordinates for the cube.
974+ vert_coord = cube .coord (vertical_coordinate )
975+ bin_coord = iris .coords .DimCoord (
976+ bins , bounds = bin_bounds , standard_name = cube .standard_name , units = cube .units
977+ )
978+ # Now construct the cube that is to be output.
979+ CFAD = iris .cube .Cube (
980+ CFAD_values ,
981+ dim_coords_and_dims = [(vert_coord , 0 ), (bin_coord , 1 )],
982+ standard_name = cube .standard_name ,
983+ units = "1" ,
984+ )
985+ CFAD .attributes ["type" ] = "Contour Frequency by Altitude Diagram (CFAD)"
986+ return CFAD
987+
988+
935989####################
936990# Public functions #
937991####################
0 commit comments