You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
3.8 KiB
161 lines
3.8 KiB
#pragma once |
|
#include "BFileW.h" |
|
#include "NEMO.h" |
|
#include "HYCOM.h" |
|
#include <utility> |
|
#include <variant> |
|
|
|
using michlib::BFileW; |
|
using michlib::errmessage; |
|
using michlib::GPL; |
|
using michlib::message; |
|
|
|
using DataVariants = std::variant<NEMOData,HYCOMData>; |
|
|
|
template<class T> |
|
concept InfoSupported = requires(T t) { |
|
{ |
|
t.template Info() |
|
} -> std::convertible_to<MString>; |
|
}; |
|
|
|
template<class T> |
|
concept ParametersSupported = requires(T t, michlib_internal::ParameterListEx& pars, const CLArgs& args) { |
|
{ |
|
t.template Parameters(pars, args).first |
|
} -> std::convertible_to<const BaseParameters*>; |
|
}; |
|
|
|
template<class T> |
|
concept ReadPSupported = requires(T t, const BaseParameters* ip, size_t i) { |
|
{ |
|
t.template Read(ip, i)(0) |
|
} -> std::convertible_to<real>; |
|
}; |
|
template<class T> |
|
concept ReadSupported = requires(T t, size_t i) { |
|
{ |
|
t.template Read(i)(0) |
|
} -> std::convertible_to<real>; |
|
}; |
|
|
|
template<class T> |
|
concept ActionTscSupported = requires(T t, michlib_internal::ParameterListEx& pars, const CLArgs& args, const BaseParameters* ip, size_t i) { |
|
{ |
|
t.template Parameters(pars, args).first |
|
} -> std::convertible_to<const BaseParameters*>; |
|
{ |
|
t.template Read(ip, i)(0) |
|
} -> std::convertible_to<real>; |
|
}; |
|
|
|
class Data: public DataVariants |
|
{ |
|
public: |
|
using TIndex = std::vector<size_t>; |
|
|
|
private: |
|
TIndex GetTIndexes(const MDateTime& b, const MDateTime& e) const |
|
{ |
|
TIndex out; |
|
auto nt = NTimes(); |
|
const MDateTime& beg = (b < e) ? b : e; |
|
const MDateTime& end = (b > e) ? b : e; |
|
|
|
if(beg > Time(nt - 1) || end < Time(0)) return out; |
|
|
|
size_t ib = 0, ie = nt - 1; |
|
for(size_t i = 0; i < nt; i++) |
|
if(Time(i) >= beg) |
|
{ |
|
ib = i; |
|
break; |
|
} |
|
|
|
for(size_t i = nt; i != 0; i--) |
|
if(Time(i - 1) <= end) |
|
{ |
|
ie = i - 1; |
|
break; |
|
} |
|
|
|
out.resize(ie - ib + 1); |
|
for(size_t i = 0; i < ie - ib + 1; i++) out[i] = i + ib; |
|
return out; |
|
} |
|
|
|
TIndex GetTIndexes(const MString& regex) |
|
{ |
|
{ |
|
MDateTime time; |
|
if(time.FromString(regex)) return TIndex(1, GetTIndex(time)); // Time, not regex |
|
if(regex == "BEGIN" || regex == "BEG" || regex == "FIRST") return TIndex(1, 0); // First time |
|
if(regex == "END" || regex == "LAST") return TIndex(1, NTimes() - 1); // Last time |
|
} |
|
|
|
TIndex out; |
|
|
|
std::unique_ptr<regex_t> regbuf(new regex_t); |
|
if(0 != regcomp(regbuf.get(), regex.Buf(), REG_EXTENDED | REG_NOSUB)) return out; |
|
|
|
for(size_t i = 0; i < NTimes(); i++) |
|
{ |
|
MString date = Time(i).ToString(); |
|
if(0 != regexec(regbuf.get(), date.Buf(), 0, 0, 0)) continue; |
|
out.push_back(i); |
|
} |
|
|
|
return out; |
|
} |
|
|
|
size_t GetTIndex(const MDateTime& t) |
|
{ |
|
size_t nt = NTimes(); |
|
|
|
if(t <= Time(0)) return 0; |
|
if(t >= Time(nt - 1)) return nt - 1; |
|
for(size_t i = 0; i < nt - 1; i++) |
|
if(t >= Time(i) && t <= Time(i + 1)) return (t - Time(i) <= Time(i + 1) - t) ? i : (i + 1); |
|
return 0; |
|
} |
|
|
|
public: |
|
Data() = default; |
|
|
|
Data(DataVariants&& d): DataVariants(std::move(d)) {} |
|
|
|
MDateTime Time(size_t it) const |
|
{ |
|
return std::visit([it = it](const auto& arg) -> auto { return arg.Time(it); }, *this); |
|
} |
|
size_t NTimes() const |
|
{ |
|
return std::visit([](const auto& arg) -> auto { return arg.NTimes(); }, *this); |
|
} |
|
|
|
MString Init(const CLArgs& args) |
|
{ |
|
MString src = args.contains("source") ? args.at("source") : ""; |
|
if(!src.Exist()) return "No source specified"; |
|
if(src == "NEMO") |
|
{ |
|
NEMOData data; |
|
auto res = data.Open(args); |
|
if(res.Exist()) return "Can't open source " + src + ":\n" + res; |
|
*this = Data(std::move(data)); |
|
} |
|
else if(src == "HYCOM") |
|
{ |
|
HYCOMData data; |
|
auto res = data.Open(args); |
|
if(res.Exist()) return "Can't open source " + src + ":\n" + res; |
|
*this = Data(std::move(data)); |
|
} |
|
else |
|
return "Unknown source: " + src; |
|
return ""; |
|
} |
|
|
|
MString ActionInfo(const CLArgs& args); |
|
MString ActionTsc(const CLArgs& args); |
|
};
|
|
|