GHCN Code

GHCN.cpp  GHCN.h Main.cpp Makefile getdaily.tcsh stations.txt

Everything you need is there, but you will need to put some effort into figuring it out. WordPress messes up the formatting.

I’m not getting paid for software support (or anything else.) LOL

//————————————————————————————–
// GHCN.cpp
// Code for parsing and processing daily GHCN data
// Written by Steve Goddard
// If you modify it and mess it up, don’t blame it on me

#include “GHCN.h”

extern size_t most_recent_year;

void
DataRecord::setHighTemperature(unsigned int day_of_month, float value)
{
getDailyHighTemperatureVector()[day_of_month] = value;
}

void
DataRecord::setLowTemperature(unsigned int day_of_month, float value)
{
getDailyLowTemperatureVector()[day_of_month] = value;
}

void
DataRecord::setSnowfall(unsigned int day_of_month, float value)
{
getDailySnowVector()[day_of_month] = value;
}

void
DataRecord::setPrecipitation(unsigned int day_of_month, float value)
{
getDailyPrecipitationVector()[day_of_month] = value;
}

void
DataRecord::parseTemperatureRecord(std::string record_string)
{
/*
——————————
Variable Columns Type
——————————
ID 1-11 Character
YEAR 12-15 Integer
MONTH 16-17 Integer
ELEMENT 18-21 Character
VALUE1 22-26 Integer
MFLAG1 27-27 Character
QFLAG1 28-28 Character
SFLAG1 29-29 Character
VALUE2 30-34 Integer
MFLAG2 35-35 Character
QFLAG2 36-36 Character
SFLAG2 37-37 Character
. . .
. . .
. . .
VALUE31 262-266 Integer
MFLAG31 267-267 Character
QFLAG31 268-268 Character
SFLAG31 269-269 Character
——————————
*/

size_t position = 0;

if (record_string.length() < 269)
{
return;
}

setStateNumber(1);

std::string station_number = record_string.substr(0, 11);
setStationNumber(station_number);
std::string country_abbreviation = record_string.substr(0, 2);
setCountryAbbreviation(country_abbreviation);
//std::string state_name = getStateName();
unsigned int year = strtoul( record_string.substr(11, 4).c_str(), NULL, 10 );

if (year > most_recent_year)
{
most_recent_year = year;
}

setYear(year);
unsigned int month = strtoul( record_string.substr(15, 2).c_str(), NULL, 10 );
setMonth(month);
std::string record_type = record_string.substr(17, 4);
setRecordTypeString(record_type);

position = 21;

for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++)
{
std::string value_string = record_string.substr(position, 5);
long value = strtol( value_string.c_str(), NULL, 10 );

if ( getRecordTypeString() == “TMIN” )
{
getDailyLowTemperatureVector()[i] = (value == -9999) ? UNKNOWN_TEMPERATURE : float(value) / 10.0f;
}
else if ( getRecordTypeString() == “TMAX” )
{
getDailyHighTemperatureVector()[i] = (value == -9999) ? UNKNOWN_TEMPERATURE : float(value) / 10.0f;
}
else if ( getRecordTypeString() == “SNOW” )
{
getDailySnowVector()[i] = (value == -9999) ? UNKNOWN_TEMPERATURE : float(value) / 10.0f;
}
else if ( getRecordTypeString() == “PRCP” )
{
getDailyPrecipitationVector()[i] = (value == -9999) ? UNKNOWN_TEMPERATURE : float(value) / 100.0f;
}

position += 8;
}
}
//————————————————————————————–
// Main.cpp
// Code for parsing and processing daily GHCN data from
// ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd_hcn.tar.gz
// Written by Steve Goddard
// If you modify it and mess it up, don’t blame it on me

// The algorthim for locating records has no time bias.
// All years which share in the min or max record get counted.
// You can run the algorithm forwards, backwards or randomly
// and you will always get the same result.

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <map>

#include “GHCN.h”

std::map<size_t, bool> months_under_test_map;
size_t most_recent_year = 0;

bool stationActiveForTheEntireDateRange(int start_date_for_records, std::vector<Year>& year_vector)
{
if ( (start_date_for_records == 0)
|| (year_vector.at(0).getYear() <= (size_t)start_date_for_records &&
year_vector.at( year_vector.size() – 1).getYear() >= (most_recent_year – 1) )
)
{
return true;
}

return false;
}
int main (int argc, char** argv)
{

if (argc < 2)
{
std::cerr << “Usage : ghcn.exe GHCN_DATA_FILE_NAME [month=0-12] [year=YYYY] [date=MODY] [dump=MODYYEAR]” << std::endl;
return (1);
}

std::string input_file_name_string = argv[1];

size_t year_under_test = 0;
size_t month_under_test = 0;
size_t months_under_test = 1;
size_t month_to_dump = 0;
size_t day_to_dump = 0;
size_t year_to_dump = 0;
std::string state_under_test = “”;
int temperature_threshold = 40;
int number_of_months_under_test = 12;
std::string station_under_test = “”;
int start_date_for_records = 0;
bool test_only_airports = false;
bool test_only_non_airports = false;

for (int i = 2; i < argc; i++)
{
std::string argument_string = std::string( argv[i] );

if ( argument_string.find(“year=”) != std::string::npos )
{
std::string year_string = argument_string.substr(5, 4);
year_under_test = (size_t)strtol(year_string.c_str(), NULL, 10);
std::cout << year_string << std::endl;
std::cerr << year_string << std::endl;
}
else if ( argument_string.find(“month=”) != std::string::npos )
{
std::string month_string = argument_string.substr(6, 4);
month_under_test = (size_t)strtol(month_string.c_str(), NULL, 10);
months_under_test_map[month_under_test] = true;
std::cout << month_string << std::endl;
std::cerr << month_string << std::endl;
}
else if ( argument_string.find(“months=”) != std::string::npos )
{
std::string months_string = argument_string.substr(7, 2);
months_under_test = (size_t)strtol(months_string.c_str(), NULL, 10);
std::cout << “Number of months ” << months_under_test << std::endl;
std::cerr << “Number of months ” << months_under_test << std::endl;

for (size_t i = 0; i < months_under_test; i++)
{
size_t valid_month = ( month_under_test + i ) % 12;
valid_month = (valid_month == 0) ? 12 : valid_month;
months_under_test_map[valid_month] = true;
std::cerr << “Month under test ” << valid_month << std::endl;
}
}
else if ( argument_string.find(“state=”) != std::string::npos )
{
state_under_test = argument_string.substr(6, 2);
}
else if ( argument_string.find(“station=”) != std::string::npos )
{
station_under_test = argument_string.substr(8, 6);
std::cout << “Station under test = ” << station_under_test << std::endl;
std::cerr << “Station under test = ” << station_under_test << std::endl;
}
else if ( argument_string.find(“period=”) != std::string::npos )
{
size_t length = argument_string.size();
std::string period_string = argument_string.substr(7, length – 7);
number_of_months_under_test = (int)strtol(period_string.c_str(), NULL, 10);
std::cout << period_string << std::endl;
std::cerr << period_string << std::endl;
}
else if ( argument_string.find(“threshold=”) != std::string::npos )
{
size_t length = argument_string.size();
std::string threshold_string = argument_string.substr(10, length – 10);
temperature_threshold = (int)strtol(threshold_string.c_str(), NULL, 10);
std::cout << “Temperature threshold = ” << temperature_threshold << std::endl;
std::cerr << “Temperature threshold = ” << temperature_threshold << std::endl;
}
else if ( argument_string.find(“start=”) != std::string::npos )
{
size_t length = argument_string.size();
std::string start_string = argument_string.substr(6, length – 4);
start_date_for_records = (int)strtol(start_string.c_str(), NULL, 10);
std::cout << “Records must include ” << start_string << std::endl;
std::cerr << “Records must include ” << start_string << std::endl;
}
else if ( argument_string.find(“airports=”) != std::string::npos )
{
std::string yes_string = argument_string.substr(9, 1);

if ( yes_string == “y” )
{
test_only_airports = true;
std::cout << “Airports only” << std::endl;
std::cerr << “Airports only” << std::endl;
}

if ( yes_string == “n” )
{
test_only_non_airports = true;
std::cout << “No airports” << std::endl;
std::cerr << “No airports” << std::endl;
}
}
else if ( argument_string.find(“date=”) != std::string::npos )
{
std::string dump_date_string = argument_string.substr(5, 4);
month_to_dump = (size_t)strtol(dump_date_string.substr(0, 2).c_str(), NULL, 10);
day_to_dump = (size_t)strtol(dump_date_string.substr(2, 2).c_str(), NULL, 10);

if ( argument_string.size() == 13 )
{
year_to_dump = (size_t)strtol(argument_string.substr(9, 4).c_str(), NULL, 10);
}
}
}

size_t number_of_countries = sizeof(COUNTRY_NAMES) / (MAX_STATE_NAME_LENGTH * 2);

std::map<std::string, std::string> country_name_map;

for (size_t i = 0; i < number_of_countries; i++)
{
country_name_map[ COUNTRY_NAMES[i][0] ] = COUNTRY_NAMES[i][1];
}

// Read in the station information
std::map<std::string, std::string> station_name_map;
std::map<std::string, std::string> state_name_map;
std::string record_string;
// ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt
std::ifstream ghcn_station_file(“ghcnd-stations.txt”);

if ( ghcn_station_file.is_open() )
{
while ( ghcn_station_file.good() )
{
getline(ghcn_station_file, record_string);

if (record_string.length() < 85)
{
continue;
}

std::string station_number = record_string.substr(0, 11);
std::string state_name = record_string.substr(38, 2);
std::string station_name = record_string.substr(41, 35);
station_name_map[station_number] = station_name;

if ( station_number.substr(0, 2) == “US”)
{
state_name_map[station_number] = state_name;
}
}

ghcn_station_file.close();
}
else
{
std::cout << “Unable to open ghcnd-stations.txt” << std::endl;
}

// read in the station data

std::ifstream ushcn_data_file( input_file_name_string.c_str() );

Country country;
std::string current_station_number = “”;
unsigned int current_state_number = UINT_MAX;
unsigned int current_year_number = 0;
bool check_ushcn_2 = true;
bool check_ghcn = true;

// Read in the temperature database
if ( ushcn_data_file.is_open() )
{
while ( ushcn_data_file.good() )
{
getline(ushcn_data_file, record_string);

char* record_char_string = (char*)record_string.c_str();

if (check_ghcn && record_char_string[0] < ‘A’ || record_char_string[0] > ‘Z’ )
{
continue;
}

DataRecord record;
record.parseTemperatureRecord(record_string);

// Uncomment this if you want to see the station info printed as the file is parsed
#if 0
if ( record.getYear() == most_recent_year )
{
std::cout << record.getStateName() << ” ” << record.getStationNumber() << ” “;
std::cout << station_name_map[ record.getStationNumber() ];
std::cout << ” ” << record.getRecordTypeString();
std::cout << ” ” << record.getMonth();
std::cout << ” ” << record.getYear();
std::cout << std::endl;
}
#endif
// Build the database

bool state_changed = false;

// Look for a new state
if ( record.getStateNumber() != current_state_number )
{
state_changed = true;
current_state_number = record.getStateNumber();
std::cerr << country_name_map[ record.getCountryAbbreviation() ] << std::endl;
std::cout << country_name_map[ record.getCountryAbbreviation() ] << std::endl;
country.getStateVector().at(current_state_number – 1).setStateNumber(current_state_number);
}

bool station_changed = false;

// Look for a new station
if ( record.getStationNumber() != current_station_number || state_changed)
{
std::string old_station_number = current_station_number;
station_changed = true;
current_station_number = record.getStationNumber();

if ( station_under_test != “” )
{
if ( current_station_number.find(station_under_test) == std::string::npos )
{
current_station_number = old_station_number;
continue;
}
}

if ( state_under_test != “” )
{
if ( state_name_map[current_station_number] != state_under_test )
{
current_station_number = old_station_number;
continue;
}
}

if ( state_name_map.count(current_station_number) )
{
if ( state_name_map[current_station_number] == “AK” || state_name_map[current_station_number] == “HI” )
{
current_station_number = old_station_number;
continue;
}
}

Station new_station;
new_station.setStationNumber(current_station_number);
new_station.setStateName( record.getStateName() );
new_station.setStationName( station_name_map[current_station_number] );

if (test_only_airports || test_only_non_airports)
{
if ( new_station.getStationName().find(” AP”) != std::string::npos
|| new_station.getStationName().find(” AF”) != std::string::npos
|| new_station.getStationName().find(” FLD”) != std::string::npos
|| new_station.getStationName().find(” AFB”) != std::string::npos
|| new_station.getStationName().find(” ASC”) != std::string::npos
|| new_station.getStationName().find(” AAF”) != std::string::npos
|| new_station.getStationName().find(” NAF”) != std::string::npos
|| new_station.getStationName().find(” NAS”) != std::string::npos
|| new_station.getStationName().find(” NAAS”) != std::string::npos
|| new_station.getStationName().find(” NAAF”) != std::string::npos
|| new_station.getStationName().find(” BASE”) != std::string::npos
|| new_station.getStationName().find(” CAA”) != std::string::npos
|| new_station.getStationName().find(“RGNL A”) != std::string::npos
|| new_station.getStationName().find(“AIRFIELD”) != std::string::npos
|| new_station.getStationName().find(“AIRPORT”) != std::string::npos
|| new_station.getStationName().find(“INTL”) != std::string::npos
|| new_station.getStationName().find(“PILOT”) != std::string::npos
|| new_station.getStationName().find(“AIR PK”) != std::string::npos
)

{
if (test_only_non_airports)
{
current_station_number = old_station_number;
continue;
}
}
else
{
if (test_only_airports)
{
current_station_number = old_station_number;
continue;
}
}
}

std::cout << new_station.getStationName() << ” , ” << state_name_map[current_station_number] << ” , ” << current_station_number << std::endl;
std::cerr << new_station.getStationName() << ” ” << state_name_map[current_station_number] << ” ” << current_station_number << std::endl;
country.getStateVector().at(current_state_number – 1).getStationVector().push_back(new_station);
}

bool year_changed = false;

if ( country.getStateVector().at(current_state_number – 1).getStationVector().size() == 0 )
{
continue;
}

// Look for a new year
if ( record.getYear() != current_year_number || state_changed || station_changed )
{
year_changed = true;
current_year_number = record.getYear();
Year new_year;
new_year.setYear(current_year_number);

if ( country.getStateVector().at(current_state_number – 1).getStationVector().size() )
{
country.getStateVector().at(current_state_number – 1).getStationVector().back().getYearVector().push_back(new_year);
}
}

State& current_state = country.getStateVector().at(current_state_number – 1);
Station& current_station = current_state.getStationVector().back();
Year& current_year = current_station.getYearVector().back();
Month& current_month = current_year.getMonthVector().at( record.getMonth() – 1 );

// read in the TMAX and TMIN records for each day of the month
if ( record.getRecordTypeString() == “TMAX”
|| record.getRecordTypeString() == “TMIN”
|| record.getRecordTypeString() == “SNOW”
|| record.getRecordTypeString() == “PRCP”
)
{
//std::cerr << current_station.getStationName() << std::endl;
for (size_t day_number = 0; day_number < MAX_DAYS_IN_MONTH; day_number++)
{
float high_temperature = record.getHighTemperature(day_number);
float low_temperature = record.getLowTemperature(day_number);
float snow = record.getSnowfall(day_number);
float precipitation = record.getSnowfall(day_number);
Day& day = current_month.getDayVector().at(day_number);

if ( record.getRecordTypeString() == “TMAX” &&
high_temperature != UNKNOWN_TEMPERATURE &&
high_temperature < UNREASONABLE_HIGH_TEMPERATURE )
{
day.setMaxTemperature(high_temperature);

if ( high_temperature > country.getRecordMaxTemperature() )
{
country.setRecordMaxTemperature( high_temperature );
country.setRecordMaxYear( current_year_number );
}

if ( high_temperature > current_state.getRecordMaxTemperature() )
{
current_state.setRecordMaxTemperature( high_temperature );
current_state.setRecordMaxYear( current_year_number );
}

if ( high_temperature > current_station.getRecordMaxTemperature() )
{
current_station.setRecordMaxTemperature( high_temperature );
current_station.setRecordMaxYear( current_year_number );
}

if ( high_temperature > current_year.getRecordMaxTemperature() )
{
current_year.setRecordMaxTemperature( high_temperature );
current_year.setRecordMaxMonth( record.getMonth() );
}

if ( high_temperature > current_month.getRecordMaxTemperature() )
{
current_month.setRecordMaxTemperature( high_temperature );
current_month.setRecordMaxDay( day_number + 1 );
}
}
else if ( record.getRecordTypeString() == “TMIN” &&
low_temperature != UNKNOWN_TEMPERATURE &&
low_temperature > UNREASONABLE_LOW_TEMPERATURE )
{
day.setMinTemperature(low_temperature);

if ( low_temperature < country.getRecordMinTemperature() )
{
country.setRecordMinTemperature( low_temperature );
country.setRecordMinYear( current_year_number );
}

if ( low_temperature < current_state.getRecordMinTemperature() )
{
current_state.setRecordMinTemperature( low_temperature );
current_state.setRecordMinYear( current_year_number );
}

if ( low_temperature < current_station.getRecordMinTemperature() )
{
current_station.setRecordMinTemperature( low_temperature );
current_station.setRecordMinYear( current_year_number );
}

if ( low_temperature < current_year.getRecordMinTemperature() )
{
current_year.setRecordMinTemperature( low_temperature );
current_year.setRecordMinMonth( record.getMonth() );
}

if ( low_temperature < current_month.getRecordMinTemperature() )
{
current_month.setRecordMinTemperature( low_temperature );
current_month.setRecordMinDay( day_number );
}
}
else if ( record.getRecordTypeString() == “SNOW” && snow != UNKNOWN_TEMPERATURE)
{
day.setSnowfall(snow);
}
else if ( record.getRecordTypeString() == “PRCP” && precipitation != UNKNOWN_TEMPERATURE)
{
day.setPrecipitation(precipitation);
}
}
}
}

ushcn_data_file.close();

std::vector<State>& state_vector = country.getStateVector();
size_t state_vector_size = state_vector.size();

// Maps to tracks records and sums

std::map<unsigned int, unsigned int> record_max_per_year_map;
std::map<unsigned int, unsigned int> record_min_per_year_map;
std::map<unsigned int, unsigned int> record_incremental_max_per_year_map;
std::map<unsigned int, unsigned int> record_incremental_min_per_year_map;
std::map<unsigned int, float> total_temperature_per_year_map;
std::map<unsigned int, float> total_snowfall_per_year_map;
std::map<unsigned int, float> total_precipitation_per_year_map;
std::map<unsigned int, unsigned int> number_of_readings_per_year_map;
std::map<unsigned int, float> total_max_temperature_per_year_map;
std::map<unsigned int, unsigned int> number_of_max_readings_per_year_map;
std::map<unsigned int, float> total_min_temperature_per_year_map;
std::map<unsigned int, unsigned int> number_of_min_readings_per_year_map;
size_t numbers_of_temperatures_above[NUMBER_OF_YEARS];
size_t numbers_of_temperatures_below[NUMBER_OF_YEARS];
float total_temperature_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];
unsigned int number_of_readings_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];
float total_max_temperature_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];
unsigned int number_of_max_readings_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];
float total_min_temperature_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];
unsigned int number_of_min_readings_per_month[NUMBER_OF_YEARS][NUMBER_OF_MONTHS_PER_YEAR];

// Zero out the maps
for (unsigned int year = FIRST_YEAR; year <= most_recent_year; year++)
{
record_max_per_year_map[year] = 0;
record_min_per_year_map[year] = 0;
record_incremental_max_per_year_map[year] = 0;
record_incremental_min_per_year_map[year] = 0;
total_temperature_per_year_map[year] = 0.0f;
total_snowfall_per_year_map[year] = 0.0f;
total_precipitation_per_year_map[year] = 0.0f;
total_max_temperature_per_year_map[year] = 0.0f;
total_min_temperature_per_year_map[year] = 0.0f;
number_of_readings_per_year_map[year] = 0;
number_of_max_readings_per_year_map[year] = 0;
number_of_min_readings_per_year_map[year] = 0;
numbers_of_temperatures_above[year – FIRST_YEAR] = 0;
numbers_of_temperatures_below[year – FIRST_YEAR] = 0;

for (size_t month = 0; month < NUMBER_OF_MONTHS_PER_YEAR; month++)
{
total_temperature_per_month[year – FIRST_YEAR][month] = 0.0f;
number_of_readings_per_month[year – FIRST_YEAR][month] = 0;
total_max_temperature_per_month[year – FIRST_YEAR][month] = 0.0f;
number_of_max_readings_per_month[year – FIRST_YEAR][month] = 0;
total_min_temperature_per_month[year – FIRST_YEAR][month] = 0.0f;
number_of_min_readings_per_month[year – FIRST_YEAR][month] = 0;
}
}

std::cout << “Stations used in this analysis” << std::endl;
std::cerr << “Stations used in this analysis” << std::endl;

size_t used_station_count = 0;

// Walk through all temperature records
for (size_t state_number = 0; state_number < state_vector_size; state_number++)
{
std::vector<Station>& station_vector = state_vector.at(state_number).getStationVector();
size_t station_vector_size = station_vector.size();

for (size_t station_number = 0; station_number < station_vector_size; station_number++)
{
Station& station = station_vector[station_number];
std::vector<Year>& year_vector = station.getYearVector();

if ( !stationActiveForTheEntireDateRange(start_date_for_records, year_vector) )
{
continue;
}

std::cout << station.getStationName() << ” , ” << state_name_map[station.getStationNumber()] << ” , ” << station.getStationNumber() << std::endl;
std::cerr << station.getStationName() << ” ” << state_name_map[station.getStationNumber()] << ” ” << station.getStationNumber() << std::endl;

used_station_count++;

size_t year_vector_size = year_vector.size();

float record_max_temperatures[NUMBER_OF_MONTHS_PER_YEAR][MAX_DAYS_IN_MONTH];
float record_min_temperatures[NUMBER_OF_MONTHS_PER_YEAR][MAX_DAYS_IN_MONTH];
std::vector<unsigned int> record_max_temperature_year_vector[NUMBER_OF_MONTHS_PER_YEAR][MAX_DAYS_IN_MONTH];
std::vector<unsigned int> record_min_temperature_year_vector[NUMBER_OF_MONTHS_PER_YEAR][MAX_DAYS_IN_MONTH];

for (size_t i = 0; i < NUMBER_OF_MONTHS_PER_YEAR; i++)
{
for (size_t j = 0; j < MAX_DAYS_IN_MONTH; j++)
{
record_max_temperatures[i][j] = float(INT_MIN);
record_min_temperatures[i][j] = float(INT_MAX);
}
}

for (size_t year_number = 0; year_number < year_vector_size; year_number++)
{
std::vector<Month>& month_vector = year_vector.at(year_number).getMonthVector();
size_t month_vector_size = month_vector.size();
unsigned int year = year_vector.at(year_number).getYear();

if ( year_under_test && (year_under_test != year) )
{
continue;
}

for (size_t month_number = 0; month_number < month_vector_size; month_number++)
{
std::vector<Day>& day_vector = month_vector.at(month_number).getDayVector();
size_t day_vector_size = day_vector.size();

if ( month_under_test && !months_under_test_map[month_number + 1] )
{
continue;
}

for (size_t day_number = 0; day_number < day_vector_size; day_number++)
{
Day& day = day_vector.at(day_number);
float max_temperature = day.getMaxTemperature();
float min_temperature = day.getMinTemperature();
float snow = day.getSnowfall();
float precipitation = day.getPrecipitation();

if ( (year_to_dump == year) && ( month_to_dump == (month_number + 1) ) && ( day_to_dump == (day_number + 1) ) &&
(max_temperature != UNKNOWN_TEMPERATURE) && ( min_temperature != UNKNOWN_TEMPERATURE) )
{
std::cout << std::setw(15) << station_vector.at(station_number).getStateName() << “, “;
std::cout << station_vector.at(station_number).getStationName() << “, ” << month_to_dump << “/” << day_to_dump;
std::cout << “/” << year;
std::cout << “, ” << std::setw(3) << max_temperature << “, ” << std::setw(3) << min_temperature << std::endl;
}

// Don’t use broken readings
if (max_temperature != UNKNOWN_TEMPERATURE && max_temperature < UNREASONABLE_HIGH_TEMPERATURE)
{
total_temperature_per_year_map[year] = total_temperature_per_year_map[year] + max_temperature;
number_of_readings_per_year_map[year] = number_of_readings_per_year_map[year] + 1;
total_temperature_per_month[year – FIRST_YEAR][month_number] += max_temperature;
number_of_readings_per_month[year – FIRST_YEAR][month_number]++;
total_max_temperature_per_month[year – FIRST_YEAR][month_number] += max_temperature;
number_of_max_readings_per_month[year – FIRST_YEAR][month_number]++;
total_max_temperature_per_year_map[year] = total_max_temperature_per_year_map[year] + max_temperature;
number_of_max_readings_per_year_map[year] = number_of_max_readings_per_year_map[year] + 1;

if (max_temperature >= temperature_threshold)
{
numbers_of_temperatures_above[year – FIRST_YEAR]++;
}

if ( max_temperature == record_max_temperatures[month_number][day_number] )
{
//std::cout << “station_number = ” << station_number;
//std::cout << ” station name = ” << station.getStationName();
//std::cout << ” year = ” << year;
//std::cout << ” month = ” << month_number;
//std::cout << ” day = ” << day_number;
//std::cout << ” old record = ” << record_max_temperatures[month_number][day_number];
//std::cout << ” new record = ” << max_temperature;
//std::cout << std::endl;
record_max_temperature_year_vector[month_number][day_number].push_back(year);
}

if ( max_temperature > record_max_temperatures[month_number][day_number] )
{
//std::cout << “station_number = ” << station_number;
//std::cout << ” station name = ” << station.getStationName();
//std::cout << ” year = ” << year;
//std::cout << ” month = ” << month_number;
//std::cout << ” day = ” << day_number;
//std::cout << ” old record = ” << record_max_temperatures[month_number][day_number];
//std::cout << ” new record = ” << max_temperature;
//std::cout << std::endl;

record_max_temperatures[month_number][day_number] = max_temperature;
record_incremental_max_per_year_map[year] = record_incremental_max_per_year_map[year] + 1;

std::vector<unsigned int>& record_max_vector = record_max_temperature_year_vector[month_number][day_number];
size_t size = record_max_vector.size();

for (int i = size – 1; i >= 0; i–)
{
record_max_vector.erase( record_max_vector.begin() + i );
}

record_max_vector.push_back(year);
}
}

if (min_temperature != UNKNOWN_TEMPERATURE && min_temperature > UNREASONABLE_LOW_TEMPERATURE)
{
total_temperature_per_year_map[year] = total_temperature_per_year_map[year] + min_temperature;
number_of_readings_per_year_map[year] = number_of_readings_per_year_map[year] + 1;
total_temperature_per_month[year – FIRST_YEAR][month_number] += min_temperature;
number_of_readings_per_month[year – FIRST_YEAR][month_number]++;
total_min_temperature_per_month[year – FIRST_YEAR][month_number] += min_temperature;
number_of_min_readings_per_month[year – FIRST_YEAR][month_number]++;
total_min_temperature_per_year_map[year] = total_min_temperature_per_year_map[year] + min_temperature;
number_of_min_readings_per_year_map[year] = number_of_min_readings_per_year_map[year] + 1;

if (min_temperature <= temperature_threshold)
{
numbers_of_temperatures_below[year – FIRST_YEAR]++;
}

if ( min_temperature == record_min_temperatures[month_number][day_number] )
{
record_min_temperature_year_vector[month_number][day_number].push_back(year);
}

if ( min_temperature < record_min_temperatures[month_number][day_number] )
{
record_min_temperatures[month_number][day_number] = min_temperature;
record_incremental_min_per_year_map[year] = record_incremental_min_per_year_map[year] + 1;

std::vector<unsigned int>& record_min_vector = record_min_temperature_year_vector[month_number][day_number];
size_t size = record_min_vector.size();

for (int i = size – 1; i >= 0; i–)
{
record_min_vector.erase( record_min_vector.begin() + i );
}

record_min_vector.push_back(year);
}
}

if (snow != UNKNOWN_TEMPERATURE)
{
total_snowfall_per_year_map[year] = total_snowfall_per_year_map[year] + snow;
}

if (precipitation != UNKNOWN_TEMPERATURE)
{
total_precipitation_per_year_map[year] = total_precipitation_per_year_map[year] + precipitation;
}
}
}
}

if ( stationActiveForTheEntireDateRange(start_date_for_records, year_vector) )
{
for (size_t i = 0; i < NUMBER_OF_MONTHS_PER_YEAR; i++)
{
for (size_t j = 0; j < MAX_DAYS_IN_MONTH; j++)
{
if ( ( month_to_dump == (i + 1) ) && ( day_to_dump == (j + 1) ) && (year_to_dump == 0) )
{
std::cout << std::setw(15) << station_vector.at(station_number).getStateName() << “, “;
std::cout << station_vector.at(station_number).getStationName() << “, ” << month_to_dump << “/” << day_to_dump;
std::cout << “, ” << std::setw(3) << record_max_temperatures[i][j] << “, “;

size_t size = record_max_temperature_year_vector[i][j].size();
size_t k = 0;

for ( ; k < size – 1; k++)
{
std::cout << record_max_temperature_year_vector[i][j].at(k) << “, “;
}

std::cout << record_max_temperature_year_vector[i][j].at(k) << std::endl;

#if 0
std::cerr << ” ” << record_min_temperatures[i][j] << ” : “;

size = record_min_temperature_year_vector[i][j].size();

for (size_t k = 0; k < size; k++)
{
std::cerr << record_min_temperature_year_vector[i][j].at(k) << “, “;
}

#endif
}

size_t size = record_max_temperature_year_vector[i][j].size();

for (size_t k = 0; k < size; k++)
{
unsigned int record_max_year = record_max_temperature_year_vector[i][j].at(k);
record_max_per_year_map[record_max_year] = record_max_per_year_map[record_max_year] + 1;
}

size = record_min_temperature_year_vector[i][j].size();

for (size_t k = 0; k < size; k++)
{
unsigned int record_min_year = record_min_temperature_year_vector[i][j].at(k);
record_min_per_year_map[record_min_year] = record_min_per_year_map[record_min_year] + 1;
}

}
}
}
}
}

size_t record_map_size = record_max_per_year_map.size();

std::cout << “Number of stations used in this analysis = ” << used_station_count << std::endl;

// Dump out the results

std::cout << “Record Maximums,” << std::endl;
std::map<unsigned int, unsigned int>::iterator itmax = record_max_per_year_map.begin();

while ( itmax != record_max_per_year_map.end() )
{
std::cout << itmax->first << “, ” << itmax->second << “,” << std::endl;
++itmax;
}

std::cout << “Record Minimums,” << std::endl;
std::map<unsigned int, unsigned int>::iterator itmin = record_min_per_year_map.begin();

while ( itmin != record_min_per_year_map.end() )
{
std::cout << itmin->first << “, ” << itmin->second << “,” << std::endl;
++itmin;
}

std::cout << “Record Incremental Maximums,” << std::endl;
itmax = record_incremental_max_per_year_map.begin();

while ( itmax != record_incremental_max_per_year_map.end() )
{
std::cout << itmax->first << “, ” << itmax->second << “,” << std::endl;
++itmax;
}

std::cout << “Record Incremental Minimums,” << std::endl;
itmin = record_incremental_min_per_year_map.begin();

while ( itmin != record_incremental_min_per_year_map.end() )
{
std::cout << itmin->first << “, ” << itmin->second << “,” << std::endl;
++itmin;
}

std::cout << “Ratio Tmax/Tmin,” << std::endl;
itmax = record_max_per_year_map.begin();
itmin = record_min_per_year_map.begin();

while ( itmin != record_min_per_year_map.end() && itmax != record_max_per_year_map.end() )
{
float ratio = float(itmax->second) / float(itmin->second);
std::cout << itmin->first << “, ” << ratio << “,” << std::endl;
++itmax;
++itmin;
}

std::cout << “Average temperature,,,,,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,Annual C,Annual F” << std::endl;
std::map<unsigned int, float>::iterator temperature_it = total_temperature_per_year_map.begin();
std::map<unsigned int, unsigned int>::iterator count_it = number_of_readings_per_year_map.begin();
std::vector<float> maximum_month_running_total_vector;
std::vector<float> minimum_month_running_total_vector;
std::vector<float> average_month_running_total_vector;
float total_temperature = 0.0f;
int consecutive_count = 0;
size_t previous_month_number = 0;

while ( temperature_it != total_temperature_per_year_map.end() && count_it != number_of_readings_per_year_map.end() )
{
float average = float(temperature_it->second) / float(count_it->second);
std::cout << temperature_it->first << “, ” << average << “, ” << (average * 1.8) + 32 << “, ” << count_it->second << “,, “;

unsigned int year = temperature_it->first;

float annual_monthly_sum = 0.0f;
size_t number_of_valid_months = 0;

for (size_t month = 0; month < NUMBER_OF_MONTHS_PER_YEAR; month++)
{
float monthly_average = UNKNOWN_TEMPERATURE;
size_t month_number = (year * NUMBER_OF_MONTHS_PER_YEAR) + month;

if ( number_of_readings_per_month[year – FIRST_YEAR][month] )
{
if ( (month_number – previous_month_number) == 1 )
{
consecutive_count ++;
}
else
{
consecutive_count = 0;
}

monthly_average = total_temperature_per_month[year – FIRST_YEAR][month] / number_of_readings_per_month[year – FIRST_YEAR][month];
total_temperature += monthly_average;
average_month_running_total_vector.push_back(total_temperature);
annual_monthly_sum += monthly_average;
number_of_valid_months++;

if (consecutive_count >= number_of_months_under_test)
{
size_t size = average_month_running_total_vector.size();
float total_variable_month_temperature = average_month_running_total_vector.at(size – 1) – average_month_running_total_vector.at(size – 1 – number_of_months_under_test);
float average_temperature = total_variable_month_temperature / float(number_of_months_under_test);
country.getVariableMonthMeanAverageMap()[average_temperature] = month_number;
}

previous_month_number = month_number;
}

std::cout << ” ” << monthly_average << “, “;
}

if (number_of_valid_months)
{
float annual_monthly_average = annual_monthly_sum / float(number_of_valid_months);
float annual_monthly_average_f = (annual_monthly_average * 1.8f) + 32.0f;
std::cout << annual_monthly_average << “, ” << annual_monthly_average_f;
}

std::cout << std::endl;

temperature_it++;
count_it++;
}

std::cout << “Hottest Average” << number_of_months_under_test << ” month periods ” << std::endl;
std::cout << “Rank, ” << “Month, ” << “Year, ” << “Temperature ” << std::endl;
std::map<float,size_t>::reverse_iterator variable_month_iterator = country.getVariableMonthMeanAverageMap().rbegin();
size_t count = 1;

for ( ; variable_month_iterator != country.getVariableMonthMeanAverageMap().rend(); variable_month_iterator++ )
{
unsigned int year = variable_month_iterator->second / NUMBER_OF_MONTHS_PER_YEAR;
unsigned int month = variable_month_iterator->second % NUMBER_OF_MONTHS_PER_YEAR;
float temperature = variable_month_iterator->first;

std::cout << count++ << “, ” << month + 1 << “, ” << year << “, ” << temperature << std::endl;
}
std::cout << “Average maximum temperature,,,,,,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,Annual C,Annual F” << std::endl;
temperature_it = total_max_temperature_per_year_map.begin();
count_it = number_of_max_readings_per_year_map.begin();

while ( temperature_it != total_max_temperature_per_year_map.end() && count_it != number_of_max_readings_per_year_map.end() )
{
float average = float(temperature_it->second) / float(count_it->second);
std::cout << temperature_it->first << “, ” << average << “, ” << (average * 1.8) + 32 << “, ” << count_it->second << “,, “;

unsigned int year = temperature_it->first;

float annual_monthly_sum = 0.0f;
size_t number_of_valid_months = 0;

for (size_t month = 0; month < NUMBER_OF_MONTHS_PER_YEAR; month++)
{
float monthly_average = UNKNOWN_TEMPERATURE;
size_t month_number = (year * NUMBER_OF_MONTHS_PER_YEAR) + month;

if ( number_of_max_readings_per_month[year – FIRST_YEAR][month] )
{
if ( (month_number – previous_month_number) == 1 )
{
consecutive_count ++;
}
else
{
consecutive_count = 0;
}

monthly_average = total_max_temperature_per_month[year – FIRST_YEAR][month] / number_of_max_readings_per_month[year – FIRST_YEAR][month];
total_temperature += monthly_average;
maximum_month_running_total_vector.push_back(total_temperature);
annual_monthly_sum += monthly_average;
number_of_valid_months++;

if (consecutive_count >= number_of_months_under_test)
{
size_t size = maximum_month_running_total_vector.size();
float total_variable_month_temperature = maximum_month_running_total_vector.at(size – 1) – maximum_month_running_total_vector.at(size – 1 – number_of_months_under_test);
float average_temperature = total_variable_month_temperature / float(number_of_months_under_test);
country.getVariableMonthMeanMaximumMap()[average_temperature] = month_number;
}

previous_month_number = month_number;
}

std::cout << ” ” << monthly_average << “, “;
}

if (number_of_valid_months)
{
float annual_monthly_average = annual_monthly_sum / float(number_of_valid_months);
float annual_monthly_average_f = (annual_monthly_average * 1.8f) + 32.0f;
std::cout << annual_monthly_average << “, ” << annual_monthly_average_f;
}

std::cout << std::endl;

temperature_it++;
count_it++;
}

std::cout << “Hottest Maximum” << number_of_months_under_test << ” month periods ” << std::endl;
std::cout << “Rank, ” << “Month, ” << “Year, ” << “Temperature ” << std::endl;
variable_month_iterator = country.getVariableMonthMeanMaximumMap().rbegin();
count = 1;

for ( ; variable_month_iterator != country.getVariableMonthMeanMaximumMap().rend(); variable_month_iterator++ )
{
unsigned int year = variable_month_iterator->second / NUMBER_OF_MONTHS_PER_YEAR;
unsigned int month = variable_month_iterator->second % NUMBER_OF_MONTHS_PER_YEAR;
float temperature = variable_month_iterator->first;

std::cout << count++ << “, ” << month + 1 << “, ” << year << “, ” << temperature << std::endl;
}

std::cout << “Average minimum temperature,,,,,,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,Annual C,Annual F” << std::endl;
temperature_it = total_min_temperature_per_year_map.begin();
count_it = number_of_min_readings_per_year_map.begin();

while ( temperature_it != total_min_temperature_per_year_map.end() && count_it != number_of_min_readings_per_year_map.end() )
{
float average = float(temperature_it->second) / float(count_it->second);
std::cout << temperature_it->first << “, ” << average << “, ” << (average * 1.8) + 32 << “, ” << count_it->second << “,, “;

unsigned int year = temperature_it->first;

float annual_monthly_sum = 0.0f;
size_t number_of_valid_months = 0;

for (size_t month = 0; month < NUMBER_OF_MONTHS_PER_YEAR; month++)
{
float monthly_average = UNKNOWN_TEMPERATURE;
size_t month_number = (year * NUMBER_OF_MONTHS_PER_YEAR) + month;

if ( number_of_min_readings_per_month[year – FIRST_YEAR][month] )
{
if ( (month_number – previous_month_number) == 1 )
{
consecutive_count ++;
}
else
{
consecutive_count = 0;
}

monthly_average = total_min_temperature_per_month[year – FIRST_YEAR][month] / number_of_min_readings_per_month[year – FIRST_YEAR][month];
total_temperature += monthly_average;
minimum_month_running_total_vector.push_back(total_temperature);
annual_monthly_sum += monthly_average;
number_of_valid_months++;

if (consecutive_count >= number_of_months_under_test)
{
size_t size = minimum_month_running_total_vector.size();
float total_variable_month_temperature = minimum_month_running_total_vector.at(size – 1) – minimum_month_running_total_vector.at(size – 1 – number_of_months_under_test);
float average_temperature = total_variable_month_temperature / float(number_of_months_under_test);
country.getVariableMonthMeanMinimumMap()[average_temperature] = month_number;
}

previous_month_number = month_number;
}

std::cout << ” ” << monthly_average << “, “;
}

if (number_of_valid_months)
{
float annual_monthly_average = annual_monthly_sum / float(number_of_valid_months);
float annual_monthly_average_f = (annual_monthly_average * 1.8f) + 32.0f;
std::cout << annual_monthly_average << “, ” << annual_monthly_average_f;
}

std::cout << std::endl;

temperature_it++;
count_it++;
}

std::cout << “Hottest Minimum” << number_of_months_under_test << ” month periods ” << std::endl;
std::cout << “Rank, ” << “Month, ” << “Year, ” << “Temperature ” << std::endl;
variable_month_iterator = country.getVariableMonthMeanMinimumMap().rbegin();
count = 1;

for ( ; variable_month_iterator != country.getVariableMonthMeanMinimumMap().rend(); variable_month_iterator++ )
{
unsigned int year = variable_month_iterator->second / NUMBER_OF_MONTHS_PER_YEAR;
unsigned int month = variable_month_iterator->second % NUMBER_OF_MONTHS_PER_YEAR;
float temperature = variable_month_iterator->first;

std::cout << count++ << “, ” << month + 1 << “, ” << year << “, ” << temperature << std::endl;
}

std::cout << “Temperature threshold, Year, Above, Below” << std::endl;

for (size_t i = 0; i <= (most_recent_year – FIRST_YEAR); i++)
{
std::cout << temperature_threshold << “, ” << FIRST_YEAR + i << “, ” << numbers_of_temperatures_above[i] << “, ” << numbers_of_temperatures_below[i] << std::endl;
}

std::cout << “Year, Average annual snowfall in cm” << std::endl;
std::map<unsigned int, float>::iterator snow_it = total_snowfall_per_year_map.begin();

while ( snow_it != total_snowfall_per_year_map.end() )
{
std::cout << snow_it->first << “, ” << (snow_it->second / used_station_count) << std::endl;
snow_it++;
}

std::cout << “Year, Average annual precipitation in cm” << std::endl;
std::map<unsigned int, float>::iterator precipitation_it = total_precipitation_per_year_map.begin();

while ( precipitation_it != total_precipitation_per_year_map.end() )
{
std::cout << precipitation_it->first << “, ” << (precipitation_it->second / used_station_count) << std::endl;
precipitation_it++;
}
}
else
{
std::cout << “Unable to open us.txt” << std::endl;
}

return 0;
}

//————————————————————————————–
// GHCN.h
// Code for parsing and processing daily GHCN data from
// Written by Steve Goddard
// If you modify it and mess it up, don’t blame it on me

#ifndef GHCN_H_INCLUDED
#define GHCN_H_INCLUDED
#include <vector>
#include <string>
#include <map>

// Comment out the next two lines to compile on MS compilers
#include <stdlib.h>
#include <limits.h>

static const unsigned int MAX_DAYS_IN_MONTH = 31;
static const unsigned int NUMBER_OF_MONTHS_PER_YEAR = 12;
static const unsigned int FIRST_YEAR = 1750;
static const unsigned int NUMBER_OF_YEARS = 300;
static const unsigned int MAX_YEARS = 3000;
static const unsigned int MAX_STATE_NAME_LENGTH = 64;
static const unsigned int NUMBER_OF_STATES = 48;
static const float UNKNOWN_TEMPERATURE = -99.0f;
static const float UNREASONABLE_HIGH_TEMPERATURE = 140.0f;
static const float UNREASONABLE_LOW_TEMPERATURE = -100.0f;
static const unsigned int NUMBER_OF_DAYS_PER_YEAR = 365;
static const int NUMBER_OF_MONTHS_UNDER_TEST = 12;

static const char STATE_NAMES[][MAX_STATE_NAME_LENGTH] =
{
“None”,
“Alabama”,
“Arizona”,
“Arkansas”,
“California”,
“Colorado”,
“Connecticut”,
“Delaware”,
“Florida”,
“Georgia”,
“Idaho”,
“Illinois”,
“Indiana”,
“Iowa”,
“Kansas”,
“Kentucky”,
“Louisiana”,
“Maine”,
“Maryland”,
“Massachusetts”,
“Michigan”,
“Minnesota”,
“Mississippi”,
“Missouri”,
“Montana”,
“Nebraska”,
“Nevada”,
“New Hampshire”,
“New Jersey”,
“New Mexico”,
“New York”,
“North Carolina”,
“North Dakota”,
“Ohio”,
“Oklahoma”,
“Oregon”,
“Pennsylvania”,
“Rhode Island”,
“South Carolina”,
“South Dakota”,
“Tennessee”,
“Texas”,
“Utah”,
“Vermont”,
“Virginia”,
“Washington”,
“West Virginia”,
“Wisconsin”,
“Wyoming”
};

// From ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-countries.txt

static const char COUNTRY_NAMES[][2][MAX_STATE_NAME_LENGTH] =
{
{ “AC”, “Antigua and Barbuda ” },
{ “AE”, “United Arab Emirates ” },
{ “AF”, “Afghanistan” },
{ “AG”, “Algeria ” },
{ “AJ”, “Azerbaijan ” },
{ “AL”, “Albania” },
{ “AM”, “Armenia ” },
{ “AO”, “Angola ” },
{ “AQ”, “American Samoa [United States] ” },
{ “AR”, “Argentina ” },
{ “AS”, “Australia ” },
{ “AU”, “Austria ” },
{ “AY”, “Antarctica ” },
{ “BA”, “Bahrain ” },
{ “BB”, “Barbados ” },
{ “BC”, “Botswana ” },
{ “BD”, “Bermuda [United Kingdom] ” },
{ “BE”, “Belgium ” },
{ “BF”, “Bahamas, The ” },
{ “BK”, “Bosnia and Herzegovina ” },
{ “BL”, “Bolivia ” },
{ “BN”, “Benin ” },
{ “BO”, “Belarus ” },
{ “BP”, “Solomon Islands ” },
{ “BR”, “Brazil ” },
{ “BY”, “Burundi” },
{ “CA”, “Canada ” },
{ “CD”, “Chad ” },
{ “CE”, “Sri Lanka ” },
{ “CF”, “Congo (Brazzaville) ” },
{ “CH”, “China ” },
{ “CI”, “Chile ” },
{ “CJ”, “Cayman Islands [United Kingdom] ” },
{ “CK”, “Cocos (Keeling) Islands [Australia] ” },
{ “CM”, “Cameroon ” },
{ “CO”, “Colombia ” },
{ “CQ”, “Northern Mariana Islands [United States] ” },
{ “CS”, “Costa Rica ” },
{ “CT”, “Central African Republic ” },
{ “CU”, “Cuba ” },
{ “CY”, “Cyprus ” },
{ “DA”, “Denmark ” },
{ “DR”, “Dominican Republic ” },
{ “EC”, “Ecuador ” },
{ “EG”, “Egypt ” },
{ “EI”, “Ireland ” },
{ “EN”, “Estonia ” },
{ “ER”, “Eritrea ” },
{ “ES”, “El Salvador ” },
{ “ET”, “Ethiopia ” },
{ “EZ”, “Czech Republic ” },
{ “FG”, “French Guiana [France] ” },
{ “FI”, “Finland ” },
{ “FJ”, “Fiji ” },
{ “FM”, “Federated States of Micronesia ” },
{ “FP”, “French Polynesia ” },
{ “FR”, “France ” },
{ “FS”, “French Southern and Antarctic Lands [France] ” },
{ “GB”, “Gabon ” },
{ “GG”, “Georgia ” },
{ “GL”, “Greenland [Denmark] ” },
{ “GM”, “Germany ” },
{ “GP”, “Guadeloupe [France] ” },
{ “GQ”, “Guam [United States] ” },
{ “GR”, “Greece ” },
{ “GT”, “Guatemala ” },
{ “GV”, “Guinea ” },
{ “GY”, “Guyana ” },
{ “HO”, “Honduras ” },
{ “HR”, “Croatia” },
{ “HU”, “Hungary ” },
{ “IC”, “Iceland ” },
{ “ID”, “Indonesia ” },
{ “IN”, “India ” },
{ “IO”, “British Indian Ocean Territory [United Kingdom] ” },
{ “IR”, “Iran ” },
{ “IS”, “Israel ” },
{ “IT”, “Italy ” },
{ “IV”, “Cote D’Ivoire ” },
{ “IZ”, “Iraq ” },
{ “JA”, “Japan ” },
{ “JM”, “Jamaica ” },
{ “JN”, “Jan Mayen [Norway] ” },
{ “JQ”, “Johnston Atoll [United States] ” },
{ “KE”, “Kenya ” },
{ “KG”, “Kyrgyzstan ” },
{ “KN”, “Korea, North ” },
{ “KR”, “Kiribati ” },
{ “KS”, “Korea, South ” },
{ “KT”, “Christmas Island [Australia] ” },
{ “KU”, “Kuwait ” },
{ “KZ”, “Kazakhstan ” },
{ “LA”, “Laos ” },
{ “LG”, “Latvia ” },
{ “LH”, “Lithuania ” },
{ “LO”, “Slovakia ” },
{ “LQ”, “Palmyra Atoll [United States] ” },
{ “LT”, “Lesotho ” },
{ “LU”, “Luxembourg ” },
{ “LY”, “Libya ” },
{ “MA”, “Madagascar ” },
{ “MD”, “Moldova ” },
{ “MG”, “Mongolia ” },
{ “MI”, “Malawi ” },
{ “MK”, “Macedonia ” },
{ “ML”, “Mali ” },
{ “MO”, “Morocco ” },
{ “MP”, “Mauritius ” },
{ “MQ”, “Midway Islands [United States} ” },
{ “MR”, “Mauritania ” },
{ “MQ”, “Midway Islands [United States} ” },
{ “MR”, “Mauritania ” },
{ “MT”, “Malta ” },
{ “MU”, “Oman ” },
{ “MV”, “Maldives ” },
{ “MX”, “Mexico ” },
{ “MY”, “Malaysia ” },
{ “MZ”, “Mozambique ” },
{ “NC”, “New Caledonia [France] ” },
{ “NG”, “Niger ” },
{ “NH”, “Vanuatu ” },
{ “NL”, “Netherlands ” },
{ “NO”, “Norway ” },
{ “NP”, “Nepal ” },
{ “NU”, “Nicaragua ” },
{ “NZ”, “New Zealand ” },
{ “PA”, “Paraguay ” },
{ “PC”, “Pitcairn Islands [United Kingdom] ” },
{ “PE”, “Peru ” },
{ “PK”, “Pakistan ” },
{ “PL”, “Poland ” },
{ “PM”, “Panama ” },
{ “PO”, “Portugal ” },
{ “PP”, “Papua New Guinea ” },
{ “PS”, “Palau ” },
{ “RI”, “Serbia” },
{ “RM”, “Marshall Islands ” },
{ “RO”, “Romania ” },
{ “RP”, “Philippines ” },
{ “RQ”, “Puerto Rico [United States] ” },
{ “RS”, “Russia ” },
{ “SA”, “Saudi Arabia ” },
{ “SE”, “Seychelles ” },
{ “SF”, “South Africa ” },
{ “SG”, “Senegal ” },
{ “SH”, “Saint Helena [United Kingdom] ” },
{ “SI”, “Slovenia ” },
{ “SL”, “Sierra Leone ” },
{ “SP”, “Spain ” },
{ “ST”, “Saint Lucia ” },
{ “SU”, “Sudan ” },
{ “SV”, “Svalbard [Norway] ” },
{ “SW”, “Sweden ” },
{ “SY”, “Syria ” },
{ “SZ”, “Switzerland ” },
{ “TD”, “Trinidad and Tobago ” },
{ “TH”, “Thailand ” },
{ “TI”, “Tajikistan ” },
{ “TL”, “Tokelau [New Zealand] ” },
{ “TN”, “Tonga ” },
{ “TO”, “Togo ” },
{ “TS”, “Tunisia ” },
{ “TU”, “Turkey ” },
{ “TV”, “Tuvalu ” },
{ “TX”, “Turkmenistan ” },
{ “TZ”, “Tanzania ” },
{ “UG”, “Uganda” },
{ “UK”, “United Kingdom ” },
{ “UP”, “Ukraine ” },
{ “US”, “United States ” },
{ “UV”, “Burkina Faso ” },
{ “UY”, “Uruguay ” },
{ “UZ”, “Uzbekistan ” },
{ “VE”, “Venezuela ” },
{ “VM”, “Vietnam ” },
{ “VQ”, “Virgin Islands [United States] ” },
{ “WA”, “Namibia ” },
{ “WF”, “Wallis and Futuna [France] ” },
{ “WQ”, “Wake Island [United States]” },
{ “WZ”, “Swaziland ” },
{ “ZA”, “Zambia ” },
{ “ZI”, “Zimbabwe ” },
};

class DataRecord
{
public:
enum RECORD_TYPE
{
RECORD_TYPE_TMAX,
RECORD_TYPE_TMIN,
RECORD_TYPE_SNOW,
RECORD_TYPE_SNWD,
RECORD_TYPE_PRCP,
RECORD_TYPE_NONE
};

DataRecord() :
m_daily_high_temperature_vector(MAX_DAYS_IN_MONTH),
m_daily_low_temperature_vector(MAX_DAYS_IN_MONTH),
m_daily_snow_vector(MAX_DAYS_IN_MONTH),
m_daily_precipitation_vector(MAX_DAYS_IN_MONTH)
{
for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++)
{
setHighTemperature(i, UNKNOWN_TEMPERATURE);
setLowTemperature(i, UNKNOWN_TEMPERATURE);
}
}

std::string& getCountryAbbreviation() { return m_country_abbreviation; }
void setCountryAbbreviation(std::string value) { m_country_abbreviation = value; }
std::string& getStationNumber() { return m_station_number; }
void setStationNumber(std::string value) { m_station_number = value; }
std::string& getRecordTypeString() { return m_record_type_string; }
void setRecordTypeString(std::string type) { m_record_type_string = type; }
unsigned int getStateNumber() { return m_state_number; }
void setStateNumber(unsigned int value) { m_state_number = value; }
std::string getStateName() { return std::string( STATE_NAMES[ getStateNumber() ] ); }
unsigned int getYear() { return m_year; }
void setYear(unsigned int value) { m_year = value; }
unsigned int getMonth() { return m_month; }
void setMonth(unsigned int value) { m_month = value; }
std::vector<float>& getDailyHighTemperatureVector() { return m_daily_high_temperature_vector; }
float getHighTemperature(unsigned int day_of_month) { return getDailyHighTemperatureVector().at(day_of_month); }
void setHighTemperature(unsigned int day_of_month, float value);
std::vector<float>& getDailyLowTemperatureVector() { return m_daily_high_temperature_vector; }
float getLowTemperature(unsigned int day_of_month) { return getDailyLowTemperatureVector().at(day_of_month); }
void setLowTemperature(unsigned int day_of_month, float value);
std::vector<float>& getDailySnowVector() { return m_daily_snow_vector; }
float getSnowfall(unsigned int day_of_month) { return getDailySnowVector().at(day_of_month); }
void setSnowfall(unsigned int day_of_month, float value);
std::vector<float>& getDailyPrecipitationVector() { return m_daily_snow_vector; }
float getPrecipitation(unsigned int day_of_month) { return getDailyPrecipitationVector().at(day_of_month); }
void setPrecipitation(unsigned int day_of_month, float value);
void parseTemperatureRecord(std::string record_string);
protected:
std::string m_country_abbreviation;
std::string m_station_number;
std::string m_record_type_string;
unsigned int m_state_number;
unsigned int m_year;
unsigned int m_month;
std::vector<float> m_daily_high_temperature_vector;
std::vector<float> m_daily_low_temperature_vector;
std::vector<float> m_daily_snow_vector;
std::vector<float> m_daily_precipitation_vector;
};

class Day
{
public:
Day()
{
setMaxTemperature( UNKNOWN_TEMPERATURE );
setMinTemperature( UNKNOWN_TEMPERATURE );
setSnowfall(0);
setPrecipitation(0);
}

float getMaxTemperature() { return m_max_temperature; }
void setMaxTemperature(float value) { m_max_temperature = value; }
float getMinTemperature() { return m_min_temperature; }
void setMinTemperature(float value) { m_min_temperature = value; }
float getSnowfall() { return m_snowfall; }
void setSnowfall(float value) { m_snowfall = value; }
float getPrecipitation() { return m_precipitation; }
void setPrecipitation(float value) { m_precipitation = value; }

protected:
float m_max_temperature;
float m_min_temperature;
float m_snowfall;
float m_precipitation;
};

class Month
{
public:
Month() : m_day_vector(MAX_DAYS_IN_MONTH)
{
setRecordMaxTemperature( float(INT_MIN) );
setRecordMinTemperature( float(INT_MAX) );
setRecordMaxDay(0);
setRecordMinDay(0);
setValid(false);
}

bool getValid() { return m_valid; }
void setValid(bool flag) { m_valid = flag; }
std::vector<Day>& getDayVector() { return m_day_vector; }
float getRecordMaxTemperature() { return m_record_max_temperature; }
void setRecordMaxTemperature(float value) { m_record_max_temperature = value; }
float getRecordMinTemperature() { return m_record_min_temperature; }
void setRecordMinTemperature(float value) { m_record_min_temperature = value; }
unsigned int getRecordMaxDay() { return m_record_max_day; }
void setRecordMaxDay(unsigned int value) { m_record_max_day = value; }
unsigned int getRecordMinDay() { return m_record_min_day; }
void setRecordMinDay(unsigned int value) { m_record_min_day = value; }
float getTotalTemperature() { return m_total_temperature; }
void setTotalTemperature(float value) { m_total_temperature = value; }
void addToTotalTemperature(float value) { m_total_temperature += value; }
unsigned int getNumberOfTemperatures() { return m_number_of_temperatures; }
void setNumberOfTemperatures(unsigned int value) { m_number_of_temperatures = value; }
void incrementNumberOfTemperatures() { m_number_of_temperatures++; }

protected:
bool m_valid;
std::vector<Day> m_day_vector;
float m_record_max_temperature;
float m_record_min_temperature;
unsigned int m_record_max_day;
unsigned int m_record_min_day;
float m_total_temperature;
unsigned int m_number_of_temperatures;
};

class Year
{
public:
Year() : m_month_vector(NUMBER_OF_MONTHS_PER_YEAR)
{
setRecordMaxTemperature( float(INT_MIN) );
setRecordMinTemperature( float(INT_MAX) );
setRecordMaxMonth(0);
setRecordMinMonth(0);
}

std::vector<Month>& getMonthVector() { return m_month_vector; }
unsigned int getYear() { return m_year; }
void setYear(unsigned int value) { m_year = value; }
float getRecordMaxTemperature() { return m_record_max_temperature; }
void setRecordMaxTemperature(float value) { m_record_max_temperature = value; }
float getRecordMinTemperature() { return m_record_min_temperature; }
void setRecordMinTemperature(float value) { m_record_min_temperature = value; }
unsigned int getRecordMaxMonth() { return m_record_max_month; }
void setRecordMaxMonth(unsigned int value) { m_record_max_month = value; }
unsigned int getRecordMinMonth() { return m_record_min_month; }
void setRecordMinMonth(unsigned int value) { m_record_min_month = value; }
float getTotalTemperature() { return m_total_temperature; }
void setTotalTemperature(float value) { m_total_temperature = value; }
void addToTotalTemperature(float value) { m_total_temperature += value; }
unsigned int getNumberOfTemperatures() { return m_number_of_temperatures; }
void setNumberOfTemperatures(unsigned int value) { m_number_of_temperatures = value; }
void incrementNumberOfTemperatures() { m_number_of_temperatures++; }

protected:
std::vector<Month> m_month_vector;
unsigned int m_year;
float m_record_max_temperature;
float m_record_min_temperature;
unsigned int m_record_max_month;
unsigned int m_record_min_month;
float m_total_temperature;
unsigned int m_number_of_temperatures;
};

class Station
{
public:
Station()
{
setRecordMaxTemperature( float(INT_MIN) );
setRecordMinTemperature( float(INT_MAX) );
setRecordMaxYear(0);
setRecordMinYear(0);
}

std::vector<Year>& getYearVector() { return m_year_vector; }
std::string& getStationNumber() { return m_station_number; }
void setStationNumber(std::string value) { m_station_number = value; }
std::string& getStationName() { return m_station_name; }
void setStationName(std::string name) { m_station_name = name; }
std::string& getStateName() { return m_state_name; }
void setStateName(std::string name) { m_state_name = name; }
float getRecordMaxTemperature() { return m_record_max_temperature; }
void setRecordMaxTemperature(float value) { m_record_max_temperature = value; }
float getRecordMinTemperature() { return m_record_min_temperature; }
void setRecordMinTemperature(float value) { m_record_min_temperature = value; }
unsigned int getRecordMaxYear() { return m_record_max_year; }
void setRecordMaxYear(unsigned int value) { m_record_max_year = value; }
unsigned int getRecordMinYear() { return m_record_min_year; }
void setRecordMinYear(unsigned int value) { m_record_min_year = value; }

protected:
std::vector<Year> m_year_vector;
std::string m_station_number;
std::string m_station_name;
std::string m_state_name;
float m_record_max_temperature;
float m_record_min_temperature;
unsigned int m_record_max_year;
unsigned int m_record_min_year;
};

class State
{
public:
State()
{
setRecordMaxTemperature( float(INT_MIN) );
setRecordMinTemperature( float(INT_MAX) );
setRecordMaxYear(0);
setRecordMinYear(0);
}

std::vector<Station>& getStationVector() { return m_station_vector; }
unsigned int getStateNumber() { return m_state_number; }
void setStateNumber(unsigned int value) { m_state_number = value; }
std::string getStateName() { return std::string( STATE_NAMES[ getStateNumber() ] ); }
float getRecordMaxTemperature() { return m_record_max_temperature; }
void setRecordMaxTemperature(float value) { m_record_max_temperature = value; }
float getRecordMinTemperature() { return m_record_min_temperature; }
void setRecordMinTemperature(float value) { m_record_min_temperature = value; }
unsigned int getRecordMaxYear() { return m_record_max_year; }
void setRecordMaxYear(unsigned int value) { m_record_max_year = value; }
unsigned int getRecordMinYear() { return m_record_min_year; }
void setRecordMinYear(unsigned int value) { m_record_min_year = value; }

protected:
std::vector<Station> m_station_vector;
unsigned int m_state_number;
float m_record_max_temperature;
float m_record_min_temperature;
unsigned int m_record_max_year;
unsigned int m_record_min_year;
};

class Country
{
public:
Country() : m_state_vector(NUMBER_OF_STATES)
{
setRecordMaxTemperature( float(INT_MIN) );
setRecordMinTemperature( float(INT_MAX) );
setRecordMaxYear(0);
setRecordMinYear(0);
}

std::map<float,size_t>& getVariableMonthMeanAverageMap() { return m_variable_month_mean_average_map; }
std::map<float,size_t>& getVariableMonthMeanMaximumMap() { return m_variable_month_mean_maximum_map; }
std::map<float,size_t>& getVariableMonthMeanMinimumMap() { return m_variable_month_mean_minimum_map; }
std::vector<State>& getStateVector() { return m_state_vector; }
float getRecordMaxTemperature() { return m_record_max_temperature; }
void setRecordMaxTemperature(float value) { m_record_max_temperature = value; }
float getRecordMinTemperature() { return m_record_min_temperature; }
void setRecordMinTemperature(float value) { m_record_min_temperature = value; }
unsigned int getRecordMaxYear() { return m_record_max_year; }
void setRecordMaxYear(unsigned int value) { m_record_max_year = value; }
unsigned int getRecordMinYear() { return m_record_min_year; }
void setRecordMinYear(unsigned int value) { m_record_min_year = value; }

protected:
std::map<float,size_t> m_variable_month_mean_average_map;
std::map<float,size_t> m_variable_month_mean_maximum_map;
std::map<float,size_t> m_variable_month_mean_minimum_map;
std::vector<State> m_state_vector;
float m_record_max_temperature;
float m_record_min_temperature;
unsigned int m_record_max_year;
unsigned int m_record_min_year;
};

#endif // GHCN_H_INCLUDED

#——————————————————————-
ghcn.exe : Makefile Main.cpp GHCN.cpp GHCN.h
g++ -O3 -o ghcn.exe Main.cpp GHCN.cpp
#g++ -g -o ghcn.exe Main.cpp GHCN.cpp

#—————————————————-
#!/usr/bin/tcsh

# get_daily.tcsh

rm *.dly*

foreach station (`cat stations.txt`)
wget ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/hcn/USC00${station}.dly
end

set today = `date +%d%m%Y`

cat *.dly > US${today}.txt

#rm US.txt

#ln -s US${today}.txt US.txt

————————————————————————–

stations.txt

011084
012813
013160
013511
013816
015749
017157
017304
017366
018024
018178
018323
018380
018438
018469
020080
021026
021248
021514
021614
023160
023596
024089
024645
024849
025512
026250
026353
026796
027281
027370
027390
027435
027716
028619
028815
029271
029287
029359
029652
030936
031596
031632
032356
032444
032930
034572
034756
035186
035512
035754
035820
035908
036253
036928
040693
040924
041048
041614
041715
041758
041912
042239
042294
042319
042728
042910
042941
043161
043257
043747
043761
043875
044232
044259
044713
044890
044997
045032
045385
045532
045983
046074
046118
046175
046399
046506
046508
046719
046730
046826
047195
047304
047306
047851
047902
047916
047965
048702
048758
048839
049087
049122
049200
049452
049490
049699
049855
049866
050848
051294
051528
051564
051741
052184
052281
052446
053005
053038
053146
053662
053951
054076
054770
054834
055322
055722
057167
057337
057936
058204
058429
059243
062658
063207
067970
068138
072730
073595
075915
076410
079605
080211
080228
080478
080611
082220
082850
082915
082944
083163
083186
083207
084289
084570
084731
085275
086414
086997
087020
087851
088758
088824
088942
090140
090586
091340
091500
092318
092475
092966
093621
093754
094170
095874
095882
096335
097276
097600
097847
098535
098703
098740
099141
099157
099186
099291
100010
100448
100470
100803
101408
101956
102845
103143
103631
103732
104140
104295
104670
104831
104845
105241
105275
105462
105559
105685
106152
106305
106388
106542
106891
107264
107386
108080
108137
110072
110187
110338
111280
111436
112140
112193
112348
112483
113335
113879
114108
114198
114442
114823
115079
115326
115515
115712
115768
115833
115901
115943
116446
116526
116558
116579
116610
116738
116910
117551
118147
118740
118916
119241
119354
120177
120200
120676
120784
121030
121229
121425
121747
121873
122149
123418
123513
123527
124008
124181
124837
125237
125337
126001
126580
126705
127125
127298
127482
127522
127646
127755
127875
127935
128036
129080
129113
129253
129511
129557
129670
130112
130133
130600
131402
131533
131635
132724
132789
132864
132977
132999
134063
134142
134735
134894
135769
135796
135952
137147
137161
137979
138296
138688
140264
140365
140405
141704
141740
141867
142401
142459
142835
143527
143810
143954
144087
144464
144530
144559
144588
144695
144972
145152
145173
145363
145856
145906
145972
146128
147093
147271
147305
147542
148495
150254
150381
150619
150909
152791
153028
153430
153762
153994
154703
157324
158709
158714
160098
160205
160537
160549
161287
161411
162151
162534
163313
163800
164407
164700
165026
166664
167344
168163
169013
169806
170100
170814
171628
172426
172765
173046
173944
174566
175304
176905
176937
179891
180700
181385
181750
182282
182523
183675
185111
185718
185985
186620
186770
187330
187806
188000
189440
189750
190120
190535
190736
193213
194105
195246
196486
196681
196783
198367
198757
199316
200032
200128
200146
200230
200779
201439
201486
201492
201675
202423
202737
203632
203823
204090
204104
204244
205434
205650
205662
205690
205816
206300
207690
207812
210018
210075
210252
210515
211465
211630
212142
212645
212698
212737
212916
213290
213303
214106
214652
215175
215400
215435
215563
215615
215638
215887
216152
216360
216547
216565
217087
217405
217460
218419
218618
219046
219249
220021
220488
220955
221094
221389
221707
221865
221880
221962
222094
223107
223605
223887
223975
224173
224776
224939
225247
225987
226009
226177
226718
227111
227128
227132
228374
229079
229400
229426
229439
229793
229860
230204
230856
231037
231364
231711
231822
232289
232809
234271
234705
234825
234850
234904
235027
235253
235541
235671
235834
235976
237263
237963
238051
238223
238466
238523
238725
240199
240364
240780
241044
241552
241722
241737
242173
242409
242689
242793
243013
243089
243110
243139
243558
243581
243751
243885
244038
244055
244345
244364
244522
244558
245015
245080
245338
245572
245668
245690
245761
246157
246472
246601
246918
247286
247318
247382
248501
248569
248597
248857
248930
250070
250130
250375
250420
250435
250622
250640
251145
251200
252020
252100
252205
252820
252840
253035
253175
253185
253365
253615
253630
253660
253715
253735
253910
254110
254440
254900
254985
255080
255310
255470
255565
256040
256135
256570
256970
257070
257515
257715
258133
258395
258465
258480
258915
259090
259510
260507
260691
261071
262573
262780
263245
264698
264950
265168
266779
267369
268988
269171
270706
272174
272999
273850
274399
280325
280734
280907
281582
283029
283951
284229
284987
285728
286055
287079
288816
290692
290858
291469
291515
291664
291813
291887
292608
292848
293265
293294
293368
294369
294426
294862
295150
295273
295960
295965
296435
297323
297610
297867
298107
298387
298501
298535
299156
299165
300023
300042
300085
300093
300183
300321
300443
300687
300889
300937
301012
301185
301401
301752
301799
301966
301974
302060
302129
302610
303033
303184
303259
303319
303773
304102
304174
304555
304647
304791
304796
304844
304912
304996
305113
305426
305512
305801
306085
306164
306314
306774
306820
307167
307484
307633
308248
308383
308600
308631
308737
308906
308910
308944
309000
309292
309670
310090
311458
311677
312635
312719
313017
313510
313969
313976
314055
314684
314938
315123
315177
315340
315356
315771
315830
315838
315890
317202
317615
317994
318113
318292
318500
318694
319147
319476
320941
321408
321871
322188
322365
323207
323287
323594
323621
324178
324203
324418
324958
325220
325479
326015
326155
326255
326315
326947
327530
328792
329100
329445
331072
331152
331541
331592
331890
332098
332119
332791
333375
333758
333780
334189
335041
335297
335315
336118
336196
336600
336781
338313
338534
338552
338769
338822
338830
339312
340017
340179
340256
340292
340548
340593
340908
341243
341504
341724
341828
342678
342912
342944
343497
343628
343821
343871
344055
344204
344235
344298
344573
344766
344861
345063
345509
345779
345855
346130
346139
346278
346629
346638
346670
346926
346935
347012
347254
348501
348677
349395
349422
349445
350304
350328
350412
350694
351055
351433
351765
351862
351897
351946
352135
352406
352440
352997
353095
353445
353770
353827
353847
354003
354506
354670
355162
355362
355384
355593
355734
356032
356073
356426
356634
356883
356907
357169
357331
358466
358494
358746
358797
358997
360106
361354
362537
362682
363028
363526
364385
364896
365915
366233
366689
367029
367322
367477
367931
368449
368596
368905
369050
369298
369408
369464
369728
369933
370896
374266
376698
380074
380165
380559
380764
381277
381310
381549
381588
381770
381944
381997
382260
383468
383747
383754
384690
384753
385017
385200
386209
386527
387631
387722
388426
388440
388887
389327
389350
389469
390020
390043
390128
391392
391739
391972
392429
392797
392927
393029
393217
393832
394007
394037
394516
395456
395481
395536
395891
396170
396597
396947
398622
398932
399442
401790
402024
402108
402202
402489
402589
404561
405187
405882
406371
406534
407884
409155
409219
409502
410120
410144
410174
410493
410498
410639
410832
410902
411000
411048
411138
411528
411772
412015
412019
412121
412266
412598
412679
412797
412906
413063
413183
413280
413420
413734
413873
413992
415018
415196
415272
415429
415618
415707
415869
415875
416135
416276
416794
416892
417079
417336
417622
417945
418201
418433
418692
418910
419532
420086
420738
420788
421731
422101
422253
422592
422726
422828
422996
423418
423611
423809
424508
424856
425065
425186
425402
425477
425733
425752
425826
426135
426404
426601
426686
427260
427516
427559
427714
427729
427909
428119
428705
428771
428973
429111
429382
429595
429717
431081
431243
431360
431580
432769
437054
437607
437612
440766
440993
441209
441593
442208
442245
442941
443192
444101
444128
444876
444909
446139
446626
446712
447338
448062
449151
449263
450008
450587
450729
450945
451233
451276
451484
451504
451630
451666
451939
452007
452030
452505
452675
452914
453222
454154
454748
454764
454769
455224
455946
456039
456096
456610
456624
456678
456789
456914
457059
457267
457458
457507
457773
457938
458059
458207
458773
458928
459012
459074
459238
459376
461220
461330
463544
465224
465626
465707
466867
466989
467029
468384
469368
469610
469683
470349
470991
471078
472001
472839
473405
474546
475017
475120
475255
475474
475516
475808
475932
476208
476330
476718
476827
476922
478027
478110
478827
478919
480140
480540
480552
481675
481730
481840
481905
482595
482715
483100
484065
485345
485415
485830
486195
486440
486660
487115
487240
487260
487388
487760
487845
487990
488160
488995
489615
489770
489905

About Tony Heller

Just having fun
This entry was posted in Uncategorized. Bookmark the permalink.

12 Responses to GHCN Code

  1. Eric Barnes says:

    Cool Steven! Thanks!

  2. tckev says:

    This is outrageous. Real climate scientists do not publish their methods – surely you know that.

    Oh, I forgot your not publicly funded, friend-reviewed, and behind a paywall so you can’t be a ‘real’ scientist.

  3. Chuck L says:

    Wow, Big Oil must have (not) paid you a fortune to write this code!

  4. johnmcguire says:

    Steven , as I’m not very computer literate I had no idea what you had to deal with , makes me appreciate the information I get from this site even more . Thank You

  5. squid2112 says:

    Thanks Steven! … I can follow this .. not too badly written.. 🙂

  6. Translate it into assembler – it’ll make more sense to me.

  7. Michael D Smith says:

    Can you post as a .zip like you did here? https://rapidshare.com/files/3964715866/code.zip

    That would presumably fix the formatting problem

  8. Michael D Smith says:

    I use divshare.com, or even google drive http://drive.google.com . Both allow big files and will allow you to share links to specific files or just to certain people without giving access to everything. Google drive ends up looking like just another windows drive, kind of nice…

    Might not be needed Steve, I will try to get it to work the way it is…

    Thanks.

  9. For sharing code, I’d put it up on something like Sourceforge, Bitbucket or Github.

  10. Richard T. Fowler says:

    I like it just like it is, posted here! Thanks a million, Steven!

    RTF

Leave a Reply to johnmcguireCancel reply