Пример #1
0
/*******************************************************************************
  Function name: InitStations()

  Purpose      : Read the station information from the options file.  This
                 information is in the [METEOROLOGY] section

  Required     :
    LISTPTR Input       - Linked list with input strings
    MAPSIZE *Map        - Information about the basin area
    int NDaysSteps      - Number of time steps in a day
    int *NStats         - Number of met stations
    METLOCATION **Stat  - Information about each met station

  Returns      : void

  Modifies     : NStats, Stat and members of Stat

  Comments     :
*****************************************************************************/
void InitStations(LISTPTR Input, MAPSIZE *Map, int NDaySteps,
  OPTIONSTRUCT *Options, int *NStats, METLOCATION **Stat)
{
  char *Routine = "InitStations";
  int i;
  int j;
  int k;
  char tempfilename[BUFSIZE + 1];
  char KeyName[station_file + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "STATION NAME",
    "NORTH COORDINATE",
    "EAST COORDINATE",
    "ELEVATION",
    "STATION FILE"
  };
  char *SectionName = "METEOROLOGY";
  char VarStr[station_file + 1][BUFSIZE + 1];
  float East;
  float North;
  FILE *PrismStatFile;

  /* Get the number of different stations */
  GetInitString(SectionName, "NUMBER OF STATIONS", "", VarStr[0],
    (unsigned long)BUFSIZE, Input);
  if (!CopyInt(NStats, VarStr[0], 1))
    ReportError("NUMBER OF STATIONS", 51);

  if (*NStats <= 0)
    ReportError("Input Options File", 6);

  printf("\nEvaluating %d Met stations for inclusion\n", *NStats);

  /* Allocate memory for the stations */
  if (!(*Stat = (METLOCATION *)calloc(*NStats, sizeof(METLOCATION))))
    ReportError(Routine, 1);

  /* Read key-entry pairs for each station from the input file */
  /* for each potential station, up to NStats, read in the data and */
  /* determine if it is in the current model bounding box */
  /* If it is then put it into memory, otherwise, forget about it */
  /* unless Outside option is TRUE, then include it anyway */
  /* use temp counter k to track number of valid stations */
  k = 0;
  for (i = 0; i < *NStats; i++) {
    for (j = 0; j <= station_file; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
        (unsigned long)BUFSIZE, Input);
    }

    /* Assign the entries to the variables */
    if (IsEmptyStr(VarStr[station_name]))
      ReportError(KeyName[number_of_maps], 51);
    strcpy((*Stat)[k].Name, VarStr[station_name]);

    if (!CopyFloat(&North, VarStr[station_north], 1))
      ReportError(KeyName[station_north], 51);

    if (!CopyFloat(&East, VarStr[station_east], 1))
      ReportError(KeyName[station_east], 51);

    (*Stat)[k].Loc.N = Round(((Map->Yorig - 0.5 * Map->DY) - North) / Map->DY);
    (*Stat)[k].Loc.E = Round((East - (Map->Xorig + 0.5 * Map->DX)) / Map->DX);

    if (!CopyFloat(&((*Stat)[k].Elev), VarStr[station_elev], 1))
      ReportError(KeyName[station_elev], 51);

    if (IsEmptyStr(VarStr[station_file]))
      ReportError(KeyName[station_file], 51);
    strcpy((*Stat)[k].MetFile.FileName, VarStr[station_file]);

    OpenFile(&((*Stat)[k].MetFile.FilePtr), (*Stat)[k].MetFile.FileName, "r", FALSE);

    /* check to see if the stations are inside the bounding box */
    if (((*Stat)[k].Loc.N >= Map->NY || (*Stat)[k].Loc.N < 0 ||
      (*Stat)[k].Loc.E >= Map->NX || (*Stat)[k].Loc.E < 0)
      && Options->Outside == FALSE)
      printf("Station %d outside bounding box: %s ignored\n", i + 1, (*Stat)[k].Name);
    else
      k = k + 1;
  }
  if (Options->Outside == FALSE)
    printf("Final number of stations in bounding box is %d \n\n", k);
  else
    printf("Forced to include all %d stations \n", k);
  *NStats = k;

  if (Options->Outside == TRUE && Options->Prism == TRUE) {

    for (i = 0; i < *NStats; i++) {
      sprintf(tempfilename, "%s.prism", (*Stat)[i].MetFile.FileName);
      /* Options->PrismDataExt); */
      OpenFile(&PrismStatFile, tempfilename, "rt", FALSE);
      for (k = 0; k < 12; k++) {
        fscanf(PrismStatFile, "%f ", &(*Stat)[i].PrismPrecip[k]);
      }
      fclose(PrismStatFile);
    }
  }
}
Пример #2
0
	void GameDataHolder::Impl::Flush()
	{
		if( !FileExist( "save" ) ){
			CreateDirectory( "save" );
		}

		UpdatePlayTime();

		std::vector < char > data;
		data.reserve( 30000 );

		std::ofstream fOut( m_SaveDataFileName, std::ios::binary | std::ios::out );
		if( !fOut ){
			return;
		}

		CopyInt( &data, m_GameFileData.m_PlayTime );
		CopyInt( &data, m_GameFileData.m_Progress );
		for( int i = 0; i < GAME_DIFFICULTY_TOTAL; ++i ){
			// 通常プレイの統計情報の保存
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_Play );
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_AllClear );
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_PlayTime );
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_Progress );
			for( int j = 0; j < STAGE_TOTAL; ++j ){
				// 敵情報の保存
				const StageStat& stage = m_GameFileData.m_Difficulty[ i ].m_NormalPlayStat.m_StageStat[ j ];
				StageStat::EnemyStatMap::const_iterator it = stage.m_EnemyStat.begin();
				// エントリ数の保存
				CopyInt( &data, stage.m_EnemyStat.size() );
				for( ; it != stage.m_EnemyStat.end(); ++it ){
					// 敵の名前の長さ保存
					CopyInt( &data, it->first.size() );
					// 敵の名前の保存
					CopyArray( &data, it->first.c_str(), it->first.size() );
					// 情報の保存
					CopyInt( &data, it->second.m_Destroy );
					CopyInt( &data, it->second.m_Damaged );
					CopyInt( &data, it->second.m_KO );
				}
			}

			// ステージ選択プレイの統計情報の保存
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_Play );
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_Clear );
			CopyInt( &data, m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_PlayTime );
			for( int j = 0; j < STAGE_TOTAL; ++j ){
				// 敵情報の保存
				const StageStat& stage = m_GameFileData.m_Difficulty[ i ].m_StageSelectionPlayStat.m_StageStat[ j ];
				StageStat::EnemyStatMap::const_iterator it = stage.m_EnemyStat.begin();
				// エントリ数の保存
				CopyInt( &data, stage.m_EnemyStat.size() );
				for( ; it != stage.m_EnemyStat.end(); ++it ){
					// 敵の名前の長さ保存
					CopyInt( &data, it->first.size() );
					// 敵の名前の保存
					CopyArray( &data, it->first.c_str(), it->first.size() );
					// 情報の保存
					CopyInt( &data, it->second.m_Destroy );
					CopyInt( &data, it->second.m_Damaged );
					CopyInt( &data, it->second.m_KO );
				}
			}

			// スコアの保存
			for( int j = 0; j < MAX_SCORE_ENTRY; ++j ){
				SaveDataRecord record = m_GameFileData.m_Difficulty[ i ].m_Record[ j ];
				CopyArray( &data, record.m_Name, sizeof( record.m_Name ) );
				CopyInt( &data, record.m_Date.m_Year );
				data.push_back( record.m_Date.m_Month );
				data.push_back( record.m_Date.m_Day );
				data.push_back( record.m_Date.m_Hour );
				data.push_back( record.m_Date.m_Min );
				data.push_back( record.m_Date.m_Sec );
				for( int k = 0; k < STAGE_TOTAL; ++k ){
					SaveDataRecord::StageData stage = record.m_StageData[ k ];
					CopyInt( &data, stage.m_Score );
					CopyInt( &data, stage.m_Killed );
					CopyInt( &data, stage.m_Crystal );
					CopyInt( &data, stage.m_CrystalUsed );
					CopyInt( &data, stage.m_Progress );
				}
				CopyInt( &data, record.m_Score );
				CopyInt( &data, record.m_Progress );
				CopyInt( &data, record.m_Killed );
				CopyInt( &data, record.m_Crystal );
				CopyInt( &data, record.m_CrystalUsed );
			}
		}

		// 圧縮
		char* pBuf = new char [ data.size() * 2 ];
		int compSize = 0;
		MAPIL::LZ lz( 200, 3 );
		lz.Compress( &data[ 0 ], data.size(), &pBuf, data.size() * 2, &compSize );
		// シーザ暗号化
		MAPIL::Caesar caesar( 10 );
		caesar.Encrypt( pBuf, compSize );
		// XOR暗号化
		MAPIL::XOR xor( 60 );
		xor.Encrypt( pBuf, compSize );
		fOut.write( pBuf, compSize );
		fOut.close();
		MAPIL::SafeDeleteArray( pBuf );
	}
Пример #3
0
/*******************************************************************************
  Function name: InitMM5()

  Purpose      : Read the MM5 information the options file.  This information
                 is in the [METEOROLOGY] section

  Required     : 
    LISTPTR Input       - Linked list with input options
    int NSoilLayers     - Number of soil layers
    TIMESTRUCT *Time    - Time information
    INPUTFILES *InFiles - Filenames for various input files

  Returns      : void

  Modifies     : Members of Time and InFiles

  Comments     :
*****************************************************************************/
void InitMM5(LISTPTR Input, int NSoilLayers, TIMESTRUCT * Time,
	     INPUTFILES * InFiles, OPTIONSTRUCT * Options, MAPSIZE * MM5Map,
	     MAPSIZE * Map)
{
  DATE Start;
  char *Routine = "InitMM5";
  char KeyName[BUFSIZE + 1];
  char VarStr[BUFSIZE + 1];
  int i;
  STRINIENTRY StrEnv[] = {
    {"METEOROLOGY", "MM5 START", "", ""},
    {"METEOROLOGY", "MM5 TEMPERATURE FILE", "", ""},
    {"METEOROLOGY", "MM5 HUMIDITY FILE", "", ""},
    {"METEOROLOGY", "MM5 WIND SPEED FILE", "", ""},
    {"METEOROLOGY", "MM5 SHORTWAVE FILE", "", ""},
    {"METEOROLOGY", "MM5 LONGWAVE FILE", "", ""},
    {"METEOROLOGY", "MM5 PRECIPITATION FILE", "", ""},
    {"METEOROLOGY", "MM5 TERRAIN FILE", "", ""},
    {"METEOROLOGY", "MM5 TEMP LAPSE FILE", "", ""},
    {"METEOROLOGY", "MM5 ROWS", "", ""},
    {"METEOROLOGY", "MM5 COLS", "", ""},
    {"METEOROLOGY", "MM5 EXTREME NORTH", "", ""},
    {"METEOROLOGY", "MM5 EXTREME WEST", "", ""},
    {"METEOROLOGY", "MM5 DY", "", ""},
    {NULL, NULL, "", NULL},
  };

  /* Read the key-entry pairs from the input file */
  for (i = 0; StrEnv[i].SectionName; i++)
    GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default,
		  StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input);

  /* Assign the entries to the variables */
  if (!SScanDate(StrEnv[MM5_start].VarStr, &Start))
    ReportError(StrEnv[MM5_start].KeyName, 51);

  InitTime(Time, NULL, NULL, NULL, &Start, Time->Dt);

  if (IsEmptyStr(StrEnv[MM5_temperature].VarStr))
    ReportError(StrEnv[MM5_temperature].KeyName, 51);
  strcpy(InFiles->MM5Temp, StrEnv[MM5_temperature].VarStr);

  if (IsEmptyStr(StrEnv[MM5_terrain].VarStr))
    ReportError(StrEnv[MM5_terrain].KeyName, 51);
  strcpy(InFiles->MM5Terrain, StrEnv[MM5_terrain].VarStr);

  if (IsEmptyStr(StrEnv[MM5_lapse].VarStr))
    ReportError(StrEnv[MM5_lapse].KeyName, 51);
  strcpy(InFiles->MM5Lapse, StrEnv[MM5_lapse].VarStr);

  if (IsEmptyStr(StrEnv[MM5_humidity].VarStr))
    ReportError(StrEnv[MM5_humidity].KeyName, 51);
  strcpy(InFiles->MM5Humidity, StrEnv[MM5_humidity].VarStr);

  if (IsEmptyStr(StrEnv[MM5_wind].VarStr))
    ReportError(StrEnv[MM5_wind].KeyName, 51);
  strcpy(InFiles->MM5Wind, StrEnv[MM5_wind].VarStr);

  if (IsEmptyStr(StrEnv[MM5_shortwave].VarStr))
    ReportError(StrEnv[MM5_shortwave].KeyName, 51);
  strcpy(InFiles->MM5ShortWave, StrEnv[MM5_shortwave].VarStr);

  if (IsEmptyStr(StrEnv[MM5_longwave].VarStr))
    ReportError(StrEnv[MM5_longwave].KeyName, 51);
  strcpy(InFiles->MM5LongWave, StrEnv[MM5_longwave].VarStr);

  if (IsEmptyStr(StrEnv[MM5_precip].VarStr))
    ReportError(StrEnv[MM5_precip].KeyName, 51);
  strcpy(InFiles->MM5Precipitation, StrEnv[MM5_precip].VarStr);

  if (Options->HeatFlux == TRUE) {

    if (!(InFiles->MM5SoilTemp = (char **) calloc(sizeof(char *), NSoilLayers)))
      ReportError(Routine, 1);

    for (i = 0; i < NSoilLayers; i++) {
      if (!
	  (InFiles->MM5SoilTemp[i] =
	   (char *) calloc(sizeof(char), BUFSIZE + 1)))
	ReportError(Routine, 1);
      sprintf(KeyName, "MM5 SOIL TEMPERATURE FILE %d", i);
      GetInitString("METEOROLOGY", KeyName, "", VarStr,
		    (unsigned long) BUFSIZE, Input);
      if (IsEmptyStr(VarStr))
	ReportError(KeyName, 51);
      strcpy(InFiles->MM5SoilTemp[i], VarStr);
    }

  }

  if (!CopyDouble(&(MM5Map->Yorig), StrEnv[MM5_ext_north].VarStr, 1))
    ReportError(StrEnv[MM5_ext_north].KeyName, 51);

  if (!CopyDouble(&(MM5Map->Xorig), StrEnv[MM5_ext_west].VarStr, 1))
    ReportError(StrEnv[MM5_ext_west].KeyName, 51);

  if (!CopyInt(&(MM5Map->NY), StrEnv[MM5_rows].VarStr, 1))
    ReportError(StrEnv[MM5_rows].KeyName, 51);

  if (!CopyInt(&(MM5Map->NX), StrEnv[MM5_cols].VarStr, 1))
    ReportError(StrEnv[MM5_cols].KeyName, 51);

  if (!CopyFloat(&(MM5Map->DY), StrEnv[MM5_dy].VarStr, 1))
    ReportError(StrEnv[MM5_dy].KeyName, 51);

  MM5Map->OffsetX = Round(((float) (MM5Map->Xorig - Map->Xorig)) /
			  ((float) Map->DX));
  MM5Map->OffsetY = Round(((float) (MM5Map->Yorig - Map->Yorig)) /
			  ((float) Map->DY));

  if (MM5Map->OffsetX > 0 || MM5Map->OffsetY < 0)
    ReportError("Input Options File", 31);

  printf("MM5 extreme north / south is %f %f \n", MM5Map->Yorig,
	 MM5Map->Yorig - MM5Map->NY * MM5Map->DY);
  printf("MM5 extreme west / east is %f %f\n", MM5Map->Xorig,
	 MM5Map->Xorig + MM5Map->NX * MM5Map->DY);
  printf("MM5 rows is %d \n", MM5Map->NY);
  printf("MM5 cols is %d \n", MM5Map->NX);
  printf("MM5 dy is %f \n", MM5Map->DY);
  printf("Temperature Map is %s\n", InFiles->MM5Temp);
  printf("Precip Map is %s\n", InFiles->MM5Precipitation);
  printf("wind Map is %s\n", InFiles->MM5Wind);
  printf("shortwave Map is %s\n", InFiles->MM5ShortWave);
  printf("humidity Map is %s\n", InFiles->MM5Humidity);
  printf("lapse Map is %s\n", InFiles->MM5Lapse);
  printf("terrain Map is %s\n", InFiles->MM5Terrain);
  printf("MM5 offset x is %d \n", MM5Map->OffsetX);
  printf("MM5 offset y is %d \n", MM5Map->OffsetY);
  printf("dhsvm extreme north / south is %f %f \n", Map->Yorig,
	 Map->Yorig - Map->NY * Map->DY);
  printf("dhsvm extreme west / east is %f %f \n", Map->Xorig,
	 Map->Xorig + Map->NX * Map->DY);
  printf("fail if %d > %d\n",
	 (int) ((Map->NY + MM5Map->OffsetY) * Map->DY / MM5Map->DY),
	 MM5Map->NY);
  printf("fail if %d > %d\n",
	 (int) ((Map->NX - MM5Map->OffsetX) * Map->DX / MM5Map->DY),
	 MM5Map->NX);
  if ((int) ((Map->NY + MM5Map->OffsetY) * Map->DY / MM5Map->DY) > MM5Map->NY
      || (int) ((Map->NX - MM5Map->OffsetX) * Map->DX / MM5Map->DY) >
      MM5Map->NX)
    ReportError("Input Options File", 31);

}
Пример #4
0
/*******************************************************************************
  Function name: InitMapDump()

  Purpose      : Initialize the map dumps.  This information is in the 
		 [OUTPUT] section of the input file

  Required     : 
    LISTPTR Input         - Linked list with input strings
    MAPSIZE *MapDump      - Information about areal extent
    int MaxSoilLayers     - Maximum number of soil layers
    int MaxVegLayers      - Maximum number of vegetation layers
    char *Path            - Directory to write output to
    int NTotalMapImages   - Total number of maps and images to dump
    int NMaps             - Number of maps to dump 
    MAPDUMP **DMap        - Array of maps and images to dump

  Returns      : void

  Modifies     : DMap and its members

  Comments     :
*******************************************************************************/
void InitMapDump(LISTPTR Input, MAPSIZE * Map, int MaxSoilLayers,
		 int MaxVegLayers, char *Path, int TotalMapImages, int NMaps,
		 MAPDUMP ** DMap)
{
  char *Routine = "InitMapDump";
  int i;			/* counter */
  int j;			/* counter */
  int MaxLayers;		/* Maximum number of layers allowed for this 
				   variable */
  char KeyName[map_date + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "MAP VARIABLE",
    "MAP LAYER",
    "NUMBER OF MAPS",
    "MAP DATE",
  };
  char *SectionName = "OUTPUT";
  char VarStr[map_date + 1][BUFSIZE + 1];

  if (!(*DMap = (MAPDUMP *) calloc(TotalMapImages, sizeof(MAPDUMP))))
    ReportError(Routine, 1);

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

    /* Read the key-entry pairs from the input file */
    for (j = 0; j <= nmaps; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
		    (unsigned long) BUFSIZE, Input);
    }

    /* Assign the entries to the appropriate variables */
    if (!CopyInt(&((*DMap)[i].ID), VarStr[map_variable], 1))
      ReportError(KeyName[map_variable], 51);

    if (!IsValidID((*DMap)[i].ID))
      ReportError("Input Options File", 19);

    if (IsMultiLayer((*DMap)[i].ID)) {
      MaxLayers = GetVarNLayers((*DMap)[i].ID, MaxSoilLayers, MaxVegLayers);
      if (!CopyInt(&((*DMap)[i].Layer), VarStr[map_layer], 1))
	ReportError(KeyName[map_layer], 51);
      if ((*DMap)[i].Layer < 1 || (*DMap)[i].Layer > MaxLayers)
	ReportError("Input Options File", 20);
    }
    else
      (*DMap)[i].Layer = 1;

    (*DMap)[i].Resolution = MAP_OUTPUT;

    strncpy((*DMap)[i].FileName, Path, BUFSIZE);
    GetVarAttr(&((*DMap)[i]));

    CreateMapFile((*DMap)[i].FileName, (*DMap)[i].FileLabel, Map);

    if (!CopyInt(&((*DMap)[i].N), VarStr[nmaps], 1))
      ReportError(KeyName[nmaps], 51);

    if ((*DMap)[i].N < 1)
      ReportError("Input Options File", 22);

    if (!((*DMap)[i].DumpDate = (DATE *) calloc((*DMap)[i].N, sizeof(DATE))))
      ReportError(Routine, 1);

    for (j = 0; j < (*DMap)[i].N; j++) {
      sprintf(KeyName[map_date], "%s %d %d", KeyStr[map_date], j + 1, i + 1);
      GetInitString(SectionName, KeyName[map_date], "", VarStr[map_date],
		    (unsigned long) BUFSIZE, Input);
      if (!SScanDate(VarStr[map_date], &((*DMap)[i].DumpDate[j])))
	ReportError(KeyName[map_date], 51);
    }

    (*DMap)[i].MinVal = 0.0;
    (*DMap)[i].MaxVal = 0.0;
  }
}
Пример #5
0
/*******************************************************************************
  Function name: InitDump()

  Purpose      : Read the model output information from the options file, and 
                 organize what to output when.  This information is in the 
		 [OUTPUT] section

  Required     : 
    LISTPTR Input         - Linked list with input strings
    OPTIONSTRUCT *Options - Mode options
    MAPSIZE *Map          - Information about basin area
    int MaxSoilLayers     - Maximum number of soil layers
    int MaxVegLayers      - Maximum number of vegetation layers
    int Dt                - Time step in seconds
    TOPOPIX **TopoMap     - Information about terrain characteristics
    DUMPSTRUCT *Dump      - Information on what to output when

  Returns      : void

  Modifies     : Members of Dump

  Comments     :
*****************************************************************************/
void InitDump(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map,
	      int MaxSoilLayers, int MaxVegLayers, int Dt,
	      TOPOPIX ** TopoMap, DUMPSTRUCT * Dump, int *NGraphics,
	      int **which_graphics)
{
  char *Routine = "InitDump";
  int i;
  int x;			/* counter */
  int y;			/* counter */
  int NImageVars;		/* Number of different variables for which to 
				   dump images */
  int NMapVars;			/* Number of different variables for which to 
				   dump maps */
  int temp_count;
  uchar **BasinMask;
  char sumoutfile[100];
  

  STRINIENTRY StrEnv[] = {
    {"OUTPUT", "OUTPUT DIRECTORY", "", ""},
    {"OUTPUT", "INITIAL STATE DIRECTORY", "", ""},
    {"OUTPUT", "NUMBER OF OUTPUT PIXELS", "", ""},
    {"OUTPUT", "NUMBER OF MODEL STATES", "", ""},
    {"OUTPUT", "NUMBER OF MAP VARIABLES", "", ""},
    {"OUTPUT", "NUMBER OF IMAGE VARIABLES", "", ""},
    {"OUTPUT", "NUMBER OF GRAPHICS", "", ""},
    {NULL, NULL, "", NULL},
  };

  printf("Initializing dump procedures\n");

  /* Get the key-entry pairs from the input file */
  for (i = 0; StrEnv[i].SectionName; i++)
    GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default,
		  StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input);

  /* Assign the entries to the variables */
  if (IsEmptyStr(StrEnv[output_path].VarStr))
    ReportError(StrEnv[output_path].KeyName, 51);
  strcpy(Dump->Path, StrEnv[output_path].VarStr);

  // delete any previous failure_summary.txt file
  sprintf(sumoutfile, "%sfailure_summary.txt", Dump->Path);
  if (remove(sumoutfile) != -1)
    printf(" - removed old version of failure_summary.txt\n");

  if (IsEmptyStr(StrEnv[initial_state_path].VarStr))
    strcpy(Dump->InitStatePath, Dump->Path);
  strcpy(Dump->InitStatePath, StrEnv[initial_state_path].VarStr);

  if (IsEmptyStr(StrEnv[npixels].VarStr))
    Dump->NPix = 0;
  else if (!CopyInt(&(Dump->NPix), StrEnv[npixels].VarStr, 1) || Dump->NPix < 0)
    ReportError(StrEnv[npixels].KeyName, 51);

  if (IsEmptyStr(StrEnv[nstates].VarStr))
    Dump->NStates = 0;
  else if (!CopyInt(&(Dump->NStates), StrEnv[nstates].VarStr, 1))
    ReportError(StrEnv[nstates].KeyName, 51);

  if (IsEmptyStr(StrEnv[nmapvars].VarStr))
    NMapVars = 0;
  else if (!CopyInt(&NMapVars, StrEnv[nmapvars].VarStr, 1) || NMapVars < 0)
    ReportError(StrEnv[nmapvars].KeyName, 51);

  if (IsEmptyStr(StrEnv[nimagevars].VarStr))
    NImageVars = 0;
  else if (!CopyInt(&NImageVars, StrEnv[nimagevars].VarStr, 1) ||
	   NImageVars < 0)
    ReportError(StrEnv[nimagevars].KeyName, 51);

  if (IsEmptyStr(StrEnv[ngraphics].VarStr))
    *NGraphics = 0;
  else if (!CopyInt(NGraphics, StrEnv[ngraphics].VarStr, 1) || *NGraphics < 0)
    ReportError(StrEnv[ngraphics].KeyName, 51);

  if (Options->Extent == POINT)
    *NGraphics = 0;

  Dump->NMaps = NMapVars + NImageVars;

  // Open file for recording aggregated values for entire basin
  sprintf(Dump->Aggregate.FileName, "%sAggregated.Values", Dump->Path);
  OpenFile(&(Dump->Aggregate.FilePtr), Dump->Aggregate.FileName, "w", TRUE);

  // If specified, open file for recording aggregated sediment values for entire basin
  if (Options->Sediment) {
    sprintf(Dump->AggregateSediment.FileName, "%sAggregatedSediment.Values", Dump->Path);
    OpenFile(&(Dump->AggregateSediment.FilePtr), Dump->AggregateSediment.FileName, "w", TRUE);

    // Open file for recording mass balance for entire basin
    sprintf(Dump->SedBalance.FileName, "%sMassSediment.Balance", Dump->Path);
    OpenFile(&(Dump->SedBalance.FilePtr), Dump->SedBalance.FileName, "w", TRUE);
  }

  // Open file for recording mass balance for entire basin
  sprintf(Dump->Balance.FileName, "%sMass.Balance", Dump->Path);
  OpenFile(&(Dump->Balance.FilePtr), Dump->Balance.FileName, "w", TRUE);

  if (Options->Extent != POINT) {

    /* Read remaining information from dump info file */

    if (Dump->NStates > 0)
      InitStateDump(Input, Dump->NStates, &(Dump->DState));

    /* if Dump->NStates < 0, the state will be dumped every time step, this is
       done directly in ExecDump */

    if (!(BasinMask = (uchar **) calloc(Map->NY, sizeof(uchar *))))
      ReportError(Routine, 1);
    for (y = 0; y < Map->NY; y++)
      if (!(BasinMask[y] = (uchar *) calloc(Map->NX, sizeof(uchar))))
	ReportError(Routine, 1);

    for (y = 0; y < Map->NY; y++)
      for (x = 0; x < Map->NX; x++)
	BasinMask[y][x] = TopoMap[y][x].Mask;

    if (Dump->NPix > 0) {
      temp_count = InitPixDump(Input, Map, BasinMask, Dump->Path, Dump->NPix,
			       &(Dump->Pix), Options);

      if (temp_count == 0) {
	Dump->NPix = 0;
	printf("no candidate dump pixels accepted \n");
      }
      else {
	Dump->NPix = temp_count;
	printf("total number of accepted dump pixels %d \n", Dump->NPix);
      }
    }
    for (y = 0; y < Map->NY; y++)
      free(BasinMask[y]);
    free(BasinMask);

    if (Dump->NMaps > 0)
      InitMapDump(Input, Map, MaxSoilLayers, MaxVegLayers, Dump->Path,
		  Dump->NMaps, NMapVars, &(Dump->DMap));
    if (NImageVars > 0)
      InitImageDump(Input, Dt, Map, MaxSoilLayers, MaxVegLayers, Dump->Path,
		    Dump->NMaps, NImageVars, &(Dump->DMap));

    if (*NGraphics > 0)
      InitGraphicsDump(Input, *NGraphics, &which_graphics);

    /* if no network open unit hydrograph file */
    if (!(Options->HasNetwork)) {
      sprintf(Dump->Stream.FileName, "%sStream.Flow", Dump->Path);
      OpenFile(&(Dump->Stream.FilePtr), Dump->Stream.FileName, "w", TRUE);
    }
  }
}
Пример #6
0
/*******************************************************************************
  Function name: InitImageDump()

  Purpose      : Initialize the image dumps.  This information is in the 
		 [OUTPUT] section of the input file

  Required     : 
    LISTPTR Input         - Linked list with input strings
    int Dt                - Model timestep in seconds
    MAPSIZE *MapDump      - Information about areal extent
    int MaxSoilLayers     - Maximum number of soil layers
    int MaxVegLayers      - Maximum number of vegetation layers
    char *Path            - Directory to write output to
    int NMaps             - Number of maps to dump
    int NImages           - Number of images to dump 
    MAPDUMP **DMap        - Array of maps and images to dump

  Returns      : void

  Modifies     : Members of DMap

  Comments     : InitImageDump must be preceded by a call to InitMapDump, since
                 the necessary memory is allocated there
*******************************************************************************/
void InitImageDump(LISTPTR Input, int Dt, MAPSIZE * Map, int MaxSoilLayers,
		   int MaxVegLayers, char *Path, int NMaps, int NImages,
		   MAPDUMP ** DMap)
{
  char *Routine = "InitImageDump";
  DATE End;			/* End of low resolution map dump period */
  DATE Start;			/* Start of low resolution map dump period */
  int i;			/* counter */
  int j;			/* counter */
  int Interval;			/* Interval between low resolution map dumps */
  int MaxLayers;		/* Maximum number of layers allowed for this 
				   variable */
  char KeyName[image_lower + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "IMAGE VARIABLE",
    "IMAGE LAYER",
    "IMAGE START",
    "IMAGE END",
    "IMAGE INTERVAL",
    "IMAGE UPPER LIMIT",
    "IMAGE LOWER LIMIT"
  };
  char *SectionName = "OUTPUT";
  char VarStr[image_lower + 1][BUFSIZE + 1];
  float tmpInterval;

  for (i = NMaps - NImages; i < NMaps; i++) {

    /* Read the key-entry pairs from the input file */
    for (j = 0; j <= image_lower; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i - (NMaps - NImages) + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
		    (unsigned long) BUFSIZE, Input);
    }

    /* Assign the entries to the appropriate variables */
    if (!CopyInt(&((*DMap)[i].ID), VarStr[image_variable], 1))
      ReportError(KeyName[image_variable], 51);

    if (!IsValidID((*DMap)[i].ID))
      ReportError("Input Options File", 19);

    if (IsMultiLayer((*DMap)[i].ID)) {
      MaxLayers = GetVarNLayers((*DMap)[i].ID, MaxSoilLayers, MaxVegLayers);
      if (!CopyInt(&((*DMap)[i].Layer), VarStr[image_layer], 1))
	ReportError(KeyName[image_layer], 51);
      if ((*DMap)[i].Layer < 1 || (*DMap)[i].Layer > MaxLayers)
	ReportError("Input Options File", 20);
    }
    else
      (*DMap)[i].Layer = 1;

    (*DMap)[i].Resolution = IMAGE_OUTPUT;

    strncpy((*DMap)[i].FileName, Path, BUFSIZE);
    GetVarAttr(&((*DMap)[i]));
    (*DMap)[i].NumberType = NC_BYTE;
    strcpy((*DMap)[i].Format, "%d");

    CreateMapFile((*DMap)[i].FileName, (*DMap)[i].FileLabel, Map);

    if (!SScanDate(VarStr[image_start], &Start))
      ReportError(KeyName[image_start], 51);

    if (!SScanDate(VarStr[image_end], &End))
      ReportError(KeyName[image_end], 51);

    if (!CopyFloat(&tmpInterval, VarStr[image_interval], 1))
      ReportError(KeyName[image_interval], 51);
    Interval = SECPHOUR * tmpInterval;

    if (Interval % Dt != 0 || Interval <= 0)
      ReportError("Input Options File", 24);

    if (((*DMap)[i].N = NumberOfSteps(&Start, &End, Interval)) < 1)
      ReportError("Input Options File", 25);

    if (!((*DMap)[i].DumpDate = (DATE *) calloc((*DMap)[i].N, sizeof(DATE))))
      ReportError(Routine, 1);

    CopyDate(&((*DMap)[i].DumpDate[0]), &Start);

    for (j = 1; j < (*DMap)[i].N; j++)
      (*DMap)[i].DumpDate[j] =
	NextDate(&((*DMap)[i].DumpDate[j - 1]), Interval);

    if (!CopyFloat(&((*DMap)[i].MaxVal), VarStr[image_upper], 1))
      ReportError(KeyName[image_upper], 51);

    if (!CopyFloat(&((*DMap)[i].MinVal), VarStr[image_lower], 1))
      ReportError(KeyName[image_lower], 51);
  }
}
Пример #7
0
/********************************************************************************
  Function Name: InitSoilTable()

  Purpose      : Initialize the soil lookup table
                 Processes most of the following section in InFileName:
		 [SOILS]

  Required     :
    SOILTABLE **SType - Pointer to lookup table
    LISTPTR Input     - Pointer to linked list with input info
    LAYER *Soil       - Pointer to structure with soil layer information

  Returns      : Number of soil layers

  Modifies     : SoilTable and Soil

  Comments     :
********************************************************************************/
int InitSoilTable(SOILTABLE ** SType, LISTPTR Input, LAYER * Soil)
{
  const char *Routine = "InitSoilTable";
  int i;			/* counter */
  int j;			/* counter */
  int NSoils;			/* Number of soil types */
  char KeyName[thermal_capacity + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "SOIL DESCRIPTION",
    "LATERAL CONDUCTIVITY",
    "EXPONENTIAL DECREASE",
    "DEPTH THRESHOLD",
    "MAXIMUM INFILTRATION",
    "CAPILLARY DRIVE",
    "SURFACE ALBEDO",
    "MANNINGS N",
    "NUMBER OF SOIL LAYERS",
    "POROSITY",
    "PORE SIZE DISTRIBUTION",
    "BUBBLING PRESSURE",
    "FIELD CAPACITY",
    "WILTING POINT",
    "BULK DENSITY",
    "VERTICAL CONDUCTIVITY",
    "THERMAL CONDUCTIVITY",
    "THERMAL CAPACITY"
  };
  char SectionName[] = "SOILS";
  char VarStr[thermal_capacity + 1][BUFSIZE + 1];

  /* Get the number of different soil types */
  GetInitString(SectionName, "NUMBER OF SOIL TYPES", "", VarStr[0],
		(unsigned long) BUFSIZE, Input);
  if (!CopyInt(&NSoils, VarStr[0], 1))
    ReportError("NUMBER OF SOIL TYPES", 51);

  if (NSoils == 0)
    return NSoils;

  if (!(Soil->NLayers = (int *) calloc(NSoils, sizeof(int))))
    ReportError((char *) Routine, 1);

  if (!(*SType = (SOILTABLE *) calloc(NSoils, sizeof(SOILTABLE))))
    ReportError((char *) Routine, 1);

  /********** Read information and allocate memory for each soil type *********/

  Soil->MaxLayers = 0;

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

    /* Read the key-entry pairs from the input file */
    for (j = 0; j <= thermal_capacity; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
		    (unsigned long) BUFSIZE, Input);
    }

    /* Assign the entries to the appropriate variables */
    if (IsEmptyStr(VarStr[soil_description]))
      ReportError(KeyName[soil_description], 51);

    strcpy((*SType)[i].Desc, VarStr[soil_description]);
    (*SType)[i].Index = i;

    if (!CopyFloat(&((*SType)[i].KsLat), VarStr[lateral_ks], 1))
      ReportError(KeyName[lateral_ks], 51);

    if (!CopyFloat(&((*SType)[i].KsLatExp), VarStr[exponent], 1))
      ReportError(KeyName[exponent], 51);

    if (!CopyFloat(&((*SType)[i].DepthThresh), VarStr[depth_thresh], 1))
      ReportError(KeyName[depth_thresh], 51);

    if (!CopyFloat(&((*SType)[i].MaxInfiltrationRate), VarStr[max_infiltration], 1))
      ReportError(KeyName[max_infiltration], 51);

    if (!CopyFloat(&((*SType)[i].G_Infilt), VarStr[capillary_drive], 1))
      ReportError(KeyName[capillary_drive], 51); 

    if (!CopyFloat(&((*SType)[i].Albedo), VarStr[soil_albedo], 1))
      ReportError(KeyName[soil_albedo], 51);

    if (!CopyInt(&(*SType)[i].NLayers, VarStr[number_of_layers], 1))
      ReportError(KeyName[number_of_layers], 51);
    Soil->NLayers[i] = (*SType)[i].NLayers;

    if (!CopyFloat(&((*SType)[i].Manning), VarStr[manning], 1))
      ReportError(KeyName[manning], 51);
    
    if (Soil->NLayers[i] > Soil->MaxLayers)
      Soil->MaxLayers = Soil->NLayers[i];
    
    /* allocate memory for the soil layers */
    if (!((*SType)[i].Porosity = (float *) calloc((*SType)[i].NLayers,
						  sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].PoreDist = (float *) calloc((*SType)[i].NLayers,
						  sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].Press = (float *) calloc((*SType)[i].NLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].FCap = (float *) calloc((*SType)[i].NLayers,
					      sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].WP = (float *) calloc((*SType)[i].NLayers,
					    sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].Dens = (float *) calloc((*SType)[i].NLayers,
					      sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].Ks = (float *) calloc((*SType)[i].NLayers,
					    sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].KhDry = (float *) calloc((*SType)[i].NLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].KhSol = (float *) calloc((*SType)[i].NLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*SType)[i].Ch = (float *) calloc((*SType)[i].NLayers,
					    sizeof(float))))
      ReportError((char *) Routine, 1);

    if (!CopyFloat((*SType)[i].Porosity, VarStr[porosity], (*SType)[i].NLayers))
      ReportError(KeyName[porosity], 51);

    if (!CopyFloat((*SType)[i].PoreDist, VarStr[pore_size],
		   (*SType)[i].NLayers))
      ReportError(KeyName[pore_size], 51);

    if (!CopyFloat((*SType)[i].Press, VarStr[bubbling_pressure],
		   (*SType)[i].NLayers))
      ReportError(KeyName[bubbling_pressure], 51);

    if (!CopyFloat((*SType)[i].FCap, VarStr[field_capacity],
		   (*SType)[i].NLayers))
      ReportError(KeyName[field_capacity], 51);

    if (!CopyFloat((*SType)[i].WP, VarStr[wilting_point], (*SType)[i].NLayers))
      ReportError(KeyName[wilting_point], 51);

    if (!CopyFloat((*SType)[i].Dens, VarStr[bulk_density], (*SType)[i].NLayers))
      ReportError(KeyName[bulk_density], 51);

    if (!CopyFloat((*SType)[i].Ks, VarStr[vertical_ks], (*SType)[i].NLayers))
      ReportError(KeyName[vertical_ks], 51);

    if (!CopyFloat((*SType)[i].KhSol, VarStr[solids_thermal],
		   (*SType)[i].NLayers))
      ReportError(KeyName[solids_thermal], 51);

    if (!CopyFloat((*SType)[i].Ch, VarStr[thermal_capacity],
		   (*SType)[i].NLayers))
      ReportError(KeyName[thermal_capacity], 51);
  }

  for (i = 0; i < NSoils; i++)
    for (j = 0; j < (*SType)[i].NLayers; j++) {
      (*SType)[i].KhDry[j] = CalcKhDry((*SType)[i].Dens[j]);
      if (((*SType)[i].Porosity[j] < (*SType)[i].FCap[j])
	  || ((*SType)[i].Porosity[j] < (*SType)[i].WP[j])
	  || ((*SType)[i].FCap[j] < (*SType)[i].WP[j]))
	ReportError((*SType)[i].Desc, 11);
    }

  return NSoils;
}
Пример #8
0
/********************************************************************************
  Function Name: InitVegTable()

  Purpose      : Initialize the vegetation lookup table
                 Processes most of the following section in the input file:
		 [VEGETATION]

  Required     :
    VEGTABLE **VType - Pointer to lookup table
    LISTPTR Input    - Pointer to linked list with input info
    LAYER *Veg       - Pointer to structure with veg layer information

  Returns      : Number of vegetation types

  Modifies     : VegTable and Veg

  Comments     :
********************************************************************************/
int InitVegTable(VEGTABLE ** VType, LISTPTR Input, OPTIONSTRUCT * Options,
		 LAYER * Veg)
{
  const char *Routine = "InitVegTable";
  int i;			/* Counter */
  int j;			/* Counter */
  float impervious;		/* flag to check whether impervious layers are 
				   specified */
  int NVegs;			/* Number of vegetation types */
  char KeyName[understory_monalb + 1][BUFSIZE + 1];
  char *KeyStr[] = {
    "VEGETATION DESCRIPTION",
    "OVERSTORY PRESENT",
    "UNDERSTORY PRESENT",
    "FRACTIONAL COVERAGE",
    "HEMI FRACT COVERAGE",
    "TRUNK SPACE",
    "AERODYNAMIC ATTENUATION",
    "RADIATION ATTENUATION",
    "CLUMPING FACTOR",
    "LEAF ANGLE A",
    "LEAF ANGLE B",
    "SCATTERING PARAMETER",
    "MAX SNOW INT CAPACITY",
    "MASS RELEASE DRIP RATIO",
    "SNOW INTERCEPTION EFF",
    "IMPERVIOUS FRACTION",
	"DETENTION FRACTION",
    "DETENTION DECAY",
    "HEIGHT",
    "MAXIMUM RESISTANCE",
    "MINIMUM RESISTANCE",
    "MOISTURE THRESHOLD",
    "VAPOR PRESSURE DEFICIT",
    "RPC",
    "NUMBER OF ROOT ZONES",
    "ROOT ZONE DEPTHS",
    "OVERSTORY ROOT FRACTION",
    "UNDERSTORY ROOT FRACTION",
    "OVERSTORY MONTHLY LAI",
    "UNDERSTORY MONTHLY LAI",
    "OVERSTORY MONTHLY ALB",
    "UNDERSTORY MONTHLY ALB"
  };
  char SectionName[] = "VEGETATION";
  char VarStr[understory_monalb + 1][BUFSIZE + 1];

  /* Get the number of different vegetation types */
  GetInitString(SectionName, "NUMBER OF VEGETATION TYPES", "", VarStr[0],
		(unsigned long) BUFSIZE, Input);
  if (!CopyInt(&NVegs, VarStr[0], 1))
    ReportError("NUMBER OF VEGETATION TYPES", 51);

  if (NVegs == 0)
    return NVegs;

  if (!(Veg->NLayers = (int *) calloc(NVegs, sizeof(int))))
    ReportError((char *) Routine, 1);

  if (!(*VType = (VEGTABLE *) calloc(NVegs, sizeof(VEGTABLE))))
    ReportError((char *) Routine, 1);

  /******* Read information and allocate memory for each vegetation type ******/

  Veg->MaxLayers = 0;
  impervious = 0.0;
  for (i = 0; i < NVegs; i++) {

    /* Read the key-entry pairs from the input file */
    for (j = 0; j <= understory_monalb; j++) {
      sprintf(KeyName[j], "%s %d", KeyStr[j], i + 1);
      GetInitString(SectionName, KeyName[j], "", VarStr[j],
		    (unsigned long) BUFSIZE, Input);
    }

    /* Assign the entries to the appropriate variables */
    if (IsEmptyStr(VarStr[veg_description]))
      ReportError(KeyName[veg_description], 51);
    strcpy((*VType)[i].Desc, VarStr[veg_description]);
    MakeKeyString(VarStr[veg_description]);	/* basically makes the string all
						   uppercase and removed spaces so
						   it is easier to compare */
    if (strncmp(VarStr[veg_description], "GLACIER", strlen("GLACIER")) == 0) {
      (*VType)[i].Index = GLACIER;
    }
    else
      (*VType)[i].Index = i;

    (*VType)[i].NVegLayers = 0;

    if (strncmp(VarStr[overstory], "TRUE", 4) == 0) {
      (*VType)[i].OverStory = TRUE;
      ((*VType)[i].NVegLayers)++;
    }
    else if (strncmp(VarStr[overstory], "FALSE", 5) == 0)
      (*VType)[i].OverStory = FALSE;
    else
      ReportError(KeyName[overstory], 51);

    if (strncmp(VarStr[understory], "TRUE", 4) == 0) {
      (*VType)[i].UnderStory = TRUE;
      ((*VType)[i].NVegLayers)++;
    }
    else if (strncmp(VarStr[understory], "FALSE", 5) == 0)
      (*VType)[i].UnderStory = FALSE;
    else
      ReportError(KeyName[understory], 51);

    Veg->NLayers[i] = (*VType)[i].NVegLayers;
    if ((*VType)[i].NVegLayers > Veg->MaxLayers)
      Veg->MaxLayers = (*VType)[i].NVegLayers;

    if (!CopyInt(&(*VType)[i].NSoilLayers, VarStr[number_of_root_zones], 1))
      ReportError(KeyName[number_of_root_zones], 51);

    if (!CopyFloat(&((*VType)[i].ImpervFrac), VarStr[imperv_frac], 1))
		ReportError(KeyName[imperv_frac], 51);
	impervious += (*VType)[i].ImpervFrac;

	 if (!CopyFloat(&((*VType)[i].DetentionFrac), VarStr[detention_frac], 1))
		 ReportError(KeyName[detention_frac], 51);

    if (!CopyFloat(&((*VType)[i].DetentionDecay), VarStr[detention_decay], 1))
		ReportError(KeyName[detention_decay], 51);

    /* allocate memory for the vegetation layers */

    if (!((*VType)[i].Fract = (float *) calloc((*VType)[i].NVegLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);

    if (Options->CanopyRadAtt == VARIABLE) {
      if (!((*VType)[i].HemiFract = (float *) calloc((*VType)[i].NVegLayers,
						     sizeof(float))))
      ReportError((char *) Routine, 1);
    }
    else {
      (*VType)[i].HemiFract = NULL;
    }

    if (!((*VType)[i].Height = (float *) calloc((*VType)[i].NVegLayers,
						sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].RsMax = (float *) calloc((*VType)[i].NVegLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].RsMin = (float *) calloc((*VType)[i].NVegLayers,
					       sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].MoistThres = (float *) calloc((*VType)[i].NVegLayers,
						    sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].VpdThres = (float *) calloc((*VType)[i].NVegLayers,
						  sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].Rpc = (float *) calloc((*VType)[i].NVegLayers,
					     sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].Albedo = (float *) calloc(((*VType)[i].NVegLayers + 1),
						sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].MaxInt = (float *) calloc((*VType)[i].NVegLayers,
						sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].LAI = (float *) calloc((*VType)[i].NVegLayers,
					     sizeof(float))))
      ReportError((char *) Routine, 1);
    if (!((*VType)[i].RootFract = (float **) calloc((*VType)[i].NVegLayers,
						    sizeof(float *))))
      ReportError((char *) Routine, 1);

    for (j = 0; j < (*VType)[i].NVegLayers; j++) {
      if (!((*VType)[i].RootFract[j] =
	    (float *) calloc((*VType)[i].NSoilLayers, sizeof(float))))
	ReportError((char *) Routine, 1);
    }
    if (!((*VType)[i].RootDepth = (float *) calloc((*VType)[i].NSoilLayers,
						   sizeof(float))))
      ReportError((char *) Routine, 1);

    if (!((*VType)[i].LAIMonthly = (float **) calloc((*VType)[i].NVegLayers,
						     sizeof(float *))))
      ReportError((char *) Routine, 1);
    for (j = 0; j < (*VType)[i].NVegLayers; j++) {
      if (!((*VType)[i].LAIMonthly[j] = (float *) calloc(12, sizeof(float))))
	ReportError((char *) Routine, 1);
    }
    
    if (!((*VType)[i].AlbedoMonthly = (float **) calloc((*VType)[i].NVegLayers,
							sizeof(float *))))
      ReportError((char *) Routine, 1);
    for (j = 0; j < (*VType)[i].NVegLayers; j++) {
      if (!((*VType)[i].AlbedoMonthly[j] = (float *) calloc(12, sizeof(float))))
	ReportError((char *) Routine, 1);
    }

    /* assign the entries to the appropriate variables */
    /* allocation of zero memory is not supported on some
       compilers */
    if ((*VType)[i].OverStory == TRUE) {
		if (!CopyFloat(&((*VType)[i].Fract[0]), VarStr[fraction], 1))
			ReportError(KeyName[fraction], 51);
		
		if (Options->CanopyRadAtt == VARIABLE) {
			if (!CopyFloat(&((*VType)[i].HemiFract[0]), VarStr[hemifraction], 1))
				ReportError(KeyName[hemifraction], 51);
			if (!CopyFloat(&((*VType)[i].ClumpingFactor),VarStr[clumping_factor], 1))
			   ReportError(KeyName[clumping_factor], 51);
			if (!CopyFloat(&((*VType)[i].LeafAngleA), VarStr[leaf_angle_a], 1))
				ReportError(KeyName[leaf_angle_a], 51);
			if (!CopyFloat(&((*VType)[i].LeafAngleB), VarStr[leaf_angle_b], 1))
				ReportError(KeyName[leaf_angle_b], 51);
			if (!CopyFloat(&((*VType)[i].Scat), VarStr[scat], 1))
				ReportError(KeyName[scat], 51);
			(*VType)[i].Atten = NOT_APPLICABLE;
		}
		else if (Options->CanopyRadAtt == FIXED) {
			if (!CopyFloat(&((*VType)[i].Atten), VarStr[radiation_att], 1))
				ReportError(KeyName[radiation_att], 51);
			(*VType)[i].ClumpingFactor = NOT_APPLICABLE;
			(*VType)[i].Scat = NOT_APPLICABLE;
			(*VType)[i].LeafAngleA = NOT_APPLICABLE;
			(*VType)[i].LeafAngleB = NOT_APPLICABLE;
		}
		
		if (!CopyFloat(&((*VType)[i].Trunk), VarStr[trunk_space], 1))
			ReportError(KeyName[trunk_space], 51);
		
		if (!CopyFloat(&((*VType)[i].Cn), VarStr[aerodynamic_att], 1))
			ReportError(KeyName[aerodynamic_att], 51);

      if (!CopyFloat(&((*VType)[i].MaxSnowInt), VarStr[snow_int_cap], 1))
		  ReportError(KeyName[snow_int_cap], 51);

      if (!CopyFloat(&((*VType)[i].MDRatio), VarStr[mass_drip_ratio], 1))
		  ReportError(KeyName[mass_drip_ratio], 51);

      if (!CopyFloat(&((*VType)[i].SnowIntEff), VarStr[snow_int_eff], 1))
	ReportError(KeyName[snow_int_eff], 51);

      if (!CopyFloat((*VType)[i].RootFract[0], VarStr[overstory_fraction],
		     (*VType)[i].NSoilLayers))
	ReportError(KeyName[overstory_fraction], 51);

      if (!CopyFloat((*VType)[i].LAIMonthly[0], VarStr[overstory_monlai], 12))
	ReportError(KeyName[overstory_monlai], 51);

      if (!CopyFloat((*VType)[i].AlbedoMonthly[0], VarStr[overstory_monalb],
		     12))
	ReportError(KeyName[overstory_monalb], 51);

      if ((*VType)[i].UnderStory == TRUE) {
	(*VType)[i].Fract[1] = 1.0;
	if (!CopyFloat((*VType)[i].RootFract[1], VarStr[understory_fraction],
		       (*VType)[i].NSoilLayers))
	  ReportError(KeyName[understory_fraction], 51);

	if (!CopyFloat((*VType)[i].LAIMonthly[1], VarStr[understory_monlai],
		       12))
	  ReportError(KeyName[understory_monlai], 51);

	if (!CopyFloat((*VType)[i].AlbedoMonthly[1], VarStr[understory_monalb],
		       12))
	  ReportError(KeyName[understory_monalb], 51);

      }
    }
    else {
      if ((*VType)[i].UnderStory == TRUE) {
	(*VType)[i].Fract[0] = 1.0;
	if (!CopyFloat((*VType)[i].RootFract[0], VarStr[understory_fraction],
		       (*VType)[i].NSoilLayers))
	  ReportError(KeyName[understory_fraction], 51);

	if (!CopyFloat((*VType)[i].LAIMonthly[0], VarStr[understory_monlai],
		       12))
	  ReportError(KeyName[understory_monlai], 51);

	if (!CopyFloat((*VType)[i].AlbedoMonthly[0], VarStr[understory_monalb],
		       12))
	  ReportError(KeyName[understory_monalb], 51);

      }
      (*VType)[i].Trunk = NOT_APPLICABLE;
      (*VType)[i].Cn = NOT_APPLICABLE;
      (*VType)[i].Atten = NOT_APPLICABLE;
      (*VType)[i].ClumpingFactor = NOT_APPLICABLE;
    }

    if (!CopyFloat((*VType)[i].Height, VarStr[height], (*VType)[i].NVegLayers))
      ReportError(KeyName[height], 51);

    if (!CopyFloat((*VType)[i].RsMax, VarStr[max_resistance],
		   (*VType)[i].NVegLayers))
      ReportError(KeyName[max_resistance], 51);

    if (!CopyFloat((*VType)[i].RsMin, VarStr[min_resistance],
		   (*VType)[i].NVegLayers))
      ReportError(KeyName[min_resistance], 51);

    if (!CopyFloat((*VType)[i].MoistThres, VarStr[moisture_threshold],
		   (*VType)[i].NVegLayers))
      ReportError(KeyName[moisture_threshold], 51);

    if (!CopyFloat((*VType)[i].VpdThres, VarStr[vpd], (*VType)[i].NVegLayers))
      ReportError(KeyName[vpd], 51);

    if (!CopyFloat((*VType)[i].Rpc, VarStr[rpc], (*VType)[i].NVegLayers))
      ReportError(KeyName[rpc], 51);

    if (!CopyFloat((*VType)[i].RootDepth, VarStr[root_zone_depth],
		   (*VType)[i].NSoilLayers))
      ReportError(KeyName[root_zone_depth], 51);

    /* Calculate the wind speed profiles and the aerodynamical resistances
       for each layer.  The values are normalized for a reference height wind
       speed of 1 m/s, and are adjusted each timestep using actual reference 
       height wind speeds */

    CalcAerodynamic((*VType)[i].NVegLayers, (*VType)[i].OverStory,
		    (*VType)[i].Cn, (*VType)[i].Height, (*VType)[i].Trunk,
		    (*VType)[i].U, &((*VType)[i].USnow), (*VType)[i].Ra,
		    &((*VType)[i].RaSnow));
  }

  if (impervious) {
    GetInitString(SectionName, "IMPERVIOUS SURFACE ROUTING FILE", "", VarStr[0],
		(unsigned long) BUFSIZE, Input);
    if (IsEmptyStr(VarStr[0]))
      ReportError("IMPERVIOUS SURFACE ROUTING FILE", 51);
    strcpy(Options->ImperviousFilePath, VarStr[veg_description]);
  }
  
  return NVegs;
}
Пример #9
0
/*****************************************************************************
  Function name: InitConstants()

  Purpose      : Initialize constants and settings for DHSVM run
                 Processes the following sections in InFile:
                 [OPTIONS]
                 [AREA]
                 [TIME]
                 [CONSTANTS}

  Required     :
    LISTPTR Input          - Linked list with input strings
    OPTIONSTRUCT *Options   - Structure with different program options
    MAPSIZE *Map            - Coverage and resolution of model area
    SOLARGEOMETRY *SolarGeo - Solar geometry information
    TIMESTRUCT *Time        - Begin and end times, model timestep

  Returns      : void

  Modifies     : (see list of required above)

  Comments     : Make sure order in settings.h matches list of keys here
                      Some modifications for input of monthly atmospheric parameters for 
	        soil chemistry model, MWW -sc 10/2005
*****************************************************************************/
void InitConstants(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map,
		   SOLARGEOMETRY * SolarGeo, TIMESTRUCT * Time, BASINWIDE * Basinwide)
{
//  const char *Routine = "InitConstants";
  int i, j;			/* counter */
  double PointModelX;		/* X-coordinate for POINT model mode */
  double PointModelY;		/* Y-coordinate for POINT model mode */
  float TimeStep;		/* Timestep in hours */
  DATE End;			/* End of run */
  DATE Start;			/* Start of run */

  STRINIENTRY StrEnv[] = {
    {"OPTIONS", "INPUTFILEVERSION", "", ""},
    {"OPTIONS", "FORMAT", "", ""},
    {"OPTIONS", "EXTENT", "", ""},
    {"OPTIONS", "GRADIENT", "", ""},
    {"OPTIONS", "FLOW ROUTING", "", ""},
    {"OPTIONS", "SENSIBLE HEAT FLUX", "", ""},
    {"OPTIONS", "STREAM TEMPERATURE", "", ""},
    {"OPTIONS", "GROUNDWATER", ""  , ""},
    {"OPTIONS", "CHEMISTRY", ""  , ""},
    {"OPTIONS", "GLACIER MOVEMENT", ""  , ""},    
    {"OPTIONS", "CHANNEL INFILTRATION", ""  , ""},
    {"OPTIONS", "FRACTIONAL ROUTING", ""  , ""},
    {"OPTIONS", "INTERPOLATION", "", ""},
    {"OPTIONS", "MM5", "", ""},
    {"OPTIONS", "QPF", "", ""},
    {"OPTIONS", "PRISM", "", ""},
    {"OPTIONS", "CANOPY RADIATION ATTENUATION MODE", "", ""},
    {"OPTIONS", "SHADING", "", ""},
    {"OPTIONS", "SNOTEL", "", ""},
    {"OPTIONS", "OUTSIDE", "", ""},
    {"OPTIONS", "RHOVERRIDE", "", ""},
    {"OPTIONS", "PRECIPITATION SOURCE", "", ""},
    {"OPTIONS", "WIND SOURCE", "", ""},
    {"OPTIONS", "TEMPERATURE LAPSE RATE", "", ""},
    {"OPTIONS", "PRECIPITATION LAPSE RATE", "", ""},
    {"OPTIONS", "CRESSMAN RADIUS", "", ""},
    {"OPTIONS", "CRESSMAN STATIONS", "", ""},
    {"OPTIONS", "PRISM DATA PATH", "", ""},
    {"OPTIONS", "PRISM DATA EXTENSION", "", ""},
    {"OPTIONS", "SHADING DATA PATH", "", ""},
    {"OPTIONS", "SHADING DATA EXTENSION", "", ""},
    {"OPTIONS", "SKYVIEW DATA PATH", "", ""},
    {"OPTIONS", "INITIAL STATE PATH", "", ""},
    {"AREA", "COORDINATE SYSTEM", "", ""},
    {"AREA", "EXTREME NORTH", "", ""},
    {"AREA", "EXTREME WEST", "", ""},
    {"AREA", "CENTER LATITUDE", "", ""},
    {"AREA", "CENTER LONGITUDE", "", ""},
    {"AREA", "TIME ZONE MERIDIAN", "", ""},
    {"AREA", "NUMBER OF ROWS", "", ""},
    {"AREA", "NUMBER OF COLUMNS", "", ""},
    {"AREA", "GRID SPACING", "", ""},
    {"AREA", "POINT NORTH", "", ""},
    {"AREA", "POINT EAST", "", ""},
    {"TIME", "TIME STEP", "", ""},
    {"TIME", "MODEL START", "", ""},
    {"TIME", "MODEL END", "", ""},
    {"CONSTANTS", "GROUND ROUGHNESS", "", ""},
    {"CONSTANTS", "SNOW ROUGHNESS", "", ""},
    {"CONSTANTS", "RAIN THRESHOLD", "", ""},
    {"CONSTANTS", "SNOW THRESHOLD", "", ""},
    {"CONSTANTS", "SNOW WATER CAPACITY", "", ""},
    {"CONSTANTS", "REFERENCE HEIGHT", "", ""},
    {"CONSTANTS", "RAIN LAI MULTIPLIER", "", ""},
    {"CONSTANTS", "SNOW LAI MULTIPLIER", "", ""},
    {"CONSTANTS", "MIN INTERCEPTED SNOW", "", ""},
    {"CONSTANTS", "OUTSIDE BASIN VALUE", "", ""},
    {"CONSTANTS", "GLACIER CREEP ACTIVATION ENERGY", "", ""},
    {"CONSTANTS", "GLEN CONSTANT", "", ""},
    {"CONSTANTS", "MAXIMUM GLACIER FLUX FRACTION", "", ""},
    {"CONSTANTS", "TEMPERATURE LAPSE RATE", "", ""},
    {"CONSTANTS", "PRECIPITATION LAPSE RATE", "", ""},
    {"CONSTANTS", "DEPTH RATIO", "", ""},
    {"CONSTANTS", "WIND ATTENUATION FACTOR", "", ""},
    {"CONSTANTS", "RAD ATTENUATION FACTOR", "", ""},
    {"CONSTANTS", "MINIMUM SEGMENT ORDER", "", ""},
    {"CHEMISTRY", "METABOLIC DOC DECOMPOSITION RATE", "", ""},
    {"CHEMISTRY", "STRUCTURAL DOC DECOMPOSITION RATE", "", ""},
    {"CHEMISTRY", "DECOMPOSITION RATE CONSTANT OF DOC", "", ""},
    {"CHEMISTRY", "MAXIMUM DOC SORPTION COEFFICIENT", "", ""},
    {"CHEMISTRY", "C:N FOR SORBED DOM", "", ""},
    {"CHEMISTRY", "C:N FOR MICROBIAL DECOMP OF DOM", "", ""},
    {"CHEMISTRY", "BACKGROUND CATIONS", "", ""},
    {"CHEMISTRY", "NITRIFICATION TEMPERATURE FACTOR", "", ""},
    {"CHEMISTRY", "FREE AIR CO2 DIFFUSION COEFFICIENT", "", ""},
    {"CHEMISTRY", "FREE AIR O2 DIFFUSION COEFFICIENT", "", ""},
    {"CHEMISTRY", "MASS TRANSFER COEFFICIENT OF DISSOLVED CO2", "", ""},
    {"CHEMISTRY", "MASS TRANSFER COEFFICIENT OF DISSOLVED O2", "", ""},
    {"CHEMISTRY", "DENITRIFICATION SATURATION THRESHOLD", "", ""},
    {"CHEMISTRY", "NITRATE REDUCTION HALF SATURATION FRACTION", "", ""},
    {"CHEMISTRY", "OXYGEN CONCENTRATION REACTION COEFFICIENT", "", ""},
    {"CHEMISTRY", "SUSPENDED DOC MINERALIZATION CONSTANT", "", ""},
    {"CHEMISTRY", "SUSPENDED DON HYDROLYSIS RATE", "", ""}, 
    {"CHEMISTRY", "SUSPENDED AMMONIUM DECOMPOSITION RATE", "", ""},
    {"CHEMISTRY", "SUSPENDED NITRIFICATION RATE", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC CO2 CONCENTRATION", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC DOC CONCENTRATION", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC DON CONCENTRATION", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC NH4 CONCENTRATION", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC NO3 CONCENTRATION", "", ""},
    {"CHEMISTRY", "ATMOSPHERIC NO2 CONCENTRATION", "", ""},
    {NULL, NULL, "", NULL}
  };

  /* Read the key-entry pairs from the input file */
  for (i = 0; StrEnv[i].SectionName; i++)
    GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default,
		  StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input);

  /**************** Determine model options ****************/

  /* Determine file format to be used */
   if (strncmp(StrEnv[inputfileversion].VarStr, "045", 3) != 0)
   {
	   printf("\n\n****************************************\nERROR LOADING INPUT FILE, WRONG VERSION\n");
	   printf("Please make sure that the inputfileversion field in the [OPTIONS] section of the config file matches the INPUT_FILE_VERSION constant set in settings.h\n");
	   printf("\nExpected INPUT_FILE_VERSION=");
	   printf(INPUT_FILE_VERSION);
	   printf("\tValue in Input file=%s",StrEnv[inputfileversion].VarStr);
	   ReportError(StrEnv[inputfileversion].KeyName,51);
   }
  if (strncmp(StrEnv[format].VarStr, "BIN", 3) == 0)
    Options->FileFormat = BIN;
  else if (strncmp(StrEnv[format].VarStr, "NETCDF", 3) == 0)
    Options->FileFormat = NETCDF;
  else if (strncmp(StrEnv[format].VarStr, "BYTESWAP", 3) == 0)
    Options->FileFormat = BYTESWAP;
  else
    ReportError(StrEnv[format].KeyName, 51);

  /* Determine whether the model should be run in POINT mode or in BASIN mode.
     If in POINT mode also read which pixel to model */
  if (strncmp(StrEnv[extent].VarStr, "POINT", 5) == 0) {
    Options->Extent = POINT;
    Options->HasNetwork = FALSE;
  }
  else if (strncmp(StrEnv[extent].VarStr, "BASIN", 5) == 0) {
    Options->Extent = BASIN;
  }
  else
    ReportError(StrEnv[extent].KeyName, 51);

  /* Determine how the flow gradient should be calculated */
  if (Options->Extent != POINT) {
    if (strncmp(StrEnv[gradient].VarStr, "TOPO", 4) == 0)
      Options->FlowGradient = TOPOGRAPHY;
    else if (strncmp(StrEnv[gradient].VarStr, "WATER", 5) == 0)
      Options->FlowGradient = WATERTABLE;
    else
      ReportError(StrEnv[gradient].KeyName, 51);
  }
  else
    Options->FlowGradient = NOT_APPLICABLE;

  /* Determine what meterological interpolation to use */

  if (strncmp(StrEnv[interpolation].VarStr, "INVDIST", 7) == 0)
    Options->Interpolation = INVDIST;
  else if (strncmp(StrEnv[interpolation].VarStr, "NEAREST", 7) == 0)
    Options->Interpolation = NEAREST;
  else if (strncmp(StrEnv[interpolation].VarStr, "VARCRESS", 8) == 0)
    Options->Interpolation = VARCRESS;
  else
    ReportError(StrEnv[interpolation].KeyName, 51);

  /* if VARIABLE CRESTMAN interpolation then get parameters */
  if (Options->Interpolation == VARCRESS) {
    if (!CopyInt(&(Options->CressRadius), StrEnv[cressman_radius].VarStr, 1))
      ReportError(StrEnv[cressman_radius].KeyName, 51);
    if (!CopyInt
	(&(Options->CressStations), StrEnv[cressman_stations].VarStr, 1))
      ReportError(StrEnv[cressman_stations].KeyName, 51);
  }

  /* Determine whether a road/network is imposed on the model area */
  if (Options->Extent != POINT) {
    if (strncmp(StrEnv[flow_routing].VarStr, "NETWORK", 7) == 0)
      Options->HasNetwork = TRUE;
    else if (strncmp(StrEnv[flow_routing].VarStr, "UNIT", 4) == 0)
      Options->HasNetwork = FALSE;
    else
      ReportError(StrEnv[flow_routing].KeyName, 51);
  }
  else
    Options->HasNetwork = FALSE;

  /* Determine whether a sensible heat flux should be calculated */
  if (strncmp(StrEnv[sensible_heat_flux].VarStr, "TRUE", 4) == 0)
    Options->HeatFlux = TRUE;
  else if (strncmp(StrEnv[sensible_heat_flux].VarStr, "FALSE", 5) == 0)
    Options->HeatFlux = FALSE;
  else
    ReportError(StrEnv[sensible_heat_flux].KeyName, 51);


  /* Determine whether or not calculate Stream Temperature  MWW 08112004 */
  if (strncmp(StrEnv[stream_temperature].VarStr, "TRUE", 4) == 0)
    Options->StreamTemp = TRUE;
  else if (strncmp(StrEnv[stream_temperature].VarStr, "FALSE", 5) == 0)
    Options->StreamTemp = FALSE;
  else
   ReportError(StrEnv[stream_temperature].KeyName, 51);

  /* determine if deeper groundwater is represented */
  if (strncmp(StrEnv[groundwater].VarStr, "TRUE", 4) == 0) 
    Options->Groundwater = TRUE;
  else if (strncmp(StrEnv[groundwater].VarStr, "FALSE", 5) == 0)
    Options->Groundwater = FALSE;
  else
    ReportError(StrEnv[groundwater].KeyName, 51);

  /* determine if soil chemistry is incorporated */
     if (strncmp(StrEnv[chemistry].VarStr, "TRUE", 4) == 0)
    Options->Chemistry = TRUE;
  else if (strncmp(StrEnv[chemistry].VarStr, "FALSE", 5) == 0)
    Options->Chemistry = FALSE;
  else
    ReportError(StrEnv[chemistry].KeyName, 51);

  /* ALLOW GLACIERS TO MOVE ? */
     if (strncmp(StrEnv[glacier_movement].VarStr, "TRUE", 4) == 0)
    Options->GlacierMove = TRUE;
  else if (strncmp(StrEnv[glacier_movement].VarStr, "FALSE", 5) == 0)
    Options->GlacierMove = FALSE;
  else
    ReportError(StrEnv[glacier_movement].KeyName, 51);
    

  /* determine if Channel Infiltration is allowed */
  if (strncmp(StrEnv[channel_infiltration].VarStr, "TRUE", 4) == 0) 
    Options->ChannelInfiltration = TRUE;
  else if (strncmp(StrEnv[channel_infiltration].VarStr, "FALSE", 5) == 0)
    Options->ChannelInfiltration = FALSE;
  else
    ReportError(StrEnv[channel_infiltration].KeyName, 51);

  /* determine if Fractional Routing is allowed */
  if (strncmp(StrEnv[fractional_routing].VarStr, "TRUE", 4) == 0)
    Options->FractionalRouting = TRUE;
  else if (strncmp(StrEnv[fractional_routing].VarStr, "FALSE", 5) == 0)
    Options->FractionalRouting = FALSE;
  else
    ReportError(StrEnv[fractional_routing].KeyName, 51);


  /* Determine whether the mm5 interface should be used */
  if (strncmp(StrEnv[mm5].VarStr, "TRUE", 4) == 0)
    Options->MM5 = TRUE;
  else if (strncmp(StrEnv[mm5].VarStr, "FALSE", 5) == 0)
    Options->MM5 = FALSE;
  else
    ReportError(StrEnv[mm5].KeyName, 51);

  /* Determine whether the QPF override should be used on the MM5 fields */
  if (strncmp(StrEnv[qpf].VarStr, "TRUE", 4) == 0)
    Options->QPF = TRUE;
  else if (strncmp(StrEnv[qpf].VarStr, "FALSE", 5) == 0)
    Options->QPF = FALSE;
  else
    ReportError(StrEnv[qpf].KeyName, 51);

  /* Determine if PRISM maps will be used to interpolate precip fields */
  if (strncmp(StrEnv[prism].VarStr, "TRUE", 4) == 0)
    Options->Prism = TRUE;
  else if (strncmp(StrEnv[prism].VarStr, "FALSE", 5) == 0)
    Options->Prism = FALSE;
  else
    ReportError(StrEnv[prism].KeyName, 51);

  /* Determine the kinf of canopy radiation attenuation to be used */
  if (strncmp(StrEnv[canopy_radatt].VarStr, "FIXED", 3) == 0)
    Options->CanopyRadAtt = FIXED;
  else if (strncmp(StrEnv[canopy_radatt].VarStr, "VARIABLE", 3) == 0)
    Options->CanopyRadAtt = VARIABLE;
  else
    ReportError(StrEnv[canopy_radatt].KeyName, 51);

  /* Determine if solar shading maps will be used */
  if (strncmp(StrEnv[shading].VarStr, "TRUE", 4) == 0)
    Options->Shading = TRUE;
  else if (strncmp(StrEnv[shading].VarStr, "FALSE", 5) == 0)
    Options->Shading = FALSE;
  else
    ReportError(StrEnv[shading].KeyName, 51);

  if (Options->MM5 == TRUE && Options->Prism == TRUE && Options->QPF == FALSE)
    ReportError(StrEnv[prism].KeyName, 51);

  /* Determine if Snotel test is called for */
  if (strncmp(StrEnv[snotel].VarStr, "TRUE", 4) == 0)
    Options->Snotel = TRUE;
  else if (strncmp(StrEnv[snotel].VarStr, "FALSE", 5) == 0)
    Options->Snotel = FALSE;
  else
    ReportError(StrEnv[snotel].KeyName, 51);

  /* Determine if listed met stations outside bounding box are used */
  if (strncmp(StrEnv[outside].VarStr, "TRUE", 4) == 0)
    Options->Outside = TRUE;
  else if (strncmp(StrEnv[outside].VarStr, "FALSE", 5) == 0)
    Options->Outside = FALSE;
  else
    ReportError(StrEnv[outside].KeyName, 51);

  if (Options->Prism == TRUE) {
    if (IsEmptyStr(StrEnv[prism_data_path].VarStr))
      ReportError(StrEnv[prism_data_path].KeyName, 51);
    strcpy(Options->PrismDataPath, StrEnv[prism_data_path].VarStr);
    if (IsEmptyStr(StrEnv[prism_data_ext].VarStr))
      ReportError(StrEnv[prism_data_ext].KeyName, 51);
    strcpy(Options->PrismDataExt, StrEnv[prism_data_ext].VarStr);
  }

  if (Options->Shading == TRUE) {
    if (IsEmptyStr(StrEnv[shading_data_path].VarStr))
      ReportError(StrEnv[shading_data_path].KeyName, 51);
    strcpy(Options->ShadingDataPath, StrEnv[shading_data_path].VarStr);
    if (IsEmptyStr(StrEnv[shading_data_ext].VarStr))
      ReportError(StrEnv[shading_data_ext].KeyName, 51);
    strcpy(Options->ShadingDataExt, StrEnv[shading_data_ext].VarStr);
    if (IsEmptyStr(StrEnv[skyview_data_path].VarStr))
      ReportError(StrEnv[skyview_data_path].KeyName, 51);
    strcpy(Options->SkyViewDataPath, StrEnv[skyview_data_path].VarStr);
  }

  /* path to inital state files */
    if (IsEmptyStr(StrEnv[initial_state_path].VarStr))
      ReportError(StrEnv[initial_state_path].KeyName, 51);
    strcpy(Options->StartStatePath, StrEnv[initial_state_path].VarStr);


  /* Determine if rh override is used */
  if (strncmp(StrEnv[rhoverride].VarStr, "TRUE", 4) == 0)
    Options->Rhoverride = TRUE;
  else if (strncmp(StrEnv[rhoverride].VarStr, "FALSE", 5) == 0)
    Options->Rhoverride = FALSE;
  else
    ReportError(StrEnv[rhoverride].KeyName, 51);

  /* The other met options are only of importance if MM5 is FALSE */

  if (Options->MM5 == TRUE) {
    Options->PrecipType = NOT_APPLICABLE;
    Options->WindSource = NOT_APPLICABLE;
    Options->PrecipLapse = NOT_APPLICABLE;
    Options->TempLapse = NOT_APPLICABLE;
    if (Options->QPF == TRUE)
      Options->PrecipType = STATION;
    if (Options->QPF == TRUE && Options->Prism == FALSE)
      Options->PrecipLapse = CONSTANT;
  }
  else {
    /* Determine the type of precipitation data that the model will use */
    if (strncmp(StrEnv[precipitation_source].VarStr, "RADAR", 5) == 0)
      Options->PrecipType = RADAR;
    else if (strncmp(StrEnv[precipitation_source].VarStr, "STATION", 7) == 0)
      Options->PrecipType = STATION;
    else
      ReportError(StrEnv[precipitation_source].KeyName, 51);

    /* Determine the type of wind data that the model will use */
    if (strncmp(StrEnv[wind_source].VarStr, "MODEL", 5) == 0)
      Options->WindSource = MODEL;
    else if (strncmp(StrEnv[wind_source].VarStr, "STATION", 7) == 0)
      Options->WindSource = STATION;
    else
      ReportError(StrEnv[wind_source].KeyName, 51);

    /* Determine the type of temperature lapse rate */
    if (strncmp(StrEnv[temp_lapse].VarStr, "CONSTANT", 8) == 0) {
      Options->TempLapse = CONSTANT;
   } else if (strncmp(StrEnv[temp_lapse].VarStr, "VARIABLE", 8) == 0) {
      Options->TempLapse = VARIABLE;
   } else if (strncmp(StrEnv[temp_lapse].VarStr, "MONTHLY", 7) == 0) {
      Options->TempLapse = MONTHLY;
   } else {
      ReportError(StrEnv[temp_lapse].KeyName, 51);
   }
  
    /* Determine the type of precipitation lapse rate */
    if (strncmp(StrEnv[precip_lapse].VarStr, "CONSTANT", 8) == 0)
      Options->PrecipLapse = CONSTANT;
    else if (strncmp(StrEnv[precip_lapse].VarStr, "MAP", 3) == 0)
      Options->PrecipLapse = MAP;
    else if (strncmp(StrEnv[precip_lapse].VarStr, "VARIABLE", 8) == 0)
      Options->PrecipLapse = VARIABLE;
    else if (strncmp(StrEnv[precip_lapse].VarStr, "MONTHLY", 7) == 0) 
      Options->PrecipLapse = MONTHLY;
    else
      ReportError(StrEnv[precip_lapse].KeyName, 51);

  }

  /**************** Determine areal extent ****************/

  if (IsEmptyStr(StrEnv[coordinate_system].VarStr))
    ReportError(StrEnv[coordinate_system].KeyName, 51);
  strcpy(Map->System, StrEnv[coordinate_system].VarStr);

  if (!CopyDouble(&(Map->Yorig), StrEnv[extreme_north].VarStr, 1))
    ReportError(StrEnv[extreme_north].KeyName, 51);

  if (!CopyDouble(&(Map->Xorig), StrEnv[extreme_west].VarStr, 1))
    ReportError(StrEnv[extreme_west].KeyName, 51);

  if (!CopyFloat(&(SolarGeo->Latitude), StrEnv[center_latitude].VarStr, 1))
    ReportError(StrEnv[center_latitude].KeyName, 51);
  SolarGeo->Latitude *= (float) RADPDEG;

  if (!CopyFloat(&(SolarGeo->Longitude), StrEnv[center_longitude].VarStr, 1))
    ReportError(StrEnv[center_longitude].KeyName, 51);
  SolarGeo->Longitude *= (float) RADPDEG;

  if (!CopyFloat(&(SolarGeo->StandardMeridian),
		 StrEnv[time_zone_meridian].VarStr, 1))
    ReportError(StrEnv[time_zone_meridian].KeyName, 51);
  SolarGeo->StandardMeridian *= (float) RADPDEG;

  if (!CopyInt(&(Map->NY), StrEnv[number_of_rows].VarStr, 1))
    ReportError(StrEnv[number_of_rows].KeyName, 51);

  if (!CopyInt(&(Map->NX), StrEnv[number_of_columns].VarStr, 1))
    ReportError(StrEnv[number_of_columns].KeyName, 51);

  if (!CopyFloat(&(Map->DY), StrEnv[grid_spacing].VarStr, 1))
    ReportError(StrEnv[grid_spacing].KeyName, 51);

  Map->DX = Map->DY;
  Map->DXY = (float) sqrt(Map->DX * Map->DX + Map->DY * Map->DY);
  Map->X = 0;
  Map->Y = 0;
  Map->OffsetX = 0;
  Map->OffsetY = 0;

#if NDIRS == 4
  Map->xneighbor[0] = 0;
  Map->yneighbor[0] = -1;    /* N (0 rads) */

  Map->xneighbor[1] = 1;
  Map->yneighbor[1] = 0;     /* E (PI/2 rads)*/

  Map->xneighbor[2] = 0;
  Map->yneighbor[2] = 1;     /* S (PI rads)*/

  Map->xneighbor[3] = -1;
  Map->yneighbor[3] = 0;     /* W (3PI/2 rads or -PI/2 rads)*/
#elif NDIRS == 8
  Map->xneighbor[0] = 0;     /*--------------------------*/
  Map->yneighbor[0] = -1;    /* N */

  Map->xneighbor[1] = 1;
  Map->yneighbor[1] = -1;    /* NE */

  Map->xneighbor[2] = 1;
  Map->yneighbor[2] = 0;     /* E  */

  Map->xneighbor[3] = 1;
  Map->yneighbor[3] = 1;     /* SE */

  Map->xneighbor[4] = 0;
  Map->yneighbor[4] = 1;     /* S */

  Map->xneighbor[5] = -1;
  Map->yneighbor[5] = 1;     /* SW */

  Map->xneighbor[6] = -1;
  Map->yneighbor[6] = 0;     /* W */

  Map->xneighbor[7] = -1;  
  Map->yneighbor[7] = -1;     /* NW */


#endif




  if (Options->Extent == POINT) {

    if (!CopyDouble(&PointModelY, StrEnv[point_north].VarStr, 1))
      ReportError(StrEnv[point_north].KeyName, 51);

    if (!CopyDouble(&PointModelX, StrEnv[point_east].VarStr, 1))
      ReportError(StrEnv[point_east].KeyName, 51);

    Options->PointY =
      Round(((Map->Yorig - 0.5 * Map->DY) - PointModelY) / Map->DY);
    Options->PointX =
      Round((PointModelX - (Map->Xorig + 0.5 * Map->DX)) / Map->DX);
  }
  else {
    Options->PointY = 0;
    Options->PointX = 0;
  }

  /**************** Determine model period ****************/

  if (!CopyFloat(&(TimeStep), StrEnv[time_step].VarStr, 1))
    ReportError(StrEnv[time_step].KeyName, 51);
  TimeStep *= SECPHOUR;

  if (!SScanDate(StrEnv[model_start].VarStr, &(Start)))
    ReportError(StrEnv[model_start].KeyName, 51);

  if (!SScanDate(StrEnv[model_end].VarStr, &(End)))
    ReportError(StrEnv[model_end].KeyName, 51);

  InitTime(Time, &Start, &End, NULL, NULL, (int) TimeStep);

  /**************** Determine model constants ****************/

  if (!CopyFloat(&Z0_GROUND, StrEnv[ground_roughness].VarStr, 1))
    ReportError(StrEnv[ground_roughness].KeyName, 51);

  if (!CopyFloat(&Z0_SNOW, StrEnv[snow_roughness].VarStr, 1))
    ReportError(StrEnv[snow_roughness].KeyName, 51);

  if (!CopyFloat(&MIN_RAIN_TEMP, StrEnv[rain_threshold].VarStr, 1))
    ReportError(StrEnv[rain_threshold].KeyName, 51);

  if (!CopyFloat(&MAX_SNOW_TEMP, StrEnv[snow_threshold].VarStr, 1))
    ReportError(StrEnv[snow_threshold].KeyName, 51);

  if (!CopyFloat(&LIQUID_WATER_CAPACITY, StrEnv[snow_water_capacity].VarStr, 1))
    ReportError(StrEnv[snow_water_capacity].KeyName, 51);

  if (!CopyFloat(&Zref, StrEnv[reference_height].VarStr, 1))
    ReportError(StrEnv[reference_height].KeyName, 51);

  if (!CopyFloat(&LAI_WATER_MULTIPLIER, StrEnv[rain_lai_multiplier].VarStr, 1))
    ReportError(StrEnv[rain_lai_multiplier].KeyName, 51);

  if (!CopyFloat(&LAI_SNOW_MULTIPLIER, StrEnv[snow_lai_multiplier].VarStr, 1))
    ReportError(StrEnv[snow_lai_multiplier].KeyName, 51);

  if (!CopyFloat(&MIN_INTERCEPTION_STORAGE,
		 StrEnv[min_intercepted_snow].VarStr, 1))
    ReportError(StrEnv[min_intercepted_snow].KeyName, 51);

  if (!CopyUChar(&OUTSIDEBASIN, StrEnv[outside_basin].VarStr, 1))
    ReportError(StrEnv[outside_basin].KeyName, 51);

  /*  Glacier model terms MWW-glacier */  
  if(Options->GlacierMove == TRUE ) {
	  if (!CopyFloat(&GLACIER_Q, StrEnv[glacier_creep_q].VarStr, 1))
	    ReportError(StrEnv[glacier_creep_q].KeyName, 51);
	  if (!CopyFloat(&GLACIER_N, StrEnv[glacier_creep_n].VarStr, 1))
	    ReportError(StrEnv[glacier_creep_n].KeyName, 51);
	  if (!CopyFloat(&MAX_GLACIER_FLUX, StrEnv[max_glacier_flux].VarStr, 1))
	    ReportError(StrEnv[max_glacier_flux].KeyName, 51);
  }
    
  if (Options->TempLapse == CONSTANT) {
   if (!CopyFloat(&TEMPLAPSE, StrEnv[temp_lapse_rate].VarStr, 1))
      ReportError(StrEnv[temp_lapse_rate].KeyName, 51);
  }
  else if (Options->TempLapse == MONTHLY) { 
   if (!CopyFloat( Basinwide->TempLapse, StrEnv[temp_lapse_rate].VarStr, 12))
      ReportError(StrEnv[temp_lapse_rate].KeyName, 51);
   }
  else
    TEMPLAPSE = NOT_APPLICABLE;

  if (Options->PrecipLapse == CONSTANT) {
    if (!CopyFloat(&PRECIPLAPSE, StrEnv[precip_lapse_rate].VarStr, 1))
      ReportError(StrEnv[precip_lapse_rate].KeyName, 51);
  }
  else if (Options->PrecipLapse == MONTHLY) { 
   if (!CopyFloat( Basinwide->PrcpLapse, StrEnv[precip_lapse_rate].VarStr, 12))
      ReportError(StrEnv[precip_lapse_rate].KeyName, 51);
   }
  else
    PRECIPLAPSE = NOT_APPLICABLE;

  if (Options->StreamTemp == TRUE) {
    if (!CopyFloat(&DEPTHRATIO, StrEnv[depthratio].VarStr, 1))
      ReportError(StrEnv[depthratio].KeyName, 51);
    if (!CopyFloat(&ST_WIND_FAC, StrEnv[st_wind_fac].VarStr, 1))
      ReportError(StrEnv[st_wind_fac].KeyName, 51);
    if (!CopyFloat(&ST_RAD_FAC, StrEnv[st_rad_fac].VarStr, 1))
      ReportError(StrEnv[st_rad_fac].KeyName, 51);
    if (!CopyInt(&MIN_SEG_ORDER, StrEnv[min_seg_order].VarStr, 1))
      ReportError(StrEnv[min_seg_order].KeyName, 51);
   }
  else {
    DEPTHRATIO = 1.0;
    ST_WIND_FAC = 1.0;
    ST_RAD_FAC = 1.0;
    MIN_SEG_ORDER = NOT_APPLICABLE;
  } 

   /* This section added for Soil Chemistry functions, MWW -sc */
   if (Options->Chemistry == TRUE) {
        if (!CopyFloat(&META_DOC_K_DECOMP, StrEnv[meta_doc_decomp_rate].VarStr, 1))
	    ReportError(StrEnv[meta_doc_decomp_rate].KeyName, 51);
	if (!CopyFloat(&STRUCT_DOC_K_DECOMP, StrEnv[struct_doc_decomp_rate].VarStr, 1))
	    ReportError(StrEnv[struct_doc_decomp_rate].KeyName, 51);
	if (!CopyFloat(&K_DECOMPOSE_DOC, StrEnv[k_decompose_doc].VarStr, 1))
	    ReportError(StrEnv[k_decompose_doc].KeyName, 51);
	if (!CopyFloat(&K1_SORPTION_MAX, StrEnv[k1_sorption_max].VarStr, 1))
	    ReportError(StrEnv[k1_sorption_max].KeyName, 51);
	if (!CopyFloat(&CN_SORB_DOM, StrEnv[cn_sorb_dom].VarStr, 1))
	    ReportError(StrEnv[cn_sorb_dom].KeyName, 51);
	if (!CopyFloat(&CN_MICRODECOMP_DOM, StrEnv[cn_microdecomp_dom].VarStr, 1))
	    ReportError(StrEnv[cn_microdecomp_dom].KeyName, 51);
	if (!CopyFloat(&BG_CATIONS, StrEnv[bg_cations].VarStr, 1))
	    ReportError(StrEnv[bg_cations].KeyName, 51);
	if (!CopyFloat(&NITRI_TEMP_FAC, StrEnv[nitri_temp_fac].VarStr, 1))
	    ReportError(StrEnv[nitri_temp_fac].KeyName, 51);
	
	if (!CopyFloat(&FREEAIRDCO2, StrEnv[freeair_co2].VarStr, 1))
	    ReportError(StrEnv[freeair_co2].KeyName, 51);    
	if (!CopyFloat(&FREEAIROXY, StrEnv[freeair_co2].VarStr, 1))
	    ReportError(StrEnv[freeair_oxy].KeyName, 51);    
        if (!CopyFloat(&CO2KGASTRANS, StrEnv[co2_kgas].VarStr, 1))
	    ReportError(StrEnv[co2_kgas].KeyName, 51);
	if (!CopyFloat(&O2KGASTRANS, StrEnv[o2_kgas].VarStr, 1))
	    ReportError(StrEnv[o2_kgas].KeyName, 51);
	if (!CopyFloat(&POTENTIALDENITRIF, StrEnv[pot_denitrif].VarStr, 1))
	    ReportError(StrEnv[pot_denitrif].KeyName, 51);
	if (!CopyFloat(&DENITRIF_HALFSAT, StrEnv[denitrif_halfsat].VarStr, 1))
	    ReportError(StrEnv[denitrif_halfsat].KeyName, 51);
	
	if (!CopyFloat(&KOXY_NITRIF, StrEnv[koxy_nitrif].VarStr, 1))
	    ReportError(StrEnv[koxy_nitrif].KeyName, 51);
	if (!CopyFloat(&KMINER_CHAN, StrEnv[kminer_chan].VarStr, 1))
	    ReportError(StrEnv[kminer_chan].KeyName, 51);
    	if (!CopyFloat(&KHYDRO_CHAN, StrEnv[khydro_chan].VarStr, 1))
	    ReportError(StrEnv[khydro_chan].KeyName, 51);
	if (!CopyFloat(&KNITRIF1_CHAN, StrEnv[knitrif1_chan].VarStr, 1))
	    ReportError(StrEnv[knitrif1_chan].KeyName, 51);
	if (!CopyFloat(&KNITRIF2_CHAN, StrEnv[knitrif2_chan].VarStr, 1))
	    ReportError(StrEnv[knitrif2_chan].KeyName, 51);

	if (!CopyFloat( Basinwide->atmos_CO2_conc, StrEnv[atmos_co2_conc].VarStr, 12))
            ReportError(StrEnv[atmos_co2_conc].KeyName, 51);
   	if (!CopyFloat( Basinwide->atmos_DOC_conc, StrEnv[atmos_doc_conc].VarStr, 12))
            ReportError(StrEnv[atmos_doc_conc].KeyName, 51);
	if (!CopyFloat( Basinwide->atmos_DON_conc, StrEnv[atmos_don_conc].VarStr, 12))
            ReportError(StrEnv[atmos_don_conc].KeyName, 51);
	if (!CopyFloat( Basinwide->atmos_NH4_conc, StrEnv[atmos_nh4_conc].VarStr, 12))
            ReportError(StrEnv[atmos_nh4_conc].KeyName, 51);
	if (!CopyFloat( Basinwide->atmos_NO3_conc, StrEnv[atmos_no3_conc].VarStr, 12))
            ReportError(StrEnv[atmos_no3_conc].KeyName, 51);
	if (!CopyFloat( Basinwide->atmos_NO2_conc, StrEnv[atmos_no2_conc].VarStr, 12))
            ReportError(StrEnv[atmos_no2_conc].KeyName, 51);

	
   } else {
     META_DOC_K_DECOMP = 0.0;
     STRUCT_DOC_K_DECOMP = 0.0;
     K_DECOMPOSE_DOC = 0.0;
     K1_SORPTION_MAX = 0.0;
     CN_SORB_DOM = 0.0;
     CN_MICRODECOMP_DOM = 0.0;
     FREEAIRDCO2 = 0.0;
     CO2KGASTRANS = 0.0;
     O2KGASTRANS = 0.0;
     POTENTIALDENITRIF = 0.0;
     DENITRIF_HALFSAT = 0.0;
     BG_CATIONS = 0.0;
     KOXY_NITRIF = 0.0; 
     KMINER_CHAN = 0.0; 
     KNITRIF1_CHAN = 0.0; 
     KNITRIF2_CHAN = 0.0; 
     for ( j=0;j<12;j++) {
        Basinwide->atmos_CO2_conc[j] = 0.0;
        Basinwide->atmos_DOC_conc[j] = 0.0;
        Basinwide->atmos_DON_conc[j] = 0.0;
        Basinwide->atmos_NH4_conc[j] = 0.0;
        Basinwide->atmos_NO3_conc[j] = 0.0;
        //Basinwide->atmos_NO3_conc[j] = 0.0;
     }
   }
   

}
/*****************************************************************************
  Function name: InitConstants()

  Purpose      : Initialize constants and settings for DHSVM run
                 Processes the following sections in InFile:
                 [OPTIONS]
                 [AREA]
                 [TIME]
                 [CONSTANTS}

  Required     :
    LISTPTR Input          - Linked list with input strings
    OPTIONSTRUCT *Options   - Structure with different program options
    MAPSIZE *Map            - Coverage and resolution of model area
    SOLARGEOMETRY *SolarGeo - Solar geometry information
    TIMESTRUCT *Time        - Begin and end times, model timestep

  Returns      : void

  Modifies     : (see list of required above)

  Comments     :
*****************************************************************************/
void InitConstants(LISTPTR Input, OPTIONSTRUCT * Options, MAPSIZE * Map,
		   SOLARGEOMETRY * SolarGeo, TIMESTRUCT * Time)
{
  int i;			/* counter */
  double PointModelX;		/* X-coordinate for POINT model mode */
  double PointModelY;		/* Y-coordinate for POINT model mode */
  float TimeStep;		/* Timestep in hours */
  DATE End;			/* End of run */
  DATE Start;			/* Start of run */

  STRINIENTRY StrEnv[] = {
    {"OPTIONS", "FORMAT", "", ""},
    {"OPTIONS", "EXTENT", "", ""},
    {"OPTIONS", "GRADIENT", "", ""},
    {"OPTIONS", "FLOW ROUTING", "", ""},
    {"OPTIONS", "SENSIBLE HEAT FLUX", "", ""},
    {"OPTIONS", "SEDIMENT", "", ""},
    {"OPTIONS", "SEDIMENT INPUT FILE", "", ""},
    {"OPTIONS", "OVERLAND ROUTING", "", ""}, 
    {"OPTIONS", "INFILTRATION", "", ""},
    {"OPTIONS", "INTERPOLATION", "", ""},
    {"OPTIONS", "MM5", "", ""},
    {"OPTIONS", "QPF", "", ""},
    {"OPTIONS", "PRISM", "", ""},
    {"OPTIONS", "CANOPY RADIATION ATTENUATION MODE", "", ""},
    {"OPTIONS", "SHADING", "", ""},
    {"OPTIONS", "SNOTEL", "", ""},
    {"OPTIONS", "OUTSIDE", "", ""},
    {"OPTIONS", "RHOVERRIDE", "", ""},
    {"OPTIONS", "PRECIPITATION SOURCE", "", ""},
    {"OPTIONS", "WIND SOURCE", "", ""},
    {"OPTIONS", "TEMPERATURE LAPSE RATE", "", ""},
    {"OPTIONS", "PRECIPITATION LAPSE RATE", "", ""},
    {"OPTIONS", "CRESSMAN RADIUS", "", ""},
    {"OPTIONS", "CRESSMAN STATIONS", "", ""},
    {"OPTIONS", "PRISM DATA PATH", "", ""},
    {"OPTIONS", "PRISM DATA EXTENSION", "", ""},
    {"OPTIONS", "SHADING DATA PATH", "", ""},
    {"OPTIONS", "SHADING DATA EXTENSION", "", ""},
    {"OPTIONS", "SKYVIEW DATA PATH", "", ""},
	{"OPTIONS", "STREAM TEMPERATURE", "", ""}, 
	{"OPTIONS", "CANOPY SHADING", "", ""}, 
    {"AREA", "COORDINATE SYSTEM", "", ""},
    {"AREA", "EXTREME NORTH", "", ""},
    {"AREA", "EXTREME WEST", "", ""},
    {"AREA", "CENTER LATITUDE", "", ""},
    {"AREA", "CENTER LONGITUDE", "", ""},
    {"AREA", "TIME ZONE MERIDIAN", "", ""},
    {"AREA", "NUMBER OF ROWS", "", ""},
    {"AREA", "NUMBER OF COLUMNS", "", ""},
    {"AREA", "GRID SPACING", "", ""},
    {"AREA", "POINT NORTH", "", ""},
    {"AREA", "POINT EAST", "", ""},
    {"TIME", "TIME STEP", "", ""},
    {"TIME", "MODEL START", "", ""},
    {"TIME", "MODEL END", "", ""},
    {"CONSTANTS", "GROUND ROUGHNESS", "", ""},
    {"CONSTANTS", "SNOW ROUGHNESS", "", ""},
    {"CONSTANTS", "RAIN THRESHOLD", "", ""},
    {"CONSTANTS", "SNOW THRESHOLD", "", ""},
    {"CONSTANTS", "SNOW WATER CAPACITY", "", ""},
    {"CONSTANTS", "REFERENCE HEIGHT", "", ""},
    {"CONSTANTS", "RAIN LAI MULTIPLIER", "", ""},
    {"CONSTANTS", "SNOW LAI MULTIPLIER", "", ""},
    {"CONSTANTS", "MIN INTERCEPTED SNOW", "", ""},
    {"CONSTANTS", "OUTSIDE BASIN VALUE", "", ""},
    {"CONSTANTS", "TEMPERATURE LAPSE RATE", "", ""},
    {"CONSTANTS", "PRECIPITATION LAPSE RATE", "", ""},
    {"CONSTANTS", "PRECIPITATION MULTIPLIER", "", ""},
    {NULL, NULL, "", NULL}
  };

  /* Read the key-entry pairs from the input file */
  for (i = 0; StrEnv[i].SectionName; i++)
    GetInitString(StrEnv[i].SectionName, StrEnv[i].KeyName, StrEnv[i].Default,
		  StrEnv[i].VarStr, (unsigned long) BUFSIZE, Input);

  /**************** Determine model options ****************/

  /* Determine file format to be used */
  if (strncmp(StrEnv[format].VarStr, "BIN", 3) == 0)
    Options->FileFormat = BIN;
  else if (strncmp(StrEnv[format].VarStr, "NETCDF", 3) == 0)
    Options->FileFormat = NETCDF;
  else if (strncmp(StrEnv[format].VarStr, "BYTESWAP", 3) == 0)
    Options->FileFormat = BYTESWAP;
  else
    ReportError(StrEnv[format].KeyName, 51);

  /* Determine whether the model should be run in POINT mode or in BASIN mode.
     If in POINT mode also read which pixel to model */
  if (strncmp(StrEnv[extent].VarStr, "POINT", 5) == 0) {
    Options->Extent = POINT;
    Options->HasNetwork = FALSE;
  }
  else if (strncmp(StrEnv[extent].VarStr, "BASIN", 5) == 0) {
    Options->Extent = BASIN;
  }
  else
    ReportError(StrEnv[extent].KeyName, 51);

  /* Determine how the flow gradient should be calculated */
  if (Options->Extent != POINT) {
    if (strncmp(StrEnv[gradient].VarStr, "TOPO", 4) == 0)
      Options->FlowGradient = TOPOGRAPHY;
    else if (strncmp(StrEnv[gradient].VarStr, "WATER", 5) == 0)
      Options->FlowGradient = WATERTABLE;
    else
      ReportError(StrEnv[gradient].KeyName, 51);
  }
  else
    Options->FlowGradient = NOT_APPLICABLE;

  /* Determine what meterological interpolation to use */

  if (strncmp(StrEnv[interpolation].VarStr, "INVDIST", 7) == 0)
    Options->Interpolation = INVDIST;
  else if (strncmp(StrEnv[interpolation].VarStr, "NEAREST", 7) == 0)
    Options->Interpolation = NEAREST;
  else if (strncmp(StrEnv[interpolation].VarStr, "VARCRESS", 8) == 0)
    Options->Interpolation = VARCRESS;
  else
    ReportError(StrEnv[interpolation].KeyName, 51);

  /* if VARIABLE CRESTMAN interpolation then get parameters */
  if (Options->Interpolation == VARCRESS) {
    if (!CopyInt(&(Options->CressRadius), StrEnv[cressman_radius].VarStr, 1))
      ReportError(StrEnv[cressman_radius].KeyName, 51);
    if (!CopyInt
	(&(Options->CressStations), StrEnv[cressman_stations].VarStr, 1))
      ReportError(StrEnv[cressman_stations].KeyName, 51);
  }

  /* Determine whether a road/network is imposed on the model area */
  if (Options->Extent != POINT) {
    if (strncmp(StrEnv[flow_routing].VarStr, "NETWORK", 7) == 0)
      Options->HasNetwork = TRUE;
    else if (strncmp(StrEnv[flow_routing].VarStr, "UNIT", 4) == 0)
      Options->HasNetwork = FALSE;
    else
      ReportError(StrEnv[flow_routing].KeyName, 51);
  }
  else
    Options->HasNetwork = FALSE;

  /* Determine whether a sensible heat flux should be calculated */
  if (strncmp(StrEnv[sensible_heat_flux].VarStr, "TRUE", 4) == 0)
    Options->HeatFlux = TRUE;
  else if (strncmp(StrEnv[sensible_heat_flux].VarStr, "FALSE", 5) == 0)
    Options->HeatFlux = FALSE;
  else
    ReportError(StrEnv[sensible_heat_flux].KeyName, 51);

  /* Determine whether sediment model should be run */
  if (strncmp(StrEnv[sediment].VarStr, "TRUE", 4) == 0)
    Options->Sediment = TRUE;
  else if (strncmp(StrEnv[sediment].VarStr, "FALSE", 5) == 0){
    printf("WARNING: Sediment option has not been chosen. All erosion\n");
    printf("options are being turned off.\n\n");
    Options->Sediment = FALSE;
    Options->MassWaste = FALSE;
    Options->SurfaceErosion = FALSE;
    Options->ErosionPeriod = FALSE;
  }
  else
    ReportError(StrEnv[sediment].KeyName, 51);

  if(Options->Sediment == TRUE) {
    if (IsEmptyStr(StrEnv[sed_input_file].VarStr))
      ReportError(StrEnv[sed_input_file].KeyName, 51);
    strcpy(Options->SedFile, StrEnv[sed_input_file].VarStr);
  }
  
  /* Determine overland flow routing method to use */
  if (strncmp(StrEnv[routing].VarStr, "KINEMATIC", 9) == 0)
    Options->Routing = TRUE;
  else if (strncmp(StrEnv[routing].VarStr, "CONVENTIONAL", 12) == 0)
    Options->Routing = FALSE;
  else
    ReportError(StrEnv[routing].KeyName, 51);
  
 
  /* Determine if the maximum infiltration rate is static or dynamic */
  if (strncmp(StrEnv[infiltration].VarStr, "STATIC", 6) == 0) {
    Options->Infiltration = STATIC;
  }
  else if (strncmp(StrEnv[infiltration].VarStr, "DYNAMIC", 7) == 0) {
    Options->Infiltration = DYNAMIC ;
    printf("WARNING: Dynamic maximum infiltration capacity has\n");
    printf("not been fully tested. It is a work in progress.\n\n");
  }
  else
    ReportError(StrEnv[infiltration].KeyName, 51);
    
  /* Determine whether the mm5 interface should be used */
  if (strncmp(StrEnv[mm5].VarStr, "TRUE", 4) == 0)
    Options->MM5 = TRUE;
  else if (strncmp(StrEnv[mm5].VarStr, "FALSE", 5) == 0)
    Options->MM5 = FALSE;
  else
    ReportError(StrEnv[mm5].KeyName, 51);

  /* Determine whether the QPF override should be used on the MM5 fields */
  if (strncmp(StrEnv[qpf].VarStr, "TRUE", 4) == 0)
    Options->QPF = TRUE;
  else if (strncmp(StrEnv[qpf].VarStr, "FALSE", 5) == 0)
    Options->QPF = FALSE;
  else
    ReportError(StrEnv[qpf].KeyName, 51);

  /* Determine if PRISM maps will be used to interpolate precip fields */
  if (strncmp(StrEnv[prism].VarStr, "TRUE", 4) == 0)
    Options->Prism = TRUE;
  else if (strncmp(StrEnv[prism].VarStr, "FALSE", 5) == 0)
    Options->Prism = FALSE;
  else
    ReportError(StrEnv[prism].KeyName, 51);

  /* Determine the kind of canopy radiation attenuation to be used */
  if (strncmp(StrEnv[canopy_radatt].VarStr, "FIXED", 3) == 0)
    Options->CanopyRadAtt = FIXED;
  else if (strncmp(StrEnv[canopy_radatt].VarStr, "VARIABLE", 3) == 0)
    Options->CanopyRadAtt = VARIABLE;
  else
    ReportError(StrEnv[canopy_radatt].KeyName, 51);

  /* Determine if solar shading maps will be used */
  if (strncmp(StrEnv[shading].VarStr, "TRUE", 4) == 0)
    Options->Shading = TRUE;
  else if (strncmp(StrEnv[shading].VarStr, "FALSE", 5) == 0)
    Options->Shading = FALSE;
  else
    ReportError(StrEnv[shading].KeyName, 51);

  if (Options->MM5 == TRUE && Options->Prism == TRUE && Options->QPF == FALSE)
    ReportError(StrEnv[prism].KeyName, 51);

  /* Determine if Snotel test is called for */
  if (strncmp(StrEnv[snotel].VarStr, "TRUE", 4) == 0)
    Options->Snotel = TRUE;
  else if (strncmp(StrEnv[snotel].VarStr, "FALSE", 5) == 0)
    Options->Snotel = FALSE;
  else
    ReportError(StrEnv[snotel].KeyName, 51);

  /* Determine if STREAM TEMP is called for */
  if (strncmp(StrEnv[stream_temp].VarStr, "TRUE", 4) == 0)
    Options->StreamTemp = TRUE;
  else if (strncmp(StrEnv[stream_temp].VarStr, "FALSE", 5) == 0)
    Options->StreamTemp = FALSE;
  else
    ReportError(StrEnv[stream_temp].KeyName, 51);

  /* Determine if CANOPY SHADING is called for */
  if (strncmp(StrEnv[canopy_shading].VarStr, "TRUE", 4) == 0) {
	Options->CanopyShading = TRUE;
	if (Options->StreamTemp == FALSE) {
	  printf("Stream temp module must be turned on to allow canopy shading options\n");
	  exit(-1);
	}
  }
  else if (strncmp(StrEnv[canopy_shading].VarStr, "FALSE", 5) == 0)
	Options->CanopyShading = FALSE;
  else
    ReportError(StrEnv[canopy_shading].KeyName, 51);

  /* Determine if listed met stations outside bounding box are used */
  if (strncmp(StrEnv[outside].VarStr, "TRUE", 4) == 0)
    Options->Outside = TRUE;
  else if (strncmp(StrEnv[outside].VarStr, "FALSE", 5) == 0)
    Options->Outside = FALSE;
  else
    ReportError(StrEnv[outside].KeyName, 51);

  if (Options->Prism == TRUE) {
    if (IsEmptyStr(StrEnv[prism_data_path].VarStr))
      ReportError(StrEnv[prism_data_path].KeyName, 51);
    strcpy(Options->PrismDataPath, StrEnv[prism_data_path].VarStr);
    if (IsEmptyStr(StrEnv[prism_data_ext].VarStr))
      ReportError(StrEnv[prism_data_ext].KeyName, 51);
    strcpy(Options->PrismDataExt, StrEnv[prism_data_ext].VarStr);
  }

  if (Options->Shading == TRUE) {
    if (IsEmptyStr(StrEnv[shading_data_path].VarStr))
      ReportError(StrEnv[shading_data_path].KeyName, 51);
    strcpy(Options->ShadingDataPath, StrEnv[shading_data_path].VarStr);
    if (IsEmptyStr(StrEnv[shading_data_ext].VarStr))
      ReportError(StrEnv[shading_data_ext].KeyName, 51);
    strcpy(Options->ShadingDataExt, StrEnv[shading_data_ext].VarStr);
    if (IsEmptyStr(StrEnv[skyview_data_path].VarStr))
      ReportError(StrEnv[skyview_data_path].KeyName, 51);
    strcpy(Options->SkyViewDataPath, StrEnv[skyview_data_path].VarStr);
  }

  /* Determine if rh override is used */
  if (strncmp(StrEnv[rhoverride].VarStr, "TRUE", 4) == 0)
    Options->Rhoverride = TRUE;
  else if (strncmp(StrEnv[rhoverride].VarStr, "FALSE", 5) == 0)
    Options->Rhoverride = FALSE;
  else
    ReportError(StrEnv[rhoverride].KeyName, 51);

  /* The other met options are only of importance if MM5 is FALSE */

  if (Options->MM5 == TRUE) {
    Options->PrecipType = NOT_APPLICABLE;
    Options->WindSource = NOT_APPLICABLE;
    Options->PrecipLapse = NOT_APPLICABLE;
    Options->TempLapse = NOT_APPLICABLE;
    if (Options->QPF == TRUE)
      Options->PrecipType = STATION;
    if (Options->QPF == TRUE && Options->Prism == FALSE)
      Options->PrecipLapse = CONSTANT;
  }
  else {
    /* Determine the type of precipitation data that the model will use */
    if (strncmp(StrEnv[precipitation_source].VarStr, "RADAR", 5) == 0)
      Options->PrecipType = RADAR;
    else if (strncmp(StrEnv[precipitation_source].VarStr, "STATION", 7) == 0)
      Options->PrecipType = STATION;
    else
      ReportError(StrEnv[precipitation_source].KeyName, 51);

    /* Determine the type of wind data that the model will use */
    if (strncmp(StrEnv[wind_source].VarStr, "MODEL", 5) == 0)
      Options->WindSource = MODEL;
    else if (strncmp(StrEnv[wind_source].VarStr, "STATION", 7) == 0)
      Options->WindSource = STATION;
    else
      ReportError(StrEnv[wind_source].KeyName, 51);

    /* Determine the type of temperature lapse rate */
    if (strncmp(StrEnv[temp_lapse].VarStr, "CONSTANT", 8) == 0)
      Options->TempLapse = CONSTANT;
    else if (strncmp(StrEnv[temp_lapse].VarStr, "VARIABLE", 8) == 0)
      Options->TempLapse = VARIABLE;
    else
      ReportError(StrEnv[temp_lapse].KeyName, 51);

    /* Determine the type of precipitation lapse rate */
    if (strncmp(StrEnv[precip_lapse].VarStr, "CONSTANT", 8) == 0)
      Options->PrecipLapse = CONSTANT;
    else if (strncmp(StrEnv[precip_lapse].VarStr, "MAP", 3) == 0)
      Options->PrecipLapse = MAP;
    else if (strncmp(StrEnv[precip_lapse].VarStr, "VARIABLE", 8) == 0)
      Options->PrecipLapse = VARIABLE;
    else
      ReportError(StrEnv[precip_lapse].KeyName, 51);
  }

  /**************** Determine areal extent ****************/

  if (IsEmptyStr(StrEnv[coordinate_system].VarStr))
    ReportError(StrEnv[coordinate_system].KeyName, 51);
  strcpy(Map->System, StrEnv[coordinate_system].VarStr);

  if (!CopyDouble(&(Map->Yorig), StrEnv[extreme_north].VarStr, 1))
    ReportError(StrEnv[extreme_north].KeyName, 51);

  if (!CopyDouble(&(Map->Xorig), StrEnv[extreme_west].VarStr, 1))
    ReportError(StrEnv[extreme_west].KeyName, 51);

  if (!CopyFloat(&(SolarGeo->Latitude), StrEnv[center_latitude].VarStr, 1))
    ReportError(StrEnv[center_latitude].KeyName, 51);
  SolarGeo->Latitude *= (float) RADPDEG;

  if (!CopyFloat(&(SolarGeo->Longitude), StrEnv[center_longitude].VarStr, 1))
    ReportError(StrEnv[center_longitude].KeyName, 51);
  SolarGeo->Longitude *= (float) RADPDEG;

  if (!CopyFloat(&(SolarGeo->StandardMeridian),
		 StrEnv[time_zone_meridian].VarStr, 1))
    ReportError(StrEnv[time_zone_meridian].KeyName, 51);
  SolarGeo->StandardMeridian *= (float) RADPDEG;

  if (!CopyInt(&(Map->NY), StrEnv[number_of_rows].VarStr, 1))
    ReportError(StrEnv[number_of_rows].KeyName, 51);

  if (!CopyInt(&(Map->NX), StrEnv[number_of_columns].VarStr, 1))
    ReportError(StrEnv[number_of_columns].KeyName, 51);

  if (!CopyFloat(&(Map->DY), StrEnv[grid_spacing].VarStr, 1))
    ReportError(StrEnv[grid_spacing].KeyName, 51);

  Map->DX = Map->DY;
  Map->DXY = (float) sqrt(Map->DX * Map->DX + Map->DY * Map->DY);
  Map->X = 0;
  Map->Y = 0;
  Map->OffsetX = 0;
  Map->OffsetY = 0;
  Map->NumCells = 0;

  if (Options->Extent == POINT) {

    if (!CopyDouble(&PointModelY, StrEnv[point_north].VarStr, 1))
      ReportError(StrEnv[point_north].KeyName, 51);

    if (!CopyDouble(&PointModelX, StrEnv[point_east].VarStr, 1))
      ReportError(StrEnv[point_east].KeyName, 51);

    Options->PointY =
      Round(((Map->Yorig - 0.5 * Map->DY) - PointModelY) / Map->DY);
    Options->PointX =
      Round((PointModelX - (Map->Xorig + 0.5 * Map->DX)) / Map->DX);
  }
  else {
    Options->PointY = 0;
    Options->PointX = 0;
  }

  /**************** Determine model period ****************/

  if (!CopyFloat(&(TimeStep), StrEnv[time_step].VarStr, 1))
    ReportError(StrEnv[time_step].KeyName, 51);
  TimeStep *= SECPHOUR;

  if (!SScanDate(StrEnv[model_start].VarStr, &(Start)))
    ReportError(StrEnv[model_start].KeyName, 51);

  if (!SScanDate(StrEnv[model_end].VarStr, &(End)))
    ReportError(StrEnv[model_end].KeyName, 51);

  InitTime(Time, &Start, &End, NULL, NULL, (int) TimeStep);

   /**************** Determine model constants ****************/

  if (!CopyFloat(&Z0_GROUND, StrEnv[ground_roughness].VarStr, 1))
    ReportError(StrEnv[ground_roughness].KeyName, 51);

  if (!CopyFloat(&Z0_SNOW, StrEnv[snow_roughness].VarStr, 1))
    ReportError(StrEnv[snow_roughness].KeyName, 51);

  if (!CopyFloat(&MIN_RAIN_TEMP, StrEnv[rain_threshold].VarStr, 1))
    ReportError(StrEnv[rain_threshold].KeyName, 51);

  if (!CopyFloat(&MAX_SNOW_TEMP, StrEnv[snow_threshold].VarStr, 1))
    ReportError(StrEnv[snow_threshold].KeyName, 51);

  if (!CopyFloat(&LIQUID_WATER_CAPACITY, StrEnv[snow_water_capacity].VarStr, 1))
    ReportError(StrEnv[snow_water_capacity].KeyName, 51);

  if (!CopyFloat(&Zref, StrEnv[reference_height].VarStr, 1))
    ReportError(StrEnv[reference_height].KeyName, 51);

  if (!CopyFloat(&LAI_WATER_MULTIPLIER, StrEnv[rain_lai_multiplier].VarStr, 1))
    ReportError(StrEnv[rain_lai_multiplier].KeyName, 51);

  if (!CopyFloat(&LAI_SNOW_MULTIPLIER, StrEnv[snow_lai_multiplier].VarStr, 1))
    ReportError(StrEnv[snow_lai_multiplier].KeyName, 51);

  if (!CopyFloat(&MIN_INTERCEPTION_STORAGE,
		 StrEnv[min_intercepted_snow].VarStr, 1))
    ReportError(StrEnv[min_intercepted_snow].KeyName, 51);

  if (!CopyUChar(&OUTSIDEBASIN, StrEnv[outside_basin].VarStr, 1))
    ReportError(StrEnv[outside_basin].KeyName, 51);

  if (Options->TempLapse == CONSTANT) {
    if (!CopyFloat(&TEMPLAPSE, StrEnv[temp_lapse_rate].VarStr, 1))
      ReportError(StrEnv[temp_lapse_rate].KeyName, 51);
  }
  else
    TEMPLAPSE = NOT_APPLICABLE;

  if (Options->PrecipLapse == CONSTANT) {
    if (!CopyFloat(&PRECIPLAPSE, StrEnv[precip_lapse_rate].VarStr, 1))
      ReportError(StrEnv[precip_lapse_rate].KeyName, 51);
  }
  else
    PRECIPLAPSE = NOT_APPLICABLE;

  if (!CopyFloat(&PRECIPMULTIPLIER, StrEnv[precip_multiplier].VarStr, 1))
      ReportError(StrEnv[precip_multiplier].KeyName, 51);
}