#include "surveyindices.h" #include "readfunc.h" #include "readword.h" #include "readaggregation.h" #include "areatime.h" #include "errorhandler.h" #include "stock.h" #include "sibylengthonstep.h" #include "sibyageonstep.h" #include "sibyfleetonstep.h" #include "sibyeffortonstep.h" #include "sibyacousticonstep.h" #include "gadget.h" #include "global.h" SurveyIndices::SurveyIndices(CommentStream& infile, const AreaClass* const Area, const TimeClass* const TimeInfo, double weight, const char* name) : Likelihood(SURVEYINDICESLIKELIHOOD, weight, name) { char text[MaxStrLength]; strncpy(text, "", MaxStrLength); int i, j, biomass; IntMatrix ages; DoubleVector lengths; CharPtrVector charindex, areaindex; char datafilename[MaxStrLength]; char aggfilename[MaxStrLength]; char sitype[MaxStrLength]; strncpy(datafilename, "", MaxStrLength); strncpy(aggfilename, "", MaxStrLength); strncpy(sitype, "", MaxStrLength); ifstream datafile; CommentStream subdata(datafile); readWordAndValue(infile, "datafile", datafilename); readWordAndValue(infile, "sitype", sitype); //JMB - added the optional reading of the biomass flag infile >> ws; char c = infile.peek(); biomass = 0; if ((c == 'b') || (c == 'B')) readWordAndVariable(infile, "biomass", biomass); if (biomass != 0 && biomass != 1) handle.logFileMessage(LOGFAIL, "\nError in surveyindex - biomass must be 0 or 1"); //read in area aggregation from file readWordAndValue(infile, "areaaggfile", aggfilename); datafile.open(aggfilename, ios::in); handle.checkIfFailure(datafile, aggfilename); handle.Open(aggfilename); i = readAggregation(subdata, areas, areaindex); handle.Close(); datafile.close(); datafile.clear(); //Must change from outer areas to inner areas. for (i = 0; i < areas.Nrow(); i++) for (j = 0; j < areas.Ncol(i); j++) areas[i][j] = Area->getInnerArea(areas[i][j]); if ((strcasecmp(sitype, "lengths") == 0) || (strcasecmp(sitype, "length") == 0)) { readWordAndValue(infile, "lenaggfile", aggfilename); datafile.open(aggfilename, ios::in); handle.checkIfFailure(datafile, aggfilename); handle.Open(aggfilename); i = readLengthAggregation(subdata, lengths, charindex); handle.Close(); datafile.close(); datafile.clear(); //read the word 'stocknames' infile >> text >> ws; } else if ((strcasecmp(sitype, "ages") == 0) || (strcasecmp(sitype, "age") == 0)) { readWordAndValue(infile, "ageaggfile", aggfilename); datafile.open(aggfilename, ios::in); handle.checkIfFailure(datafile, aggfilename); handle.Open(aggfilename); i = readAggregation(subdata, ages, charindex); handle.Close(); datafile.close(); datafile.clear(); //read the word 'stocknames' infile >> text >> ws; } else if ((strcasecmp(sitype, "fleets") == 0) || (strcasecmp(sitype, "fleet") == 0)) { readWordAndValue(infile, "lenaggfile", aggfilename); datafile.open(aggfilename, ios::in); handle.checkIfFailure(datafile, aggfilename); handle.Open(aggfilename); i = readLengthAggregation(subdata, lengths, charindex); handle.Close(); datafile.close(); datafile.clear(); //read in the fleetnames i = 0; infile >> text >> ws; if (strcasecmp(text, "fleetnames") != 0) handle.logFileUnexpected(LOGFAIL, "fleetnames", text); infile >> text; while (!infile.eof() && (strcasecmp(text, "stocknames") != 0)) { fleetnames.resize(new char[strlen(text) + 1]); strcpy(fleetnames[i++], text); infile >> text >> ws; } if (fleetnames.Size() == 0) handle.logFileMessage(LOGFAIL, "\nError in surveyindex - failed to read fleets"); handle.logMessage(LOGMESSAGE, "Read fleet data - number of fleets", fleetnames.Size()); } else if ((strcasecmp(sitype, "effort") == 0) || (strcasecmp(sitype, "cpue") == 0)) { //read in the fleetnames i = 0; infile >> text >> ws; if (strcasecmp(text, "fleetnames") != 0) handle.logFileUnexpected(LOGFAIL, "fleetnames", text); infile >> text; while (!infile.eof() && (strcasecmp(text, "stocknames") != 0)) { fleetnames.resize(new char[strlen(text) + 1]); strcpy(fleetnames[i++], text); infile >> text >> ws; } if (fleetnames.Size() == 0) handle.logFileMessage(LOGFAIL, "\nError in surveyindex - failed to read fleets"); handle.logMessage(LOGMESSAGE, "Read fleet data - number of fleets", fleetnames.Size()); if (biomass) //JMB the biomass flag is probably not needed for effort index handle.logMessage(LOGWARN, "Warning in surveyindex - biomass flag specified for effort index"); } else if (strcasecmp(sitype, "acoustic") == 0) { //read in the fleetnames i = 0; infile >> text >> ws; if (strcasecmp(text, "surveynames") != 0) handle.logFileUnexpected(LOGFAIL, "surveynames", text); infile >> text; while (!infile.eof() && (strcasecmp(text, "stocknames") != 0)) { charindex.resize(new char[strlen(text) + 1]); strcpy(charindex[i++], text); infile >> text >> ws; } if (charindex.Size() == 0) handle.logFileMessage(LOGFAIL, "\nError in surveyindex - failed to read acoustic survey names"); handle.logMessage(LOGMESSAGE, "Read acoustic survey data - number of survey names", charindex.Size()); if (biomass) //JMB the biomass flag is probably not needed for acoustic index handle.logMessage(LOGWARN, "Warning in surveyindex - biomass flag specified for acoustic index"); } else if (strcasecmp(sitype, "ageandlengths") == 0) { handle.logFileMessage(LOGFAIL, "\nThe ageandlengths surveyindex likelihood component is no longer supported\nUse the surveydistribution likelihood component instead"); } else handle.logFileMessage(LOGFAIL, "\nError in surveyindex - unrecognised type", sitype); if (strcasecmp(text, "stocknames") != 0) handle.logFileUnexpected(LOGFAIL, "stocknames", text); i = 0; infile >> text; //read in the stocknames while (!infile.eof() && (strcasecmp(text, "fittype") != 0)) { stocknames.resize(new char[strlen(text) + 1]); strcpy(stocknames[i++], text); infile >> text >> ws; } if (stocknames.Size() == 0) handle.logFileMessage(LOGFAIL, "\nError in surveyindex - failed to read stocks"); handle.logMessage(LOGMESSAGE, "Read stock data - number of stocks", stocknames.Size()); //We have now read in all the data from the main likelihood file if ((strcasecmp(sitype, "lengths") == 0) || (strcasecmp(sitype, "length") == 0)) { SI = new SIByLengthOnStep(infile, areas, lengths, areaindex, charindex, TimeInfo, datafilename, this->getName(), biomass); } else if ((strcasecmp(sitype, "ages") == 0) || (strcasecmp(sitype, "age") == 0)) { SI = new SIByAgeOnStep(infile, areas, ages, areaindex, charindex, TimeInfo, datafilename, this->getName(), biomass); } else if ((strcasecmp(sitype, "fleets") == 0) || (strcasecmp(sitype, "fleet") == 0)) { SI = new SIByFleetOnStep(infile, areas, lengths, areaindex, charindex, TimeInfo, datafilename, this->getName(), biomass); } else if ((strcasecmp(sitype, "effort") == 0) || (strcasecmp(sitype, "cpue") == 0)) { SI = new SIByEffortOnStep(infile, areas, areaindex, fleetnames, TimeInfo, datafilename, this->getName(), biomass); } else if (strcasecmp(sitype, "acoustic") == 0) { SI = new SIByAcousticOnStep(infile, areas, areaindex, charindex, TimeInfo, datafilename, this->getName(), biomass); } else handle.logFileMessage(LOGFAIL, "\nError in surveyindex - unrecognised type", sitype); //delete objects that are no longer needed to free memory for (i = 0; i < charindex.Size(); i++) delete[] charindex[i]; for (i = 0; i < areaindex.Size(); i++) delete[] areaindex[i]; //prepare for next likelihood component infile >> ws; if (!infile.eof()) { infile >> text >> ws; if (strcasecmp(text, "[component]") != 0) handle.logFileUnexpected(LOGFAIL, "[component]", text); } } SurveyIndices::~SurveyIndices() { int i; for (i = 0; i < stocknames.Size(); i++) delete[] stocknames[i]; for (i = 0; i < fleetnames.Size(); i++) delete[] fleetnames[i]; delete SI; } void SurveyIndices::addLikelihood(const TimeClass* const TimeInfo) { SI->Sum(TimeInfo); if (TimeInfo->getTime() == TimeInfo->numTotalSteps()) likelihood += SI->calcSSE(); } void SurveyIndices::setFleetsAndStocks(FleetPtrVector& Fleets, StockPtrVector& Stocks) { int i, j, k, found; FleetPtrVector f; StockPtrVector s; for (i = 0; i < fleetnames.Size(); i++) { found = 0; for (j = 0; j < Fleets.Size(); j++) { if (strcasecmp(fleetnames[i], Fleets[j]->getName()) == 0) { found++; f.resize(Fleets[j]); } } if (found == 0) handle.logMessage(LOGFAIL, "Error in surveyindex - failed to match fleet", fleetnames[i]); } for (i = 0; i < f.Size(); i++) for (j = 0; j < f.Size(); j++) if ((strcasecmp(f[i]->getName(), f[j]->getName()) == 0) && (i != j)) handle.logMessage(LOGFAIL, "Error in surveyindex - repeated fleet", f[i]->getName()); for (i = 0; i < stocknames.Size(); i++) { found = 0; for (j = 0; j < Stocks.Size(); j++) { if (strcasecmp(stocknames[i], Stocks[j]->getName()) == 0) { found++; s.resize(Stocks[j]); } } if (found == 0) handle.logMessage(LOGFAIL, "Error in surveyindex - failed to match stock", stocknames[i]); } for (i = 0; i < s.Size(); i++) for (j = 0; j < s.Size(); j++) if ((strcasecmp(s[i]->getName(), s[j]->getName()) == 0) && (i != j)) handle.logMessage(LOGFAIL, "Error in surveyindex - repeated stock", s[i]->getName()); //check fleet and stock areas if (handle.getLogLevel() >= LOGWARN) { if (fleetnames.Size() > 0) { //JMB might not be any fleets for (j = 0; j < areas.Nrow(); j++) { found = 0; for (i = 0; i < f.Size(); i++) for (k = 0; k < areas.Ncol(j); k++) if (f[i]->isInArea(areas[j][k])) found++; if (found == 0) handle.logMessage(LOGWARN, "Warning in surveyindex - fleet not defined on all areas"); } } for (j = 0; j < areas.Nrow(); j++) { found = 0; for (i = 0; i < s.Size(); i++) for (k = 0; k < areas.Ncol(j); k++) if (s[i]->isInArea(areas[j][k])) found++; if (found == 0) handle.logMessage(LOGWARN, "Warning in surveyindex - stock not defined on all areas"); } } SI->setFleetsAndStocks(f, s); } void SurveyIndices::Reset(const Keeper* const keeper) { Likelihood::Reset(keeper); SI->Reset(); if (handle.getLogLevel() >= LOGMESSAGE) handle.logMessage(LOGMESSAGE, "Reset surveyindex component", this->getName()); } void SurveyIndices::Print(ofstream& outfile) const { int i; outfile << "\nSurvey Indices " << this->getName() << " - likelihood value " << likelihood; if (stocknames.Size() > 0) { outfile << "\n\tStock names: "; for (i = 0; i < stocknames.Size(); i++) outfile << stocknames[i] << sep; } if (fleetnames.Size() > 0) { outfile << "\n\tFleet names: "; for (i = 0; i < fleetnames.Size(); i++) outfile << fleetnames[i] << sep; } outfile << endl; SI->Print(outfile); outfile.flush(); }