Skip to content

Commit 3d5e8c9

Browse files
Fix multiple bugs for encoding of BrightnessTemperature
1 parent ee28c42 commit 3d5e8c9

9 files changed

Lines changed: 67 additions & 61 deletions

File tree

src/metkit/mars2grib/backend/concepts/analysis/analysisEncoding.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void AnalysisOp(const MarsDict_t& mars, const ParDict_t& par, const OptDict_t& o
150150
MARS2GRIB_LOG_CONCEPT(analysis);
151151

152152
// Structural validation
153-
validation::match_LocalDefinitionNumber_or_throw(opt, out, {36L, 38L, 39L});
153+
validation::match_LocalDefinitionNumber_or_throw(opt, out, {36L, 37L, 38L, 39L});
154154

155155
// Deductions
156156
long offsetToEndOf4DvarWindowVal = deductions::resolve_offsetToEndOf4DvarWindow_or_throw(mars, par, opt);

src/metkit/mars2grib/backend/concepts/derived/derivedEncoding.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@
5151
#include "metkit/mars2grib/utils/generalUtils.h"
5252

5353
// Deductions
54+
#include "metkit/mars2grib/backend/deductions/channel.h"
5455
#include "metkit/mars2grib/backend/deductions/derivedForecast.h"
5556
#include "metkit/mars2grib/backend/deductions/numberOfForecastsInEnsemble.h"
57+
#include "metkit/mars2grib/backend/deductions/numberOfFrequencies.h"
5658

5759
// Tables
5860
#include "metkit/mars2grib/backend/tables/derivedForecast.h"
@@ -96,7 +98,7 @@ namespace metkit::mars2grib::backend::concepts_ {
9698
///
9799
template <std::size_t Stage, std::size_t Section, DerivedType Variant>
98100
constexpr bool derivedApplicable() {
99-
return (Stage == StagePreset) && (Section == SecProductDefinitionSection);
101+
return (Stage == StagePreset) && ((Section == SecProductDefinitionSection) || (Section == SecLocalUseSection));
100102
}
101103

102104
///
@@ -158,16 +160,35 @@ void DerivedOp(const MarsDict_t& mars, const ParDict_t& par, const OptDict_t& op
158160

159161
MARS2GRIB_LOG_CONCEPT(derived);
160162

161-
// Structural validation
162-
validation::check_DerivedProductDefinitionSection_or_throw(opt, out);
163+
if constexpr (Section == SecLocalUseSection && Stage == StagePreset &&
164+
Variant == DerivedType::BrightnessTemperature) {
163165

164-
// Deductions
165-
tables::DerivedForecast derivedForecast = deductions::resolve_DerivedForecast_or_throw(mars, par, opt);
166-
long numberOfForecastsInEnsemble = deductions::resolve_NumberOfForecastsInEnsemble_or_throw(mars, par, opt);
166+
// Check/Validation
167+
validation::match_LocalDefinitionNumber_or_throw(opt, out, {37});
167168

168-
// Encoding
169-
set_or_throw<long>(out, "derivedForecast", static_cast<long>(derivedForecast));
170-
set_or_throw<long>(out, "numberOfForecastsInEnsemble", numberOfForecastsInEnsemble);
169+
// Deductions
170+
long channelNumber = deductions::resolve_Channel_or_throw(mars, par, opt);
171+
long numberOfFrequencies = deductions::resolve_NumberOfFrequencies_or_throw(mars, par, opt);
172+
173+
// Encoding
174+
set_or_throw<long>(out, "channelNumber", channelNumber);
175+
set_or_throw<long>(out, "numberOfFrequencies", numberOfFrequencies);
176+
}
177+
178+
if constexpr (Section == SecProductDefinitionSection && Stage == StagePreset &&
179+
Variant != DerivedType::BrightnessTemperature) {
180+
// Structural validation
181+
validation::check_DerivedProductDefinitionSection_or_throw(opt, out);
182+
183+
// Deductions
184+
tables::DerivedForecast derivedForecast = deductions::resolve_DerivedForecast_or_throw(mars, par, opt);
185+
long numberOfForecastsInEnsemble =
186+
deductions::resolve_NumberOfForecastsInEnsemble_or_throw(mars, par, opt);
187+
188+
// Encoding
189+
set_or_throw<long>(out, "derivedForecast", static_cast<long>(derivedForecast));
190+
set_or_throw<long>(out, "numberOfForecastsInEnsemble", numberOfForecastsInEnsemble);
191+
}
171192
}
172193
catch (...) {
173194

src/metkit/mars2grib/backend/concepts/derived/derivedEnum.h

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,7 @@ inline constexpr std::string_view derivedName{"derived"};
8383
/// tables and registries.
8484
///
8585
enum class DerivedType : std::size_t {
86-
Individual = 0,
87-
Derived,
88-
PerturbedParameters,
89-
RandomPatterns,
90-
MeanUnweightedAll,
91-
MeanWeightedAll,
92-
StddevCluster,
93-
StddevClusterNorm,
94-
SpreadAll,
95-
LargeAnomalyIndex,
96-
MeanUnweightedCluster,
97-
Iqr,
98-
MinAll,
99-
MaxAll,
100-
VarianceAll,
86+
BrightnessTemperature, // Special variant for satellite brightness temperature products
10187
Default
10288
};
10389

@@ -114,11 +100,7 @@ enum class DerivedType : std::size_t {
114100
/// The order of this list must match the intended iteration order
115101
/// for registry construction and diagnostics.
116102
///
117-
using DerivedList = ValueList<DerivedType::Individual, DerivedType::Derived, DerivedType::PerturbedParameters,
118-
DerivedType::RandomPatterns, DerivedType::MeanUnweightedAll, DerivedType::MeanWeightedAll,
119-
DerivedType::StddevCluster, DerivedType::StddevClusterNorm, DerivedType::SpreadAll,
120-
DerivedType::LargeAnomalyIndex, DerivedType::MeanUnweightedCluster, DerivedType::Iqr,
121-
DerivedType::MinAll, DerivedType::MaxAll, DerivedType::VarianceAll, DerivedType::Default>;
103+
using DerivedList = ValueList<DerivedType::BrightnessTemperature, DerivedType::Default>;
122104

123105

124106
///
@@ -148,21 +130,7 @@ constexpr std::string_view derivedTypeName();
148130
return NAME; \
149131
}
150132

151-
DEF(DerivedType::Individual, "individual");
152-
DEF(DerivedType::Derived, "derived");
153-
DEF(DerivedType::PerturbedParameters, "perturbedParameters");
154-
DEF(DerivedType::RandomPatterns, "randomPatterns");
155-
DEF(DerivedType::MeanUnweightedAll, "meanUnweightedAll");
156-
DEF(DerivedType::MeanWeightedAll, "meanWeightedAll");
157-
DEF(DerivedType::StddevCluster, "stddevCluster");
158-
DEF(DerivedType::StddevClusterNorm, "stddevClusterNorm");
159-
DEF(DerivedType::SpreadAll, "spreadAll");
160-
DEF(DerivedType::LargeAnomalyIndex, "largeAnomalyIndex");
161-
DEF(DerivedType::MeanUnweightedCluster, "meanUnweightedCluster");
162-
DEF(DerivedType::Iqr, "iqr");
163-
DEF(DerivedType::MinAll, "minAll");
164-
DEF(DerivedType::MaxAll, "maxAll");
165-
DEF(DerivedType::VarianceAll, "varianceAll");
133+
DEF(DerivedType::BrightnessTemperature, "brightnessTemperature");
166134
DEF(DerivedType::Default, "default");
167135

168136
#undef DEF

src/metkit/mars2grib/backend/concepts/derived/derivedMatcher.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ namespace metkit::mars2grib::backend::concepts_ {
1313

1414
template <class MarsDict_t, class OptDict_t>
1515
std::size_t derivedMatcher(const MarsDict_t& mars, const OptDict_t& opt) {
16+
1617
using metkit::mars2grib::utils::dict_traits::get_or_throw;
18+
using metkit::mars2grib::utils::dict_traits::has;
1719

1820
const auto& type = get_or_throw<std::string>(mars, "type");
1921
if (type == "em" || // Ensemble mean
@@ -27,6 +29,11 @@ std::size_t derivedMatcher(const MarsDict_t& mars, const OptDict_t& opt) {
2729
return static_cast<std::size_t>(DerivedType::Default);
2830
}
2931

32+
if (has(mars, "channel") && has(mars, "param") && get_or_throw<long>(mars, "param") == 194 && has(mars, "stream") &&
33+
get_or_throw<std::string>(mars, "stream") == "elda") {
34+
return static_cast<std::size_t>(DerivedType::BrightnessTemperature);
35+
}
36+
3037
return compile_time_registry_engine::MISSING;
3138
}
3239

src/metkit/mars2grib/backend/concepts/level/levelMatcher.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ inline std::size_t matchSFC(const long param) {
3333
if (matchAny(param, 262118)) {
3434
return static_cast<std::size_t>(LevelType::DepthBelowSeaLayer);
3535
}
36-
if (matchAny(param, 59, 78, 79, 136, 137, 164, 206, range(162059, 162063), 162071, 162072, 162093, 228001, 228044,
37-
228050, 228052, range(228088, 228090), 228164, 235087, 235088, 235136, 235137, 235287, 235288, 235290,
38-
235326, 235383, 237087, 237088, 237137, 237287, 237288, 237290, 237326, 238087, 238088, 238137, 238287,
39-
238288, 238290, 238326, 239087, 239088, 239137, 239287, 239288, 239290, 239326, 260132)) {
36+
if (matchAny(param, 59, 78, 79, 136, 137, 164, 194, 206, range(162059, 162063), 162071, 162072, 162093, 228001,
37+
228044, 228050, 228052, range(228088, 228090), 228164, 235087, 235088, 235136, 235137, 235287, 235288,
38+
235290, 235326, 235383, 237087, 237088, 237137, 237287, 237288, 237290, 237326, 238087, 238088, 238137,
39+
238287, 238288, 238290, 238326, 239087, 239088, 239137, 239287, 239288, 239290, 239326, 260132)) {
4040
return static_cast<std::size_t>(LevelType::EntireAtmosphere);
4141
}
4242
if (matchAny(param, 228007, 228011)) {
@@ -126,11 +126,6 @@ inline std::size_t matchSFC(const long param) {
126126
return static_cast<std::size_t>(LevelType::Tropopause);
127127
}
128128

129-
// Satellite
130-
if (matchAny(param, 194)) {
131-
return static_cast<std::size_t>(LevelType::Surface);
132-
}
133-
134129
// Chemical
135130
if (matchAny(param, range(228080, 228085), range(233032, 233035), range(235062, 235064))) {
136131
return static_cast<std::size_t>(LevelType::Surface);

src/metkit/mars2grib/backend/concepts/satellite/satelliteMatcher.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ std::size_t satelliteMatcher(const MarsDict_t& mars, const OptDict_t& opt) {
1515
using metkit::mars2grib::utils::dict_traits::get_or_throw;
1616
using metkit::mars2grib::utils::dict_traits::has;
1717

18-
if (has(mars, "channel") && has(mars, "ident") && has(mars, "instrument")) {
19-
if (has(mars, "param") && get_or_throw<long>(mars, "param") == 194) {
20-
return static_cast<std::size_t>(SatelliteType::BrightnessTemperature);
21-
}
18+
// BrightnessTemperature (paramId=194): only requires channel.
19+
// Section 2 (local def 37) encodes channelNumber + numberOfFrequencies.
20+
// Section 4 satellite band metadata (ident, instrument, series, waveNumber)
21+
// is only present for PDT 32/33 — the encoding handles this conditionally.
22+
if (has(mars, "channel") && has(mars, "param") && get_or_throw<long>(mars, "param") == 194 && has(mars, "stream") &&
23+
get_or_throw<std::string>(mars, "stream") == "oper") {
24+
return static_cast<std::size_t>(SatelliteType::BrightnessTemperature);
25+
}
2226

27+
// Default satellite: requires full satellite identification keys
28+
if (has(mars, "channel") && has(mars, "ident") && has(mars, "instrument")) {
2329
return static_cast<std::size_t>(SatelliteType::Default);
2430
}
2531

src/metkit/mars2grib/backend/deductions/derivedForecast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ tables::DerivedForecast resolve_DerivedForecast_or_throw(const MarsDict_t& mars,
146146
if (marsType == "em" || marsType == "taem") {
147147
derivedForecast = tables::DerivedForecast::UnweightedMeanAllMembers;
148148
}
149-
else if (marsType == "es" || marsType == "taes") {
149+
else if (marsType == "es" || marsType == "ses" || marsType == "taes") {
150150
derivedForecast = tables::DerivedForecast::SpreadAllMembers;
151151
}
152152
else {

src/metkit/mars2grib/backend/sections/initializers/sectionRegistry.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ inline constexpr Entry<MarsDict_t, ParDict_t, OptDict_t, OutDict_t> Sec2Reg[] =
8181
{24, &allocateTemplateNumber2<2, 24, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
8282
{25, &allocateTemplateNumber2<2, 25, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
8383
{36, &allocateTemplateNumber2<2, 36, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
84+
{37, &allocateTemplateNumber2<2, 37, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
8485
{38, &allocateTemplateNumber2<2, 38, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
8586
{39, &allocateTemplateNumber2<2, 39, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},
8687
{1000, &allocateTemplateNumber2<2, 1000, MarsDict_t, ParDict_t, OptDict_t, OutDict_t>},

src/metkit/mars2grib/frontend/resolution/section-recipes/impl/section2Recipes.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,20 @@ inline const Recipe S2_R36 =
6161
>();
6262

6363
// Brightness temperature satellite products
64-
inline const Recipe S2_R37 =
64+
inline const Recipe S2_R37A =
6565
make_recipe<37,
6666
Select<MarsConcept>,
6767
Select<AnalysisConcept>,
6868
Select<SatelliteConcept, SatelliteType::BrightnessTemperature>
6969
>();
7070

71+
inline const Recipe S2_R37B =
72+
make_recipe<37,
73+
Select<MarsConcept>,
74+
Select<AnalysisConcept>,
75+
Select<DerivedConcept, DerivedType::BrightnessTemperature>
76+
>();
77+
7178
// 4i Analysis-related products
7279
inline const Recipe S2_R38 =
7380
make_recipe<38,
@@ -121,7 +128,8 @@ inline const Recipes Section2Recipes{ 2,
121128
&S2_R24,
122129
&S2_R25,
123130
&S2_R36,
124-
&S2_R37,
131+
&S2_R37A,
132+
&S2_R37B,
125133
&S2_R38,
126134
&S2_R39,
127135
&S2_R1001,

0 commit comments

Comments
 (0)