This page contains the main body and utility methods of OpenTemp.cs
Use the links below for the input methods:
Use the links below for the analysis methods:
CalculateMonthlyAverages()
CalculateSeriesOffsets()
_MeshUSALower48()
Use these links for the ouput methods:
WriteStationResults()
WriteCellStationResults()
WriteCellInfo()
WriteSeriesOffsets()
WriteMonthlyResults()
WriteYearlyResults()
// =====
// Copyright 2007 John Van Vliet, all rights reserved
// Here’s my simple license, soon to be replaced by a proper license.
// What you can do:
// - read the code
// - play with the code
// - run the code
// - modify the code
// What you can’t do:
// - re-publish the original code or any modified versions
// =====
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Text;
namespace OpenTemp
{
/// <summary>
/// The OpenTemp program processes station, temperature, and region files to generate temperature trends.
/// </summary>
/// <remarks>
/// <para>The program is currently hard-coded for the USA lower-48.</para>
/// </remarks>
class OpenTemp
{
string _dataFile;
string _stationsFile;
static string _outputStationFile;
static string _outputSeriesOffsetsFile;
static string _outputCellFile;
static string _outputCellStationsFile;
static string _outputMonthlyFile;
static string _outputYearlyFile;
static string _logFile;
static GraphicsPath _regionGraphicsPath;
static StreamWriter _logSW;
Dictionary<string, Station> _stations;
List<Cell> _cells;
SortedList<DateTime, float> _monthlyAverages;
float _cellSize = 0.5f; // mesh size in degrees of latitude and longitude
float _averagingRadius = 1000.0f; // number of kilometers for averaging region
/// <summary>
/// Program entry point. Process command line parameters and coordinate processing.
/// </summary>
static int Main(string[] args)
{
string dataFile = “”; // Name of the GHCN file to read
string stationsFile = “”; // Name of the file with a list of stations
bool writeStations = false;
bool writeCells = false;
bool writeCellStations = false;
bool writeMonthly = false;
bool writeYearly = false;
bool useOffsets = false;
int status;
// Output file names
DateTime now = DateTime.Now;
_outputStationFile = “station.csv”;
_outputCellFile = “cell.csv”;
_outputCellStationsFile = “cellstation.csv”;
_outputSeriesOffsetsFile = “offsets.csv”;
_outputMonthlyFile = “monthly.csv”;
_outputYearlyFile = “yearly.csv”;
_logFile = “opentemp.log”;
// Open log file
using (_logSW = new StreamWriter(_logFile, false))
{
// Parse command-line arguments
foreach (string arg in args)
{
if (arg.StartsWith(@”/ghcn=”))
{
dataFile = arg.Substring(6);
}
else if (arg.StartsWith(@”/stn=”))
{
stationsFile = arg.Substring(5);
}
else if (arg.StartsWith(@”/offset”))
{
useOffsets = true;
}
else if (arg.StartsWith(@”/os”))
{
writeStations = true;
}
else if (arg.StartsWith(@”/ocs”)) // note: must come before “-oc” because of StartsWith()
{
writeCellStations = true;
}
else if (arg.StartsWith(@”/oc”))
{
writeCells = true;
}
else if (arg.StartsWith(@”/om”))
{
writeMonthly = true;
}
else if (arg.StartsWith(@”/oy”))
{
writeYearly = true;
}
else
{
OpenTemp.WriteLine(string.Format(”!!! Unrecognized command-line parameter ‘{0}’”, arg));
}
}
if ((dataFile.Length == 0) || (stationsFile.Length == 0))
{
OpenTemp.WriteLine(”Usage:”);
OpenTemp.WriteLine(” GHCNParser /ghcn=[GHCN] /stn=[stations] /rgn=[region] {/offset} {/os} {/oc} {/ocs} {/oo} {/om} {/oy}”);
OpenTemp.WriteLine(” where”);
OpenTemp.WriteLine(” [GHCN] is the name of the GHCN data file to read”);
OpenTemp.WriteLine(” (GHCNv2 monthly data files are supported)”);
OpenTemp.WriteLine(” [stations] is the name of a file with a list of stations to analyze”);
OpenTemp.WriteLine(” (one station per line with: stationID, latitude, longitude)”);
OpenTemp.WriteLine(” [rgn] NOT IMPLEMENTED: is the name of a file that defines the regions to be analyzed”);
OpenTemp.WriteLine(” (currently the program is hard-coded to analyze the USA lower 48)”);
OpenTemp.WriteLine(” {/offset} true to calculate and use series offsets to the region average”);
OpenTemp.WriteLine(” (offsets will be written to offsets.csv)”);
OpenTemp.WriteLine(” {/os} include this flag to write station details for all requested stations”);
OpenTemp.WriteLine(” {/oc} include this flag to write cell data for the region (cell location and size)”);
OpenTemp.WriteLine(” {/ocs} include this flag to write cell-stations (stations that can affect each cell)”);
OpenTemp.WriteLine(” {/om} include this flag to write monthly averages for each region”);
OpenTemp.WriteLine(” {/oy} include this flag to write yearly averages for each region”);
OpenTemp.WriteLine();
OpenTemp.WriteLine(”Results will be written to data files with the following names:”);
OpenTemp.WriteLine(” monthly.csv contains monthly overall averages for each region”);
OpenTemp.WriteLine(” yearly.csv contains yearly overall averages for each region”);
OpenTemp.WriteLine(” station.csv contains monthly readings for every station in a convenient format”);
OpenTemp.WriteLine(” cell.csv contains cell information for the entire region”);
OpenTemp.WriteLine(” cellstation.csv contains cell-station interaction results”);
OpenTemp.WriteLine(” offsets.csv contains the static offsets applied to each series”);
OpenTemp.WriteLine(” opentemp.log contains a complete processing log (same as console output)”);
OpenTemp.WriteLine();
OpenTemp.WriteLine(”Notes:”);
OpenTemp.WriteLine(” - Each output file is written only if the appropriae /o option is used”);
OpenTemp.WriteLine(” - If the /offset option is used:”);
OpenTemp.WriteLine(” - Monthly and yearly data includes a static offset applied to each series”);
OpenTemp.WriteLine(” (Offset is equal to the average difference between the series and the monthly averages)”);
OpenTemp.WriteLine(” - The offsets.csv file is written if the /offset option is used”);
Console.ReadKey();
return -1;
}
// Parsing object
OpenTemp parser = new OpenTemp(dataFile, stationsFile);
// Parse stations file
if (writeStations || writeCellStations || writeYearly || writeMonthly || useOffsets)
{
status = parser.ParseStations();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when parsing stations file”, status));
Console.ReadKey();
return status;
}
}
// Parse data file
if (writeMonthly || writeYearly || writeStations || writeCellStations || useOffsets)
{
status = parser.ParseGHCNv2();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when parsing data file”, status));
Console.ReadKey();
return status;
}
}
// Write station results
if (writeStations)
{
status = parser.WriteStationResults();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing station output file”, status));
Console.ReadKey();
return status;
}
}
// Generate mesh
if (writeCells || writeCellStations || writeYearly || writeMonthly || useOffsets)
{
status = parser._MeshUSALower48();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when generating mesh for the USA lower 48″, status));
Console.ReadKey();
return status;
}
}
// Write cell information to file
if (writeCells)
{
status = parser.WriteCellInfo();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing cell data”, status));
Console.ReadKey();
return status;
}
}
// Write cell-stations to file
if (writeCellStations)
{
status = parser.WriteCellStationResults();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing cell-station results”, status));
Console.ReadKey();
return status;
}
}
// Compute overall average for every month
if (writeMonthly || writeYearly || useOffsets)
{
status = parser.CalculateMonthlyAverages(false);
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when calculating overall monthly averages”, status));
Console.ReadKey();
return status;
}
}
// Compute overall offset for each series
// (Compensates for the introduction or removal of stations with average temperatures different than the overall average)
if (writeMonthly || writeYearly || useOffsets)
{
status = parser.CalculateSeriesOffsets();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when calculating offsets for each series”, status));
Console.ReadKey();
return status;
}
}
// Write series offsets
if (useOffsets)
{
status = parser.WriteSeriesOffsets();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing series offsets file”, status));
Console.ReadKey();
return status;
}
}
// Re-calculate overall average for every month including series offsets
if (useOffsets)
{
status = parser.CalculateMonthlyAverages(true);
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when calculating overall monthly averages”, status));
Console.ReadKey();
return status;
}
}
// Write monthly results
if (writeMonthly)
{
status = parser.WriteMonthlyResults();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing monthly output file”, status));
Console.ReadKey();
return status;
}
}
// Write yearly results
if (writeYearly)
{
status = parser.WriteYearlyResults();
if (status < 0)
{
OpenTemp.WriteLine(”!!!”);
OpenTemp.WriteLine(string.Format(”ERROR <{0}> when writing yearly output file”, status));
Console.ReadKey();
return status;
}
}
// Done
//parser.Close();
OpenTemp.Write(”Press any key to continue”);
Console.ReadKey();
return 0;
} // using StreamWriter
}
/// <summary>
/// Append a string to the console output and log file.
/// </summary>
internal static void Write(string msg)
{
Console.Write(msg);
_logSW.Write(msg);
}
/// <summary>
/// Append a string to the console output and log file, followed by a new line.
/// </summary>
internal static void WriteLine(string msg)
{
Console.WriteLine(msg);
_logSW.WriteLine(msg);
}
/// <summary>
/// Append a newline to the console output and log file.
/// </summary>
internal static void WriteLine()
{
Console.WriteLine();
_logSW.WriteLine();
}
/// <summary>
/// Constructor.
/// </summary>
OpenTemp(string dataFile, string stationsFile)
{
_dataFile = dataFile;
_stationsFile = stationsFile;
_stations = new Dictionary<string, Station>();
_cells = new List<Cell>();
_monthlyAverages = new SortedList<DateTime, float>();
}