#pragma once #include "comdefs.h" #include using michlib::real; class BaseParameters { public: virtual ~BaseParameters(); }; class BaseData { protected: static constexpr real fillval = 1.0e10; std::vector data; std::vector lons, lats; BaseData(size_t n): data(n), lons(n), lats(n) {} template BaseData(size_t n, Lon genlon, Lat genlat): data(n), lons(n), lats(n) { for(size_t i = 0; i < n; i++) { lons[i] = genlon(i); lats[i] = genlat(i); } }; public: BaseData() = default; const real& V(size_t i) const { return data[i]; } real& V(size_t i) { return data[i]; } const real& operator()(size_t i) const { return data[i]; } real& operator()(size_t i) { return data[i]; } real Lon(size_t i) const { return lons[i]; } real Lat(size_t i) const { return lats[i]; } size_t N() const { return data.size(); } bool IsFill(size_t i) const { return V(i) == Fillval(); } static real Fillval() { return fillval; } explicit operator bool() const { return N() != 0; } }; template class Averager: public Data { std::vector count; public: void Add(const Data& d) { if(!d) return; if(!*this) { *static_cast(this) = d; count.resize(Data::N()); for(size_t i = 0; i < Data::N(); i++) count[i] = (Data::V(i) == Data::Fillval()) ? 0 : 1; return; } if(Data::N() != d.N()) return; for(size_t i = 0; i < Data::N(); i++) if(d(i) != Data::Fillval()) { if(Data::V(i) == Data::Fillval()) { Data::V(i) = d(i); count[i] = 1; } else { Data::V(i) += d(i); count[i]++; } } } Averager& Div() { if(!*this) return *this; for(size_t i = 0; i < Data::N(); i++) if(count[i] != 0) Data::V(i) /= count[i]; return *this; } };