Skip to content

Commit e1239f0

Browse files
committed
Call GRIB2 encoder in metkit from encode-mtg2 action
1 parent 2379df8 commit e1239f0

File tree

2 files changed

+77
-98
lines changed

2 files changed

+77
-98
lines changed

src/multio/action/encode-mtg2/EncodeMtg2.cc

Lines changed: 72 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,34 @@
1111
#include "EncodeMtg2.h"
1212

1313
#include <iostream>
14-
#include <type_traits>
1514

15+
#include "eckit/config/LocalConfiguration.h"
1616
#include "eckit/exception/Exceptions.h"
1717

1818
#include "multio/action/encode-mtg2/AtlasGeoSetter.h"
1919
#include "multio/action/encode-mtg2/EncodeMtg2Exception.h"
2020
#include "multio/datamod/MarsMiscGeo.h"
21+
#include "multio/datamod/core/EntryDumper.h"
2122
#include "multio/datamod/core/EntryParser.h"
2223
#include "multio/datamod/core/Record.h"
23-
#include "multio/mars2grib/api/RawAPI.h"
2424
#include "multio/mars2mars/Rules.h"
2525
#include "multio/message/Parametrization.h"
2626
#include "multio/util/PrecisionTag.h"
2727

28-
namespace multio::action {
28+
namespace multio::action::encode_mtg2 {
2929

3030
namespace dm = multio::datamod;
3131

3232
using message::Message;
3333
using message::Peer;
3434

35-
mars2grib::RawOptions mapOpts(EncodeMtg2Options opts) {
36-
mars2grib::RawOptions ret;
37-
ret.cached = opts.cached;
38-
return ret;
39-
};
40-
4135

4236
EncodeMtg2::EncodeMtg2(const ComponentConfiguration& compConf) :
43-
ChainedAction{compConf}, opts_{cf::parseActionConfig<EncodeMtg2Options>(compConf)}, mars2grib_{mapOpts(opts_)} {}
37+
ChainedAction{compConf}, opts_{cf::parseActionConfig<EncodeMtg2Options>(compConf)}, encoder_{} {
38+
if (opts_.cached) {
39+
throw eckit::NotImplemented{"Encoder cache is currently not implemented!", Here()};
40+
}
41+
}
4442

4543

4644
void EncodeMtg2::executeImpl(Message msg) {
@@ -49,94 +47,76 @@ void EncodeMtg2::executeImpl(Message msg) {
4947
return;
5048
}
5149

50+
if (msg.payload().size() == 0) {
51+
throw EncodeMtg2Exception("Message has empty payload - no values to encode", Here());
52+
}
53+
5254
auto& md = msg.metadata();
5355

54-
{
55-
// Read and set unscoped mars keys
56-
auto marsRec = dm::readRecord<dm::FullMarsRecord>(md);
57-
58-
// Read scoped misc keys
59-
auto scopedMiscRec = dm::scopeRecord(dm::MiscRecord{});
60-
dm::readRecord(scopedMiscRec, md);
61-
// Write unscoped misc keys
62-
auto miscRec = dm::unscopeRecord(std::move(scopedMiscRec));
63-
64-
auto scopedGeo = dm::getGeometryRecord(marsRec);
65-
66-
// If grid.. check if atlas is given.
67-
if (marsRec.grid.isSet()) {
68-
std::string scope{std::visit([](const auto& k) { return dm::getRecordScope(k); }, scopedGeo)};
69-
const auto& global = message::Parametrization::instance().get();
70-
// Fetch atlas and store in global parametrization (by scoping keys...)
71-
// Scoping here may be refactored
72-
if (opts_.geoFromAtlas && (global.find(scope) == global.end())) {
73-
extract::AtlasGeoSetter::handleGrid(scope, marsRec.grid.get());
74-
}
56+
// Read and set unscoped mars keys
57+
auto marsRec = dm::readRecord<dm::FullMarsRecord>(md);
58+
59+
// Read scoped misc keys
60+
auto scopedMiscRec = dm::scopeRecord(dm::MiscRecord{});
61+
dm::readRecord(scopedMiscRec, md);
62+
// Write unscoped misc keys
63+
auto miscRec = dm::unscopeRecord(std::move(scopedMiscRec));
64+
65+
auto scopedGeom = dm::getGeometryRecord(marsRec);
66+
67+
// If grid.. check if atlas is given.
68+
if (marsRec.grid.isSet()) {
69+
std::string scope{std::visit([](const auto& k) { return dm::getRecordScope(k); }, scopedGeom)};
70+
const auto& global = message::Parametrization::instance().get();
71+
// Fetch atlas and store in global parametrization (by scoping keys...)
72+
// Scoping here may be refactored
73+
if (opts_.geoFromAtlas && (global.find(scope) == global.end())) {
74+
extract::AtlasGeoSetter::handleGrid(scope, marsRec.grid.get());
7575
}
76+
}
7677

77-
// Read & unscope geo keys from metadata
78-
auto geo = std::visit(
79-
[&](auto&& geoRec) -> dm::Geometry {
80-
dm::readRecord(geoRec, md);
81-
return unscopeRecord(std::move(geoRec));
82-
},
83-
std::move(scopedGeo));
84-
85-
86-
// Apply mappings
87-
auto mappingResult = mars2mars::applyMappings(mars2mars::allRules(), marsRec, miscRec);
88-
78+
// Read & unscope geo keys from metadata
79+
auto geomRec = std::visit(
80+
[&](auto&& scopedGeom) -> dm::Geometry {
81+
dm::readRecord(scopedGeom, md);
82+
return unscopeRecord(std::move(scopedGeom));
83+
},
84+
std::move(scopedGeom));
85+
86+
// Apply mappings
87+
auto mappingResult = mars2mars::applyMappings(mars2mars::allRules(), marsRec, miscRec);
88+
89+
const auto mars = dm::dumpRecord<eckit::LocalConfiguration>(marsRec);
90+
const auto misc = dm::dumpRecord<eckit::LocalConfiguration>(miscRec);
91+
const auto geom
92+
= std::visit([](const auto& geomRec) { return dm::dumpRecord<eckit::LocalConfiguration>(geomRec); }, geomRec);
93+
94+
executeNext(dispatchPrecisionTag(msg.precision(), [&](auto pt) {
95+
using Precision = typename decltype(pt)::type;
96+
auto values = static_cast<Precision*>(msg.payload().modifyData());
97+
size_t size = msg.payload().size() / sizeof(Precision);
98+
99+
// Check if values need scaling
100+
if (mappingResult && mappingResult->valuesScaleFactor) {
101+
msg.payload().acquire();
102+
ASSERT(values);
103+
104+
const auto scaleFactor = *(mappingResult->valuesScaleFactor);
105+
std::transform(values, values + size, values,
106+
[&](const Precision& value) -> Precision { return value * scaleFactor; });
107+
}
89108

90-
std::unique_ptr<metkit::codes::CodesHandle> sample = mars2grib_.getHandle(marsRec, miscRec, geo);
109+
// Call the GRIB2 encoder in metkit
110+
const auto sample = encoder_.encode(mars, misc, geom, values, size);
91111

92-
if (msg.payload().size() == 0) {
93-
throw EncodeMtg2Exception("Message has empty payload - no values to encode", Here());
94-
}
112+
eckit::Buffer buf{sample->messageSize()};
113+
sample->copyInto(reinterpret_cast<uint8_t*>(buf.data()), buf.size());
95114

96-
// ecCodes does not support setting float values (yet)
97-
auto setValuesAsDouble = [&] (const auto* data, size_t size) {
98-
using Precision = std::decay_t<decltype(*data)>;
99-
if constexpr (std::is_same_v<Precision, double>) {
100-
sample->set("values", metkit::codes::Span<const Precision>(data, size));
101-
}
102-
else {
103-
sample->set("values", std::vector<double>{data, data+size});
104-
}
105-
};
106-
107-
executeNext(dispatchPrecisionTag(msg.precision(), [&](auto pt) {
108-
using Precision = typename decltype(pt)::type;
109-
size_t size = msg.payload().size() / sizeof(Precision);
110-
111-
// Check if values need scaling
112-
if (mappingResult && mappingResult->valuesScaleFactor) {
113-
msg.payload().acquire();
114-
auto values = static_cast<Precision*>(msg.payload().modifyData());
115-
ASSERT(values);
116-
117-
const auto scaleFactor = *(mappingResult->valuesScaleFactor);
118-
std::transform(values, values + size, values,
119-
[&](const Precision& value) -> Precision { return value * scaleFactor; });
120-
121-
setValuesAsDouble(values, size);
122-
}
123-
else {
124-
// No scaling
125-
auto values = static_cast<const Precision*>(msg.payload().data());
126-
setValuesAsDouble(values, size);
127-
}
128-
129-
// The +32 is related to bug
130-
// TODO(pgeier) Track bug ECC-2130: https://jira.ecmwf.int/browse/ECC-2130
131-
eckit::Buffer buf{sample->messageSize()};
132-
sample->copyInto(reinterpret_cast<uint8_t*>(buf.data()), buf.size());
133-
134-
// TODO(pgeier) write mapped metadata
135-
return Message{Message::Header{Message::Tag::Field, Peer{msg.source()}, Peer{msg.destination()},
136-
dm::dumpRecord<message::Metadata>(marsRec)},
137-
std::move(buf)};
138-
}));
139-
}
115+
// TODO(pgeier) write mapped metadata
116+
return Message{Message::Header{Message::Tag::Field, Peer{msg.source()}, Peer{msg.destination()},
117+
dm::dumpRecord<message::Metadata>(marsRec)},
118+
std::move(buf)};
119+
}));
140120
}
141121

142122
void EncodeMtg2::print(std::ostream& os) const {
@@ -146,4 +126,4 @@ void EncodeMtg2::print(std::ostream& os) const {
146126

147127
static ActionBuilder<EncodeMtg2> EncodeMtg2Builder("encode-mtg2");
148128

149-
} // namespace multio::action
129+
} // namespace multio::action::encode_mtg2

src/multio/action/encode-mtg2/EncodeMtg2.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010

1111
#pragma once
1212

13-
13+
#include "metkit/mars2grib/api/Grib2Encoder.h"
1414
#include "multio/action/ChainedAction.h"
15-
#include "multio/mars2grib/api/RawAPI.h"
1615
#include "multio/util/config/Parser.h"
1716

1817

19-
namespace multio::action {
18+
namespace multio::action::encode_mtg2 {
2019

2120
namespace cf = multio::util::config;
2221

2322
//----------------------------------------------------------------------------------------------------------------------
2423

2524
struct EncodeMtg2Options {
26-
bool cached = true;
25+
bool cached = false;
2726
bool geoFromAtlas = false;
2827

2928
static constexpr auto fields_
@@ -48,11 +47,11 @@ class EncodeMtg2 : public ChainedAction {
4847

4948
// TODO pgeier this option will be renamed and the action should get it own struct with parsing capabilities again
5049
EncodeMtg2Options opts_;
51-
mars2grib::Mars2GribRaw mars2grib_;
50+
metkit::mars2grib::Grib2Encoder encoder_;
5251
};
5352

5453

5554
//----------------------------------------------------------------------------------------------------------------------
5655

5756

58-
} // namespace multio::action
57+
} // namespace multio::action::encode_mtg2

0 commit comments

Comments
 (0)