mirror of https://github.com/ecmwf/eccodes.git
ECC-1388: GRIB2 CCSDS: Unpacked values different from simple packing
This commit is contained in:
parent
46aa690e88
commit
9476708bfd
|
@ -396,7 +396,12 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||||
Assert(val[i] == val[0]);
|
Assert(val[i] == val[0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((err = grib_set_double_internal(hand, self->reference_value, val[0])) != GRIB_SUCCESS)
|
if (grib_get_nearest_smaller_value(hand, self->reference_value, val[0], &reference_value) != GRIB_SUCCESS) {
|
||||||
|
grib_context_log(a->context, GRIB_LOG_ERROR,
|
||||||
|
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
|
||||||
|
return GRIB_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if ((err = grib_set_double_internal(hand, self->reference_value, reference_value)) != GRIB_SUCCESS)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if ((err = grib_set_long_internal(hand, self->number_of_values, n_vals)) != GRIB_SUCCESS)
|
if ((err = grib_set_long_internal(hand, self->number_of_values, n_vals)) != GRIB_SUCCESS)
|
||||||
|
@ -413,21 +418,60 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||||
if ((err = grib_get_long_internal(hand, self->number_of_data_points, &number_of_data_points)) != GRIB_SUCCESS)
|
if ((err = grib_get_long_internal(hand, self->number_of_data_points, &number_of_data_points)) != GRIB_SUCCESS)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
d = grib_power(decimal_scale_factor, 10);
|
if (bits_per_value == 0 || (binary_scale_factor == 0 && decimal_scale_factor != 0)) {
|
||||||
min *= d;
|
d = grib_power(decimal_scale_factor, 10);
|
||||||
max *= d;
|
min *= d;
|
||||||
|
max *= d;
|
||||||
|
|
||||||
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
|
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
|
||||||
grib_context_log(a->context, GRIB_LOG_ERROR,
|
grib_context_log(a->context, GRIB_LOG_ERROR,
|
||||||
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
|
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
|
||||||
return GRIB_INTERNAL_ERROR;
|
return GRIB_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reference_value > min) {
|
||||||
|
grib_context_log(a->context, GRIB_LOG_ERROR,
|
||||||
|
"CCSDS pack_double: reference_value=%g min_value=%g diff=%g", reference_value, min, reference_value - min);
|
||||||
|
DebugAssert(reference_value <= min);
|
||||||
|
return GRIB_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int last = 127; /* last must be a parameter coming from the def file*/
|
||||||
|
double range = 0;
|
||||||
|
double minrange = 0, maxrange = 0;
|
||||||
|
double unscaled_max = 0;
|
||||||
|
double unscaled_min = 0;
|
||||||
|
double f = 0;
|
||||||
|
double decimal = 1;
|
||||||
|
|
||||||
if (reference_value > min) {
|
range = (max - min);
|
||||||
grib_context_log(a->context, GRIB_LOG_ERROR,
|
unscaled_min = min;
|
||||||
"CCSDS pack_double: reference_value=%g min_value=%g diff=%g", reference_value, min, reference_value - min);
|
unscaled_max = max;
|
||||||
DebugAssert(reference_value <= min);
|
f = (grib_power(bits_per_value, 2) - 1);
|
||||||
return GRIB_INTERNAL_ERROR;
|
minrange = grib_power(-last, 2) * f;
|
||||||
|
maxrange = grib_power(last, 2) * f;
|
||||||
|
|
||||||
|
while (range < minrange) {
|
||||||
|
decimal_scale_factor += 1;
|
||||||
|
decimal *= 10;
|
||||||
|
min = unscaled_min * decimal;
|
||||||
|
max = unscaled_max * decimal;
|
||||||
|
range = (max - min);
|
||||||
|
}
|
||||||
|
while (range > maxrange) {
|
||||||
|
decimal_scale_factor -= 1;
|
||||||
|
decimal /= 10;
|
||||||
|
min = unscaled_min * decimal;
|
||||||
|
max = unscaled_max * decimal;
|
||||||
|
range = (max - min);
|
||||||
|
}
|
||||||
|
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
|
||||||
|
grib_context_log(a->context, GRIB_LOG_ERROR,
|
||||||
|
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
|
||||||
|
return GRIB_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
d = grib_power(decimal_scale_factor, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
binary_scale_factor = grib_get_binary_scale_fact(max, reference_value, bits_per_value, &err);
|
binary_scale_factor = grib_get_binary_scale_fact(max, reference_value, bits_per_value, &err);
|
||||||
|
@ -445,7 +489,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||||
p = encoded;
|
p = encoded;
|
||||||
for (i = 0; i < n_vals; i++) {
|
for (i = 0; i < n_vals; i++) {
|
||||||
long blen = bits8;
|
long blen = bits8;
|
||||||
unsigned long unsigned_val = (unsigned long)((((val[i] * d) - (reference_value)) * divisor) + 0.5);
|
unsigned long unsigned_val = (unsigned long)((((val[i] * d) - reference_value) * divisor) + 0.5);
|
||||||
while (blen >= 8) {
|
while (blen >= 8) {
|
||||||
blen -= 8;
|
blen -= 8;
|
||||||
*p = (unsigned_val >> blen);
|
*p = (unsigned_val >> blen);
|
||||||
|
@ -455,8 +499,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||||
}
|
}
|
||||||
/* buflen = n_vals*(bits_per_value/8);*/
|
/* buflen = n_vals*(bits_per_value/8);*/
|
||||||
|
|
||||||
grib_context_log(a->context, GRIB_LOG_DEBUG,
|
grib_context_log(a->context, GRIB_LOG_DEBUG,"CCSDS pack_double: packing %s, %d values", a->name, n_vals);
|
||||||
"CCSDS pack_double: packing %s, %d values", a->name, n_vals);
|
|
||||||
|
|
||||||
buflen += 10240;
|
buflen += 10240;
|
||||||
buf = (unsigned char*)grib_context_buffer_malloc_clear(a->context, buflen);
|
buf = (unsigned char*)grib_context_buffer_malloc_clear(a->context, buflen);
|
||||||
|
|
|
@ -33,8 +33,30 @@ grib_check_key_equals $outfile2 packingType,const "grid_ccsds 1"
|
||||||
grib_check_key_equals $outfile2 accuracy 0
|
grib_check_key_equals $outfile2 accuracy 0
|
||||||
rm -f $outfile1 $outfile2
|
rm -f $outfile1 $outfile2
|
||||||
|
|
||||||
|
# ECC-1388: Tiny values
|
||||||
|
# ---------------------
|
||||||
|
tempFilt=temp.$label.filter
|
||||||
|
IFS_SAMPLES_ROOT=${proj_dir}/ifs_samples
|
||||||
|
IFS_SAMPLE_SIMPLE=$IFS_SAMPLES_ROOT/grib1_mlgrib2/gg_ml.tmpl
|
||||||
|
IFS_SAMPLE_CCSDS=$IFS_SAMPLES_ROOT/grib1_mlgrib2_ccsds/gg_ml.tmpl
|
||||||
|
echo 'set bitsPerValue=24; set values={ 1.00000007851413483E-25, 1.00000007851413529E-25 }; write;' > $tempFilt
|
||||||
|
${tools_dir}/grib_filter -o $outfile1 $tempFilt $IFS_SAMPLE_SIMPLE
|
||||||
|
${tools_dir}/grib_filter -o $outfile2 $tempFilt $IFS_SAMPLE_CCSDS
|
||||||
|
${tools_dir}/grib_compare -c data:n $outfile1 $outfile2
|
||||||
|
rm -f $tempFilt
|
||||||
|
|
||||||
|
# ECC-1388: Constant field variant
|
||||||
|
# --------------------------------
|
||||||
|
echo 'set bitsPerValue=24; set values={ 1.00000007851413483E-25, 1.00000007851413483E-25 }; write;' > $tempFilt
|
||||||
|
${tools_dir}/grib_filter -o $outfile1 $tempFilt $IFS_SAMPLE_SIMPLE
|
||||||
|
${tools_dir}/grib_filter -o $outfile2 $tempFilt $IFS_SAMPLE_CCSDS
|
||||||
|
# Must compare the referenceValue with 0 tolerance (override the referenceValueError key)
|
||||||
|
${tools_dir}/grib_compare -R referenceValue=0 -c referenceValue $outfile1 $outfile2
|
||||||
|
rm -f $tempFilt
|
||||||
|
|
||||||
|
|
||||||
# ECC-1387
|
# ECC-1387
|
||||||
# --------
|
# ---------
|
||||||
echo 'set values={6, 6, 6};write;' | ${tools_dir}/grib_filter -o $outfile2 - ${data_dir}/ccsds.grib2
|
echo 'set values={6, 6, 6};write;' | ${tools_dir}/grib_filter -o $outfile2 - ${data_dir}/ccsds.grib2
|
||||||
grib_check_key_equals $outfile2 referenceValue,bitsPerValue '6 0'
|
grib_check_key_equals $outfile2 referenceValue,bitsPerValue '6 0'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue