Skip to content

Commit

Permalink
griddef
Browse files Browse the repository at this point in the history
  • Loading branch information
pmaciel committed Nov 22, 2024
1 parent 87af8ac commit 60fc361
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 59 deletions.
4 changes: 4 additions & 0 deletions src/mir/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ list(APPEND mir_srcs
input/GribMemoryInput.h
input/GribStreamInput.cc
input/GribStreamInput.h
input/GriddefInput.cc
input/GriddefInput.h
input/MIRInput.cc
input/MIRInput.h
input/MultiDimensionalGribFileInput.cc
Expand Down Expand Up @@ -457,6 +459,8 @@ list(APPEND mir_srcs
output/GribOutput.h
output/GribStreamOutput.cc
output/GribStreamOutput.h
output/GriddefOutput.cc
output/GriddefOutput.h
output/MIROutput.cc
output/MIROutput.h
output/MultiDimensionalOutput.cc
Expand Down
106 changes: 106 additions & 0 deletions src/mir/input/GriddefInput.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* (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 "mir/input/GriddefInput.h"

#include <cctype>
#include <fstream>
#include <ostream>
#include "eckit/filesystem/PathName.h"
#include "eckit/serialisation/IfstreamStream.h"

#include "mir/data/MIRField.h"
#include "mir/repres/other/UnstructuredGrid.h"
#include "mir/util/Exceptions.h"
#include "mir/util/Log.h"


namespace mir::input {


GriddefInput::GriddefInput(const eckit::PathName& path) : calls_(0) {
load(path, latitudes_, longitudes_);
ASSERT(latitudes_.size() == longitudes_.size());
ASSERT(!latitudes_.empty());
}


void GriddefInput::load(const eckit::PathName& path, std::vector<double>& latitudes, std::vector<double>& longitudes) {
Log::info() << "GriddefInput::load '" << path << "'" << std::endl;

std::ifstream in(path.asString().c_str());
if (!in) {
throw exception::CantOpenFile(path);
}

if (std::isprint(in.peek()) == 0) {
// binary
eckit::IfstreamStream s(in);

size_t version = 0;
s >> version;
ASSERT(version == 1);

size_t count = 0;
s >> count;

latitudes.resize(count);
longitudes.resize(count);

for (size_t i = 0; i < count; ++i) {
s >> latitudes[i];
s >> longitudes[i];
}
}
else {
double lat = 0;
double lon = 0;
while (in >> lat >> lon) {
latitudes.push_back(lat);
longitudes.push_back(lon);
}
}
}


bool GriddefInput::next() {
return calls_++ == 0;
}


size_t GriddefInput::dimensions() const {
return 1;
}


const param::MIRParametrisation& GriddefInput::parametrisation(size_t which) const {
ASSERT(which == 0);
return empty_;
}


data::MIRField GriddefInput::field() const {
return {new repres::other::UnstructuredGrid{latitudes_, longitudes_}};
}


bool GriddefInput::sameAs(const MIRInput&) const {
return false;
}


void GriddefInput::print(std::ostream& out) const {
out << "GriddefInput[size=" << latitudes_.size() << "]";
}


} // namespace mir::input
56 changes: 56 additions & 0 deletions src/mir/input/GriddefInput.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* (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.
*/


#pragma once

#include <vector>

#include "mir/input/MIRInput.h"
#include "mir/param/SimpleParametrisation.h"


namespace eckit {
class PathName;
}


namespace mir::input {


class GriddefInput final : public MIRInput {
public:
GriddefInput(const eckit::PathName&);

static void load(const eckit::PathName&, std::vector<double>& latitudes, std::vector<double>& longitudes);

private:
std::vector<double> latitudes_;
std::vector<double> longitudes_;
size_t calls_;

const param::SimpleParametrisation empty_;

bool next() override;
size_t dimensions() const override;
const param::MIRParametrisation& parametrisation(size_t which = 0) const override;
data::MIRField field() const override;
bool sameAs(const MIRInput&) const override;
void print(std::ostream&) const override;

friend std::ostream& operator<<(std::ostream& s, const GriddefInput& p) {
p.print(s);
return s;
}
};


} // namespace mir::input
113 changes: 113 additions & 0 deletions src/mir/output/GriddefOutput.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* (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 "mir/output/GriddefOutput.h"

#include <memory>
#include <ostream>

#include "eckit/filesystem/PathName.h"
#include "eckit/serialisation/FileStream.h"

#include "mir/action/context/Context.h"
#include "mir/data/MIRField.h"
#include "mir/repres/Iterator.h"
#include "mir/repres/Representation.h"


namespace mir::output {


GriddefOutput::GriddefOutput(std::string path, bool binary) : path_(std::move(path)), binary_(binary) {}


void GriddefOutput::save(const eckit::PathName& path, const std::vector<double>& latitudes,
const std::vector<double>& longitudes, bool binary) {
ASSERT(latitudes.size() == longitudes.size());
const auto count = latitudes.size();

if (binary) {
eckit::FileStream s(path, "w");
s << 1; // version
s << count;

for (size_t i = 0; i < count; ++i) {
s << latitudes[i];
s << longitudes[i];
}

s.close();
}
else {
std::ofstream out(path.asString().c_str());
for (size_t i = 0; i < count; ++i) {
out << latitudes[i] << ' ' << longitudes[i] << '\n';
}
}
}


size_t GriddefOutput::save(const param::MIRParametrisation& param, context::Context& ctx) {
const auto& field = ctx.field();
repres::RepresentationHandle repres{field.representation()};

if (binary_) {
eckit::FileStream s(path_, "w");
s << static_cast<size_t>(1); // version
s << static_cast<size_t>(repres->numberOfPoints());

for (std::unique_ptr<repres::Iterator> it{repres->iterator()}; it->next();) {
const auto& p = **it;
s << p[0]; // latitude
s << p[1]; // longitude
}

s.close();
}
else {
std::ofstream out(path_.c_str());
for (std::unique_ptr<repres::Iterator> it{repres->iterator()}; it->next();) {
const auto& p = **it;
out << p[0] << ' ' << p[1] << '\n';
}
}

return 1;
}


bool GriddefOutput::sameAs(const MIROutput& other) const {
const auto* o = dynamic_cast<const GriddefOutput*>(&other);
return (o != nullptr) && eckit::PathName(path_) == eckit::PathName(o->path_);
}


bool GriddefOutput::sameParametrisation(const param::MIRParametrisation& /*unused*/,
const param::MIRParametrisation& /*unused*/) const {
return false;
}


bool GriddefOutput::printParametrisation(std::ostream& /*unused*/, const param::MIRParametrisation& /*unused*/) const {
return false;
}


void GriddefOutput::print(std::ostream& out) const {
out << "GriddefOutput[path=" << path_ << ",binary=" << binary_ << "]";
}


static const MIROutputBuilder<GriddefOutput> _output("griddef");


} // namespace mir::output
45 changes: 45 additions & 0 deletions src/mir/output/GriddefOutput.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* (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.
*/


#pragma once

#include "mir/output/MIROutput.h"


namespace eckit {
class PathName;
}


namespace mir::output {


class GriddefOutput : public MIROutput {
public:
GriddefOutput(std::string path, bool binary = true);

static void save(const eckit::PathName&, const std::vector<double>& latitudes,
const std::vector<double>& longitudes, bool binary = true);

private:
const std::string path_;
const bool binary_;

size_t save(const param::MIRParametrisation&, context::Context&) override;
bool sameAs(const MIROutput&) const override;
bool sameParametrisation(const param::MIRParametrisation&, const param::MIRParametrisation&) const override;
bool printParametrisation(std::ostream&, const param::MIRParametrisation&) const override;
void print(std::ostream&) const override;
};


} // namespace mir::output
Loading

0 comments on commit 60fc361

Please sign in to comment.