Example #1
0
import ghcnpy

# Provide introduction
ghcnpy.intro()

# Print Latest Version
ghcnpy.get_ghcnd_version()

# Testing Search Capabilities
print("\nTESTING SEARCH CAPABILITIES")
ghcnpy.find_station("Asheville")

# Testing Search Capabilities
print("\nTESTING PULL CAPABILITIES")
outfile = ghcnpy.get_data_station("USW00003812")
print(outfile, " has been downloaded")
Example #2
0
def output_to_netcdf(station_id):
    print "\nOUTPUTTING TO netCDF: ", station_id, ".nc"

    begin_year = 1700
    end_year = datetime.datetime.now().year
    num_years = (end_year - begin_year) + 1

    start_date = date(begin_year, 01, 01)
    end_date = date(end_year, 12, 31)

    # 5 Elements of GHCN-D
    num_elements = 5
    tmax = 0
    tmin = 1
    prcp = 2
    snow = 3
    snwd = 4

    # 3 Flags for each value
    num_flags = 3

    # Measurement Flag (MFLAG)
    mflag = 0
    mflag_codes = np.array(
        [ord(x) for x in ["B", "D", "H", "K", "L", "O", "P", "T", "W"]],
        dtype='b')
    mflag_meanings = np.array(["precipitation total formed from two 12 hour totals".replace(" ","_")+" ",\
          "precipitation total formed from four six hour totals".replace(" ","_")+" ",\
          "represents highest or lowest hourly temperature".replace(" ","_")+" ",\
          "converted from knots".replace(" ","_")+" ",\
          "temperature appears to be lagged with respect to reported hour of observation".replace(" ","_")+" ",\
          "converted from oktas".replace(" ","_")+" ",\
          "identified as missing presumed zero in DSI 3200 and 3206".replace(" ","_")+" ",\
          "trace of precipitation snowfall or snow depth".replace(" ","_")+" ",\
          "converted from 16 point WBAN code for wind direction".replace(" ","_")],\
          dtype='str')

    # Quality Control Flag (QCFLAG)
    qcflag = 1
    qcflag_codes = np.array([
        ord(x) for x in
        ["D", "G", "I", "K", "L", "M", "N", "O", "R", "S", "T", "W", "X", "Z"]
    ],
                            dtype='b')
    qcflag_meanings = np.array(["failed duplicate check".replace(" ","_")+" ",\
           "failed gap check".replace(" ","_")+" ",\
           "failed internal consistency check".replace(" ","_")+" ",\
           "failed streak frequent value check".replace(" ","_")+" ",\
           "failed check on length of multiday period".replace(" ","_")+" ",\
           "failed megaconsistency check".replace(" ","_")+" ",\
           "failed naught check".replace(" ","_")+" ",\
           "failed climatological outlier check".replace(" ","_")+" ",\
           "failed lagged range check".replace(" ","_")+" ",\
           "failed spatial consistency check".replace(" ","_")+" ",\
           "failed temporal consistency check".replace(" ","_")+" ",\
           "failed bounds check".replace(" ","_")+" ",\
           "failed climatological outlier check".replace(" ","_")+" ",\
           "flagged as a result of an official Datzilla investigation".replace(" ","_")],\
           dtype='str')

    # Source Flag (SRCFLAG)
    srcflag = 2
    srcflag_codes = np.array([ord(x) for x in ["0","6","7","A","a","B","b","C","E","F","G","H","I","K","M","N","Q","R","r","S","s",\
              "T","U","u","W","X","Z","z"]],dtype='b')
    srcflag_meanings = np.array(["US Cooperative Summary of the Day".replace(" ","_")+" ",\
            "CDMP Cooperative Summary of the Day".replace(" ","_")+" ",\
            "US Cooperative Summary of the Day Transmitted via WxCoder3".replace(" ","_")+" ",\
            "Automated Surface Observing System real time data since January 1 2006".replace(" ","_")+" ",\
            "Australian data from the Australian Bureau of Meteorology".replace(" ","_")+" ",\
            "US ASOS data for October 2000 to December 2005".replace(" ","_")+" ",\
            "Belarus update".replace(" ","_")+" ",\
            "Environment Canada".replace(" ","_")+" ",\
            "European Climate Assessment and Dataset".replace(" ","_")+" ",\
            "US Fort data".replace(" ","_")+" ",\
            "Official Global Climate Observing System".replace(" ","_")+" ",\
            "High Plains Regional Climate Center real time data".replace(" ","_")+" ",\
            "International collection non U.S. data received through personal contacts".replace(" ","_")+" ",\
            "US Cooperative Summary of the Day data digitized from paper observer forms".replace(" ","_")+" ",\
            "Monthly METAR Extract".replace(" ","_")+" ",\
            "Community Collaborative Rain Hail and Snow".replace(" ","_")+" ",\
            "Data from several African countries that had been quarantined".replace(" ","_")+" ",\
            "Climate Reference Network and Historical Climatology Network Modernized".replace(" ","_")+" ",\
            "All Russian Research Institute of Hydrometeorological Information World Data Center".replace(" ","_")+" ",\
            "Global Summary of the Day".replace(" ","_")+" ",\
            "China Meteorological Administration National Meteorological Information Center".replace(" ","_")+" ",\
            "SNOwpack TELemtry data obtained from the Western Regional Climate Center".replace(" ","_")+" ",\
            "Remote Automatic Weather Station data obtained from the Western Regional Climate Center".replace(" ","_")+" ",\
            "Ukraine update".replace(" ","_")+" ",\
            "WBAN ASOS Summary of the Day from Integrated Surface Data ISD".replace(" ","_")+" ",\
            "US First Order Summary of the Day".replace(" ","_")+" ",\
            "Datzilla official additions or replacements".replace(" ","_")+" ",\
            "Uzbekistan update ".replace(" ","_")],\
         dtype='str')

    # Get Version Number of GHCN-D
    ghcnd_version = gp.get_ghcnd_version()

    # Grab Data
    gp.get_data_station(station_id)

    # Read in GHCN-D Data
    infile = station_id + ".dly"

    file_handle = open(infile, 'r')
    ghcnd_contents = file_handle.readlines()
    file_handle.close()

    # Get Year Start and End of File for time dimensions
    station_start_year = int(ghcnd_contents[0][11:15])
    station_end_year = int(ghcnd_contents[len(ghcnd_contents) - 1][11:15])
    station_start_month = int(ghcnd_contents[0][15:17])
    station_end_month = int(ghcnd_contents[len(ghcnd_contents) - 1][15:17])

    num_values = 0
    results_time = np.zeros((num_years * 12 * 31), dtype='f') - (9999.0)
    results_pos = np.zeros((num_years, 12, 31), dtype='f') - (9999.0)
    for year in xrange(station_start_year, station_end_year + 1):
        year_counter = int(year - station_start_year)

        if year == station_start_year:
            begin_month = int(station_start_month - 1)
        else:
            begin_month = 0

        if year == station_end_year:
            end_month = int(station_end_month)
        else:
            end_month = 12

        for month_counter in xrange(begin_month, end_month):
            month = month_counter + 1
            for day_counter in xrange(0, 31):
                day = day_counter + 1
                try:
                    current_date = date(year, month, day)
                    num_days = (current_date - start_date).days
                    results_time[num_values] = num_days
                    results_pos[year_counter, month_counter,
                                day_counter] = int(num_values)
                    num_values += 1
                except:
                    pass

    #################################################
    # Open netCDF file
    outfile = station_id + '.nc'
    test = os.path.exists(outfile)
    if test == True:
        os.remove(outfile)
    output = nc.Dataset(outfile, mode='w')

    #################################################
    # Create global attributes
    output.title = "Global Historical Climatology Network - Daily Dataset"
    output.summary = "GHCN-Daily is an integrated database of daily climate summaries from land surface stations across the globe. "+\
                     "GHCN-Daily is comprised of daily climate records from numerous sources that have been integrated and "+\
                     "subjected to a common suite of quality assurance reviews. This dataset includes the top five core elements: "+\
                     "PRCP (precipitation), SNOW (snowfall), SNWD (snow depth), TMAX (maximum temperature), TMIN (minimum temperature)"
    output.version = ghcnd_version
    output.keywords = "daily, station, extremes, temperature, precipitation, snowfall, snow depth"
    output.Conventions = "CF-1.6, ACDD-1.3"
    output.institution = "Cooperative Institute for Climate and Satellites - North Carolina (CICS-NC) and "+\
                         "NOAAs National Centers for Environmental Information (NCEI), Asheville, North Carolina, USA"
    output.source = "surface observations from multiple sources around the globe"
    output.featureType = "timeSeries"
    output.history = "File generatred on ", str(datetime.datetime.now())
    output.creator_name = "Jared Rennie, CICS-NC"
    output.creator_email = "*****@*****.**"
    output.creator_url = "http://www.cicsnc.org/people/jared-rennie/"
    output.references = "Menne et al 2012: http://dx.doi.org/10.1175/JTECH-D-11-00103.1"
    output.comment = "More information can be found here: ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt"

    #################################################
    # Create Dimensions
    output.createDimension('element', num_elements)
    output.createDimension('time', num_values)
    output.createDimension('name_strlen', 30)
    output.createDimension('id_strlen', 11)

    #################################################
    # Create Variables

    # LON
    lon_var = output.createVariable('lon', datatype='f')
    lon_var.standard_name = "longitude"
    lon_var.long_name = "station longitude"
    lon_var.units = "degrees_east"

    # LAT
    lat_var = output.createVariable('lat', datatype='f')
    lat_var.standard_name = "latitude"
    lat_var.long_name = "station latitude"
    lat_var.units = "degrees_north"

    # ELEV (ALT)
    alt_var = output.createVariable('alt', datatype='f')
    alt_var.long_name = "vertical distance above the surface"
    alt_var.standard_name = "height"
    alt_var.units = "m"
    alt_var.positive = "up"
    alt_var.axis = "Z"

    # ID
    id_var = output.createVariable('id',
                                   datatype='S1',
                                   dimensions=('id_strlen'))
    id_var.long_name = "station identifier"

    # NAME
    name_var = output.createVariable('station_name',
                                     datatype='S1',
                                     dimensions=('name_strlen'))
    name_var.long_name = "station name"
    name_var.cf_role = "timeseries_id"

    # TIME
    time_var = output.createVariable('time', datatype='f8', dimensions='time')
    time_var.standard_name = "time"
    time_var.long_name = "Time of Measurement"
    time_var.units = "days since ", begin_year, "-01-01 00:00:00"
    time_var.calendar = "gregorian"
    time_var.axis = "T"
    time_var[:] = results_time[0:num_values]
    time_var.valid_min = np.min(results_time[0:num_values])

    # FLAGS
    mflag_var = output.createVariable('mflag',
                                      datatype='b',
                                      dimensions=('time', 'element'),
                                      fill_value=32.)
    mflag_var.long_name = "measurement flag"
    mflag_var.flag_values = mflag_codes
    mflag_var.flag_meanings = mflag_meanings

    qcflag_var = output.createVariable('qcflag',
                                       datatype='b',
                                       dimensions=('time', 'element'),
                                       fill_value=32.)
    qcflag_var.long_name = "quality control flag"
    qcflag_var.flag_values = qcflag_codes
    qcflag_var.flag_meanings = qcflag_meanings

    srcflag_var = output.createVariable('srcflag',
                                        datatype='b',
                                        dimensions=('time', 'element'),
                                        fill_value=32.)
    srcflag_var.long_name = "source flag"
    srcflag_var.flag_values = srcflag_codes
    srcflag_var.flag_meanings = srcflag_meanings

    # TMAX
    tmax_var = output.createVariable('tmax',
                                     datatype='f',
                                     dimensions=('time'),
                                     fill_value=-9999.)
    tmax_var.long_name = "surface maximum temperature"
    tmax_var.units = "Celsius"
    tmax_var.coordinates = "time lat lon alt station_name"
    tmax_var.ancillary_variables = "mflag qcflag srcflag"

    # TMIN
    tmin_var = output.createVariable('tmin',
                                     datatype='f',
                                     dimensions=('time'),
                                     fill_value=-9999.)
    tmin_var.long_name = "surface minimum temperature"
    tmin_var.units = "Celsius"
    tmin_var.coordinates = "time lat lon alt station_name"
    tmin_var.ancillary_variables = "mflag qcflag srcflag"

    # PRCP
    prcp_var = output.createVariable('prcp',
                                     datatype='f',
                                     dimensions=('time'),
                                     fill_value=-9999.)
    prcp_var.long_name = "surface precipitation"
    prcp_var.units = "mm"
    prcp_var.coordinates = "time lat lon alt station_name"
    prcp_var.ancillary_variables = "mflag qcflag srcflag"

    # SNOW
    snow_var = output.createVariable('snow',
                                     datatype='f',
                                     dimensions=('time'),
                                     fill_value=-9999.)
    snow_var.long_name = "surface snowfall"
    snow_var.units = "mm"
    snow_var.coordinates = "time lat lon alt station_name"
    snow_var.ancillary_variables = "mflag qcflag srcflag"

    # SNWD
    snwd_var = output.createVariable('snwd',
                                     datatype='f',
                                     dimensions=('time'),
                                     fill_value=-9999.)
    snwd_var.long_name = "surface snow depth"
    snwd_var.units = "mm"
    snwd_var.coordinates = "time lat lon alt station_name"
    snwd_var.ancillary_variables = "mflag qcflag srcflag"

    #################################################
    # Read in GHCN-D Meta
    ghcnd_stations = gp.get_ghcnd_stations()
    ghcnd_meta = ghcnd_stations[ghcnd_stations[:, 0] == station_id]

    ghcnd_id = ghcnd_meta[0][0]
    ghcnd_lat = float(ghcnd_meta[0][1])
    ghcnd_lon = float(ghcnd_meta[0][2])
    ghcnd_alt = float(ghcnd_meta[0][3])
    ghcnd_name = ghcnd_meta[0][5]
    ghcnd_name = ghcnd_name.strip()
    ghcnd_name = re.sub(' +', ' ', ghcnd_name)
    ghcnd_name = ghcnd_name.replace(" ", "_")

    for string_counter in xrange(0, len(ghcnd_id)):
        id_var[string_counter] = ghcnd_id[string_counter]
    lat_var[:] = ghcnd_lat
    lon_var[:] = ghcnd_lon
    alt_var[:] = ghcnd_alt
    for string_counter in xrange(0, len(ghcnd_name)):
        name_var[string_counter] = ghcnd_name[string_counter]

    #################################################
    # Go through GHCN-D Data
    ghcnd_data = np.zeros((num_values, num_elements), dtype='f') - (9999.0)
    ghcnd_flag = np.zeros(
        (num_values, num_elements, num_flags), dtype='i') + 32

    for counter in xrange(len(ghcnd_contents)):
        element = ghcnd_contents[counter][17:21]

        if element == "TMAX" or element == "TMIN" or element == "PRCP" or element == "SNOW" or element == "SNWD":
            if element == "TMAX":
                element_counter = tmax
                divisor = 10.0
            if element == "TMIN":
                element_counter = tmin
                divisor = 10.0
            if element == "PRCP":
                element_counter = prcp
                divisor = 10.0
            if element == "SNOW":
                element_counter = snow
                divisor = 1.0
            if element == "SNWD":
                element_counter = snwd
                divisor = 1.0

            year = int(ghcnd_contents[counter][11:15])
            year_counter = int(year - station_start_year)
            month = int(ghcnd_contents[counter][15:17])
            month_counter = int(month - 1)

            char = 21
            for day_counter in xrange(0, 31):
                time_pos = results_pos[year_counter, month_counter,
                                       day_counter]

                # Get Values / Flags
                if ghcnd_contents[counter][char:char + 5] != "-9999":
                    ghcnd_data[time_pos, element_counter] = float(
                        ghcnd_contents[counter][char:char + 5]) / divisor
                    ghcnd_flag[time_pos, element_counter, mflag] = ord(
                        ghcnd_contents[counter][char + 5:char + 6])
                    ghcnd_flag[time_pos, element_counter, qcflag] = ord(
                        ghcnd_contents[counter][char + 6:char + 7])
                    ghcnd_flag[time_pos, element_counter, srcflag] = ord(
                        ghcnd_contents[counter][char + 7:char + 8])
                char = char + 8

    #################################################
    # Assign data to netCDF variables
    tmax_var[:] = ghcnd_data[:, tmax]
    tmax_var.valid_min = np.min(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, tmax, qcflag] != ord(" "),
                               ghcnd_data[:, tmax]), -9999))
    tmax_var.valid_max = np.max(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, tmax, qcflag] != ord(" "),
                               ghcnd_data[:, tmax]), -9999))

    tmin_var[:] = ghcnd_data[:, tmin]
    tmin_var.valid_min = np.min(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, tmin, qcflag] != ord(" "),
                               ghcnd_data[:, tmin]), -9999))
    tmin_var.valid_max = np.max(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, tmin, qcflag] != ord(" "),
                               ghcnd_data[:, tmin]), -9999))

    prcp_var[:] = ghcnd_data[:, prcp]
    prcp_var.valid_min = np.min(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, prcp, qcflag] != ord(" "),
                               ghcnd_data[:, prcp]), -9999))
    prcp_var.valid_max = np.max(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, prcp, qcflag] != ord(" "),
                               ghcnd_data[:, prcp]), -9999))

    snow_var[:] = ghcnd_data[:, snow]
    snow_var.valid_min = np.min(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, snow, qcflag] != ord(" "),
                               ghcnd_data[:, snow]), -9999))
    snow_var.valid_max = np.max(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, snow, qcflag] != ord(" "),
                               ghcnd_data[:, snow]), -9999))

    snwd_var[:] = ghcnd_data[:, snwd]
    snwd_var.valid_min = np.min(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, snwd, qcflag] != ord(" "),
                               ghcnd_data[:, snwd]), -9999))
    snwd_var.valid_max = np.max(
        np.ma.masked_equal(
            np.ma.masked_where(ghcnd_flag[:, snwd, qcflag] != ord(" "),
                               ghcnd_data[:, snwd]), -9999))

    mflag_var[:, :] = ghcnd_flag[:, :, mflag]
    qcflag_var[:, :] = ghcnd_flag[:, :, qcflag]
    srcflag_var[:, :] = ghcnd_flag[:, :, srcflag]

    #################################################
    # Close netCDF file
    output.close()

    return None
Example #3
0
import ghcnpy

# Provide introduction
ghcnpy.intro()

# Print Latest Version
ghcnpy.get_ghcnd_version()

# Testing Search Capabilities
print("\nTESTING SEARCH CAPABILITIES")
ghcnpy.find_station("Asheville")

# Testing Search Capabilities
print("\nTESTING PULL CAPABILITIES")
outfile=ghcnpy.get_data_station("USW00003812")
print(outfile," has been downloaded")
Example #4
0
def output_to_csv(station_id):
    print "\nOUTPUTTING TO CSV: ", station_id, ".csv"

    # 5 Elements of GHCN-D
    num_elements = 5
    tmax = 0
    tmin = 1
    prcp = 2
    snow = 3
    snwd = 4

    # Grab Data
    gp.get_data_station(station_id)

    # Read in GHCN-D Data
    infile = station_id + ".dly"

    file_handle = open(infile, 'r')
    ghcnd_contents = file_handle.readlines()
    file_handle.close()

    # Get Year Start and End of File for time dimensions
    ghcnd_begin_year = int(ghcnd_contents[0][11:15])
    ghcnd_end_year = int(ghcnd_contents[len(ghcnd_contents) - 1][11:15])
    num_years = int((ghcnd_end_year - ghcnd_begin_year) + 1)

    # Go through GHCN-D Data
    ghcnd_data = np.zeros(
        (num_years, 12, 31, num_elements), dtype='f') - (9999.0)

    for counter in xrange(len(ghcnd_contents)):
        element = ghcnd_contents[counter][17:21]

        if element == "TMAX" or element == "TMIN" or element == "PRCP" or element == "SNOW" or element == "SNWD":
            if element == "TMAX":
                element_counter = tmax
                divisor = 10.0
            if element == "TMIN":
                element_counter = tmin
                divisor = 10.0
            if element == "PRCP":
                element_counter = prcp
                divisor = 10.0
            if element == "SNOW":
                element_counter = snow
                divisor = 1.0
            if element == "SNWD":
                element_counter = snwd
                divisor = 1.0

            year = int(ghcnd_contents[counter][11:15])
            year_counter = int(year - ghcnd_begin_year)
            month = int(ghcnd_contents[counter][15:17])
            month_counter = int(month - 1)

            char = 21
            for day_counter in xrange(0, 31):
                if ghcnd_contents[counter][char:char +
                                           5] != "-9999" and ghcnd_contents[
                                               counter][char + 6:char +
                                                        7].strip() == "":
                    ghcnd_data[year_counter, month_counter, day_counter,
                               element_counter] = float(
                                   ghcnd_contents[counter][char:char +
                                                           5]) / divisor
                char = char + 8

    # Print out data to csv file
    outfile_data = station_id + '.csv'
    out_data = open(outfile_data, 'w')
    out_data.write("YYYY,MM,DD,TMAX,TMIN,PRCP,SNOW,SNWD\n")
    for year_counter in xrange(0, num_years):
        for month_counter in xrange(0, 12):
            for day_counter in xrange(0, 31):

                # Print Out
                if (ghcnd_data[year_counter,month_counter,day_counter,tmax] != -9999. or \
                    ghcnd_data[year_counter,month_counter,day_counter,tmin] != -9999. or \
                    ghcnd_data[year_counter,month_counter,day_counter,prcp] != -9999. or \
                    ghcnd_data[year_counter,month_counter,day_counter,snow] != -9999. or \
                    ghcnd_data[year_counter,month_counter,day_counter,snwd] != -9999.):
                    out_data.write("%04i,%02i,%02i,%7.1f,%7.1f,%7.1f,%7.1f,%7.1f\n" % \
                       (year_counter+ghcnd_begin_year,month_counter+1,day_counter+1,\
                       ghcnd_data[year_counter,month_counter,day_counter,tmax],\
                       ghcnd_data[year_counter,month_counter,day_counter,tmin],\
                       ghcnd_data[year_counter,month_counter,day_counter,prcp],\
                       ghcnd_data[year_counter,month_counter,day_counter,snow],\
                       ghcnd_data[year_counter,month_counter,day_counter,snwd]))
    out_data.close()
    return None
Example #5
0
def output_to_netcdf(station_id):
  print("\nOUTPUTTING TO netCDF: ",station_id,".nc")

  begin_year=1700
  end_year=datetime.datetime.now().year
  num_years=(end_year-begin_year) + 1

  start_date=date(begin_year, 1, 1)
  end_date=date(end_year,12,31)

  # 5 Elements of GHCN-D
  num_elements=5
  tmax=0
  tmin=1
  prcp=2
  snow=3
  snwd=4

  # 3 Flags for each value
  num_flags=3

  # Measurement Flag (MFLAG)
  mflag=0
  mflag_codes = np.array([ord(x) for x in ["B","D","H","K","L","O","P","T","W"]],dtype='b')
  mflag_meanings = np.array(["precipitation total formed from two 12 hour totals".replace(" ","_")+" ",\
                             "precipitation total formed from four six hour totals".replace(" ","_")+" ",\
                             "represents highest or lowest hourly temperature".replace(" ","_")+" ",\
                             "converted from knots".replace(" ","_")+" ",\
                             "temperature appears to be lagged with respect to reported hour of observation".replace(" ","_")+" ",\
                             "converted from oktas".replace(" ","_")+" ",\
                             "identified as missing presumed zero in DSI 3200 and 3206".replace(" ","_")+" ",\
                             "trace of precipitation snowfall or snow depth".replace(" ","_")+" ",\
                             "converted from 16 point WBAN code for wind direction".replace(" ","_")],\
                             dtype='str')

  # Quality Control Flag (QCFLAG)
  qcflag=1
  qcflag_codes = np.array([ord(x) for x in ["D","G","I","K","L","M","N","O","R","S","T","W","X","Z"]],dtype='b')
  qcflag_meanings = np.array(["failed duplicate check".replace(" ","_")+" ",\
                              "failed gap check".replace(" ","_")+" ",\
                              "failed internal consistency check".replace(" ","_")+" ",\
                              "failed streak frequent value check".replace(" ","_")+" ",\
                              "failed check on length of multiday period".replace(" ","_")+" ",\
                              "failed megaconsistency check".replace(" ","_")+" ",\
                              "failed naught check".replace(" ","_")+" ",\
                              "failed climatological outlier check".replace(" ","_")+" ",\
                              "failed lagged range check".replace(" ","_")+" ",\
                              "failed spatial consistency check".replace(" ","_")+" ",\
                              "failed temporal consistency check".replace(" ","_")+" ",\
                              "failed bounds check".replace(" ","_")+" ",\
                              "failed climatological outlier check".replace(" ","_")+" ",\
                              "flagged as a result of an official Datzilla investigation".replace(" ","_")],\
                              dtype='str')

  # Source Flag (SRCFLAG)
  srcflag=2
  srcflag_codes = np.array([ord(x) for x in ["0","6","7","A","a","B","b","C","E","F","G","H","I","K","M","N","Q","R","r","S","s",\
                                             "T","U","u","W","X","Z","z"]],dtype='b')
  srcflag_meanings = np.array(["US Cooperative Summary of the Day".replace(" ","_")+" ",\
                               "CDMP Cooperative Summary of the Day".replace(" ","_")+" ",\
                               "US Cooperative Summary of the Day Transmitted via WxCoder3".replace(" ","_")+" ",\
                               "Automated Surface Observing System real time data since January 1 2006".replace(" ","_")+" ",\
                               "Australian data from the Australian Bureau of Meteorology".replace(" ","_")+" ",\
                               "US ASOS data for October 2000 to December 2005".replace(" ","_")+" ",\
                               "Belarus update".replace(" ","_")+" ",\
                               "Environment Canada".replace(" ","_")+" ",\
                               "European Climate Assessment and Dataset".replace(" ","_")+" ",\
                               "US Fort data".replace(" ","_")+" ",\
                               "Official Global Climate Observing System".replace(" ","_")+" ",\
                               "High Plains Regional Climate Center real time data".replace(" ","_")+" ",\
                               "International collection non U.S. data received through personal contacts".replace(" ","_")+" ",\
                               "US Cooperative Summary of the Day data digitized from paper observer forms".replace(" ","_")+" ",\
                               "Monthly METAR Extract".replace(" ","_")+" ",\
                               "Community Collaborative Rain Hail and Snow".replace(" ","_")+" ",\
                               "Data from several African countries that had been quarantined".replace(" ","_")+" ",\
                               "Climate Reference Network and Historical Climatology Network Modernized".replace(" ","_")+" ",\
                               "All Russian Research Institute of Hydrometeorological Information World Data Center".replace(" ","_")+" ",\
                               "Global Summary of the Day".replace(" ","_")+" ",\
                               "China Meteorological Administration National Meteorological Information Center".replace(" ","_")+" ",\
                               "SNOwpack TELemtry data obtained from the Western Regional Climate Center".replace(" ","_")+" ",\
                               "Remote Automatic Weather Station data obtained from the Western Regional Climate Center".replace(" ","_")+" ",\
                               "Ukraine update".replace(" ","_")+" ",\
                               "WBAN ASOS Summary of the Day from Integrated Surface Data ISD".replace(" ","_")+" ",\
                               "US First Order Summary of the Day".replace(" ","_")+" ",\
                               "Datzilla official additions or replacements".replace(" ","_")+" ",\
                               "Uzbekistan update ".replace(" ","_")],\
                            dtype='str')



  # Get Version Number of GHCN-D
  ghcnd_version=gp.get_ghcnd_version()

  # Grab Data
  gp.get_data_station(station_id)

  # Read in GHCN-D Data
  infile = station_id+".dly"

  file_handle = open(infile, 'r')
  ghcnd_contents = file_handle.readlines()
  file_handle.close()

  # Get Year Start and End of File for time dimensions
  station_start_year =  int(ghcnd_contents[0][11:15])
  station_end_year = int(ghcnd_contents[len(ghcnd_contents)-1][11:15])
  station_start_month =  int(ghcnd_contents[0][15:17])
  station_end_month = int(ghcnd_contents[len(ghcnd_contents)-1][15:17])

  num_values=0
  results_time = np.zeros((num_years*12*31),dtype='f')-(9999.0)
  results_pos = np.zeros((num_years,12,31),dtype='f')-(9999.0)
  for year in xrange(station_start_year,station_end_year+1):
    year_counter = int(year - station_start_year)

    if year == station_start_year:
      begin_month = int(station_start_month-1)
    else:
      begin_month = 0

    if year == station_end_year:
      end_month = int(station_end_month)
    else:
      end_month = 12

    for month_counter in xrange(begin_month,end_month):
      month = month_counter + 1
      for day_counter in xrange(0,31):
        day = day_counter + 1
        try:
          current_date=date(year,month,day)
          num_days = (current_date-start_date).days
          results_time[num_values] = num_days
          results_pos[year_counter,month_counter,day_counter] = int(num_values)
          num_values+=1
        except:
          pass

  #################################################
  # Open netCDF file
  outfile=station_id+'.nc'
  test=os.path.exists(outfile)
  if test == True:
    os.remove(outfile)
  output = nc.Dataset(outfile, mode='w')

  #################################################
  # Create global attributes
  output.title = "Global Historical Climatology Network - Daily Dataset"
  output.summary = "GHCN-Daily is an integrated database of daily climate summaries from land surface stations across the globe. "+\
                   "GHCN-Daily is comprised of daily climate records from numerous sources that have been integrated and "+\
                   "subjected to a common suite of quality assurance reviews. This dataset includes the top five core elements: "+\
                   "PRCP (precipitation), SNOW (snowfall), SNWD (snow depth), TMAX (maximum temperature), TMIN (minimum temperature)"
  output.version=ghcnd_version
  output.keywords = "daily, station, extremes, temperature, precipitation, snowfall, snow depth"
  output.Conventions = "CF-1.6, ACDD-1.3"
  output.institution = "Cooperative Institute for Climate and Satellites - North Carolina (CICS-NC) and "+\
                       "NOAAs National Centers for Environmental Information (NCEI), Asheville, North Carolina, USA"
  output.source = "surface observations from multiple sources around the globe"
  output.featureType = "timeSeries"
  output.history = "File generatred on ",str(datetime.datetime.now())
  output.creator_name = "Jared Rennie, CICS-NC"
  output.creator_email = "*****@*****.**"
  output.creator_url = "http://www.cicsnc.org/people/jared-rennie/"
  output.references= "Menne et al 2012: http://dx.doi.org/10.1175/JTECH-D-11-00103.1"
  output.comment="More information can be found here: ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/readme.txt"

  #################################################
  # Create Dimensions
  output.createDimension('element',num_elements)
  output.createDimension('time',num_values)
  output.createDimension('name_strlen',30)
  output.createDimension('id_strlen',11)

  #################################################
  # Create Variables

  # LON
  lon_var = output.createVariable('lon', datatype='f')
  lon_var.standard_name = "longitude"
  lon_var.long_name = "station longitude"
  lon_var.units = "degrees_east"

  # LAT
  lat_var = output.createVariable('lat', datatype='f')
  lat_var.standard_name = "latitude"
  lat_var.long_name = "station latitude"
  lat_var.units = "degrees_north"

  # ELEV (ALT)
  alt_var = output.createVariable('alt', datatype='f')
  alt_var.long_name = "vertical distance above the surface"
  alt_var.standard_name = "height"
  alt_var.units = "m"
  alt_var.positive = "up"
  alt_var.axis = "Z"

  # ID
  id_var = output.createVariable('id', datatype='S1', dimensions=('id_strlen'))
  id_var.long_name = "station identifier"

  # NAME
  name_var = output.createVariable('station_name', datatype='S1', dimensions=('name_strlen'))
  name_var.long_name = "station name"
  name_var.cf_role = "timeseries_id"

  # TIME
  time_var = output.createVariable('time', datatype='f8', dimensions='time')
  time_var.standard_name = "time"
  time_var.long_name = "Time of Measurement"
  time_var.units = "days since ",begin_year,"-01-01 00:00:00"
  time_var.calendar = "gregorian"
  time_var.axis = "T"
  time_var[:] = results_time[0:num_values]
  time_var.valid_min = np.min(results_time[0:num_values])

  # FLAGS
  mflag_var = output.createVariable('mflag', datatype='b', dimensions=('time','element'), fill_value=32.)
  mflag_var.long_name = "measurement flag"
  mflag_var.flag_values=mflag_codes
  mflag_var.flag_meanings=mflag_meanings

  qcflag_var = output.createVariable('qcflag', datatype='b', dimensions=('time','element'), fill_value=32.)
  qcflag_var.long_name = "quality control flag"
  qcflag_var.flag_values=qcflag_codes
  qcflag_var.flag_meanings=qcflag_meanings

  srcflag_var = output.createVariable('srcflag', datatype='b', dimensions=('time','element'), fill_value=32.)
  srcflag_var.long_name = "source flag"
  srcflag_var.flag_values=srcflag_codes
  srcflag_var.flag_meanings=srcflag_meanings

  # TMAX
  tmax_var = output.createVariable('tmax', datatype='f', dimensions=('time'), fill_value=-9999.)
  tmax_var.long_name = "surface maximum temperature"
  tmax_var.units = "Celsius"
  tmax_var.coordinates = "time lat lon alt station_name"
  tmax_var.ancillary_variables = "mflag qcflag srcflag"

  # TMIN
  tmin_var = output.createVariable('tmin', datatype='f', dimensions=('time'), fill_value=-9999.)
  tmin_var.long_name = "surface minimum temperature"
  tmin_var.units = "Celsius"
  tmin_var.coordinates = "time lat lon alt station_name"
  tmin_var.ancillary_variables = "mflag qcflag srcflag"

  # PRCP
  prcp_var = output.createVariable('prcp', datatype='f', dimensions=('time'), fill_value=-9999.)
  prcp_var.long_name = "surface precipitation"
  prcp_var.units = "mm"
  prcp_var.coordinates = "time lat lon alt station_name"
  prcp_var.ancillary_variables = "mflag qcflag srcflag"

  # SNOW
  snow_var = output.createVariable('snow', datatype='f', dimensions=('time'), fill_value=-9999.)
  snow_var.long_name = "surface snowfall"
  snow_var.units = "mm"
  snow_var.coordinates = "time lat lon alt station_name"
  snow_var.ancillary_variables = "mflag qcflag srcflag"

  # SNWD
  snwd_var = output.createVariable('snwd', datatype='f', dimensions=('time'), fill_value=-9999.)
  snwd_var.long_name = "surface snow depth"
  snwd_var.units = "mm"
  snwd_var.coordinates = "time lat lon alt station_name"
  snwd_var.ancillary_variables = "mflag qcflag srcflag"

  #################################################
  # Read in GHCN-D Meta
  ghcnd_stations=gp.get_ghcnd_stations()
  ghcnd_meta = ghcnd_stations[ghcnd_stations[:,0] == station_id]

  ghcnd_id=ghcnd_meta[0][0]
  ghcnd_lat=float(ghcnd_meta[0][1])
  ghcnd_lon=float(ghcnd_meta[0][2])
  ghcnd_alt=float(ghcnd_meta[0][3])
  ghcnd_name=ghcnd_meta[0][5]
  ghcnd_name = ghcnd_name.strip()
  ghcnd_name = re.sub(' +',' ',ghcnd_name)
  ghcnd_name = ghcnd_name.replace(" ","_")

  for string_counter in xrange(0,len(ghcnd_id)):
    id_var[string_counter] = ghcnd_id[string_counter]
  lat_var[:] = ghcnd_lat
  lon_var[:] = ghcnd_lon
  alt_var[:] = ghcnd_alt
  for string_counter in xrange(0,len(ghcnd_name)):
    name_var[string_counter] = ghcnd_name[string_counter]

  #################################################
  # Go through GHCN-D Data
  ghcnd_data= np.zeros((num_values,num_elements),dtype='f')-(9999.0)
  ghcnd_flag= np.zeros((num_values,num_elements,num_flags),dtype='i')+32

  for counter in xrange(len(ghcnd_contents)):
    element = ghcnd_contents[counter][17:21]

    if element == "TMAX" or element == "TMIN" or element == "PRCP" or element == "SNOW" or element == "SNWD":
      if element == "TMAX":
        element_counter=tmax
        divisor = 10.0
      if element == "TMIN":
        element_counter=tmin
        divisor = 10.0
      if element == "PRCP":
        element_counter=prcp
        divisor = 10.0
      if element == "SNOW":
        element_counter=snow
        divisor = 1.0
      if element == "SNWD":
        element_counter=snwd
        divisor = 1.0

      year = int(ghcnd_contents[counter][11:15])
      year_counter = int(year - station_start_year)
      month = int(ghcnd_contents[counter][15:17])
      month_counter = int(month - 1)

      char=21
      for day_counter in xrange(0,31):
        time_pos=results_pos[year_counter,month_counter,day_counter]

        # Get Values / Flags
        if ghcnd_contents[counter][char:char+5] != "-9999":
          ghcnd_data[time_pos,element_counter] = float(ghcnd_contents[counter][char:char+5]) / divisor
          ghcnd_flag[time_pos,element_counter,mflag] = ord(ghcnd_contents[counter][char+5:char+6])
          ghcnd_flag[time_pos,element_counter,qcflag] = ord(ghcnd_contents[counter][char+6:char+7])
          ghcnd_flag[time_pos,element_counter,srcflag] = ord(ghcnd_contents[counter][char+7:char+8])
        char = char + 8

  #################################################
  # Assign data to netCDF variables
  tmax_var[:] = ghcnd_data[:,tmax]
  tmax_var.valid_min = np.min(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,tmax,qcflag]!=ord(" "),ghcnd_data[:,tmax]),-9999))
  tmax_var.valid_max = np.max(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,tmax,qcflag]!=ord(" "),ghcnd_data[:,tmax]),-9999))

  tmin_var[:] = ghcnd_data[:,tmin]
  tmin_var.valid_min = np.min(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,tmin,qcflag]!=ord(" "),ghcnd_data[:,tmin]),-9999))
  tmin_var.valid_max = np.max(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,tmin,qcflag]!=ord(" "),ghcnd_data[:,tmin]),-9999))

  prcp_var[:] = ghcnd_data[:,prcp]
  prcp_var.valid_min = np.min(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,prcp,qcflag]!=ord(" "),ghcnd_data[:,prcp]),-9999))
  prcp_var.valid_max = np.max(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,prcp,qcflag]!=ord(" "),ghcnd_data[:,prcp]),-9999))

  snow_var[:] = ghcnd_data[:,snow]
  snow_var.valid_min = np.min(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,snow,qcflag]!=ord(" "),ghcnd_data[:,snow]),-9999))
  snow_var.valid_max = np.max(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,snow,qcflag]!=ord(" "),ghcnd_data[:,snow]),-9999))

  snwd_var[:] = ghcnd_data[:,snwd]
  snwd_var.valid_min = np.min(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,snwd,qcflag]!=ord(" "),ghcnd_data[:,snwd]),-9999))
  snwd_var.valid_max = np.max(np.ma.masked_equal(np.ma.masked_where(ghcnd_flag[:,snwd,qcflag]!=ord(" "),ghcnd_data[:,snwd]),-9999))

  mflag_var[:,:] = ghcnd_flag[:,:,mflag]
  qcflag_var[:,:] = ghcnd_flag[:,:,qcflag]
  srcflag_var[:,:] = ghcnd_flag[:,:,srcflag]

  #################################################
  # Close netCDF file
  output.close()

  return None
Example #6
0
def output_to_csv(station_id):
  print("\nOUTPUTTING TO CSV: ",station_id,".csv")

  # 5 Elements of GHCN-D
  num_elements=5
  tmax=0
  tmin=1
  prcp=2
  snow=3
  snwd=4

  # Grab Data
  gp.get_data_station(station_id)

  # Read in GHCN-D Data
  infile = station_id+".dly"

  file_handle = open(infile, 'r')
  ghcnd_contents = file_handle.readlines()
  file_handle.close()

  # Get Year Start and End of File for time dimensions
  ghcnd_begin_year =  int(ghcnd_contents[0][11:15])
  ghcnd_end_year = int(ghcnd_contents[len(ghcnd_contents)-1][11:15])
  num_years = int((ghcnd_end_year - ghcnd_begin_year) + 1)

  # Go through GHCN-D Data
  ghcnd_data= np.zeros((num_years,12,31,num_elements),dtype='f')-(9999.0)

  for counter in xrange(len(ghcnd_contents)):
    element = ghcnd_contents[counter][17:21]

    if element == "TMAX" or element == "TMIN" or element == "PRCP" or element == "SNOW" or element == "SNWD":
      if element == "TMAX":
        element_counter=tmax
        divisor = 10.0
      if element == "TMIN":
        element_counter=tmin
        divisor = 10.0
      if element == "PRCP":
        element_counter=prcp
        divisor = 10.0
      if element == "SNOW":
        element_counter=snow
        divisor = 1.0
      if element == "SNWD":
        element_counter=snwd
        divisor = 1.0

      year = int(ghcnd_contents[counter][11:15])
      year_counter = int(year - ghcnd_begin_year)
      month = int(ghcnd_contents[counter][15:17])
      month_counter = int(month - 1)

      char=21
      for day_counter in xrange(0,31):
        if ghcnd_contents[counter][char:char+5] != "-9999" and ghcnd_contents[counter][char+6:char+7].strip() == "":
          ghcnd_data[year_counter,month_counter,day_counter,element_counter] = float(ghcnd_contents[counter][char:char+5]) / divisor
        char = char + 8

  # Print(out data to csv file)
  outfile_data = station_id+'.csv'
  out_data = open(outfile_data,'w')
  out_data.write("YYYY,MM,DD,TMAX,TMIN,PRCP,SNOW,SNWD\n")
  for year_counter in xrange(0,num_years):
    for month_counter in xrange(0,12):
      for day_counter in xrange(0,31):

        # Print(Out)
        if (ghcnd_data[year_counter,month_counter,day_counter,tmax] != -9999. or \
            ghcnd_data[year_counter,month_counter,day_counter,tmin] != -9999. or \
            ghcnd_data[year_counter,month_counter,day_counter,prcp] != -9999. or \
            ghcnd_data[year_counter,month_counter,day_counter,snow] != -9999. or \
            ghcnd_data[year_counter,month_counter,day_counter,snwd] != -9999.):
          out_data.write("%04i,%02i,%02i,%7.1f,%7.1f,%7.1f,%7.1f,%7.1f\n" % \
                   (year_counter+ghcnd_begin_year,month_counter+1,day_counter+1,\
                   ghcnd_data[year_counter,month_counter,day_counter,tmax],\
                   ghcnd_data[year_counter,month_counter,day_counter,tmin],\
                   ghcnd_data[year_counter,month_counter,day_counter,prcp],\
                   ghcnd_data[year_counter,month_counter,day_counter,snow],\
                   ghcnd_data[year_counter,month_counter,day_counter,snwd]))
  out_data.close()
  return None
Example #7
0
def plot_snowfall(station_id):
  print("\nPLOTTING SNOWFALL DATA FOR STATION: ",station_id)

  # Declare Other Variables
  begin_year=1895
  num_elements=1 # SNOW
  snow=0
  num_days=366

  end_year=datetime.now().year
  num_years=(end_year-begin_year) + 1

  # Get station metadatafile
  ghcnd_stations=gp.get_ghcnd_stations()

  ghcnd_meta = ghcnd_stations[ghcnd_stations[:,0] == station_id]
  ghcnd_id=ghcnd_meta[0][0]
  ghcnd_lat=float(ghcnd_meta[0][1])
  ghcnd_lon=float(ghcnd_meta[0][2])
  ghcnd_alt=float(ghcnd_meta[0][3])
  ghcnd_name=ghcnd_meta[0][5]
  ghcnd_name = ghcnd_name.strip()
  ghcnd_name = re.sub(' +',' ',ghcnd_name)
  ghcnd_name = ghcnd_name.replace(" ","_")

  # Grab Data
  gp.get_data_station(station_id)

  #################################################
  # Read in GHCN-D Data (Original, QC'd data removed)
  infile = station_id+".dly"
  ghcnd_value = np.zeros((num_years,12,31,num_elements),dtype='f')

  file_handle = open(infile, 'r')
  contents = file_handle.readlines()
  file_handle.close()

  valid_end=-9999
  valid_begin=9999
  for counter in xrange(len(contents)):

    element = contents[counter][17:21]

    if element == "SNOW":
      element_counter=snow

      year = int(contents[counter][11:15])
      year_counter = year-begin_year
      valid_begin=min(valid_begin,year)
      valid_end=max(valid_end,year)

      month = int(contents[counter][15:17])
      month_counter = month-1

      char=21
      for day_counter in xrange(0,31):
        if contents[counter][char:char+5] != "-9999" and contents[counter][char+6:char+7] == " ":
          ghcnd_value[year_counter][month_counter][day_counter][element_counter] = float(contents[counter][char:char+5])
          last_day=day_counter+1
        char = char + 8

  # Get day of year for last day with valid data
  last_day=datetime(year, month, last_day).timetuple().tm_yday
  last_day=last_day+92 # Shift three months
  if last_day >=365:
    last_day=last_day-365

  # Convert from mm to inch
  ghcnd_value=(ghcnd_value*0.0393701)

  # Get Record / Average Values for every day in year
  average_snow = np.zeros((num_days),dtype='f')-(9999.0)
  day_of_year=0
  day_before=0
  for month_counter in [9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
    for day_counter in xrange(0,31):
      try:
        # Check if leap-year date is valid
        datetime(year=2012,month=month_counter+1,day=day_counter+1)

        average_snow[day_of_year] = day_before + ma.average(ghcnd_value[(valid_begin-begin_year):(valid_end-begin_year),month_counter,day_counter,snow])
        day_before=average_snow[day_of_year]

        day_of_year=day_of_year+1
      except:
        pass

  #################################################
  # Create Accumulations
  new_year_counter=0
  snow_accum = np.zeros((num_years+1,num_days),dtype='f')
  total_accum = np.zeros((num_years+1),dtype='f')
  for year_counter in xrange(0,num_years):
    for month_counter in xrange(0,12):
      if month_counter==9: # Month Begins in Oct
        new_year_counter=year_counter+1
        day_of_year=0
        day_before=0
      for day_counter in xrange(0,31):
        try:
          # Check if date is valid
          datetime(year=year_counter+begin_year,month=month_counter+1,day=day_counter+1)
          snow_accum[new_year_counter][day_of_year] = day_before + ghcnd_value[year_counter,month_counter,day_counter,snow]
          total_accum[new_year_counter]=snow_accum[new_year_counter][day_of_year]
          day_before=snow_accum[new_year_counter][day_of_year]
          day_of_year=day_of_year+1
        except:
          pass
      if month_counter+1==12 and snow_accum[year_counter][365]==0:
        snow_accum[year_counter][365]=snow_accum[year_counter][364]

  #################################################
  # PLOT
  # Mask Zero Data before plotting
  #snow_accum = ma.masked_values(snow_accum, 0.)
  total_accum = ma.masked_values(total_accum, 0.)

  #Get Some Stats Needed For Plotting
  x_axis=range(num_days)
  x_axis_end=range(last_day)

  current_loc = num_years-1
  current_snow = "%6.2f" % total_accum[current_loc]
  current_year = current_loc + begin_year
  current_data=snow_accum[current_loc,0:last_day]
  current_last=snow_accum[current_loc,last_day]

  max_snow = "%6.2f" % np.max(total_accum)
  max_loc = np.argmax(total_accum)
  max_year = max_loc+begin_year

  min_snow = "%6.2f" % np.min(total_accum[np.where(total_accum != 0)])
  min_loc = np.nanargmin(total_accum)
  min_year = min_loc+begin_year

  avg_snow = "%6.2f" % average_snow[365]

  # Create Figure
  fig, ax1 = plt.subplots(figsize=(15, 8), edgecolor='white', facecolor='white', dpi=300)

  # Add grid lines
  plt.grid(color='black', linestyle='--', linewidth=0.5, alpha=0.3)

  # Plot Accumulated SNOW (Sort by end of year accumulation and plot by range of color)
  order=np.argsort(snow_accum[:,364])
  color_pos=np.linspace(0.5,1,num_years)
  order_counter=0
  color_counter=0
  for year_counter in xrange(0,num_years):
    pos=order[order_counter]
    if pos != (num_years-1):
      plt.plot(x_axis, snow_accum[pos,:], linewidth=0.5, color=colors.rgb2hex(pylab.cm.GnBu(color_pos[color_counter])[0:3]))
      color_counter=color_counter+1
    order_counter=order_counter+1

  # Overlay Record Max Snow Year
  if max_loc==current_loc:
    plt.plot(x_axis_end, snow_accum[max_loc,0:last_day], color='#084081', linewidth=3, label='Max ('+str(max_year-1)+'-'+str(max_year)+': '+str(max_snow)+'")')
  else:
    plt.plot(x_axis, snow_accum[max_loc,:], color='#084081', linewidth=3, label='Max ('+str(max_year-1)+'-'+str(max_year)+': '+str(max_snow)+'")')

  # Overlay Record Min Snow Year
  if min_loc==current_loc:
    plt.plot(x_axis_end, snow_accum[min_loc,0:last_day], color='#66ff99', linewidth=3, label='Min ('+str(min_year-1)+'-'+str(min_year)+': '+str(min_snow)+'")')
  else:
    plt.plot(x_axis, snow_accum[min_loc,:], color='#66ff99', linewidth=3, label='Min ('+str(min_year-1)+'-'+str(min_year)+': '+str(min_snow)+'")')

  # Overlay Average SNOW
  plt.plot(x_axis, average_snow[:], color='#e6b800', linewidth=3, markeredgecolor='white', label='Avg ('+str(avg_snow)+'")')

  # Overlay Current Snow Year
  plt.plot(x_axis_end, current_data, color='black', linewidth=3, label='Current ('+str(current_year-1)+'-'+str(current_year)+': '+str(current_snow)+'")')
  plt.plot(x_axis_end[last_day-1],current_last, marker='o', color='black', markersize=10)

  # Plot Legend
  plt.legend(bbox_to_anchor=(0., -.102, 1., -1.02), loc=3, ncol=4, mode="expand", borderaxespad=0., fontsize=12)

  # Plot X/Y Limits
  ymin=0
  ymax=int(5 * round(float((np.max(snow_accum) + 10))/5))
  plt.ylim(ymin,ymax)
  plt.xlim(-5, num_days)

  # Plot Y-Axis Label
  plt.yticks(range(ymin, ymax, 10), [r'{}"'.format(x) for x in range(ymin, ymax, 10)], fontsize=10)
  plt.ylabel(r'Accumulated Snowfall (inches)', fontsize=12)

  # Plot X-Axis Label
  month_pos=[0,31,60,91,121,152,182,213,244,274,305,335]
  month_names=["Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep"]
  plt.xticks(month_pos, month_names, fontsize=10)

  # Plot 2nd Y Axis Labels
  ax3 = ax1.twinx()
  plt.yticks(range(ymin, ymax, 10), [r'{}"'.format(x) for x in range(ymin, ymax, 10)], fontsize=10)
  plt.ylim(ymin, ymax)

  # Plot Title/Subtitle
  plt.suptitle(station_id+': '+ghcnd_name, fontsize=20)
  plt.title('LAT= '+str(ghcnd_lat)+' | LON= '+str(ghcnd_lon)+' | ELEV= '+str(int(ghcnd_alt*3.2808399))+'\'', fontsize=15)

  # Save Figure
  plt.savefig(station_id+'_snowfall.png', dpi=300)
  plt.clf()
  return None
Example #8
0
def plot_temperature(station_id,begin_date,end_date):
  print("\nPLOTTING TEMPERATURE DATA FOR STATION: ",station_id)

  # Declare Other Variables
  begin_year=1895
  num_elements=2 # TMAX/TMIN
  tmax=0
  tmin=1
  end_year=datetime.now().year
  num_years=(end_year-begin_year) + 1

  # Get station metadatafile
  ghcnd_stations=gp.get_ghcnd_stations()

  ghcnd_meta = ghcnd_stations[ghcnd_stations[:,0] == station_id]
  ghcnd_id=ghcnd_meta[0][0]
  ghcnd_lat=float(ghcnd_meta[0][1])
  ghcnd_lon=float(ghcnd_meta[0][2])
  ghcnd_alt=float(ghcnd_meta[0][3])
  ghcnd_name=ghcnd_meta[0][5]
  ghcnd_name = ghcnd_name.strip()
  ghcnd_name = re.sub(' +',' ',ghcnd_name)
  ghcnd_name = ghcnd_name.replace(" ","_")

  # Grab Data
  gp.get_data_station(station_id)

  #################################################
  # Read in GHCN-D Data (Original, QC'd data removed)
  infile = station_id+".dly"
  ghcnd_value = np.zeros((num_years,12,31,num_elements),dtype='f')-(9999.0)

  file_handle = open(infile, 'r')
  contents = file_handle.readlines()
  file_handle.close()

  for counter in xrange(len(contents)):

    element = contents[counter][17:21]

    if element == "TMAX" or element == "TMIN":

      if element == "TMAX":
        element_counter=tmax
      if element == "TMIN":
        element_counter=tmin

      year = int(contents[counter][11:15])
      year_counter = year-begin_year

      month = int(contents[counter][15:17])
      month_counter = month-1

      char=21
      for day_counter in xrange(0,31):
        if contents[counter][char:char+5] != "-9999" and contents[counter][char+6:char+7] == " ":
          ghcnd_value[year_counter][month_counter][day_counter][element_counter] = float(contents[counter][char:char+5]) / 10.0
        char = char + 8

  # Mask Missing, convert from C to F
  ghcnd_nonmiss = ma.masked_values(ghcnd_value, -9999.)
  ghcnd_nonmiss=(ghcnd_nonmiss*1.8) + 32

  # Get Record / Average Values for every day in year
  # For averages, use 1981-2010
  record_max_ghcnd = np.zeros((12,31),dtype='f')-(9999.0)
  record_min_ghcnd = np.zeros((12,31),dtype='f')-(9999.0)
  average_max_ghcnd = np.zeros((12,31),dtype='f')-(9999.0)
  average_min_ghcnd = np.zeros((12,31),dtype='f')-(9999.0)
  for month_counter in xrange(0,12):
    for day_counter in xrange(0,31):

      record_max_ghcnd[month_counter,day_counter] = ma.max(ghcnd_nonmiss[:,month_counter,day_counter,tmax])
      record_min_ghcnd[month_counter,day_counter] = ma.min(ghcnd_nonmiss[:,month_counter,day_counter,tmin])
      average_max_ghcnd[month_counter,day_counter] = ma.average(ghcnd_nonmiss[(1980-begin_year):(2010-begin_year),month_counter,day_counter,tmax])
      average_min_ghcnd[month_counter,day_counter] = ma.average(ghcnd_nonmiss[(1980-begin_year):(2010-begin_year),month_counter,day_counter,tmin])

  #################################################
  # Gather Data based Upon Date Requested
  begin_yy = int(begin_date[0:4])
  begin_mm = int(begin_date[4:6])
  begin_dd = int(begin_date[6:8])

  end_yy = int(end_date[0:4])
  end_mm = int(end_date[4:6])
  end_dd = int(end_date[6:8])

  num_days = (date(end_yy, end_mm, end_dd) - date(begin_yy, begin_mm, begin_dd)).days
  num_days=num_days+1

  num_months = ((date(end_yy, end_mm, end_dd).year - date(begin_yy, begin_mm, begin_dd).year)*12 +\
               date(end_yy, end_mm, end_dd).month - date(begin_yy, begin_mm, begin_dd).month) + 1

  record_max = np.zeros((num_days),dtype='f')-(9999.0)
  record_min = np.zeros((num_days),dtype='f')-(9999.0)
  average_max = np.zeros((num_days),dtype='f')-(9999.0)
  average_min = np.zeros((num_days),dtype='f')-(9999.0)
  raw_max = np.zeros((num_days),dtype='f')-(9999.0)
  raw_min = np.zeros((num_days),dtype='f')-(9999.0)

  month_pos = np.zeros((num_months),dtype='i')-(9999.0)
  month_names = np.empty((num_months),dtype='S7')

  num_days=0
  num_months=0
  for year_counter in xrange(begin_yy,end_yy+1):

    if year_counter == begin_yy:
      start_month=begin_mm
      end_month=12
    elif year_counter == end_yy:
      start_month=1
      end_month=end_mm
    else:
      start_month=1
      end_month=12
    for month_counter in xrange(start_month,end_month+1):
      month_pos[num_months] = num_days
      month_names[num_months] = calendar.month_name[month_counter][0:3]+" '"+str(year_counter)[2:4]

      for day_counter in xrange(begin_dd,end_dd+1):
        try:
          # Check if date is valid
          datetime(year=year_counter,month=month_counter,day=day_counter)
          record_max[num_days] = record_max_ghcnd[month_counter-1,day_counter-1]
          record_min[num_days] = record_min_ghcnd[month_counter-1,day_counter-1]
          average_max[num_days] = average_max_ghcnd[month_counter-1,day_counter-1]
          average_min[num_days] = average_min_ghcnd[month_counter-1,day_counter-1]
          raw_max[num_days] = ghcnd_nonmiss[year_counter-begin_year,month_counter-1,day_counter-1,tmax]
          raw_min[num_days] = ghcnd_nonmiss[year_counter-begin_year,month_counter-1,day_counter-1,tmin]
          num_days=num_days+1
        except:
          pass
      num_months=num_months+1

  x_axis=range(num_days)

  #################################################
  # PLOT
  fig, ax1 = plt.subplots(figsize=(15, 8), edgecolor='white', facecolor='white', dpi=300)

  # Add grid lines
  plt.grid(color='black', linestyle='--', linewidth=0.5, alpha=0.3)

  # Plot Record TMAX/TMIN
  plt.bar(x_axis, record_max - record_min, bottom=record_min, edgecolor='none', color='#c3bba4', width=1, label="Record Max/Min")

  # Plot Average TMAX/TMIN
  plt.bar(x_axis, average_max - average_min, bottom=average_min, edgecolor='none', color='#9a9180', width=1, label="Average Max/Min")

  # Plot Raw TMAX/TMIN
  plt.bar(x_axis, raw_max - raw_min, bottom=raw_min, edgecolor='black', linewidth=0.5, color='#5a3b49', width=1, label="Actual Max/Min")

  # Find New Max/Min Records
  new_max_records = raw_max[raw_max >= record_max]
  new_min_records = raw_min[raw_min <= record_min]

  # Plot New Max/Min Records
  plt.scatter(np.where(raw_max >= record_max)[0] + 0.5, new_max_records + 1.25, s=15, zorder=10, color='#d62728', alpha=0.75, linewidth=0, label="New Max Record")
  plt.scatter(np.where(raw_min <= record_min)[0] + 0.5, new_min_records - 1.25, s=15, zorder=10, color='#1f77b4', alpha=0.75, linewidth=0, label="New Min Record")

  # Plot Legend
  plt.legend(bbox_to_anchor=(0., -.102, 1., -1.02), loc=3, ncol=5, mode="expand", borderaxespad=0., fontsize=12)

  # Plot X/Y Limits
  ymin=int(5 * round(float((min(record_min) - 10))/5))
  ymax=int(5 * round(float((max(record_max) + 10))/5))
  plt.ylim(ymin, ymax)
  plt.xlim(-5, (num_days))

  # Plot Y-Axis Label
  plt.yticks(range(ymin, ymax, 10), [r'{}$^\circ$'.format(x) for x in range(ymin, ymax, 10)], fontsize=10)
  plt.ylabel(r'Temperature ($^\circ$F)', fontsize=12)

  # Plot X-Axis Label
  plt.xticks(month_pos, month_names, fontsize=10)

  # Plot 2nd Y Axis Labels
  ax3 = ax1.twinx()
  plt.yticks(range(ymin, ymax, 10), [r'{}$^\circ$'.format(x) for x in range(ymin, ymax, 10)], fontsize=10)
  plt.ylim(ymin, ymax)

  # Plot Title/Subtitle
  plt.suptitle(station_id+': '+ghcnd_name, fontsize=20)
  plt.title('LAT= '+str(ghcnd_lat)+' | LON= '+str(ghcnd_lon)+' | ELEV= '+str(int(ghcnd_alt*3.2808399))+'\'', fontsize=15)

  # Save Figure
  plt.savefig(station_id+'_temperature.png', dpi=300)
  plt.clf()
  return None