diff --git a/crhmcode/src/core/CRHMmain/CRHMmain.cpp b/crhmcode/src/core/CRHMmain/CRHMmain.cpp index 5eeb116bc..e00921a45 100644 --- a/crhmcode/src/core/CRHMmain/CRHMmain.cpp +++ b/crhmcode/src/core/CRHMmain/CRHMmain.cpp @@ -71,15 +71,27 @@ CRHMmain* CRHMmain::getInstance() { if (instance == 0) { - instance = new CRHMmain(); + instance = new CRHMmain(NULL); } return instance; } -CRHMmain::CRHMmain() +CRHMmain::CRHMmain(struct crhm_arguments * arguments) { + if (arguments == NULL) + { + //Use default values + Global::TimeFormat = TIMEFORMAT::ISO; + this->OutputFormat = OUTPUT_FORMAT::STD; + } + else + { + Global::TimeFormat = arguments->time_format; + this->OutputFormat = arguments->output_format; + } + FormCreate(); } @@ -865,7 +877,7 @@ void CRHMmain::SetSharedParams(ClassPar *basinPar) { } -void CRHMmain::FormCreate(void) { +void CRHMmain::FormCreate() { Global::BuildFlag = TBuild::BUILD; @@ -956,7 +968,7 @@ void CRHMmain::FormCreate(void) { Global::NaNcheck = false; Global::LOGVARLOAD = false; - Global::TimeFormat = TIMEFORMAT::MS; + } @@ -2365,26 +2377,42 @@ void CRHMmain::AllRprt(void) { TStringList *LogList = new TStringList; - RprtHeader(LogList, SeriesCnt); - + if (this->OutputFormat == OUTPUT_FORMAT::STD) + { + //standard output header + RprtHeader(LogList, SeriesCnt); + } + else if (this->OutputFormat == OUTPUT_FORMAT::OBS) + { + //.obs file output header + RprtHeaderObs(LogList, SeriesCnt); + } + else + { + CRHMException e = CRHMException("No output format was specified defaulting to STD.", TExcept::WARNING); + CRHMLogger::instance()->log_run_error(e); + //standard output header + RprtHeader(LogList, SeriesCnt); + } + string Sx, Sy; for (int nn = 0; nn < cdSeries[0]->Count(); ++nn) { - //Sx = FloatToStrF(cdSeries[0]->XValue(nn), ffGeneral, 10, 0); - //Sx = StandardConverterUtility::GetDateTimeInStringForOutput(cdSeries[0]->XValue(nn)); + Sx = FloatToStrF(cdSeries[0]->XValue(nn), TFloatFormat::ffGeneral, 10, 0); + Sx = StandardConverterUtility::GetDateTimeInStringForOutput(cdSeries[0]->XValue(nn)); //added this switch statement according to Peter's code. switch (Global::TimeFormat) { case TIMEFORMAT::MS: Sx = FloatToStrF(cdSeries[0]->XValue(nn), TFloatFormat::ffGeneral, 10, 0); break; - case TIMEFORMAT::MMDDYYYY: - Sx = StandardConverterUtility::FormatDateTime("mm/dd/yyyy hh:mm ", cdSeries[0]->XValue(nn)); - break; case TIMEFORMAT::YYYYMMDD: Sx = StandardConverterUtility::FormatDateTime("yyyy-mm-dd hh:mm ", cdSeries[0]->XValue(nn)); break; + case TIMEFORMAT::ISO: + Sx = StandardConverterUtility::FormatDateTime("ISO", cdSeries[0]->XValue(nn)); + break; default: break; } @@ -2396,10 +2424,10 @@ void CRHMmain::AllRprt(void) ClassVar *thisVar = (ClassVar *)cdSeries[vv]->Tag; int prec = 7; //Manishankar did this, because GCC is showing segmentation fault here. thisVar remains null. - /* - if (thisVar->varType == CRHM::Int || thisVar->varType == CRHM::ReadI) + + if (thisVar->varType == TVar::Int || thisVar->varType == TVar::ReadI) prec = 7; - */ + Sy = FloatToStrF(cdSeries[vv]->YValue(nn), TFloatFormat::ffGeneral, prec, 10); Sx = Sx + "\t" + Sy; } @@ -2423,6 +2451,22 @@ void CRHMmain::LastRprt(void) int nn = cdSeries[0]->Count(); Sx = FloatToStrF(cdSeries[0]->XValue(nn - 1), TFloatFormat::ffGeneral, 10, 0); + Sx = StandardConverterUtility::GetDateTimeInStringForOutput(cdSeries[0]->XValue(nn-1)); + + //added this switch statement according to Peter's code. + switch (Global::TimeFormat) { + case TIMEFORMAT::MS: + Sx = FloatToStrF(cdSeries[0]->XValue(nn-1), TFloatFormat::ffGeneral, 10, 0); + break; + case TIMEFORMAT::YYYYMMDD: + Sx = StandardConverterUtility::FormatDateTime("yyyy-mm-dd hh:mm ", cdSeries[0]->XValue(nn-1)); + break; + case TIMEFORMAT::ISO: + Sx = StandardConverterUtility::FormatDateTime("ISO", cdSeries[0]->XValue(nn)); + break; + default: + break; + } for (int vv = 0; vv < SeriesCnt; ++vv) { ClassVar *thisVar = (ClassVar *)cdSeries[vv]->Tag; @@ -2802,6 +2846,69 @@ void CRHMmain::RprtHeader(TStringList *LogList, int LocalCnt) long ID = 0; + if (!thisPar) { + MapPar::iterator itPar; + + for (itPar = Global::MapPars.begin(); itPar != Global::MapPars.end(); itPar++) { + thisPar = (*itPar).second; + if (thisPar->param == "RUN_ID") { + ID = thisPar->ivalues[0]; + break; + } + } + } + else + ID = thisPar->ivalues[0]; + + OpenNameReport = ProjectDirectory + "/CRHM_output"; //manishankar updated this line to make it suitable for both windows and linux.s + if (ID >= 0) { + if (ID > 0) { + OpenNameReport += "_"; + OpenNameReport += inttoStr(ID); + } + OpenNameReport += ".txt"; + } + else if (ID < 0) { + ID = -ID; + OpenNameReport = OpenNamePrj.substr(0, OpenNamePrj.length() - 4) + "_" + Common::longtoStr(ID) + ".txt"; + } + + //LogList->Add("Future File Description"); + /** + for (int vv = 0; vv < LocalCnt; ++vv) { + ClassVar *thisVar = (ClassVar *)cdSeries[vv]->Tag; + Sx = cdSeries[vv]->Title; + Sx += string(" 1 "); + Sx += thisVar->units; + LogList->Add(Sx); + } + **/ + Sx = "time"; + for (int vv = 0; vv < LocalCnt; ++vv) { + string S = cdSeries[vv]->Title; + Sx += "\t" + S; + } + LogList->Add(Sx); + + Sx = "units"; + for (int vv = 0; vv < LocalCnt; ++vv) { + ClassVar* thisVar = (ClassVar*)cdSeries[vv]->Tag; + string S = thisVar->units; + Sx += "\t" + S; + } + LogList->Add(Sx); +} + +void CRHMmain::RprtHeaderObs(TStringList* LogList, int LocalCnt) +{ + + string Sx, Sy; + + ClassPar* thisPar; + thisPar = ParFind("basin RUN_ID"); + + long ID = 0; + if (!thisPar) { MapPar::iterator itPar; @@ -2830,17 +2937,16 @@ void CRHMmain::RprtHeader(TStringList *LogList, int LocalCnt) } LogList->Add("Future File Description"); - + for (int vv = 0; vv < LocalCnt; ++vv) { ClassVar *thisVar = (ClassVar *)cdSeries[vv]->Tag; Sx = cdSeries[vv]->Title; Sx += string(" 1 "); - //gcc is showing segmentation fault here. thisVar remains null. - //Sx += thisVar->units; + Sx += thisVar->units; LogList->Add(Sx); } - - Sx = "##### time"; + + Sx = "###### time"; for (int vv = 0; vv < LocalCnt; ++vv) { string S = cdSeries[vv]->Title; Sx += "\t" + S; diff --git a/crhmcode/src/core/CRHMmain/CRHMmain.h b/crhmcode/src/core/CRHMmain/CRHMmain.h index a089b2743..e3eb5b777 100644 --- a/crhmcode/src/core/CRHMmain/CRHMmain.h +++ b/crhmcode/src/core/CRHMmain/CRHMmain.h @@ -28,6 +28,7 @@ #include "TSeries.h" #include "Classinfo.h" #include "CRHMLogger.h" +#include "../../gcc/CRHMArguments.h" //class ObsFileInfo { //private: @@ -51,7 +52,7 @@ class CRHMmain CRHMLogger* Logger; static CRHMmain * getInstance(); - CRHMmain(); + CRHMmain(struct crhm_arguments * ); //virtual void DoPrjOpen(string OpenNamePrj, string ProjectDirectory); string Sstrings[12] = { "", "_WtoMJ", "_MJtoW", "_Avg", "_Min", "_Max", "_Sum", "_Pos", "_Tot", "_Tot/Freq", "_First", "_Last" }; @@ -106,6 +107,8 @@ class CRHMmain bool ShiftDown; // Linked to ListBox1 and ListBox2 bool HruNames; + OUTPUT_FORMAT OutputFormat; + typedef void LoadModuleType(string DllName); // TDateTime ProjectFileDate; @@ -184,6 +187,7 @@ class CRHMmain void ControlSaveState(bool MainLoop, ClassPar * VarPar, BitSet &Bit); void DoObsStatus(bool &First); void RprtHeader(TStringList *LogList, int LocalCnt); + void RprtHeaderObs(TStringList *LogList, int LocalCnt); void ResetLoopList(void); void ReadStateFile(bool & GoodRun); string DttoStr(double D); diff --git a/crhmcode/src/core/Common/Common.h b/crhmcode/src/core/Common/Common.h index 0a8f57fc8..f84831fc3 100644 --- a/crhmcode/src/core/Common/Common.h +++ b/crhmcode/src/core/Common/Common.h @@ -71,7 +71,7 @@ enum class TExtra { BLANK, DD, TT, DT }; enum class TAKA { AKAERROR = -1, VARG, OBSR, VARD, OBSD, PARD, OBSF, AKAEND }; enum TMsgDlgBtn { mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore, mbAll, mbNoToAll, mbYesToAll, mbHelp }; enum class TBuild { BUILD, DECL, INIT, RUN }; -enum class TIMEFORMAT { MS, MMDDYYYY, YYYYMMDD }; +enum class TIMEFORMAT { MS, YYYYMMDD, ISO}; enum class LMODULE { BASIC, MACRO, ADVANCE, SUPPORT, CUSTOM, PROTO, OBSOL }; enum class TFun { FOBS, VP_SAT, W_MJ, MJ_W, AVG, MIN, MAX, TOT, POS, FIRST, LAST, CNT, CNT0, DLTA, INTVL, DAY, DTOT }; enum class TVISIBLE { OUTPUT, USUAL, DIAGNOSTIC, PRIVATE }; // OUTPUT infers all variables/parameters diff --git a/crhmcode/src/core/StandardConverterUtility.cpp b/crhmcode/src/core/StandardConverterUtility.cpp index 72ed83e1d..8855795ea 100644 --- a/crhmcode/src/core/StandardConverterUtility.cpp +++ b/crhmcode/src/core/StandardConverterUtility.cpp @@ -157,13 +157,13 @@ std::string StandardConverterUtility::FormatDateTime(std::string fmt, double dat if (h < 10) { h1 = "0" + h1; } if (min < 10) { min1 = "0" + min1; } - if (fmt == "mm/dd/yyyy hh:mm ") + if (fmt == "yyyy-mm-dd hh:mm ") { - return m1 + "/" + d1 + "/" + to_string(y) + " " + h1 + ":" + min1+" "; + return to_string(y) + " " + m1 + " " + d1 + " " + h1 + " " + min1; } - else if (fmt == "yyyy-mm-dd hh:mm ") + else if (fmt == "ISO") { - return to_string(y) + "-" + m1 + "-" + d1 + " " + h1 + ":" + min1; + return to_string(y) + "-" + m1 + "-" + d1 + "T" + h1 + ":" + min1; } return ""; diff --git a/crhmcode/src/gcc/CRHMArguments.h b/crhmcode/src/gcc/CRHMArguments.h new file mode 100644 index 000000000..fe21c9757 --- /dev/null +++ b/crhmcode/src/gcc/CRHMArguments.h @@ -0,0 +1,34 @@ +#ifndef CRHM_ARGUMENTS +#define CRHM_ARGUMENTS + +#include "../core/Common/Common.h" + +enum class OUTPUT_FORMAT {STD, OBS}; + +const string USE_MESSAGE = "\ncrhm [options] PROJECT_FILE\n" + "\n" + "\t-h - Display this message.\n" + "\n" + "\t-t TIME_FORMAT - Select the format for date time outputs.\n" + "\t\tValid formats are:\n" + "\t\tMS - Microsoft Excel floating point.\n" + "\t\tISO - ISO 8601 extended format YYYY-MM-DDThh:mm\n" + "\t\tYYYYMMDD - YYYY MM DD hh mm\n" + "\n" + "\t-f OUTPUT_FORMAT - Select the file format for the output.\n" + "\t\tValid formats are:\n" + "\t\tSTD - Standard output format. Sutable for a spreadsheet.\n" + "\t\tOBS - Observation file .obs format. Sutable for reading with CRHM GUI.\n" + "\n"; + +struct crhm_arguments +{ + std::string project_name; + TIMEFORMAT time_format; + bool time_format_set{false}; + OUTPUT_FORMAT output_format; +}; + +#endif // !CRHM_ARGUMENTS + + diff --git a/crhmcode/src/gcc/main.cpp b/crhmcode/src/gcc/main.cpp index b8d97df84..f5024d131 100644 --- a/crhmcode/src/gcc/main.cpp +++ b/crhmcode/src/gcc/main.cpp @@ -1,13 +1,151 @@ //#include "stdafx.h" #include + #include "../core/CRHMmain/CRHMmain.h" +const char * argp_program_version = + "CRHMcode gcc Version 1.2"; +const char * argp_program_bug_address = + ""; + +static char doc[] = "CRHM"; + +static char args_doc[] = "PROJECT_FILE [STRING...]"; + +std::string unrecongnized_option(char * option) +{ + std::string message = + "\nUnrecognized option \"" + + std::string(option) + + "\" given. Use option --help for usage information.\n"; + return message; +} + + +void read_option(char ** argv, struct crhm_arguments * arguments, int * i) +{ + + + switch (argv[*i][1]) + { + case 'h': + std::cout << USE_MESSAGE; + exit(1); + case 't': + arguments->time_format_set = true; + *i = *i + 1; + if (!strcmp(argv[*i], "MS")) + { + arguments->time_format = TIMEFORMAT::MS; + } + else if (!strcmp(argv[*i], "YYYYMMDD")) + { + arguments->time_format = TIMEFORMAT::YYYYMMDD; + } + else if (!strcmp(argv[*i], "ISO")) + { + arguments->time_format = TIMEFORMAT::ISO; + } + else + { + std::cout << "\nUnable to read time format argument. "+ std::string(argv[*i]) +"\n"; + std::cout << "-t must be followed directly by a valid time format.\n"; + std::cout << "Valid formats are: \n\tMS \n\tISO \n\tYYYYMMDD\n"; + exit(1); + } + break; + case 'f': + *i = *i + 1; + if (!strcmp(argv[*i], "STD")) + { + arguments->output_format = OUTPUT_FORMAT::STD; + } + else if (!strcmp(argv[*i], "OBS")) + { + arguments->output_format = OUTPUT_FORMAT::OBS; + } + else + { + std::cout << "\nUnable to read output format argument. " + std::string(argv[*i]) + "\n"; + std::cout << "-f must be followed directly by a valid output format.\n"; + std::cout << "Valid formats are: \n\tSTD - standard output.\n\tOBS - obsfile output.\n"; + exit(1); + } + break; + case '-': + switch (argv[*i][2]) + { + case 'h': + if (!strcmp(argv[*i], "--help")) + { + std::cout << USE_MESSAGE; + exit(1); + } + default: + std::cout << unrecongnized_option(argv[*i]); + exit(1); + } + break; + default: + std::cout << unrecongnized_option(argv[*i]); + exit(1); + } + +} + +void read_argument(char* argument, struct crhm_arguments* arguments) +{ + arguments->project_name = std::string(argument); +} + int main(int argc, char *argv[]) { - CRHMmain * m = new CRHMmain(); + struct crhm_arguments arguments; + // Set Default Argument Values + arguments.project_name = ""; + arguments.time_format = TIMEFORMAT::ISO; + arguments.output_format = OUTPUT_FORMAT::STD; + + /* + * Read the incoming argv[] vector + */ + for (int i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + read_option(argv, &arguments, &i); + } + else + { + read_argument(argv[i], &arguments); + } + } + + if (arguments.output_format == OUTPUT_FORMAT::OBS) + { + if (arguments.time_format_set) + { + //Check that time format was set to MS or YYYYMMDD + if (!(arguments.time_format == TIMEFORMAT::MS || arguments.time_format == TIMEFORMAT::YYYYMMDD)) + { + std::cout << "\nCannot use specified time format while requesting output format of OBS.\n" + "Only MS and YYYYMMDD formats are compatible with OBS output file.\n"; + exit(1); + } + + } + else + { + //Default to MS time format. + arguments.time_format = TIMEFORMAT::MS; + } + } + + + CRHMmain * m = new CRHMmain(&arguments); - std::string projectArgument = argv[1]; + std::string projectArgument = arguments.project_name; m->OpenNamePrj = projectArgument; m->DoPrjOpen(projectArgument, ""); diff --git a/crhmcode/src/vcc/CRHM_GUI.vcxproj b/crhmcode/src/vcc/CRHM_GUI.vcxproj index 7cf2f8680..fd307714f 100644 --- a/crhmcode/src/vcc/CRHM_GUI.vcxproj +++ b/crhmcode/src/vcc/CRHM_GUI.vcxproj @@ -197,6 +197,7 @@ + @@ -763,6 +764,7 @@ + diff --git a/crhmcode/src/vcc/CRHM_GUI.vcxproj.filters b/crhmcode/src/vcc/CRHM_GUI.vcxproj.filters index 1884389d5..b5da585b9 100644 --- a/crhmcode/src/vcc/CRHM_GUI.vcxproj.filters +++ b/crhmcode/src/vcc/CRHM_GUI.vcxproj.filters @@ -1473,6 +1473,9 @@ Resource Files\Header Files + + Resource Files\Header Files + @@ -2099,6 +2102,9 @@ Source Files + + Source Files +