#ifndef GLM_OUTPUTTER_H_ #define GLM_OUTPUTTER_H_ #include #include #include #include "grid_cell.h" #include "config.h" #define NCERR(s, e) { printf("Error: %s %s\n", s, nc_strerror(e)); exit(62); } namespace glm { class Outputter { class OutputFile { public: int fileID_; int latDimID_; int lonDimID_; int timeDimID_; int bndDimID_; int latVarID_; int lonVarID_; int timeVarID_; int dimVarID_; OutputFile(std::string fileName, Config& config); void addLatLon(double lat[], double lon[]); void addYear(size_t index, int year); void sync() { int rv; if ((rv = nc_sync(fileID_))) { NCERR("sync", rv); } } }; class VarBase { public: VarBase (OutputFile* file, const char* name, const char* standardName, const char* longName, const char* units) : fileID_(file->fileID_), name_(name), standardName_(standardName), longName_(longName), units_(units) {} virtual ~VarBase () {}; virtual void updateVal (size_t now, GridCell& gc, size_t gcNow) = 0; virtual void flush (size_t index[], size_t count[]) = 0; int fileID_; std::string name_; std::string standardName_; std::string longName_; std::string units_; int varID_; }; template class VarTemplateBase : public VarBase { public: VarTemplateBase(OutputFile* file, const char* name, const char* standardName, const char* longName, const char* units, T fill) : VarBase(file, name, standardName, longName, units), fill_(fill) { for (size_t t=0; t class Var : public VarTemplateBase{ public: Var (OutputFile* file, const char* name, const char* standardName, const char* longName, const char* units, T (GridCell::*get)(size_t), T fill) : VarTemplateBase(file, name, standardName, longName, units, fill), getVal_(get) { } inline void updateVal (size_t now, GridCell& gc, size_t gcNow) { this->buffer_[now][gc.y][gc.x] = (gc.*getVal_)(gcNow); } T (GridCell::*getVal_)(size_t); }; template class StateVar : public VarTemplateBase { public: StateVar (OutputFile* file, std::string name, std::string standardName, std::string longName, sub_lu_types lu, const char* units, T (GridCell::*get)(size_t, sub_lu_types), T fill) : VarTemplateBase(file, name.c_str(), standardName.c_str(), longName.c_str(), units, fill), lu_(lu), getVal_(get) { } inline void updateVal (size_t now, GridCell& gc, size_t gcNow) { this->buffer_[now][gc.y][gc.x] = (gc.*getVal_)(gcNow, lu_); } sub_lu_types lu_; T (GridCell::*getVal_)(size_t, sub_lu_types); }; template class FlowVar : public VarTemplateBase { public: FlowVar (OutputFile* file, std::string name, std::string standardName, std::string longName, sub_lu_types from, sub_lu_types to, const char* units, T (GridCell::*get)(sub_lu_types, sub_lu_types), T fill) : VarTemplateBase(file, name.c_str(), standardName.c_str(), longName.c_str(), units, fill), from_(from), to_(to), getVal_(get) { } inline void updateVal (size_t now, GridCell& gc, size_t gcNow) { this->buffer_[now][gc.y][gc.x] = (gc.*getVal_)(from_, to_); } sub_lu_types from_; sub_lu_types to_; T (GridCell::*getVal_)(sub_lu_types, sub_lu_types); }; public: void init (std::string name, int startYear, double lat[], double lon[], Config& config); void initVars (Config& config); template void registerVar (OutputFile* file, const char* name, const char* standardName, const char* longName, const char* units, T (GridCell::*get)(size_t), T fill) { registeredVars_.push_back(new Var(file, name, standardName, longName, units, get, fill)); } template void registerVarByLandUse (OutputFile* file, std::string name, std::string standardName, std::string longName, sub_lu_types lu, const char* units, T (GridCell::*get)(size_t, sub_lu_types), T fill) { registeredVars_.push_back(new StateVar(file, name, standardName, longName, lu, units, get, fill)); } template void registerFlowVar (sub_lu_types from, sub_lu_types to, const char* units, const char* standardName, T (GridCell::*get)(sub_lu_types, sub_lu_types), T fill) { registeredVars_.push_back(new FlowVar(flowsFile_, getSubFlowName(from, to), std::string("transition from ") +getSubLandUseLongName(from) +" to "+getSubLandUseLongName(to), standardName, from, to, units, get, fill)); } void updateOutputs (GridCell& gc, size_t gcNow); void flush (bool writeFlows=true); private: int createFile(std::string fileName); void addLatLon(int ncID, double lat[], double lon[]); int startYear_; size_t now_; size_t recNo_; OutputFile* stateFile_; OutputFile* flowsFile_; OutputFile* mngmtFile_; OutputFile* diagnFile_; size_t index_[3]; size_t count_[3]; std::vector registeredVars_; }; } // end glm namespace #endif // GLM_OUTPUTTER_H_