// no longer used private static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List <string> timeStamps, out List <ClimateRecord>[] climateRecords) { // each item in timeStamps is the timeStamp 'key' for the data // each item in climateRecords is of length Climate.ModelCore.Ecoregions.Count, and is filled in with data from the input file, indexed by Ecoregion.Index. timeStamps = new List <string>(); climateRecords = new List <ClimateRecord> [Climate.ModelCore.Ecoregions.Count]; for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) { climateRecords[i] = new List <ClimateRecord>(); } // get trigger words for parsing based on file format ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat); if (!File.Exists(climateFile)) { throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile); } var reader = File.OpenText(climateFile); Climate.TextLog.WriteLine(" Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity); // maps from ecoregion column index in the input file to the ecoregion.index for the region int[] ecoRegionIndexMap = null; var ecoRegionCount = 0; var rowIndex = -1; var sectionIndex = -1; FileSection section = 0; string row; while ((row = reader.ReadLine()) != null) { var fields = row.Replace(" ", "").Split(',').ToList(); // JM: don't know if stripping blanks is needed, but just in case // check for trigger word if (fields[0].StartsWith("#")) { // determine which section we're in var triggerWord = fields[0].TrimStart('#'); // remove the leading "#" if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Precipitation; } else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MaxTemperature; } else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MinTemperature; } else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.NDeposition; } else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Winddirection; } else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Windspeed; } else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.CO2; } else { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile)); } sectionIndex++; // if this is the first section then parse the ecoregions, etc. if (sectionIndex == 0) { // read next line to get ecoregion headers var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList(); ecoRegionHeaders.RemoveAt(0); // remove blank cell at the beginning of ecoregion header row // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev ecoRegionCount = ecoRegionHeaders.Count / 3; if (ecoRegionCount == 0) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile)); } var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active); if (ecoRegionCount != modelCoreActiveEcoRegionCount) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount)); } // determine the map from ecoregions in this file to ecoregion indices in ModelCore ecoRegionIndexMap = new int[ecoRegionCount]; for (var i = 0; i < ecoRegionCount; ++i) { IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]]; // JM: Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive. if (eco != null && eco.Active) { ecoRegionIndexMap[i] = eco.Index; } else { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile)); } } } else { // skip ecoregion header line reader.ReadLine(); } // skip data headers reader.ReadLine(); // get next line as first line of data fields = reader.ReadLine().Replace(" ", "").Split(',').ToList(); // reset row index rowIndex = -1; } // ** // process line of data ++rowIndex; // grab the key as the first field and remove it from the data var key = fields[0]; fields.RemoveAt(0); // if this is the first section then add key to timestamps and add new climate records for this rowIndex to the ecoregion array if (sectionIndex == 0) { timeStamps.Add(key); for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) { climateRecords[i].Add(new ClimateRecord()); } } else { // check that the timestamp key order matches if (key != timeStamps[rowIndex]) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}' timestamp '{1}' in climate file '{2}'.", section, key, climateFile)); } } for (var i = 0; i < ecoRegionCount; ++i) { var ecoIndex = ecoRegionIndexMap[i]; var ecoRecords = climateRecords[ecoIndex]; // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev var mean = double.Parse(fields[i]); var variance = double.Parse(fields[ecoRegionCount + i]); var stdev = double.Parse(fields[2 * ecoRegionCount + i]); switch (section) { case FileSection.Precipitation: ecoRecords[rowIndex].AvgPpt = mean * format.PrecipTransformation; ecoRecords[rowIndex].StdDevPpt = stdev * format.PrecipTransformation; break; case FileSection.MaxTemperature: case FileSection.MinTemperature: mean += format.TemperatureTransformation; if (section == FileSection.MaxTemperature) { ecoRecords[rowIndex].AvgMaxTemp = mean; } else { ecoRecords[rowIndex].AvgMinTemp = mean; } // for temperature variance wait until both min and max have been read before calculating the final value if (ecoRecords[rowIndex].AvgVarTemp == -99.0) { ecoRecords[rowIndex].AvgVarTemp = variance; // set AvgVarTemp to the first value we have (min or max) } else { // have both min and max, so average the variance ecoRecords[rowIndex].AvgVarTemp = (ecoRecords[rowIndex].AvgVarTemp + variance) / 2.0; } ecoRecords[rowIndex].StdDevTemp = System.Math.Sqrt(ecoRecords[rowIndex].AvgVarTemp); // this will set the st dev even if the data file only has one temperature section break; case FileSection.Winddirection: mean += format.WindDirectionTransformation; if (mean > 360.0) { mean -= 360; } ecoRecords[rowIndex].AvgWindDirection = mean; ecoRecords[rowIndex].AvgVarWindDirection = variance; ecoRecords[rowIndex].StdDevWindDirection = stdev; break; case FileSection.Windspeed: ecoRecords[rowIndex].AvgWindSpeed = mean * format.WindSpeedTransformation; ecoRecords[rowIndex].AvgVarWindSpeed = variance; ecoRecords[rowIndex].StdDevWindSpeed = stdev; break; case FileSection.NDeposition: ecoRecords[rowIndex].AvgNDeposition = mean; ecoRecords[rowIndex].AvgVarNDeposition = variance; ecoRecords[rowIndex].StdDevNDeposition = stdev; break; case FileSection.CO2: ecoRecords[rowIndex].AvgCO2 = mean; ecoRecords[rowIndex].AvgVarCO2 = variance; ecoRecords[rowIndex].StdDevCO2 = stdev; break; } } } }
private static void Convert_USGS_to_ClimateData2(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List <int> yearKeys, out List <List <ClimateRecord>[]> climateRecords) { var precipYearKeys = new List <int>(); var windYearKeys = new List <int>(); // indexing of precip and wind ClimateRecords: [yearIndex][ecoregion][i], where yearIndex is [0..n] corresponding to the yearKeys index, i.e. index 0 is for 1950, index 1 for 1951, etc. var precipClimateRecords = new List <List <ClimateRecord>[]>(); var windClimateRecords = new List <List <ClimateRecord>[]>(); // get trigger words for parsing based on file format ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat); if (!File.Exists(climateFile)) { throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile); } var reader = File.OpenText(climateFile); Climate.TextLog.WriteLine(" Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity); // maps from ecoregion column index in the input file to the ecoregion.index for the region int[] ecoRegionIndexMap = null; var ecoRegionCount = 0; var numberOfGroups = 2; // the number of allowed groups. Presently: (1) precip, tmin, tmax, Ndep, CO2; (2) winddirection & windspeed var groupSectionCounts = new int[numberOfGroups]; // used to know if I'm beyond the first section in a group var groupTimeSteps = new List <string> [numberOfGroups]; // keeps track of timesteps within each group to ensure they match for (var i = 0; i < numberOfGroups; ++i) { groupTimeSteps[i] = new List <string>(); } var sectionYearRowIndex = -1; var sectionYear = -1; var sectionYearIndex = -1; var sectionRowIndex = -1; FileSection section = 0; var groupIndex = -1; List <ClimateRecord>[] yearEcoRecords = null; // could be either precip or wind data, depending on the section group. string row; while (!string.IsNullOrEmpty(row = reader.ReadLine())) { var fields = row.Replace(" ", "").Split(',').ToList(); // JM: don't know if stripping blanks is needed, but just in case // skip blank rows if (fields.All(x => string.IsNullOrEmpty(x))) { continue; } // check for trigger word if (fields[0].StartsWith("#")) { // determine which section we're in var triggerWord = fields[0].TrimStart('#'); // remove the leading "#" if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Precipitation; groupIndex = 0; } else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MaxTemperature; groupIndex = 0; } else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MinTemperature; groupIndex = 0; } else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.NDeposition; groupIndex = 0; } else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Winddirection; groupIndex = 1; } else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Windspeed; groupIndex = 1; } else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.CO2; groupIndex = 0; } else { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile)); } // increment group section count ++groupSectionCounts[groupIndex]; // if this is the first section in the file then parse the ecoregions, etc. if (ecoRegionIndexMap == null) { // read next line to get ecoregion headers var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList(); ecoRegionHeaders.RemoveAt(0); // remove blank cell at the beginning of ecoregion header row // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev ecoRegionCount = ecoRegionHeaders.Count / 3; if (ecoRegionCount == 0) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile)); } var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active); if (ecoRegionCount != modelCoreActiveEcoRegionCount) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount)); } // determine the map from ecoregions in this file to ecoregion indices in ModelCore ecoRegionIndexMap = new int[ecoRegionCount]; for (var i = 0; i < ecoRegionCount; ++i) { IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]]; // JM: Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive. if (eco != null && eco.Active) { ecoRegionIndexMap[i] = eco.Index; } else { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile)); } } } else { // skip ecoregion header line reader.ReadLine(); } // skip data headers reader.ReadLine(); // get next line as first line of data fields = reader.ReadLine().Replace(" ", "").Split(',').ToList(); sectionYear = -999; sectionYearIndex = -1; sectionRowIndex = -1; } // ** // process line of data // grab the timeStep as the first field and remove it from the data var timeStep = fields[0]; fields.RemoveAt(0); ++sectionRowIndex; // if this is the first section for this group, add the timeStep to the group timeStep List // otherwise check that the timeStep matches that of the same row in the first section for the group // this also ensures that the sectionYearIndex exists in the yearEcoRecords below if (groupSectionCounts[groupIndex] == 1) { groupTimeSteps[groupIndex].Add(timeStep); } else if (sectionRowIndex > groupTimeSteps[groupIndex].Count - 1 || timeStep != groupTimeSteps[groupIndex][sectionRowIndex]) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}', timestamp '{1}', sectionRowIndex {2}, in climate file '{3}'.", section, timeStep, sectionRowIndex, climateFile)); } // parse out the year var year = int.Parse(timeStep.Substring(0, 4)); if (year != sectionYear) { // start of a new year sectionYear = year; ++sectionYearIndex; // if this is the first section for the group, then make a new yearEcoRecord and add it to the output data, either precip or wind if (groupSectionCounts[groupIndex] == 1) { yearEcoRecords = new List <ClimateRecord> [Climate.ModelCore.Ecoregions.Count]; for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) { yearEcoRecords[i] = new List <ClimateRecord>(); } if (groupIndex == 0) { precipClimateRecords.Add(yearEcoRecords); precipYearKeys.Add(year); } else if (groupIndex == 1) { windClimateRecords.Add(yearEcoRecords); windYearKeys.Add(year); } } else { // if not the first section, grab the ecorecords for this year, either precip or wind yearEcoRecords = groupIndex == 0 ? precipClimateRecords[sectionYearIndex] : windClimateRecords[sectionYearIndex]; } sectionYearRowIndex = -1; } // ** // incorporate (or add) this row's data into yearEcoRecords ++sectionYearRowIndex; // if this is the first section for the group, add new ClimateRecords for each ecoregion. if (groupSectionCounts[groupIndex] == 1) { for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) { yearEcoRecords[i].Add(new ClimateRecord()); } } for (var i = 0; i < ecoRegionCount; ++i) { var ecoRecord = yearEcoRecords[ecoRegionIndexMap[i]][sectionYearRowIndex]; // if this is the first section for the group, sectionYearRowIndex will give the record just instantiated above // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev var mean = double.Parse(fields[i]); var variance = double.Parse(fields[ecoRegionCount + i]); var stdev = double.Parse(fields[2 * ecoRegionCount + i]); if (groupIndex == 0) { // "precip" group switch (section) { case FileSection.Precipitation: ecoRecord.AvgPpt = mean * format.PrecipTransformation; ecoRecord.StdDevPpt = stdev * format.PrecipTransformation; break; case FileSection.MaxTemperature: case FileSection.MinTemperature: mean += format.TemperatureTransformation; if (section == FileSection.MaxTemperature) { ecoRecord.AvgMaxTemp = mean; } else { ecoRecord.AvgMinTemp = mean; } // for temperature variance wait until both min and max have been read before calculating the final value if (ecoRecord.AvgVarTemp == -99.0) { ecoRecord.AvgVarTemp = variance; // set AvgVarTemp to the first value we have (min or max) } else { // have both min and max, so average the variance ecoRecord.AvgVarTemp = (ecoRecord.AvgVarTemp + variance) / 2.0; } ecoRecord.StdDevTemp = System.Math.Sqrt(ecoRecord.AvgVarTemp); // this will set the st dev even if the data file only has one temperature section break; case FileSection.NDeposition: ecoRecord.AvgNDeposition = mean; ecoRecord.AvgVarNDeposition = variance; ecoRecord.StdDevNDeposition = stdev; break; case FileSection.CO2: ecoRecord.AvgCO2 = mean; ecoRecord.AvgVarCO2 = variance; ecoRecord.StdDevCO2 = stdev; break; } } else if (groupIndex == 1) { // "wind" group switch (section) { case FileSection.Winddirection: mean += format.WindDirectionTransformation; if (mean > 360.0) { mean -= 360; } ecoRecord.AvgWindDirection = mean; ecoRecord.AvgVarWindDirection = variance; ecoRecord.StdDevWindDirection = stdev; break; case FileSection.Windspeed: ecoRecord.AvgWindSpeed = mean * format.WindSpeedTransformation; ecoRecord.AvgVarWindSpeed = variance; ecoRecord.StdDevWindSpeed = stdev; break; } } } } reader.Close(); // ** // basic data checks for (var i = 0; i < precipClimateRecords.Count; ++i) { var ecoRecords = precipClimateRecords[i][ecoRegionIndexMap[0]]; // check the first eco region provided in the file if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count)); } if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count)); } } // if wind data exist, check them, too if (groupSectionCounts[1] > 0) { for (var i = 0; i < windClimateRecords.Count; ++i) { var ecoRecords = windClimateRecords[i][ecoRegionIndexMap[0]]; // check the first eco region provided in the file if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count)); } if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count)); } } // also check that the number of years matches that of the precip data if (precipClimateRecords.Count != windClimateRecords.Count) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: The number of years ({0}) of Precip/Tmax/Tmin, etc. data does not equal the number of years ({1}) of Wind data in climate file '{2}'.", precipClimateRecords.Count, windClimateRecords.Count, climateFile)); } } // ** // normalize daily data for leap years into 365 days if (sourceTemporalGranularity == TemporalGranularity.Daily) { // precip data first foreach (var yEcoRecords in precipClimateRecords) { foreach (var ecoRecords in yEcoRecords) { if (ecoRecords.Count == 366) { var feb28Record = ecoRecords[58]; // get data for Feb. 28 (day 59). var feb29Record = ecoRecords[59]; // get data for Feb. 29 (day 60). ecoRecords.RemoveAt(59); // remove Feb. 29 from the ecoRecords // ignore std. dev. and variance data from Feb. 29. // average some Feb. 29 values with their corresponding Feb. 28 values feb28Record.AvgMinTemp = 0.5 * (feb28Record.AvgMinTemp + feb29Record.AvgMinTemp); feb28Record.AvgMaxTemp = 0.5 * (feb28Record.AvgMaxTemp + feb29Record.AvgMaxTemp); feb28Record.AvgRH = 0.5 * (feb28Record.AvgRH + feb29Record.AvgRH); feb28Record.AvgCO2 = 0.5 * (feb28Record.AvgCO2 + feb29Record.AvgCO2); feb28Record.AvgPAR = 0.5 * (feb28Record.AvgPAR + feb29Record.AvgPAR); // amortize (spread out) some Feb. 29 values over the entire month so that a monthly total still contains the Feb. 29 value. // do this rather than simply adding the Feb. 28 and Feb. 29 values, which would leave a spike in the final Feb. 28 data. var avgPptIncrement = feb28Record.AvgPpt / 28.0; var avgNDepositionIncrement = feb28Record.AvgNDeposition / 28.0; var feb1 = 31; // Feb. 1 index (day 32) for (var j = feb1; j < feb1 + 28; ++j) { ecoRecords[j].AvgPpt += avgPptIncrement; ecoRecords[j].AvgNDeposition += avgNDepositionIncrement; } } } } // wind data next (if it exists) if (groupSectionCounts[1] > 0) { foreach (var yEcoRecords in windClimateRecords) { foreach (var ecoRecords in yEcoRecords) { if (ecoRecords.Count == 366) { var feb28Record = ecoRecords[58]; // get data for Feb. 28 (day 59). var feb29Record = ecoRecords[59]; // get data for Feb. 29 (day 60). ecoRecords.RemoveAt(59); // remove Feb. 29 from the ecoRecords // ignore std. dev. and variance data from Feb. 29. // average some Feb. 29 values with their corresponding Feb. 28 values feb28Record.AvgWindDirection = 0.5 * (feb28Record.AvgWindDirection + feb29Record.AvgWindDirection); feb28Record.AvgWindSpeed = 0.5 * (feb28Record.AvgWindSpeed + feb29Record.AvgWindSpeed); } } } } } // ** // if wind data exist, combine them with precip data if (groupSectionCounts[1] > 0) { for (var i = 0; i < precipClimateRecords.Count; ++i) { for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j) { for (var k = 0; k < precipClimateRecords[i][j].Count; ++k) { var precipRecord = precipClimateRecords[i][j][k]; var windRecord = windClimateRecords[i][j][k]; precipRecord.AvgWindDirection = windRecord.AvgWindDirection; precipRecord.AvgVarWindDirection = windRecord.AvgVarWindDirection; precipRecord.StdDevWindDirection = windRecord.StdDevWindDirection; precipRecord.AvgWindSpeed = windRecord.AvgWindSpeed; precipRecord.AvgVarWindSpeed = windRecord.AvgVarWindSpeed; precipRecord.StdDevWindSpeed = windRecord.StdDevWindSpeed; } } } } // ** // final data structures to return // yearKeys is the list of years in the file, e.g. 1950, 1951, etc. taken from the precip timesteps yearKeys = precipYearKeys; climateRecords = precipClimateRecords; }
private static void Convert_USGS_to_ClimateData2(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List<int> yearKeys, out List<List<ClimateRecord>[]> climateRecords) { var precipYearKeys = new List<int>(); var windYearKeys = new List<int>(); // indexing of precip and wind ClimateRecords: [yearIndex][ecoregion][i], where yearIndex is [0..n] corresponding to the yearKeys index, i.e. index 0 is for 1950, index 1 for 1951, etc. var precipClimateRecords = new List<List<ClimateRecord>[]>(); var windClimateRecords = new List<List<ClimateRecord>[]>(); // get trigger words for parsing based on file format ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat); if (!File.Exists(climateFile)) { throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile); } var reader = File.OpenText(climateFile); Climate.ModelCore.UI.WriteLine(" Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity); // maps from ecoregion column index in the input file to the ecoregion.index for the region int[] ecoRegionIndexMap = null; var ecoRegionCount = 0; var numberOfGroups = 2; // the number of allowed groups. Presently: (1) precip, tmin, tmax, Ndep, CO2; (2) winddirection & windspeed var groupSectionCounts = new int[numberOfGroups]; // used to know if I'm beyond the first section in a group var groupTimeSteps = new List<string>[numberOfGroups]; // keeps track of timesteps within each group to ensure they match for (var i = 0; i < numberOfGroups; ++i) groupTimeSteps[i] = new List<string>(); var sectionYearRowIndex = -1; var sectionYear = -1; var sectionYearIndex = -1; var sectionRowIndex = -1; FileSection section = 0; var groupIndex = -1; List<ClimateRecord>[] yearEcoRecords = null; // could be either precip or wind data, depending on the section group. string row; while (!string.IsNullOrEmpty(row = reader.ReadLine())) { var fields = row.Replace(" ", "").Split(',').ToList(); // JM: don't know if stripping blanks is needed, but just in case // skip blank rows if (fields.All(x => string.IsNullOrEmpty(x))) continue; // check for trigger word if (fields[0].StartsWith("#")) { // determine which section we're in var triggerWord = fields[0].TrimStart('#'); // remove the leading "#" if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Precipitation; groupIndex = 0; } else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MaxTemperature; groupIndex = 0; } else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.MinTemperature; groupIndex = 0; } else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.NDeposition; groupIndex = 0; } else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Winddirection; groupIndex = 1; } else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.Windspeed; groupIndex = 1; } else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) { section = FileSection.CO2; groupIndex = 0; } else throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile)); // increment group section count ++groupSectionCounts[groupIndex]; // if this is the first section in the file then parse the ecoregions, etc. if (ecoRegionIndexMap == null) { // read next line to get ecoregion headers var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList(); ecoRegionHeaders.RemoveAt(0); // remove blank cell at the beginning of ecoregion header row // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev ecoRegionCount = ecoRegionHeaders.Count / 3; if (ecoRegionCount == 0) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile)); var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active); if (ecoRegionCount != modelCoreActiveEcoRegionCount) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount)); // determine the map from ecoregions in this file to ecoregion indices in ModelCore ecoRegionIndexMap = new int[ecoRegionCount]; for (var i = 0; i < ecoRegionCount; ++i) { IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]]; // JM: Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive. if (eco != null && eco.Active) ecoRegionIndexMap[i] = eco.Index; else throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile)); } } else // skip ecoregion header line reader.ReadLine(); // skip data headers reader.ReadLine(); // get next line as first line of data fields = reader.ReadLine().Replace(" ", "").Split(',').ToList(); sectionYear = -999; sectionYearIndex = -1; sectionRowIndex = -1; } // ** // process line of data // grab the timeStep as the first field and remove it from the data var timeStep = fields[0]; fields.RemoveAt(0); ++sectionRowIndex; // if this is the first section for this group, add the timeStep to the group timeStep List // otherwise check that the timeStep matches that of the same row in the first section for the group // this also ensures that the sectionYearIndex exists in the yearEcoRecords below if (groupSectionCounts[groupIndex] == 1) { groupTimeSteps[groupIndex].Add(timeStep); } else if (sectionRowIndex > groupTimeSteps[groupIndex].Count - 1 || timeStep != groupTimeSteps[groupIndex][sectionRowIndex]) { throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}', timestamp '{1}', sectionRowIndex {2}, in climate file '{3}'.", section, timeStep, sectionRowIndex, climateFile)); } // parse out the year var year = int.Parse(timeStep.Substring(0, 4)); if (year != sectionYear) { // start of a new year sectionYear = year; ++sectionYearIndex; // if this is the first section for the group, then make a new yearEcoRecord and add it to the output data, either precip or wind if (groupSectionCounts[groupIndex] == 1) { yearEcoRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count]; for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) yearEcoRecords[i] = new List<ClimateRecord>(); if (groupIndex == 0) { precipClimateRecords.Add(yearEcoRecords); precipYearKeys.Add(year); } else if (groupIndex == 1) { windClimateRecords.Add(yearEcoRecords); windYearKeys.Add(year); } } else { // if not the first section, grab the ecorecords for this year, either precip or wind yearEcoRecords = groupIndex == 0 ? precipClimateRecords[sectionYearIndex] : windClimateRecords[sectionYearIndex]; } sectionYearRowIndex = -1; } // ** // incorporate (or add) this row's data into yearEcoRecords ++sectionYearRowIndex; // if this is the first section for the group, add new ClimateRecords for each ecoregion. if (groupSectionCounts[groupIndex] == 1) for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) yearEcoRecords[i].Add(new ClimateRecord()); for (var i = 0; i < ecoRegionCount; ++i) { var ecoRecord = yearEcoRecords[ecoRegionIndexMap[i]][sectionYearRowIndex]; // if this is the first section for the group, sectionYearRowIndex will give the record just instantiated above // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev var mean = double.Parse(fields[i]); var variance = double.Parse(fields[ecoRegionCount + i]); var stdev = double.Parse(fields[2 * ecoRegionCount + i]); if (groupIndex == 0) { // "precip" group switch (section) { case FileSection.Precipitation: ecoRecord.AvgPpt = mean * format.PrecipTransformation; ecoRecord.StdDevPpt = stdev * format.PrecipTransformation; break; case FileSection.MaxTemperature: case FileSection.MinTemperature: mean += format.TemperatureTransformation; if (section == FileSection.MaxTemperature) ecoRecord.AvgMaxTemp = mean; else ecoRecord.AvgMinTemp = mean; // for temperature variance wait until both min and max have been read before calculating the final value if (ecoRecord.AvgVarTemp == -99.0) ecoRecord.AvgVarTemp = variance; // set AvgVarTemp to the first value we have (min or max) else // have both min and max, so average the variance ecoRecord.AvgVarTemp = (ecoRecord.AvgVarTemp + variance) / 2.0; ecoRecord.StdDevTemp = System.Math.Sqrt(ecoRecord.AvgVarTemp); // this will set the st dev even if the data file only has one temperature section break; case FileSection.NDeposition: ecoRecord.AvgNDeposition = mean; ecoRecord.AvgVarNDeposition = variance; ecoRecord.StdDevNDeposition = stdev; break; case FileSection.CO2: ecoRecord.AvgCO2 = mean; ecoRecord.AvgVarCO2 = variance; ecoRecord.StdDevCO2 = stdev; break; } } else if (groupIndex == 1) { // "wind" group switch (section) { case FileSection.Winddirection: mean += format.WindDirectionTransformation; if (mean > 360.0) mean -= 360; ecoRecord.AvgWindDirection = mean; ecoRecord.AvgVarWindDirection = variance; ecoRecord.StdDevWindDirection = stdev; break; case FileSection.Windspeed: ecoRecord.AvgWindSpeed = mean * format.WindSpeedTransformation; ecoRecord.AvgVarWindSpeed = variance; ecoRecord.StdDevWindSpeed = stdev; break; } } } } reader.Close(); // ** // basic data checks for (var i = 0; i < precipClimateRecords.Count; ++i) { var ecoRecords = precipClimateRecords[i][ecoRegionIndexMap[0]]; // check the first eco region provided in the file if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count)); if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Precip/Tmax/Tmin, etc. Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", precipYearKeys[i], climateFile, ecoRecords.Count)); } // if wind data exist, check them, too if (groupSectionCounts[1] > 0) { for (var i = 0; i < windClimateRecords.Count; ++i) { var ecoRecords = windClimateRecords[i][ecoRegionIndexMap[0]]; // check the first eco region provided in the file if (sourceTemporalGranularity == TemporalGranularity.Monthly && ecoRecords.Count != 12) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Monthly data for year {0} in climate file '{1}' do not have 12 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count)); if (sourceTemporalGranularity == TemporalGranularity.Daily && ecoRecords.Count != 365 && ecoRecords.Count != 366) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Wind Daily data for year {0} in climate file '{1}' do not have 365 or 366 records. The year has {2} records.", windYearKeys[i], climateFile, ecoRecords.Count)); } // also check that the number of years matches that of the precip data if (precipClimateRecords.Count != windClimateRecords.Count) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: The number of years ({0}) of Precip/Tmax/Tmin, etc. data does not equal the number of years ({1}) of Wind data in climate file '{2}'.", precipClimateRecords.Count, windClimateRecords.Count, climateFile)); } // ** // normalize daily data for leap years into 365 days if (sourceTemporalGranularity == TemporalGranularity.Daily) { // precip data first foreach (var yEcoRecords in precipClimateRecords) foreach (var ecoRecords in yEcoRecords) if (ecoRecords.Count == 366) { var feb28Record = ecoRecords[58]; // get data for Feb. 28 (day 59). var feb29Record = ecoRecords[59]; // get data for Feb. 29 (day 60). ecoRecords.RemoveAt(59); // remove Feb. 29 from the ecoRecords // ignore std. dev. and variance data from Feb. 29. // average some Feb. 29 values with their corresponding Feb. 28 values feb28Record.AvgMinTemp = 0.5 * (feb28Record.AvgMinTemp + feb29Record.AvgMinTemp); feb28Record.AvgMaxTemp = 0.5 * (feb28Record.AvgMaxTemp + feb29Record.AvgMaxTemp); feb28Record.AvgRH = 0.5 * (feb28Record.AvgRH + feb29Record.AvgRH); feb28Record.AvgCO2 = 0.5 * (feb28Record.AvgCO2 + feb29Record.AvgCO2); feb28Record.AvgPAR = 0.5 * (feb28Record.AvgPAR + feb29Record.AvgPAR); // amortize (spread out) some Feb. 29 values over the entire month so that a monthly total still contains the Feb. 29 value. // do this rather than simply adding the Feb. 28 and Feb. 29 values, which would leave a spike in the final Feb. 28 data. var avgPptIncrement = feb28Record.AvgPpt / 28.0; var avgNDepositionIncrement = feb28Record.AvgNDeposition / 28.0; var feb1 = 31; // Feb. 1 index (day 32) for (var j = feb1; j < feb1 + 28; ++j) { ecoRecords[j].AvgPpt += avgPptIncrement; ecoRecords[j].AvgNDeposition += avgNDepositionIncrement; } } // wind data next (if it exists) if (groupSectionCounts[1] > 0) foreach (var yEcoRecords in windClimateRecords) foreach (var ecoRecords in yEcoRecords) if (ecoRecords.Count == 366) { var feb28Record = ecoRecords[58]; // get data for Feb. 28 (day 59). var feb29Record = ecoRecords[59]; // get data for Feb. 29 (day 60). ecoRecords.RemoveAt(59); // remove Feb. 29 from the ecoRecords // ignore std. dev. and variance data from Feb. 29. // average some Feb. 29 values with their corresponding Feb. 28 values feb28Record.AvgWindDirection = 0.5 * (feb28Record.AvgWindDirection + feb29Record.AvgWindDirection); feb28Record.AvgWindSpeed = 0.5 * (feb28Record.AvgWindSpeed + feb29Record.AvgWindSpeed); } } // ** // if wind data exist, combine them with precip data if (groupSectionCounts[1] > 0) for (var i = 0; i < precipClimateRecords.Count; ++i) for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j) for (var k = 0; k < precipClimateRecords[i][j].Count; ++k) { var precipRecord = precipClimateRecords[i][j][k]; var windRecord = windClimateRecords[i][j][k]; precipRecord.AvgWindDirection = windRecord.AvgWindDirection; precipRecord.AvgVarWindDirection = windRecord.AvgVarWindDirection; precipRecord.StdDevWindDirection = windRecord.StdDevWindDirection; precipRecord.AvgWindSpeed = windRecord.AvgWindSpeed; precipRecord.AvgVarWindSpeed = windRecord.AvgVarWindSpeed; precipRecord.StdDevWindSpeed = windRecord.StdDevWindSpeed; } // ** // final data structures to return // yearKeys is the list of years in the file, e.g. 1950, 1951, etc. taken from the precip timesteps yearKeys = precipYearKeys; climateRecords = precipClimateRecords; }
public static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat) { ClimateFileFormatProvider formatProvider = new ClimateFileFormatProvider(climateFileFormat); maxTriggerWord = formatProvider.MaxTempTriggerWord; minTriggerWord = formatProvider.MinTempTriggerWord; prcpTriggerWord = formatProvider.PrecipTriggerWord; rhTriggerWord = formatProvider.RhTriggerWord; windSpeedTriggerWord = formatProvider.WindSpeedTriggerWord; bool checkRHWindSpeed = false; string unmatched_TriggerWords; if (checkRHWindSpeed == false) unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord; else unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord; int triggerWordsCheckingTime = 0; string path = climateFile; StreamReader sreader; string centuryPath = ""; // monthly and daily climates should be filled before in order to chack weather input climatefile can be processed as daily or monthly //List<string> montlyClimates; //List<string> DailyClimate; climateFileFormat = climateFileFormat.ToLower(); Climate.ModelCore.UI.WriteLine(" Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat, sourceTemporalGranularity); #region IPCC3 Input file if (climateFileFormat == "ipcc3_daily" || climateFileFormat == "ipcc3_monthly") { exportToTxtFormatFile = false; sreader = new StreamReader(path); string line; string[] fields; DataTable _dataTableDataByTime = new DataTable(); line = sreader.ReadLine(); fields = line.Split(','); line = sreader.ReadLine(); fields = line.Split(','); string CurrentScenarioType = ""; climate_Dic = new Dictionary<string, double[]>(); string key = ""; currentYear = ""; int currentTimeS = 0; currentMonth = 1; int tempEco = 1; double AverageMax = 0; double AverageMin = 0; double SumPrecp = 0; double AverageSTDT = 0; double SumVarPpt = 0; int numberOfDays = 0; double[] tempSum = new double[31]; double[] tempPrp = new double[31]; //bool emptytxt = false; int updatedIndex = 0; //int ecoIndex = -1; climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>(); foreach (string field in fields) { if (field != "") { //if (Convert.ToInt16(field) > ecoIndex) //{ // ecoIndex = Convert.ToInt16(field); IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault(); //numberOfAllEcoregions = Convert.ToInt16(field); if (eco != null && eco.Active) { if (!climateFileActiveEcoregions.ContainsKey(eco.Index)) climateFileActiveEcoregions.Add(eco.Index, eco); } else { //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions); Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile); throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file."); } } } //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std int dicSize = climateFileActiveEcoregions.Count * 15; sreader.Close(); StreamReader reader = new StreamReader(path); while (reader.Peek() >= 0) { line = reader.ReadLine(); fields = line.Split(','); foreach (string field in fields) { if (field.Contains("#")) { triggerWordsCheckingTime++; if (triggerWordsCheckingTime > 1) if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following trigger words did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following trigger words did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } //tempScenarioName = CurrentScenarioName; //if (field.ToLower().Contains(maxTriggerWord) || field.ToLower().Contains(minTriggerWord)) //{ //CurrentScenarioName = field.Substring(1, field.LastIndexOf("t") - 2); if (field.ToLower().Contains(maxTriggerWord.ToLower())) { CurrentScenarioType = maxTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, ""); } else if (field.ToLower().Contains(minTriggerWord.ToLower())) { CurrentScenarioType = minTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, ""); } else if (field.ToLower().Contains(prcpTriggerWord.ToLower())) { //CurrentScenarioName = field.Substring(1, field.LastIndexOf("p") - 2); CurrentScenarioType = prcpTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, ""); } else if (field.ToLower().Contains(rhTriggerWord.ToLower())) { CurrentScenarioType = rhTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, ""); } else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower())) { CurrentScenarioType = windSpeedTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, ""); } } } if (fields[0] == string.Empty && !fields[0].Contains("#")) { line = reader.ReadLine(); fields = line.Split(','); if (fields[0].Contains("TIME")) { line = reader.ReadLine(); fields = line.Split(','); //now fill array //Get the lenght of array according to the number of ecorigions/ // } } if (!fields[0].Contains("#")) //if (CurrentScenarioName == tempScenarioName && !fields[0].Contains("#")) { key = fields[0].ToString(); if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower())) { IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMaxT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMax_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD); IndexMaxT_Mean = IndexMaxT_Mean + 9; //IndexMax_MaxT = IndexMax_MaxT + 12; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; updatedIndex = 0; //indexofSTD++; //} } } else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower())) { IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ //currentSTD = fields[indexofSTD]; climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMinT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMin_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_STD); //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD); IndexMinT_Mean = IndexMinT_Mean + 9; //IndexMin_MaxT = IndexMin_MaxT + 12; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; updatedIndex = 0; // IndexSTD = IndexSTD + 6; // indexofSTD++; //} } } else if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower())) { IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of Precipitation and STD for each ecoregion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ //currentSTD = fields[indexofSTD]; climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) / 10, IndexPrcp_Mean); // /10 is for mm to cm conversion updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexPrcp_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_STD); //NOTE: this might be a wrong conversion for converting IndexPrcp_STD from mm to cm because STD is calculate using root square. //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD); IndexPrcp_Mean = IndexPrcp_Mean + 9; //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; updatedIndex = 0; //IndexSTD = IndexSTD + 6; //indexofSTD++; } } //----- else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower())) { IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD); IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; updatedIndex = 0; } } //----- else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower())) { IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD); IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; updatedIndex = 0; } } //----- } //end while //if (CurrentScenarioName != tempScenarioName || reader.EndOfStream) if (reader.EndOfStream) { //Print file for one scenario then clear dictionary to use for another scenario //Daily period centuryPath = "Century_Climate_Inputs_Monthly.txt"; setIndexed(); //using (System.IO.StreamWriter file = new System.IO.StreamWriter(centuryPath, emptytxt)) //{ // if (exportToTxtFormatFile) // { // file.WriteLine("LandisData" + " \"Climate Data\" \n"); // file.WriteLine("ClimateTable \n"); // //file.WriteLine(tempScenarioName + "\n"); // file.WriteLine(">>Eco" + "\t\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDevPpt" + "\t" + "PAR" + "\t" + "VarT" + "\t" + "VarPpt" + "\n"); // file.WriteLine(">>Name" + "\t\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\t" + "(cm)" + "\t" + "(cm)" + "\n"); // } // else // { // file.WriteLine("This file is not generated when converting a Daily Climate to Monthly."); // file.WriteLine("To enable the generation of this file:"); // file.WriteLine("set 'exportToTxtFormatFile = true;' in 'if (sourceTemporalGranularity == TemporalGranularity.Daily) \n { \n \t exportToTxtFormatFile = false; ' in ClimateDataConvertor class."); // file.WriteLine("Caution: Note that the right AnnualCliamte_Monthly will not be generated if this generated Monthly-climate txt file is used as a climate input file."); // } currentYear = climate_Dic.First().Key.Substring(0, 4).ToString(); //starting timestep currentTimeS = 0; currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString()); tempEco = 1; lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max(); firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min(); if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear) lastYear = lastYear - 1; for (int j = firstYear; j <= lastYear; j++) { for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { currentYear = j.ToString(); foreach (KeyValuePair<string, double[]> row in climate_Dic) { if (currentYear == row.Key.Substring(0, 4).ToString()) { if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2))) { //(row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean])/2 //AverageMin += (row.Value[IndexMin_MaxT] + row.Value[IndexMinT_Mean]) / 2; //AverageMax += (row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean]) / 2; //AveragePrecp += (row.Value[IndexPrcp_MaxT] + row.Value[IndexPrcp_Mean]) / 2; //AverageSTDT += (row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2; //AverageMaxSTD += Math.Round(Convert.ToDouble(row.Value[2]), 2); AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); numberOfDays++; } else { //if (exportToTxtFormatFile) // file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n"); currentMonth = Convert.ToInt16(row.Key.Substring(5, 2)); //if (tempMonth != currentMonth) alldays += numberOfDays; AverageMax = 0; AverageMin = 0; SumPrecp = 0; AverageSTDT = 0; SumVarPpt = 0; numberOfDays = 0; AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); numberOfDays++; } } else { if (currentMonth == 12) { alldays += numberOfDays; if (!yearsdays.Keys.Contains(j)) { yearsdays.Add(j, alldays); alldays = 0; } } alldays = 0; tempEco = i; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; SumVarPpt = 0; numberOfDays = 0; AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); //sums = 0; //stdTemp = 0; //prpSums = 0; //stdPrp = 0; numberOfDays++; } } tempEco = i; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; SumVarPpt = 0; IndexMaxT_Mean = IndexMaxT_Mean + 9; //IndexMax_MaxT = IndexMax_MaxT + 12; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; IndexMinT_Mean = IndexMinT_Mean + 9; //IndexMin_MaxT = IndexMin_MaxT + 12; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; IndexPrcp_Mean = IndexPrcp_Mean + 9; //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; } //file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(StdDevPpt), 2) + "\t" + "0.0" + "\n"); tempEco = 1; currentTimeS = currentTimeS + 1; IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; SumVarPpt = 0; } } //If file contains more than one scenario then these setting will be needed //climate_Dic.Clear(); //emptytxt = true; //tempScenarioName = CurrentScenarioName; //} } //if (unmatched_TriggerWords != "") //{ // Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format.", climateFile); // Climate.ModelCore.UI.WriteLine("The following triggerWords did not match the triggerwords in the given file: {1}. Selected format: {2}", unmatched_TriggerWords, formatProvider.SelectedFormat); // throw new ApplicationException("Error in ClimateDataConvertor: See Log File."); //: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); //} } #endregion #region IPCC5 Input file else if (climateFileFormat == "ipcc5_monthly" || climateFileFormat == "ipcc5_daily") { exportToTxtFormatFile = false; sreader = new StreamReader(path); string line; string[] fields; DataTable _dataTableDataByTime = new DataTable(); line = sreader.ReadLine(); fields = line.Split(','); line = sreader.ReadLine(); fields = line.Split(','); string CurrentScenarioType = ""; climate_Dic = new Dictionary<string, double[]>(); string key = ""; currentYear = ""; int currentTimeS = 0; currentMonth = 1; int tempEco = 1; double AverageMax = 0; double AverageMin = 0; double SumPrecp = 0; double AverageSTDT = 0; double SumVarPpt = 0; int numberOfDays = 0; double[] tempSum = new double[31]; double[] tempPrp = new double[31]; //bool emptytxt = false; int updatedIndex = 0; //int ecoIndex = -1; climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>(); foreach (string field in fields) { if (field != "") //if (Convert.ToInt16(field) > ecoIndex) { //ecoIndex = Convert.ToInt16(field); IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault(); if (eco != null && eco.Active) { if (!climateFileActiveEcoregions.ContainsKey(eco.Index)) climateFileActiveEcoregions.Add(eco.Index, eco); } else { //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions); Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile); throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file."); } } } //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std int dicSize = climateFileActiveEcoregions.Count * 15; sreader.Close(); StreamReader reader = new StreamReader(path); while (reader.Peek() >= 0) { line = reader.ReadLine(); fields = line.Split(','); foreach (string field in fields) { if (field.Contains("#")) { triggerWordsCheckingTime++; if (triggerWordsCheckingTime > 1) if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } //tempScenarioName = CurrentScenarioName; //if (field.ToLower().Contains(maxTriggerWord) || field.ToLower().Contains(minTriggerWord)) //{ //CurrentScenarioName = field.Substring(1, field.LastIndexOf("t") - 2); if (field.ToLower().Contains(maxTriggerWord.ToLower())) { CurrentScenarioType = maxTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, ""); } else if (field.ToLower().Contains(minTriggerWord.ToLower())) { CurrentScenarioType = minTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, ""); } else if (field.ToLower().Contains(prcpTriggerWord.ToLower())) { //CurrentScenarioName = field.Substring(1, field.LastIndexOf("p") - 2); CurrentScenarioType = prcpTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, ""); } else if (field.ToLower().Contains(rhTriggerWord.ToLower())) { CurrentScenarioType = rhTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, ""); } else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower())) { CurrentScenarioType = windSpeedTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, ""); } } } if (fields[0] == string.Empty && !fields[0].Contains("#")) { line = reader.ReadLine(); fields = line.Split(','); if (fields[0].Contains("TIME")) { line = reader.ReadLine(); fields = line.Split(','); } } if (!fields[0].Contains("#")) { key = fields[0].ToString(); if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower())) { IndexMaxT_Mean = 0; IndexMaxT_Var = 1; IndexMaxT_STD = 2; if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) - 274.15, IndexMaxT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD); IndexMaxT_Mean = IndexMaxT_Mean + 9; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; updatedIndex = 0; } } else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower())) { IndexMinT_Mean = 3; IndexMinT_Var = 4; IndexMinT_STD = 5; // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) - 274.15, IndexMinT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) - 274.15, IndexMinT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) - 274.15, IndexMinT_STD); IndexMinT_Mean = IndexMinT_Mean + 9; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; updatedIndex = 0; } } else if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower())) { IndexPrcp_Mean = 6; IndexPrcp_Var = 7; IndexPrcp_STD = 8; if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of Precipitation and STD for each ecoregion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) * 315360, IndexPrcp_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) * 315360, IndexPrcp_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) * 315360, IndexPrcp_STD); //NOTE: this might be a wrong conversion for converting IndexPrcp_STD from mm to cm because STD is calculate using root square. IndexPrcp_Mean = IndexPrcp_Mean + 9; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; updatedIndex = 0; } } //----- else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower())) { IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD); IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; updatedIndex = 0; } } //----- else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower())) { IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD); IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; updatedIndex = 0; } } //----- } //end while //if (CurrentScenarioName != tempScenarioName || reader.EndOfStream) if (reader.EndOfStream) { //Daily period //centuryPath = "Century_Climate_Inputs_Monthly.txt"; setIndexed(); currentYear = climate_Dic.First().Key.Substring(0, 4).ToString(); //starting timestep currentTimeS = 0; currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString()); tempEco = 1; lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max(); firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min(); if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear) lastYear = lastYear - 1; for (int j = firstYear; j <= lastYear; j++) { for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { currentYear = j.ToString(); foreach (KeyValuePair<string, double[]> row in climate_Dic) { if (currentYear == row.Key.Substring(0, 4).ToString()) { if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2))) { AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); numberOfDays++; } else { //if (exportToTxtFormatFile) // file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n"); currentMonth = Convert.ToInt16(row.Key.Substring(5, 2)); //if (tempMonth != currentMonth) alldays += numberOfDays; AverageMax = 0; AverageMin = 0; SumPrecp = 0; AverageSTDT = 0; SumVarPpt = 0; numberOfDays = 0; AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); numberOfDays++; } } else { if (currentMonth == 12) { alldays += numberOfDays; //if (exportToTxtFormatFile) // file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(Math.Sqrt(SumVarPpt), 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(SumVarPpt, 2) + "\n"); if (!yearsdays.Keys.Contains(j)) { yearsdays.Add(j, alldays); alldays = 0; } } alldays = 0; tempEco = i; currentMonth = 1; AverageMax = 0; AverageMin = 0; SumPrecp = 0; AverageSTDT = 0; SumVarPpt = 0; numberOfDays = 0; AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); SumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_Var]); numberOfDays++; } } tempEco = i; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; SumVarPpt = 0; IndexMaxT_Mean = IndexMaxT_Mean + 9; //IndexMax_MaxT = IndexMax_MaxT + 12; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; IndexMinT_Mean = IndexMinT_Mean + 9; //IndexMin_MaxT = IndexMin_MaxT + 12; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; IndexPrcp_Mean = IndexPrcp_Mean + 9; //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; } //file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(StdDevPpt), 2) + "\t" + "0.0" + "\n"); tempEco = 1; currentTimeS = currentTimeS + 1; IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; SumVarPpt = 0; } } //If file contains more than one scenario then these setting will be needed //climate_Dic.Clear(); //emptytxt = true; //tempScenarioName = CurrentScenarioName; //} } //if (unmatched_TriggerWords != "") //{ // Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format.", climateFile); // Climate.ModelCore.UI.WriteLine("The following triggerWords did not match the triggerwords in the given file: {1}. Selected format: {2}", unmatched_TriggerWords, formatProvider.SelectedFormat); // throw new ApplicationException("Error in ClimateDataConvertor: See Log File."); //: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); //} } #endregion #region PRISM Monthly Data //else if (sourceTemporalGranularity == TemporalGranularity.Monthly) else if (climateFileFormat == "prism_monthly") { //unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord; sreader = new StreamReader(path); // NEED TRY CATCH FILE OPEN HERE string line; string[] fields; checkRHWindSpeed = false; if (checkRHWindSpeed == false) unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord;// +", " + rhTriggerWord + ", " + windSpeedTriggerWord; else unmatched_TriggerWords = maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord; //string tempScenarioName = ""; DataTable _dataTableDataByTime = new DataTable(); //int numberOfAllEcoregions = 0; line = sreader.ReadLine(); fields = line.Split(','); //tempScenarioName = fields[0].Substring(1, fields[0].LastIndexOf("t") - 2); //tempScenarioName = fields[0].Substring(1, 4); line = sreader.ReadLine(); fields = line.Split(','); //int totalRows = 0; //string[,] wholedata; //string CurrentScenarioName = ""; string CurrentScenarioType = ""; climate_Dic = new Dictionary<string, double[]>(); //string currentT; //string currentSTD; //string currentPart = ""; //int totalRow = 0; string key = ""; int IndexMaxT_Mean = 0; //int IndexMax_MaxT = 1; int IndexMaxT_Var = 1; int IndexMaxT_STD = 2; int IndexMinT_Mean = 3; //int IndexMin_MaxT = 5; int IndexMinT_Var = 4; int IndexMinT_STD = 5; int IndexPrcp_Mean = 6; //int IndexPrcp_MaxT = 9; int IndexPrcp_Var = 7; int IndexPrcp_STD = 8; int IndexRH_Mean = 9; int IndexRH_Var = 10; int IndexRH_STD = 11; int IndexwindSpeed_Mean = 12; int IndexwindSpeed_Var = 13; int IndexwindSpeed_STD = 14; //bool firstFlag = false; currentYear = ""; //starting timestep int currentTimeS = 0; currentMonth = 1; int tempEco = 1; double AverageMax = 0; //double AverageMaxSTD = 0; double AverageMin = 0; //double AverageMinSTD = 0; double SumPrecp = 0; double AverageSTDT = 0; double sumVarPpt = 0; //double AveragePrecSTD = 0; int numberOfDays = 0; double[] tempSum = new double[31]; double[] tempPrp = new double[31]; //double sums = 0; //double prpSums = 0; //double stdTemp = 0; //double stdPrp = 0; bool emptytxt = false; int updatedIndex = 0; // IEnumerable<Core.IEcoregion> activeEcoregions = Climate.ModelCore.Ecoregions.Where(P => P.Active); //int ecoIndex = -1; climateFileActiveEcoregions = new SortedList<int, Core.IEcoregion>(); foreach (string field in fields) { if (field != "") { //if (Convert.ToInt16(field) > ecoIndex) //{ // ecoIndex = Convert.ToInt16(field); IEcoregion eco = Climate.ModelCore.Ecoregions[field]; //.Where(P => P.Index == ecoIndex).FirstOrDefault(); //numberOfAllEcoregions = Convert.ToInt16(field); if (eco != null && eco.Active) { if (!climateFileActiveEcoregions.ContainsKey(eco.Index)) climateFileActiveEcoregions.Add(eco.Index, eco); } else { //Climate.ModelCore.UI.WriteLine("ClimateDataConvertor: Number of active ecoregions does not match the input file. The climate data for ecoregion with index {0} was ignored.", numberOfAllEcoregions); Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; Number of active ecoregions does not match the input file.", climateFile); throw new ApplicationException("Error in ClimateDataConvertor: Converting" + climateFile + "file into standard format; Number of active ecoregions does not match the input file."); } } } //12 beacuse for each ecoriogn we need Max_MinT,Max_MaxT,Max_Var Max_Std, Min_MinT,Min_MaxT,Min_Var Min_Std, Prcp_MinT,Prcp_MaxT,Prcp_Var Prcp_Std int dicSize = climateFileActiveEcoregions.Count * 15;// Climate.ModelCore.Ecoregions.Count * 9; sreader.Close(); StreamReader reader = new StreamReader(path); while (reader.Peek() >= 0) { line = reader.ReadLine(); fields = line.Split(','); foreach (string field in fields) { if (field.Contains("#")) { triggerWordsCheckingTime++; if (triggerWordsCheckingTime > 1) if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord + ", " + rhTriggerWord + ", " + windSpeedTriggerWord && checkRHWindSpeed == true) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } else if (unmatched_TriggerWords == maxTriggerWord + ", " + minTriggerWord + ", " + prcpTriggerWord && checkRHWindSpeed == false) { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } //tempScenarioName = CurrentScenarioName; if (field.ToLower().Contains(prcpTriggerWord.ToLower())) { //CurrentScenarioName = field.Substring(1, 4); CurrentScenarioType = prcpTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + prcpTriggerWord, ""); } //else if (field.ToLower().Contains(maxTriggerWord.ToLower()) || field.ToLower().Contains(minTriggerWord.ToLower())) //{ //CurrentScenarioName = field.Substring(1, 4); else if (field.ToLower().Contains(maxTriggerWord.ToLower())) { CurrentScenarioType = maxTriggerWord; unmatched_TriggerWords = unmatched_TriggerWords.Replace(maxTriggerWord, ""); } else if (field.ToLower().Contains(minTriggerWord.ToLower())) { CurrentScenarioType = minTriggerWord.ToLower(); unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + minTriggerWord, ""); } else if (field.ToLower().Contains(rhTriggerWord.ToLower())) { CurrentScenarioType = rhTriggerWord.ToLower(); unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + rhTriggerWord, ""); } else if (field.ToLower().Contains(windSpeedTriggerWord.ToLower())) { CurrentScenarioType = windSpeedTriggerWord.ToLower(); unmatched_TriggerWords = unmatched_TriggerWords.Replace(", " + windSpeedTriggerWord, ""); } //} //if (tempScenarioName != CurrentScenarioName)// firstFlag == false) //{ // tempScenarioName = CurrentScenarioName; // //firstFlag = true; //} //line = reader.ReadLine(); //fields = line.Split(','); } } if (fields[0] == string.Empty && !fields[0].Contains("#")) { line = reader.ReadLine(); fields = line.Split(','); if (fields[0].Contains("TIME")) { line = reader.ReadLine(); fields = line.Split(','); //now fill array //Get the lenght of array according to the number of ecorigions/ // } } if (!fields[0].Contains("#"))//(CurrentScenarioName == tempScenarioName && !fields[0].Contains("#")) { key = fields[0].ToString(); if (CurrentScenarioType.ToLower().Contains(prcpTriggerWord.ToLower())) { IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ //currentSTD = fields[indexofSTD]; climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]) / 10, IndexPrcp_Mean); // /10 is for mm to cm conversion updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexPrcp_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]) / 10, IndexPrcp_STD); //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD); IndexPrcp_Mean = IndexPrcp_Mean + 9; //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; updatedIndex = 0; //IndexSTD = IndexSTD + 6; //indexofSTD++; } } else if (CurrentScenarioType.ToLower().Contains(maxTriggerWord.ToLower())) { IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMaxT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMax_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMaxT_STD); IndexMaxT_Mean = IndexMaxT_Mean + 9; //IndexMax_MaxT = IndexMax_MaxT + 12; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; updatedIndex = 0; //indexofSTD++; //} } } else if (CurrentScenarioType.ToLower().Contains(minTriggerWord.ToLower())) { IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); //set index of max and maxSTD for each ecorigion if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { //currentT = fields[i+1]; //if (indexofSTD < 26) //{ //currentSTD = fields[indexofSTD]; climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexMinT_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; //climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMin_MaxT); //updatedIndex += numberOfAllEcoregions; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexMinT_STD); //climate_Dic[key].SetValue(Convert.ToDouble(currentSTD), IndexSTD); IndexMinT_Mean = IndexMinT_Mean + 9; //IndexMin_MaxT = IndexMin_MaxT + 12; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; updatedIndex = 0; // IndexSTD = IndexSTD + 6; // indexofSTD++; //} } } //----- else if (CurrentScenarioType.ToLower().Contains(rhTriggerWord.ToLower())) { IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexRH_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexRH_STD); IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; updatedIndex = 0; } } //----- else if (CurrentScenarioType.ToLower().Contains(windSpeedTriggerWord.ToLower())) { IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; //IndexSTD = 5; //int indexofSTD = 0; //indexofSTD = fields.Length - (numberOfAllEcoregions); // climate_Dic.Add(key, new double[dicSize]);//{ currentT, currentSTD, 0, 0, 0, 0 }); if (!climate_Dic.Keys.Contains(key)) climate_Dic.Add(key, new double[dicSize]); //set index of max and maxSTD for each ecorigion for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { climate_Dic[key].SetValue(Convert.ToDouble(fields[i + 1]), IndexwindSpeed_Mean); updatedIndex += i + climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_Var); updatedIndex += climateFileActiveEcoregions.Count; climate_Dic[key].SetValue(Convert.ToDouble(fields[updatedIndex + 1]), IndexwindSpeed_STD); IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; updatedIndex = 0; } } } if (reader.EndOfStream)//CurrentScenarioName != tempScenarioName || reader.EndOfStream) { //tempScenarioName = CurrentScenarioName; //Print file for one scenario then clear dictionary to use for another scenario //Monthly peiod centuryPath = "Century_Climate_Inputs_PRISM_Monthly.txt"; //int AverageMaxT = 0; //int AverageMaxSTD = 1; //int AverageMinT = 2; //int AverageMinSTD = 3; //int AveragePrec = 4; //int AveragePrecSTD = 5; IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; //int AverageMaxT = 0; //int AverageMaxSTD = 1; //int AverageMinT = 1; //int AverageMinSTD = 3; //int AveragePrec = 2; //int AveragePrecSTD = 5; using (System.IO.StreamWriter file = new System.IO.StreamWriter(centuryPath, emptytxt)) { if (exportToTxtFormatFile) { file.WriteLine("LandisData" + " \"Climate Data\" \n"); file.WriteLine("ClimateTable \n"); //file.WriteLine(tempScenarioName + "\n"); file.WriteLine(">>Eco" + "\t\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDevPpt" + "\t" + "PAR" + "\t" + "VarT" + "\t" + "VarPpt" + "\n"); file.WriteLine(">>Name" + "\t\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\t" + "(cm)" + "\t" + "(cm)" + "\n"); //file.WriteLine(">>Eco" + "\t" + "Time" + "\t" + "Month" + "\t" + "AvgMinT" + "\t" + "AvgMaxT" + "\t" + "StdDevT" + "\t" + "AvgPpt" + "\t" + "StdDev" + "\t" + "PAR" + "\n"); //file.WriteLine(">>Name" + "\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(k)" + "\t" + "(cm)" + "\t" + "Ppt" + "\t" + "µmol m-2 s-1" + "\n"); //file.WriteLine(">>Eco" + "\t" + "Time" + "\t" + "\t" + "AvgMaxT" + "\t" + "StdMaxT" + "\t" + "AvgMinT" + "\t" + "StdMinT" + "\t" + "AvgPpt" + "\t" + "StdDev" + "\n"); // file.WriteLine(">>Name" + "\t" + "Step" + "\t" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\t" + "(C)" + "\n"); } //initialize currentYear and month currentYear = climate_Dic.First().Key.Substring(0, 4).ToString(); //starting timestep currentTimeS = 0; currentMonth = Convert.ToInt16(climate_Dic.First().Key.Substring(5, 2).ToString()); tempEco = 1; lastYear = climate_Dic.AsEnumerable().Select(ax => Convert.ToInt32(ax.Key.Substring(0, 4).ToString())).Distinct().ToList().Max(); firstYear = climate_Dic.AsEnumerable().Select(ai => Convert.ToInt32(ai.Key.Substring(0, 4).ToString())).Distinct().ToList().Min(); if ((double)climate_Dic.Count / 12 > (double)lastYear - firstYear) lastYear = lastYear - 1; for (int j = firstYear; j <= lastYear; j++) { for (int i = 0; i < climateFileActiveEcoregions.Count; i++) { currentYear = j.ToString(); foreach (KeyValuePair<string, double[]> row in climate_Dic) { if (currentYear == row.Key.Substring(0, 4).ToString()) { if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2))) { AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); sumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]); numberOfDays++; } else { if (exportToTxtFormatFile) file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\n"); //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n"); //tempMonth = currentMonth; currentMonth = Convert.ToInt16(row.Key.Substring(5, 2)); //if (tempMonth != currentMonth) AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; sumVarPpt = 0; numberOfDays = 0; AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); SumPrecp += (Math.Round(row.Value[IndexPrcp_Mean], 2)); AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); sumVarPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]); //sums = 0; //stdTemp = 0; //prpSums = 0; //stdPrp = 0; numberOfDays++; } } else // currentYear != row.Key.Substring(0, 4).ToString()) { //if (tempEco != i && currentMonth == 12) // file.WriteLine("eco" + tempEco.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); if (exportToTxtFormatFile) if (currentMonth == 12) file.WriteLine(climateFileActiveEcoregions.ElementAt(i).Value.Name + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(SumPrecp, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\t" + "0.0" + "\t" + Math.Round(AverageSTDT / numberOfDays, 2) + "\t" + Math.Round(sumVarPpt, 2) + "\n"); ////if (currentTimeS == 0 && currentMonth == 12 && i==2) // file.WriteLine("eco2" + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); //else if (tempEco != i) // currentTimeS = 0; //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMaxT / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n"); //currentYear = row.Key.Substring(0, 4).ToString(); //currentTimeS = currentTimeS + 1; tempEco = i; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; sumVarPpt = 0; numberOfDays = 0; } } tempEco = i; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; sumVarPpt = 0; IndexMaxT_Mean = IndexMaxT_Mean + 9; //IndexMax_MaxT = IndexMax_MaxT + 12; IndexMaxT_Var = IndexMaxT_Var + 9; IndexMaxT_STD = IndexMaxT_STD + 9; IndexMinT_Mean = IndexMinT_Mean + 9; //IndexMin_MaxT = IndexMin_MaxT + 12; IndexMinT_Var = IndexMinT_Var + 9; IndexMinT_STD = IndexMinT_STD + 9; IndexPrcp_Mean = IndexPrcp_Mean + 9; //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; IndexPrcp_Var = IndexPrcp_Var + 9; IndexPrcp_STD = IndexPrcp_STD + 9; IndexRH_Mean = IndexRH_Mean + 9; IndexRH_Var = IndexRH_Var + 9; IndexRH_STD = IndexRH_STD + 9; IndexwindSpeed_Mean = IndexwindSpeed_Mean + 9; IndexwindSpeed_Var = IndexwindSpeed_Var + 9; IndexwindSpeed_STD = IndexwindSpeed_STD + 9; } tempEco = 1; currentTimeS = currentTimeS + 1; IndexMaxT_Mean = 0; //IndexMax_MaxT = 1; IndexMaxT_Var = 1; IndexMaxT_STD = 2; IndexMinT_Mean = 3; //IndexMin_MaxT = 5; IndexMinT_Var = 4; IndexMinT_STD = 5; IndexPrcp_Mean = 6; //IndexPrcp_MaxT = 9; IndexPrcp_Var = 7; IndexPrcp_STD = 8; IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; currentMonth = 1; AverageMax = 0; //AverageMaxSTD = 0; AverageMin = 0; //AverageMinSTD = 0; SumPrecp = 0; //AveragePrecSTD = 0; AverageSTDT = 0; sumVarPpt = 0; } // for (int i = 1; i <= numberOfAllEcoregions; i++) // { // foreach (KeyValuePair<string, double[]> row in climate_Dic) // { // //file.WriteLine("eco" + i.ToString() + "\t" + row.Key.Remove(10) + "\t" + Math.Round(row.Value[AverageMaxT], 2) + "\t" + Math.Round(row.Value[AverageMinT], 2) + "\t" + Math.Round(row.Value[AveragePrec], 2) + "\n"); // //file.WriteLine("eco" + i.ToString() + "\t" + row.Key.Remove(10) + "\t" + Math.Round(row.Value[AverageMaxT], 2) + "\t" + Math.Round(row.Value[AverageMaxSTD], 2) + "\t" + Math.Round(row.Value[AverageMinT], 2) + "\t" + Math.Round(row.Value[AverageMinSTD], 2) + "\t" + Math.Round(row.Value[AveragePrec], 2) + "\t" + Math.Round(row.Value[AveragePrecSTD], 2) + "\n"); // if (currentYear == row.Key.Substring(0, 4).ToString()) // { // if (currentMonth == Convert.ToInt16(row.Key.Substring(5, 2))) // { // //(row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean])/2 // //AverageMin += (row.Value[IndexMin_MaxT] + row.Value[IndexMinT_Mean]) / 2; // //AverageMax += (row.Value[IndexMax_MaxT] + row.Value[IndexMaxT_Mean]) / 2; // //AveragePrecp += (row.Value[IndexPrcp_MaxT] + row.Value[IndexPrcp_Mean]) / 2; // //AverageSTDT += (row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2; // //AverageMaxSTD += Math.Round(Convert.ToDouble(row.Value[2]), 2); // AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); // AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); // AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2); // AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); // StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]); // //AverageMinSTD += Math.Round(Convert.ToDouble(row.Value[4]), 2); // //AveragePrecp += Math.Round(row.Value[AveragePrec], 2); // //AveragePrecSTD += Math.Round(Convert.ToDouble(row.Value[6]), 2); // //Calculating STD of Tempeture // //tempSum[numberOfDays] = (row.Value[AverageMaxT] + row.Value[AverageMinT]) / 2; // //stdTemp = 0; // //stdPrp = 0; // //Calculating STD of Prp // //tempPrp[numberOfDays] = row.Value[AveragePrec]; // numberOfDays++; // } // else // { // //for (int j = 0; j < numberOfDays; j++) // //{ // // sums += Math.Pow((tempSum[j] - (((AverageMax / numberOfDays) + (AverageMin / numberOfDays)) / 2)), 2); // // prpSums += Math.Pow(tempPrp[j] - (AveragePrec / numberOfDays), 2); // //} // //stdTemp = Math.Sqrt(sums / (numberOfDays - 1)); // //stdPrp = Math.Sqrt(prpSums / (numberOfDays - 1)); // file.WriteLine("eco" + i.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); // //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n"); // //tempMonth = currentMonth; // currentMonth = Convert.ToInt16(row.Key.Substring(5, 2)); // //if (tempMonth != currentMonth) // AverageMax = 0; // //AverageMaxSTD = 0; // AverageMin = 0; // //AverageMinSTD = 0; // AveragePrecp = 0; // //AveragePrecSTD = 0; // AverageSTDT = 0; // StdDevPpt = 0; // numberOfDays = 0; // AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); // AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); // AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2); // AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); // StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]); // //sums = 0; // //stdTemp = 0; // //prpSums = 0; // //stdPrp = 0; // numberOfDays++; // } // } // else // { // //If ecorigion has been changed // if (tempEco != i && currentMonth == 12) // { // file.WriteLine("eco" + tempEco.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); // currentTimeS = 0; // } // else if (currentMonth == 12) // { // file.WriteLine("eco" + i.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); // currentTimeS = currentTimeS + 1; // } // else if (tempEco != i) // currentTimeS = 0; // //file.WriteLine("eco1" + "\t" + currentYear + "\t" + currentMonth + "\t" + Math.Round(AverageMaxT / numberOfDays, 2) + "\t" + Math.Round(AverageMaxSTD / numberOfDays, 2) + "\t" + Math.Round(AverageMinT / numberOfDays, 2) + "\t" + Math.Round(AverageMinSTD / numberOfDays, 2) + "\t" + Math.Round(AveragePrec / numberOfDays, 2) + "\t" + Math.Round(AveragePrecSTD / numberOfDays, 2) + "\n"); // currentYear = row.Key.Substring(0, 4).ToString(); // //currentTimeS = currentTimeS + 1; // tempEco = i; // currentMonth = 1; // AverageMax = 0; // //AverageMaxSTD = 0; // AverageMin = 0; // //AverageMinSTD = 0; // AveragePrecp = 0; // //AveragePrecSTD = 0; // AverageSTDT = 0; // StdDevPpt = 0; // numberOfDays = 0; // AverageMin += Math.Round(row.Value[IndexMinT_Mean], 2); // AverageMax += Math.Round(row.Value[IndexMaxT_Mean], 2); // AveragePrecp += Math.Round(row.Value[IndexPrcp_Mean], 2); // AverageSTDT += Math.Round((row.Value[IndexMaxT_Var] + row.Value[IndexMinT_Var]) / 2, 2); // StdDevPpt += Convert.ToDouble(row.Value[IndexPrcp_STD]); // //sums = 0; // //stdTemp = 0; // //prpSums = 0; // //stdPrp = 0; // numberOfDays++; // } // } // IndexMaxT_Mean = IndexMaxT_Mean + 9; // //IndexMax_MaxT = IndexMax_MaxT + 12; // IndexMaxT_Var = IndexMaxT_Var + 9; // IndexMaxT_STD = IndexMaxT_STD + 9; // IndexMinT_Mean = IndexMinT_Mean + 9; // //IndexMin_MaxT = IndexMin_MaxT + 12; // IndexMinT_Var = IndexMinT_Var + 9; // IndexMinT_STD = IndexMinT_STD + 9; // IndexPrcp_Mean = IndexPrcp_Mean + 9; // //IndexPrcp_MaxT = IndexPrcp_MaxT + 12; // IndexPrcp_Var = IndexPrcp_Var + 9; // IndexPrcp_STD = IndexPrcp_STD + 9; // } // file.WriteLine("eco" + numberOfAllEcoregions.ToString() + "\t" + currentTimeS + "\t" + currentMonth + "\t" + Math.Round(AverageMin / numberOfDays, 2) + "\t" + Math.Round(AverageMax / numberOfDays, 2) + "\t" + Math.Round(Math.Sqrt(AverageSTDT / numberOfDays), 2) + "\t" + Math.Round(AveragePrecp / numberOfDays, 2) + "\t" + Math.Round(StdDevPpt, 2) + "\t" + "0.0" + "\n"); } //If file contains more than one scenario then these setting will be needed //climate_Dic.Clear(); //emptytxt = true; //tempScenarioName = CurrentScenarioName; } } if (unmatched_TriggerWords != "") { Climate.ModelCore.UI.WriteLine("Error in ClimateDataConvertor: Converting {0} file into standard format; The following triggerWords did not match the triggerwords in the given file: {1}." + "selected format: \"{2}\"", climateFile, unmatched_TriggerWords, formatProvider.SelectedFormat); throw new ApplicationException("Error in ClimateDataConvertor: Converting " + climateFile + " file into standard format; The following triggerWords did not match the triggerwords in the given file: " + unmatched_TriggerWords + "." + "selected format: \"" + formatProvider.SelectedFormat + "\""); } } #endregion return; // centuryPath; }
// no longer used private static void Convert_USGS_to_ClimateData(TemporalGranularity sourceTemporalGranularity, string climateFile, string climateFileFormat, out List<string> timeStamps, out List<ClimateRecord>[] climateRecords) { // each item in timeStamps is the timeStamp 'key' for the data // each item in climateRecords is of length Climate.ModelCore.Ecoregions.Count, and is filled in with data from the input file, indexed by Ecoregion.Index. timeStamps = new List<string>(); climateRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count]; for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) climateRecords[i] = new List<ClimateRecord>(); // get trigger words for parsing based on file format ClimateFileFormatProvider format = new ClimateFileFormatProvider(climateFileFormat); if (!File.Exists(climateFile)) { throw new ApplicationException("Error in ClimateDataConvertor: Cannot open climate file" + climateFile); } var reader = File.OpenText(climateFile); Climate.ModelCore.UI.WriteLine(" Converting raw data from text file: {0}, Format={1}, Temporal={2}.", climateFile, climateFileFormat.ToLower(), sourceTemporalGranularity); // maps from ecoregion column index in the input file to the ecoregion.index for the region int[] ecoRegionIndexMap = null; var ecoRegionCount = 0; var rowIndex = -1; var sectionIndex = -1; FileSection section = 0; string row; while ((row = reader.ReadLine()) != null) { var fields = row.Replace(" ", "").Split(',').ToList(); // JM: don't know if stripping blanks is needed, but just in case // check for trigger word if (fields[0].StartsWith("#")) { // determine which section we're in var triggerWord = fields[0].TrimStart('#'); // remove the leading "#" if (format.PrecipTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.Precipitation; else if (format.MaxTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.MaxTemperature; else if (format.MinTempTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.MinTemperature; else if (format.NDepositionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.NDeposition; else if (format.WindDirectionTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.Winddirection; else if (format.WindSpeedTriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.Windspeed; else if (format.CO2TriggerWord.FindIndex(x => x.Equals(triggerWord, StringComparison.OrdinalIgnoreCase)) >= 0) section = FileSection.CO2; else throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Unrecognized trigger word '{0}' in climate file '{1}'.", triggerWord, climateFile)); sectionIndex++; // if this is the first section then parse the ecoregions, etc. if (sectionIndex == 0) { // read next line to get ecoregion headers var ecoRegionHeaders = reader.ReadLine().Replace(" ", "").Split(',').ToList(); ecoRegionHeaders.RemoveAt(0); // remove blank cell at the beginning of ecoregion header row // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev ecoRegionCount = ecoRegionHeaders.Count / 3; if (ecoRegionCount == 0) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains no ecoregion data.", climateFile)); var modelCoreActiveEcoRegionCount = Climate.ModelCore.Ecoregions.Count(x => x.Active); if (ecoRegionCount != modelCoreActiveEcoRegionCount) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: climate file '{0}' contains data for {1} ecoregions, but the simulation has {2} active ecoregions.", climateFile, ecoRegionCount, modelCoreActiveEcoRegionCount)); // determine the map from ecoregions in this file to ecoregion indices in ModelCore ecoRegionIndexMap = new int[ecoRegionCount]; for (var i = 0; i < ecoRegionCount; ++i) { IEcoregion eco = Climate.ModelCore.Ecoregions[ecoRegionHeaders[i]]; // JM: Ecoregions appear to be indexed by string name, but I don't know if it is case-sensitive. if (eco != null && eco.Active) ecoRegionIndexMap[i] = eco.Index; else throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Ecoregion name '{0}' in climate file '{1}' is not recognized or is inactive", ecoRegionHeaders[i], climateFile)); } } else // skip ecoregion header line reader.ReadLine(); // skip data headers reader.ReadLine(); // get next line as first line of data fields = reader.ReadLine().Replace(" ", "").Split(',').ToList(); // reset row index rowIndex = -1; } // ** // process line of data ++rowIndex; // grab the key as the first field and remove it from the data var key = fields[0]; fields.RemoveAt(0); // if this is the first section then add key to timestamps and add new climate records for this rowIndex to the ecoregion array if (sectionIndex == 0) { timeStamps.Add(key); for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) climateRecords[i].Add(new ClimateRecord()); } else { // check that the timestamp key order matches if (key != timeStamps[rowIndex]) throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Timestamp order mismatch in section '{0}' timestamp '{1}' in climate file '{2}'.", section, key, climateFile)); } for (var i = 0; i < ecoRegionCount; ++i) { var ecoIndex = ecoRegionIndexMap[i]; var ecoRecords = climateRecords[ecoIndex]; // JM: the next line assumes all input files have exactly three groups of columns: Mean, Variance, Std_dev var mean = double.Parse(fields[i]); var variance = double.Parse(fields[ecoRegionCount + i]); var stdev = double.Parse(fields[2 * ecoRegionCount + i]); switch (section) { case FileSection.Precipitation: ecoRecords[rowIndex].AvgPpt = mean * format.PrecipTransformation; ecoRecords[rowIndex].StdDevPpt = stdev * format.PrecipTransformation; break; case FileSection.MaxTemperature: case FileSection.MinTemperature: mean += format.TemperatureTransformation; if (section == FileSection.MaxTemperature) ecoRecords[rowIndex].AvgMaxTemp = mean; else ecoRecords[rowIndex].AvgMinTemp = mean; // for temperature variance wait until both min and max have been read before calculating the final value if (ecoRecords[rowIndex].AvgVarTemp == -99.0) ecoRecords[rowIndex].AvgVarTemp = variance; // set AvgVarTemp to the first value we have (min or max) else // have both min and max, so average the variance ecoRecords[rowIndex].AvgVarTemp = (ecoRecords[rowIndex].AvgVarTemp + variance) / 2.0; ecoRecords[rowIndex].StdDevTemp = System.Math.Sqrt(ecoRecords[rowIndex].AvgVarTemp); // this will set the st dev even if the data file only has one temperature section break; case FileSection.Winddirection: mean += format.WindDirectionTransformation; if (mean > 360.0) mean -= 360; ecoRecords[rowIndex].AvgWindDirection = mean; ecoRecords[rowIndex].AvgVarWindDirection = variance; ecoRecords[rowIndex].StdDevWindDirection = stdev; break; case FileSection.Windspeed: ecoRecords[rowIndex].AvgWindSpeed = mean * format.WindSpeedTransformation; ecoRecords[rowIndex].AvgVarWindSpeed = variance; ecoRecords[rowIndex].StdDevWindSpeed = stdev; break; case FileSection.NDeposition: ecoRecords[rowIndex].AvgNDeposition = mean; ecoRecords[rowIndex].AvgVarNDeposition = variance; ecoRecords[rowIndex].StdDevNDeposition = stdev; break; case FileSection.CO2: ecoRecords[rowIndex].AvgCO2 = mean; ecoRecords[rowIndex].AvgVarCO2 = variance; ecoRecords[rowIndex].StdDevCO2 = stdev; break; } } } }