Browse Source

Add Adapter interface to the COPERNICUS source

master
Michael Uleysky 4 weeks ago
parent
commit
c18843670a
  1. 113
      sources/COPERNICUS.cpp
  2. 6
      sources/COPERNICUS.h

113
sources/COPERNICUS.cpp

@ -1,8 +1,11 @@
#define MICHLIB_NOSOURCE
#include "COPERNICUS.h"
#include "CF.h"
#include "mirrorfuncs.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <numeric>
#include <valarray>
using michlib::GPL;
@ -232,3 +235,113 @@ Error COPERNICUSData::Mirror(const CLArgs& args) const
return Error();
}
RetVal<Adapter> COPERNICUSData::GetAdapter(const CLArgs& args, michlib_internal::ParameterListEx& pars) const
{
static const MString pref = "COPERNICUSData::GetAdapter";
bool debug = args.contains("debug");
Adapter out(Adapter::ZarrMethod::MZARR);
MString dataset = args.contains("dataset") ? args.at("dataset") : "DT";
GPL.UsePrefix("NEMO");
// Get link for dataset
MString product;
std::vector<MString> dset;
{
// Try one url
MString url = GPL.ParameterSValue(dataset + "_URL", "");
if(url.Exist())
{
auto list = url.Split(":");
product = list[0];
for(size_t i = 1; i < list.size(); i++) dset.push_back(list[i]);
}
else // Multiple urls
{
size_t i = 1;
while(true)
{
MString url = GPL.ParameterSValue(dataset + "_URL" + i, "");
if(url.Exist())
{
// Split url on product and dataset
auto words = url.Split(":");
if(words.size() != 2) return {pref, "Invalid url for dataset " + dataset + ": " + url};
if(product.Exist() && product != words[0]) return {pref, "Product for dataset " + dataset + " was already defined: " + url};
product = words[0];
dset.push_back(words[1]);
}
else
break;
i++;
}
}
if(!product.Exist()) return {pref, "Can't find product for the dataset " + dataset};
if(dset.size() == 0) // Get datasets from catalog
{
CopernicusCatalog cat;
auto dlist = cat.DatasetList(product);
if(!dlist) return dlist.Add(pref, "Can't get list of datasets for product " + product);
dset = dlist.Value();
}
}
pars.AddParameter("product", product);
pars.AddParameter("datasets", std::accumulate(dset.begin() + 1, dset.end(), dset.front(), [](const MString& a, const MString& b) { return a + "," + b; }));
// Open data
std::unique_ptr<NCZarr> pnc(new NCZarr);
{
auto ret = pnc->OpenMultiZarr(product, dset);
if(!ret) return ret.Add(pref, "Can't open dataset " + dataset);
}
pars.AddParameter("dataset", dataset);
// Title
{
MString title;
CopernicusCatalog cat;
auto ret = cat.DatasetTitle(product, dset[0]);
if(!ret) return ret.Add(pref, "Can't get title for dataset " + dataset);
title = ret.Value();
pars.AddParameter("title", title);
out.SetTitle(title);
}
// Filename for adapter
MString fname = product + ":" + dset[0];
for(size_t i = 1; i < dset.size(); i++) fname += "," + dset[i];
auto tvar = CF::GetTVarName(*pnc);
if(!tvar.Exist()) return {pref, "Can't find time variable in the dataset " + dataset};
if(pnc->NDim(tvar) != 1) return {pref, "Unsupported number of time dimensions: " + MString(pnc->NDim(tvar))};
if(debug) pars.AddParameter("File name", fname);
// Read and set times
{
auto ret = CF::ReadTimes(*pnc, tvar);
if(!ret) return ret.Add(pref, "Can't read time values from the dataset " + dataset);
auto ret1 = out.SetTimes(ret.Value(), args, pars);
if(!ret1) return ret1.Add(pref, "Can't filter time values from the dataset " + dataset);
}
// Timetable
{
std::vector<Adapter::TimeRow> table{1};
table[0].beg = 0;
table[0].end = out.Times().size() - 1;
table[0].file = fname;
out.SetTimeTable(std::move(table));
}
{
auto ret = CF::FillAdapterFromCF(args, pars, out, std::move(pnc));
if(!ret) return ret.Add(pref, "Can't get adapter");
}
return out;
}

6
sources/COPERNICUS.h

@ -1,10 +1,13 @@
#pragma once
#include "Adapter.h"
#include "ParseArgs.h"
#include "copcat.h"
#include "mdatetime.h"
using michlib::DetGeoDomain;
using michlib::MDateTime;
using michlib::MString;
using michlib::ToGeoDomain;
class COPERNICUSData
{
@ -18,4 +21,7 @@ class COPERNICUSData
// Main mirror function
Error Mirror(const CLArgs& args) const;
// Adapter
RetVal<Adapter> GetAdapter(const CLArgs& args, michlib_internal::ParameterListEx& pars) const;
};

Loading…
Cancel
Save