Log In | Get Help   
Home My Page Projects Code Snippets Project Openings Mareframe
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files
[mareframe] View of /trunk/gadget/maturity.cc
[mareframe] / trunk / gadget / maturity.cc Repository:
ViewVC logotype

View of /trunk/gadget/maturity.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (download) (annotate)
Mon Feb 10 17:09:07 2014 UTC (10 years, 3 months ago) by agomez
File size: 24540 byte(s)
Initial version based on Gadget 2.2.00
#include "maturity.h"
#include "stock.h"
#include "mathfunc.h"
#include "readfunc.h"
#include "readword.h"
#include "conversionindex.h"
#include "errorhandler.h"
#include "gadget.h"
#include "global.h"

// ********************************************************
// Functions for base Maturity
// ********************************************************
Maturity::Maturity(const IntVector& tmpareas, int minage, int numage,
  const LengthGroupDivision* const lgrpdiv, const char* givenname)
  : HasName(givenname), LivesOnAreas(tmpareas) {

  int i;
  istagged = 0;
  tmpratio = 1.0;
  ratioscale = 1.0; //JMB used to scale the ratios to ensure that they sum to 1
  LgrpDiv = new LengthGroupDivision(*lgrpdiv);
  if (LgrpDiv->Error())
    handle.logMessage(LOGFAIL, "Error in maturity - failed to create length group");

  IntVector lower(numage, 0);
  IntVector agesize(numage, LgrpDiv->numLengthGroups());
  Storage.resize(areas.Size(), minage, lower, agesize);
  for (i = 0; i < Storage.Size(); i++)
    Storage[i].setToZero();
}

Maturity::~Maturity() {
  int i;
  for (i = 0; i < matureStockNames.Size(); i++)
    delete[] matureStockNames[i];
  for (i = 0; i < CI.Size(); i++)
    delete CI[i];
  delete LgrpDiv;
}

void Maturity::setStock(StockPtrVector& stockvec) {
  int i, j, index;

  for (i = 0; i < matureStockNames.Size(); i++)
    for (j = 0; j < matureStockNames.Size(); j++)
      if ((strcasecmp(matureStockNames[i], matureStockNames[j]) == 0) && (i != j))
        handle.logMessage(LOGFAIL, "Error in maturity - repeated stock", matureStockNames[i]);

  for (i = 0; i < stockvec.Size(); i++)
    for (j = 0; j < matureStockNames.Size(); j++)
      if (strcasecmp(stockvec[i]->getName(), matureStockNames[j]) == 0)
        matureStocks.resize(stockvec[i]);

  if (matureStocks.Size() != matureStockNames.Size()) {
    handle.logMessage(LOGWARN, "Error in maturity - failed to match mature stocks");
    for (i = 0; i < stockvec.Size(); i++)
      handle.logMessage(LOGWARN, "Error in maturity - found stock", stockvec[i]->getName());
    for (i = 0; i < matureStockNames.Size(); i++)
      handle.logMessage(LOGWARN, "Error in maturity - looking for stock", matureStockNames[i]);
    handle.logMessage(LOGFAIL, ""); //JMB this will exit gadget
  }

  //JMB ensure that the ratio vector is indexed in the right order
  ratioindex.resize(matureStocks.Size(), 0);
  for (i = 0; i < matureStocks.Size(); i++)
    for (j = 0; j < matureStockNames.Size(); j++)
      if (strcasecmp(matureStocks[i]->getName(), matureStockNames[j]) == 0)
        ratioindex[i] = j;

  for (i = 0; i < matureStocks.Size(); i++) {
    CI.resize(new ConversionIndex(LgrpDiv, matureStocks[i]->getLengthGroupDiv()));
    if (CI[i]->Error())
      handle.logMessage(LOGFAIL, "Error in maturity - error when checking length structure");

    index = 0;
    for (j = 0; j < areas.Size(); j++)
      if (!matureStocks[i]->isInArea(areas[j]))
        index++;

    if (index != 0)
      handle.logMessage(LOGWARN, "Warning in maturity - mature stock isnt defined on all areas");
  }
}

void Maturity::Print(ofstream& outfile) const {
  int i;
  outfile << "\nMaturity\n\tNames of mature stocks:";
   for (i = 0; i < matureStockNames.Size(); i++)
    outfile << sep << matureStockNames[i];
  outfile << "\n\tRatio maturing into each stock:";
  for (i = 0; i < matureRatio.Size(); i++)
    outfile << sep << (matureRatio[ratioindex[i]] * ratioscale);
  outfile << "\n\tStored numbers:\n";
  for (i = 0; i < areas.Size(); i++) {
    outfile << "\tInternal area " << areas[i] << endl;
    Storage[i].printNumbers(outfile);
  }
}

void Maturity::Reset(const TimeClass* const TimeInfo) {
  //JMB check that the sum of the ratios is 1
  if (TimeInfo->getTime() == 1) {
    int i;
    ratioscale = 0.0;
    for (i = 0; i < matureRatio.Size(); i++ )
      ratioscale += matureRatio[i];

    if (isZero(ratioscale)) {
      handle.logMessage(LOGWARN, "Warning in maturity - specified ratios are zero");
      ratioscale = 1.0;
    } else if (isEqual(ratioscale, 1.0)) {
      // do nothing
    } else {
      handle.logMessage(LOGWARN, "Warning in maturity - scaling ratios using", ratioscale);
      ratioscale = 1.0 / ratioscale;
    }
  }
}

void Maturity::Move(int area, const TimeClass* const TimeInfo) {
  if (!(this->isMaturationStep(TimeInfo)))
    handle.logMessage(LOGFAIL, "Error in maturity - maturity requested on wrong timestep");
  int i, inarea = this->areaNum(area);
  for (i = 0; i < matureStocks.Size(); i++) {
    if (!matureStocks[i]->isInArea(area))
      handle.logMessage(LOGFAIL, "Error in maturity - mature stock doesnt live on area", area);

    tmpratio = matureRatio[ratioindex[i]] * ratioscale;
    matureStocks[i]->Add(Storage[inarea], CI[i], area, tmpratio);
    if (istagged && tagStorage.numTagExperiments() > 0)
      matureStocks[i]->Add(tagStorage, CI[i], area, tmpratio);
  }

  Storage[inarea].setToZero();
  if (istagged && tagStorage.numTagExperiments() > 0)
    tagStorage[inarea].setToZero();
}

void Maturity::storeMatureStock(int area, int age, int length, double number, double weight) {
  if (isZero(number) || isZero(weight)) {
    Storage[this->areaNum(area)][age][length].setToZero();
  } else {
    Storage[this->areaNum(area)][age][length].N = number;
    Storage[this->areaNum(area)][age][length].W = weight;
  }
}

void Maturity::storeMatureTagStock(int area, int age, int length, double number, int id) {
  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in maturity - invalid tagging experiment");
  if ((id >= tagStorage.numTagExperiments()) || (id < 0))
    handle.logMessage(LOGFAIL, "Error in maturity - invalid tagging experiment");
  if (isZero(number))
    *(tagStorage[this->areaNum(area)][age][length][id].N) = 0.0;
  else
    *(tagStorage[this->areaNum(area)][age][length][id].N) = number;
}

const StockPtrVector& Maturity::getMatureStocks() {
  return matureStocks;
}

void Maturity::setTagged() {
  istagged = 1;
  //resize tagStorage to be the same size as Storage
  int i, minage, maxage;
  minage = Storage[0].minAge();
  maxage = Storage[0].maxAge();
  IntVector lower(maxage - minage + 1, 0);
  IntVector size(maxage - minage + 1, LgrpDiv->numLengthGroups());
  tagStorage.resize(areas.Size(), minage, lower, size);
  for (i = 0; i < tagStorage.Size(); i++)
    tagStorage[i].setToZero();
}

void Maturity::addMaturityTag(const char* tagname) {
  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in maturity - invalid tagging experiment", tagname);
  tagStorage.addTag(tagname);
}

void Maturity::deleteMaturityTag(const char* tagname) {
  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in maturity - invalid tagging experiment", tagname);

  int minage, maxage, age, len, a;
  int id = tagStorage.getTagID(tagname);

  if (id >= 0) {
    minage = tagStorage[0].minAge();
    maxage = tagStorage[0].maxAge();
    //free memory allocated for tagging experiment
    for (a = 0; a < tagStorage.Size(); a++) {
      for (age = minage; age <= maxage; age++) {
        for (len = tagStorage[a].minLength(age); len < tagStorage[a].maxLength(age); len++) {
          delete[] (tagStorage[a][age][len][id].N);
          (tagStorage[a][age][len][id].N) = NULL;
        }
      }
    }
    tagStorage.deleteTag(tagname);

  } else
    handle.logMessage(LOGWARN, "Warning in maturity - failed to delete tagging experiment", tagname);
}

// ********************************************************
// Functions for MaturityA
// ********************************************************
MaturityA::MaturityA(CommentStream& infile, const TimeClass* const TimeInfo,
  Keeper* const keeper, int minage, int numage, const IntVector& tmpareas,
  const char* givenname, const LengthGroupDivision* const lgrpdiv)
  : Maturity(tmpareas, minage, numage, lgrpdiv, givenname), minStockAge(minage) {

  //JMB store the length of the timestep
  timesteplength = TimeInfo->getTimeStepSize();

  char text[MaxStrLength];
  strncpy(text, "", MaxStrLength);
  int i;

  keeper->addString("maturity");
  infile >> text >> ws;
  if ((strcasecmp(text, "nameofmaturestocksandratio") != 0) && (strcasecmp(text, "maturestocksandratios") != 0))
    handle.logFileUnexpected(LOGFAIL, "maturestocksandratios", text);

  i = 0;
  infile >> text >> ws;
  while (strcasecmp(text, "coefficients") != 0 && !infile.eof()) {
    matureStockNames.resize(new char[strlen(text) + 1]);
    strcpy(matureStockNames[i], text);
    matureRatio.resize(1, keeper);
    if (!(infile >> matureRatio[i]))
      handle.logFileMessage(LOGFAIL, "invalid format for mature ratio");
    matureRatio[i].Inform(keeper);

    infile >> text >> ws;
    i++;
  }

  if (infile.eof())
    handle.logFileEOFMessage(LOGFAIL);
  maturityParameters.resize(4, keeper);
  maturityParameters.read(infile, TimeInfo, keeper);
  preCalcMaturation.AddRows(numage, LgrpDiv->numLengthGroups(), 0.0);

  infile >> ws;
  if (!infile.eof()) {
    infile >> text >> ws;
    handle.logFileUnexpected(LOGFAIL, "<end of file>", text);
  }
  handle.logMessage(LOGMESSAGE, "Read maturity data file");
  keeper->clearLast();
}

void MaturityA::Reset(const TimeClass* const TimeInfo) {
  Maturity::Reset(TimeInfo);

  if (TimeInfo->didStepSizeChange())
    timesteplength = TimeInfo->getTimeStepSize();

  maturityParameters.Update(TimeInfo);
  if (maturityParameters.didChange(TimeInfo)) {
    if (maturityParameters[1] < LgrpDiv->minLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 less than minimum length for stock", this->getName());
    if (maturityParameters[1] > LgrpDiv->maxLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 greater than maximum length for stock", this->getName());

    int age, len;
    for (age = 0; age < preCalcMaturation.Nrow(); age++) {
      for (len = 0; len < LgrpDiv->numLengthGroups(); len++) {
        tmpratio = exp(-maturityParameters[0] * (LgrpDiv->meanLength(len) - maturityParameters[1]) -
             maturityParameters[2] * (age + minStockAge - maturityParameters[3]));
        preCalcMaturation[age][len] = 1.0 / (1.0 + tmpratio);
      }
    }

    if (handle.getLogLevel() >= LOGMESSAGE)
      handle.logMessage(LOGMESSAGE, "Reset maturity data for stock", this->getName());
  }
}

void MaturityA::setStock(StockPtrVector& stockvec) {
  Maturity::setStock(stockvec);

  int i;
  minMatureAge = 9999;
  double minlength = 9999.0;
  for (i = 0; i < matureStocks.Size(); i++) {
    minMatureAge = min(matureStocks[i]->minAge(), minMatureAge);
    minlength = min(matureStocks[i]->getLengthGroupDiv()->minLength(), minlength);
  }
  minMatureLength = LgrpDiv->numLengthGroup(minlength);
  if (minMatureAge < minStockAge)
    handle.logMessage(LOGFAIL, "Error in maturity - minimum mature age is less than stock age for stock", this->getName());
}

double MaturityA::calcMaturation(int age, int length, int growth, double weight) {

  if ((age >= minMatureAge) && ((length + growth) >= minMatureLength)) {
    tmpratio = preCalcMaturation[age - minStockAge][length] *
       (maturityParameters[0] * growth * LgrpDiv->dl() + maturityParameters[2] * timesteplength);
    return (min(max(0.0, tmpratio), 1.0));
  }
  return 0.0;
}

void MaturityA::Print(ofstream& outfile) const {
  Maturity::Print(outfile);
  outfile << "\tPrecalculated maturity:\n";
  preCalcMaturation.Print(outfile);
}

int MaturityA::isMaturationStep(const TimeClass* const TimeInfo) {
  return 1;
}

// ********************************************************
// Functions for MaturityB
// ********************************************************
MaturityB::MaturityB(CommentStream& infile, const TimeClass* const TimeInfo,
  Keeper* const keeper, int minage, int numage, const IntVector& tmpareas,
  const char* givenname, const LengthGroupDivision* const lgrpdiv)
  : Maturity(tmpareas, minage, numage, lgrpdiv, givenname) {

  //JMB set the default value for currenttimestep
  currentmaturitystep = 0;

  char text[MaxStrLength];
  strncpy(text, "", MaxStrLength);
  int i, tmpint = 0;

  keeper->addString("maturity");
  infile >> text >> ws;
  if ((strcasecmp(text, "nameofmaturestocksandratio") != 0) && (strcasecmp(text, "maturestocksandratios") != 0))
    handle.logFileUnexpected(LOGFAIL, "maturestocksandratios", text);

  i = 0;
  infile >> text >> ws;
  while (strcasecmp(text, "maturitysteps") != 0 && !infile.eof()) {
    matureStockNames.resize(new char[strlen(text) + 1]);
    strcpy(matureStockNames[i], text);
    matureRatio.resize(1, keeper);
    if (!(infile >> matureRatio[i]))
      handle.logFileMessage(LOGFAIL, "invalid format for mature ratio");
    matureRatio[i].Inform(keeper);

    infile >> text >> ws;
    i++;
  }

  if (infile.eof())
    handle.logFileEOFMessage(LOGFAIL);

  infile >> ws;
  while (isdigit(infile.peek()) && !infile.eof()) {
    infile >> tmpint >> ws;
    maturitystep.resize(1, tmpint);
  }
  if (infile.eof())
    handle.logFileEOFMessage(LOGFAIL);

  i = 0;
  infile >> text;
  if (strcasecmp(text, "maturitylengths") != 0)
    handle.logFileUnexpected(LOGFAIL, "maturitylengths", text);
  while (i < maturitystep.Size() && !infile.eof()) {
    maturitylength.resize(1, keeper);
    maturitylength[i++].read(infile, TimeInfo, keeper);
  }

  for (i = 0; i < maturitystep.Size(); i++)
    if (maturitystep[i] < 1 || maturitystep[i] > TimeInfo->numSteps())
      handle.logFileMessage(LOGFAIL, "invalid maturity step", maturitystep[i]);

  if (maturitylength.Size() != maturitystep.Size())
    handle.logFileMessage(LOGFAIL, "number of maturitysteps does not equal number of maturitylengths");

  infile >> ws;
  if (!infile.eof()) {
    infile >> text >> ws;
    handle.logFileUnexpected(LOGFAIL, "<end of file>", text);
  }
  handle.logMessage(LOGMESSAGE, "Read maturity data file");
  keeper->clearLast();
}

void MaturityB::Print(ofstream& outfile) const {
  int i;
  Maturity::Print(outfile);
  outfile << "\tMaturity timesteps";
  for (i = 0; i < maturitystep.Size(); i++)
    outfile << sep << maturitystep[i];
  outfile << "\n\tMaturity lengths";
  for (i = 0; i < maturitylength.Size(); i++)
    outfile << sep << maturitylength[i];
  outfile << endl;
}

void MaturityB::setStock(StockPtrVector& stockvec) {
  Maturity::setStock(stockvec);
}

void MaturityB::Reset(const TimeClass* const TimeInfo) {
  Maturity::Reset(TimeInfo);

  int i;
  maturitylength.Update(TimeInfo);
  if (maturitylength.didChange(TimeInfo)) {
    for (i = 0; i < maturitylength.Size(); i++) {
      if (maturitylength[i] < LgrpDiv->minLength())
        handle.logMessage(LOGWARN, "Warning in maturity calculation - length less than minimum stock length for stock", this->getName());
      if (maturitylength[i] > LgrpDiv->maxLength())
        handle.logMessage(LOGWARN, "Warning in maturity calculation - length greater than maximum stock length for stock", this->getName());
    }

    if (handle.getLogLevel() >= LOGMESSAGE)
      handle.logMessage(LOGMESSAGE, "Reset maturity data for stock", this->getName());
  }
}

double MaturityB::calcMaturation(int age, int length, int growth, double weight) {
  if ((LgrpDiv->meanLength(length) > maturitylength[currentmaturitystep]) ||
      (isEqual(LgrpDiv->meanLength(length), maturitylength[currentmaturitystep])))
    return 1.0;
  return 0.0;
}

int MaturityB::isMaturationStep(const TimeClass* const TimeInfo) {
  int i;
  for (i = 0; i < maturitystep.Size(); i++) {
    if (maturitystep[i] == TimeInfo->getStep()) {
      currentmaturitystep = i;
      return 1;
    }
  }
  return 0;
}

// ********************************************************
// Functions for MaturityC
// ********************************************************
MaturityC::MaturityC(CommentStream& infile, const TimeClass* const TimeInfo,
  Keeper* const keeper, int minage, int numage, const IntVector& tmpareas,
  const char* givenname, const LengthGroupDivision* const lgrpdiv, int numMatConst)
  : Maturity(tmpareas, minage, numage, lgrpdiv, givenname), minStockAge(minage) {

  char text[MaxStrLength];
  strncpy(text, "", MaxStrLength);
  int i, tmpint = 0;

  keeper->addString("maturity");
  infile >> text >> ws;
  if ((strcasecmp(text, "nameofmaturestocksandratio") != 0) && (strcasecmp(text, "maturestocksandratios") != 0))
    handle.logFileUnexpected(LOGFAIL, "maturestocksandratios", text);

  i = 0;
  infile >> text >> ws;
  while (strcasecmp(text, "coefficients") != 0 && !infile.eof()) {
    matureStockNames.resize(new char[strlen(text) + 1]);
    strcpy(matureStockNames[i], text);
    matureRatio.resize(1, keeper);
    if (!(infile >> matureRatio[i]))
      handle.logFileMessage(LOGFAIL, "invalid format for mature ratio");
    matureRatio[i].Inform(keeper);

    infile >> text >> ws;
    i++;
  }

  if (infile.eof())
    handle.logFileEOFMessage(LOGFAIL);
  maturityParameters.resize(numMatConst, keeper);
  maturityParameters.read(infile, TimeInfo, keeper);
  preCalcMaturation.AddRows(numage, LgrpDiv->numLengthGroups(), 0.0);

  infile >> text >> ws;
  if ((strcasecmp(text, "maturitystep") != 0) && (strcasecmp(text, "maturitysteps") != 0))
    handle.logFileUnexpected(LOGFAIL, "maturitysteps", text);

  while (isdigit(infile.peek()) && !infile.eof()) {
    infile >> tmpint >> ws;
    maturitystep.resize(1, tmpint);
    i++;
  }

  for (i = 0; i < maturitystep.Size(); i++)
    if (maturitystep[i] < 1 || maturitystep[i] > TimeInfo->numSteps())
      handle.logFileMessage(LOGFAIL, "invalid maturity step", maturitystep[i]);

  infile >> ws;
  if (!infile.eof()) {
    infile >> text >> ws;
    handle.logFileUnexpected(LOGFAIL, "<end of file>", text);
  }

  handle.logMessage(LOGMESSAGE, "Read maturity data file");
  keeper->clearLast();
}

void MaturityC::setStock(StockPtrVector& stockvec) {
  Maturity::setStock(stockvec);

  int i;
  minMatureAge = 9999;
  double minlength = 9999.0;
  for (i = 0; i < matureStocks.Size(); i++) {
    minMatureAge = min(matureStocks[i]->minAge(), minMatureAge);
    minlength = min(matureStocks[i]->getLengthGroupDiv()->minLength(), minlength);
  }
  minMatureLength = LgrpDiv->numLengthGroup(minlength);
  if (minMatureAge < minStockAge)
    handle.logMessage(LOGFAIL, "Error in maturity - minimum mature age is less than stock age for stock", this->getName());
}

void MaturityC::Reset(const TimeClass* const TimeInfo) {
  Maturity::Reset(TimeInfo);

  maturityParameters.Update(TimeInfo);
  if (maturityParameters.didChange(TimeInfo)) {
    if (maturityParameters[1] < LgrpDiv->minLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 less than minimum length for stock", this->getName());
    if (maturityParameters[1] > LgrpDiv->maxLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 greater than maximum length for stock", this->getName());

    int age, len;
    for (age = 0; age < preCalcMaturation.Nrow(); age++) {
      for (len = 0; len < LgrpDiv->numLengthGroups(); len++) {
        if ((age + minStockAge >= minMatureAge) && (len >= minMatureLength)) {
          tmpratio = exp(-1.0 * maturityParameters[0] * (LgrpDiv->meanLength(len) - maturityParameters[1])
                 - maturityParameters[2] * (age + minStockAge - maturityParameters[3]));
          preCalcMaturation[age][len] = 1.0 / (1.0 + tmpratio);
          if (preCalcMaturation[age][len] < 0.0)
            preCalcMaturation[age][len] = 0.0;
          if (preCalcMaturation[age][len] > 1.0)
            preCalcMaturation[age][len] = 1.0;

        } else
          preCalcMaturation[age][len] = 0.0;
      }
    }

    if (handle.getLogLevel() >= LOGMESSAGE)
      handle.logMessage(LOGMESSAGE, "Reset maturity data for stock", this->getName());
  }
}

double MaturityC::calcMaturation(int age, int length, int growth, double weight) {
  if (age >= minStockAge)
    return preCalcMaturation[age - minStockAge][length];
  return 0.0;
}

int MaturityC::isMaturationStep(const TimeClass* const TimeInfo) {
  int i;
  for (i = 0; i < maturitystep.Size(); i++)
    if (maturitystep[i] == TimeInfo->getStep())
      return 1;
  return 0;
}

void MaturityC::Print(ofstream& outfile) const {
  int i;
  Maturity::Print(outfile);
  outfile << "\tPrecalculated maturity:\n";
  preCalcMaturation.Print(outfile);
  outfile << "\tMaturity timesteps:";
  for (i = 0; i < maturitystep.Size(); i++)
    outfile << sep << maturitystep[i];
  outfile << endl;
}

// ********************************************************
// Functions for MaturityD
// ********************************************************
MaturityD::MaturityD(CommentStream& infile, const TimeClass* const TimeInfo,
  Keeper* const keeper, int minage, int numage, const IntVector& tmpareas,
  const char* givenname, const LengthGroupDivision* const lgrpdiv, int numMatConst, const char* refWeightFile)
  : MaturityC(infile, TimeInfo, keeper, minage, numage, tmpareas, givenname, lgrpdiv, numMatConst) {

  //read information on reference weights.
  ifstream subweightfile;
  subweightfile.open(refWeightFile, ios::in);
  handle.checkIfFailure(subweightfile, refWeightFile);
  handle.Open(refWeightFile);
  CommentStream subweightcomment(subweightfile);
  DoubleMatrix tmpRefW;
  readRefWeights(subweightcomment, tmpRefW);
  handle.Close();
  subweightfile.close();
  subweightfile.clear();

  //aggregate the reference weight data to be the same length groups
  if (LgrpDiv->meanLength(0) < tmpRefW[0][0] ||
      LgrpDiv->meanLength(LgrpDiv->numLengthGroups() - 1) > tmpRefW[tmpRefW.Nrow() - 1][0])
    handle.logFileMessage(LOGFAIL, "lengths for reference weights must span the range of growth lengths");

  refWeight.resize(LgrpDiv->numLengthGroups(), 0.0);
  int i, j, pos = 0;
  double tmplen;
  for (j = 0; j < LgrpDiv->numLengthGroups(); j++) {
    tmplen = LgrpDiv->meanLength(j);
    for (i = pos; i < tmpRefW.Nrow() - 1; i++) {
      if (((tmplen > tmpRefW[i][0]) || (isEqual(tmplen, tmpRefW[i][0]))) &&
          ((tmplen < tmpRefW[i + 1][0]) || (isEqual(tmplen, tmpRefW[i + 1][0])))) {

        tmpratio = (tmplen - tmpRefW[i][0]) / (tmpRefW[i + 1][0] - tmpRefW[i][0]);
        refWeight[j] = tmpRefW[i][1] + tmpratio * (tmpRefW[i + 1][1] - tmpRefW[i][1]);
        pos = i;
      }
    }
  }
}

void MaturityD::setStock(StockPtrVector& stockvec) {
  Maturity::setStock(stockvec);

  int i;
  minMatureAge = 9999;
  double minlength = 9999.0;
  for (i = 0; i < matureStocks.Size(); i++) {
    minMatureAge = min(matureStocks[i]->minAge(), minMatureAge);
    minlength = min(matureStocks[i]->getLengthGroupDiv()->minLength(), minlength);
  }
  minMatureLength = LgrpDiv->numLengthGroup(minlength);
  if (minMatureAge < minStockAge)
    handle.logMessage(LOGFAIL, "Error in maturity - minimum mature age is less than stock age for stock", this->getName());
}

void MaturityD::Reset(const TimeClass* const TimeInfo) {
  Maturity::Reset(TimeInfo);

  maturityParameters.Update(TimeInfo);
  if (maturityParameters.didChange(TimeInfo)) {
    if (maturityParameters[1] < LgrpDiv->minLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 less than minimum length for stock", this->getName());
    if (maturityParameters[1] > LgrpDiv->maxLength())
      handle.logMessage(LOGWARN, "Warning in maturity calculation - l50 greater than maximum length for stock", this->getName());

   if (handle.getLogLevel() >= LOGMESSAGE)
      handle.logMessage(LOGMESSAGE, "Reset maturity data for stock", this->getName());
  }
}

double MaturityD::calcMaturation(int age, int length, int growth, double weight) {

  if ((age >= minMatureAge) && (length >= minMatureLength)) {
    double tmpweight, my;

    if ((length >= refWeight.Size()) || (isZero(refWeight[length])))
      tmpweight = maturityParameters[5];
    else
      tmpweight = weight / refWeight[length];

    my = exp(-1.0 * maturityParameters[0] * (LgrpDiv->meanLength(length) - maturityParameters[1])
           - maturityParameters[2] * (age + minStockAge - maturityParameters[3])
           - maturityParameters[4] * (tmpweight - maturityParameters[5]));
    tmpratio = 1.0 / (1.0 + my);
    return (min(max(0.0, tmpratio), 1.0));
  }
  return 0.0;
}

int MaturityD::isMaturationStep(const TimeClass* const TimeInfo) {
  int i;
  for (i = 0; i < maturitystep.Size(); i++)
    if (maturitystep[i] == TimeInfo->getStep())
      return 1;
  return 0;
}

void MaturityD::Print(ofstream& outfile) const {
  int i;
  Maturity::Print(outfile);
  outfile << "\tMaturity timesteps:";
  for (i = 0; i < maturitystep.Size(); i++)
    outfile << sep << maturitystep[i];
  outfile << endl;
}

root@forge.cesga.es
ViewVC Help
Powered by ViewVC 1.0.0  

Powered By FusionForge