Esempio n. 1
0
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clConstantGLI::DoShellSetup(xercesc::DOMDocument * p_oDoc) {
  try {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

    FillSingleValue(p_oElement, "li_constGLI", &m_fGLI, true);

    if (0 > m_fGLI || 100 < m_fGLI) {
      modelErr stcErr;
      stcErr.sFunction = "clConstantGLI::DoShellSetup";
      stcErr.sMoreInfo = "Constant GLI must be between 0 and 100.";
      stcErr.iErrorCode = BAD_DATA;
      throw(stcErr);
    }
  } catch (modelErr& err) {
    throw(err);
  } catch (modelMsg & msg) {
    throw(msg);
  } //non-fatal error
  catch (...) {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clConstantGLI::DoShellSetup";
    throw(stcErr);
  }
}
Esempio n. 2
0
////////////////////////////////////////////////////////////////////////////
// ReadParameterFileData()
////////////////////////////////////////////////////////////////////////////
void clGLIMap::ReadParameterFileData( xercesc::DOMDocument * p_oDoc )
{
  DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

  m_iNumAltAng = 0;
  m_iNumAziAng = 0;
  m_fMinSunAngle = 0;

  //Get the photo height value - required
  FillSingleValue( p_oElement, "li_mapLightHeight", & m_fLightHeight, true );

  //Get our values
  //Number of alitude angles
  FillSingleValue( p_oElement, "li_numAltGrids", & m_iNumAltAng, true );
  //Number of azimuth angles
  FillSingleValue( p_oElement, "li_numAziGrids", & m_iNumAziAng, true );
  //Minimum sun angle
  FillSingleValue( p_oElement, "li_minSunAngle", & m_fMinSunAngle, true );
  //Azimuth of north - not required for backwards compatibility
  FillSingleValue( p_oElement, "li_AziOfNorth", & m_fAzimuthOfNorth, false );

  //Validate the data
  if ( 0 >= m_iNumAltAng )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The number of sky altitude divisions must be greater than 0.";
    throw( stcErr );
  }

  if ( 0 >= m_iNumAziAng )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The number of sky azimuth divisions must be greater than 0.";
    throw( stcErr );
  }

  if ( 0 > m_fLightHeight )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The height of the GLI point for the GLI map cannot be less than 0.";
    throw( stcErr );
  }

  //Make sure azimuth of north is between 0 and 2PI
  if (0 > m_fAzimuthOfNorth || (2.0 * M_PI) < m_fAzimuthOfNorth) {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "Azimuth of north must be between 0 and 2PI.";
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// ReadParameterFileData()
////////////////////////////////////////////////////////////////////////////
void clResourceMortality::ReadParameterFileData( xercesc::DOMDocument * p_oDoc )
{
  clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
  DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
  floatVal * p_fTempValues; //for getting species-specific values
  short int i; //loop counter

  //Declare the temp array and populate it with the species to which this
  //behavior applies
  p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    p_fTempValues[i].code = mp_iWhatSpecies[i];

  //Declare the index array and populate it
  mp_iIndexes = new short int[p_oPop->GetNumberOfSpecies()];

  //Make the list of indexes
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    mp_iIndexes[mp_iWhatSpecies[i]] = i;

  //Declare the arrays for holding the variables
  mp_fRho = new float[m_iNumBehaviorSpecies];
  mp_fMu = new float[m_iNumBehaviorSpecies];
  mp_fDelta = new float[m_iNumBehaviorSpecies];
  mp_fSigma = new float[m_iNumBehaviorSpecies];

  //Capture the values from the parameter file

  //Scaling factor (rho)
  FillSpeciesSpecificValue( p_oElement, "mo_resMortScalingFactor", "mo_rmsfVal", p_fTempValues,
       m_iNumBehaviorSpecies, p_oPop, true );
  //Transfer to the appropriate array buckets
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    mp_fRho[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

  //Function mode (mu)
  FillSpeciesSpecificValue( p_oElement, "mo_resMortMode", "mo_rmmVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
  //Transfer to the appropriate array buckets
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    mp_fMu[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

  //Growth increase in survival (delta)
  FillSpeciesSpecificValue( p_oElement, "mo_resMortGrowthIncSurv", "mo_rmgisVal", p_fTempValues,
       m_iNumBehaviorSpecies, p_oPop, true );
  //Transfer to the appropriate array buckets
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    mp_fDelta[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

  //Low growth function shape (sigma)
  FillSpeciesSpecificValue( p_oElement, "mo_resMortLoGrowthShape", "mo_rmlgsVal", p_fTempValues,
       m_iNumBehaviorSpecies, p_oPop, true );
  //Transfer to the appropriate array buckets
  for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    mp_fSigma[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;


  delete[] p_fTempValues; p_fTempValues = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// GetParameterFileData()
/////////////////////////////////////////////////////////////////////////////
void clCarbonValueCalculator::GetParameterFileData( xercesc::DOMDocument * p_oDoc, clTreePopulation *p_oPop )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    int i;

    //Set up our doubleVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Declare our array
    mp_fCPercentBiomass = new double[m_iNumTotalSpecies];

    //Get the parameter file values

    //Percent of biomass that is carbon
    FillSpeciesSpecificValue( p_oElement, "an_carbonPercentBiomassCarbon", "an_cpbcVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets, and
    //convert to proportion; check to make sure it's between 0 and 1
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fCPercentBiomass[p_fTempValues[i].code] = p_fTempValues[i].val / 100.0;
      if (mp_fCPercentBiomass[p_fTempValues[i].code] > 1 ||
          mp_fCPercentBiomass[p_fTempValues[i].code] < 0) {
        modelErr stcErr;
        stcErr.sFunction = "clCarbonValueCalculator::GetParameterFileData" ;
        stcErr.sMoreInfo = "Percent of biomass that is carbon must be between 0 and 100.";
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    FillSingleValue( p_oElement, "an_carbonPricePerMetricTonCarbon", & m_fPricePerTonCarbon, true );

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clCarbonValueCalculator::GetParameterFileData" ;
    throw( stcErr );
  }
}
/////////////////////////////////////////////////////////////////////////////
// GetParameterFileData()
/////////////////////////////////////////////////////////////////////////////
void clRipleysKCalculator::GetParameterFileData( xercesc::DOMDocument * p_oDoc )
{
  try
  {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

    //Get the max distance
    FillSingleValue( p_oElement, "an_RipleysKMaxDistance", &m_fMaxDistance, true );

    //Get the increment
    FillSingleValue( p_oElement, "an_RipleysKDistanceInc", &m_fIncrement, true );

    //Validate that the increment and max distance values are greater than 0
    if ( m_fMaxDistance <= 0 )
    {
      modelErr stcErr;
      stcErr.sFunction = "clRipleysKCalculator::GetData" ;
      stcErr.sMoreInfo = "The max distance must be greater than zero.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }
    if ( m_fIncrement <= 0 )
    {
      modelErr stcErr;
      stcErr.sFunction = "clRipleysKCalculator::GetData" ;
      stcErr.sMoreInfo = "The distance increment must be greater than zero.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Verify that the increment is less than the max distance
    if (m_fMaxDistance <= m_fIncrement) {
      modelErr stcErr;
      stcErr.sFunction = "clRipleysKCalculator::GetData" ;
      stcErr.sMoreInfo = "The distance increment must be less than the max distance.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clRipleysKCalculator::GetParameterFileData" ;
    throw( stcErr );
  }
}
//---------------------------------------------------------------------------
// PowerHeightGrowth.cpp
//---------------------------------------------------------------------------
#include "PowerHeightGrowth.h"
#include "TreePopulation.h"
#include "SimManager.h"
#include "ParsingFunctions.h"
#include "GrowthOrg.h"
#include <math.h>

//////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////*/
clPowerHeightGrowth::clPowerHeightGrowth(clSimManager * p_oSimManager) :
  clWorkerBase(p_oSimManager), clBehaviorBase(p_oSimManager), clGrowthBase(
      p_oSimManager) {

  try {
    mp_fN = NULL;
    mp_fB = NULL;

    m_iGrowthMethod = height_only;
    m_iNumberYearsPerTimestep = 0;

    m_sNameString = "powergrowthshell";
    m_sXMLRoot = "PowerGrowth";

  } catch (modelErr& err) {
    throw(err);
  } catch (modelMsg & msg) {
    throw(msg);
  } //non-fatal error
  catch (...) {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clPowerHeightGrowth::clPowerHeightGrowth";
    throw(stcErr);
  }
}

//////////////////////////////////////////////////////////////////////////////
// Destructor
/////////////////////////////////////////////////////////////////////////////*/
clPowerHeightGrowth::~clPowerHeightGrowth() {

  delete[] mp_fN;
  delete[] mp_fB;
}

//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
/////////////////////////////////////////////////////////////////////////////*/
void clPowerHeightGrowth::DoShellSetup(DOMDocument * p_oDoc) {
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try {
    clTreePopulation * p_oPop =
        (clTreePopulation *) mp_oSimManager->GetPopulationObject(
            "treepopulation");
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int iNumSpecies = p_oPop->GetNumberOfSpecies(), i;

    //Declare the arrays we'd like read
    mp_fB = new double[iNumSpecies];
    mp_fN = new double[iNumSpecies];

    //Declare the species-specific temp array and pre-load with the species that
    //this behavior affects
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //N
    FillSpeciesSpecificValue(p_oElement, "gr_powerHeightN", "gr_phnVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);

    //Transfer values to our permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fN[p_fTempValues[i].code] = p_fTempValues[i].val;

    //B
    FillSpeciesSpecificValue(p_oElement, "gr_powerHeightExp", "gr_pheVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);

    //Transfer values to our permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fB[p_fTempValues[i].code] = p_fTempValues[i].val;

    m_iNumberYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    delete[] p_fTempValues;
  } catch (modelErr& err) {
    delete[] p_fTempValues;
    throw(err);
  } catch (modelMsg & msg) {
    delete[] p_fTempValues;
    throw(msg);
  } //non-fatal error
  catch (...) {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clPowerHeightGrowth::GetNameData";
    throw(stcErr);
  }
}
Esempio n. 7
0
////////////////////////////////////////////////////////////////////////////
// ReadParameterFileData()
////////////////////////////////////////////////////////////////////////////
void clGLIMap::ReadParameterFileData( xercesc::DOMDocument * p_oDoc )
{
  DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

  m_iNumAltAng = 0;
  m_iNumAziAng = 0;
  m_fMinSunAngle = 0;

  //Get the photo height value - required
  FillSingleValue( p_oElement, "li_mapLightHeight", & m_fLightHeight, true );

  //Get our values - none required because they might be in another light tag
  //Number of alitude angles
  FillSingleValue( p_oElement, "li_numAltGrids", & m_iNumAltAng, true );
  //Number of azimuth angles
  FillSingleValue( p_oElement, "li_numAziGrids", & m_iNumAziAng, true );
  //Minimum sun angle
  FillSingleValue( p_oElement, "li_minSunAngle", & m_fMinSunAngle, true );

  //Validate the data
  if ( 0 >= m_iNumAltAng )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The number of sky altitude divisions must be greater than 0.";
    throw( stcErr );
  }

  if ( 0 >= m_iNumAziAng )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The number of sky azimuth divisions must be greater than 0.";
    throw( stcErr );
  }

  if ( 0 > m_fLightHeight )
  {
    modelErr stcErr;
    stcErr.iErrorCode = BAD_DATA;
    stcErr.sFunction = "clGLIMap::ReadParameterFileData" ;
    stcErr.sMoreInfo = "The height of the GLI point for the GLI map cannot be less than 0.";
    throw( stcErr );
  }
}
/////////////////////////////////////////////////////////////////////////////
// ReadParFile()
/////////////////////////////////////////////////////////////////////////////
void clAggregatedMortality::ReadParFile( xercesc::DOMDocument * p_oDoc )
{
  DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

  //Mortality episode return interval in years
  FillSingleValue( p_oElement, "mo_aggReturnInterval", &m_fMortalityEpisodeProbability, true );
  if (m_fMortalityEpisodeProbability < 0) {
    modelErr stcErr;
    stcErr.sFunction = "clAggregatedMortality::ReadParFile" ;
    stcErr.sMoreInfo = "Return interval cannot be negative.";
    stcErr.iErrorCode = BAD_DATA;
    throw( stcErr );
  }

  //Mortality probability per year of a mortality episode
  //Make sure each value is between 0 and 1
  FillSingleValue( p_oElement, "mo_aggPropTreesToKill", &m_fMortalityProb, true );
  if (m_fMortalityProb < 0 || m_fMortalityProb > 1) {
    modelErr stcErr;
    stcErr.sFunction = "clAggregatedMortality::ReadParFile" ;
    stcErr.sMoreInfo = "Mortality probability must be between 0 and 1.";
    stcErr.iErrorCode = BAD_DATA;
    throw( stcErr );
  }

  //Number of trees to aggregate
  FillSingleValue( p_oElement, "mo_aggNumTreesToClump", &m_iNumTreesToClump, true );
  //Make sure each value is greater than 0
  if (m_iNumTreesToClump < 1) {
    modelErr stcErr;
    stcErr.sFunction = "clAggregatedMortality::ReadParFile" ;
    stcErr.sMoreInfo = "Number of trees to aggregate must be greater than 0.";
    stcErr.iErrorCode = BAD_DATA;
    throw( stcErr );
  }

  //Whether clump size is deterministic (true) or from the
  //negative binomial probability distribution (false)
  FillSingleValue( p_oElement, "mo_aggClumpSizeDeterministic", &m_bClumpSizeDeterministic, true );

  //Clumping parameter for negative binomial distribution, if required
  if (!m_bClumpSizeDeterministic)
    FillSingleValue( p_oElement, "mo_aggClumpingParameter", &m_fClumpingParameter, true );
}
Esempio n. 9
0
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clStochasticMort::DoShellSetup(xercesc::DOMDocument *p_oDoc) {
 try {
   clTreePopulation *p_oPop = (clTreePopulation*) mp_oSimManager->GetPopulationObject("treepopulation");
   DOMElement *p_oElement = GetParentParametersElement(p_oDoc);
   floatVal *p_fTempValues;  //for getting species-specific values
   float fNumberYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();
   short int iNumSpecies = mp_oMortalityOrg->GetNumberOfSpecies(),
             i; //loop counter

   //Declare the temp array and populate it with the species to which this
   //behavior applies
   p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
   for (i = 0; i < m_iNumBehaviorSpecies; i++)
     p_fTempValues[i].code = mp_iWhatSpecies[i];

   //Declare the arrays for holding the variables
   mp_fRandomMort = new float[iNumSpecies];

   //Capture the values from the parameter file

   //Random mortality
   FillSpeciesSpecificValue(p_oElement, "mo_stochasticMortRate",
               "mo_smrVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);
   //Transfer to the appropriate array buckets and compound by the number
   //of years per timestep
   for (i = 0; i < m_iNumBehaviorSpecies; i++) {
     mp_fRandomMort[p_fTempValues[i].code] = 1 - pow(1 - p_fTempValues[i].val, fNumberYearsPerTimestep);
   }

   delete[] p_fTempValues;
 }
 catch (modelErr&err) {throw(err);}
 catch (modelMsg &msg) {throw(msg);} //non-fatal error
 catch (...) {
   modelErr stcErr;
   stcErr.iErrorCode = UNKNOWN;
   stcErr.sFunction = "clStochasticMort::DoShellSetup";
   throw(stcErr);
 }
}
Esempio n. 10
0
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clBasalAreaLight::DoShellSetup( xercesc::DOMDocument * p_oDoc )
{
  int *p_iTemp = NULL;
  try
  {
  	clTreePopulation *p_oPop = (clTreePopulation*) mp_oSimManager->GetPopulationObject("treepopulation");
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    float fLight, fConBA, fAngBA;
    int i, j, iNumXCells, iNumYCells,
        iNumSpecies = p_oPop->GetNumberOfSpecies();
    bool bMap;

    p_iTemp = new int[iNumSpecies];

    m_bGridUpdated = false;

    mp_iSpeciesTypes = new iTreeType[iNumSpecies];

    //**********************************************
    //Read values from the parameter file
    //**********************************************
    //GLI mean value "a" parameter
    FillSingleValue( p_oElement, "li_baLightA", & m_fA, true );

    //Conifer "b" parameter
    FillSingleValue( p_oElement, "li_baConiferLightB", & m_fConiferB, true );

    //Angiosperm "b" parameter
    FillSingleValue( p_oElement, "li_baAngiospermLightB", & m_fAngiospermB, true );

    //Conifer "c" parameter
    FillSingleValue( p_oElement, "li_baConiferLightC", & m_fConiferC, true );
    //Error if this is equal to 0
    if (0 == m_fConiferC) {
      modelErr stcErr;
      stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
      stcErr.sMoreInfo = "Basal area light conifer \"c\" parameter cannot equal 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Angiosperm "c" parameter
    FillSingleValue( p_oElement, "li_baAngiospermLightC", & m_fAngiospermC, true );
    //Error if this is equal to 0
    if (0 == m_fAngiospermC) {
      modelErr stcErr;
      stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
      stcErr.sMoreInfo = "Basal area light angiosperm \"c\" parameter cannot equal 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Sigma parameter for lognormal PDF
    FillSingleValue( p_oElement, "li_baLightSigma", & m_fSigma, true );

    //Basal area change threshold for grid cells for recalculating GLI
    FillSingleValue( p_oElement, "li_baLightChangeThreshold", & m_fChangeThreshold, true );
    //Error if this is less than 0
    if (m_fChangeThreshold < 0) {
      modelErr stcErr;
      stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
      stcErr.sMoreInfo = "Basal area light change threshold cannot be less than 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Density light minimum DBH (cm) for a tree counting towards the density
    FillSingleValue( p_oElement, "li_baLightMinDBH", & m_fMinDbh, true );
    //Error if this is less thano 0
    if (m_fMinDbh < 0) {
      modelErr stcErr;
      stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
      stcErr.sMoreInfo = "Basal area light minimum DBH cannot be less than 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Search radius for neighbors
    FillSingleValue( p_oElement, "li_baLightSearchRadius", & m_fRadius, true );
    //Error if this is less than 0
    if (m_fRadius < 0) {
      modelErr stcErr;
      stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
      stcErr.sMoreInfo = "Basal area light radius cannot be less than 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Whether a species is an angiosperm or conifer
    FillSpeciesSpecificValue( p_oElement, "li_baTreeType", "li_bttVal", p_iTemp, p_oPop, true );
    for (i = 0; i < iNumSpecies; i++) {
      if (angiosperm == p_iTemp[i]) mp_iSpeciesTypes[i] = angiosperm;
      else if (conifer == p_iTemp[i]) mp_iSpeciesTypes[i] = conifer;
      else {
      	modelErr stcErr;
        stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
        std::stringstream s;
        s << "Unrecognized basal area light tree type: " << p_iTemp[i];
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //**********************************************
    //Set up the light grid
    //**********************************************
    //Is there already a grid from the parameter file?
    mp_oLightGrid = mp_oSimManager->GetGridObject( "Basal Area Light" );

    if ( !mp_oLightGrid )
    {
      //Create the grid with three float data members
      mp_oLightGrid = mp_oSimManager->CreateGrid( "Basal Area Light", 0, 3, 0, 0 );
      //Register the data member called "Light"
      m_iGridLightCode = mp_oLightGrid->RegisterFloat( "Light" );
      //Register the data member called "Con BA"
      m_iGridConBACode = mp_oLightGrid->RegisterFloat( "Con BA" );
      //Register the data member called "Ang BA"
      m_iGridAngBACode = mp_oLightGrid->RegisterFloat( "Ang BA" );
    }
    else
    {
      //Get the data member codes
      m_iGridLightCode = mp_oLightGrid->GetFloatDataCode( "Light" );
      m_iGridConBACode = mp_oLightGrid->GetFloatDataCode( "Con BA" );
      m_iGridAngBACode = mp_oLightGrid->GetFloatDataCode( "Ang BA" );
      if ( -1 == m_iGridLightCode || -1 == m_iGridConBACode || -1 == m_iGridAngBACode)
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
        stcErr.sMoreInfo = "\"Basal Light\" grid was incorrectly set up in the parameter file.  Data members missing.";
        throw( stcErr );
      }
    }

    iNumXCells = mp_oLightGrid->GetNumberXCells();
    iNumYCells = mp_oLightGrid->GetNumberYCells();

    //Set the basal area totals of trees for each grid cell to below the
    //minimum change threshold, to be sure that a light level is calculated for
    //each cell the first timestep; but first make sure that there's no grid map
    bMap = false;
    for (i = 0; i < iNumXCells; i++) {
      for (j = 0; j < iNumYCells; j++) {
        mp_oLightGrid->GetValueOfCell(i, j, m_iGridLightCode, &fLight);
        mp_oLightGrid->GetValueOfCell(i, j, m_iGridConBACode, &fConBA);
        mp_oLightGrid->GetValueOfCell(i, j, m_iGridAngBACode, &fAngBA);
        if (fLight > 0 || fConBA > 0 || fAngBA > 0) {
          bMap = true;
          break;
        }
      }
    }

    if (!bMap) {
      fConBA = -1 - m_fChangeThreshold;
      for (i = 0; i < iNumXCells; i++) {
        for (j = 0; j < iNumYCells; j++) {
          mp_oLightGrid->SetValueOfCell(i, j, m_iGridConBACode, fConBA);
        }
      }
    }

    delete[] p_iTemp;
  }
  catch ( modelErr & err )
  {
    delete[] p_iTemp;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_iTemp;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_iTemp;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clBasalAreaLight::DoShellSetup" ;
    throw( stcErr );
  }
}
///////////////////////////////////////////////////////////////////////////////
// GetParameterFileData
/////////////////////////////////////////////////////////////////////////////
void clSubstrateDepSeedSurvival::GetParameterFileData(
    xercesc::DOMDocument * p_oDoc) {
  doubleVal * p_fTemp = NULL; //for getting species-specific values
  try {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    clTreePopulation * p_oPop =
        (clTreePopulation *) mp_oSimManager->GetPopulationObject(
            "treepopulation");

    short int iNumSpecies = p_oPop->GetNumberOfSpecies(), i;

    //Declare our data arrays
    mp_iIndexes = new short int[iNumSpecies];
    //Load the indexes array
    //Make the list of indexes
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //Declare the canopy array values
    mp_fCanGroundScarSoilFav = new double[m_iNumBehaviorSpecies];
    mp_fCanGroundTipUpFav = new double[m_iNumBehaviorSpecies];
    mp_fCanGroundFreshLogFav = new double[m_iNumBehaviorSpecies];
    mp_fCanGroundDecLogFav = new double[m_iNumBehaviorSpecies];
    mp_fCanGroundForFlLitterFav = new double[m_iNumBehaviorSpecies];
    mp_fCanGroundForFlMossFav = new double[m_iNumBehaviorSpecies];

    //Set up our temp array - pre-load with this behavior's species
    p_fTemp = new doubleVal[m_iNumBehaviorSpecies];
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      p_fTemp[i].code = mp_iWhatSpecies[i];

    //Canopy scarified soil favorability
    FillSpeciesSpecificValue(p_oElement, "es_scarifiedSoilCanopyFav",
        "es_sscfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundScarSoilFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

    //Canopy tip-up mound favorability
    FillSpeciesSpecificValue(p_oElement, "es_tipUpCanopyFav", "es_tucfVal",
        p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundTipUpFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

    //Canopy fresh log favorability
    FillSpeciesSpecificValue(p_oElement, "es_freshLogCanopyFav", "es_flcfVal",
        p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundFreshLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

    //Canopy decayed log favorability
    FillSpeciesSpecificValue(p_oElement, "es_decayedLogCanopyFav",
        "es_dlcfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundDecLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

    //Canopy forest floor litter favorability
    FillSpeciesSpecificValue(p_oElement, "es_forestFloorLitterCanopyFav",
        "es_fflcfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundForFlLitterFav[mp_iIndexes[p_fTemp[i].code]]
          = p_fTemp[i].val;

    //Canopy forest floor moss favorability
    FillSpeciesSpecificValue(p_oElement, "es_forestFloorMossCanopyFav",
        "es_ffmcfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
    //Now transfer the values to the permanent array
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fCanGroundForFlMossFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

    //Verify that all values are between 0 and 1
    for (i = 0; i < m_iNumBehaviorSpecies; i++) {
      if (mp_fCanGroundScarSoilFav[i] < 0 || mp_fCanGroundScarSoilFav[i] > 1
          || mp_fCanGroundTipUpFav[i] < 0 || mp_fCanGroundTipUpFav[i] > 1
          || mp_fCanGroundFreshLogFav[i] < 0 || mp_fCanGroundFreshLogFav[i] > 1
          || mp_fCanGroundDecLogFav[i] < 0 || mp_fCanGroundDecLogFav[i] > 1
          || mp_fCanGroundForFlLitterFav[i] < 0
          || mp_fCanGroundForFlLitterFav[i] > 1 || mp_fCanGroundForFlMossFav[i]
          < 0 || mp_fCanGroundForFlMossFav[i] > 1) {
        modelErr stcErr;
        stcErr.sFunction = "clSubstrateDepSeedSurvival::GetParameterFileData";
        stcErr.sMoreInfo = "All substrate favorabilities must be between 0 and 1.";
        stcErr.iErrorCode = BAD_DATA;
        throw(stcErr);
      }
    }

    if (m_bUsesGap) {
      //Declare the gap array values
      mp_fGapMoundScarSoilFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundTipUpFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundFreshLogFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundDecLogFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundForFlLitterFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundForFlMossFav = new double[m_iNumBehaviorSpecies];

      //Load the gap values
      //Gap scarified soil favorability
      FillSpeciesSpecificValue(p_oElement, "es_scarifiedSoilGapFav",
          "es_ssgfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundScarSoilFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Gap tip-up mound favorability
      FillSpeciesSpecificValue(p_oElement, "es_tipUpGapFav", "es_tugfVal",
          p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundTipUpFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Gap fresh log favorability
      FillSpeciesSpecificValue(p_oElement, "es_freshLogGapFav", "es_flgfVal",
          p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundFreshLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Gap decayed log favorability
      FillSpeciesSpecificValue(p_oElement, "es_decayedLogGapFav", "es_dlgfVal",
          p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundDecLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Gap forest floor litter favorability
      FillSpeciesSpecificValue(p_oElement, "es_forestFloorLitterGapFav",
          "es_fflgfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundForFlLitterFav[mp_iIndexes[p_fTemp[i].code]]
            = p_fTemp[i].val;

      //Gap forest floor moss favorability
      FillSpeciesSpecificValue(p_oElement, "es_forestFloorMossGapFav",
          "es_ffmgfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundForFlMossFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Verify that all values are between 0 and 1
      for (i = 0; i < m_iNumBehaviorSpecies; i++) {
        if (mp_fGapMoundScarSoilFav[i] < 0 || mp_fGapMoundScarSoilFav[i] > 1
            || mp_fGapMoundTipUpFav[i] < 0 || mp_fGapMoundTipUpFav[i] > 1
            || mp_fGapMoundFreshLogFav[i] < 0 || mp_fGapMoundFreshLogFav[i] > 1
            || mp_fGapMoundDecLogFav[i] < 0 || mp_fGapMoundDecLogFav[i] > 1
            || mp_fGapMoundForFlLitterFav[i] < 0
            || mp_fGapMoundForFlLitterFav[i] > 1 || mp_fGapMoundForFlMossFav[i]
            < 0 || mp_fGapMoundForFlMossFav[i] > 1) {
          modelErr stcErr;
          stcErr.sFunction = "clSubstrateDepSeedSurvival::GetParameterFileData";
          stcErr.sMoreInfo = "All substrate favorabilities must be between 0 and 1.";
          stcErr.iErrorCode = BAD_DATA;
          throw(stcErr);
        }
      }
    }

    //If using microtopography...
    if (m_bUsesMicro) {
      //Declare the gap array values
      mp_fGapMoundScarSoilFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundTipUpFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundFreshLogFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundDecLogFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundForFlLitterFav = new double[m_iNumBehaviorSpecies];
      mp_fGapMoundForFlMossFav = new double[m_iNumBehaviorSpecies];

      //Proportion of plot that is mound
      FillSingleValue(p_oElement, "es_moundProportion", &m_fMoundProp, true);
      if (m_fMoundProp < 0 || m_fMoundProp > 1) {
        modelErr stcErr;
        stcErr.sFunction = "clSubstrateDepSeedSurvival::GetParameterFileData";
        stcErr.sMoreInfo = "Mound proportion must be between 0 and 1.";
        stcErr.iErrorCode = BAD_DATA;
        throw(stcErr);
      }

      //Mound scarified soil favorability
      FillSpeciesSpecificValue(p_oElement, "es_scarifiedSoilMoundFav",
          "es_ssmfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundScarSoilFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Mound tip-up mound favorability
      FillSpeciesSpecificValue(p_oElement, "es_tipUpMoundFav", "es_tumfVal",
          p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundTipUpFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Mound fresh log favorability
      FillSpeciesSpecificValue(p_oElement, "es_freshLogMoundFav", "es_flmfVal",
          p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundFreshLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Mound decayed log favorability
      FillSpeciesSpecificValue(p_oElement, "es_decayedLogMoundFav",
          "es_dlmfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundDecLogFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Mound forest floor litter favorability
      FillSpeciesSpecificValue(p_oElement, "es_forestFloorLitterMoundFav",
          "es_fflmfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundForFlLitterFav[mp_iIndexes[p_fTemp[i].code]]
            = p_fTemp[i].val;

      //Mound forest floor moss favorability
      FillSpeciesSpecificValue(p_oElement, "es_forestFloorMossMoundFav",
          "es_ffmmfVal", p_fTemp, m_iNumBehaviorSpecies, p_oPop, true);
      //Now transfer the values to the permanent array
      for (i = 0; i < m_iNumBehaviorSpecies; i++)
        mp_fGapMoundForFlMossFav[mp_iIndexes[p_fTemp[i].code]] = p_fTemp[i].val;

      //Verify that all values are between 0 and 1
      for (i = 0; i < m_iNumBehaviorSpecies; i++) {
        if (mp_fGapMoundScarSoilFav[i] < 0 || mp_fGapMoundScarSoilFav[i] > 1
            || mp_fGapMoundTipUpFav[i] < 0 || mp_fGapMoundTipUpFav[i] > 1
            || mp_fGapMoundFreshLogFav[i] < 0 || mp_fGapMoundFreshLogFav[i] > 1
            || mp_fGapMoundDecLogFav[i] < 0 || mp_fGapMoundDecLogFav[i] > 1
            || mp_fGapMoundForFlLitterFav[i] < 0
            || mp_fGapMoundForFlLitterFav[i] > 1 || mp_fGapMoundForFlMossFav[i]
            < 0 || mp_fGapMoundForFlMossFav[i] > 1) {
          modelErr stcErr;
          stcErr.sFunction = "clSubstrateDepSeedSurvival::GetParameterFileData";
          stcErr.sMoreInfo = "All substrate favorabilities must be between 0 and 1.";
          stcErr.iErrorCode = BAD_DATA;
          throw(stcErr);
        }
      }
    }

    delete[] p_fTemp;
  } catch (modelErr& err) {
    delete[] p_fTemp;
    throw(err);
  } catch (modelMsg & msg) {
    delete[] p_fTemp;
    throw(msg);
  } //non-fatal error
  catch (...) {
    delete[] p_fTemp;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clSubstrateDepSeedSurvival::GetParameterFileData";
    throw(stcErr);
  }
}
void clInsectInfestation::ReadParFile( xercesc::DOMDocument * p_oDoc, clTreePopulation *p_oPop )
{
  floatVal * p_fTempValues = NULL; //for getting species-specific values
  try {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    int i;

    //Declare our arrays
    mp_fIntercept = new float[m_iTotalNumSpecies];
    mp_fMax = new float[m_iTotalNumSpecies];
    mp_fX0 = new float[m_iTotalNumSpecies];
    mp_fXb = new float[m_iTotalNumSpecies];
    mp_fMinDBH = new float[m_iTotalNumSpecies];

    //Set up our floatVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Intercept parameter - rate of infestation at time 1
    FillSpeciesSpecificValue( p_oElement, "di_insectIntercept", "di_iiVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets and make sure all values are
    //between 0 and 1
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fIntercept[p_fTempValues[i].code] = p_fTempValues[i].val;
      if (mp_fIntercept[p_fTempValues[i].code] < 0 ||
          mp_fIntercept[p_fTempValues[i].code] > 1) {
        modelErr stcErr;
        strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
        strcpy( stcErr.cMoreInfo, "Intercept value must be between 0 and 1." );
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //Maximum infestation rate
    FillSpeciesSpecificValue( p_oElement, "di_insectMaxInfestation",
        "di_imiVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets and make sure all values are
    //between 0 and 1
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fMax[p_fTempValues[i].code] = p_fTempValues[i].val;
      if (mp_fMax[p_fTempValues[i].code] < 0 ||
          mp_fMax[p_fTempValues[i].code] > 1) {
        modelErr stcErr;
        strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
        strcpy( stcErr.cMoreInfo, "Max infestation value must be between 0 and 1." );
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //X0
    FillSpeciesSpecificValue( p_oElement, "di_insectX0", "di_ix0Val",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets and make sure all values are
    //not 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fX0[p_fTempValues[i].code] = p_fTempValues[i].val;
      if (mp_fX0[p_fTempValues[i].code] == 0) {
        modelErr stcErr;
        strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
        strcpy( stcErr.cMoreInfo, "X0 cannot be 0." );
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //Xb
    FillSpeciesSpecificValue( p_oElement, "di_insectXb", "di_ixbVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fXb[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //Minimum DBH to infest
    FillSpeciesSpecificValue( p_oElement, "di_insectMinDBH", "di_imdVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets and make sure all values are
    //greater than 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fMinDBH[p_fTempValues[i].code] = p_fTempValues[i].val;
      if (mp_fMinDBH[p_fTempValues[i].code] < 0) {
        modelErr stcErr;
        strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
        strcpy( stcErr.cMoreInfo, "Minimum DBH for insect infestation cannot be negative." );
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //Timestep to start infestation
    FillSingleValue( p_oElement, "di_insectStartTimestep", &m_iFirstTimestep, true );
    if (m_iFirstTimestep < 0) {
      modelErr stcErr;
      strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
      strcpy( stcErr.cMoreInfo, "Timestep to start infestation cannot be negative." );
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    strcpy( stcErr.cFunction, "clInsectInfestation::ReadParFile" );
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// ReadParameterFile()
////////////////////////////////////////////////////////////////////////////
void clLaggedPostHarvestGrowth::ReadParameterFile( xercesc::DOMDocument * p_oDoc )
{
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    doubleVal * p_fTempValues; //for getting species-specific values

    short int i; //loop counters

    mp_iIndexes = new short int[m_iNumTotalSpecies];

    //The rest are sized number of species to which this behavior applies
    mp_fMaxGrowthConstant = new double[m_iNumBehaviorSpecies];
    mp_fMaxGrowthDbhEffect = new double[m_iNumBehaviorSpecies];
    mp_fNciConstant = new double[m_iNumBehaviorSpecies];
    mp_fNciDbhEffect = new double[m_iNumBehaviorSpecies];
    mp_fTimeSinceHarvestRateParam = new double[m_iNumBehaviorSpecies];


    //If any of the types is seedling, error out
    for ( i = 0; i < m_iNumSpeciesTypeCombos; i++ )
      if ( clTreePopulation::sapling != mp_whatSpeciesTypeCombos[i].iType
          && clTreePopulation::adult != mp_whatSpeciesTypeCombos[i].iType )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clLaggedPostHarvestGrowth::ReadParameterFile" ;
        stcErr.sMoreInfo = "This behavior can only be applied to saplings and adults.";
        throw( stcErr );
      }

    //Make the list of indexes
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //Set up our doubleVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Fill the variables

    //Multiplier constant in Max potential growth term
    FillSpeciesSpecificValue( p_oElement, "gr_lagMaxGrowthConstant", "gr_lmgcVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fMaxGrowthConstant[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Effect of DBH on max potential growth term
    FillSpeciesSpecificValue( p_oElement, "gr_lagMaxGrowthDbhEffect", "gr_lmgdbheVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fMaxGrowthDbhEffect[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Effect of NCI on growth
    FillSpeciesSpecificValue( p_oElement, "gr_lagNciConstant", "gr_lncicVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fNciConstant[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Effect of DBH on NCI term
    FillSpeciesSpecificValue( p_oElement, "gr_lagNciDbhEffect", "gr_lncidbheVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fNciDbhEffect[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Rate parameter for time since harvest lag effect
    FillSpeciesSpecificValue( p_oElement, "gr_lagTimeSinceHarvestRateParam", "gr_ltshrpVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fTimeSinceHarvestRateParam[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //NCI radius
    FillSingleValue( p_oElement, "gr_lagNciDistanceRadius", & m_fNciDistanceRadius, true );


    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clLaggedPostHarvestGrowth::ReadParameterFile" ;
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clSenescenceMort::DoShellSetup( xercesc::DOMDocument * p_oDoc )
{
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int i; //loop counter

    m_iNumTotalSpecies = p_oPop->GetNumberOfSpecies();

    //Declare the floatVal arrays and populate with the species to which this
    //behavior applies
    mp_fRandomAlpha = new floatVal[m_iNumBehaviorSpecies];
    mp_fRandomBeta = new floatVal[m_iNumBehaviorSpecies];
    mp_fDbhAtOnset = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    {
      mp_fRandomAlpha[i].code = mp_iWhatSpecies[i];
      mp_fRandomBeta[i].code = mp_iWhatSpecies[i];
      mp_fDbhAtOnset[i].code = mp_iWhatSpecies[i];
    }

    //Capture the values from the parameter file

    //Random mortality alpha
    FillSpeciesSpecificValue( p_oElement, "mo_senescenceAlpha", "mo_saVal",
        mp_fRandomAlpha, m_iNumBehaviorSpecies, p_oPop, true );


    //Random mortality beta
    FillSpeciesSpecificValue( p_oElement, "mo_senescenceBeta", "mo_sbVal",
        mp_fRandomBeta, m_iNumBehaviorSpecies, p_oPop, true );


    //Dbh at onset of senescence
    FillSpeciesSpecificValue( p_oElement, "mo_dbhAtOnsetOfSenescence",
        "mo_daoosVal", mp_fDbhAtOnset, m_iNumBehaviorSpecies, p_oPop, true );


    //Max dbh - that of asymptotic max mortality
    FillSingleValue( p_oElement, "mo_dbhAtAsympMaxMort", & m_iMaxDbh, false );

    CalculateMortalityProbability();

    //Make sure that only saplings and adults were assigned to this behavior
    for ( i = 0; i < m_iNumSpeciesTypeCombos; i++ )
      if ( clTreePopulation::sapling != mp_whatSpeciesTypeCombos->iType
          && clTreePopulation::adult != mp_whatSpeciesTypeCombos->iType )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        strcpy( stcErr.cFunction, "clSenescenceMort::DoShellSetup" );
        strcpy( stcErr.cMoreInfo, "This behavior cannot be applied to seedlings" );
        throw( stcErr );
      }
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    strcpy( stcErr.cFunction, "clSenescenceMort::DoShellSetup" );
    throw( stcErr );
  }
}
//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
//////////////////////////////////////////////////////////////////////////////
void clBrowsedRelativeGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int i, j, iNumTypes = p_oPop->GetNumberOfTypes();

    m_iNumSpecies = p_oPop->GetNumberOfSpecies();

    //Set up our doubleVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    m_ifNumberYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays
    mp_fUnbrowsedS = new double[m_iNumSpecies];
    mp_fBrowsedS = new double[m_iNumSpecies];
    mp_fUnbrowsedA = new double[m_iNumSpecies];
    mp_fBrowsedA = new double[m_iNumSpecies];
    mp_fUnbrowsedDiamExp = new double[m_iNumSpecies];
    mp_fBrowsedDiamExp = new double[m_iNumSpecies];

    //Unbrowsed S
    FillSpeciesSpecificValue(p_oElement, "gr_slopeGrowthResponse", "gr_sgrVal",
                          p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fUnbrowsedS[p_fTempValues[i].code] = p_fTempValues[i].val;


    //Unbrowsed A
    FillSpeciesSpecificValue(p_oElement, "gr_asympDiameterGrowth", "gr_adgVal",
                          p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fUnbrowsedA[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Unbrowsed diameter exponent
    FillSpeciesSpecificValue( p_oElement, "gr_relGrowthDiamExp", "gr_rgdeVal",
                          p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fUnbrowsedDiamExp[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Browsed S
    FillSpeciesSpecificValue(p_oElement, "gr_browsedSlopeGrowthResponse",
       "gr_bsgrVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fBrowsedS[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Browsed A
    FillSpeciesSpecificValue(p_oElement, "gr_browsedAsympDiameterGrowth",
       "gr_badgVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true);
    for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_fBrowsedA[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Browsed diameter exponent
    FillSpeciesSpecificValue( p_oElement, "gr_browsedRelGrowthDiamExp",
        "gr_brgdeVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fBrowsedDiamExp[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Scale the browsed and unbrowsed S values
    for (i = 0; i < m_iNumBehaviorSpecies; i++) {
      if (mp_fBrowsedS[mp_iWhatSpecies[i]] != 0.0) {
        mp_fBrowsedS[mp_iWhatSpecies[i]] =
                                          mp_fBrowsedA[mp_iWhatSpecies[i]] /
                                          mp_fBrowsedS[mp_iWhatSpecies[i]];
      }
      if (mp_fUnbrowsedS[mp_iWhatSpecies[i]] != 0.0) {
        mp_fUnbrowsedS[mp_iWhatSpecies[i]] =
                                           mp_fUnbrowsedA[mp_iWhatSpecies[i]] /
                                           mp_fUnbrowsedS[mp_iWhatSpecies[i]];
      }
    }

    //Collect the "Light" codes
    mp_iLightCodes = new short int *[m_iNumSpecies];
    mp_iBrowsedCodes = new short int *[m_iNumSpecies];
    for (i = 0; i < m_iNumSpecies; i++) {
      mp_iLightCodes[i] = new short int[iNumTypes];
      mp_iBrowsedCodes[i] = new short int[iNumTypes];
      for (j = 0; j < iNumTypes; j++) {
        mp_iLightCodes[i][j] = -1;
        mp_iBrowsedCodes[i][j] = -1;
      }
    }
    for (i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      mp_iLightCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                    [mp_whatSpeciesTypeCombos[i].iType] =
            mp_oGrowthOrg->GetLightCode(mp_whatSpeciesTypeCombos[i].iSpecies,
                                           mp_whatSpeciesTypeCombos[i].iType );
      if (-1 ==  mp_iLightCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                               [mp_whatSpeciesTypeCombos[i].iType] )
      {
        modelErr stcErr;
        stcErr.sFunction = "clBrowsedRelativeGrowth::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a required light behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }

      mp_iBrowsedCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                      [mp_whatSpeciesTypeCombos[i].iType] =
            p_oPop->GetBoolDataCode("Browsed",
                                    mp_whatSpeciesTypeCombos[i].iSpecies,
                                    mp_whatSpeciesTypeCombos[i].iType );
      if (-1 ==  mp_iBrowsedCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                                 [mp_whatSpeciesTypeCombos[i].iType] )
      {
        modelErr stcErr;
        stcErr.sFunction = "clBrowsedRelativeGrowth::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have the browse behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clBrowsedRelativeGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
//---------------------------------------------------------------------------
// MichMenPhotoinhibition.cpp
//---------------------------------------------------------------------------
#include "MichMenPhotoinhibition.h"
#include "TreePopulation.h"
#include "SimManager.h"
#include "ParsingFunctions.h"
#include "GrowthOrg.h"
#include <math.h>
#include <sstream>

//////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////*/
clMichMenPhotoinhibition::clMichMenPhotoinhibition( clSimManager * p_oSimManager ) :
  clWorkerBase( p_oSimManager ), clBehaviorBase( p_oSimManager ), clGrowthBase( p_oSimManager )
{
  try
  {
    m_sNameString = "michmenphotogrowthshell";
    m_sXMLRoot = "MichaelisMentenPhotoinhibitionGrowth";

    m_iGrowthMethod = height_only;
    mp_fAlpha = NULL;
    mp_fBeta = NULL;
    mp_fPhi = NULL;
    mp_fD = NULL;
    mp_iIndexes = NULL;

    m_fYearsPerTimestep = 0;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clMichMenPhotoinhibition::clMichMenPhotoinhibition" ;
    throw( stcErr );
  }
}

//////////////////////////////////////////////////////////////////////////////
// Destructor
/////////////////////////////////////////////////////////////////////////////*/
clMichMenPhotoinhibition::~clMichMenPhotoinhibition()
{
  delete[] mp_fAlpha;
  delete[] mp_fBeta;
  delete[] mp_fPhi;
  delete[] mp_fD;
  delete[] mp_iIndexes;
}

//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
/////////////////////////////////////////////////////////////////////////////*/
void clMichMenPhotoinhibition::DoShellSetup( DOMDocument * p_oDoc )
{
  floatVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int i;

    //Get number of years per timestep
    m_fYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays we'd like read
    mp_fAlpha = new float[m_iNumBehaviorSpecies];
    mp_fBeta = new float[m_iNumBehaviorSpecies];
    mp_fPhi = new float[m_iNumBehaviorSpecies];
    mp_fD = new float[m_iNumBehaviorSpecies];
    mp_iIndexes = new int[p_oPop->GetNumberOfSpecies()];

    //Set up the array indexes
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //Declare the species-specific temp array and pre-load with the species that
    //this behavior affects
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Alpha
    FillSpeciesSpecificValue( p_oElement, "gr_mmPhotGrowthAlpha",
        "gr_mmpgaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fAlpha[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Beta
    FillSpeciesSpecificValue( p_oElement, "gr_mmPhotGrowthBeta",
        "gr_mmpgbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array while making sure none of them
    //are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val == 0) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clMichMenPhotoinhibition::DoShellSetup";
        stcErr.sMoreInfo = "Beta values cannot equal 0.";
        throw(stcErr);
      }
      mp_fBeta[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }


    //D
    FillSpeciesSpecificValue( p_oElement, "gr_mmPhotGrowthD",
        "gr_mmpgdVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fD[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Phi
    FillSpeciesSpecificValue( p_oElement, "gr_mmPhotGrowthPhi",
        "gr_mmpgpVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fPhi[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    delete[] p_fTempValues;

    //Make sure all species/type combos have "Light" registered
    for ( int i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      if ( -1 == mp_oGrowthOrg->GetLightCode(mp_whatSpeciesTypeCombos[i].iSpecies,
                                           mp_whatSpeciesTypeCombos[i].iType ) )
      {
        modelErr stcErr;
        stcErr.sFunction = "clRelativeGrowth::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a required light behavior.";
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clMichMenPhotoinhibition::DoShellSetup" ;
    throw( stcErr );
  }
}
Esempio n. 17
0
////////////////////////////////////////////////////////////////////////////
// GetData()
////////////////////////////////////////////////////////////////////////////
void clStormLight::GetData( xercesc::DOMDocument * p_oDoc )
{
  try
  {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);

    //**********************************************
    //Read values from the parameter file
    //**********************************************
    //Get the type of stochasticity
    int iTemp;
    FillSingleValue( p_oElement, "li_stormLightStoch", & iTemp, true );

    //Make sure the value is valid
    if ( deterministic_pdf == iTemp )
    {
      m_iStochasticity = deterministic_pdf;
    }
    else if ( lognormal_pdf == iTemp )
    {
      m_iStochasticity = lognormal_pdf;
    }
    else if ( normal_pdf == iTemp )
    {
      m_iStochasticity = normal_pdf;
    }
    else
    {
      modelErr stcErr;
      stcErr.sFunction = "clStormLight::GetData" ;
      std::stringstream s;
      s << "Unrecognized value for stochasticity: " << iTemp;
      stcErr.sMoreInfo = s.str();
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //Max radius
    FillSingleValue( p_oElement, "li_stormLightRadius", & m_fMaxRadius, true );

    //The slope of the light function
    FillSingleValue( p_oElement, "li_stormLightSlope", & m_fSlope, true );

    //The intercept of the light function
    FillSingleValue( p_oElement, "li_stormLightIntercept", & m_fIntercept, true );

    //The max time since damage that a tree can count toward light calculations
    FillSingleValue( p_oElement, "li_stormLightMaxDmgTime", & m_iMaxDmgTime, true );

    //The max time since damage that a snag can count toward light calculations
    FillSingleValue( p_oElement, "li_stormLightSnagMaxDmgTime", & m_iMaxSnagDmgTime, true );

    //Minimum number of trees for full canopy
    FillSingleValue( p_oElement, "li_stormLightMinFullCanopy", & m_fMinCanopyTrees, true );
    //Error if this is negative
    if (m_fMinCanopyTrees < 0) {
      modelErr stcErr;
      stcErr.sFunction = "clStormLight::GetData" ;
      stcErr.sMoreInfo = "Minimum number of trees for full canopy cannot be less than 0.";
      stcErr.iErrorCode = BAD_DATA;
      throw( stcErr );
    }

    //If a stochastic method is used, the standard deviation
    if ( deterministic_pdf != m_iStochasticity )
    {
      FillSingleValue( p_oElement, "li_stormLightRandPar", & m_fRandParameter, true );
    }

    //**********************************************
    //Set up the light grid
    //**********************************************
    //Is there already a grid from the parameter file?
    mp_oLightGrid = mp_oSimManager->GetGridObject( "Storm Light" );

    if ( !mp_oLightGrid )
    {
      //Create the grid with one float data member
      mp_oLightGrid = mp_oSimManager->CreateGrid( "Storm Light", 0, 1, 0, 0 );
      //Register the data member - called "Light"
      m_iGridLightCode = mp_oLightGrid->RegisterFloat( "Light" );
    }
    else
    {
      //Get the data member code
      m_iGridLightCode = mp_oLightGrid->GetFloatDataCode( "Light" );
      if ( -1 == m_iGridLightCode )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clStormLight::GetData" ;
        stcErr.sMoreInfo = "\"Storm Light\" grid was incorrectly set up in the parameter file.  Missing float \"Light\".";
        throw( stcErr );
      }
    }

    //**********************************************
    //Get storm damage codes
    //**********************************************
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    int i, j, iNumSpecies = p_oPop->GetNumberOfSpecies();
    m_iNumTypes = 2;

    mp_iStmDmgCodes = new int * [m_iNumTypes];
    for ( i = 0; i < m_iNumTypes; i++ )
    {
      mp_iStmDmgCodes[i] = new int[iNumSpecies];
      for ( j = 0; j < iNumSpecies; j++ )
      {
        mp_iStmDmgCodes[i] [j] = -1;
      }
    }

    //Get the values for adults and snags
    for ( i = 0; i < iNumSpecies; i++ )
    {
      mp_iStmDmgCodes[adult] [i] = p_oPop->GetIntDataCode( "stm_dmg", i, clTreePopulation::adult );
      mp_iStmDmgCodes[snag] [i] = p_oPop->GetIntDataCode( "stm_dmg", i, clTreePopulation::snag );
    }
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clStormLight::GetData" ;
    throw( stcErr );
  }
}
Esempio n. 18
0
//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
//////////////////////////////////////////////////////////////////////////////
void clRelativeGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    doubleVal * p_fTempValues; //for getting species-specific values
    short int iNumSpecies = mp_oGrowthOrg->GetNumberOfSpecies(), i;

    //Set up our doubleVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    m_iNumberYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays we'd like read
    if (diameter_auto == m_iGrowthMethod || diameter_only == m_iGrowthMethod) {
      mp_fAsympDiamGrowth = new double[iNumSpecies];
      mp_fSlopeDiamGrowthResponse = new double[iNumSpecies];
    } else {
      mp_fAsympHeightGrowth = new double[iNumSpecies];
      mp_fSlopeHeightGrowthResponse = new double[iNumSpecies];
    }

    mp_fExp = new double[iNumSpecies];

    if ( m_bConstRadialLimited )
    {
      mp_fAdultConstRadInc = new double[iNumSpecies];
    }

    if ( m_bConstBasalAreaLimited )
    {
      mp_fAdultConstBAInc = new double[iNumSpecies];
    }

    //Read the base variables
    GetParameterFileData( p_oDoc );

    if (diameter_auto == m_iGrowthMethod || diameter_only == m_iGrowthMethod) {
      //Get the diameter exponent
      FillSpeciesSpecificValue( p_oElement, "gr_relGrowthDiamExp", "gr_rgdeVal", p_fTempValues,
           m_iNumBehaviorSpecies, p_oPop, true );
    } else {
      //Get the height exponent
      FillSpeciesSpecificValue( p_oElement, "gr_relHeightGrowthHeightExp", "gr_rhgheVal", p_fTempValues,
           m_iNumBehaviorSpecies, p_oPop, true );
    }

    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fExp[p_fTempValues[i].code] = p_fTempValues[i].val;


    //Make sure all species/type combos have "Light" registered
    for ( int i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      if ( -1 == mp_oGrowthOrg->GetLightCode(mp_whatSpeciesTypeCombos[i].iSpecies,
                                           mp_whatSpeciesTypeCombos[i].iType ) )
      {
        modelErr stcErr;
        stcErr.sFunction = "clRelativeGrowth::DoShellSetup";
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a required light behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clRelativeGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
Esempio n. 19
0
void clLightFilter::GetData(xercesc::DOMDocument * p_oDoc)
{
  try
  {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    clTreePopulation * p_oPop = (clTreePopulation *) mp_oSimManager->GetPopulationObject("treepopulation");
    const char * cCounterLabel = "lf_count",
         * cZLabel = "z",
         * cLightLabel = "Light";
    float fTemp;
    short int iNumTypes = p_oPop->GetNumberOfTypes(), i, j;

    m_iNumSpecies = p_oPop->GetNumberOfSpecies();

    //Declare the data member code arrays
    mp_iCounterCodes = new short int * [m_iNumSpecies];
    mp_iZCodes = new short int * [m_iNumSpecies];
    mp_iLightCodes = new short int * [m_iNumSpecies];
    mp_iHeightCodes = new short int * [m_iNumSpecies];

    for (i = 0; i < m_iNumSpecies; i++)
    {

      mp_iCounterCodes[i] = new short int[iNumTypes];
      mp_iZCodes[i] = new short int[iNumTypes];
      mp_iLightCodes[i] = new short int[iNumTypes];
      mp_iHeightCodes[i] = new short int[iNumTypes];

      //Initialize all values to -1
      for (j = 0; j < iNumTypes; j++)
      {

        mp_iCounterCodes[i] [j] = -1;
        mp_iZCodes[i] [j] = -1;
        mp_iLightCodes[i] [j] = -1;
        mp_iHeightCodes[i] [j] = -1;

      }
    }

    //Get the parameter file values

    //Light extinction coefficient
    FillSingleValue(p_oElement, "lf_lightExtinctionCoefficient", & m_fLightExtinctionCoefficient, true);

    //Convert to 1/mm units from 1/m units
    m_fLightExtinctionCoefficient /= 1000;

    //Height of fern layer
    FillSingleValue(p_oElement, "lf_heightOfFilter", & fTemp, true);

    //Convert the height of fern layer to mm - I'm willfully int casting and
    //throwing away sub-mm precision
    m_iFilterHeight = (int)(fTemp * 1000);

    //Register the data members
    for (i = 0; i < m_iNumSpeciesTypeCombos; i++) {
      mp_iCounterCodes[mp_whatSpeciesTypeCombos[i].iSpecies] [mp_whatSpeciesTypeCombos[i].iType] =
           p_oPop->RegisterInt(cCounterLabel, mp_whatSpeciesTypeCombos[i].iSpecies, mp_whatSpeciesTypeCombos[i].iType);

      mp_iZCodes[mp_whatSpeciesTypeCombos[i].iSpecies] [mp_whatSpeciesTypeCombos[i].iType] =
           p_oPop->RegisterInt(cZLabel, mp_whatSpeciesTypeCombos[i].iSpecies, mp_whatSpeciesTypeCombos[i].iType);

      //Get the codes for the "Light" and "Height" data member
      mp_iLightCodes[mp_whatSpeciesTypeCombos[i].iSpecies] [mp_whatSpeciesTypeCombos[i].iType] =
           p_oPop->GetFloatDataCode(cLightLabel, mp_whatSpeciesTypeCombos[i].iSpecies, mp_whatSpeciesTypeCombos[i].iType);


      mp_iHeightCodes[mp_whatSpeciesTypeCombos[i].iSpecies] [mp_whatSpeciesTypeCombos[i].iType] =
           p_oPop->GetHeightCode(mp_whatSpeciesTypeCombos[i].iSpecies, mp_whatSpeciesTypeCombos[i].iType);

      //If the return code for Light is -1, throw an error
      if (-1 == mp_iLightCodes[mp_whatSpeciesTypeCombos[i].iSpecies] [mp_whatSpeciesTypeCombos[i].iType]) {
        modelErr stcErr;
        stcErr.sFunction = "clLightFilter::GetData";
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a light behavior compatible with light filtering.";
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sMoreInfo = s.str();
        throw(stcErr);
      }
    }
  }
  catch (modelErr& err)
  {
    throw(err);
  }
  catch (modelMsg & msg)
  {
    throw(msg);
  } //non-fatal error
  catch (...)
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clLightFilter::GetData";
    throw(stcErr);
  }
}
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clBrowsedStochasticMortality::DoShellSetup( xercesc::DOMDocument * p_oDoc )
{
  floatVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    float fYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();
    short int i, j, iNumTypes = p_oPop->GetNumberOfTypes();

    m_iNumSpecies = p_oPop->GetNumberOfSpecies();

    //Declare the arrays we'd like read
    mp_fBrowsedMortProb = new float[m_iNumSpecies];
    mp_fUnbrowsedMortProb = new float[m_iNumSpecies];

    //Declare the species-specific temp array and pre-load with the species
    //that this behavior affects
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Browsed mortality probability
    FillSpeciesSpecificValue( p_oElement, "mo_browsedRandomMortality", "mo_brmVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array, making sure all values are
    //between 0 and 1 and translating to a timestep probability
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    {
      if ( 0 > p_fTempValues[i].val || 1 < p_fTempValues[i].val )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clBrowsedStochasticMortality::DoShellSetup" ;
        stcErr.sMoreInfo = "All values for probability of mortality must be between 0 and 1.";
        throw( stcErr );
      }
      mp_fBrowsedMortProb[p_fTempValues[i].code] = 1 - pow( 1 - p_fTempValues[i].val, fYearsPerTimestep );
    }

    //Unbrowsed mortality probability
    FillSpeciesSpecificValue( p_oElement, "mo_stochasticMortRate", "mo_smrVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array, making sure all values are
    //between 0 and 1 and translating to a timestep probability
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    {
      if ( 0 > p_fTempValues[i].val || 1 < p_fTempValues[i].val )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clBrowsedStochasticMortality::DoShellSetup" ;
        stcErr.sMoreInfo = "All values for probability of mortality must be between 0 and 1.";
        throw( stcErr );
      }
      mp_fUnbrowsedMortProb[p_fTempValues[i].code] = 1 - pow( 1 - p_fTempValues[i].val, fYearsPerTimestep );
    }

    //Collect the "Browsed" codes
    mp_iBrowsedCodes = new short int *[m_iNumSpecies];
    for (i = 0; i < m_iNumSpecies; i++) {
      mp_iBrowsedCodes[i] = new short int[iNumTypes];
      for (j = 0; j < iNumTypes; j++) {
        mp_iBrowsedCodes[i][j] = -1;
      }
    }
    for (i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      mp_iBrowsedCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                       [mp_whatSpeciesTypeCombos[i].iType] =
                           p_oPop->GetBoolDataCode("Browsed",
                               mp_whatSpeciesTypeCombos[i].iSpecies,
                               mp_whatSpeciesTypeCombos[i].iType );
      if (-1 == mp_iBrowsedCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                                 [mp_whatSpeciesTypeCombos[i].iType] )
      {
        modelErr stcErr;
        stcErr.sFunction = "clBrowsedStochasticMortality::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
            << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
            << mp_whatSpeciesTypeCombos[i].iType
            << " does not have the browse behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clBrowsedStochasticMortality::DoShellSetup" ;
    throw( stcErr );
  }
}
//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
//////////////////////////////////////////////////////////////////////////////
void clDoubleMMRelGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL;
  try
  {
    short int iNumSpecies = mp_oGrowthOrg->GetNumberOfSpecies(), i;

    m_iNumberYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays we'd like read
    mp_fAsympDiamGrowth = new double[iNumSpecies];
    mp_fSlopeDiamGrowthResponse = new double[iNumSpecies];
    mp_fResourceInfluence = new double[iNumSpecies];

    //Read the base variables with the base class function
    GetParameterFileData( p_oDoc );

    //Now read this behavior's additional parameter
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    clTreePopulation *p_oPop = (clTreePopulation*) mp_oSimManager->GetPopulationObject("treepopulation");
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];
    FillSpeciesSpecificValue( p_oElement, "gr_diamDoubleMMResourceInfluence", "gr_ddmmriVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
    {
      mp_fResourceInfluence[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //UNSCALE the slope of growth response parameter to undo what the base
    //function did because we don't want it
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      if ( mp_fSlopeDiamGrowthResponse[mp_iWhatSpecies[i]] != 0.0 )
        mp_fSlopeDiamGrowthResponse[mp_iWhatSpecies[i]] =
            ( 1 / mp_fSlopeDiamGrowthResponse[mp_iWhatSpecies[i]] ) * mp_fAsympDiamGrowth[mp_iWhatSpecies[i]];

    //Make sure all species/type combos have "Light" registered
    for ( i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      if ( -1 == mp_oGrowthOrg->GetLightCode( mp_whatSpeciesTypeCombos[i].iSpecies, mp_whatSpeciesTypeCombos[i].iType ) )
      {
        modelErr stcErr;
        stcErr.sFunction = "clDoubleMMRelGrowth::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a required light behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    //Get the "Resource" grid
    mp_oResourceGrid = mp_oSimManager->GetGridObject( "Resource" );
    if ( NULL == mp_oResourceGrid )
    {
      modelErr stcErr;
      stcErr.sFunction = "clDoubleMMRelGrowth::DoShellSetup" ;
      stcErr.sMoreInfo = "Can't find required grid object \"Resources\".";
      stcErr.iErrorCode = CANT_FIND_OBJECT;
      throw( stcErr );
    }

    m_iResourceCode = mp_oResourceGrid->GetFloatDataCode( "Resource" );
    if ( -1 == m_iResourceCode )
    {
      modelErr stcErr;
      stcErr.sFunction = "clDoubleMMRelGrowth::DoShellSetup" ;
      stcErr.sMoreInfo = "Grid object \"Resources\" is set up incorrectly.";
      stcErr.iErrorCode = CANT_FIND_OBJECT;
      throw( stcErr );
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clDoubleMMRelGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
Esempio n. 22
0
//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
//////////////////////////////////////////////////////////////////////////////
void clPRSemiStochGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    floatVal * p_fTempValues; //for getting species-specific values
    short int iNumSpecies = p_oPop->GetNumberOfSpecies(), i;

    //Make the list of indexes
    mp_iIndexes = new short int[iNumSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //Declare the arrays we'd like read
    mp_fHeightThreshold = new float[m_iNumBehaviorSpecies];
    mp_fA = new float[m_iNumBehaviorSpecies];
    mp_fB = new float[m_iNumBehaviorSpecies];
    mp_fMeanDiam = new float[m_iNumBehaviorSpecies];
    mp_fDiamStdDev = new float[m_iNumBehaviorSpecies];

    //Declare the species-specific temp array and pre-load with the species that
    //this behavior affects
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Height threshold for stochastic growth
    FillSpeciesSpecificValue( p_oElement, "gr_prStochHiteThreshold", "gr_pshtVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fHeightThreshold[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //"a" for deterministic growth
    FillSpeciesSpecificValue( p_oElement, "gr_prStochDetermA", "gr_psdaVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fA[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //"b" for deterministic growth
    FillSpeciesSpecificValue( p_oElement, "gr_prStochDetermB", "gr_psdbVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fB[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Mean diam for stochastic growth
    FillSpeciesSpecificValue( p_oElement, "gr_prStochMeanDBH", "gr_psmdVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fMeanDiam[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    //Standard deviation for stochastic growth
    FillSpeciesSpecificValue( p_oElement, "gr_prStochStdDev", "gr_pssdVal", p_fTempValues,
        m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fDiamStdDev[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clPRSemiStochGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
//---------------------------------------------------------------------------
// MichMenNegGrowth.cpp
//---------------------------------------------------------------------------
#include "MichMenNegGrowth.h"
#include "TreePopulation.h"
#include "SimManager.h"
#include "ParsingFunctions.h"
#include "GrowthOrg.h"
#include <math.h>
#include <sstream>

//////////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////////
clMichMenNegGrowth::clMichMenNegGrowth( clSimManager * p_oSimManager ) :
  clWorkerBase( p_oSimManager ), clBehaviorBase( p_oSimManager ), clGrowthBase( p_oSimManager )
{
  try
  {
    m_sNameString = "michmenneggrowthshell";
    m_sXMLRoot = "MichaelisMentenNegativeGrowth";

    m_iGrowthMethod = height_only;
    mp_fAlpha = NULL;
    mp_fBeta = NULL;
    mp_fPhi = NULL;
    mp_fGamma = NULL;
    mp_iIndexes = NULL;
    mp_iAutoCorrCodes = NULL;
    mp_fStdDev = NULL;
    mp_fProbAutoCorr = NULL;

    m_iNewTreeFloats += 1; //make sure we leave room for the growth data member

    m_iYearsPerTimestep = 0;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clMichMenNegGrowth::clMichMenNegGrowth" ;
    throw( stcErr );
  }
}

//////////////////////////////////////////////////////////////////////////////
// Destructor
/////////////////////////////////////////////////////////////////////////////*/
clMichMenNegGrowth::~clMichMenNegGrowth()
{
  delete[] mp_fAlpha;
  delete[] mp_fBeta;
  delete[] mp_fPhi;
  delete[] mp_fGamma;
  delete[] mp_iIndexes;
  delete[] mp_fStdDev;
  delete[] mp_fProbAutoCorr;
  for (int i = 0; i < m_iNumBehaviorSpecies; i++)
    delete[] mp_iAutoCorrCodes[i];
  delete[] mp_iAutoCorrCodes;
}

//////////////////////////////////////////////////////////////////////////////
// RegisterTreeDataMembers()
/////////////////////////////////////////////////////////////////////////////*/
void clMichMenNegGrowth::RegisterTreeDataMembers() {
 try {
   clTreePopulation *p_oPop = (clTreePopulation *)mp_oSimManager->GetPopulationObject("treepopulation");
   short int iNumTypes = p_oPop->GetNumberOfTypes(), //number of unique types
             iNumTotalSpecies = p_oPop->GetNumberOfSpecies(),
             i, j;           //loop counters

   //Call the base class version as well
   clGrowthBase::RegisterTreeDataMembers();

   mp_iIndexes = new int[iNumTotalSpecies];
   for (i = 0; i < iNumTotalSpecies; i++) mp_iIndexes[i] = -1;

    //Set up the array indexes
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

   //Declare the temp. types array to be as big as the combo list to make
   //sure we have space for everything, and initialize values to -1
   mp_iAutoCorrCodes = new short int*[m_iNumBehaviorSpecies];
   for (i = 0; i < m_iNumBehaviorSpecies; i++)
      mp_iAutoCorrCodes[i] = new short int[iNumTypes];
   for (i = 0; i < m_iNumBehaviorSpecies; i++)
     for (j = 0; j < iNumTypes; j++)
       mp_iAutoCorrCodes[i][j] = -1;


   //Register the variables for what's actually in our type/species
   //combos
   for (i = 0; i < m_iNumSpeciesTypeCombos; i++) {
     //Register the code and capture it
     mp_iAutoCorrCodes[mp_iIndexes[mp_whatSpeciesTypeCombos[i].iSpecies]]
                      [mp_whatSpeciesTypeCombos[i].iType] =
       p_oPop->RegisterFloat("autocorr", mp_whatSpeciesTypeCombos[i].iSpecies,
                            mp_whatSpeciesTypeCombos[i].iType);
   }
 }
 catch (modelErr&err) {throw(err);}
 catch (modelMsg &msg) {throw(msg);} //non-fatal error
 catch (...) {
   modelErr stcErr;
   stcErr.iErrorCode = UNKNOWN;
   stcErr.sFunction = "clAbsoluteGrowth::RegisterTreeDataMembers";
   throw(stcErr);
 }
}

//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
/////////////////////////////////////////////////////////////////////////////*/
void clMichMenNegGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int i;


    //Get number of years per timestep
    m_iYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays we'd like read
    mp_fAlpha = new double[m_iNumBehaviorSpecies];
    mp_fBeta = new double[m_iNumBehaviorSpecies];
    mp_fPhi = new double[m_iNumBehaviorSpecies];
    mp_fGamma = new double[m_iNumBehaviorSpecies];
    mp_fStdDev = new double[m_iNumBehaviorSpecies];
    mp_fProbAutoCorr = new double[m_iNumBehaviorSpecies];

    //Declare the species-specific temp array and pre-load with the species that
    //this behavior affects
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Alpha
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthAlpha",
        "gr_mmngaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fAlpha[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Beta
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthBeta",
        "gr_mmngbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array while making sure none of them
    //are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val == 0) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clMichMenNegGrowth::DoShellSetup";
        stcErr.sMoreInfo = "Beta values cannot equal 0.";
        throw(stcErr);
      }
      mp_fBeta[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }


    //Gamma
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthGamma",
        "gr_mmnggVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fGamma[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Phi
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthPhi",
        "gr_mmngpVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fPhi[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //standard deviation of growth stochasticity in cm/year
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthStdDev",
        "gr_mmngsdVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fStdDev[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //one year probability of autocorrelation
    FillSpeciesSpecificValue( p_oElement, "gr_mmNegGrowthAutoCorrProb",
        "gr_mmngacpVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val < 0 || p_fTempValues[i].val > 1) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clMichMenNegGrowth::DoShellSetup";
        stcErr.sMoreInfo = "Autocorrelation probability must be between 0 and 1.";
        throw(stcErr);
      }
      mp_fProbAutoCorr[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    delete[] p_fTempValues;

    //Make sure all species/type combos have "Light" registered
    for ( int i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      if ( -1 == mp_oGrowthOrg->GetLightCode(mp_whatSpeciesTypeCombos[i].iSpecies,
                                           mp_whatSpeciesTypeCombos[i].iType ) )
      {
        modelErr stcErr;
        stcErr.sFunction = "clRelativeGrowth::DoShellSetup";
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have a required light behavior.";
        stcErr.sMoreInfo = s.str();
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clMichMenNegGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
Esempio n. 24
0
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clQuadratGLILight::DoShellSetup(xercesc::DOMDocument * p_oDoc) {
  try
  {
    DOMElement *p_oElement = GetParentParametersElement(p_oDoc);
    clBehaviorBase * p_oTemp; //for searching for a behavior
    clLightBase * p_oGli; //quadrat gli light object
    float fAngChunk;
    short int iHalfAzi, //for partitioning the sky hemisphere
    iNumXCells, iNumYCells, //number X and Y grid cells
    i, j; //loop counters

    //**********************************************
    //Read values from the parameter file
    //**********************************************
    m_iNumAltAng = 0;
    m_iNumAziAng = 0;
    m_fMinSunAngle = 0;

    //Number of alitude angles
    FillSingleValue( p_oElement, "li_numAltGrids", & m_iNumAltAng, true );
    //Number of azimuth angles
    FillSingleValue( p_oElement, "li_numAziGrids", & m_iNumAziAng, true );
    //Minimum sun angle
    FillSingleValue( p_oElement, "li_minSunAngle", & m_fMinSunAngle, true );
    //Azimuth of north - not required for backwards compatibility
    FillSingleValue( p_oElement, "li_AziOfNorth", & m_fAzimuthOfNorth, false );
    //Height of quadrat light
    FillSingleValue( p_oElement, "li_quadratLightHeight", & m_fLightHeight, true );
    //Whether to calculate all values
    FillSingleValue( p_oElement, "li_quadratAllGLIs", & m_bCalcAll, true );

    //Validate the data
    if ( 0 >= m_iNumAltAng )
    {
      modelErr stcErr;
      stcErr.iErrorCode = BAD_DATA;
      stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ;
      stcErr.sMoreInfo = "The number of sky altitude divisions must be greater than 0.";
      throw( stcErr );
    }

    if ( 0 >= m_iNumAziAng )
    {
      modelErr stcErr;
      stcErr.iErrorCode = BAD_DATA;
      stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ;
      stcErr.sMoreInfo = "The number of sky azimuth divisions must be greater than 0.";
      throw( stcErr );
    }

    if (0 > m_fAzimuthOfNorth || (2.0 * M_PI) < m_fAzimuthOfNorth) {
      modelErr stcErr;
      stcErr.iErrorCode = BAD_DATA;
      stcErr.sFunction = "clQuadratGLILight::DoShellSetup";
      stcErr.sMoreInfo = "Azimuth of north must be between 0 and 2PI.";
      throw( stcErr );
    }

    if ( 0 > m_fLightHeight )
    {
      modelErr stcErr;
      stcErr.iErrorCode = BAD_DATA;
      stcErr.sFunction = "clQuadratGLILight::DoShellSetup";
      stcErr.sMoreInfo = "The height of the GLI point for the GLI map cannot be less than 0.";
      throw( stcErr );
    }

    //**********************************************
    //Populate the sky brightness and photo arrays
    //**********************************************
    //Declare 'em
    mp_fBrightness = new float * [m_iNumAltAng];
    mp_fPhoto = new float * [m_iNumAltAng];
    for ( i = 0; i < m_iNumAltAng; i++ )
    {
      mp_fBrightness[i] = new float[m_iNumAziAng];
      mp_fPhoto[i] = new float[m_iNumAziAng];
      for ( j = 0; j < m_iNumAziAng; j++ )
      mp_fBrightness[i] [j] = 0;
    }

    m_fSinMinSunAng = sin( m_fMinSunAngle );
    m_iMinAngRow = (int)floor( m_fSinMinSunAng * m_iNumAltAng );

    //Now - we need to fill the sky brightness array.  Check to see if the
    //"glilightshell" object has been created
    p_oTemp = mp_oSimManager->GetBehaviorObject( "glilightshell" );
    if ( NULL != p_oTemp )
    {

      p_oGli = dynamic_cast < clLightBase * > ( p_oTemp );

      if ( p_oGli->m_iNumAltAng == m_iNumAltAng && p_oGli->m_iNumAziAng == m_iNumAziAng
          && p_oGli->m_iMinAngRow == m_iMinAngRow )
      {

        //Good!  We can assume that their photo brightness array is done, and
        //copy (if it wasn't done the sky resolution data wouldn't match)
        for ( i = 0; i < m_iNumAltAng; i++ )
        for ( j = 0; j < m_iNumAziAng; j++ )
        mp_fBrightness[i] [j] = p_oGli->mp_fBrightness[i] [j];

      }
      else
      {

        //Create our own sky brightness array
        PopulateGLIBrightnessArray();

      }
    }
    else
    { //p_oTemp is NULL
      //Create our own sky brightness array
      PopulateGLIBrightnessArray();
    }

    m_fAziChunkConverter = m_iNumAziAng / 360.0; //force float conversion
    m_fRcpTanMinAng = 1 / ( tan( m_fMinSunAngle ) );
    //Calculate search radius to look for shading neighbors
    clTreePopulation *p_oPop = (clTreePopulation*) mp_oSimManager->GetPopulationObject("treepopulation");
    m_fMaxSearchRad = ( mp_oLightOrg->GetMaxTreeHeight() - m_fLightHeight ) * m_fRcpTanMinAng + p_oPop->GetAllometryObject()->GetMaxCrownRadius();

    mp_fAziSlope = new float[m_iNumAziAng];
    iHalfAzi = m_iNumAziAng / 2;
    //Get the size of each azimuth chunk in radians
    fAngChunk = ( 2.0 * M_PI ) / m_iNumAziAng;
    for ( i = 0; i < iHalfAzi; i++ )
    {
      //slope = tan of azimuth angle
      mp_fAziSlope[i] = 1 / (tan( fAngChunk * ( i + 0.5 ) ));
      mp_fAziSlope[i + iHalfAzi] = mp_fAziSlope[i];
    }

    //**********************************************
    //Set up the quadrat grid
    //**********************************************
    //Is there already a grid from the parameter file?
    mp_oQuadrats = mp_oSimManager->GetGridObject( "Quadrat GLI" );

    if ( !mp_oQuadrats )
    {
      //Create the grid with one float data member
      mp_oQuadrats = mp_oSimManager->CreateGrid( "Quadrat GLI", 0, 1, 0, 0,
          QUADRAT_CELL_SIZE, QUADRAT_CELL_SIZE );
      //Register the data member - called "GLI"
      m_iGridGliCode = mp_oQuadrats->RegisterFloat( "GLI" );
    }
    else
    {
      //Get the data member code
      m_iGridGliCode = mp_oQuadrats->GetFloatDataCode( "GLI" );
      if ( -1 == m_iGridGliCode )
      {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ;
        stcErr.sMoreInfo = "Quadrat GLI grid was incorrectly set up in the parameter file.  Missing float \"GLI\".";
        throw( stcErr );
      }
    }

    //Set all the values to -1
    iNumXCells = mp_oQuadrats->GetNumberXCells();
    iNumYCells = mp_oQuadrats->GetNumberYCells();
    fAngChunk = -1; //dangerously reuse
    for ( i = 0; i < iNumXCells; i++ )
    for ( j = 0; j < iNumYCells; j++ )
    mp_oQuadrats->SetValueOfCell( i, j, m_iGridGliCode, fAngChunk );

  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ;
    throw( stcErr );
  }
}
//---------------------------------------------------------------------------
// LogBiLevelGrowth.cpp
//---------------------------------------------------------------------------
#include "LogBiLevelGrowth.h"
#include "TreePopulation.h"
#include "SimManager.h"
#include "ParsingFunctions.h"
#include "Grid.h"
#include <math.h>

//////////////////////////////////////////////////////////////////////////////
// Constructor
/////////////////////////////////////////////////////////////////////////////*/
clLogBiLevelGrowth::clLogBiLevelGrowth( clSimManager * p_oSimManager ) :
  clWorkerBase( p_oSimManager ), clBehaviorBase( p_oSimManager ), clGrowthBase( p_oSimManager )
{

  try
  {

    m_iGrowthMethod = height_only;

    mp_oStormLight = NULL;
    mp_fLoLightMaxGrowth = NULL;
    mp_fLoLightX0 = NULL;
    mp_fLoLightXb = NULL;
    mp_fHiLightMaxGrowth = NULL;
    mp_fHiLightX0 = NULL;
    mp_fHiLightXb = NULL;
    mp_fHiLightThreshold = NULL;
    mp_iIndexes = NULL;

    m_iYearsPerTimestep = 0;
    m_iLightCode = -1;

    m_sNameString = "logbilevelgrowthshell";
    m_sXMLRoot = "LogBilevelGrowth";
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clLogBiLevelGrowth::clLogBiLevelGrowth" ;
    throw( stcErr );
  }
}

//////////////////////////////////////////////////////////////////////////////
// Destructor
/////////////////////////////////////////////////////////////////////////////*/
clLogBiLevelGrowth::~clLogBiLevelGrowth()
{
  delete[] mp_fLoLightMaxGrowth;
  delete[] mp_fLoLightX0;
  delete[] mp_fLoLightXb;
  delete[] mp_fHiLightMaxGrowth;
  delete[] mp_fHiLightX0;
  delete[] mp_fHiLightXb;
  delete[] mp_fHiLightThreshold;
  delete[] mp_iIndexes;
}

//////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
/////////////////////////////////////////////////////////////////////////////*/
void clLogBiLevelGrowth::DoShellSetup( DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int iNumSpecies = p_oPop->GetNumberOfSpecies(), i;

    //Get number of years per timestep
    m_iYearsPerTimestep = mp_oSimManager->GetNumberOfYearsPerTimestep();

    //Declare the arrays we'd like read
    mp_fLoLightMaxGrowth = new double[m_iNumBehaviorSpecies];
    mp_fLoLightX0 = new double[m_iNumBehaviorSpecies];
    mp_fLoLightXb = new double[m_iNumBehaviorSpecies];
    mp_fHiLightMaxGrowth = new double[m_iNumBehaviorSpecies];
    mp_fHiLightX0 = new double[m_iNumBehaviorSpecies];
    mp_fHiLightXb = new double[m_iNumBehaviorSpecies];
    mp_fHiLightThreshold = new double[m_iNumBehaviorSpecies];
    mp_iIndexes = new int[iNumSpecies];

    //Set up the array indexes
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //See if we can find the storm light grid
    mp_oStormLight = mp_oSimManager->GetGridObject("Storm Light");
    if (NULL != mp_oStormLight) {
      m_iLightCode = mp_oStormLight->GetFloatDataCode("Light");
    }

    //Declare the species-specific temp array and pre-load with the species that
    //this behavior affects
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Low-light X0
    FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevLoLiteX0",
        "gr_lbllx0Val", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array while making sure none of them
    //are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val == 0) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
        stcErr.sMoreInfo = "X0 values cannot equal 0.";
        throw(stcErr);
      }
      mp_fLoLightX0[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Low-light Xb
    FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevLoLiteXb",
        "gr_lbllxbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array while making sure none of them
    //are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val == 0) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
        stcErr.sMoreInfo = "Xb values cannot equal 0.";
        throw(stcErr);
      }
      mp_fLoLightXb[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }


    //Low-light max growth
    FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevLoLiteMaxGrowth",
        "gr_lbllmgVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array while making sure none of them
    //are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (p_fTempValues[i].val < 0) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
        stcErr.sMoreInfo = "Max growth values must be greater than 0.";
        throw(stcErr);
      }
      mp_fLoLightMaxGrowth[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
    }

    //Get high-light parameters if we have a storm light grid
    if (NULL != mp_oStormLight) {

      //High-light threshold
      FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevHiLiteThreshold",
        "gr_lobhltVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer values to our permanent array, making sure all values are
      //between 0 and 100
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
        if (p_fTempValues[i].val < 0 || p_fTempValues[i].val > 100) {
          modelErr stcErr;
          stcErr.iErrorCode = BAD_DATA;
          stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
          stcErr.sMoreInfo = "All values in high-light growth threshold must be between 0 and 100.";
          throw(stcErr);
        }
        mp_fHiLightThreshold[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
      }

      //High-light X0
      FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevHiLiteX0",
          "gr_lbhlx0Val", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer values to our permanent array while making sure none of them
      //are 0
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
        if (p_fTempValues[i].val == 0) {
          modelErr stcErr;
          stcErr.iErrorCode = BAD_DATA;
          stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
          stcErr.sMoreInfo = "X0 values cannot equal 0.";
          throw(stcErr);
        }
        mp_fHiLightX0[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
      }

      //High-light Xb
      FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevHiLiteXb",
          "gr_lbhlxbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer values to our permanent array while making sure none of them
      //are 0
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
        if (p_fTempValues[i].val == 0) {
          modelErr stcErr;
          stcErr.iErrorCode = BAD_DATA;
          stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
          stcErr.sMoreInfo = "Xb values cannot equal 0.";
          throw(stcErr);
        }
        mp_fHiLightXb[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
      }

      //High-light max growth
      FillSpeciesSpecificValue( p_oElement, "gr_lognormalBilevHiLiteMaxGrowth",
          "gr_lbhlmgVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer values to our permanent array while making sure none of them
      //are 0
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
        if (p_fTempValues[i].val < 0) {
          modelErr stcErr;
          stcErr.iErrorCode = BAD_DATA;
          stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup";
          stcErr.sMoreInfo = "Max growth values must be greater than 0.";
          throw(stcErr);
        }
        mp_fHiLightMaxGrowth[mp_iIndexes[p_fTempValues[i].code]] = p_fTempValues[i].val;
      }

    } else {
      for (i = 0; i < m_iNumBehaviorSpecies; i++) {
        mp_fHiLightThreshold[i] = 100;
      }
    }

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clLogBiLevelGrowth::DoShellSetup" ;
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clTempDependentNeighborhoodDisperse::DoShellSetup( DOMDocument * p_oDoc )
{
    doubleVal * p_fTempValues = NULL; //for getting species-specific values
    try
    {
        clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
        DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
        int iNumTotalSpecies = p_oPop->GetNumberOfSpecies();
        short int i; //loop counter

        //Get the minimum sapling height
        m_fMinSaplingHeight = 50;
        for ( i = 0; i < iNumTotalSpecies; i++ )
            if ( p_oPop->GetMaxSeedlingHeight( i ) < m_fMinSaplingHeight )
                m_fMinSaplingHeight = p_oPop->GetMaxSeedlingHeight( i );

        //Declare the temp array and populate it with the species to which this
        //behavior applies
        p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            p_fTempValues[i].code = mp_iWhatSpecies[i];

        //Declare the arrays for holding the variables
        mp_fA = new double[iNumTotalSpecies];
        mp_fB = new double[iNumTotalSpecies];
        mp_fFecM = new double[iNumTotalSpecies];
        mp_fFecN = new double[iNumTotalSpecies];
        mp_fPresB = new double[iNumTotalSpecies];
        mp_fPresM = new double[iNumTotalSpecies];
        mp_fThreshold = new double[iNumTotalSpecies];

        //Capture the values from the parameter file

        //Fecundity M
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighFecM",
                                  "di_tdnfmVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fFecM[p_fTempValues[i].code] = p_fTempValues[i].val;

        //Fecundity N
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighFecN",
                                  "di_tdnfnVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fFecN[p_fTempValues[i].code] = p_fTempValues[i].val;

        //Presence M
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighPresM",
                                  "di_tdnpmVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fPresM[p_fTempValues[i].code] = p_fTempValues[i].val;

        //Presence B
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighPresB",
                                  "di_tdnpbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fPresB[p_fTempValues[i].code] = p_fTempValues[i].val;

        //Presence threshold
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighPresThreshold",
                                  "di_tdnptVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fThreshold[p_fTempValues[i].code] = p_fTempValues[i].val;
        //Reinforce zero and one to ensure that proper behavior occurs
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
            if (mp_fThreshold[mp_iWhatSpecies[i]] < 1e-5)
                mp_fThreshold[mp_iWhatSpecies[i]] = -0.01;
            if (mp_fThreshold[mp_iWhatSpecies[i]] > (1 - 1e-5))
                mp_fThreshold[mp_iWhatSpecies[i]] = 1.01;
        }

        //A
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighA",
                                  "di_tdnaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fA[p_fTempValues[i].code] = p_fTempValues[i].val;

        //B
        FillSpeciesSpecificValue( p_oElement, "di_tempDepNeighB",
                                  "di_tdnbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
        //Transfer to the appropriate array buckets
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
            mp_fB[p_fTempValues[i].code] = p_fTempValues[i].val;

        //Neighborhood search radius
        FillSingleValue(p_oElement, "di_tempDepNeighRadius", &m_fRadius, true );

        //Check to see if presence testing is required for this run. If all values
        //in the threshold parameter are zero, it is not. Set a flag to save
        //processing later.
        m_bDoPresenceTesting = false;
        for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
            if ( mp_fThreshold[mp_iWhatSpecies[i]] > 0 ) {
                m_bDoPresenceTesting = true;
                break;
            }
        }
        delete[] p_fTempValues;

    }
    catch ( modelErr & err )
    {
        delete[] p_fTempValues;
        throw( err );
    }
    catch ( modelMsg & msg )
    {
        delete[] p_fTempValues;
        throw( msg );
    } //non-fatal error
    catch ( ... )
    {
        delete[] p_fTempValues;
        modelErr stcErr;
        stcErr.iErrorCode = UNKNOWN;
        stcErr.sFunction = "clTempDependentNeighborhoodDisperse::DoShellSetup" ;
        throw( stcErr );
    }
}
////////////////////////////////////////////////////////////////////////////
// ReadParameterFile()
////////////////////////////////////////////////////////////////////////////
void clWeibullClimateQuadratGrowth::ReadParameterFile(
    xercesc::DOMDocument * p_oDoc, clTreePopulation *p_oPop )
{
  try
  {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    floatVal * p_fTempValues; //for getting species-specific values
    short int iNumTotalSpecies = p_oPop->GetNumberOfSpecies(),
              i; //loop counter

    m_fMinSaplingHeight = 50;

    //Get the minimum sapling height
    for ( i = 0; i < iNumTotalSpecies; i++ )
    {
      if ( p_oPop->GetMaxSeedlingHeight( i ) < m_fMinSaplingHeight )
      {
        m_fMinSaplingHeight = p_oPop->GetMaxSeedlingHeight( i );
      }
    }

    //Make the list of indexes
    mp_iIndexes = new short int[iNumTotalSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iIndexes[mp_iWhatSpecies[i]] = i;

    //This alone is sized total number of species
    mp_fMinimumNeighborDBH = new float[iNumTotalSpecies];

    //The rest are sized number of species to which this behavior applies
    mp_fCompC = new float[m_iNumBehaviorSpecies];
    mp_fCompD = new float[m_iNumBehaviorSpecies];
    mp_fPrecipA = new float[m_iNumBehaviorSpecies];
    mp_fPrecipB = new float[m_iNumBehaviorSpecies];
    mp_fPrecipC = new float[m_iNumBehaviorSpecies];
    mp_fTempA = new float[m_iNumBehaviorSpecies];
    mp_fTempB = new float[m_iNumBehaviorSpecies];
    mp_fTempC = new float[m_iNumBehaviorSpecies];
    mp_fMaxRG = new float[m_iNumBehaviorSpecies];

    //Set up our floatVal array that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Fill the variables

    //Maximum potential growth
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadMaxGrowth", "gr_wcqmgVal", p_fTempValues,
         m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fMaxRG[i] = p_fTempValues[i].val;

    //Max crowding radius
    FillSingleValue( p_oElement, "gr_weibClimQuadMaxNeighRad", &m_fMaxCrowdingRadius, true );

    //Minimum neighbor DBH
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadMinNeighDBH",
        "gr_wcqmndVal", mp_fMinimumNeighborDBH, p_oPop, true );

    //C
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadCompEffC",
        "gr_wcqcecVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fCompC[i] = p_fTempValues[i].val;

    //D
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadCompEffD",
        "gr_wcqcedVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fCompD[i] = p_fTempValues[i].val;

    //temperature effect a
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadTempEffA",
        "gr_wcqteaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fTempA[i] = p_fTempValues[i].val;

    //temperature effect b
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadTempEffB",
        "gr_wcqtebVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fTempB[i] = p_fTempValues[i].val;

    //temperature effect c
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadTempEffC",
        "gr_wcqtecVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fTempC[i] = p_fTempValues[i].val;

    //precipitation effect a
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadPrecipEffA",
        "gr_wcqpeaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPrecipA[i] = p_fTempValues[i].val;

    //precipitation effect b
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadPrecipEffB",
        "gr_wcqpebVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPrecipB[i] = p_fTempValues[i].val;

    //precipitation effect c
    FillSpeciesSpecificValue( p_oElement, "gr_weibClimQuadPrecipEffC",
        "gr_wcqpecVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPrecipC[i] = p_fTempValues[i].val;

    delete[] p_fTempValues;
  }
  catch ( modelErr & err )
  {
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    strcpy( stcErr.cFunction, "clWeibullClimateQuadratGrowth::ReadParameterFile" );
    throw( stcErr );
  }
}
Esempio n. 28
0
/////////////////////////////////////////////////////////////////////////////
// GetData()
/////////////////////////////////////////////////////////////////////////////
void clDimensionAnalysis::GetData( xercesc::DOMDocument * p_oDoc )
{
  floatVal * p_fTempValues = NULL; //for getting species-specific values
  intVal * p_iTempValues = NULL; //for getting species-specific values
  boolVal * p_bTempValues = NULL; //for getting species-specific values
  std::stringstream sQueryTemp;
  try
  {
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    float fConvertGramsToMg = CONVERT_G_TO_KG * CONVERT_KG_TO_MG,
          fConvertLbsToMg = CONVERT_LBS_TO_KG * CONVERT_KG_TO_MG;
    int i;
    bool bSapling = false, bAdult = false, bSnag = false;

    //*************************
    // Read in parameters
    //*************************

    //Set up our arrays that will extract values only for the species
    //assigned to this behavior
    p_fTempValues = new floatVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];
    p_iTempValues = new intVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_iTempValues[i].code = mp_iWhatSpecies[i];
    p_bTempValues = new boolVal[m_iNumBehaviorSpecies];
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        p_bTempValues[i].code = mp_iWhatSpecies[i];

    //Declare our arrays
    mp_fA = new float[m_iNumBehaviorSpecies];
    mp_fB = new float[m_iNumBehaviorSpecies];
    mp_fC = new float[m_iNumBehaviorSpecies];
    mp_fD = new float[m_iNumBehaviorSpecies];
    mp_fE = new float[m_iNumBehaviorSpecies];
    mp_fCorrectionFactor = new float[m_iNumBehaviorSpecies];
    mp_fDbhConverter = new float[m_iNumBehaviorSpecies];
    mp_fBiomassConverter = new float[m_iNumBehaviorSpecies];
    mp_iEquationID = new int[m_iNumBehaviorSpecies];
    mp_iWhatDia = new int[m_iNumBehaviorSpecies];
    mp_bUseCorrectionFactor = new bool[m_iNumBehaviorSpecies];
    mp_bConvertDBH = new bool[m_iNumBehaviorSpecies];

    //Get the parameter file values

    //a in the biomass equation
    FillSpeciesSpecificValue( p_oElement, "bi_a", "bi_aVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fA[i] = p_fTempValues[i].val;

    //b in the biomass equation
    FillSpeciesSpecificValue( p_oElement, "bi_b", "bi_bVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fB[i] = p_fTempValues[i].val;

    //c in the biomass equation
    FillSpeciesSpecificValue( p_oElement, "bi_c", "bi_cVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fC[i] = p_fTempValues[i].val;

    //d in the biomass equation
    FillSpeciesSpecificValue( p_oElement, "bi_d", "bi_dVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fD[i] = p_fTempValues[i].val;

    //e in the biomass equation
    FillSpeciesSpecificValue( p_oElement, "bi_e", "bi_eVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fE[i] = p_fTempValues[i].val;

    //Use correction factor
    FillSpeciesSpecificValue( p_oElement, "bi_useCorrectionFactor", "bi_ucfVal", p_bTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_bUseCorrectionFactor[i] = p_bTempValues[i].val;

    //Correction factor
    FillSpeciesSpecificValue( p_oElement, "bi_correctionFactorValue", "bi_cfvVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fCorrectionFactor[i] = p_fTempValues[i].val;

    //Equation ID
    FillSpeciesSpecificValue( p_oElement, "bi_eqID", "bi_eiVal", p_iTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iEquationID[i] = p_iTempValues[i].val;

    //Make sure the equation ID is between 1 and 9
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (mp_iEquationID[i] < 1 || mp_iEquationID[i] > 9 ) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clDimensionAnalysis::GetData";
        std::stringstream s;
        s << "Unidentified equation ID \"" << mp_iEquationID[i]
          << "\" for species \"" << mp_iWhatSpecies[i] << "\".";
        stcErr.sMoreInfo = s.str();
        throw(stcErr);
      }
    }

    //Meaning of "dia"
    FillSpeciesSpecificValue( p_oElement, "bi_whatDia", "bi_wdVal", p_iTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_iWhatDia[i] = p_iTempValues[i].val;

    //Make sure the value is valid
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (mp_iWhatDia[i] < DBH || mp_iWhatDia[i] > DBH2 ) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clDimensionAnalysis::GetData";
        std::stringstream s;
        s << "Unidentified dia meaning \"" << mp_iWhatDia[i]
          << "\" for species \"" << mp_iWhatSpecies[i] << "\".";
        stcErr.sMoreInfo = s.str();
        throw(stcErr);
      }
    }

    //DBH units
    FillSpeciesSpecificValue( p_oElement, "bi_dbhUnits", "bi_duVal", p_iTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Go through and assign the appropriate correction factor for each
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (mm == p_iTempValues[i].val) {
        mp_fDbhConverter[i] = CONVERT_CM_TO_MM;
        mp_bConvertDBH[i] = true;
      }
      else if (cm == p_iTempValues[i].val) {
        mp_fDbhConverter[i] = 1;
        mp_bConvertDBH[i] = false;
      }
      else if (in == p_iTempValues[i].val) {
        mp_fDbhConverter[i] = CONVERT_CM_TO_IN;
        mp_bConvertDBH[i] = true;
      }
      else {
        //Unrecognized value - throw an error
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clDimensionAnalysis::GetData";
        std::stringstream s;
        s << "Unidentified DBH units code \"" << p_iTempValues[i].val
          << "\" for species \"" << mp_iWhatSpecies[i] << "\".";
        stcErr.sMoreInfo = s.str();
        throw(stcErr);
      }
    }

    //Biomass units
    FillSpeciesSpecificValue( p_oElement, "bi_biomassUnits", "bi_buVal", p_iTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Go through and assign the appropriate correction factor for each
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if (g == p_iTempValues[i].val) {
        mp_fBiomassConverter[i] = fConvertGramsToMg;
      }
      else if (kg == p_iTempValues[i].val) {
        mp_fBiomassConverter[i] = CONVERT_KG_TO_MG;
      }
      else if (lb == p_iTempValues[i].val) {
        mp_fBiomassConverter[i] = fConvertLbsToMg;
      }
      else {
        //Unrecognized value - throw an error
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clDimensionAnalysis::GetData";
        std::stringstream s;
        s << "Unidentified biomass units code \"" << p_iTempValues[i].val
          << "\" for species \"" << mp_iWhatSpecies[i] << "\".";
        stcErr.sMoreInfo = s.str();
        throw(stcErr);
      }
    }


    //*************************
    // Format query string
    //*************************
    //Do a type/species search on all the types and species
    sQueryTemp << "species=";
    for (i = 0; i < m_iNumBehaviorSpecies - 1; i++) {
      sQueryTemp << mp_iWhatSpecies[i] << ",";
    }
    sQueryTemp << mp_iWhatSpecies[m_iNumBehaviorSpecies - 1];

    //Find all the types
    for (i = 0; i < m_iNumSpeciesTypeCombos; i++) {
      if ( clTreePopulation::sapling == mp_whatSpeciesTypeCombos[i].iType ) {
        bSapling = true;
      } else if ( clTreePopulation::adult == mp_whatSpeciesTypeCombos[i].iType ) {
        bAdult = true;
      } else if ( clTreePopulation::snag == mp_whatSpeciesTypeCombos[i].iType ) {
        bSnag = true;
      }
    }
    sQueryTemp << "::type=";
    if (bSapling) {
      sQueryTemp << clTreePopulation::sapling << ",";
    } if (bAdult) {
      sQueryTemp << clTreePopulation::adult << ",";
    } if (bSnag) {
      sQueryTemp << clTreePopulation::snag << ",";
    }

    //Remove the last comma and put it in m_sQuery
    m_sQuery = sQueryTemp.str().substr(0, sQueryTemp.str().length() - 1);

    delete[] p_fTempValues;
    delete[] p_iTempValues;
    delete[] p_bTempValues;

    Action();
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    delete[] p_iTempValues;
    delete[] p_bTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    delete[] p_iTempValues;
    delete[] p_bTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clDimensionAnalysis::GetData" ;
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clInsectInfestationMortality::DoShellSetup( xercesc::DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    short int i, j, iNumTypes = p_oPop->GetNumberOfTypes();

    m_iNumSpecies = p_oPop->GetNumberOfSpecies();

    //Declare the arrays we'd like read
    mp_fIntercept = new double[m_iNumSpecies];
    mp_fMax = new double[m_iNumSpecies];
    mp_fX0 = new double[m_iNumSpecies];
    mp_fXb = new double[m_iNumSpecies];

    //Declare the species-specific temp array and pre-load with the species
    //that this behavior affects
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Intercept
    FillSpeciesSpecificValue( p_oElement, "mo_insectMortIntercept", "mo_imiVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array, making sure all values are
    //between 0 and 1
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if ( 0 > p_fTempValues[i].val || 1 < p_fTempValues[i].val ) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clInsectInfestationMortality::DoShellSetup" ;
        stcErr.sMoreInfo = "All values for mortality intercept must be between 0 and 1.";
        throw( stcErr );
      }
      mp_fIntercept[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //Max mortality probability
    FillSpeciesSpecificValue( p_oElement, "mo_insectMortMaxRate", "mo_immrVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array, making sure all values are
    //between 0 and 1
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if ( 0 > p_fTempValues[i].val || 1 < p_fTempValues[i].val ) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clInsectInfestationMortality::DoShellSetup" ;
        stcErr.sMoreInfo = "All values for max mortality must be between 0 and 1.";
        throw( stcErr );
      }
      mp_fMax[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //X0
    FillSpeciesSpecificValue( p_oElement, "mo_insectMortX0", "mo_imx0Val",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array, making sure no values are 0
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      if ( 0 == p_fTempValues[i].val) {
        modelErr stcErr;
        stcErr.iErrorCode = BAD_DATA;
        stcErr.sFunction = "clInsectInfestationMortality::DoShellSetup" ;
        stcErr.sMoreInfo = "Values for insect mortality X0 cannot be 0.";
        throw( stcErr );
      }
      mp_fX0[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //Xb
    FillSpeciesSpecificValue( p_oElement, "mo_insectMortXb", "mo_imxbVal",
        p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer values to our permanent array
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ ) {
      mp_fXb[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    //Collect the "YearsInfested" codes
    mp_iDataCodes = new short int *[m_iNumSpecies];
    for (i = 0; i < m_iNumSpecies; i++) {
      mp_iDataCodes[i] = new short int[iNumTypes];
      for (j = 0; j < iNumTypes; j++) {
        mp_iDataCodes[i][j] = -1;
      }
    }
    for (i = 0; i < m_iNumSpeciesTypeCombos; i++ )
    {
      mp_iDataCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                      [mp_whatSpeciesTypeCombos[i].iType] =
            p_oPop->GetIntDataCode("YearsInfested",
                                    mp_whatSpeciesTypeCombos[i].iSpecies,
                                    mp_whatSpeciesTypeCombos[i].iType );
      if (-1 == mp_iDataCodes[mp_whatSpeciesTypeCombos[i].iSpecies]
                                 [mp_whatSpeciesTypeCombos[i].iType] )
      {
        modelErr stcErr;
        stcErr.sFunction = "clInsectInfestationMortality::DoShellSetup" ;
        std::stringstream s;
        s << "Type/species combo species="
          << mp_whatSpeciesTypeCombos[i].iSpecies << " type="
          << mp_whatSpeciesTypeCombos[i].iType
          << " does not have the insect infestation behavior.";
        stcErr.iErrorCode = BAD_DATA;
        throw( stcErr );
      }
    }

    delete[] p_fTempValues;

    //Pre-calculate mortalities
    m_iMaxMortTime = 0;
    for (i = 0; i < m_iNumBehaviorSpecies; i++) {
      if ((int)(mp_fX0[mp_iWhatSpecies[i]] * 2) > m_iMaxMortTime)
        m_iMaxMortTime = (int)(mp_fX0[mp_iWhatSpecies[i]] * 2);
    }
    m_iMaxMortTime++;
    mp_fMortProbs = new double *[m_iNumSpecies];
    for (i = 0; i < m_iNumSpecies; i++) {
      mp_fMortProbs[i] = new double[m_iMaxMortTime];
      for (j = 0; j < m_iMaxMortTime; j++) mp_fMortProbs[i][j] = 0;
    }

    for (i = 0; i < m_iNumBehaviorSpecies; i++) {
      for (j = 1; j < m_iMaxMortTime; j++) {
        mp_fMortProbs[mp_iWhatSpecies[i]][j] = mp_fIntercept[mp_iWhatSpecies[i]] +
        ((mp_fMax[mp_iWhatSpecies[i]] - mp_fIntercept[mp_iWhatSpecies[i]])/
            (1+pow(j/mp_fX0[mp_iWhatSpecies[i]], mp_fXb[mp_iWhatSpecies[i]])));
      }
    }
  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clInsectInfestationMortality::DoShellSetup" ;
    throw( stcErr );
  }
}
////////////////////////////////////////////////////////////////////////////
// DoShellSetup()
////////////////////////////////////////////////////////////////////////////
void clStochDoubleLogTempDepNeighDisperse::DoShellSetup( DOMDocument * p_oDoc )
{
  doubleVal * p_fTempValues = NULL; //for getting species-specific values
  try
  {
    clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" );
    DOMElement * p_oElement = GetParentParametersElement(p_oDoc);
    int iNumTotalSpecies = p_oPop->GetNumberOfSpecies();
    short int i; //loop counter

    //Get the minimum sapling height
    m_fMinSaplingHeight = 50;
    for ( i = 0; i < iNumTotalSpecies; i++ )
      if ( p_oPop->GetMaxSeedlingHeight( i ) < m_fMinSaplingHeight )
        m_fMinSaplingHeight = p_oPop->GetMaxSeedlingHeight( i );

    //Declare the temp array and populate it with the species to which this
    //behavior applies
    p_fTempValues = new doubleVal[m_iNumBehaviorSpecies];
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      p_fTempValues[i].code = mp_iWhatSpecies[i];

    //Declare the arrays for holding the variables
    mp_fPA = new double[iNumTotalSpecies];
    mp_fPB = new double[iNumTotalSpecies];
    mp_fPM = new double[iNumTotalSpecies];
    mp_fAl = new double[iNumTotalSpecies];
    mp_fBl = new double[iNumTotalSpecies];
    mp_fCl = new double[iNumTotalSpecies];
    mp_fAh = new double[iNumTotalSpecies];
    mp_fBh = new double[iNumTotalSpecies];
    mp_fCh = new double[iNumTotalSpecies];
    mp_fA = new double[iNumTotalSpecies];
    mp_fB = new double[iNumTotalSpecies];

    //Capture the values from the parameter file

    //PA
    FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighPA",
        "di_sdltdnpaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPA[p_fTempValues[i].code] = p_fTempValues[i].val;

    //PB
    FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighPB",
        "di_sdltdnpbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPB[p_fTempValues[i].code] = p_fTempValues[i].val;

    //PM
    FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighPM",
        "di_sdltdnpmVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fPM[p_fTempValues[i].code] = p_fTempValues[i].val;

    //A
    FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighA",
        "di_sdltdnaVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fA[p_fTempValues[i].code] = p_fTempValues[i].val;

    //B
    FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighB",
        "di_sdltdnbVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
    //Transfer to the appropriate array buckets
    for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
      mp_fB[p_fTempValues[i].code] = p_fTempValues[i].val;

    //Neighborhood search radius
    FillSingleValue(p_oElement, "di_stochDoubLogTempDepNeighRadius", &m_fRadius, true );

    //Original analysis plot size, square meters
    FillSingleValue(p_oElement, "di_stochDoubLogTempDepNeighPlotSize", &m_fAnalysisPlotSize, true );

    //Deterministic or Poisson seed distribution
    FillSingleValue(p_oElement, "di_stochDoubLogTempDepNeighDeterministic", &m_bDeterministic, false );

    //Use temperature dependent portion of fecundity
    FillSingleValue(p_oElement, "di_stochDoubLogTempDepNeighTempFec", &m_bFecTempDep, true );

    //T, in years, to go from cumulative to annualized probability
    FillSingleValue(p_oElement, "di_stochDoubLogTempDepNeighT", &m_fAnnualizePeriod, true );

    //If we are using temperature dependent fecundity, get those values
    if (m_bFecTempDep) {
      //Al
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighAl",
          "di_sdltdnalVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fAl[p_fTempValues[i].code] = p_fTempValues[i].val;

      //Bl
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighBl",
          "di_sdltdnblVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fBl[p_fTempValues[i].code] = p_fTempValues[i].val;

      //Cl
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighCl",
          "di_sdltdnclVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fCl[p_fTempValues[i].code] = p_fTempValues[i].val;

      //Ah
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighAh",
          "di_sdltdnahVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fAh[p_fTempValues[i].code] = p_fTempValues[i].val;

      //Bh
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighBh",
          "di_sdltdnbhVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fBh[p_fTempValues[i].code] = p_fTempValues[i].val;

      //Ch
      FillSpeciesSpecificValue( p_oElement, "di_stochDoubLogTempDepNeighCh",
          "di_sdltdnchVal", p_fTempValues, m_iNumBehaviorSpecies, p_oPop, true );
      //Transfer to the appropriate array buckets
      for ( i = 0; i < m_iNumBehaviorSpecies; i++ )
        mp_fCh[p_fTempValues[i].code] = p_fTempValues[i].val;
    }

    delete[] p_fTempValues;

  }
  catch ( modelErr & err )
  {
    delete[] p_fTempValues;
    throw( err );
  }
  catch ( modelMsg & msg )
  {
    delete[] p_fTempValues;
    throw( msg );
  } //non-fatal error
  catch ( ... )
  {
    delete[] p_fTempValues;
    modelErr stcErr;
    stcErr.iErrorCode = UNKNOWN;
    stcErr.sFunction = "clStochDoubleLogTempDepNeighDisperse::DoShellSetup" ;
    throw( stcErr );
  }
}