{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Extending Many Variables To Cover The Same Time Domain \n", "\n", "In this tutorial we create two variables over two different but overlapping time domains. \n", "We will *grow* both variables to span the same (union) domain, filling the added times with missing data\n", "\n", "The CDAT software was developed by LLNL. This tutorial was written by Charles Doutriaux. This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.\n", "\n", "[Download the Jupyter Notebook](Extend_Two_Variables_To_Cover_Same_Time_Domain.ipynb)" ] }, { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Table of Contents

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating the Variables\n", "[Back to Top](#top)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's create two distinct variables (monthly time series)\n", "\n", "variable 1 going from 1989 through 2010\n", "variable 2 going from 2000 through 2017\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import cdms2\n", "import numpy\n", "import MV2\n", "import cdtime\n", "import cdutil\n", "\n", "def createTimeAxis(start, end):\n", " \"\"\" Create a monthly time axis going from a start date to another\"\"\"\n", " if isinstance(start, int):\n", " start = cdtime.comptime(start)\n", " if isinstance(end, int):\n", " end = cdtime.comptime(end, 12, 31)\n", " # Figure out how many month are there\n", " units = \"months since {}\".format(start)\n", " n = end.torelative(units).value + 1\n", " # Create time axis\n", " time = cdms2.createAxis(numpy.arange(n))\n", " time.id = \"time\"\n", " time.units = units\n", " time.designateTime()\n", " cdutil.setTimeBoundsMonthly(time)\n", " return time\n", "\n", "def createData(start, end, shape=()):\n", " \"\"\" Create an array of random monthly data going from start to end, you can also pass shape for additional data\"\"\"\n", " time = createTimeAxis(start, end)\n", " n = len(time)\n", " # Add time at beginning\n", " shape = (n,) + shape\n", " data = MV2.array(numpy.random.randn(*shape))\n", " data.setAxis(0,time)\n", " data.id = \"data\"\n", " return data\n", "\n", "data1 = createData(1989, 2010)\n", "data2 = createData(2000, 2017)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Function Create \"Grown\" Data\n", "[Back to Top](#top)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def missingMonths(time, start, end):\n", " \"\"\" given a time axis and a staert and end date, returns how mny months are missing before and after the time axis\"\"\"\n", " # Before the time axis starts\n", " if time[0].cmp(start)<=0:\n", " before = 0\n", " else:\n", " units = \"months since {}\".format(start)\n", " before = time[0].torelative(units).value\n", " \n", " # After the time axis ends\n", " if time[-1].cmp(end)>=0:\n", " end = 0\n", " else:\n", " units = \"months since {}\".format(time[-1])\n", " end = end.torelative(units).value\n", " return int(before), int(end)\n", "\n", "def grow(data, start, end):\n", " \"\"\" Given an array and a start and end date, grows the array to fill the full time range \"\"\"\n", " order = data.getOrder(ids=True)\n", " data = data(order=('t...'))\n", " tc = data.getTime().asComponentTime()\n", " b, e = missingMonths(tc, start, end)\n", " # Prepare the new data\n", " sh = list(data.shape)\n", " sh[0] = sh[0] + b + e\n", " new = MV2.ones(sh)\n", " new = MV2.masked_greater(new,0.) # mask everywhere\n", " if e != 0:\n", " new[b:-e] = data[:]\n", " else:\n", " new[b:] = data[:]\n", " new_time = cdms2.createAxis(numpy.arange(sh[0]))\n", " new_time.units= \"months since {}\".format(start)\n", " new_time.id = \"time\"\n", " new_time.designateTime()\n", " cdutil.setAxisTimeBoundsMonthly(new_time)\n", " new.setAxis(0,new_time)\n", " # set the old axes\n", " for i, axis in enumerate(data.getAxisList()[1:]):\n", " new.setAxis(i+1,ax)\n", " \n", " new.id = data.id\n", " return new(order=order)\n", " \n", " \n", "def growDatasets(*arrays):\n", " \"\"\" Given N cdms2 transient variables, grow them both to start and end at the same time, filling the rest with missing values\"\"\"\n", " \n", " start = None\n", " end = None\n", " for data in arrays:\n", " # Get time axis (as component time)\n", " tc = data.getTime().asComponentTime()\n", " \n", " # figure out which data start first and end last\n", " if start is None or tc[0].cmp(start) <=0: # data starts first\n", " start = tc[0]\n", " if end is None or tc[-1].cmp(end) >=0: # data ends last\n", " end = tc[-1]\n", " \n", " # Figure out how many months are needed\n", " for data in arrays:\n", " yield grow(data, start, end)\n", " \n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Use the function\n", "[Back to Top](#top)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data1, data2 = growDatasets(data1, data2)\n", "\n", "print(data1.shape, data1[0], data1[-1], data2[0], data2[-1])" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }