//Reads in the forcing file. forcingFileStartDate is used if a VIC //file is being imported to allow the date of each row to be determined //and stored. private void readForcingFile(string forcingFile, ForcingFormat format, DateTime forcingFileStartDate) { DateTime startDate = new DateTime(dates[0].startYear, dates[0].startMonth, 1);//period to be adjusted starts on this date DateTime endDate = new DateTime(dates[0].endYear, dates[0].endMonth, 1); endDate = endDate.AddMonths(1);//period to be adjusted ends on the day before this date switch (format) { case ForcingFormat.VIC: forcingData = readForcingFileVIC(forcingFile, startDate, endDate, forcingFileStartDate); break; case ForcingFormat.DHSVM: forcingData = readForcingFileDHSVM(forcingFile, startDate, endDate); break; case ForcingFormat.GSFLOW: forcingDataGSFLOW = readForcingFileGSFLOW(forcingFile, startDate, endDate); break; default: throw new InvalidEnumArgumentException(); } }
//write out copies of the forcing file, one for each ensemble, adjusting the precip and temp columns in the process private void writeAdjustedForcingFiles(string forcingFile, ForcingFormat format) { switch (format) { case ForcingFormat.VIC: case ForcingFormat.DHSVM: writeAdjustedForcingFilesVICorDHSVM(forcingFile, format); break; case ForcingFormat.GSFLOW: writeAdjustedForcingFilesGSFLOW(forcingFile, format); break; default: throw new InvalidEnumArgumentException(); } }
/// <summary> /// Reads in a forcing file and writes out a copy for each ensemble /// with the precipitation and temperatures adjusted according to the /// ensemble results. /// </summary> /// <param name="forcingFile">The path to the forcing file.</param> /// <param name="VIC">True if VIC, false if DHSVM</param> public void adjustForcingFile(string forcingFile, ForcingFormat format, bool generateDatabase, DateTime forcingFileStartDate = default(DateTime)) { if (outputFolderName == "") { return; } if (format == ForcingFormat.VIC && forcingFileStartDate == default(DateTime)) { return; } //read in forcing file readForcingFile(forcingFile, format, forcingFileStartDate); //write adjusted data to output folder writeAdjustedForcingFiles(forcingFile, format); //generate pisces database if requested //if (generateDatabase) // generatePiscesDatabase(); }
private void writeAdjustedForcingFilesVICorDHSVM(string forcingFile, ForcingFormat format) { findMonthlyValues(format); for (int range = 0; range < dates.Count - 1; range++) { var output = new List <string> [ensembles.Length]; for (int i = 0; i < output.Length; i++) { output[i] = new List <string>(); } int index = 0; MonthlyData monthData = monthlyData[0]; foreach (KeyValuePair <DateTime, double[]> pair in forcingData) { if (format == ForcingFormat.VIC) { if (pair.Key.Day == 1) { monthData = monthlyData[index++]; } //value in vic = Precip, MaxTemp, MinTemp, Wind, AvgTemp; monthData.changeFactors = future date ranges * ensembles * precip, temp for (int ensemble = 0; ensemble < ensembles.Length; ensemble++) { double precip = pair.Value[0]; if (monthData.changeFactors[range, ensemble, 0] != 0)//multiply precip value by change factor if factor is not 0, change factor will be 0 sometimes with summer only { precip *= monthData.changeFactors[range, ensemble, 0]; } output[ensemble].Add(precip.ToString("F04") + "\t" + (pair.Value[1] + monthData.changeFactors[range, ensemble, 1]).ToString("F04") + "\t" + (pair.Value[2] + monthData.changeFactors[range, ensemble, 1]).ToString("F04") + "\t" + pair.Value[3].ToString("F04")); } } else if (format == ForcingFormat.DHSVM) { if (pair.Key.Day == 1 && pair.Key.Hour == 0) { monthData = monthlyData[index++]; } string date = pair.Key.ToString("MM/dd/yyyy-HH"); string glacier = "";//if the DHSVM file has 9 columns, the last column has something to do with glacier lapse rates if (pair.Value.Length == 8) { glacier = pair.Value[7].ToString("F08"); } //value = temp, ?, ?, ?, ?, precip, ?, ?, monthData.changeFactors = future date ranges * ensembles * precip, temp for (int ensemble = 0; ensemble < ensembles.Length; ensemble++) { double precip = pair.Value[5]; if (monthData.changeFactors[range, ensemble, 0] != 0)//multiply precip value by change factor if factor is not 0, change factor will be 0 sometimes with summer only { precip *= monthData.changeFactors[range, ensemble, 0]; } output[ensemble].Add(date + " " + (pair.Value[0] + monthData.changeFactors[range, ensemble, 1]).ToString("F04") + " " + pair.Value[1].ToString("F04") + " " + pair.Value[2].ToString("F04") + " " + pair.Value[3].ToString("F04") + " " + pair.Value[4].ToString("F04") + " " + precip.ToString("F07") + " " + pair.Value[6].ToString("F08") + " " + glacier); } } } for (int ensemble = 0; ensemble < output.Length; ensemble++) { var fname = outputFolderName + "/" + makeValidFileName(ensembles[ensemble].ensembleName) + "_" + dates[range + 1].ToStringWithUnderscores() + "_" + Path.GetFileName(forcingFile); using (TextWriter fileTW = new StreamWriter(fname)) { fileTW.NewLine = "\n"; for (int i = 0; i < output[ensemble].Count; i++) { fileTW.WriteLine(output[ensemble][i]); } } } } }
private void writeAdjustedForcingFilesGSFLOW(string forcingFile, ForcingFormat format) { for (int range = 0; range < dates.Count - 1; range++) { var output = new List <KeyValuePair <DateTime, Dictionary <string, double[]> > > [ensembles.Length]; for (int i = 0; i < ensembles.Length; i++) { output[i] = copyForcingDataGSFLOW(); } //use precip as surrogate for number of grid points to adjust for (int i = 0; i < varsGSFLOW["precip"]; i++) { forcingData = getVIClikeGSFLOWforcingData(i); findMonthlyValues(format); int monthIdx = 0; MonthlyData monthData = monthlyData[0]; int dateIdx = 0; foreach (KeyValuePair <DateTime, double[]> pair in forcingData) { if (pair.Key.Day == 1) { monthData = monthlyData[monthIdx++]; } //values = precip, tmax, tmin, tavg monthData.changeFactors = future date ranges * ensembles * precip, temp for (int ensemble = 0; ensemble < ensembles.Length; ensemble++) { double precip = pair.Value[0]; double precipFactor = monthData.changeFactors[range, ensemble, 0]; double tempFactor = monthData.changeFactors[range, ensemble, 1]; if (precipFactor != 0) //multiply precip value by change factor if factor is not 0, change factor will be 0 sometimes with summer only { precip *= precipFactor; } output[ensemble][dateIdx].Value["precip"][i] = precip; output[ensemble][dateIdx].Value["tmax"][i] = pair.Value[1] + tempFactor; output[ensemble][dateIdx].Value["tmin"][i] = pair.Value[2] + tempFactor; } dateIdx++; } } //write output files to GSFLOW format for (int ensemble = 0; ensemble < ensembles.Length; ensemble++) { var fname = outputFolderName + "/" + makeValidFileName(ensembles[ensemble].ensembleName) + "_" + dates[range + 1].ToStringWithUnderscores() + "_" + Path.GetFileName(forcingFile); using (TextWriter fileTW = new StreamWriter(fname)) { fileTW.NewLine = "\n"; //write header foreach (var line in headerGSFLOW) { fileTW.WriteLine(line); } for (int i = 0; i < output[ensemble].Count; i++) { //write date fileTW.Write(output[ensemble][i].Key.ToString("yyyy M d H m s") + " "); //write each var var numVars = varsOrderedGSFLOW.Count; for (int j = 0; j < numVars; j++) { var var = varsOrderedGSFLOW[j]; var line = string.Join(" ", output[ensemble][i].Value[var].Select(x => x.ToString("F02")).ToArray()); fileTW.Write(line); if (j < numVars - 1) { fileTW.Write(" "); } } fileTW.WriteLine(""); } } } } }
//Creates a list of MonthlyData objects, one for each month, containing data about each month private void findMonthlyValues(ForcingFormat format) { double totalTemp = 0, avgTemp = 0, totalPrecip = 0; int numOfTimePeriodsThisMonth = 0, month = 0, year = 0, index = 0; double[,,] changeFactors;//temporary array to pass to MonthlyData object Dictionary <int, int>[] precipPercentiles, tempPercentiles; int precipPercentile, tempPercentile; List <KeyValuePair <int, double> >[] precipValues = new List <KeyValuePair <int, double> > [12]; //a list of totalPrecip values by month List <KeyValuePair <int, double> >[] tempValues = new List <KeyValuePair <int, double> > [12]; //a list of average temp values by month //initialize lists monthlyData = new List <MonthlyData>(); for (int i = 0; i < 12; i++) { precipValues[i] = new List <KeyValuePair <int, double> >(); tempValues[i] = new List <KeyValuePair <int, double> >(); } //creates a MonthlyData object for each month in forcingData foreach (KeyValuePair <DateTime, double[]> pair in forcingData) { if ((pair.Key.Day == 1 && (format == ForcingFormat.VIC || format == ForcingFormat.GSFLOW)) || (format == ForcingFormat.DHSVM && pair.Key.Day == 1 && pair.Key.Hour == 0)) //new month { if (numOfTimePeriodsThisMonth != 0) { //add new MonthlyData object to monthlyData avgTemp = totalTemp / numOfTimePeriodsThisMonth; monthlyData.Add(new MonthlyData(index, year, month, totalPrecip, avgTemp)); precipValues[month].Add(new KeyValuePair <int, double>(index, totalPrecip)); tempValues[month].Add(new KeyValuePair <int, double>(index, avgTemp)); index++; } //reset variables month = pair.Key.Month - 1; year = pair.Key.Year; numOfTimePeriodsThisMonth = 0; totalTemp = totalPrecip = 0; } switch (format) { case ForcingFormat.VIC: //value = Precip, MaxTemp, MinTemp, Wind, AvgTemp totalPrecip += pair.Value[0]; totalTemp += pair.Value[4]; break; case ForcingFormat.DHSVM: //value = temp, ?, ?, ?, ?, precip, ?, ? totalPrecip += pair.Value[5]; totalTemp += pair.Value[0]; break; case ForcingFormat.GSFLOW: //values = precip, tmax, tmin, tavg totalPrecip += pair.Value[0]; totalTemp += pair.Value[3]; break; default: throw new InvalidEnumArgumentException(); } numOfTimePeriodsThisMonth++; } //add last MonthlyData object to monthlyData avgTemp = totalTemp / numOfTimePeriodsThisMonth; monthlyData.Add(new MonthlyData(index, year, month, totalPrecip, avgTemp)); precipValues[month].Add(new KeyValuePair <int, double>(index, totalPrecip)); tempValues[month].Add(new KeyValuePair <int, double>(index, avgTemp)); //find percentiles precipPercentiles = getPercentiles(precipValues); tempPercentiles = getPercentiles(tempValues); //get data from ProcessData instance ensembles = processor.getEnsembles(); setNamePadding(); //add percentiles change factors to each monthlyData object for (int range = 0; range < dates.Count - 1; range++) { foreach (MonthlyData md in monthlyData) { if (md.changeFactors == null) { changeFactors = new double[dates.Count - 1, ensembles.Length, 2];//ensembles * precip, temp } else { changeFactors = md.changeFactors; } precipPercentile = precipPercentiles[md.month][md.index]; tempPercentile = tempPercentiles[md.month][md.index]; //hDE = 12 months * 49 quantiles .02 - .98 * precip, temp * future periods //fill changeFactors array for (int i = 0; i < ensembles.Length; i++) { ProcessData.Ensemble ensemble = ensembles[i]; //precip changeFactors[range, i, 0] = ensemble.hybridDeltaEnsemble[md.month, precipPercentile, 0, range]; //temp changeFactors[range, i, 1] = ensemble.hybridDeltaEnsemble[md.month, tempPercentile, 1, range]; } //fill in remaining fields in md md.precipPct = precipPercentile; md.tempPct = tempPercentile; md.changeFactors = changeFactors; } } }