#include "readfunc.h" #include "errorhandler.h" #include "gadget.h" #include "global.h" void readRefWeights(CommentStream& infile, DoubleMatrix& M) { //Check the number of columns in the inputfile if (countColumns(infile) != 2) handle.logFileMessage(LOGFAIL, "wrong number of columns in inputfile - should be 2"); int i = 0; M.Reset(); infile >> ws; while (!infile.eof()) { //crude check to see if something has gone wrong and avoid infinite loops if (!(isdigit(infile.peek()))) handle.logFileMessage(LOGFAIL, "failed to read data from file"); M.AddRows(1, 2, 0.0); infile >> M[i][0] >> M[i][1]; if (infile.fail()) handle.logFileMessage(LOGFAIL, "failed to read reference weights"); infile >> ws; i++; } //Check the data to make sure that it is continuous and the weights are positive if (M[0][0] < 0.0) handle.logFileMessage(LOGFAIL, "lengths for reference weights must be positive"); for (i = 1; i < M.Nrow(); i++) if ((M[i][0] - M[i - 1][0]) < verysmall) handle.logFileMessage(LOGFAIL, "lengths for reference weights must be strictly increasing"); for (i = 1; i < M.Nrow(); i++) if (M[i][1] < verysmall) handle.logFileMessage(LOGFAIL, "weights for reference weights must be positive"); handle.logMessage(LOGMESSAGE, "Read reference weights OK - number of entries", M.Nrow()); } int countColumns(CommentStream& infile) { if (infile.fail()) return 0; char line[MaxStrLength]; char temp[MaxStrLength]; strncpy(line, "", MaxStrLength); strncpy(temp, "", MaxStrLength); streampos pos = infile.tellg(); infile >> ws; infile.getLine(line, MaxStrLength); if (infile.fail()) return 0; istringstream istr(line); istr >> ws; char c; int i = 0; int p = 0; while (!istr.eof()) { // with the new formula syntax a column can contain whitespace, // so this code was changed to keep track of opening and closing // parens when counting columns. [mnaa] c = (char)istr.peek(); //JMB keep GCC 4.3 happy if (c == '(') { istr.get(c); p++; while (p > 0) { if (istr.eof()) return 0; istr.get(c); if (c == '(') p++; if (c == ')') p--; } istr >> ws; i++; } else { istr >> temp; if (istr.fail() && !istr.eof()) return 0; istr >> ws; i++; } } infile.seekg(pos); return i; } void readAmounts(CommentStream& infile, const IntVector& tmpareas, const TimeClass* const TimeInfo, const AreaClass* const Area, FormulaMatrix& amount, const char* givenname) { char c; char tmpname[MaxStrLength]; strncpy(tmpname, "", MaxStrLength); int i, year, step, area; int keepdata, timeid, areaid, tmpareaid, count, reject; //Check the number of columns in the inputfile infile >> ws; if (countColumns(infile) != 5) handle.logFileMessage(LOGFAIL, "wrong number of columns in inputfile - should be 5"); //Create storage for the data - size of the data is known amount.AddRows(TimeInfo->numTotalSteps() + 1, tmpareas.Size(), 0.0); year = step = area = count = reject = 0; while (!infile.eof()) { keepdata = 1; infile >> year >> step >> area >> tmpname; //crude check to see if something has gone wrong and avoid infinite loops if (strlen(tmpname) == 0) handle.logFileMessage(LOGFAIL, "failed to read data for", givenname); //check if the year and step are in the simulation timeid = -1; if (TimeInfo->isWithinPeriod(year, step)) timeid = TimeInfo->calcSteps(year, step); else keepdata = 0; //only keep the data if tmpname matches givenname if (strcasecmp(givenname, tmpname) != 0) keepdata = 0; //only keep the data if area is a required area areaid = -1; tmpareaid = Area->getInnerArea(area); for (i = 0; i < tmpareas.Size(); i++) if (tmpareas[i] == tmpareaid) areaid = i; if (areaid == -1) keepdata = 0; if (keepdata == 1) { //data is required, so store it count++; infile >> amount[timeid][areaid] >> ws; } else { //data not required - skip rest of line reject++; infile.get(c); while (c != '\n' && !infile.eof()) infile.get(c); infile >> ws; } } if (count == 0) handle.logMessage(LOGWARN, "Warning in readamounts - found no data in the data file for", givenname); if (reject != 0) handle.logMessage(LOGMESSAGE, "Discarded invalid amounts data - number of invalid entries", reject); handle.logMessage(LOGMESSAGE, "Read amounts data file - number of entries", count); } void readGrowthAmounts(CommentStream& infile, const TimeClass* const TimeInfo, const AreaClass* const Area, FormulaMatrixPtrVector& amount, const CharPtrVector& lenindex, const IntVector& tmpareas) { int i, year, step, area; char c; char tmplength[MaxStrLength]; strncpy(tmplength, "", MaxStrLength); int keepdata, timeid, areaid, lenid, tmpareaid, count, reject; //Check the number of columns in the inputfile infile >> ws; if (countColumns(infile) != 5) handle.logFileMessage(LOGFAIL, "wrong number of columns in inputfile - should be 5"); year = step = area = count = reject = 0; while (!infile.eof()) { keepdata = 1; infile >> year >> step >> area >> tmplength; //crude check to see if something has gone wrong and avoid infinite loops if (strlen(tmplength) == 0) handle.logFileMessage(LOGFAIL, "failed to read growth data"); //check if the year and step are in the simulation timeid = -1; if (TimeInfo->isWithinPeriod(year, step)) timeid = TimeInfo->calcSteps(year, step); else keepdata = 0; //if tmplength is in lenindex find lengthid, else dont keep the data lenid = -1; for (i = 0; i < lenindex.Size(); i++) if (strcasecmp(lenindex[i], tmplength) == 0) lenid = i; if (lenid == -1) keepdata = 0; //only keep the data if area is a required area areaid = -1; tmpareaid = Area->getInnerArea(area); for (i = 0; i < tmpareas.Size(); i++) if (tmpareas[i] == tmpareaid) areaid = i; if (areaid == -1) keepdata = 0; if (keepdata == 1) { count++; infile >> (*amount[areaid])[timeid][lenid] >> ws; } else { //data not required - skip rest of line reject++; infile.get(c); while (c != '\n' && !infile.eof()) infile.get(c); infile >> ws; } } if (count == 0) handle.logMessage(LOGWARN, "Warning in growthamounts - found no data in the data file"); if (reject != 0) handle.logMessage(LOGMESSAGE, "Discarded invalid growth data - number of invalid entries", reject); handle.logMessage(LOGMESSAGE, "Read growth data file - number of entries", count); }