From a7435950e357ddc33e5872697971cb11d10baf42 Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Wed, 21 Feb 2024 13:28:38 +0000 Subject: [PATCH] METK-120 lowercase metadata --- VERSION | 2 +- share/metkit/language.yaml | 8 +-- src/metkit/CMakeLists.txt | 2 + src/metkit/mars/TypeLowercase.cc | 44 +++++++++++++++ src/metkit/mars/TypeLowercase.h | 40 ++++++++++++++ tests/test_expand.cc | 93 ++++++++++++++++---------------- tests/test_typesfactory.cc | 2 +- 7 files changed, 139 insertions(+), 52 deletions(-) create mode 100644 src/metkit/mars/TypeLowercase.cc create mode 100644 src/metkit/mars/TypeLowercase.h diff --git a/VERSION b/VERSION index e6dbb7c2..6b37cb71 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.11.5 +1.11.6 diff --git a/share/metkit/language.yaml b/share/metkit/language.yaml index f764ee5a..ccbf260c 100644 --- a/share/metkit/language.yaml +++ b/share/metkit/language.yaml @@ -316,7 +316,7 @@ _field: &_field model: category: data - type: any + type: lowercase repres: flatten: false @@ -729,11 +729,11 @@ _field: &_field activity: category: data - type: any + type: lowercase experiment: category: data - type: any + type: lowercase generation: category: data @@ -745,7 +745,7 @@ _field: &_field resolution: category: data - type: any + type: lowercase ####################################################################### diff --git a/src/metkit/CMakeLists.txt b/src/metkit/CMakeLists.txt index c798ac6a..49a3426b 100644 --- a/src/metkit/CMakeLists.txt +++ b/src/metkit/CMakeLists.txt @@ -69,6 +69,8 @@ list( APPEND metkit_srcs mars/TypeFloat.h mars/TypeInteger.cc mars/TypeInteger.h + mars/TypeLowercase.cc + mars/TypeLowercase.h mars/TypeMixed.cc mars/TypeMixed.h mars/TypeParam.cc diff --git a/src/metkit/mars/TypeLowercase.cc b/src/metkit/mars/TypeLowercase.cc new file mode 100644 index 00000000..7a3a34a2 --- /dev/null +++ b/src/metkit/mars/TypeLowercase.cc @@ -0,0 +1,44 @@ +/* + * (C) Copyright 1996- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation nor + * does it submit to any jurisdiction. + */ + + +#include "metkit/mars/TypesFactory.h" +#include "metkit/mars/TypeLowercase.h" + +#include +#include +#include + +namespace metkit::mars { + +//---------------------------------------------------------------------------------------------------------------------- + +TypeLowercase::TypeLowercase(const std::string &name, const eckit::Value& settings) : + Type(name, settings) { +} + +TypeLowercase::~TypeLowercase() { +} + +void TypeLowercase::print(std::ostream &out) const { + out << "TypeLowercase[name=" << name_ << "]"; +} + +bool TypeLowercase::expand(const MarsExpandContext& ctx, std::string &value) const { + + std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c){ return std::tolower(c); }); + return true; +} + + +static TypeBuilder type("lowercase"); + +//---------------------------------------------------------------------------------------------------------------------- +} // namespace metkit::mars diff --git a/src/metkit/mars/TypeLowercase.h b/src/metkit/mars/TypeLowercase.h new file mode 100644 index 00000000..e75be14a --- /dev/null +++ b/src/metkit/mars/TypeLowercase.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 1996- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation nor + * does it submit to any jurisdiction. + */ + +/// @file TypeLowercase.h +/// @author Emanuele Danovaro +/// @date February 2024 + +#pragma once + +#include "metkit/mars/Type.h" + +namespace metkit::mars { + +//---------------------------------------------------------------------------------------------------------------------- + +class TypeLowercase : public Type { + +public: // methods + + TypeLowercase(const std::string &name, const eckit::Value& settings = eckit::Value()); + + virtual ~TypeLowercase() override; + +private: // methods + + virtual void print(std::ostream &out) const override; + virtual bool expand(const MarsExpandContext& ctx, std::string &value) const override; + +}; + +//---------------------------------------------------------------------------------------------------------------------- +} // namespace metkit::mars + diff --git a/tests/test_expand.cc b/tests/test_expand.cc index 5e4ce59e..3a6b988b 100644 --- a/tests/test_expand.cc +++ b/tests/test_expand.cc @@ -131,21 +131,31 @@ CASE( "test_metkit_expand_10_strict" ) { } } -void quantileThrows(std::vector values) { + +void expandKeyThrows(const std::string& key, std::vector values) { DummyContext ctx; static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("quantile"); - EXPECT_THROWS_AS(t->expand(ctx, values), eckit::BadValue); + metkit::mars::Type* t = language.type(key); + std::cout << key << "Throws " << values << std::endl; + EXPECT_THROWS(t->expand(ctx, values)); } - -void quantile(std::vector values, std::vector expected) { +void expandKey(const std::string& key, std::vector values, std::vector expected) { DummyContext ctx; static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("quantile"); + metkit::mars::Type* t = language.type(key); + std::cout << key << " " << values; t->expand(ctx, values); + std::cout << " ==> " << values << " - expected " << expected << std::endl; ASSERT(values == expected); } +void quantileThrows(std::vector values) { + expandKeyThrows("quantile", values); +} +void quantile(std::vector values, std::vector expected) { + expandKey("quantile", values, expected); +} + CASE( "test_metkit_expand_11_quantile" ) { quantileThrows({"-1:5"}); quantileThrows({"0:-5"}); @@ -178,21 +188,10 @@ CASE( "test_metkit_expand_11_quantile" ) { void timeThrows(std::vector values) { - DummyContext ctx; - static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("time"); - std::cout << "timeThrows " << values << std::endl; - EXPECT_THROWS(t->expand(ctx, values)); + expandKeyThrows("time", values); } - void time(std::vector values, std::vector expected) { - DummyContext ctx; - static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("time"); - std::cout << "time " << values; - t->expand(ctx, values); - std::cout << " ==> " << values << " - expected " << expected << std::endl; - ASSERT(values == expected); + expandKey("time", values, expected); } CASE( "test_metkit_expand_12_time" ) { @@ -228,42 +227,17 @@ CASE( "test_metkit_expand_12_time" ) { time({"1","to","6","by","6"}, {"0100"}); time({"1","to","3h","by","30m"}, {"0100", "0130", "0200", "0230", "0300"}); - - // quantile({"0:5","to","0:5"}, {"0:5"}); - // quantile({"3:3","to","3:3"}, {"3:3"}); - // quantile({"0:5","to","5:5"}, {"0:5","1:5","2:5","3:5","4:5","5:5"}); - // quantile({"0:5","to","5:5","by","1"}, {"0:5","1:5","2:5","3:5","4:5","5:5"}); - // quantile({"0:5","to","5:5","by","2"}, {"0:5","2:5","4:5"}); - // quantile({"0:5","to","5:5","by","3"}, {"0:5","3:5"}); - // quantile({"0:5","to","5:5","by","5"}, {"0:5","5:5"}); - // quantile({"0:5","to","5:5","by","6"}, {"0:5"}); - // quantile({"2:5","to","5:5","by","2"}, {"2:5","4:5"}); - // quantile({"3:5","to","5:5","by","2"}, {"3:5","5:5"}); - // quantile({"4:5","to","5:5","by","2"}, {"4:5"}); - // quantile({"0:10","3:10","to","7:10","by","2","10:10"}, {"0:10","3:10","5:10","7:10","10:10"}); } void stepThrows(std::vector values) { - DummyContext ctx; - static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("step"); - std::cout << "stepThrows " << values << std::endl; - EXPECT_THROWS(t->expand(ctx, values)); + expandKeyThrows("step", values); } - void step(std::vector values, std::vector expected) { - DummyContext ctx; - static metkit::mars::MarsLanguage language("retrieve"); - metkit::mars::Type* t = language.type("step"); - std::cout << "step " << values << " ==> "; - t->expand(ctx, values); - std::cout << values << " - expected: " << expected << std::endl; - ASSERT(values == expected); + expandKey("step", values, expected); } CASE( "test_metkit_expand_13_step" ) { -// stepThrows({"0:70"}); step({"0"}, {"0"}); step({"1"}, {"1"}); step({"24"}, {"24"}); @@ -299,6 +273,33 @@ CASE( "test_metkit_expand_13_step" ) { } + +void activity(std::vector values, std::vector expected) { + expandKey("activity", values, expected); +} +void experiment(std::vector values, std::vector expected) { + expandKey("experiment", values, expected); +} +void model(std::vector values, std::vector expected) { + expandKey("model", values, expected); +} + +CASE( "test_metkit_expand_lowercase" ) { + activity({"ScenarioMIP"}, {"scenariomip"}); + activity({"CMIP6"}, {"cmip6"}); + activity({"ScenarioMIP"}, {"scenariomip"}); + activity({"cmip6"}, {"cmip6"}); + experiment({"SSP3-7.0"}, {"ssp3-7.0"}); + experiment({"ssp3-7.0"}, {"ssp3-7.0"}); + experiment({"hist"}, {"hist"}); + model({"IFS-NEMO"}, {"ifs-nemo"}); + model({"IFS"}, {"ifs"}); + model({"ifs-nemo"}, {"ifs-nemo"}); + model({"ifs"}, {"ifs"}); + model({"ICON"}, {"icon"}); + model({"icon"}, {"icon"}); +} + //----------------------------------------------------------------------------- } // namespace test diff --git a/tests/test_typesfactory.cc b/tests/test_typesfactory.cc index bdf91e14..e88b707d 100644 --- a/tests/test_typesfactory.cc +++ b/tests/test_typesfactory.cc @@ -35,7 +35,7 @@ CASE ("test_list_types") { std::stringstream ss; TypesFactory::list(ss); std::cout << ss.str() << std::endl; - EXPECT(ss.str() == std::string("[any,date,enum,expver,float,integer,mixed,param,range,regex,time,to-by-list,to-by-list-float,to-by-list-quantile]")); + EXPECT(ss.str() == std::string("[any,date,enum,expver,float,integer,lowercase,mixed,param,range,regex,time,to-by-list,to-by-list-float,to-by-list-quantile]")); }