Created
September 25, 2015 01:37
-
-
Save lbesnard/8de1847de97f1bef022d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
# | |
# Author: Laurent Besnard | |
# Institute: IMOS / eMII | |
# email address: laurent.besnard@utas.edu.au | |
# Website: http://imos.org.au/ https://github.com/aodn/imos_user_code_library | |
# Aug 2014; Last revision: 26-August-2013 | |
# | |
# Copyright 2014 IMOS | |
# The script is distributed under the terms of the GNUv3 General Public License | |
# This script purpose is to provide a tool to users who want to plot a timeseries at | |
# a given location, from a NetCDF gridded file created by the GOGODUCK directly from the | |
# imos portal 123 portal-123.aodn.org.au . | |
# The GOGODUCK is a tool implemented in the 123 portal that allows data products | |
# to be partitioned temporally and spatially as well as aggregated into a single file. | |
# It allows users to create aggregations by selecting various constraints, i.e. date | |
# and area of interest directly through the IMOS portal. | |
# This script can then handle the aggregated file downloaded by the user | |
# see http://help.aodn.org.au/help/?q=node/67 to learn more about how to use | |
# It asks for a longitude and latitude values, and return if there is any data available | |
# a plot, as well as a csv file | |
#import numpy | |
from netCDF4 import Dataset, num2date | |
#from matplotlib.pyplot import figure, plot, xlabel, ylabel, title, show, subplot | |
import csv | |
from Tkinter import Tk | |
from tkFileDialog import askopenfilename | |
import os | |
def openFile(): | |
# Box Dialog to select an GOGODUCK file | |
Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing | |
if os.path.exists(os.path.expanduser('~/Downloads')): | |
srs_GOGODUCK_URL=askopenfilename(filetypes=[("NetCDF file","*.nc")], initialdir=(os.path.expanduser('~/Downloads'))) | |
else: | |
srs_GOGODUCK_URL=askopenfilename(filetypes=[("NetCDF file","*.nc")]) | |
return srs_GOGODUCK_URL | |
def promptLatLon(lat,lon): | |
# prompt Lon | |
prompt_text_Lon = 'Enter longitude value between ' + str(min(lon)) + ' and '+ str(max(lon)) + ": " | |
input_Lon = raw_input(prompt_text_Lon) | |
while (float(input_Lon) < min(lon) ) or (float(input_Lon) > max(lon) ): | |
prompt_text_Lon = 'Enter longitude value between ' + str(min(lon)) + ' and '+ str(max(lon)) + ": " | |
input_Lon = raw_input(prompt_text_Lon) | |
# prompt Lat | |
prompt_text_Lat = 'Enter latitude value between ' + str(min(lat)) + ' and '+ str(max(lat)) + ": " | |
input_Lat = raw_input(prompt_text_Lat) | |
while ((float(input_Lat) < min(lat) ) or (float(input_Lat) > max(lat) )): | |
prompt_text_Lat = 'Enter latitude value between ' + str(min(lat)) + ' and '+ str(max(lat)) + ": " | |
input_Lat = raw_input(prompt_text_Lat) | |
return input_Lat, input_Lon | |
def tryAgain(): | |
c = raw_input('Do you want to try again y/n') | |
if c.lower().startswith('y'): | |
c = True | |
else: | |
c = False | |
return c | |
def getMainVarDataAt1Point(lat,lon,mainVar,timeData): | |
# look for the bounding box values | |
lat_min = lat[0] | |
lat_max = lat[-1] | |
lon_min = lon[0] | |
lon_max = lon[-1] | |
[input_Lat , input_Lon] = promptLatLon(lat,lon) | |
lon_index = int((float(input_Lon)-lon_min)*lon.size/(lon_max - lon_min ))-1 | |
lat_index = int((float(input_Lat)-lat_min)*lat.size/(lat_max - lat_min ))-1 | |
print lon_index | |
print lat_index | |
# load timeseries data at the requested location | |
mainVar_values = mainVar[:,lat_index,lon_index] | |
print mainVar_values | |
# this is a test to check if the mainVar_values array is full of fillvalue or no, ie masked | |
nValues = 0 # just to initiate | |
try: | |
test_nGoodValues = mainVar_values[~mainVar_values.mask].size | |
if test_nGoodValues == 0: | |
# Bail | |
print 'There is no data at the selected point' | |
if tryAgain(): | |
getMainVarDataAt1Point(lat,lon,mainVar,timeData) | |
else: | |
timeData_unmasked = timeData[~mainVar_values.mask] | |
mainVar_values_unmasked = mainVar_values[~mainVar_values.mask] | |
nValues = mainVar_values[~mainVar_values.mask].size | |
except: | |
timeData_unmasked = timeData | |
mainVar_values_unmasked = mainVar_values | |
nValues = mainVar_values.size | |
return timeData_unmasked,mainVar_values_unmasked,nValues | |
def main(): | |
try: | |
srs_GOGODUCK_URL = openFile() | |
srs_GOGODUCK_DATA = Dataset(srs_GOGODUCK_URL) | |
# Look for the Variable names in the NetCDF file. | |
# There is CURRENTLY always ONLY 1 main Var in the GOGODUCK file | |
for v in srs_GOGODUCK_DATA.variables: | |
if v[0:3].lower() == 'LAT'.lower(): | |
latName = v | |
elif v[0:3].lower() == 'LON'.lower(): | |
lonName = v | |
elif v[0:3].lower() == 'tim'.lower(): | |
timeName = v | |
else : | |
mainVarName = 'sea_surface_temperature' | |
# loading the data into arrays | |
mainVar = srs_GOGODUCK_DATA.variables[mainVarName] | |
lat = srs_GOGODUCK_DATA.variables[latName] | |
lon = srs_GOGODUCK_DATA.variables[lonName] | |
TIME = srs_GOGODUCK_DATA.variables[timeName] | |
timeData = num2date(TIME[:], TIME.units) | |
[timeData_unmasked,mainVar_values_unmasked,nValues] = getMainVarDataAt1Point(lat,lon,mainVar,timeData) | |
print ('Latitude and longitude values to get a timeseries plot at the wanted location') | |
# Not checking if values entered by the user are numbers. We assume the user wants to make | |
# this code run, and not try to kill it | |
if nValues != 0: | |
## save timeseries at point in CSV | |
csvFilename = srs_GOGODUCK_URL[0:-3] + '_timeseriesOutput.csv' | |
with open(csvFilename,'w') as outputfile: | |
wrtr = csv.writer(outputfile, delimiter=',', quotechar='"') | |
a = (TIME.long_name,mainVar.long_name + ' in ' + mainVar.units) | |
wrtr.writerow(a) | |
for index in range(nValues) : | |
a = (timeData_unmasked[index].strftime('%Y-%m-%d %H:%M:%S'),mainVar_values_unmasked[index]) | |
wrtr.writerow(a) | |
print ('CSV ouput to ' + csvFilename) | |
# Plot of the timeseries | |
#figure1 = figure( num=None , figsize=(15, 10), dpi=80, facecolor='w', edgecolor='k') | |
#ax1 = subplot(111) | |
#ax1.plot (timeData,mainVar_values) | |
# Not all the GOGODUCK files have the same global attributes | |
#try : | |
# ax1.title(srs_GOGODUCK_DATA.title + '-' + srs_GOGODUCK_DATA.DSD_entry_id) | |
#except : | |
# pass | |
#try : | |
# ax1.xlabel(TIME.long_name ) | |
#except : | |
# pass | |
#try : | |
# ax1.ylabel(mainVar.long_name + ' in ' + mainVar.units) | |
#except : | |
# pass | |
#show() | |
#return | |
else: | |
print 'There is no data at the selected point' | |
return | |
except Exception,e: | |
print str(e) | |
return | |
if __name__ == '__main__': | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment