/// <summary> /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData /// </summary> /// public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase) { if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily")) { future_allData_granularity = TemporalGranularity.Daily; } else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly")) { future_allData_granularity = TemporalGranularity.Monthly; } else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily")) { spinup_allData_granularity = TemporalGranularity.Daily; } else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly")) { spinup_allData_granularity = TemporalGranularity.Monthly; } if (timeSeries.Contains("Daily")) { ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); } else if (timeSeries.Contains("Monthly")) { ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); } return; }
//------ public ClimateFileFormatProvider(string format) { this.format = format; this.maxTempTriggerWord = "maxtemp"; this.minTempTriggerWord = "mintemp"; this.precipTriggerWord = "ppt"; this.rhTriggerWord = "rh"; this.windSpeedTriggerWord = "windSpeed"; //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily); switch (this.format.ToLower()) { case "ipcc3_daily": //was 'gfdl_a1fi' { this.timeStep = TemporalGranularity.Daily; break; } case "ipcc3_monthly": //ADD { this.timeStep = TemporalGranularity.Monthly; break; } case "ipcc5_monthly": { this.timeStep = TemporalGranularity.Monthly; break; } case "ipcc5_daily": //ADD { this.timeStep = TemporalGranularity.Daily; break; } case "prism_monthly": //was 'prism' { this.timeStep = TemporalGranularity.Monthly; break; } case "Mauer_daily": //was griddedobserved { this.timeStep = TemporalGranularity.Daily; break; } default: { Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format); throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported."); //break; } } }
//------ public ClimateFileFormatProvider(string format) { this.format = format; this.maxTempTriggerWord = "maxtemp"; this.minTempTriggerWord = "mintemp"; this.precipTriggerWord = "ppt"; this.rhTriggerWord = "rh"; this.windSpeedTriggerWord = "windSpeed"; //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily); switch (this.format.ToLower()) { case "ipcc3_daily": //was 'gfdl_a1fi' { this.timeStep = TemporalGranularity.Daily; break; } case "ipcc3_monthly": //ADD { this.timeStep = TemporalGranularity.Monthly; break; } case "ipcc5_monthly": { this.timeStep = TemporalGranularity.Monthly; break; } case "ipcc5_daily": //ADD { this.timeStep = TemporalGranularity.Daily; break; } case "prism_monthly": //was 'prism' { this.timeStep = TemporalGranularity.Monthly; break; } case "Mauer_daily": //was griddedobserved { this.timeStep = TemporalGranularity.Daily; break; } default: { Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format); throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported."); //break; } } }
public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase) { // ** // John McNabb: new parsing code List <int> yearKeys; List <List <ClimateRecord>[]> climateRecords; Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords); Dictionary <int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly if (climatePhase == Climate.Phase.Future_Climate) { allDataRef = Climate.Future_AllData; } if (climatePhase == Climate.Phase.SpinUp_Climate) { allDataRef = Climate.Spinup_AllData; } if (allDataRef == null) { allDataRef = new Dictionary <int, ClimateRecord[][]>(); } else { allDataRef.Clear(); } for (var i = 0; i < yearKeys.Count; ++i) { var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][]; allDataRef[yearKeys[i]] = ecoRecords; for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j) { // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][] ecoRecords[j] = climateRecords[i][j].ToArray(); } } }
//public static void GetPDSI_Test() //{ // IEcoregion ecoregion = Climate.ModelCore.Ecoregions[0]; // //here: // string outputFilePath = @"C:\Program Files\LANDIS-II\v6\examples\base-BDA_1\PDSI_BaseBDA_Test2.csv"; // File.WriteAllText(outputFilePath, String.Empty); // int startYear = 1893, endYear = 1897; // AnnualClimate_Monthly[] acs; // if (endYear > startYear) // { // int numOfYears = endYear - startYear + 1; // acs = new AnnualClimate_Monthly[numOfYears]; // double[] mon_T_normal = new double[12] { 19.693, 23.849, 34.988, 49.082, 60.467, 70.074, 75.505, 73.478, 64.484, 52.634, 36.201, 24.267 }; // IClimateRecord[] climateRecs = new ClimateRecord[12]; // //Climate.TimestepData = allData[0]; // //for (int mo = 0; mo < 12; mo++) // //{ // // climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo]; // // //mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2; // //} // acs[0] = new AnnualClimate_Monthly(ecoregion, 1893, 0); // ((AnnualClimate_Monthly)acs[0]).MonthlyTemp = new double[] { 14.371, 14.000, 26.435, 44.250, 54.645, 70.683, 73.355, 69.323, 63.600, 48.806, 32.867, 19.161 }; // //acs[0].MonthlyPrecip = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // ((AnnualClimate_Monthly)acs[0]).MonthlyPrecip = new double[] { 0.610, 1.500, 1.730, 4.050, 1.950, 0.790, 3.020, 2.570, 1.430, 0.850, 1.260, 2.350 }; // acs[1] = new AnnualClimate_Monthly(ecoregion, 1894, 0); // ((AnnualClimate_Monthly)acs[1]).MonthlyTemp = new double[] { 12.705, 14.979, 37.984, 49.700, 61.209, 71.463, 77.935, 74.312, 65.283, 51.516, 34.767, 29.548 }; // ((AnnualClimate_Monthly)acs[1]).MonthlyPrecip = new double[] { 0.700, 0.550, 0.580, 4.240, 2.430, 1.150, 0.580, 1.480, 0.550, 1.760, 0.050, 1.000 }; // acs[2] = new AnnualClimate_Monthly(ecoregion, 1895, 0); // ((AnnualClimate_Monthly)acs[2]).MonthlyTemp = new double[] { 12.519, 17.964, 33.994, 54.506, 60.411, 66.172, 70.548, 69.622, 65.288, 44.795, 32.433, 23.333 }; // ((AnnualClimate_Monthly)acs[2]).MonthlyPrecip = new double[] { 0.650, 0.540, 0.520, 3.980, 2.380, 6.240, 2.320, 3.920, 4.770, 0.060, 1.040, 0.000 }; // acs[3] = new AnnualClimate_Monthly(ecoregion, 1896, 0); // ((AnnualClimate_Monthly)acs[3]).MonthlyTemp = new double[] { 23.258, 27.397, 26.425, 48.833, 62.790, 68.054, 71.365, 70.677, 57.991, 46.355, 21.154, 28.597 }; // ((AnnualClimate_Monthly)acs[3]).MonthlyPrecip = new double[] { 0.250, 0.270, 1.670, 5.680, 6.240, 7.740, 5.550, 1.660, 1.810, 3.230, 3.850, 0.230 }; // acs[4] = new AnnualClimate_Monthly(ecoregion, 1897, 0); // ((AnnualClimate_Monthly)acs[4]).MonthlyTemp = new double[] { 13.758, 20.179, 26.613, 46.700, 59.016, 66.533, 74.032, 67.928, 71.617, 54.613, 32.450, 18.686 }; // ((AnnualClimate_Monthly)acs[4]).MonthlyPrecip = new double[] { 2.500, 0.540, 3.010, 4.480, 0.980, 5.820, 3.780, 1.600, 1.010, 1.940, 0.910, 2.950 }; // //for (int i = startYear; i <= endYear; i++) // //{ // // acs[i - startYear] = new AnnualClimate(ecoregion, i, 0); // Latitude should be given // // //Climate.ModelCore.UI.WriteLine(ac.MonthlyTemp[0].ToString() + "\n"); // // //Climate.ModelCore.UI.WriteLine(ac.MonthlyPrecip[0].ToString() + "\n"); // //} // //for (int mo = 0; mo < 12; mo++) // //{ // // climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo]; // // mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2; // //} // double AWC = 0.3;//Landis.Extension.Succession.Century.EcoregionData.FieldCapacity[ecoregion] - Landis.Extension.Succession.Century.EcoregionData.WiltingPoint[ecoregion]; // double latitude = 42.60;//Landis.Extension.Succession.Century.EcoregionData.Latitude[ecoregion]; // new PDSI_Calculator().CalculatePDSI(acs, mon_T_normal, AWC, latitude, /*outputFilePath,*/ UnitSystem.USCustomaryUnits); // } /// <summary> /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData /// </summary> /// public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase) { if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily")) { future_allData_granularity = TemporalGranularity.Daily; } else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly")) { future_allData_granularity = TemporalGranularity.Monthly; } else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily")) { spinup_allData_granularity = TemporalGranularity.Daily; } else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly")) { spinup_allData_granularity = TemporalGranularity.Monthly; } if (timeSeries.Contains("Daily")) { ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); } else if (timeSeries.Contains("Monthly")) { ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); } //string readableFile = ""; //if (timeSeries.Contains("MonthlyStandard")) //{ // ModelCore.UI.WriteLine("Loading from file with Monthly Standard format...\n"); // if (future_allData_granularity == TemporalGranularity.Daily) // { // ClimateParser parser = new ClimateParser(); // future_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, parser); // } // else if (future_allData_granularity == TemporalGranularity.Monthly) // { // ClimateParser spinup_parser = new ClimateParser(); // spinup_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, spinup_parser); // } // return; // filePath; //} //else if (timeSeries.Contains("Average") || timeSeries.Contains("Random")) //{ // if (timeSeries.Contains("Daily")) // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); // else if (timeSeries.Contains("Monthly")) // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} //else if (timeSeries.Contains("MonthlyAverage"))//AverageMonthly //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} ////else if (timeSeries.Contains("Random")) ////{ //// if (timeSeries.Contains("Daily")) //// return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, File, fileFormat, climatePhase); //// else if (timeSeries.Contains("Monthly")) //// return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, File, fileFormat, climatePhase); ////} //else if (timeSeries.Contains("DailyGCM")) //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); //} //else if (timeSeries.Contains("MonthlyGCM")) //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} //else //{ // ModelCore.UI.WriteLine("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file."); // throw new Exception("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file."); //} return;// readableFile; }
//------ public ClimateFileFormatProvider(string format) { this.format = format; // default trigger words this.maxTempTriggerWord = new List<string>() { "maxTemp", "Tmax" }; this.minTempTriggerWord = new List<string>() { "minTemp", "Tmin"}; this.precipTriggerWord = new List<string>() { "ppt", "precip", "Prcp" }; this.windDirectionTriggerWord = new List<string>() { "windDirect", "wd", "winddirection", "wind_from_direction" }; this.windSpeedTriggerWord = new List<string>() { "windSpeed", "ws", "wind_speed" }; this.nDepositionTriggerWord = new List<string>() { "Ndeposition", "Ndep" }; this.co2TriggerWord = new List<string>() { "CO2", "CO2conc" }; //IMPORTANT FOR ML: Need to add these as optional trigger words. //this.precipTriggerWord = "Prcp"; // this.maxTempTriggerWord = "Tmax"; // this.minTempTriggerWord = "Tmin"; // Transformations used for all formats that have temps in C and precip in mm this.PrecipTransformation = 0.1; // Assumes data is in mm and so it converts the data from mm to cm. this.TemperatureTransformation = 0.0; // Assumes data is in degrees Celsius so no transformation is needed. this.WindSpeedTransformation = 3.6; //Assumes datas is in m/s so it converts the data to km/h this.WindDirectionTransformation = 180; //Assumes datas is expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO. //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily); switch (this.format.ToLower()) { case "daily_temp-c_precip-mmday": //was 'gfdl_a1fi' then ipcc3_daily this.timeStep = TemporalGranularity.Daily; //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm. break; case "monthly_temp-c_precip-mmmonth": // was ipcc3_monthly this.timeStep = TemporalGranularity.Monthly; //temp data are in oC and precip is in mm. CFFP converts them to cm. break; case "monthly_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 262974.6; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month break; case "daily_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Daily; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 8640.0; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day break; case "monthly_temp-k_precip-mmmonth": //not currently being used on USGS data portal but it's an option nevertheless this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // Temp. data in Kelvin. Precip in mm. CFFP converts them to cm. break; case "daily_temp-k_precip-mmday": // U of Idaho data this.timeStep = TemporalGranularity.Daily; //Temp are in Kelvin and precip is in mm. this.TemperatureTransformation = ABS_ZERO; break; //case "prism_monthly": //was 'prism' // this.timeStep = TemporalGranularity.Monthly; // break; //case "mauer_daily": //was griddedobserved // this.timeStep = TemporalGranularity.Daily; // this.precipTriggerWord = "Prcp"; // this.maxTempTriggerWord = "Tmax"; // this.minTempTriggerWord = "Tmin"; // // RH and wind speed for Mauer are the default trigger words //break; default: Climate.TextLog.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format); throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported."); } }
/// <summary> /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData /// </summary> /// public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase) { if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily")) future_allData_granularity = TemporalGranularity.Daily; else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly")) future_allData_granularity = TemporalGranularity.Monthly; else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily")) spinup_allData_granularity = TemporalGranularity.Daily; else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly")) spinup_allData_granularity = TemporalGranularity.Monthly; if (timeSeries.Contains("Daily")) ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); else if (timeSeries.Contains("Monthly")) ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); return; }
//------ public ClimateFileFormatProvider(string format) { this.format = format; // default trigger words this.maxTempTriggerWord = new List <string>() { "maxTemp", "Tmax" }; this.minTempTriggerWord = new List <string>() { "minTemp", "Tmin" }; this.precipTriggerWord = new List <string>() { "ppt", "precip", "Prcp" }; this.windDirectionTriggerWord = new List <string>() { "windDirect", "wd", "winddirection", "wind_from_direction" }; this.windSpeedTriggerWord = new List <string>() { "windSpeed", "ws", "wind_speed" }; this.windEastingTriggerWord = new List <string>() { "wind_easting", "easting" }; this.windNorthingTriggerWord = new List <string>() { "northing", "wind_northing" }; this.nDepositionTriggerWord = new List <string>() { "Ndeposition", "Ndep" }; this.co2TriggerWord = new List <string>() { "CO2", "CO2conc" }; this.relativeHumidityTriggerWord = new List <string>() { "relative_humidity", "RH" }; this.maxRHTriggerWord = new List <string>() { "max_relative_humidity", "maxRH" }; this.minRHTriggerWord = new List <string>() { "min_relative_humidity", "minRH" }; this.specificHumidityTriggerWord = new List <string>() { "specific_humidity", "SH" }; this.petTriggerWord = new List <string>() { "pet", "PET", "potentialevapotranspiration" }; this.parTriggerWord = new List <string>() { "PAR", "Light" }; this.ozoneTriggerWord = new List <string>() { "ozone", "O3" }; this.shortWaveRadiationTriggerWord = new List <string>() { "shortwave_radiation", "SW_radiation", "SWR" }; this.temperatureTriggerWord = new List <string>() { "Temp", "Temperature" }; //IMPORTANT FOR ML: Need to add these as optional trigger words. //this.precipTriggerWord = "Prcp"; // this.maxTempTriggerWord = "Tmax"; // this.minTempTriggerWord = "Tmin"; // Transformations used for all formats that have temps in C and precip in mm this.PrecipTransformation = 0.1; // Assumes data are in mm and so it converts the data from mm to cm. this.TemperatureTransformation = 0.0; // Assumes data are in degrees Celsius so no transformation is needed. this.WindSpeedTransformation = 3.6; //Assumes data are in m/s so it converts the data to km/h this.WindDirectionTransformation = 180; //Assumes data are expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO. //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily); switch (this.format.ToLower()) { case "daily_temp-c_precip-mmday": //was 'gfdl_a1fi' then ipcc3_daily this.timeStep = TemporalGranularity.Daily; //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm. break; case "monthly_temp-c_precip-mmmonth": // was ipcc3_monthly this.timeStep = TemporalGranularity.Monthly; //temp data are in oC and precip is in mm. CFFP converts them to cm. break; case "monthly_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 262974.6; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month break; case "daily_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Daily; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 8640.0; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day break; case "monthly_temp-k_precip-mmmonth": //not currently being used on USGS data portal but it's an option nevertheless this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // Temp. data in Kelvin. Precip in mm. CFFP converts them to cm. break; case "daily_temp-k_precip-mmday": // U of Idaho data this.timeStep = TemporalGranularity.Daily; //Temp are in Kelvin and precip is in mm. this.TemperatureTransformation = ABS_ZERO; break; default: Climate.TextLog.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format); throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported."); } }
//public static void GetPDSI_Test() //{ // IEcoregion ecoregion = Climate.ModelCore.Ecoregions[0]; // //here: // string outputFilePath = @"C:\Program Files\LANDIS-II\v6\examples\base-BDA_1\PDSI_BaseBDA_Test2.csv"; // File.WriteAllText(outputFilePath, String.Empty); // int startYear = 1893, endYear = 1897; // AnnualClimate_Monthly[] acs; // if (endYear > startYear) // { // int numOfYears = endYear - startYear + 1; // acs = new AnnualClimate_Monthly[numOfYears]; // double[] mon_T_normal = new double[12] { 19.693, 23.849, 34.988, 49.082, 60.467, 70.074, 75.505, 73.478, 64.484, 52.634, 36.201, 24.267 }; // IClimateRecord[] climateRecs = new ClimateRecord[12]; // //Climate.TimestepData = allData[0]; // //for (int mo = 0; mo < 12; mo++) // //{ // // climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo]; // // //mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2; // //} // acs[0] = new AnnualClimate_Monthly(ecoregion, 1893, 0); // ((AnnualClimate_Monthly)acs[0]).MonthlyTemp = new double[] { 14.371, 14.000, 26.435, 44.250, 54.645, 70.683, 73.355, 69.323, 63.600, 48.806, 32.867, 19.161 }; // //acs[0].MonthlyPrecip = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // ((AnnualClimate_Monthly)acs[0]).MonthlyPrecip = new double[] { 0.610, 1.500, 1.730, 4.050, 1.950, 0.790, 3.020, 2.570, 1.430, 0.850, 1.260, 2.350 }; // acs[1] = new AnnualClimate_Monthly(ecoregion, 1894, 0); // ((AnnualClimate_Monthly)acs[1]).MonthlyTemp = new double[] { 12.705, 14.979, 37.984, 49.700, 61.209, 71.463, 77.935, 74.312, 65.283, 51.516, 34.767, 29.548 }; // ((AnnualClimate_Monthly)acs[1]).MonthlyPrecip = new double[] { 0.700, 0.550, 0.580, 4.240, 2.430, 1.150, 0.580, 1.480, 0.550, 1.760, 0.050, 1.000 }; // acs[2] = new AnnualClimate_Monthly(ecoregion, 1895, 0); // ((AnnualClimate_Monthly)acs[2]).MonthlyTemp = new double[] { 12.519, 17.964, 33.994, 54.506, 60.411, 66.172, 70.548, 69.622, 65.288, 44.795, 32.433, 23.333 }; // ((AnnualClimate_Monthly)acs[2]).MonthlyPrecip = new double[] { 0.650, 0.540, 0.520, 3.980, 2.380, 6.240, 2.320, 3.920, 4.770, 0.060, 1.040, 0.000 }; // acs[3] = new AnnualClimate_Monthly(ecoregion, 1896, 0); // ((AnnualClimate_Monthly)acs[3]).MonthlyTemp = new double[] { 23.258, 27.397, 26.425, 48.833, 62.790, 68.054, 71.365, 70.677, 57.991, 46.355, 21.154, 28.597 }; // ((AnnualClimate_Monthly)acs[3]).MonthlyPrecip = new double[] { 0.250, 0.270, 1.670, 5.680, 6.240, 7.740, 5.550, 1.660, 1.810, 3.230, 3.850, 0.230 }; // acs[4] = new AnnualClimate_Monthly(ecoregion, 1897, 0); // ((AnnualClimate_Monthly)acs[4]).MonthlyTemp = new double[] { 13.758, 20.179, 26.613, 46.700, 59.016, 66.533, 74.032, 67.928, 71.617, 54.613, 32.450, 18.686 }; // ((AnnualClimate_Monthly)acs[4]).MonthlyPrecip = new double[] { 2.500, 0.540, 3.010, 4.480, 0.980, 5.820, 3.780, 1.600, 1.010, 1.940, 0.910, 2.950 }; // //for (int i = startYear; i <= endYear; i++) // //{ // // acs[i - startYear] = new AnnualClimate(ecoregion, i, 0); // Latitude should be given // // //Climate.ModelCore.UI.WriteLine(ac.MonthlyTemp[0].ToString() + "\n"); // // //Climate.ModelCore.UI.WriteLine(ac.MonthlyPrecip[0].ToString() + "\n"); // //} // //for (int mo = 0; mo < 12; mo++) // //{ // // climateRecs[mo] = Climate.TimestepData[ecoregion.Index, mo]; // // mon_T_normal[mo] = (climateRecs[mo].AvgMinTemp + climateRecs[mo].AvgMinTemp) / 2; // //} // double AWC = 0.3;//Landis.Extension.Succession.Century.EcoregionData.FieldCapacity[ecoregion] - Landis.Extension.Succession.Century.EcoregionData.WiltingPoint[ecoregion]; // double latitude = 42.60;//Landis.Extension.Succession.Century.EcoregionData.Latitude[ecoregion]; // new PDSI_Calculator().CalculatePDSI(acs, mon_T_normal, AWC, latitude, /*outputFilePath,*/ UnitSystem.USCustomaryUnits); // } /// <summary> /// Converts USGS Data to Standard Input climate Data and fill out the Future_AllData and/or Spinup_AllData /// </summary> /// public static void ConvertFileFormat_FillOutAllData(String timeSeries, string filePath, string fileFormat, Climate.Phase climatePhase) { if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Daily")) future_allData_granularity = TemporalGranularity.Daily; else if (climatePhase == Climate.Phase.Future_Climate && timeSeries.Contains("Monthly")) future_allData_granularity = TemporalGranularity.Monthly; else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Daily")) spinup_allData_granularity = TemporalGranularity.Daily; else if (climatePhase == Climate.Phase.SpinUp_Climate && timeSeries.Contains("Monthly")) spinup_allData_granularity = TemporalGranularity.Monthly; if (timeSeries.Contains("Daily")) ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); else if (timeSeries.Contains("Monthly")) ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //string readableFile = ""; //if (timeSeries.Contains("MonthlyStandard")) //{ // ModelCore.UI.WriteLine("Loading from file with Monthly Standard format...\n"); // if (future_allData_granularity == TemporalGranularity.Daily) // { // ClimateParser parser = new ClimateParser(); // future_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, parser); // } // else if (future_allData_granularity == TemporalGranularity.Monthly) // { // ClimateParser spinup_parser = new ClimateParser(); // spinup_allData = Landis.Data.Load<Dictionary<int, IClimateRecord[,]>>(filePath, spinup_parser); // } // return; // filePath; //} //else if (timeSeries.Contains("Average") || timeSeries.Contains("Random")) //{ // if (timeSeries.Contains("Daily")) // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); // else if (timeSeries.Contains("Monthly")) // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} //else if (timeSeries.Contains("MonthlyAverage"))//AverageMonthly //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} ////else if (timeSeries.Contains("Random")) ////{ //// if (timeSeries.Contains("Daily")) //// return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, File, fileFormat, climatePhase); //// else if (timeSeries.Contains("Monthly")) //// return readableFile = Landis.Library.Climate.ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, File, fileFormat, climatePhase); ////} //else if (timeSeries.Contains("DailyGCM")) //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Daily, filePath, fileFormat, climatePhase); //} //else if (timeSeries.Contains("MonthlyGCM")) //{ // //return readableFile = // ClimateDataConvertor.Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity.Monthly, filePath, fileFormat, climatePhase); //} //else //{ // ModelCore.UI.WriteLine("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file."); // throw new Exception("Error in converting input-climate-file format: invalid ClimateTimeSeries value provided in cliamte-generator input file."); //} return;// readableFile; }
public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase) { //Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly //if (climatePhase == Climate.Phase.Future_Climate) // allDataRef = Climate.Future_AllData; //if (climatePhase == Climate.Phase.SpinUp_Climate) // allDataRef = Climate.Spinup_AllData; //// parse the input file into lists of timestamps and corresponding climate records arrays //List<string> timeStamps; //List<ClimateRecord>[] climateRecords; // indexing: [ecoregion.Count][i] //Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat, out timeStamps, out climateRecords); //// break up the ecoregion lists into a dictionary by year based on timeStamp keys //var yearData = new Dictionary<int, List<ClimateRecord>[]>(); // indexing: [year][ecoregion][i] //var currentYear = -999; //List<ClimateRecord>[] yearRecords = null; //for (var j = 0; j < timeStamps.Count; ++j) //{ // var year = int.Parse(timeStamps[j].Substring(0, 4)); // // timestamps are grouped by year in the input files // if (year != currentYear) // { // // make yearRecords instance for the new year // yearRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count]; // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // yearRecords[i] = new List<ClimateRecord>(); // yearData[year] = yearRecords; // currentYear = year; // } // // add the climate records onto the year records // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // yearRecords[i].Add(climateRecords[i][j]); //} //// transfer the data to allDataRef and //// do some basic error checking //if (allDataRef == null) // allDataRef = new Dictionary<int, ClimateRecord[][]>(); //else // allDataRef.Clear(); //foreach (var key in yearData.Keys) //{ // allDataRef[key] = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][]; // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // { // if (timeStep == TemporalGranularity.Monthly && yearData[key][i].Count != 12) // throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Monthly data for year {0} in climate file '{1}' does not have 12 records. It has {2} records.", key, climateFile, yearData[key][i].Count)); // if (timeStep == TemporalGranularity.Daily && yearData[key][i].Count != 365) // throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Daily data for year {0} in climate file '{1}' does not have 365 records. It has {2} records.", key, climateFile, yearData[key][i].Count)); // // convert the yearRecords from List<ClimateRecord>[] to ClimateRecord[][] // allDataRef[key][i] = yearData[key][i].ToArray(); // } //} // ** // John McNabb: new parsing code List <int> yearKeys; List <List <ClimateRecord>[]> climateRecords; Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords); Dictionary <int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly if (climatePhase == Climate.Phase.Future_Climate) { allDataRef = Climate.Future_AllData; } if (climatePhase == Climate.Phase.SpinUp_Climate) { allDataRef = Climate.Spinup_AllData; } if (allDataRef == null) { allDataRef = new Dictionary <int, ClimateRecord[][]>(); } else { allDataRef.Clear(); } for (var i = 0; i < yearKeys.Count; ++i) { var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][]; allDataRef[yearKeys[i]] = ecoRecords; for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j) { // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][] ecoRecords[j] = climateRecords[i][j].ToArray(); } } }
//-------------------------------------------------------------------- /// <summary> /// This function converts Monthly to Monthly and Daily to Monthly /// </summary> /// <returns>string: file name of the converted monthly file </returns> public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase) { Dictionary<int, IClimateRecord[,]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly if (climatePhase == Climate.Phase.Future_Climate) allDataRef = Climate.Future_AllData; if (climatePhase == Climate.Phase.SpinUp_Climate) allDataRef = Climate.Spinup_AllData; //The Convert conversts the csv file data to a dictionary (of either daily or monthly data) //-------------------------------------------------------------------- //string resultingFileName = Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat); //-------------------------------------------------------------------- //Then read from the dictionary and convert it to IClimate records //if (timeStep == TimeStep.Daily) //{ //setIndexed(checkRHWindSpeed); IndexMaxT_Mean = 0; IndexMaxT_Var = 1; IndexMaxT_STD = 2; IndexMinT_Mean = 3; IndexMinT_Var = 4; IndexMinT_STD = 5; IndexPrcp_Mean = 6; IndexPrcp_Var = 7; IndexPrcp_STD = 8; IndexRH_Mean = 9; IndexRH_Var = 10; IndexRH_STD = 11; IndexwindSpeed_Mean = 12; IndexwindSpeed_Var = 13; IndexwindSpeed_STD = 14; for (int j = firstYear; j <= lastYear; j++)//for each year { currentYear = j.ToString(); //Dictionary<string, double[]> climate_Dic_currentYear = (Dictionary<string, double[]>)climate_Dic.Where(r => r.Key.Substring(0, 4).ToString() == currentYear); IEnumerable<KeyValuePair<string, double[]>> climate_Dic_currentYear = climate_Dic.Where(r => r.Key.Substring(0, 4).ToString() == currentYear); IClimateRecord[,] icrs = new IClimateRecord[Climate.ModelCore.Ecoregions.Count, climate_Dic_currentYear.Count()]; // climate_Dic_currentYear.Count: number of days/months in a year for (int i = 0; i < Climate.ModelCore.Ecoregions.Count; i++) //for each ecoregion either active or inactive { //IClimateRecord icr; List<IClimateRecord> icrList = new List<IClimateRecord>(); int icrCount = 0; foreach (KeyValuePair<string, double[]> row in climate_Dic_currentYear) // foreach day/month in a certain year-ecoregion { IClimateRecord icr = new ClimateRecord(row.Value[IndexMinT_Mean], row.Value[IndexMaxT_Mean], (row.Value[IndexMinT_STD] + row.Value[IndexMaxT_STD]) / 2, row.Value[IndexPrcp_Mean], row.Value[IndexPrcp_STD], 0, (row.Value[IndexMinT_Var] + row.Value[IndexMaxT_Var]) / 2, 0, row.Value[IndexRH_Mean], row.Value[IndexRH_Var], row.Value[IndexRH_STD], row.Value[IndexwindSpeed_Mean], row.Value[IndexwindSpeed_Var], row.Value[IndexwindSpeed_STD]); if (Climate.ModelCore.Ecoregions[i].Active) icrs[i, icrCount++] = icr;//new KeyValuePair<int, IClimateRecord>(i, icr); } } allDataRef.Add(j, icrs); } return;// resultingFileName; }
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; }
public static void Convert_USGS_to_ClimateData_FillAlldata(TemporalGranularity timeStep, string climateFile, string climateFileFormat, Climate.Phase climatePhase) { //Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly //if (climatePhase == Climate.Phase.Future_Climate) // allDataRef = Climate.Future_AllData; //if (climatePhase == Climate.Phase.SpinUp_Climate) // allDataRef = Climate.Spinup_AllData; //// parse the input file into lists of timestamps and corresponding climate records arrays //List<string> timeStamps; //List<ClimateRecord>[] climateRecords; // indexing: [ecoregion.Count][i] //Convert_USGS_to_ClimateData(timeStep, climateFile, climateFileFormat, out timeStamps, out climateRecords); //// break up the ecoregion lists into a dictionary by year based on timeStamp keys //var yearData = new Dictionary<int, List<ClimateRecord>[]>(); // indexing: [year][ecoregion][i] //var currentYear = -999; //List<ClimateRecord>[] yearRecords = null; //for (var j = 0; j < timeStamps.Count; ++j) //{ // var year = int.Parse(timeStamps[j].Substring(0, 4)); // // timestamps are grouped by year in the input files // if (year != currentYear) // { // // make yearRecords instance for the new year // yearRecords = new List<ClimateRecord>[Climate.ModelCore.Ecoregions.Count]; // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // yearRecords[i] = new List<ClimateRecord>(); // yearData[year] = yearRecords; // currentYear = year; // } // // add the climate records onto the year records // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // yearRecords[i].Add(climateRecords[i][j]); //} //// transfer the data to allDataRef and //// do some basic error checking //if (allDataRef == null) // allDataRef = new Dictionary<int, ClimateRecord[][]>(); //else // allDataRef.Clear(); //foreach (var key in yearData.Keys) //{ // allDataRef[key] = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][]; // for (var i = 0; i < Climate.ModelCore.Ecoregions.Count; ++i) // { // if (timeStep == TemporalGranularity.Monthly && yearData[key][i].Count != 12) // throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Monthly data for year {0} in climate file '{1}' does not have 12 records. It has {2} records.", key, climateFile, yearData[key][i].Count)); // if (timeStep == TemporalGranularity.Daily && yearData[key][i].Count != 365) // throw new ApplicationException(string.Format("Error in ClimateDataConvertor: Daily data for year {0} in climate file '{1}' does not have 365 records. It has {2} records.", key, climateFile, yearData[key][i].Count)); // // convert the yearRecords from List<ClimateRecord>[] to ClimateRecord[][] // allDataRef[key][i] = yearData[key][i].ToArray(); // } //} // ** // John McNabb: new parsing code List<int> yearKeys; List<List<ClimateRecord>[]> climateRecords; Convert_USGS_to_ClimateData2(timeStep, climateFile, climateFileFormat, out yearKeys, out climateRecords); Dictionary<int, ClimateRecord[][]> allDataRef = null; //this dictionary is filled out either by Daily data or Monthly if (climatePhase == Climate.Phase.Future_Climate) allDataRef = Climate.Future_AllData; if (climatePhase == Climate.Phase.SpinUp_Climate) allDataRef = Climate.Spinup_AllData; if (allDataRef == null) allDataRef = new Dictionary<int, ClimateRecord[][]>(); else allDataRef.Clear(); for (var i = 0; i < yearKeys.Count; ++i) { var ecoRecords = new ClimateRecord[Climate.ModelCore.Ecoregions.Count][]; allDataRef[yearKeys[i]] = ecoRecords; for (var j = 0; j < Climate.ModelCore.Ecoregions.Count; ++j) { // convert the parsed climateRecords for this year from List<ClimateRecord>[] to ClimateRecord[][] ecoRecords[j] = climateRecords[i][j].ToArray(); } } }
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; }
// 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; } } } }
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; }
// 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; } } } }
//------ public ClimateFileFormatProvider(string format) { this.format = format; // default trigger words this.maxTempTriggerWord = new List <string>() { "maxTemp", "Tmax" }; this.minTempTriggerWord = new List <string>() { "minTemp", "Tmin" }; this.precipTriggerWord = new List <string>() { "ppt", "precip", "Prcp" }; this.windDirectionTriggerWord = new List <string>() { "windDirect", "wd", "winddirection", "wind_from_direction" }; this.windSpeedTriggerWord = new List <string>() { "windSpeed", "ws", "wind_speed" }; this.nDepositionTriggerWord = new List <string>() { "Ndeposition", "Ndep" }; this.co2TriggerWord = new List <string>() { "CO2", "CO2conc" }; //IMPORTANT FOR ML: Need to add these as optional trigger words. //this.precipTriggerWord = "Prcp"; // this.maxTempTriggerWord = "Tmax"; // this.minTempTriggerWord = "Tmin"; // Transformations used for all formats that have temps in C and precip in mm this.PrecipTransformation = 0.1; // Assumes data is in mm and so it converts the data from mm to cm. this.TemperatureTransformation = 0.0; // Assumes data is in degrees Celsius so no transformation is needed. this.WindSpeedTransformation = 3.6; //Assumes datas is in m/s so it converts the data to km/h this.WindDirectionTransformation = 180; //Assumes datas is expressed as the direction the wind comes FROM so it converts it to the direction where wind is blowing TO. //this.timeStep = ((this.format == "PRISM") ? TemporalGranularity.Monthly : TemporalGranularity.Daily); switch (this.format.ToLower()) { case "daily_temp-c_precip-mmday": //was 'gfdl_a1fi' then ipcc3_daily this.timeStep = TemporalGranularity.Daily; //temp data are in oC and precip is in mm. CFFP (climate file format provider, L62) converts them to cm. break; case "monthly_temp-c_precip-mmmonth": // was ipcc3_monthly this.timeStep = TemporalGranularity.Monthly; //temp data are in oC and precip is in mm. CFFP converts them to cm. break; case "monthly_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 262974.6; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / month break; case "daily_temp-k_precip-kgm2sec": //ipcc5 option this.timeStep = TemporalGranularity.Daily; this.TemperatureTransformation = ABS_ZERO; // ipcc5 temp. data are in Kelvin. this.PrecipTransformation = 8640.0; // ipcc5 precip. data are in kg / m2 / sec -> convert to cm / day break; case "monthly_temp-k_precip-mmmonth": //not currently being used on USGS data portal but it's an option nevertheless this.timeStep = TemporalGranularity.Monthly; this.TemperatureTransformation = ABS_ZERO; // Temp. data in Kelvin. Precip in mm. CFFP converts them to cm. break; case "daily_temp-k_precip-mmday": // U of Idaho data this.timeStep = TemporalGranularity.Daily; //Temp are in Kelvin and precip is in mm. this.TemperatureTransformation = ABS_ZERO; break; //case "prism_monthly": //was 'prism' // this.timeStep = TemporalGranularity.Monthly; // break; //case "mauer_daily": //was griddedobserved // this.timeStep = TemporalGranularity.Daily; // this.precipTriggerWord = "Prcp"; // this.maxTempTriggerWord = "Tmax"; // this.minTempTriggerWord = "Tmin"; // // RH and wind speed for Mauer are the default trigger words //break; default: Climate.ModelCore.UI.WriteLine("Error in ClimateFileFormatProvider: the given \"{0}\" file format is not supported.", this.format); throw new ApplicationException("Error in ClimateFileFormatProvider: the given \"" + this.format + "\" file format is not supported."); } }