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

View of /trunk/gadget/recapture.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: 17481 byte(s)
Initial version based on Gadget 2.2.00
#include "areatime.h"
#include "recapture.h"
#include "fleet.h"
#include "stock.h"
#include "stockprey.h"
#include "errorhandler.h"
#include "mathfunc.h"
#include "readfunc.h"
#include "readword.h"
#include "readaggregation.h"
#include "gadget.h"
#include "global.h"

Recaptures::Recaptures(CommentStream& infile, const AreaClass* const Area,
  const TimeClass* const TimeInfo, double weight, TagPtrVector Tag, const char* name)
  : Likelihood(TAGLIKELIHOOD, weight, name), alptr(0) {

  aggregator = 0;
  char text[MaxStrLength];
  strncpy(text, "", MaxStrLength);
  int i, j, check;
  int numarea = 0, numlen = 0;

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

  functionname = new char[MaxStrLength];
  strncpy(functionname, "", MaxStrLength);

  readWordAndValue(infile, "datafile", datafilename);
  readWordAndValue(infile, "function", functionname);
  if (strcasecmp(functionname, "poisson") == 0)
    functionnumber = 1;
  else
    handle.logFileMessage(LOGFAIL, "\nError in recaptures - unrecognised function", functionname);

  //read in area aggregation from file
  readWordAndValue(infile, "areaaggfile", aggfilename);
  datafile.open(aggfilename, ios::in);
  handle.checkIfFailure(datafile, aggfilename);
  handle.Open(aggfilename);
  numarea = 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]);

  //read in length aggregation from file
  readWordAndValue(infile, "lenaggfile", aggfilename);
  datafile.open(aggfilename, ios::in);
  handle.checkIfFailure(datafile, aggfilename);
  handle.Open(aggfilename);
  numlen = readLengthAggregation(subdata, lengths, lenindex);
  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, "[component]") != 0)) {
    fleetnames.resize(new char[strlen(text) + 1]);
    strcpy(fleetnames[i++], text);
    infile >> text >> ws;
  }
  if (fleetnames.Size() == 0)
    handle.logFileMessage(LOGFAIL, "\nError in recaptures - failed to read fleets");
  handle.logMessage(LOGMESSAGE, "Read fleet data - number of fleets", fleetnames.Size());

  //We have now read in all the data from the main likelihood file
  //But we have to read in the recapture data from datafilename
  datafile.open(datafilename, ios::in);
  handle.checkIfFailure(datafile, datafilename);
  handle.Open(datafilename);
  readRecaptureData(subdata, TimeInfo, numarea, numlen);
  handle.Close();
  datafile.close();
  datafile.clear();

  for (j = 0; j < tagnames.Size(); j++) {
    check = 0;
    for (i = 0; i < Tag.Size(); i++) {
      if (strcasecmp(tagnames[j], Tag[i]->getName()) == 0) {
        check++;
        tagvec.resize(Tag[i]);
        //likelihoodValues.AddRows(1, Tag[i]->getNumTagTimeSteps(), 0.0);
      }
    }
    if (check == 0)
      handle.logMessage(LOGFAIL, "Error in recaptures - failed to match tag", tagnames[j]);
  }
}

void Recaptures::readRecaptureData(CommentStream& infile,
  const TimeClass* const TimeInfo, int numarea, int numlen) {

  int i, j, k;
  double tmpnumber;
  char tmparea[MaxStrLength], tmplength[MaxStrLength], tmptagid[MaxStrLength];
  strncpy(tmparea, "", MaxStrLength);
  strncpy(tmplength, "", MaxStrLength);
  strncpy(tmptagid, "", MaxStrLength);
  int keepdata, timeid, areaid, lenid, tid;
  int year, step, count, reject;
  char* tagName;

  infile >> ws;
  //Check the number of columns in the inputfile
  if (countColumns(infile) != 6)
      handle.logFileMessage(LOGFAIL, "wrong number of columns in inputfile - should be 6");

  year = step = count = reject = 0;
  while (!infile.eof()) {
    keepdata = 1;
    infile >> tmptagid >> year >> step >> tmparea >> tmplength >> tmpnumber >> ws;

    //crude check to see if something has gone wrong and avoid infinite loops
    if (strlen(tmparea) == 0)
      handle.logFileMessage(LOGFAIL, "failed to read data from file");

    //if tmparea is in areaindex find areaid, else dont keep the data
    areaid = -1;
    for (i = 0; i < areaindex.Size(); i++)
      if (strcasecmp(areaindex[i], tmparea) == 0)
        areaid = i;

    if (areaid == -1)
      keepdata = 0;

    //if tmplength is in lenindex find lenid, 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;

    timeid = -1;
    tid = -1;
    if ((TimeInfo->isWithinPeriod(year, step)) && (keepdata == 1)) {
      //if this is a new tagging exp. then resize
      for (i = 0; i < tagnames.Size(); i++)
        if (strcasecmp(tagnames[i], tmptagid) == 0)
          tid = i;

      if (tid == -1) {
        //if this is a new tagging experiment, resize to store the data
        tagName = new char[strlen(tmptagid) + 1];
        strcpy(tagName, tmptagid);
        tagnames.resize(tagName);
        tid = tagnames.Size() - 1;
        obsYears.AddRows(1, 1, year);
        obsSteps.AddRows(1, 1, step);
        timeid = 0;
        obsDistribution.resize();
        obsDistribution[tid].resize(new DoubleMatrix(numarea, numlen, 0.0));
        modelDistribution.resize();
        modelDistribution[tid].resize(new DoubleMatrix(numarea, numlen, 0.0));
        //JMB - add objects to allow for timesteps when no recpatures are found
        modYears.AddRows(1, 0, 0);
        modSteps.AddRows(1, 0, 0);
        newDistribution.resize();

      } else {
        for (i = 0; i < obsYears[tid].Size(); i++)
          if ((obsYears[tid][i] == year) && (obsSteps[tid][i] == step))
            timeid = i;

        //if this is a new timestep, resize to store the data
        if (timeid == -1) {
          obsYears[tid].resize(1, year);
          obsSteps[tid].resize(1, step);
          timeid = obsYears.Ncol(tid) - 1;
          obsDistribution[tid].resize(new DoubleMatrix(numarea, numlen, 0.0));
          modelDistribution[tid].resize(new DoubleMatrix(numarea, numlen, 0.0));
        }
      }

      //finally store the number of the obsDistribution
      count++;
      (*obsDistribution[tid][timeid])[areaid][lenid] = tmpnumber;

    } else
      reject++;  //count number of rejected data points read from file
  }

  if (count == 0)
    handle.logMessage(LOGWARN, "Warning in recaptures - found no data in the data file for", this->getName());
  if (reject != 0)
    handle.logMessage(LOGMESSAGE, "Discarded invalid recaptures data - number of invalid entries", reject);
  handle.logMessage(LOGMESSAGE, "Read recaptures data file - number of entries", count);
}

Recaptures::~Recaptures() {
  int i, j;
  for (i = 0; i < fleetnames.Size(); i++)
    delete[] fleetnames[i];
  for (i = 0; i < areaindex.Size(); i++)
    delete[] areaindex[i];
  for (i = 0; i < lenindex.Size(); i++)
    delete[] lenindex[i];
  for (i = 0; i < tagnames.Size(); i++)
    delete[] tagnames[i];
  for (i = 0; i < obsDistribution.Nrow(); i++) {
    for (j = 0; j < obsDistribution.Ncol(i); j++) {
      delete obsDistribution[i][j];
      delete modelDistribution[i][j];
    }
  }
  for (i = 0; i < newDistribution.Nrow(); i++)
    for (j = 0; j < newDistribution.Ncol(i); j++)
      delete newDistribution[i][j];
  if (aggregator != 0)  {
    for (i = 0; i < tagvec.Size(); i++)
      delete aggregator[i];
    delete[] aggregator;
    aggregator = 0;
  }
  delete[] functionname;
}

void Recaptures::Reset(const Keeper* const keeper) {
  int i, j;
  Likelihood::Reset(keeper);
  for (i = 0; i < newDistribution.Nrow(); i++)
    for (j = 0; j < newDistribution.Ncol(i); j++)
      delete newDistribution[i][j];
  for (i = 0; i < modelDistribution.Nrow(); i++)
    for (j = 0; j < modelDistribution.Ncol(i); j++)
      (*modelDistribution[i][j]).setToZero();
  if (handle.getLogLevel() >= LOGMESSAGE)
    handle.logMessage(LOGMESSAGE, "Reset recaptures component", this->getName());
}

void Recaptures::setFleetsAndStocks(FleetPtrVector& Fleets, StockPtrVector& Stocks) {
  int i, j, k, l, found;
  FleetPtrVector fleets;
  StockPtrVector stocks;
  CharPtrVector stocknames;

  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++;
        fleets.resize(Fleets[j]);
      }

    if (found == 0)
      handle.logMessage(LOGFAIL, "Error in recaptures - failed to match fleet", fleetnames[i]);
  }

  for (i = 0; i < fleets.Size(); i++)
    for (j = 0; j < fleets.Size(); j++)
      if ((strcasecmp(fleets[i]->getName(), fleets[j]->getName()) == 0) && (i != j))
        handle.logMessage(LOGFAIL, "Error in recaptures - repeated fleet", fleets[i]->getName());

  double minlen, maxlen;
  int minage, maxage, size;

  aggregator = new RecAggregator*[tagvec.Size()];
  for (k = 0; k < tagvec.Size(); k++) {
    stocknames = tagvec[k]->getStockNames();
    for (i = 0; i < stocknames.Size(); i++)  {
      found = 0;
      for (j = 0; j < Stocks.Size(); j++) {
        if (Stocks[j]->isEaten()) {
          if (strcasecmp(stocknames[i], Stocks[j]->getName()) == 0) {
            found++;
            stocks.resize(Stocks[j]);
          }
        }
      }
      if (found == 0)
        handle.logMessage(LOGFAIL, "Error in recaptures - failed to match stock", stocknames[i]);
    }

    //Check the stock has been tagged
    for (j = 0; j < stocks.Size(); j++)
      if (!stocks[j]->isTagged())
        handle.logMessage(LOGFAIL, "Error in recaptures - stocks hasnt been tagged", stocks[j]->getName());

    //Check if the stock lives on all the areas that were read in
    for (i = 0; i < areas.Nrow(); i++)
      for (l = 0; l < areas.Ncol(i); l++)
        for (j = 0; j < stocks.Size(); j++)
          if (!stocks[j]->isInArea(areas[i][l]))
            handle.logMessage(LOGFAIL, "Error in recaptures - stocks arent defined on all areas");

    IntMatrix agematrix(1, 0, 0);
    minage = 999;
    maxage = 0;
    for (i = 0; i < stocks.Size(); i++) {
      minage = min(stocks[i]->minAge(), minage);
      maxage = max(stocks[i]->maxAge(), maxage);
    }

    for (i = 0; i <= maxage - minage; i++)
      agematrix[0].resize(1, minage + i);

    LengthGroupDivision* lgrpdiv = new LengthGroupDivision(lengths);
    if (lgrpdiv->Error())
      handle.logMessage(LOGFAIL, "Error in recaptures - failed to create length group");
    aggregator[k] = new RecAggregator(fleets, stocks, lgrpdiv, areas, agematrix, tagvec[k]);

    delete lgrpdiv;
    stocks.Reset();
  }
}

void Recaptures::addLikelihood(const TimeClass* const TimeInfo) {
  double l = 0.0;
  switch (functionnumber) {
    case 1:
      l = calcLikPoisson(TimeInfo);
      break;
    default:
      handle.logMessage(LOGWARN, "Warning in recaptures - unrecognised function", functionname);
      break;
  }

  if (!(isZero(l))) {
    likelihood += l;
    if (handle.getLogLevel() >= LOGMESSAGE)
      handle.logMessage(LOGMESSAGE, "The likelihood score for this component on this timestep is", l);
 }
}

double Recaptures::calcLikPoisson(const TimeClass* const TimeInfo) {
  double x, n, lik, total;
  int t, a, ti, len, timeid, checktag, checktime;
  int year = TimeInfo->getYear();
  int step = TimeInfo->getStep();

  total = 0.0;
  for (t = 0; t < tagvec.Size(); t++) {
    checktag = 0;
    lik = 0.0;
    if (tagvec[t]->isWithinPeriod(year, step)) {

      if (!checktag) {
        if (handle.getLogLevel() >= LOGMESSAGE)
          handle.logMessage(LOGMESSAGE, "Calculating likelihood score for recaptures component", this->getName());
        checktag++;
      }

      aggregator[t]->Sum();
      alptr = &aggregator[t]->getSum();

      checktime = 0;
      timeid = -1;
      for (ti = 0; ti < obsYears.Ncol(t); ti++)
        if ((obsYears[t][ti] == year) && (obsSteps[t][ti] == step))
          timeid = ti;

      if (timeid == -1) {
        // this is a modelled return that doesnt have a corresponding observed return
        checktime++;
        for (ti = 0; ti < modYears.Ncol(t); ti++)
          if ((modYears[t][ti] == year) && (modSteps[t][ti] == step))
            timeid = ti;

        // resize objects if needed
        if (timeid == -1) {
          modYears[t].resize(1, year);
          modSteps[t].resize(1, step);
          timeid = modYears.Ncol(t) - 1;
          newDistribution[t].resize(new DoubleMatrix(areaindex.Size(), lenindex.Size(), 0.0));
        }
      }

      for (a = 0; a < areas.Nrow(); a++) {
        for (len = 0; len < lengths.Size() - 1; len++) {
          x = ((*alptr)[a][0][len]).N;

          if (!checktime) {
            // this is a modelled return that has a non-zero observed return
            n = (*obsDistribution[t][timeid])[a][len];
            (*modelDistribution[t][timeid])[a][len] = x;
          } else {
            // this is a modelled return that doesnt have a corresponding observed return
            n = 0.0;
            (*newDistribution[t][timeid])[a][len] = x;
          }

          if (isZero(n))
            lik += x;
          else if (x < verysmall)
            lik += verybig;
          else
            lik -= -x + (n * log(x)) - logFactorial(n);

        }
      }
    }
    total += lik;
  }
  return total;
}

void Recaptures::Print(ofstream& outfile) const {
  int t, ti, area, len;
  outfile << "\nRecaptures Data " << this->getName() << " - likelihood value " << likelihood
    << "\n\tFunction " << functionname << endl;
  for (t = 0; t < tagvec.Size(); t++) {
    outfile << "\tTagging experiment:\t" << tagnames[t];
    for (ti = 0; ti < obsYears.Ncol(t); ti++) {
      outfile << "\n\tyear " << obsYears[t][ti] << " and step " << obsSteps[t][ti] << "\n\tobserved recaptures";
      for (area = 0; area < (*obsDistribution[t][ti]).Nrow(); area++)
        for (len = 0; len < (*obsDistribution[t][ti]).Ncol(area); len++)
          outfile << TAB << (*obsDistribution[t][ti])[area][len];

      outfile << "\n\tmodelled recaptures";
      for (area = 0; area < (*modelDistribution[t][ti]).Nrow(); area++)
        for (len = 0; len < (*modelDistribution[t][ti]).Ncol(area); len++)
          outfile << TAB << (*modelDistribution[t][ti])[area][len];
    }
    outfile << endl;
  }
  outfile.flush();
}

void Recaptures::printSummary(ofstream& outfile) {
  //JMB to start with just print a summary of all likelihood scores
  //This needs to be changed to print something for each timestep and area
  //but we need to sort out how to get the information in the same format as other components
  if (!(isZero(likelihood))) {
    outfile << "all   all        all" << sep << setw(largewidth) << this->getName() << sep
      << setprecision(smallprecision) << setw(smallwidth) << weight << sep
      << setprecision(largeprecision) << setw(largewidth) << likelihood << endl;
    outfile.flush();
  }
}

void Recaptures::printLikelihood(ofstream& outfile, const TimeClass* const TimeInfo) {
  int year = TimeInfo->getYear();
  int step = TimeInfo->getStep();
  int t, ti, timeid, area, len;

  for (t = 0; t < tagvec.Size(); t++) {
    if (tagvec[t]->isWithinPeriod(year, step)) {
      timeid = -1;
      for (ti = 0; ti < obsYears.Ncol(t); ti++)
        if (obsYears[t][ti] == year && obsSteps[t][ti] == step)
          timeid = ti;

      if (timeid > -1) {
        for (area = 0; area < modelDistribution[t][timeid]->Nrow(); area++) {
          for (len = 0; len < modelDistribution[t][timeid]->Ncol(area); len++) {
            outfile << setw(printwidth) << tagnames[t] << sep << setw(lowwidth)
              << obsYears[t][timeid] << sep << setw(lowwidth) << obsSteps[t][timeid] << sep
              << setw(printwidth) << areaindex[area] << sep << setw(printwidth)
              << lenindex[len] << sep << setprecision(largeprecision) << setw(largewidth);

            //JMB crude filter to remove the 'silly' values from the output
            if ((*modelDistribution[t][timeid])[area][len] < rathersmall)
              outfile << 0 << endl;
            else
              outfile << (*modelDistribution[t][timeid])[area][len] << endl;
          }
        }

      } else {
        for (ti = 0; ti < modYears.Ncol(t); ti++)
          if ((modYears[t][ti] == year) && (modSteps[t][ti] == step))
            timeid = ti;

        if (timeid > -1) {
          for (area = 0; area < newDistribution[t][timeid]->Nrow(); area++) {
            for (len = 0; len < newDistribution[t][timeid]->Ncol(area); len++) {
              outfile << setw(printwidth) << tagnames[t] << sep << setw(lowwidth)
                << modYears[t][timeid] << sep << setw(lowwidth) << modSteps[t][timeid] << sep
                << setw(printwidth) << areaindex[area] << sep << setw(printwidth)
                << lenindex[len] << sep << setprecision(largeprecision) << setw(largewidth);

            //JMB crude filter to remove the 'silly' values from the output
            if ((*newDistribution[t][timeid])[area][len] < rathersmall)
              outfile << 0 << endl;
            else
              outfile << (*newDistribution[t][timeid])[area][len] << endl;
            }
          }
        }
      }
    }
  }
}

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

Powered By FusionForge