Skip to content

Regression fixes for MTG2 conversion and encoding logic#238

Open
tweska wants to merge 18 commits into
developfrom
fix/grib2mars
Open

Regression fixes for MTG2 conversion and encoding logic#238
tweska wants to merge 18 commits into
developfrom
fix/grib2mars

Conversation

@tweska

@tweska tweska commented Jul 22, 2026

Copy link
Copy Markdown
Member

This PR is contains various fixes for MTG2 conversion and encoding related logic.

📋 Metkit Documentation 📋
https://sites.ecmwf.int/docs/metkit/pull-requests/PR-238

@codecov-commenter

codecov-commenter commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 20.33898% with 141 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.29%. Comparing base (7db08f8) to head (21b3abd).

Files with missing lines Patch % Lines
src/tools/grib1-to-grib2.cc 0.00% 26 Missing ⚠️
src/metkit/grib2mars/mappings/rules/misc.h 0.00% 24 Missing ⚠️
src/metkit/mars2mars/mappings/rules/incremental.h 12.50% 21 Missing ⚠️
src/metkit/grib2mars/mappings/rules/coeffindex.h 0.00% 11 Missing ⚠️
src/metkit/grib2mars/mappings/rules/iteration.h 0.00% 11 Missing ⚠️
.../backend/concepts/model-error/modelErrorEncoding.h 0.00% 11 Missing ⚠️
src/metkit/mars2grib/backend/encodeValues.h 16.66% 10 Missing ⚠️
...2grib/backend/deductions/fourierCoefficientIndex.h 0.00% 7 Missing ⚠️
...b/backend/deductions/numberOfFourierCoefficients.h 0.00% 7 Missing ⚠️
src/metkit/grib2mars/mappings/rules/number.h 0.00% 4 Missing ⚠️
... and 6 more
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #238      +/-   ##
===========================================
- Coverage    50.51%   50.29%   -0.22%     
===========================================
  Files          385      391       +6     
  Lines        15438    15593     +155     
  Branches      1307     1331      +24     
===========================================
+ Hits          7798     7842      +44     
- Misses        7640     7751     +111     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets regressions in the GRIB1→GRIB2 pipeline by adjusting mars2mars mappings, extending mars2grib model-error support (including Fourier-coefficient products), and refining grib2mars extraction/misc metadata handling.

Changes:

  • Extend mars2mars mapping rules (incremental + miscellaneous parameter conversions) and fix a couple of mapping edge cases.
  • Add mars2grib support for model-error Fourier-coefficient products (template 45) with new deductions and section registration.
  • Refine grib2mars extraction and misc handling (boolean/float misc values, new extractors for coeffindex/iteration, ensemble/model-error metadata).

mars2grib documentation sync (per repo guideline 1000000)

Impacted files under src/metkit/mars2grib/**:

  • src/metkit/mars2grib/frontend/resolution/section-recipes/impl/section2Recipes.h
  • src/metkit/mars2grib/backend/sections/initializers/sectionRegistry.h
  • src/metkit/mars2grib/backend/deductions/numberOfFourierCoefficients.h (new)
  • src/metkit/mars2grib/backend/deductions/fourierCoefficientIndex.h (new)
  • src/metkit/mars2grib/backend/deductions/level.h
  • src/metkit/mars2grib/backend/concepts/model-error/modelErrorMatcher.h
  • src/metkit/mars2grib/backend/concepts/model-error/modelErrorEncoding.h
  • src/metkit/mars2grib/backend/concepts/level/levelMatcher.h
  • src/metkit/mars2grib/backend/concepts/level/levelEncoding.h

Documentation status: ❌ outdated
The mars2grib Doxygen input list (src/metkit/mars2grib/docs/doxygen/mars2grib.config.in) enumerates deduction headers explicitly but does not include the newly added Fourier-coefficient deduction headers, so generated documentation will likely omit them.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/tools/grib1-to-grib2.cc Preserve boolean misc/config values during LocalConfiguration merges.
src/metkit/mars2mars/mappings/rules/windspeed.h Adjust levtype comparison to lowercase sfc.
src/metkit/mars2mars/mappings/rules/misc-params.h Add misc parameter conversions (incl. offset handling).
src/metkit/mars2mars/mappings/rules/local2wmo.h Fix a param mapping used for local→WMO conversion.
src/metkit/mars2mars/mappings/rules/incremental.h Add incremental-field parameter conversions.
src/metkit/mars2mars/mappings/mappings.h Wire new mars2mars rules into the conversion pipeline.
src/metkit/mars2grib/frontend/resolution/section-recipes/impl/section2Recipes.h Add recipe for model-error Fourier coefficients (template 45) and refine model-error selection.
src/metkit/mars2grib/backend/sections/initializers/sectionRegistry.h Register template 45 in section 2 template registry.
src/metkit/mars2grib/backend/deductions/numberOfFourierCoefficients.h New deduction to read total Fourier coefficient count from parameter dictionary.
src/metkit/mars2grib/backend/deductions/level.h Default level=0 for levtype=sfc when levelist is absent.
src/metkit/mars2grib/backend/deductions/fourierCoefficientIndex.h New deduction to read Fourier coefficient index from MARS dictionary.
src/metkit/mars2grib/backend/concepts/model-error/modelErrorMatcher.h Prefer Fourier-coefficient variant when coeffindex is present.
src/metkit/mars2grib/backend/concepts/model-error/modelErrorEncoding.h Implement encoding for Fourier-coefficient model-error variant (template 45).
src/metkit/mars2grib/backend/concepts/level/levelMatcher.h Add note clarifying assumptions for certain ocean params.
src/metkit/mars2grib/backend/concepts/level/levelEncoding.h Adjust which level types require a numeric level during encoding.
src/metkit/grib2mars/mappings/rules/truncation.h Read laplacianOperator as double into misc.
src/metkit/grib2mars/mappings/rules/step.h Default initialStep and timeIncrementInSeconds when missing.
src/metkit/grib2mars/mappings/rules/packing.h Store bitmapPresent as bool in misc.
src/metkit/grib2mars/mappings/rules/number.h Simplify number extraction to direct key read/write.
src/metkit/grib2mars/mappings/rules/misc.h Extract additional misc metadata (typeOfProcessedData, model-error + ensemble metadata).
src/metkit/grib2mars/mappings/rules/iteration.h New extractor for iteration + total number of iterations.
src/metkit/grib2mars/mappings/rules/extract.h Register new extractors (iteration, coeffindex).
src/metkit/grib2mars/mappings/rules/coeffindex.h New extractor for coeffindex + numberOfFourierCoefficients into misc.

Comment on lines 17 to 25
try {
if (!grib.has("type")) {
if (!grib.has(keyword)) {
throw Grib2MarsGenericException(
"Missing GRIB key `type` required to extract MARS keyword `" + keyword + "`", Here());
"Missing GRIB key `" + keyword + "` required to extract MARS keyword `" + keyword + "`", Here());
}

const std::string type = grib.getString("type");

if (type == "es" || type == "em") {
if (!grib.has("numberOfForecastsInEnsemble")) {
throw Grib2MarsGenericException(
"Missing GRIB key `numberOfForecastsInEnsemble` required "
"for derived ensemble forecast",
Here());
}

const long numberOfForecastsInEnsemble = grib.getLong("numberOfForecastsInEnsemble");

misc.set("numberOfForecastsInEnsemble", numberOfForecastsInEnsemble);

return;
}

if (!grib.has("number") || !grib.has("numberOfForecastsInEnsemble")) {
return;
}

const long number = grib.getLong("number");
const long numberOfForecastsInEnsemble = grib.getLong("numberOfForecastsInEnsemble");

if (number != 0 && numberOfForecastsInEnsemble == 0) {
throw Grib2MarsGenericException("The value for key `numberOfForecastsInEnsemble` must not be 0", Here());
}

if (numberOfForecastsInEnsemble == 0) {
return;
}

set_or_throw<long>(mars, keyword, number);

misc.set("numberOfForecastsInEnsemble", numberOfForecastsInEnsemble);

if (grib.has("class")) {
const std::string klass = grib.getString("class");

if (klass == "ai") {
// Handled in the encoder, matching the original tool logic.
return;
}
}

if (grib.has("typeOfEnsembleForecast")) {
const long typeOfEnsembleForecast = grib.getLong("typeOfEnsembleForecast");

misc.set("typeOfEnsembleForecast", typeOfEnsembleForecast);

return;
}

if (grib.has("eps")) {
const long eps = grib.getLong("eps");

misc.set("typeOfEnsembleForecast", eps);
}
const long value = grib.getLong(keyword);
set_or_throw<long>(mars, keyword, value);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that number must already be in the MARS namespace before this extractor is triggered.

Comment thread src/metkit/grib2mars/mappings/rules/misc.h
Comment thread src/metkit/mars2mars/mappings/rules/incremental.h Outdated
Comment thread src/metkit/mars2grib/backend/deductions/numberOfFourierCoefficients.h Outdated
Comment thread src/metkit/mars2grib/backend/deductions/fourierCoefficientIndex.h Outdated
Comment thread src/metkit/grib2mars/mappings/rules/misc.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants