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

View of /trunk/gadget/sionstep.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: 13007 byte(s)
Initial version based on Gadget 2.2.00
#include "sionstep.h"
#include "areatime.h"
#include "errorhandler.h"
#include "readfunc.h"
#include "readword.h"
#include "gadget.h"
#include "global.h"

SIOnStep::~SIOnStep() {
  int i;
  if (LgrpDiv != 0)
    delete LgrpDiv;
  if (LR != 0)
    delete LR;
  for (i = 0; i < areaindex.Size(); i++)
    delete[] areaindex[i];
  for (i = 0; i < colindex.Size(); i++)
    delete[] colindex[i];
  for (i = 0; i < obsIndex.Size(); i++) {
    delete obsIndex[i];
    delete modelIndex[i];
  }
  for (i = 0; i < weightIndex.Size(); i++)
    delete weightIndex[i];
}

SIOnStep::SIOnStep(CommentStream& infile, const char* datafilename, const CharPtrVector& aindex,
  const TimeClass* const TimeInfo, const IntMatrix& areas, const CharPtrVector& charindex,
  const char* givenname, int bio, SIType type) : HasName(givenname), Areas(areas), alptr(0) {

  biomass = bio;
  sitype = type;
  useweight = 0;
  timeindex = 0;
  slope = 0.0;
  intercept = 0.0;

  int i;
  for (i = 0; i < aindex.Size(); i++) {
    areaindex.resize(new char[strlen(aindex[i]) + 1]);
    strcpy(areaindex[i], aindex[i]);
  }
  for (i = 0; i < charindex.Size(); i++) {
    colindex.resize(new char[strlen(charindex[i]) + 1]);
    strcpy(colindex[i], charindex[i]);
  }

  //read the fittype
  readSIRegressionData(infile);

  //read the survey indices data from the datafile
  ifstream datafile;
  CommentStream subdata(datafile);
  datafile.open(datafilename, ios::in);
  handle.checkIfFailure(datafile, datafilename);
  handle.Open(datafilename);
  readSIData(subdata, TimeInfo);
  handle.Close();
  datafile.close();
  datafile.clear();

  //resize to store the regression information
  slopes.AddRows(areaindex.Size(), colindex.Size(), slope);
  intercepts.AddRows(areaindex.Size(), colindex.Size(), intercept);
  sse.AddRows(areaindex.Size(), colindex.Size(), 0.0);
  if (useweight)
    tmpWeight.resize(Years.Size(), 0.0);
  tmpModel.resize(Years.Size(), 0.0);
  tmpData.resize(Years.Size(), 0.0);
  likelihoodValues.resize(areaindex.Size(), 0.0);
}

void SIOnStep::readSIData(CommentStream& infile, const TimeClass* const TimeInfo) {

  double tmpnumber, tmpweight;
  char tmparea[MaxStrLength], tmplabel[MaxStrLength];
  strncpy(tmparea, "", MaxStrLength);
  strncpy(tmplabel, "", MaxStrLength);
  int keepdata, timeid, colid, areaid;
  int i, year, step, count, reject;

  //Check the number of columns in the inputfile
  infile >> ws;
  if ((!useweight) && (countColumns(infile) != 5))
    handle.logFileMessage(LOGFAIL, "wrong number of columns in inputfile - should be 5");
  else if ((useweight) && (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;

    if (useweight)
      infile >> year >> step >> tmparea >> tmplabel >> tmpnumber >> tmpweight >> ws;
    else
      infile >> year >> step >> tmparea >> tmplabel >> 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 keep data, 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 tmplabel is in colindex find colid, else dont keep the data
    colid = -1;
    for (i = 0; i < colindex.Size(); i++)
      if (strcasecmp(colindex[i], tmplabel) == 0)
        colid = i;

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

    //check if the year and step are in the simulation
    timeid = -1;
    if ((TimeInfo->isWithinPeriod(year, step)) && (keepdata == 1)) {
      for (i = 0; i < Years.Size(); i++)
        if ((Years[i] == year) && (Steps[i] == step))
          timeid = i;

      if (timeid == -1) {
        Years.resize(1, year);
        Steps.resize(1, step);
        timeid = (Years.Size() - 1);
        obsIndex.resize(new DoubleMatrix(areaindex.Size(), colindex.Size(), 0.0));
        modelIndex.resize(new DoubleMatrix(areaindex.Size(), colindex.Size(), 0.0));
        if (useweight)
          weightIndex.resize(new DoubleMatrix(areaindex.Size(), colindex.Size(), 0.0));
      }

    } else
      keepdata = 0;

    if (keepdata == 1) {
      //survey indices data is required, so store it
      count++;
      (*obsIndex[timeid])[areaid][colid] = tmpnumber;
      if (useweight)
        (*weightIndex[timeid])[areaid][colid] = tmpweight;
    } else
      reject++;  //count number of rejected data points read from file
  }

  AAT.addActions(Years, Steps, TimeInfo);
  if (count == 0)
    handle.logMessage(LOGWARN, "Warning in surveyindex - found no data in the data file for", this->getName());
  if (Years.Size() < 2)
    handle.logMessage(LOGWARN, "Warning in surveyindex - insufficient data to fit a regression line for", this->getName());

  if ((handle.getLogLevel() >= LOGWARN) && (Steps.Size() > 0) && (this->getSIType() != SIEFFORT)) {
    //JMB to be comparable, this should only take place on the same step in each year
    //However the effort data will be on most timesteps so this check isnt required
    step = Steps[0];
    timeid = 0;
    for (i = 1; i < Steps.Size(); i++)
      if (Steps[i] != step)
        timeid++;

    if (timeid != 0)
      handle.logMessage(LOGWARN, "Warning in surveyindex - differing timesteps for", this->getName());
  }

  if (reject != 0)
    handle.logMessage(LOGMESSAGE, "Discarded invalid surveyindex data - number of invalid entries", reject);
  handle.logMessage(LOGMESSAGE, "Read surveyindex data file - number of entries", count);
}

void SIOnStep::readSIRegressionData(CommentStream& infile) {

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

  infile >> ws >> text;
  if (strcasecmp(text, "linearfit") == 0) {
    fittype = LINEARFIT;
    LR = new LinearRegression(FREE);
  } else if (strcasecmp(text, "loglinearfit") == 0) {
    fittype = LOGLINEARFIT;
    LR = new LogLinearRegression(FREE);
  } else if (strcasecmp(text, "weightlinearfit") == 0) {
    useweight = 1;
    fittype = WEIGHTLINEARFIT;
    LR = new WeightRegression(FREE);
  } else if (strcasecmp(text, "logweightlinearfit") == 0) {
    useweight = 1;
    fittype = LOGWEIGHTLINEARFIT;
    LR = new LogWeightRegression(FREE);
  } else if (strcasecmp(text, "fixedslopelinearfit") == 0) {
    fittype = FIXEDSLOPELINEARFIT;
    LR = new LinearRegression(FIXEDSLOPE);
  } else if (strcasecmp(text, "fixedslopeloglinearfit") == 0) {
    fittype = FIXEDSLOPELOGLINEARFIT;
    LR = new LogLinearRegression(FIXEDSLOPE);
  } else if (strcasecmp(text, "fixedslopeweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDSLOPEWEIGHTLINEARFIT;
    LR = new WeightRegression(FIXEDSLOPE);
  } else if (strcasecmp(text, "fixedslopelogweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDSLOPELOGWEIGHTLINEARFIT;
    LR = new LogWeightRegression(FIXEDSLOPE);
  } else if (strcasecmp(text, "fixedinterceptlinearfit") == 0) {
    fittype = FIXEDINTERCEPTLINEARFIT;
    LR = new LinearRegression(FIXEDINTERCEPT);
  } else if (strcasecmp(text, "fixedinterceptloglinearfit") == 0) {
    fittype = FIXEDINTERCEPTLOGLINEARFIT;
    LR = new LogLinearRegression(FIXEDINTERCEPT);
  } else if (strcasecmp(text, "fixedinterceptweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDINTERCEPTWEIGHTLINEARFIT;
    LR = new WeightRegression(FIXEDINTERCEPT);
  } else if (strcasecmp(text, "fixedinterceptlogweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDINTERCEPTLOGWEIGHTLINEARFIT;
    LR = new LogWeightRegression(FIXEDINTERCEPT);
  } else if (strcasecmp(text, "fixedlinearfit") == 0) {
    fittype = FIXEDLINEARFIT;
    LR = new LinearRegression(FIXED);
  } else if (strcasecmp(text, "fixedloglinearfit") == 0) {
    fittype = FIXEDLOGLINEARFIT;
    LR = new LogLinearRegression(FIXED);
  } else if (strcasecmp(text, "fixedweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDWEIGHTLINEARFIT;
    LR = new WeightRegression(FIXED);
  } else if (strcasecmp(text, "fixedlogweightlinearfit") == 0) {
    useweight = 1;
    fittype = FIXEDLOGWEIGHTLINEARFIT;
    LR = new LogWeightRegression(FIXED);
  } else
    handle.logFileMessage(LOGFAIL, "\nError in surveyindex - unrecognised fittype", text);

  switch (fittype) {
    case LINEARFIT:
    case LOGLINEARFIT:
    case WEIGHTLINEARFIT:
    case LOGWEIGHTLINEARFIT:
      break;
    case FIXEDSLOPELINEARFIT:
    case FIXEDSLOPELOGLINEARFIT:
    case FIXEDSLOPEWEIGHTLINEARFIT:
    case FIXEDSLOPELOGWEIGHTLINEARFIT:
      readWordAndVariable(infile, "slope", slope);
      LR->setSlope(slope);
      break;
    case FIXEDINTERCEPTLINEARFIT:
    case FIXEDINTERCEPTLOGLINEARFIT:
    case FIXEDINTERCEPTWEIGHTLINEARFIT:
    case FIXEDINTERCEPTLOGWEIGHTLINEARFIT:
      readWordAndVariable(infile, "intercept", intercept);
      LR->setIntercept(intercept);
      break;
    case FIXEDLINEARFIT:
    case FIXEDLOGLINEARFIT:
    case FIXEDWEIGHTLINEARFIT:
    case FIXEDLOGWEIGHTLINEARFIT:
      readWordAndVariable(infile, "slope", slope);
      readWordAndVariable(infile, "intercept", intercept);
      LR->setSlope(slope);
      LR->setIntercept(intercept);
      break;
    default:
      handle.logFileMessage(LOGFAIL, "\nError in surveyindex - unrecognised fittype", text);
      break;
  }

  //JMB - check that the slope of the regression line is positive
  if (slope < 0.0)
    handle.logFileMessage(LOGFAIL, "\nError in surveyindex - slope of the regression line must be positive", slope);
}

void SIOnStep::printLikelihood(ofstream& outfile, const TimeClass* const TimeInfo) {

  int a, i;
  if (AAT.atCurrentTime(TimeInfo)) {
    timeindex = -1;
    for (i = 0; i < Years.Size(); i++)
      if ((Years[i] == TimeInfo->getYear()) && (Steps[i] == TimeInfo->getStep()))
        timeindex = i;
    if (timeindex == -1)
      handle.logMessage(LOGFAIL, "Error in surveyindex - invalid timestep");

    for (a = 0; a < areaindex.Size(); a++) {
      for (i = 0; i < colindex.Size(); i++) {
        outfile << setw(lowwidth) << Years[timeindex] << sep << setw(lowwidth)
          << Steps[timeindex] << sep << setw(printwidth) << areaindex[a] << sep
          << setw(printwidth) << colindex[i] << sep << setw(largewidth);

        //JMB crude filter to remove the 'silly' values from the output
        if ((*modelIndex[timeindex])[a][i] < rathersmall)
          outfile << 0;
        else
          outfile << setprecision(largeprecision) << (*modelIndex[timeindex])[a][i];

        if (useweight)
          outfile << sep << setw(printwidth) << (*weightIndex[timeindex])[a][i];
        outfile << endl;
      }
    }
  }

  //JMB - this is nasty hack to output the regression information
  if (TimeInfo->getTime() == TimeInfo->numTotalSteps()) {
    for (a = 0; a < areaindex.Size(); a++) {
      outfile << "; Regression information for area " << areaindex[a] << endl;
      for (i = 0; i < colindex.Size(); i++)
        outfile << "; " << colindex[i] << " intercept " << intercepts[a][i]
          << " slope " << slopes[a][i] << " sse " << sse[a][i] << endl;
    }
  }
}

double SIOnStep::calcSSE() {

  if (handle.getLogLevel() >= LOGMESSAGE)
    handle.logMessage(LOGMESSAGE, "Calculating likelihood score for surveyindex component", this->getName());

  int a, i, j;
  double score = 0.0;
  for (a = 0; a < areaindex.Size(); a++) {
    likelihoodValues[a] = 0.0;
    for (i = 0; i < colindex.Size(); i++) {
      for (j = 0; j < tmpData.Size(); j++) {
        tmpData[j] = (*obsIndex[j])[a][i];
        tmpModel[j] = (*modelIndex[j])[a][i];
      }

      //if the weights are required then pass them to the regression line
      if (useweight) {
        for (j = 0; j < tmpWeight.Size(); j++)
          tmpWeight[j] = (*weightIndex[j])[a][i];
        LR->setWeights(tmpWeight);
      }

      //fit the data to the (log) linear regression line
      LR->storeVectors(tmpModel, tmpData);
      LR->calcFit();

      //and then store the results
      slopes[a][i] = LR->getSlope();
      intercepts[a][i] = LR->getIntercept();
      sse[a][i] = LR->getSSE();
      likelihoodValues[a] += LR->getSSE();
    }
    score += likelihoodValues[a];
  }

  if (handle.getLogLevel() >= LOGMESSAGE)
    handle.logMessage(LOGMESSAGE, "The likelihood score from the regression line for this component is", score);
  return score;
}

void SIOnStep::printSummary(ofstream& outfile, const double weight) {
  int a;
  for (a = 0; a < areaindex.Size(); a++)
    outfile << "all   all " << setw(printwidth) << areaindex[a] << sep
      << setw(largewidth) << this->getName() << sep << setprecision(smallprecision)
      << setw(smallwidth) << weight << sep << setprecision(largeprecision)
      << setw(largewidth) << likelihoodValues[a] << endl;
  outfile.flush();
}

void SIOnStep::Reset() {
  int i;
  for (i = 0; i < modelIndex.Size(); i++)
    (*modelIndex[i]).setToZero();
}

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

Powered By FusionForge