{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "source": [ "# CF NetCDF Trajectory Template\n", "\n", "This notebook is an attempt create a [CF](http://cfconventions.org/) compliant\n", "netCDF trajectory file with an IPython Notebook. The data are canned, but this\n", "notebook could serve a template for data providers wishing to create CF\n", "compliant netCDF trajectories.\n", "\n", "This Python CF trajectory template follows [NODC guidance for\n", "trajectories](https://geo-ide.noaa.gov/wiki/index.php?title=NODC_NetCDF_Trajectory_Template).\n", "\n", "Note that there are many \"RECOMMENDED\" and \"REQUIRED\" fields, and I have done my\n", "best to adhere to those suggestions, but I may have missed some details. If so\n", "please send a pull request." ] }, { "cell_type": "markdown", "source": [ "Need to import netcdf4-python and numpy." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import netCDF4\n", "import numpy as np" ], "language": "python", "outputs": [], "prompt_number": 8 }, { "cell_type": "markdown", "source": [ "Now let's create a new, empty, netCDF file open for writing. Please adjust its\n", "name and location for your purposes." ] }, { "cell_type": "code", "collapsed": false, "input": [ "ncfile = netCDF4.Dataset('/tmp/traj.nc','w')" ], "language": "python", "outputs": [], "prompt_number": 9 }, { "cell_type": "markdown", "source": [ "We will first need to create the 'obs' and 'trajectory' dimensions." ] }, { "cell_type": "code", "collapsed": false, "input": [ "obs_dim = ncfile.createDimension('obs', 5)\n", "trajectory_dim = ncfile.createDimension('trajectory', 2)" ], "language": "python", "outputs": [], "prompt_number": 10 }, { "cell_type": "markdown", "source": [ "Now we will create some trajectory variables:\n", "\n", "- trajectory\n", "- times\n", "- lat\n", "- lon\n", "- z\n", "- geophysical variable(s)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Defining the 'trajectory' coordinate variable\n", "trajectory = ncfile.createVariable('trajectory', 'i4', ('trajectory',))\n", "trajectory.long_name = \"\"\n", "trajectory.cf_role = \"trajectory_id\"\n", "\n", "# time\n", "times = ncfile.createVariable('time','f8',('trajectory','obs'))\n", "times.standard_name = 'time'\n", "times.units = 'hours since 2014-06-01T00:00:00Z'\n", "times.axis = 'T'\n", "\n", "# lat\n", "lat = ncfile.createVariable('lat', 'f4', ('trajectory','obs'))\n", "lat.units = 'degrees_north'\n", "lat.standard_name = 'latitude'\n", "lat.axis = 'Y'\n", "\n", "# lon\n", "lon = ncfile.createVariable('lon', 'f4', ('trajectory','obs'))\n", "lon.units = 'degrees_east'\n", "lon.standard_name = 'longitude'\n", "lon.axis = 'X'\n", "\n", "# z\n", "z = ncfile.createVariable('z', 'f4', ('trajectory','obs'))\n", "z.units = 'meter'\n", "z.standard_name = 'altitude'\n", "z.axis = 'Z'\n", "z.positive = \"up\"\n", "\n", "# mean sea level pressure \n", "mslp = ncfile.createVariable('mslp','f4',('trajectory','obs'))\n", "mslp.units = 'hPa' # hecto-Pascals also known as millibars\n", "mslp.standard_name = 'air_pressure_at_sea_level'\n", "mslp.coordinates = 'time lat lon z'\n", "\n" ], "language": "python", "outputs": [], "prompt_number": 11 }, { "cell_type": "markdown", "source": [ "Now add the global attributes. If trying to adhere to [Unidata Dataset Discovery\n", "v1.1](http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery_%28ACDD%29),\n", "John Caron recommends adding any attribute starting with 'geospatial' or 'time'." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# global attributes\n", "ncfile.Conventions = 'CF-1.6'\n", "ncfile.Metadata_Conventions = 'Unidata Dataset Discovery v1.0'\n", "ncfile.featureType = 'trajectory'\n", "ncfile.cdm_data_type = 'Trajectory'\n", "ncfile.nodc_template_version = 'NODC_NetCDF_Trajectory_Template_v0.9'\n", "ncfile. standard_name_vocabulary = 'CF-1.6'" ], "language": "python", "outputs": [], "prompt_number": 12 }, { "cell_type": "markdown", "source": [ "Finally, let us add the actual (in this case fake) data." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# trajectory IDs\n", "trajectory[:] = np.array([17,42])\n", "\n", "# times (hours since 2014-06-01T00:00:00Z)\n", "times[:] = np.array([[0, 0, 0, 0, 0], [12, 12, 12, 12, 12]])\n", "\n", "# lat/lon/z\n", "lat[:] = np.array([[40, 40, 40, 40, 40], [41, 41, 41, 41, 41]])\n", "lon[:] = np.array([[-106, -106, -106, -106, -106], [-107, -107, -107, -107, -107]])\n", "z[:] = np.array([[0, 1000, 2000, 3000, 4000], [0, 1000, 2000, 3000, 4000]])\n", "\n", "# mean sea level pressure\n", "mslp[:] = np.array([[1000, 950, 800, 700, 625], [990, 940, 810, 690, 620]])" ], "language": "python", "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "# Close the netCDF file\n", "ncfile.close()" ], "language": "python", "outputs": [], "prompt_number": 14 }, { "cell_type": "markdown", "source": [ "At this point we are done. You now have a CF compliant netCDF trajectory file." ] } ] } ] }