#include "areatime.h" #include "errorhandler.h" #include "stockstdprinter.h" #include "stockaggregator.h" #include "stockpreyaggregator.h" #include "charptrvector.h" #include "stockptrvector.h" #include "preyptrvector.h" #include "stock.h" #include "stockprey.h" #include "conversionindex.h" #include "readword.h" #include "gadget.h" #include "runid.h" #include "global.h" StockStdPrinter::StockStdPrinter(CommentStream& infile, const TimeClass* const TimeInfo) : Printer(STOCKSTDPRINTER), stockname(0), LgrpDiv(0), saggregator(0), paggregator(0), salptr(0), palptr(0) { char text[MaxStrLength]; strncpy(text, "", MaxStrLength); filename = new char[MaxStrLength]; strncpy(filename, "", MaxStrLength); isaprey = 0; stockname = new char[MaxStrLength]; strncpy(stockname, "", MaxStrLength); readWordAndValue(infile, "stockname", stockname); infile >> text >> ws; if (strcasecmp(text, "scale") == 0) { infile >> scale >> ws >> text >> ws; if (scale < rathersmall) { handle.logFileMessage(LOGWARN, "scale should be a positive integer - set to default value 1"); scale = 1.0; } } else scale = 1.0; //JMB - removed the need to read in the area aggregation file if (strcasecmp(text, "areaaggfile") == 0) { infile >> text >> ws; handle.logMessage(LOGWARN, "Warning in stockstdprinter - area aggregation file ignored"); infile >> text >> ws; } //open the printfile if (strcasecmp(text, "printfile") != 0) handle.logFileUnexpected(LOGFAIL, "printfile", text); infile >> filename >> ws; outfile.open(filename, ios::out); handle.checkIfFailure(outfile, filename); infile >> text >> ws; if (strcasecmp(text, "precision") == 0) { infile >> precision >> ws >> text >> ws; width = precision + 4; } else { // use default values precision = largeprecision; width = largewidth; } if (precision < 0) handle.logFileMessage(LOGFAIL, "\nError in stockstdprinter - invalid value of precision"); if (strcasecmp(text, "printatstart") == 0) infile >> printtimeid >> ws >> text >> ws; else printtimeid = 0; if (printtimeid != 0 && printtimeid != 1) handle.logFileMessage(LOGFAIL, "\nError in stockstdprinter - invalid value of printatstart"); if (strcasecmp(text, "yearsandsteps") != 0) handle.logFileUnexpected(LOGFAIL, "yearsandsteps", text); if (!AAT.readFromFile(infile, TimeInfo)) handle.logFileMessage(LOGFAIL, "\nError in stockstdprinter - wrong format for yearsandsteps"); //prepare for next printfile component infile >> ws; if (!infile.eof()) { infile >> text >> ws; if (strcasecmp(text, "[component]") != 0) handle.logFileUnexpected(LOGFAIL, "[component]", text); } //finished initializing. Now print first lines outfile << "; "; RUNID.Print(outfile); outfile << "; Standard output file for the stock " << stockname; if (scale != 1.0) { outfile << "\n; Scaling factor for the number and number consumed is " << scale; //JMB - store this as 1/scale scale = 1.0 / scale; } if (printtimeid == 0) outfile << "\n; Printing the following information at the end of each timestep"; else outfile << "\n; Printing the following information at the start of each timestep"; outfile << "\n; year-step-area-age-number-mean length-mean weight-" << "stddev length-number consumed-biomass consumed\n"; outfile.flush(); } StockStdPrinter::~StockStdPrinter() { outfile.close(); outfile.clear(); if (isaprey) delete paggregator; delete saggregator; delete LgrpDiv; delete[] stockname; } void StockStdPrinter::setStock(StockPtrVector& stockvec, const AreaClass* const Area) { StockPtrVector stocks; int i, maxage; for (i = 0; i < stockvec.Size(); i++) if (strcasecmp(stockvec[i]->getName(), stockname) == 0) stocks.resize(stockvec[i]); if (stocks.Size() != 1) { handle.logMessage(LOGWARN, "Error in stockstdprinter - failed to match stocks"); for (i = 0; i < stocks.Size(); i++) handle.logMessage(LOGWARN, "Error in stockstdprinter - found stock", stocks[i]->getName()); handle.logMessage(LOGFAIL, "Error in stockstdprinter - looking for stock", stockname); } IntVector areas = stocks[0]->getAreas(); outerareas.resize(areas.Size(), 0); for (i = 0; i < outerareas.Size(); i++) outerareas[i] = Area->getModelArea(areas[i]); //prepare for the creation of the aggregator minage = stocks[0]->minAge(); maxage = stocks[0]->maxAge(); IntMatrix agematrix(maxage - minage + 1, 1, 0); for (i = 0; i < agematrix.Nrow(); i++) agematrix[i][0] = i + minage; IntMatrix areamatrix(areas.Size(), 1, 0); for (i = 0; i < areamatrix.Nrow(); i++) areamatrix[i][0] = areas[i]; LgrpDiv = new LengthGroupDivision(*stocks[0]->getLengthGroupDiv()); if (LgrpDiv->Error()) handle.logMessage(LOGFAIL, "Error in stockstdprinter - failed to create length group"); saggregator = new StockAggregator(stocks, LgrpDiv, areamatrix, agematrix); if (stocks[0]->isEaten()) { isaprey = 1; PreyPtrVector preys; preys.resize(stocks[0]->getPrey()); //need to construct length group based on the min/max lengths of the stock double minl, maxl; minl = stocks[0]->getLengthGroupDiv()->minLength(); maxl = stocks[0]->getLengthGroupDiv()->maxLength(); LengthGroupDivision* tmpLgrpDiv = new LengthGroupDivision(minl, maxl, maxl - minl); if (LgrpDiv->Error()) handle.logMessage(LOGFAIL, "Error in stockstdprinter - failed to create length group"); paggregator = new StockPreyAggregator(preys, tmpLgrpDiv, areamatrix, agematrix); //JMB tmpLgrpDiv is no longer needed so delete it to free memory delete tmpLgrpDiv; } } void StockStdPrinter::Print(const TimeClass* const TimeInfo, int printtime) { if ((!AAT.atCurrentTime(TimeInfo)) || (printtime != printtimeid)) return; saggregator->Sum(); salptr = &saggregator->getSum(); if (isaprey) { paggregator->Sum(); palptr = &paggregator->getSum(); } int a, age; for (a = 0; a < outerareas.Size(); a++) { for (age = (*salptr)[a].minAge(); age <= (*salptr)[a].maxAge(); age++) { outfile << setw(lowwidth) << TimeInfo->getYear() << sep << setw(lowwidth) << TimeInfo->getStep() << sep << setw(lowwidth) << outerareas[a] << sep << setw(lowwidth) << age + minage << sep; ps.calcStatistics((*salptr)[a][age], LgrpDiv); //JMB crude filters to remove the 'silly' values from the output if (ps.totalNumber() < rathersmall) { outfile << setw(width) << 0 << sep << setw(printwidth) << 0 << sep << setw(printwidth) << 0 << sep << setw(printwidth) << 0 << sep << setw(width) << 0 << sep << setw(width) << 0 << endl; } else { outfile << setprecision(precision) << setw(width) << ps.totalNumber() * scale << sep << setprecision(printprecision) << setw(printwidth) << ps.meanLength() << sep << setprecision(printprecision) << setw(printwidth) << ps.meanWeight() << sep << setprecision(printprecision) << setw(printwidth) << ps.sdevLength() << sep; if (isaprey) { //JMB crude filter to remove the 'silly' values from the output if (((*palptr)[a][age][0].N < rathersmall) || ((*palptr)[a][age][0].W < 0.0)) outfile << setw(width) << 0 << sep << setw(width) << 0 << endl; else outfile << setprecision(precision) << setw(width) << (*palptr)[a][age][0].N << sep << setprecision(precision) << setw(width) << (*palptr)[a][age][0].W * (*palptr)[a][age][0].N << endl; } else outfile << setw(width) << 0 << sep << setw(width) << 0 << endl; } } } outfile.flush(); }