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/stray.cc
[mareframe] / trunk / gadget / stray.cc Repository:
ViewVC logotype

View of /trunk/gadget/stray.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (download) (annotate)
Mon Feb 10 17:09:07 2014 UTC (10 years, 4 months ago) by agomez
File size: 12284 byte(s)
Initial version based on Gadget 2.2.00
#include "stray.h"
#include "errorhandler.h"
#include "keeper.h"
#include "areatime.h"
#include "mathfunc.h"
#include "readfunc.h"
#include "readword.h"
#include "readaggregation.h"
#include "gadget.h"
#include "global.h"

StrayData::StrayData(CommentStream& infile, const LengthGroupDivision* const lgrpdiv,
  const IntVector& areas, const AreaClass* const Area, const char* givenname,
  const TimeClass* const TimeInfo, Keeper* const keeper) : HasName(givenname), LivesOnAreas(areas) {

  keeper->addString("stray");
  int i, tmpint = 0;
  istagged = 0;
  ratioscale = 1.0; //JMB used to scale the ratios to ensure that they sum to 1

  char text[MaxStrLength];
  strncpy(text, "", MaxStrLength);
  ifstream datafile;
  CommentStream subdata(datafile);

  LgrpDiv = new LengthGroupDivision(*lgrpdiv);
  if (LgrpDiv->Error())
    handle.logMessage(LOGFAIL, "Error in straying data - failed to create length group");
  strayProportion.resize(LgrpDiv->numLengthGroups(), 0.0);

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

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

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

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

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

  for (i = 0; i < strayArea.Size(); i++)
    strayArea[i] = Area->getInnerArea(strayArea[i]);

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

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

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

  if (infile.eof())
    handle.logFileEOFMessage(LOGFAIL);
  if (strcasecmp(text, "proportionfunction") != 0)
    handle.logFileUnexpected(LOGFAIL, "proportionfunction", text);

  infile >> text >> ws;
  if (strcasecmp(text, "constant") == 0)
    fnProportion = new ConstSelectFunc();
  else if (strcasecmp(text, "straightline") == 0)
    fnProportion = new StraightSelectFunc();
  else if (strcasecmp(text, "exponential") == 0)
    fnProportion = new ExpSelectFunc();
  else
    handle.logFileMessage(LOGFAIL, "unrecognised proportion function", text);

  fnProportion->readConstants(infile, TimeInfo, keeper);

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

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

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

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

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

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

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

  //JMB check that the straying stocks are defined on all the areas
  int minStrayAge = 9999;
  int maxStrayAge = 0;
  double minlength = 9999.0;
  for (i = 0; i < strayStocks.Size(); i++) {
    CI.resize(new ConversionIndex(LgrpDiv, strayStocks[i]->getLengthGroupDiv()));
    if (CI[i]->Error())
      handle.logMessage(LOGFAIL, "Error in straying data - error when checking length structure");
    index = 0;
    for (j = 0; j < strayArea.Size(); j++)
      if (!strayStocks[i]->isInArea(strayArea[j]))
        index++;

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

    minStrayAge = min(strayStocks[i]->minAge(), minStrayAge);
    maxStrayAge = max(strayStocks[i]->maxAge(), maxStrayAge);
    minlength = min(strayStocks[i]->getLengthGroupDiv()->minLength(), minlength);
  }

  minStrayLength = LgrpDiv->numLengthGroup(minlength);
  IntVector minlv(maxStrayAge - minStrayAge + 1, 0);
  IntVector sizev(maxStrayAge - minStrayAge + 1, LgrpDiv->numLengthGroups());
  Storage.resize(areas.Size(), minStrayAge, minlv, sizev);
  for (i = 0; i < Storage.Size(); i++)
    Storage[i].setToZero();
}

void StrayData::storeStrayingStock(int area, AgeBandMatrix& Alkeys, const TimeClass* const TimeInfo) {

  int age, len;
  int inarea = this->areaNum(area);
  double straynumber;

  for (age = Storage[inarea].minAge(); age < Storage[inarea].maxAge(); age++) {
    for (len = Storage[inarea].minLength(age); len < Storage[inarea].maxLength(age); len++) {
      straynumber = Alkeys[age][len].N * strayProportion[len];
      Storage[inarea][age][len].N = straynumber;
      Storage[inarea][age][len].W = Alkeys[age][len].W;

      if (len >= minStrayLength)
        Alkeys[age][len].N -= straynumber;
    }
  }
}

void StrayData::storeStrayingStock(int area, AgeBandMatrix& Alkeys,
  AgeBandMatrixRatio& TagAlkeys, const TimeClass* const TimeInfo) {

  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in stray - invalid tagging experiment");

  int age, len, tag;
  int inarea = this->areaNum(area);
  double straynumber;

  for (age = Storage[inarea].minAge(); age < Storage[inarea].maxAge(); age++) {
    for (len = Storage[inarea].minLength(age); len < Storage[inarea].maxLength(age); len++) {
      straynumber = Alkeys[age][len].N * strayProportion[len];
      Storage[inarea][age][len].N = straynumber;
      Storage[inarea][age][len].W = Alkeys[age][len].W;

      if (len >= minStrayLength)
        Alkeys[age][len].N -= straynumber;

      for (tag = 0; tag < TagAlkeys.numTagExperiments(); tag++) {
        straynumber = *(TagAlkeys[age][len][tag].N) * strayProportion[len];
        if (straynumber < verysmall)
          *(tagStorage[inarea][age][len][tag].N) = 0.0;
        else
          *(tagStorage[inarea][age][len][tag].N) = straynumber;

        if (len >= minStrayLength)
          *(TagAlkeys[age][len][tag].N) -= straynumber;
      }
    }
  }
}

void StrayData::addStrayStock(int area, const TimeClass* const TimeInfo) {

  int i, inarea = this->areaNum(area);
  double ratio;
  for (i = 0; i < strayStocks.Size(); i++) {
    if (!strayStocks[i]->isInArea(area))
      handle.logMessage(LOGFAIL, "Error in straying - stray stock doesnt live on area", area);

    if (strayStocks[i]->isBirthday(TimeInfo)) {
      Storage[inarea].IncrementAge();
      if (istagged && tagStorage.numTagExperiments() > 0)
        tagStorage[inarea].IncrementAge(Storage[inarea]);
    }

    ratio = strayRatio[ratioindex[i]] * ratioscale;
    strayStocks[i]->Add(Storage[inarea], CI[i], area, ratio);
    if (istagged && tagStorage.numTagExperiments() > 0)
      strayStocks[i]->Add(tagStorage, CI[i], area, ratio);
  }
  Storage[inarea].setToZero();
  if (istagged && tagStorage.numTagExperiments() > 0)
    tagStorage[inarea].setToZero();
}

int StrayData::isStrayStepArea(int area, const TimeClass* const TimeInfo) {
  int i, j;

  for (i = 0; i < strayStep.Size(); i++)
    for (j = 0; j < strayArea.Size(); j++)
      if ((strayStep[i] == TimeInfo->getStep()) && (strayArea[j] == area))
        return 1;
  return 0;
}

void StrayData::Reset(const TimeClass* const TimeInfo) {
  int i;

  //JMB check that the sum of the ratios is 1
  if (TimeInfo->getTime() == 1) {
    ratioscale = 0.0;
    for (i = 0; i < strayRatio.Size(); i++ )
      ratioscale += strayRatio[i];

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

  fnProportion->updateConstants(TimeInfo);
  if (fnProportion->didChange(TimeInfo)) {
    for (i = 0; i < LgrpDiv->numLengthGroups(); i++) {
      strayProportion[i] = fnProportion->calculate(LgrpDiv->meanLength(i));
      if (strayProportion[i] < 0.0) {
        handle.logMessage(LOGWARN, "Warning in straying - function outside bounds", strayProportion[i]);
        strayProportion[i] = 0.0;
      }
      if (strayProportion[i] > 1.0) {
        handle.logMessage(LOGWARN, "Warning in straying - function outside bounds", strayProportion[i]);
        strayProportion[i] = 1.0;
      }
    }

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

void StrayData::Print(ofstream& outfile) const {
  int i;
  outfile << "\nStraying information\n\tNames of straying stocks:";
  for (i = 0; i < strayStockNames.Size(); i++)
    outfile << sep << strayStockNames[i];
  outfile << "\n\tRatio moving into each stock:";
  for (i = 0; i < strayRatio.Size(); i++)
    outfile << sep << (strayRatio[ratioindex[i]] * ratioscale);
  outfile << "\n\tStraying timesteps:";
  for (i = 0; i < strayStep.Size(); i++)
    outfile << sep << strayStep[i];
  outfile << endl;
}

const StockPtrVector& StrayData::getStrayStocks() {
  return strayStocks;
}

void StrayData::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 StrayData::addStrayTag(const char* tagname) {
  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in stray - invalid tagging experiment", tagname);
  tagStorage.addTag(tagname);
}

void StrayData::deleteStrayTag(const char* tagname) {
  if (!istagged)
    handle.logMessage(LOGFAIL, "Error in stray - 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 stray - failed to delete tagging experiment", tagname);
}

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

Powered By FusionForge