From 18afbb7119a5c61b8ab30f47eb940f98f54bd57b Mon Sep 17 00:00:00 2001 From: Lars Hoffmann Date: Tue, 25 Jun 2024 16:34:59 +0200 Subject: [PATCH] Added boundary checks for reading compressed meteo data. --- src/mptrac.c | 40 +++++++++++++++++++-------------- src/mptrac.h | 62 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/mptrac.c b/src/mptrac.c index 22e642d5c..47ef6d3bb 100644 --- a/src/mptrac.c +++ b/src/mptrac.c @@ -440,7 +440,6 @@ void compress_cms( if (decompress) { /* Loop over levels... */ - //#pragma omp parallel for double cr = 0; for (size_t ip = 0; ip < np; ip++) { @@ -448,6 +447,7 @@ void compress_cms( cms_sol_t *sol = cms_read_sol(cms_ptr, inout); /* Evaluate... */ +#pragma omp parallel for default(shared) for (size_t ix = 0; ix < nx; ix++) for (size_t iy = 0; iy < ny; iy++) { double val, x[] = { lon[ix], lat[iy] }; @@ -470,7 +470,6 @@ void compress_cms( else { /* Loop over levels... */ - //#pragma omp parallel for double cr = 0; for (size_t ip = 0; ip < np; ip++) { @@ -5706,22 +5705,22 @@ int read_met( read_met_bin_2d(in, met, met->cin, "CIN"); /* Read level data... */ - read_met_bin_3d(in, ctl, met, met->z, "Z"); - read_met_bin_3d(in, ctl, met, met->t, "T"); - read_met_bin_3d(in, ctl, met, met->u, "U"); - read_met_bin_3d(in, ctl, met, met->v, "V"); - read_met_bin_3d(in, ctl, met, met->w, "W"); - read_met_bin_3d(in, ctl, met, met->pv, "PV"); - read_met_bin_3d(in, ctl, met, met->h2o, "H2O"); - read_met_bin_3d(in, ctl, met, met->o3, "O3"); - read_met_bin_3d(in, ctl, met, met->lwc, "LWC"); + read_met_bin_3d(in, ctl, met, met->z, "Z", -1e34f, 1e34f); + read_met_bin_3d(in, ctl, met, met->t, "T", 0, 1e34f); + read_met_bin_3d(in, ctl, met, met->u, "U", -1e34f, 1e34f); + read_met_bin_3d(in, ctl, met, met->v, "V", -1e34f, 1e34f); + read_met_bin_3d(in, ctl, met, met->w, "W", -1e34f, 1e34f); + read_met_bin_3d(in, ctl, met, met->pv, "PV", -1e34f, 1e34f); + read_met_bin_3d(in, ctl, met, met->h2o, "H2O", 0, 1e34f); + read_met_bin_3d(in, ctl, met, met->o3, "O3", 0, 1e34f); + read_met_bin_3d(in, ctl, met, met->lwc, "LWC", 0, 1e34f); if (version >= 102) - read_met_bin_3d(in, ctl, met, met->rwc, "RWC"); - read_met_bin_3d(in, ctl, met, met->iwc, "IWC"); + read_met_bin_3d(in, ctl, met, met->rwc, "RWC", 0, 1e34f); + read_met_bin_3d(in, ctl, met, met->iwc, "IWC", 0, 1e34f); if (version >= 102) - read_met_bin_3d(in, ctl, met, met->swc, "SWC"); + read_met_bin_3d(in, ctl, met, met->swc, "SWC", 0, 1e34f); if (version >= 101) - read_met_bin_3d(in, ctl, met, met->cc, "CC"); + read_met_bin_3d(in, ctl, met, met->cc, "CC", 0, 1); /* Read final flag... */ int final; @@ -5845,7 +5844,9 @@ void read_met_bin_3d( ctl_t * ctl, met_t * met, float var[EX][EY][EP], - char *varname) { + char *varname, + float bound_min, + float bound_max) { float *help; @@ -5910,8 +5911,13 @@ void read_met_bin_3d( #pragma omp parallel for default(shared) collapse(2) for (int ix = 0; ix < met->nx; ix++) for (int iy = 0; iy < met->ny; iy++) - for (int ip = 0; ip < met->np; ip++) + for (int ip = 0; ip < met->np; ip++) { var[ix][iy][ip] = help[ARRAY_3D(ix, iy, met->ny, ip, met->np)]; + if (var[ix][iy][ip] < bound_min) + var[ix][iy][ip] = bound_min; + else if (var[ix][iy][ip] > bound_max) + var[ix][iy][ip] = bound_max; + } /* Free... */ free(help); diff --git a/src/mptrac.h b/src/mptrac.h index 9aea5b105..66495bdef 100644 --- a/src/mptrac.h +++ b/src/mptrac.h @@ -6185,31 +6185,39 @@ void read_met_bin_2d( char *varname); /** - * @brief Reads a 3-dimensional meteorological variable from a binary file and stores it in the provided array. - * - * This function reads a 3-dimensional meteorological variable from a - * binary file, which can be uncompressed or compressed using - * different methods, and stores it in the provided 3-dimensional - * array `var`. The variable name is used for logging purposes to - * identify the data being read. - * - * @param in A pointer to the FILE structure representing the binary file to read from. - * @param ctl A pointer to a structure containing control parameters. - * @param met A pointer to a structure containing meteorological data. - * @param var A 3-dimensional array to store the read variable. - * @param varname A string containing the name of the variable being read. - * - * The function performs the following steps based on the compression type specified in `ctl->met_type`: - * - If uncompressed data, it allocates memory for a temporary buffer, reads the data from the file, - * and then copies it to the provided array. - * - If the data is compressed using packing, zfp, zstd, or cmultiscale compression, it calls corresponding - * compression functions to decompress the data, then copies the decompressed data to the provided array. - * - The data is copied to the provided array using OpenMP parallelization for improved performance. - * - Finally, the memory allocated for the temporary buffer is freed. - * - * @note This function supports different compression methods based on the value of `ctl->met_type`. - * If a particular compression method is not supported or the necessary libraries are not available, - * an error message is generated. + * @brief Reads 3D meteorological data from a binary file, potentially using different compression methods. + * + * This function reads 3-dimensional meteorological data from a binary + * file into a specified variable array. The data can be read in + * uncompressed form or using one of several supported compression + * methods. The data is then clamped to specified minimum and maximum + * bounds. + * + * @param[in] in Pointer to the input file from which to read the data. + * @param[in] ctl Pointer to the control structure that contains metadata about the type of data and how it is stored. + * @param[in] met Pointer to the meteorological structure that contains the dimensions of the data. + * @param[out] var 3D array to store the read data, with dimensions [EX][EY][EP]. + * @param[in] varname Name of the variable being read, used for logging and debugging. + * @param[in] bound_min Minimum bound to which data values should be clamped. + * @param[in] bound_max Maximum bound to which data values should be clamped. + * + * The function supports the following types of data: + * - Uncompressed data + * - Packed data + * - ZFP compressed data (if compiled with ZFP support) + * - ZSTD compressed data (if compiled with ZSTD support) + * - CMULTISCALE compressed data (if compiled with CMS support) + * + * Depending on the compression type specified in the control + * structure, the appropriate reading and decompression function is + * used. The data is read into a temporary buffer, then copied into + * the output array, applying the specified bounds to each value. + * + * @note The function assumes that the dimensions EX, EY, and EP are + * correctly defined and match the dimensions specified in the + * `met` structure. + * @note If the appropriate compression support is not compiled, an + * error message is generated. * * @author Lars Hoffmann */ @@ -6218,7 +6226,9 @@ void read_met_bin_3d( ctl_t * ctl, met_t * met, float var[EX][EY][EP], - char *varname); + char *varname, + float bound_min, + float bound_max); /** * @brief Calculates Convective Available Potential Energy (CAPE) for each grid point.