# Example scripts¶

Often it is quickest to learn from examples. Here are some scripts illustrating how to solve some common tasks using dynlib. They also provide a good basis for your own scripts.

## Read data, apply diagnostic, plot and save results¶

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35``` ```#!/usr/bin/env python # -*- encoding: utf-8 import numpy as np from dynlib.metio.erainterim import conf, dt, get_instantaneous, metsave from dynlib.plotsettings import pconf, pconfl import dynlib.diag import dynlib.proj as proj import dynlib.figures as fig timeinterval = [dt(2011,12,25,0), dt(2011,12,26,12)] plev = '850' # Get wind velocity components on 850 hPa for Ekstremværet Dagmar dat, grid = get_instantaneous([(plev, 'u'), (plev,'v'), ], timeinterval) # Calculate total deformation defabs = dynlib.diag.def_total(dat[plev,'u'][:,0,:,:], dat[plev,'v'][:,0,:,:], grid.dx, grid.dy) # Save results as netCDF file tosave = { 'defabs': defabs[:,np.newaxis,:,:], # Pressure-level data is expected to be 4-dimensional } metsave(tosave, grid, f'ei.ans.Dagmar.{plev}.defabs') # Plot results for tidx in range(len(grid.t)): fig.map(defabs[tidx,::], grid, q='defabs', plev=plev, name=grid.t_parsed[tidx], m=proj.N_Atlantic, show=False, save=f'Dagmar_defabs_{grid.t_parsed[tidx].strftime("%Y%m%d_%H")}.pdf') fig.plt.close() # the end ```

The first two lines are a standard header for a python file. Line 1 declares the file to be a python script, allowing it to be executed by `./script_name.py`. Line 2 gives the file encoding, which is required of you use non-acsii characters in your script. Both lines are optional, but recommended.

Lines 4 through 11 import some standard functionality from dynlib. Of these line 6 is of special importance, as this is line defines that the script uses ERA-Interim reanalysis as its data base.

The time interval on line 13 is a list of datetime objects, that define the time interval for which data is to be fetched in lines 17. Analogously the vertical level for the requested data is set on line 14. In additon to the actual data, the data fetcher function `get_instantaneous()` also returns meta-information about the variable, mainly the grid that the variable is defined on.

Line 20 finally calculated total deformation from the given wind velocity components. The results are then saved to a netCDF file in line 26.

For each of the time steps available, the deformation field is also plotted on a map covering the North Atlantic (line 30-32).

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27``` ```#!/usr/bin/env python # -*- encoding: utf-8 import numpy as np from dynlib.metio.erainterim import conf, dt, get_instantaneous, metsave from dynlib.plotsettings import pconf, pconfl import dynlib.diag year = 2011 timeinterval = [dt(year,1,1,0), dt(year+1,1,1,0)] # end of the time interval is excluced plev = '850' # Get wind velocity components on 850 hPa for the entire year 2011 dat, grid = get_instantaneous([(plev, 'u'), (plev,'v'), ], timeinterval) # Calculate total deformation defabs = dynlib.diag.def_total(dat[plev,'u'][:,0,:,:], dat[plev,'v'][:,0,:,:], grid.dx, grid.dy) # Save results as netCDF file tosave = { 'defabs': defabs[:,np.newaxis,:,:], # Pressure-level data is expected to be 4-dimensional } metsave(tosave, grid, f'ei.ans.{year}.{plev}.defabs') # the end ```

The script changes hardly at all if you want to calculate and save deformation for longer period. Typically, for ERA-Interim, we would use yearly chunks as shown in the script. Differences to the first example are highlighted in yellow.

## Define and calculate composites¶

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40``` ```#!/usr/bin/env python # -*- encoding: utf-8 from dynlib.metio.erainterim import conf, dt, get_composite, get_static, metopen, metsave_composite from dynlib.metio.composite import decide_by_date, decide_by_timeseries, matrix # Which variable(s) to composite, given by list of 2-tuples (plev, q) qs = [('500', 'z'), ] # Time interval to consider for the composites, here 2001-2010 timeinterval = [dt(2001,1,1,0), dt(2011,1,1,0)] # Define the composite based on two different kinds of tests: # 1. First, get tests for the different seasons djf = decide_by_date('DJF', lambda date: date.month in [12,1,2]) jja = decide_by_date('JJA', lambda date: date.month in [6,7,8]) # 2. Then tests based on the monthly values of the NAO ts = metopen('indexes/ts_NAO', no_static=True) naop = decide_by_timeseries('NAO+', ts, lambda idx: idx >= 1.0) naom = decide_by_timeseries('NAO-', ts, lambda idx: idx <= -1.0) # 3. Combine the tests to make composites for all combinations between # NAO+/- and summer/winter composites = matrix([djf, jja,], [naom, naop]) # Actually construct the composites dat = get_composite(qs, timeinterval, composites) # Save the composites as netCDF files; requires injection of missing vertical level information grid = get_static() metsave_composite(dat, composites, grid, 'ei.ans.NAO_composites') # C'est le fin ```

Requesting composite averages works very similarly to requesting instantaneous data. The only additional argument in `get_aggregate()` over `get_instantaneous()` is the list of composite conditions to be applied.

These conditions can be constructed easily from the primitives defined in `dynlib.metio.composite`. In this example, lines 18-19 defines two conditions based on the date only to define seasonal averages through a composite. In the following, line 22 loads a monthly NAO index time series, and lines 23-24 define composites based on the NAO index. Finally, line 28 combines the seasonal and the NAO criteria by creating all combinations, here composites of NAO+ and NAO- for both summer and winter.

The function `get_instantaneous()` does (currently) not return the grid information itself, so we need to manually request this metadata through `get_static()` (line 35) before we can save the result.

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36``` ```#!/usr/bin/env python # -*- encoding: utf-8 from dynlib.metio.erainterim import conf, dt, get_composite, get_static, metsave_composite from dynlib.metio.composite import decide_by_date, decide_by_data # Which variable(s) to composite, given by list of 2-tuples (plev, q) qs = [('500', 'z'), ] # Time interval to consider for the composites, here 2001-2010 timeinterval = [dt(2001,1,1,0), dt(2011,1,1,0)] # Define the composite based on two different kinds of tests: # 1. First define summer season jja = decide_by_date('JJA', lambda date: date.month in [6,7,8]) # 2. Find time steps when Bergen 2m temperatures exceed 20 degC warm_bgo = decide_by_data('warm_BGO', 'sfc', 't2m', lambda t2m: t2m[60,370] > 293.0) # 3. Combine the tests composites = [warm_bgo & jja, ] # Actually construct the composites dat = get_composite(qs, timeinterval, composites) # Save the composites as netCDF files; requires injection of missing vertical level information grid = get_static() metsave_composite(dat, composites, grid, 'ei.ans.warm_BGO_composite') # C'est le fin ```

The final example adapts the previous composite definitions to an example of a data-driven composite. This example composites all time steps in which the ERA-Interim grid point closest to Bergen exceeds a 2-meter temperature of 20°C (line 21). The structure of the script is almost entirely identical to the above, only in line 24 the combination of the one seasonal criterion with the one temperature criterion is done manually instead through the `matrix()` function.