# Grey radiation modeling with climlab

This notebook is part of [The Climate Laboratory](https://brian-rose.github.io/ClimateLaboratoryBook) by [Brian E. J. Rose](http://www.atmos.albany.edu/facstaff/brose/index.html), University at Albany.

____________

## 1. Introducing `climlab`
____________

## About climlab

climlab is a specialized python package for process-oriented climate modeling.

It is based on a very general concept of a model as a collection of individual,
interacting processes. climlab defines a base class called `Process`, which
can contain an arbitrarily complex tree of sub-processes (each also some
sub-class of `Process`). Every climate process (radiative, dynamical,
physical, turbulent, convective, chemical, etc.) can be simulated as a stand-alone
process model given appropriate input, or as a sub-process of a more complex model.
New classes of model can easily be defined and run interactively by putting together an
appropriate collection of sub-processes.

climlab is an open-source community project. The latest code can always be found on github:

https://github.com/brian-rose/climlab

## Installing climlab

If you've followed [these instructions from the Climate Laboratory book](https://brian-rose.github.io/ClimateLaboratoryBook/how-to.html), then you should be all set -- climlab is automatically installed as part of the suite of tools used in [The Climate Laboratory](https://brian-rose.github.io/ClimateLaboratoryBook).

If you are maintaining your own Python installation (e.g. on a personal laptop), you can always install climlab by doing

```
conda install -c conda-forge climlab
```

```python
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
from numpy import cos, deg2rad, log
import climlab
```

____________

## 2. Using `climlab` to implement the two-layer leaky greenhouse model
____________

One of the things that ``climlab`` is set up to do is the grey-radiation modeling we have already been discussing.

Since we already derived a [complete analytical solution to the two-layer leaky greenhouse model](Lecture06 -- Elementary greenhouse models.ipynb), we will use this to validate the `climlab` code.

### Validation

We want to verify that the model reproduces the observed OLR given observed temperatures, and the absorptivity that we tuned in the analytical model. The target numbers are:

$$
\begin{align}
T_s &= 288 \text{ K} \\
T_0 &= 275 \text{ K} \\
T_1 &= 230 \text{ K} \\
\end{align}
$$

$$ \epsilon = 0.586  $$

$$ OLR = 238.5 \text{ W m}^{-2} $$

### Initialize a model in `climlab`
The first thing we do is create a new model.

The following example code is sparsely commented but will hopefully orient you on the basics of defining and working with a `climlab Process` object.

```python
#  Test in a 2-layer atmosphere
col = climlab.GreyRadiationModel(num_lev=2)
print( col)
```

    climlab Process of type <class 'climlab.model.column.GreyRadiationModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (2,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.GreyRadiationModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>

```python
col.subprocess
```

    AttrDict({'LW': <climlab.radiation.greygas.GreyGas object at 0x109debd00>, 'SW': <climlab.radiation.greygas.GreyGasSW object at 0x109debd60>, 'insolation': <climlab.radiation.insolation.FixedInsolation object at 0x1657336a0>})

Every item in the above dictionary is itself an instance of the `climlab.Process` object:

```python
print( col.subprocess['LW'])
```

    climlab Process of type <class 'climlab.radiation.greygas.GreyGas'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (2,)
    The subprocess tree:
    Untitled: <class 'climlab.radiation.greygas.GreyGas'>

The `state` dictionary holds the state variables of the model. In this case, temperatures:

```python
climlab.to_xarray(col.state)
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.Dataset>
Dimensions:       (depth: 1, depth_bounds: 2, lev: 2, lev_bounds: 3)
Coordinates:
  * depth         (depth) float64 0.5
  * depth_bounds  (depth_bounds) float64 0.0 1.0
  * lev           (lev) float64 250.0 750.0
  * lev_bounds    (lev_bounds) float64 0.0 500.0 1e+03
Data variables:
    Ts            (depth) float64 288.0
    Tatm          (lev) float64 200.0 278.0

xarray.Dataset

<input id='section-52f11911-31f5-4be6-be32-c2e6d55b4419' class='xr-section-summary-in' type='checkbox' disabled >Dimensions:

depth: 1

depth_bounds: 2

lev: 2

lev_bounds: 3

<input id='section-8757b16e-4e73-47db-b958-6fa920edb156' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (4)

depth

(depth)

float64

0.5
<input id='attrs-b9c05e8c-c71f-4eef-a167-ba6fcf1a20ae' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-5863b9dc-16be-4231-8ac1-ec3cbaf6d59d' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

meters

array([0.5])

depth_bounds

(depth_bounds)

float64

0.0 1.0
<input id='attrs-75c45f8e-7005-40c3-aa01-bd14b3fd2654' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-9afff932-307a-4721-bc20-f7cac4e40242' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

meters

array([0., 1.])

lev

(lev)

float64

250.0 750.0
<input id='attrs-c7904015-6b67-4005-9903-d709f804712d' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-03e06367-8383-471d-9c3c-84a018e0805e' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

mb

array([250., 750.])

lev_bounds

(lev_bounds)

float64

0.0 500.0 1e+03
<input id='attrs-ae8ce933-1784-404d-bd66-d83ce2a38fa8' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-a0f15ff1-f7cd-42fd-8c71-a69b71d17b5f' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

mb

array([   0.,  500., 1000.])

<input id='section-edbcd3b3-e12b-4f17-83e0-c7516ba46c9c' class='xr-section-summary-in' type='checkbox'  checked>Data variables: (2)

Ts

(depth)

float64

288.0
<input id='attrs-52772108-f9f3-446c-a81a-e4bb3bec8495' class='xr-var-attrs-in' type='checkbox' disabled><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-bdd38b5d-84c8-4725-926d-a54b57bb52d5' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

array([288.])

Tatm

(lev)

float64

200.0 278.0
<input id='attrs-f1f8c1db-ef80-4e00-aec7-d617075a250c' class='xr-var-attrs-in' type='checkbox' disabled><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-a9d611a6-7cca-4689-b717-8f890ca7496b' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

array([200., 278.])

<input id='section-4afbf3f4-5cac-4a68-b8a3-a10f864fc56b' class='xr-section-summary-in' type='checkbox' disabled >Attributes: (0)

Access these either through dictionary methods or as attributes of the model object:

```python
print( col.state['Ts'])
print( col.Ts)
col.Ts is col.state['Ts']
```

    [288.]
    [288.]

    True

Now we are assigning the "observed" temperatures to our model state:

```python
col.Ts[:] = 288.
col.Tatm[:] = np.array([230., 275.])
climlab.to_xarray(col.state)
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.Dataset>
Dimensions:       (depth: 1, depth_bounds: 2, lev: 2, lev_bounds: 3)
Coordinates:
  * depth         (depth) float64 0.5
  * depth_bounds  (depth_bounds) float64 0.0 1.0
  * lev           (lev) float64 250.0 750.0
  * lev_bounds    (lev_bounds) float64 0.0 500.0 1e+03
Data variables:
    Ts            (depth) float64 288.0
    Tatm          (lev) float64 230.0 275.0

xarray.Dataset

<input id='section-92a89090-eb04-43a9-94e1-bcbadfee31e1' class='xr-section-summary-in' type='checkbox' disabled >Dimensions:

depth: 1

depth_bounds: 2

lev: 2

lev_bounds: 3

<input id='section-aa94f2f9-4dfc-4f67-9d8c-fd33985a2f18' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (4)

depth

(depth)

float64

0.5
<input id='attrs-9caddb4f-b8a0-49a8-a119-529d7b529f2d' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-05bef08c-86b1-4f84-807a-5d3df705a747' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

meters

array([0.5])

depth_bounds

(depth_bounds)

float64

0.0 1.0
<input id='attrs-492d5eda-c146-48af-acd8-0a21b68dd332' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-fcef5b9d-368a-4f97-8677-6973bd394e41' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

meters

array([0., 1.])

lev

(lev)

float64

250.0 750.0
<input id='attrs-fcff0a84-37f7-44d8-8d54-2c4a667a63ec' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-02627e7f-0e40-4094-a931-4abe48847212' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

mb

array([250., 750.])

lev_bounds

(lev_bounds)

float64

0.0 500.0 1e+03
<input id='attrs-60c74f56-591f-4519-b9de-b83ea84bf08e' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-33f1dfee-23ba-4bfe-86f1-8297a45c7021' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

mb

array([   0.,  500., 1000.])

<input id='section-95f7178f-3880-4439-be51-35344e93e171' class='xr-section-summary-in' type='checkbox'  checked>Data variables: (2)

Ts

(depth)

float64

288.0
<input id='attrs-0d0c4e43-988e-4386-923a-a19683cdeb35' class='xr-var-attrs-in' type='checkbox' disabled><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-9f0abe1b-bf93-4726-a6d8-d0b0dc5bdd51' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

array([288.])

Tatm

(lev)

float64

230.0 275.0
<input id='attrs-a1baadb6-ccf7-4e0e-b335-439a5bfecf7b' class='xr-var-attrs-in' type='checkbox' disabled><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-51bb339e-a748-4ab3-9ed9-dec803b3fcd5' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

array([230., 275.])

<input id='section-bc1c1d51-c298-430b-9b74-14118c302e4e' class='xr-section-summary-in' type='checkbox' disabled >Attributes: (0)

```python
LW = col.subprocess['LW']
print(LW)
```

    climlab Process of type <class 'climlab.radiation.greygas.GreyGas'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (2,)
    The subprocess tree:
    Untitled: <class 'climlab.radiation.greygas.GreyGas'>

```python
LW.absorptivity
```

    Field([0.47737425, 0.47737425])

```python
#  copying the tuned value of epsilon from Lecture 6 notes
LW.absorptivity = 0.586
LW.absorptivity
```

    Field([0.586, 0.586])

```python
#  This does all the calculations that would be performed at each time step,
#  but doesn't actually update the temperatures
col.compute_diagnostics()
#  Print out the dictionary
col.diagnostics
```

    {'flux_from_sfc': Field([102.0487]),
     'flux_to_sfc': array([341.3]),
     'flux_to_space': array([102.0487]),
     'absorbed': array([0., 0.]),
     'absorbed_total': 0.0,
     'emission': Field([0., 0.]),
     'emission_sfc': Field([0.]),
     'flux_reflected_up': array([  0.    ,   0.    , 102.0487]),
     'insolation': Field([341.3]),
     'coszen': Field([1.]),
     'OLR': array([238.5247311]),
     'LW_down_sfc': array([228.53426769]),
     'LW_up_sfc': Field([390.10502995]),
     'LW_absorbed_sfc': Field([-161.57076227]),
     'LW_absorbed_atm': array([ 20.02990881, -96.98387764]),
     'LW_emission': Field([ 92.98664086, 190.03779837]),
     'ASR': Field([239.2513]),
     'SW_absorbed_sfc': Field([239.2513]),
     'SW_absorbed_atm': array([0., 0.]),
     'SW_up_sfc': Field([102.0487]),
     'SW_up_TOA': array([102.0487]),
     'SW_down_TOA': Field([341.3]),
     'planetary_albedo': Field([0.299])}

```python
#  Check OLR against our analytical solution
col.OLR
```

    array([238.5247311])

```python
# Like the state variables, the diagnostics can also be accessed in two different ways
col.diagnostics['OLR']
```

    array([238.5247311])

```python
col.state
```

    AttrDict({'Ts': Field([288.]), 'Tatm': Field([230., 275.])})

```python
# perform a single time step
col.step_forward()
```

```python
col.state
```

    AttrDict({'Ts': Field([289.60514636]), 'Tatm': Field([230.33784312, 273.3641795 ])})

We just stepped forward one discreet unit in time. Because we didn't specify a timestep when we created the model, it is set to a default value:

```python
col.timestep
```

    86400.0

which is 1 day (expressed in seconds).

Now we will integrate the model out to equilibrium.

We could easily write a loop to call the `step_forward()` method many times.

Or use a handy shortcut that allows us to specify the integration length in physical time units:

```python
# integrate out to radiative equilibrium
col.integrate_years(2.)
```

    Integrating for 730 steps, 730.4844 days, or 2.0 years.
    Total elapsed time is 2.0014116660123062 years.

```python
# Check for equilibrium
col.ASR - col.OLR
```

    Field([-2.34514516e-07])

```python
#  The temperatures at radiative equilibrium
col.state
```

    AttrDict({'Ts': Field([296.38447748]), 'Tatm': Field([233.72131685, 262.28540231])})

Compare these to the analytical solutions for radiative equilibrium with $\epsilon = 0.58$:

\begin{align}
T_s &= 296.4 \text{ K} \\
T_0 &= 262.3 \text{ K} \\
T_1 &= 233.8 \text{ K} \\
\end{align}

So it looks like `climlab` agrees with our analytical results to within 0.1 K. That's good.

____________

## 3. The observed annual, global mean temperature profile
____________

We want to model the OLR in a column whose temperatures match observations. As we've done before, we'll calculate the global, annual mean air temperature from the NCEP Reanalysis data.

```python
## The NOAA ESRL server is shutdown! January 2019
## This will try to read the data over the internet.
ncep_filename = 'air.mon.1981-2010.ltm.nc'
##  to read over internet
ncep_url = "http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis.derived/pressure/"
path = ncep_url
##  Open handle to data
ncep_air = xr.open_dataset( path + ncep_filename, decode_times=False )

#url = 'http://apdrc.soest.hawaii.edu:80/dods/public_data/Reanalysis_Data/NCEP/NCEP/clima/pressure/air'
#air = xr.open_dataset(url)
# The name of the vertical axis is different than the NOAA ESRL version..
#ncep_air = air.rename({'lev': 'level'})
ncep_air
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.Dataset>
Dimensions:             (lat: 73, level: 17, lon: 144, nbnds: 2, time: 12)
Coordinates:
  * level               (level) float32 1e+03 925.0 850.0 ... 30.0 20.0 10.0
  * lon                 (lon) float32 0.0 2.5 5.0 7.5 ... 352.5 355.0 357.5
  * time                (time) float64 -6.571e+05 -6.57e+05 ... -6.567e+05
  * lat                 (lat) float32 90.0 87.5 85.0 82.5 ... -85.0 -87.5 -90.0
Dimensions without coordinates: nbnds
Data variables:
    climatology_bounds  (time, nbnds) float64 1.736e+07 1.761e+07 ... 1.762e+07
    air                 (time, level, lat, lon) float32 ...
    valid_yr_count      (time, level, lat, lon) float32 ...
Attributes:
    description:                     Data from NCEP initialized reanalysis (4...
    platform:                       Model
    Conventions:                    COARDS
    not_missing_threshold_percent:  minimum 3% values input to have non-missi...
    history:                        Created 2011/07/12 by doMonthLTM\nConvert...
    title:                          monthly ltm air from the NCEP Reanalysis
    dataset_title:                  NCEP-NCAR Reanalysis 1
    References:                     http://www.psl.noaa.gov/data/gridded/data...

xarray.Dataset

<input id='section-028c8d81-bcaa-4f48-9f26-542dce8fca1f' class='xr-section-summary-in' type='checkbox' disabled >Dimensions:

lat: 73

level: 17

lon: 144

nbnds: 2

time: 12

<input id='section-961e2d0a-5c92-4ab5-afb8-826eece85645' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (4)

level

(level)

float32

1e+03 925.0 850.0 ... 20.0 10.0
<input id='attrs-4d5fa288-5658-424a-bd11-0fddcc0bd80f' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-a5a0ce7b-34d9-4f03-a965-784f24cbfe65' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

millibar

long_name :

Level

positive :

down

GRIB_id :

100

GRIB_name :

hPa

actual_range :

[1000.   10.]

axis :

Z

array([1000.,  925.,  850.,  700.,  600.,  500.,  400.,  300.,  250.,  200.,
        150.,  100.,   70.,   50.,   30.,   20.,   10.], dtype=float32)

lon

(lon)

float32

0.0 2.5 5.0 ... 352.5 355.0 357.5
<input id='attrs-4c25ded9-2a92-4ede-81a7-e7b36401503b' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-08b712f3-7d71-4afa-b76a-10a519f51eb9' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

degrees_east

long_name :

Longitude

actual_range :

[  0.  357.5]

standard_name :

longitude

axis :

X

array([  0. ,   2.5,   5. ,   7.5,  10. ,  12.5,  15. ,  17.5,  20. ,  22.5,
        25. ,  27.5,  30. ,  32.5,  35. ,  37.5,  40. ,  42.5,  45. ,  47.5,
        50. ,  52.5,  55. ,  57.5,  60. ,  62.5,  65. ,  67.5,  70. ,  72.5,
        75. ,  77.5,  80. ,  82.5,  85. ,  87.5,  90. ,  92.5,  95. ,  97.5,
       100. , 102.5, 105. , 107.5, 110. , 112.5, 115. , 117.5, 120. , 122.5,
       125. , 127.5, 130. , 132.5, 135. , 137.5, 140. , 142.5, 145. , 147.5,
       150. , 152.5, 155. , 157.5, 160. , 162.5, 165. , 167.5, 170. , 172.5,
       175. , 177.5, 180. , 182.5, 185. , 187.5, 190. , 192.5, 195. , 197.5,
       200. , 202.5, 205. , 207.5, 210. , 212.5, 215. , 217.5, 220. , 222.5,
       225. , 227.5, 230. , 232.5, 235. , 237.5, 240. , 242.5, 245. , 247.5,
       250. , 252.5, 255. , 257.5, 260. , 262.5, 265. , 267.5, 270. , 272.5,
       275. , 277.5, 280. , 282.5, 285. , 287.5, 290. , 292.5, 295. , 297.5,
       300. , 302.5, 305. , 307.5, 310. , 312.5, 315. , 317.5, 320. , 322.5,
       325. , 327.5, 330. , 332.5, 335. , 337.5, 340. , 342.5, 345. , 347.5,
       350. , 352.5, 355. , 357.5], dtype=float32)

time

(time)

float64

-6.571e+05 -6.57e+05 ... -6.567e+05
<input id='attrs-55f05a76-8509-47e7-ab3e-958a87bf5abc' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-c81a5ddd-7007-4813-9cba-c7d658cdf034' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

Time

delta_t :

0000-01-00 00:00:00

avg_period :

0030-00-00 00:00:00

prev_avg_period :

0000-01-00 00:00:00

standard_name :

time

axis :

T

climatology :

climatology_bounds

climo_period :

1981/01/01 - 2010/12/31

interpreted_actual_range :

0001/01/01 00:00:00 - 0001/12/01 00:00:00

units :

days since 1800-01-01 00:00:0.0

actual_range :

[-657073. -656739.]

array([-657073., -657042., -657014., -656983., -656953., -656922., -656892.,
       -656861., -656830., -656800., -656769., -656739.])

lat

(lat)

float32

90.0 87.5 85.0 ... -87.5 -90.0
<input id='attrs-fe32dd0c-003a-4b43-a229-2a82d14865df' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-a06675f4-ea8b-481f-905d-117e60c4aa45' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

degrees_north

actual_range :

[ 90. -90.]

long_name :

Latitude

standard_name :

latitude

axis :

Y

array([ 90. ,  87.5,  85. ,  82.5,  80. ,  77.5,  75. ,  72.5,  70. ,  67.5,
        65. ,  62.5,  60. ,  57.5,  55. ,  52.5,  50. ,  47.5,  45. ,  42.5,
        40. ,  37.5,  35. ,  32.5,  30. ,  27.5,  25. ,  22.5,  20. ,  17.5,
        15. ,  12.5,  10. ,   7.5,   5. ,   2.5,   0. ,  -2.5,  -5. ,  -7.5,
       -10. , -12.5, -15. , -17.5, -20. , -22.5, -25. , -27.5, -30. , -32.5,
       -35. , -37.5, -40. , -42.5, -45. , -47.5, -50. , -52.5, -55. , -57.5,
       -60. , -62.5, -65. , -67.5, -70. , -72.5, -75. , -77.5, -80. , -82.5,
       -85. , -87.5, -90. ], dtype=float32)

<input id='section-b2a4dbbc-f76e-439d-894d-71d5426dca38' class='xr-section-summary-in' type='checkbox'  checked>Data variables: (3)

climatology_bounds

(time, nbnds)

float64

...
<input id='attrs-9189d616-8e2f-4e06-b076-68080026fac2' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-dc3c9310-ee20-46cc-a801-55acca178497' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

Climate Time Boundaries

units :

hours since 1-1-1 00:00:0.0

array([[17356368., 17610576.],
       [17357112., 17611320.],
       [17357784., 17611992.],
       [17358528., 17612736.],
       [17359248., 17613456.],
       [17359992., 17614200.],
       [17360712., 17614920.],
       [17361456., 17615664.],
       [17362200., 17616408.],
       [17362920., 17617128.],
       [17363664., 17617872.],
       [17364384., 17618592.]])

air

(time, level, lat, lon)

float32

...
<input id='attrs-78e39c69-82b3-4c74-8d7d-ea9d78fd3732' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-b95454b8-071c-40fc-86bd-33e4ac65e2ee' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

Monthly Long Term Mean of Air temperature

units :

degC

precision :

2

var_desc :

Air Temperature

level_desc :

Multiple levels

statistic :

Long Term Mean

parent_stat :

Mean

valid_range :

[-200.  300.]

actual_range :

[-89.722336  41.616005]

dataset :

NCEP Reanalysis Derived Products

_ChunkSizes :

[  1   1  73 144]

[2144448 values with dtype=float32]

valid_yr_count

(time, level, lat, lon)

float32

...
<input id='attrs-643a7b88-9fba-4dbf-b409-0b1d2b94a3c3' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-0de93ce3-f47f-403a-acc9-dd4db3d7a65f' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

count of non-missing values used in mean

_ChunkSizes :

[  1   1  73 144]

[2144448 values with dtype=float32]

<input id='section-8950250a-0fec-4119-abf0-d71d7b356e9b' class='xr-section-summary-in' type='checkbox'  checked>Attributes: (8)

description :

 Data from NCEP initialized reanalysis (4x/day).  These are interpolated to pressure surfaces from model (sigma) surfaces.

platform :

Model

Conventions :

COARDS

not_missing_threshold_percent :

minimum 3% values input to have non-missing output value

history :

Created 2011/07/12 by doMonthLTM
Converted to chunked, deflated non-packed NetCDF4 2014/09

title :

monthly ltm air from the NCEP Reanalysis

dataset_title :

NCEP-NCAR Reanalysis 1

References :

http://www.psl.noaa.gov/data/gridded/data.ncep.reanalysis.derived.html

```python
#  Take global, annual average and convert to Kelvin
weight = cos(deg2rad(ncep_air.lat)) / cos(deg2rad(ncep_air.lat)).mean(dim='lat')
Tglobal = (ncep_air.air * weight).mean(dim=('lat','lon','time'))
Tglobal
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.DataArray (level: 17)>
array([ 15.179084  ,  11.207003  ,   7.8383274 ,   0.21994135,
        -6.4483433 , -14.888848  , -25.570469  , -39.36969   ,
       -46.797905  , -53.652245  , -60.56356   , -67.006065  ,
       -65.53293   , -61.48664   , -55.853584  , -51.593952  ,
       -43.21999   ], dtype=float32)
Coordinates:
  * level    (level) float32 1e+03 925.0 850.0 700.0 ... 50.0 30.0 20.0 10.0

xarray.DataArray

level: 17

<input id='section-8b374725-9b01-4dcf-9ff9-d81e66327222' class='xr-array-in' type='checkbox' checked><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>
15.18 11.21 7.838 0.2199 -6.448 ... -65.53 -61.49 -55.85 -51.59 -43.22

array([ 15.179084  ,  11.207003  ,   7.8383274 ,   0.21994135,
        -6.4483433 , -14.888848  , -25.570469  , -39.36969   ,
       -46.797905  , -53.652245  , -60.56356   , -67.006065  ,
       -65.53293   , -61.48664   , -55.853584  , -51.593952  ,
       -43.21999   ], dtype=float32)

<input id='section-8c34d40c-322b-4294-a2a4-863398a7c9c6' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (1)

level

(level)

float32

1e+03 925.0 850.0 ... 20.0 10.0
<input id='attrs-343cdfa6-2bfd-43f0-b004-709db59460dc' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-44ff95ca-8bcd-4aff-bd52-651b05f74f89' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

millibar

long_name :

Level

positive :

down

GRIB_id :

100

GRIB_name :

hPa

actual_range :

[1000.   10.]

axis :

Z

array([1000.,  925.,  850.,  700.,  600.,  500.,  400.,  300.,  250.,  200.,
        150.,  100.,   70.,   50.,   30.,   20.,   10.], dtype=float32)

<input id='section-f626b62d-522a-4c44-9074-b10cb161c8bb' class='xr-section-summary-in' type='checkbox' disabled >Attributes: (0)

We're going to convert this to degrees Kelvin, using a handy list of pre-defined constants in `climlab.constants`

```python
climlab.constants.tempCtoK
```

    273.15

```python
Tglobal += climlab.constants.tempCtoK
Tglobal
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.DataArray (level: 17)>
array([288.32907, 284.357  , 280.9883 , 273.36993, 266.70166, 258.26114,
       247.57953, 233.7803 , 226.35208, 219.49774, 212.58643, 206.14392,
       207.61707, 211.66336, 217.29642, 221.55605, 229.93001],
      dtype=float32)
Coordinates:
  * level    (level) float32 1e+03 925.0 850.0 700.0 ... 50.0 30.0 20.0 10.0

xarray.DataArray

level: 17

<input id='section-70ec5d9b-e0bf-4a2f-a9b7-ea60911a8a4c' class='xr-array-in' type='checkbox' checked><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>
288.3 284.4 281.0 273.4 266.7 258.3 ... 207.6 211.7 217.3 221.6 229.9

array([288.32907, 284.357  , 280.9883 , 273.36993, 266.70166, 258.26114,
       247.57953, 233.7803 , 226.35208, 219.49774, 212.58643, 206.14392,
       207.61707, 211.66336, 217.29642, 221.55605, 229.93001],
      dtype=float32)

<input id='section-fb5e77da-3d36-4fd4-8f5a-9800b3fff7a6' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (1)

level

(level)

float32

1e+03 925.0 850.0 ... 20.0 10.0
<input id='attrs-25d68f06-4ce0-44f0-93cf-e83ce9d12e25' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-626bc9e3-95db-4bb2-89fc-8d22d96c7de3' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

millibar

long_name :

Level

positive :

down

GRIB_id :

100

GRIB_name :

hPa

actual_range :

[1000.   10.]

axis :

Z

array([1000.,  925.,  850.,  700.,  600.,  500.,  400.,  300.,  250.,  200.,
        150.,  100.,   70.,   50.,   30.,   20.,   10.], dtype=float32)

<input id='section-54646f05-589b-4269-a715-c0c3b378ccd3' class='xr-section-summary-in' type='checkbox' disabled >Attributes: (0)

```python
#  A handy re-usable routine for making a plot of the temperature profiles
#  We will plot temperatures with respect to log(pressure) to get a height-like coordinate

def zstar(lev):
    return -np.log(lev / climlab.constants.ps)

def plot_soundings(result_list, name_list, plot_obs=True, fixed_range=True):
    color_cycle=['r', 'g', 'b', 'y']
    # col is either a column model object or a list of column model objects
    #if isinstance(state_list, climlab.Process):
    #    # make a list with a single item
    #    collist = [collist]
    fig, ax = plt.subplots(figsize=(9,9))
    if plot_obs:
        ax.plot(Tglobal, zstar(Tglobal.level), color='k', label='Observed')
    for i, state in enumerate(result_list):
        Tatm = state['Tatm']
        lev = Tatm.domain.axes['lev'].points
        Ts = state['Ts']
        ax.plot(Tatm, zstar(lev), color=color_cycle[i], label=name_list[i])
        ax.plot(Ts, 0, 'o', markersize=12, color=color_cycle[i])
    #ax.invert_yaxis()
    yticks = np.array([1000., 750., 500., 250., 100., 50., 20., 10., 5.])
    ax.set_yticks(-np.log(yticks/1000.))
    ax.set_yticklabels(yticks)
    ax.set_xlabel('Temperature (K)', fontsize=14)
    ax.set_ylabel('Pressure (hPa)', fontsize=14)
    ax.grid()
    ax.legend()
    if fixed_range:
        ax.set_xlim([200, 300])
        ax.set_ylim(zstar(np.array([1000., 5.])))
    #ax2 = ax.twinx()

    return ax
```

```python
plot_soundings([],[] );
```

____________

## 4. A 30-layer model using the observed temperatures
____________

```python
#  initialize a grey radiation model with 30 levels
col = climlab.GreyRadiationModel()
print(col)
```

    climlab Process of type <class 'climlab.model.column.GreyRadiationModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (30,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.GreyRadiationModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>

```python
col.lev
```

    array([ 16.66666667,  50.        ,  83.33333333, 116.66666667,
           150.        , 183.33333333, 216.66666667, 250.        ,
           283.33333333, 316.66666667, 350.        , 383.33333333,
           416.66666667, 450.        , 483.33333333, 516.66666667,
           550.        , 583.33333333, 616.66666667, 650.        ,
           683.33333333, 716.66666667, 750.        , 783.33333333,
           816.66666667, 850.        , 883.33333333, 916.66666667,
           950.        , 983.33333333])

```python
col.lev_bounds
```

    array([   0.        ,   33.33333333,   66.66666667,  100.        ,
            133.33333333,  166.66666667,  200.        ,  233.33333333,
            266.66666667,  300.        ,  333.33333333,  366.66666667,
            400.        ,  433.33333333,  466.66666667,  500.        ,
            533.33333333,  566.66666667,  600.        ,  633.33333333,
            666.66666667,  700.        ,  733.33333333,  766.66666667,
            800.        ,  833.33333333,  866.66666667,  900.        ,
            933.33333333,  966.66666667, 1000.        ])

```python
# interpolate to 30 evenly spaced pressure levels
lev = col.lev
Tinterp = np.interp(lev, np.flipud(Tglobal.level), np.flipud(Tglobal))
Tinterp
#  Need to 'flipud' because the interpolation routine
#  needs the pressure data to be in increasing order
```

    array([224.34736633, 211.6633606 , 206.96233453, 208.29142253,
           212.58642578, 217.19396973, 221.78252157, 226.3520813 ,
           231.30422974, 236.08017476, 240.67991638, 245.279658  ,
           249.35979716, 252.92033386, 256.48087056, 259.66789246,
           262.48139954, 265.29490662, 267.81303914, 270.03579712,
           272.25855509, 274.21642049, 275.90939331, 277.60236613,
           279.29533895, 280.98831177, 282.48550415, 283.98269653,
           285.6810201 , 287.4463874 ])

```python
# Initialize model with observed temperatures
col.Ts[:] = Tglobal[0]
col.Tatm[:] = Tinterp
```

```python
# This should look just like the observations
result_list = [col.state]
name_list = ['Observed, interpolated']
plot_soundings(result_list, name_list);
```

### Tune absorptivity to get observed OLR

```python
col.compute_diagnostics()
col.OLR
```

    array([263.15000104])

```python
# Need to tune absorptivity to get OLR = 238.5
epsarray = np.linspace(0.01, 0.1, 100)
OLRarray = np.zeros_like(epsarray)
```

```python
for i in range(epsarray.size):
    col.subprocess['LW'].absorptivity = epsarray[i]
    col.compute_diagnostics()
    OLRarray[i] = col.OLR

plt.plot(epsarray, OLRarray)
plt.grid()
plt.xlabel('epsilon')
plt.ylabel('OLR')
```

The necessary value seems to lie near 0.055 or so.

We can be more precise with a numerical root-finder.

```python
def OLRanom(eps):
    col.subprocess['LW'].absorptivity = eps
    col.compute_diagnostics()
    return col.OLR - 238.5
```

```python
# Use numerical root-finding to get the equilibria
from scipy.optimize import brentq
# brentq is a root-finding function
#  Need to give it a function and two end-points
#  It will look for a zero of the function between those end-points
eps = brentq(OLRanom, 0.01, 0.1)
print( eps)
```

    0.05369073166506245

```python
col.subprocess.LW.absorptivity = eps
col.subprocess.LW.absorptivity
```

    Field([0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073,
           0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073,
           0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073,
           0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073,
           0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073,
           0.05369073, 0.05369073, 0.05369073, 0.05369073, 0.05369073])

```python
col.compute_diagnostics()
col.OLR
```

    array([238.5])

____________

## 5. Radiative forcing in the 30-layer model
____________

Let's compute radiative forcing for a **2% increase in absorptivity**.

```python
#  clone our model using a built-in climlab function
col2 = climlab.process_like(col)
print(col2)
```

    climlab Process of type <class 'climlab.model.column.GreyRadiationModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (30,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.GreyRadiationModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>

```python
col2.subprocess['LW'].absorptivity *= 1.02
col2.subprocess['LW'].absorptivity
```

    Field([0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455,
           0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455,
           0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455,
           0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455,
           0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455,
           0.05476455, 0.05476455, 0.05476455, 0.05476455, 0.05476455])

```python
#  Radiative forcing by definition is the change in TOA radiative flux,
# HOLDING THE TEMPERATURES FIXED.
col2.Ts - col.Ts
```

    Field([0.])

```python
col2.Tatm - col.Tatm
```

    Field([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

```python
col2.compute_diagnostics()
col2.OLR
```

    array([236.65384137])

The OLR decreased after we added the extra absorbers, as we expect. Now we can calculate the Radiative Forcing:

```python
RF = -(col2.OLR - col.OLR)
print( 'The radiative forcing is %.2f W/m2.' %RF)
```

    The radiative forcing is 1.85 W/m2.

____________

## 6. Radiative equilibrium in the 30-layer model
____________

```python
re = climlab.process_like(col)
```

```python
#  To get to equilibrium, we just time-step the model forward long enough
re.integrate_years(1.)
```

    Integrating for 365 steps, 365.2422 days, or 1.0 years.
    Total elapsed time is 0.9993368783782377 years.

```python
#  Check for energy balance
print( 'The net downward radiative flux at TOA is %.4f W/m2.' %(re.ASR - re.OLR))
```

    The net downward radiative flux at TOA is -0.0015 W/m2.

```python
result_list.append(re.state)
name_list.append('Radiative equilibrium (grey gas)')
plot_soundings(result_list, name_list)
```

Some properties of the **radiative equilibrium** temperature profile:

- The surface is warmer than observed.
- The lower troposphere is colder than observed.
- Very cold air is sitting immediately above the warm surface.
- There is no tropopause, no stratosphere.

____________

## 7. Radiative-Convective Equilibrium in the 30-layer model
____________

We recognize that the large drop in temperature just above the surface is unphysical. Parcels of air in direct contact with the ground will be warmed by mechansisms other than radiative transfer.

These warm air parcels will then become buoyant, and will convect upward, mixing their heat content with the environment.

We **parameterize** the statistical effects of this mixing through a **convective adjustment**.

At each timestep, our model checks for any locations at which the **lapse rate** exceeds some threshold. Unstable layers are removed through an energy-conserving mixing formula.

This process is assumed to be fast relative to radiative heating. In the model, it is instantaneous.

### Add the convective adjustment as an additional subprocess

```python
#  Here is the existing model
print(re)
```

    climlab Process of type <class 'climlab.model.column.GreyRadiationModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (30,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.GreyRadiationModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>

```python
#  First we make a new clone
rce = climlab.process_like(re)
#  Then create a new ConvectiveAdjustment process
conv = climlab.convection.ConvectiveAdjustment(state=rce.state,
                                               adj_lapse_rate=6.)
#  And add it to our model
rce.add_subprocess('Convective Adjustment', conv)
print(rce)
```

    climlab Process of type <class 'climlab.model.column.GreyRadiationModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (30,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.GreyRadiationModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>
       Convective Adjustment: <class 'climlab.convection.convadj.ConvectiveAdjustment'>

This model is exactly like our previous models, except for one additional subprocess called ``Convective Adjustment``.

We passed a parameter ``adj_lapse_rate`` (in K / km) that sets the neutrally stable lapse rate -- in this case, 6 K / km.

This number is chosed to very loosely represent the net effect of **moist convection**.

```python
#  Run out to equilibrium
rce.integrate_years(1.)
```

    Integrating for 365 steps, 365.2422 days, or 1.0 years.
    Total elapsed time is 1.9986737567564754 years.

```python
#  Check for energy balance
rce.ASR - rce.OLR
```

    Field([0.0007796])

```python
result_list.append(rce.state)
name_list.append('Radiatve-Convective equilibrium (grey gas)')
```

```python
plot_soundings(result_list, name_list)
```

Introducing convective adjustment into the model cools the surface quite a bit (compared to Radiative Equilibrium, in green here) -- and warms the lower troposphere. It gives us a MUCH better fit to observations.

But of course we still have no stratosphere.

____________

## 8. Putting stratospheric ozone in the grey-gas model
____________

Our model has no equivalent of the stratosphere, where temperature increases with height. That's because our model has been completely transparent to shortwave radiation up until now.

We can load the observed ozone climatology from the input files for the CESM model:

```python
datapath = "http://thredds.atmos.albany.edu:8080/thredds/dodsC/CESMA/"
ozone = xr.open_dataset( datapath + "som_input/ozone_1.9x2.5_L26_2000clim_c091112.nc")
```

```python
ozone
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.Dataset>
Dimensions:  (ilev: 27, lat: 96, lev: 26, lon: 144, slat: 95, slon: 144, time: 12)
Coordinates:
  * ilev     (ilev) float64 2.194 4.895 9.882 18.05 ... 903.3 956.0 985.1 1e+03
  * lat      (lat) float64 -90.0 -88.11 -86.21 -84.32 ... 84.32 86.21 88.11 90.0
  * lev      (lev) float64 3.545 7.389 13.97 23.94 ... 867.2 929.6 970.6 992.6
  * lon      (lon) float64 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
  * slat     (slat) float64 -89.05 -87.16 -85.26 -83.37 ... 85.26 87.16 89.05
  * slon     (slon) float64 -1.25 1.25 3.75 6.25 ... 348.8 351.2 353.8 356.2
  * time     (time) object 2000-01-15 00:00:00 ... 2000-12-15 00:00:00
Data variables:
    P0       float64 1e+05
    date     (time) int32 20000115 20000215 20000315 ... 20001115 20001215
    datesec  (time) int32 0 0 0 0 0 0 0 0 0 0 0 0
    gw       (lat) float64 0.0001367 0.001093 0.002185 ... 0.001093 0.0001367
    hyai     (ilev) float64 0.002194 0.004895 0.009882 ... 0.002521 0.0 0.0
    hyam     (lev) float64 0.003545 0.007389 0.01397 ... 0.004803 0.001261 0.0
    hybi     (ilev) float64 0.0 0.0 0.0 0.0 0.0 ... 0.8962 0.9535 0.9851 1.0
    hybm     (lev) float64 0.0 0.0 0.0 0.0 0.0 ... 0.8569 0.9248 0.9693 0.9926
    w_stag   (slat) float64 0.0005467 0.00164 0.002731 ... 0.00164 0.0005467
    O3       (time, lev, lat, lon) float32 ...
    PS       (time, lat, lon) float32 ...
Attributes: (12/14)
    Conventions:                     CF-1.0
    source:                          CAM
    case:                            ar5_cam_1850-2000_03
    title:
    logname:                         lamar
    host:                            be0207en.ucar.ed
    ...                              ...
    initial_file:                    /ptmp/lamar/cam-inputs/ar5_cam_1850_06.c...
    topography_file:                 /fs/cgd/csm/inputdata/atm/cam/topo/USGS-...
    history:                         Wed Jan  5 14:56:28 2011: ncks -d time,1...
    nco_openmp_thread_number:        1
    NCO:                             4.0.5
    DODS_EXTRA.Unlimited_Dimension:  time

xarray.Dataset

<input id='section-cd448494-3c82-4402-a6c1-32602248616a' class='xr-section-summary-in' type='checkbox' disabled >Dimensions:

ilev: 27

lat: 96

lev: 26

lon: 144

slat: 95

slon: 144

time: 12

<input id='section-431b705c-69f8-4d13-b8b6-0147c1d4001a' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (7)

ilev

(ilev)

float64

2.194 4.895 9.882 ... 985.1 1e+03
<input id='attrs-bbcee7a9-a633-47e8-8b22-b380104cc8cf' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-84b0eaa9-a564-4383-838a-c56276b62004' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid level at interfaces (1000*(A+B))

units :

level

positive :

down

standard_name :

atmosphere_hybrid_sigma_pressure_coordinate

formula_terms :

a: hyai b: hybi p0: P0 ps: PS

array([   2.194067,    4.895209,    9.882418,   18.05201 ,   29.83724 ,
         44.62334 ,   61.60587 ,   78.51243 ,   92.3658  ,  108.66359 ,
        127.83708 ,  150.39371 ,  176.93043 ,  208.14944 ,  244.87709 ,
        288.08522 ,  338.91731 ,  398.71865 ,  469.0718  ,  551.83871 ,
        649.20969 ,  744.38289 ,  831.02123 ,  903.30029 ,  955.99746 ,
        985.1122  , 1000.      ])

lat

(lat)

float64

-90.0 -88.11 -86.21 ... 88.11 90.0
<input id='attrs-5ac94b12-d07e-4019-af39-9f116750084c' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-e7a6f738-9eab-4a1a-8b8b-a9959c699cb9' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

latitude

units :

degrees_north

array([-90.      , -88.105263, -86.210526, -84.315789, -82.421053, -80.526316,
       -78.631579, -76.736842, -74.842105, -72.947368, -71.052632, -69.157895,
       -67.263158, -65.368421, -63.473684, -61.578947, -59.684211, -57.789474,
       -55.894737, -54.      , -52.105263, -50.210526, -48.315789, -46.421053,
       -44.526316, -42.631579, -40.736842, -38.842105, -36.947368, -35.052632,
       -33.157895, -31.263158, -29.368421, -27.473684, -25.578947, -23.684211,
       -21.789474, -19.894737, -18.      , -16.105263, -14.210526, -12.315789,
       -10.421053,  -8.526316,  -6.631579,  -4.736842,  -2.842105,  -0.947368,
         0.947368,   2.842105,   4.736842,   6.631579,   8.526316,  10.421053,
        12.315789,  14.210526,  16.105263,  18.      ,  19.894737,  21.789474,
        23.684211,  25.578947,  27.473684,  29.368421,  31.263158,  33.157895,
        35.052632,  36.947368,  38.842105,  40.736842,  42.631579,  44.526316,
        46.421053,  48.315789,  50.210526,  52.105263,  54.      ,  55.894737,
        57.789474,  59.684211,  61.578947,  63.473684,  65.368421,  67.263158,
        69.157895,  71.052632,  72.947368,  74.842105,  76.736842,  78.631579,
        80.526316,  82.421053,  84.315789,  86.210526,  88.105263,  90.      ])

lev

(lev)

float64

3.545 7.389 13.97 ... 970.6 992.6
<input id='attrs-9fa3d103-558c-42c9-aff1-1ef93fe1901d' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-e8d96914-1b9f-4ed8-ac47-8aa1a5c41efb' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid level at midpoints (1000*(A+B))

units :

level

positive :

down

standard_name :

atmosphere_hybrid_sigma_pressure_coordinate

formula_terms :

a: hyam b: hybm p0: P0 ps: PS

array([  3.544638,   7.388814,  13.967214,  23.944625,  37.23029 ,  53.114605,
        70.05915 ,  85.439115, 100.514695, 118.250335, 139.115395, 163.66207 ,
       192.539935, 226.513265, 266.481155, 313.501265, 368.81798 , 433.895225,
       510.455255, 600.5242  , 696.79629 , 787.70206 , 867.16076 , 929.648875,
       970.55483 , 992.5561  ])

lon

(lon)

float64

0.0 2.5 5.0 ... 352.5 355.0 357.5
<input id='attrs-965b4dc3-f664-42ca-81ec-547baf4ad9c6' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-9bc1e5e7-a86f-4710-bb6b-2977c5712957' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

longitude

units :

degrees_east

array([  0. ,   2.5,   5. ,   7.5,  10. ,  12.5,  15. ,  17.5,  20. ,  22.5,
        25. ,  27.5,  30. ,  32.5,  35. ,  37.5,  40. ,  42.5,  45. ,  47.5,
        50. ,  52.5,  55. ,  57.5,  60. ,  62.5,  65. ,  67.5,  70. ,  72.5,
        75. ,  77.5,  80. ,  82.5,  85. ,  87.5,  90. ,  92.5,  95. ,  97.5,
       100. , 102.5, 105. , 107.5, 110. , 112.5, 115. , 117.5, 120. , 122.5,
       125. , 127.5, 130. , 132.5, 135. , 137.5, 140. , 142.5, 145. , 147.5,
       150. , 152.5, 155. , 157.5, 160. , 162.5, 165. , 167.5, 170. , 172.5,
       175. , 177.5, 180. , 182.5, 185. , 187.5, 190. , 192.5, 195. , 197.5,
       200. , 202.5, 205. , 207.5, 210. , 212.5, 215. , 217.5, 220. , 222.5,
       225. , 227.5, 230. , 232.5, 235. , 237.5, 240. , 242.5, 245. , 247.5,
       250. , 252.5, 255. , 257.5, 260. , 262.5, 265. , 267.5, 270. , 272.5,
       275. , 277.5, 280. , 282.5, 285. , 287.5, 290. , 292.5, 295. , 297.5,
       300. , 302.5, 305. , 307.5, 310. , 312.5, 315. , 317.5, 320. , 322.5,
       325. , 327.5, 330. , 332.5, 335. , 337.5, 340. , 342.5, 345. , 347.5,
       350. , 352.5, 355. , 357.5])

slat

(slat)

float64

-89.05 -87.16 ... 87.16 89.05
<input id='attrs-8362236e-f483-41f1-bf54-727177005db1' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-cf263a30-67ed-421b-8e15-916326d035de' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

staggered latitude

units :

degrees_north

array([-89.052632, -87.157895, -85.263158, -83.368421, -81.473684, -79.578947,
       -77.684211, -75.789474, -73.894737, -72.      , -70.105263, -68.210526,
       -66.315789, -64.421053, -62.526316, -60.631579, -58.736842, -56.842105,
       -54.947368, -53.052632, -51.157895, -49.263158, -47.368421, -45.473684,
       -43.578947, -41.684211, -39.789474, -37.894737, -36.      , -34.105263,
       -32.210526, -30.315789, -28.421053, -26.526316, -24.631579, -22.736842,
       -20.842105, -18.947368, -17.052632, -15.157895, -13.263158, -11.368421,
        -9.473684,  -7.578947,  -5.684211,  -3.789474,  -1.894737,   0.      ,
         1.894737,   3.789474,   5.684211,   7.578947,   9.473684,  11.368421,
        13.263158,  15.157895,  17.052632,  18.947368,  20.842105,  22.736842,
        24.631579,  26.526316,  28.421053,  30.315789,  32.210526,  34.105263,
        36.      ,  37.894737,  39.789474,  41.684211,  43.578947,  45.473684,
        47.368421,  49.263158,  51.157895,  53.052632,  54.947368,  56.842105,
        58.736842,  60.631579,  62.526316,  64.421053,  66.315789,  68.210526,
        70.105263,  72.      ,  73.894737,  75.789474,  77.684211,  79.578947,
        81.473684,  83.368421,  85.263158,  87.157895,  89.052632])

slon

(slon)

float64

-1.25 1.25 3.75 ... 353.8 356.2
<input id='attrs-fa725872-76b9-4faf-8f87-c220843d187f' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-48ca6c49-0769-4415-86ca-53b4f5885a76' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

staggered longitude

units :

degrees_east

array([ -1.25,   1.25,   3.75,   6.25,   8.75,  11.25,  13.75,  16.25,  18.75,
        21.25,  23.75,  26.25,  28.75,  31.25,  33.75,  36.25,  38.75,  41.25,
        43.75,  46.25,  48.75,  51.25,  53.75,  56.25,  58.75,  61.25,  63.75,
        66.25,  68.75,  71.25,  73.75,  76.25,  78.75,  81.25,  83.75,  86.25,
        88.75,  91.25,  93.75,  96.25,  98.75, 101.25, 103.75, 106.25, 108.75,
       111.25, 113.75, 116.25, 118.75, 121.25, 123.75, 126.25, 128.75, 131.25,
       133.75, 136.25, 138.75, 141.25, 143.75, 146.25, 148.75, 151.25, 153.75,
       156.25, 158.75, 161.25, 163.75, 166.25, 168.75, 171.25, 173.75, 176.25,
       178.75, 181.25, 183.75, 186.25, 188.75, 191.25, 193.75, 196.25, 198.75,
       201.25, 203.75, 206.25, 208.75, 211.25, 213.75, 216.25, 218.75, 221.25,
       223.75, 226.25, 228.75, 231.25, 233.75, 236.25, 238.75, 241.25, 243.75,
       246.25, 248.75, 251.25, 253.75, 256.25, 258.75, 261.25, 263.75, 266.25,
       268.75, 271.25, 273.75, 276.25, 278.75, 281.25, 283.75, 286.25, 288.75,
       291.25, 293.75, 296.25, 298.75, 301.25, 303.75, 306.25, 308.75, 311.25,
       313.75, 316.25, 318.75, 321.25, 323.75, 326.25, 328.75, 331.25, 333.75,
       336.25, 338.75, 341.25, 343.75, 346.25, 348.75, 351.25, 353.75, 356.25])

time

(time)

object

2000-01-15 00:00:00 ... 2000-12-...
<input id='attrs-6aeed902-ea8a-4f54-93ec-b47b6e68f4d5' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-6d645b1a-969a-4318-a123-ee96cf4523a7' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

time

bounds :

time_bnds

array([cftime.DatetimeNoLeap(2000, 1, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 2, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 3, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 4, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 5, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 6, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 7, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 8, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 9, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 10, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 11, 15, 0, 0, 0, 0),
       cftime.DatetimeNoLeap(2000, 12, 15, 0, 0, 0, 0)], dtype=object)

<input id='section-90fb6bed-cddb-4f80-9a5d-42ab0afae279' class='xr-section-summary-in' type='checkbox'  checked>Data variables: (11)

P0

()

float64

...
<input id='attrs-4b433aa4-1a12-4f06-a2a5-497a32b1c901' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-7d14952f-f266-49c1-a801-fcaeb5aba8bd' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

reference pressure

units :

Pa

array(100000.)

date

(time)

int32

...
<input id='attrs-8db17eed-a3f5-42c5-b0d5-84c5bf5a2164' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-594cd18b-f958-4aeb-9a2a-77ca606a174a' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

date

format :

YYYYMMDD

array([20000115, 20000215, 20000315, 20000415, 20000515, 20000615, 20000715,
       20000815, 20000915, 20001015, 20001115, 20001215], dtype=int32)

datesec

(time)

int32

...
<input id='attrs-f4906dd6-a53b-48cc-9cdb-00391e61594d' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-eafd1dbe-3018-4a4f-9608-0b2173da5827' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

current seconds of current date

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

gw

(lat)

float64

...
<input id='attrs-53a30144-d067-43b7-bc02-16fd190f2ff2' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-636e07b1-a914-45ed-9f93-aa2deb84e57f' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

gauss weights

array([0.000137, 0.001093, 0.002185, 0.003275, 0.004361, 0.005443, 0.006518,
       0.007587, 0.008647, 0.009697, 0.010737, 0.011765, 0.012781, 0.013782,
       0.014768, 0.015739, 0.016692, 0.017626, 0.018542, 0.019437, 0.020311,
       0.021162, 0.021991, 0.022795, 0.023575, 0.024329, 0.025056, 0.025756,
       0.026427, 0.02707 , 0.027683, 0.028266, 0.028818, 0.029339, 0.029827,
       0.030283, 0.030705, 0.031094, 0.031449, 0.03177 , 0.032056, 0.032307,
       0.032522, 0.032702, 0.032847, 0.032955, 0.033027, 0.033063, 0.033063,
       0.033027, 0.032955, 0.032847, 0.032702, 0.032522, 0.032307, 0.032056,
       0.03177 , 0.031449, 0.031094, 0.030705, 0.030283, 0.029827, 0.029339,
       0.028818, 0.028266, 0.027683, 0.02707 , 0.026427, 0.025756, 0.025056,
       0.024329, 0.023575, 0.022795, 0.021991, 0.021162, 0.020311, 0.019437,
       0.018542, 0.017626, 0.016692, 0.015739, 0.014768, 0.013782, 0.012781,
       0.011765, 0.010737, 0.009697, 0.008647, 0.007587, 0.006518, 0.005443,
       0.004361, 0.003275, 0.002185, 0.001093, 0.000137])

hyai

(ilev)

float64

...
<input id='attrs-671c5f1c-59a0-4ada-bd29-65e227bf9f9a' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-63d2e4d9-4cea-4bf0-ad7f-70a88a4a61c6' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid A coefficient at layer interfaces

array([0.002194, 0.004895, 0.009882, 0.018052, 0.029837, 0.044623, 0.061606,
       0.078512, 0.077313, 0.075901, 0.074241, 0.072287, 0.069989, 0.067286,
       0.064105, 0.060363, 0.055961, 0.050782, 0.04469 , 0.037522, 0.029089,
       0.020847, 0.013344, 0.007085, 0.002521, 0.      , 0.      ])

hyam

(lev)

float64

...
<input id='attrs-071510f3-a2dd-4514-ab41-0fc691db9e6e' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-af5d6cb8-0bad-4457-af22-8d0b1790d9a9' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid A coefficient at layer midpoints

array([0.003545, 0.007389, 0.013967, 0.023945, 0.03723 , 0.053115, 0.070059,
       0.077913, 0.076607, 0.075071, 0.073264, 0.071138, 0.068638, 0.065695,
       0.062234, 0.058162, 0.053372, 0.047736, 0.041106, 0.033306, 0.024968,
       0.017096, 0.010215, 0.004803, 0.001261, 0.      ])

hybi

(ilev)

float64

...
<input id='attrs-cf338f38-46c4-4a0d-96ce-fd4559686c19' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-37143111-1a34-4f20-8430-3c05e51ac833' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid B coefficient at layer interfaces

array([0.      , 0.      , 0.      , 0.      , 0.      , 0.      , 0.      ,
       0.      , 0.015053, 0.032762, 0.053596, 0.078106, 0.106941, 0.140864,
       0.180772, 0.227722, 0.282956, 0.347936, 0.424382, 0.514317, 0.62012 ,
       0.723536, 0.817677, 0.896215, 0.953476, 0.985112, 1.      ])

hybm

(lev)

float64

...
<input id='attrs-1e628330-a033-479d-a280-ff3c0dfc4d15' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-0701e6cf-8bb0-415b-9034-751ba9c87477' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid B coefficient at layer midpoints

array([0.      , 0.      , 0.      , 0.      , 0.      , 0.      , 0.      ,
       0.007527, 0.023908, 0.043179, 0.065851, 0.092524, 0.123902, 0.160818,
       0.204247, 0.255339, 0.315446, 0.386159, 0.46935 , 0.567219, 0.671828,
       0.770606, 0.856946, 0.924846, 0.969294, 0.992556])

w_stag

(slat)

float64

...
<input id='attrs-d6000dfd-1b89-4646-9255-fd431a37a066' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-12502d39-e2d3-4311-9d50-a25ac2e5c037' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

staggered latitude weights

array([0.000547, 0.00164 , 0.002731, 0.003819, 0.004903, 0.005981, 0.007053,
       0.008118, 0.009173, 0.010219, 0.011253, 0.012275, 0.013283, 0.014277,
       0.015256, 0.016217, 0.017161, 0.018086, 0.018992, 0.019876, 0.020739,
       0.02158 , 0.022396, 0.023188, 0.023955, 0.024696, 0.025409, 0.026095,
       0.026752, 0.027381, 0.027979, 0.028546, 0.029082, 0.029587, 0.030059,
       0.030498, 0.030904, 0.031276, 0.031614, 0.031917, 0.032186, 0.032419,
       0.032617, 0.032779, 0.032905, 0.032996, 0.03305 , 0.033068, 0.03305 ,
       0.032996, 0.032905, 0.032779, 0.032617, 0.032419, 0.032186, 0.031917,
       0.031614, 0.031276, 0.030904, 0.030498, 0.030059, 0.029587, 0.029082,
       0.028546, 0.027979, 0.027381, 0.026752, 0.026095, 0.025409, 0.024696,
       0.023955, 0.023188, 0.022396, 0.02158 , 0.020739, 0.019876, 0.018992,
       0.018086, 0.017161, 0.016217, 0.015256, 0.014277, 0.013283, 0.012275,
       0.011253, 0.010219, 0.009173, 0.008118, 0.007053, 0.005981, 0.004903,
       0.003819, 0.002731, 0.00164 , 0.000547])

O3

(time, lev, lat, lon)

float32

...
<input id='attrs-794416bf-080d-4ff7-8304-9592254cc179' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-b2b25a0c-5029-4059-8921-448f1c072218' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

mol/mol

long_name :

O3 concentration

cell_method :

time: mean

[4313088 values with dtype=float32]

PS

(time, lat, lon)

float32

...
<input id='attrs-ad8f2bd6-74d6-4c4d-ac93-c0ee1dc9670d' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-b2d2bed4-895c-43f7-996c-31081ced592f' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

units :

Pa

long_name :

Surface pressure

cell_method :

time: mean

[165888 values with dtype=float32]

<input id='section-39c762e0-b8cd-4a25-a428-e3de355d7778' class='xr-section-summary-in' type='checkbox'  >Attributes: (14)

Conventions :

CF-1.0

source :

CAM

case :

ar5_cam_1850-2000_03

title :

logname :

lamar

host :

be0207en.ucar.ed

Version :

$Name$

revision_Id :

$Id$

initial_file :

/ptmp/lamar/cam-inputs/ar5_cam_1850_06.cam2.i.1860-01-01-00000.nc

topography_file :

/fs/cgd/csm/inputdata/atm/cam/topo/USGS-gtopo30_1.9x2.5_remap_c050602.nc

history :

Wed Jan  5 14:56:28 2011: ncks -d time,192,203 /fs/cgd/csm/inputdata/atm/cam/ozone/ozone_1.9x2.5_L26_1850-2005_c091112.nc ozone_1.9x2.5_L26_2000clim_c091112.nc
Tue Nov 17 09:59:20 2009: ncks --append -v date,time date_time_1849-2006_c091112.nc ozone_1.9x2.5_L26_1850-2005_c091112.nc
Tue Nov 17 09:54:06 2009: ncrcat ozone_1850-1859.r4.nc ozone_1850-1859.r4.nc ozone_1860-1869.r4.nc ozone_1870-1879.r4.nc ozone_1880-1889.r4.nc ozone_1890-1899.r4.nc ozone_1900-1909.r4.nc ozone_1910-1919.r4.nc ozone_1920-1929.r4.nc ozone_1930-1939.r4.nc ozone_1940-1949.r4.nc ozone_1950-1959.r4.nc ozone_1960-1969.r4.nc ozone_1970-1979.r4.nc ozone_1980-1989.r4.nc ozone_1990-1999.r4.nc ozone_2000-2009.r4.nc ozone_2000-2009.r4.nc ozone_1.9x2.5_L26_1850-2005_c091112.nc.672194

11/17/09 09:53:33 eaton:be1105en.ucar.ed:interpic -e T -p 4 -t /fis/cgd/cseg/csm/inputdata/atm/cam/inic/fv/cami_0000-01-01_1.9x2.5_L26_c070408.nc /ptmp/lamar/IPCC_AR5/Climatologies_20091110/ozone_1850-1859.nc ozone_1850-1859.r4.nc

nco_openmp_thread_number :

1

NCO :

4.0.5

DODS_EXTRA.Unlimited_Dimension :

time

The pressure levels in this dataset are:

```python
ozone.lev
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.DataArray 'lev' (lev: 26)>
array([  3.544638,   7.388814,  13.967214,  23.944625,  37.23029 ,  53.114605,
        70.05915 ,  85.439115, 100.514695, 118.250335, 139.115395, 163.66207 ,
       192.539935, 226.513265, 266.481155, 313.501265, 368.81798 , 433.895225,
       510.455255, 600.5242  , 696.79629 , 787.70206 , 867.16076 , 929.648875,
       970.55483 , 992.5561  ])
Coordinates:
  * lev      (lev) float64 3.545 7.389 13.97 23.94 ... 867.2 929.6 970.6 992.6
Attributes:
    long_name:      hybrid level at midpoints (1000*(A+B))
    units:          level
    positive:       down
    standard_name:  atmosphere_hybrid_sigma_pressure_coordinate
    formula_terms:  a: hyam b: hybm p0: P0 ps: PS

xarray.DataArray

'lev'

lev: 26

<input id='section-d3592d0c-eeae-4c4e-af04-4fabeab9ec17' class='xr-array-in' type='checkbox' checked><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>
3.545 7.389 13.97 23.94 37.23 53.11 ... 787.7 867.2 929.6 970.6 992.6

array([  3.544638,   7.388814,  13.967214,  23.944625,  37.23029 ,  53.114605,
        70.05915 ,  85.439115, 100.514695, 118.250335, 139.115395, 163.66207 ,
       192.539935, 226.513265, 266.481155, 313.501265, 368.81798 , 433.895225,
       510.455255, 600.5242  , 696.79629 , 787.70206 , 867.16076 , 929.648875,
       970.55483 , 992.5561  ])

<input id='section-7ace6c19-5886-4a69-96d0-639e9834bbd5' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (1)

lev

(lev)

float64

3.545 7.389 13.97 ... 970.6 992.6
<input id='attrs-cbd03bf1-25e8-4d20-a51d-3a1e806b18c8' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-6067fa06-ffb1-4372-8cc3-6ad067b295b8' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid level at midpoints (1000*(A+B))

units :

level

positive :

down

standard_name :

atmosphere_hybrid_sigma_pressure_coordinate

formula_terms :

a: hyam b: hybm p0: P0 ps: PS

array([  3.544638,   7.388814,  13.967214,  23.944625,  37.23029 ,  53.114605,
        70.05915 ,  85.439115, 100.514695, 118.250335, 139.115395, 163.66207 ,
       192.539935, 226.513265, 266.481155, 313.501265, 368.81798 , 433.895225,
       510.455255, 600.5242  , 696.79629 , 787.70206 , 867.16076 , 929.648875,
       970.55483 , 992.5561  ])

<input id='section-f6efd123-04db-4431-b277-8fdf47053ffc' class='xr-section-summary-in' type='checkbox'  checked>Attributes: (5)

long_name :

hybrid level at midpoints (1000*(A+B))

units :

level

positive :

down

standard_name :

atmosphere_hybrid_sigma_pressure_coordinate

formula_terms :

a: hyam b: hybm p0: P0 ps: PS

### Take the global average of the ozone climatology, and plot it as a function of pressure (or height)

```python
#  Take global, annual average and convert to Kelvin
weight_ozone = cos(deg2rad(ozone.lat)) / cos(deg2rad(ozone.lat)).mean(dim='lat')
O3_global = (ozone.O3 * weight_ozone).mean(dim=('lat','lon','time'))
O3_global
```

<svg style="position: absolute; width: 0; height: 0; overflow: hidden">
<defs>
<symbol id="icon-database" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z"></path>
<path d="M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
<path d="M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z"></path>
</symbol>
<symbol id="icon-file-text2" viewBox="0 0 32 32">
<path d="M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z"></path>
<path d="M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
<path d="M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z"></path>
</symbol>
</defs>
</svg>

<xarray.DataArray (lev: 26)>
array([7.82792878e-06, 8.64150529e-06, 7.58940028e-06, 5.24567145e-06,
       3.17761574e-06, 1.82320006e-06, 9.80756960e-07, 6.22870516e-07,
       4.47620550e-07, 3.34481169e-07, 2.62570302e-07, 2.07898125e-07,
       1.57074555e-07, 1.12425545e-07, 8.06004999e-08, 6.27826498e-08,
       5.42990561e-08, 4.99506089e-08, 4.60075681e-08, 4.22977789e-08,
       3.80559071e-08, 3.38768568e-08, 3.12171619e-08, 2.97807119e-08,
       2.87980968e-08, 2.75429934e-08])
Coordinates:
  * lev      (lev) float64 3.545 7.389 13.97 23.94 ... 867.2 929.6 970.6 992.6

xarray.DataArray

lev: 26

<input id='section-b8be8ee1-d71c-4723-9a10-459755ab101d' class='xr-array-in' type='checkbox' checked><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>
7.828e-06 8.642e-06 7.589e-06 ... 2.978e-08 2.88e-08 2.754e-08

array([7.82792878e-06, 8.64150529e-06, 7.58940028e-06, 5.24567145e-06,
       3.17761574e-06, 1.82320006e-06, 9.80756960e-07, 6.22870516e-07,
       4.47620550e-07, 3.34481169e-07, 2.62570302e-07, 2.07898125e-07,
       1.57074555e-07, 1.12425545e-07, 8.06004999e-08, 6.27826498e-08,
       5.42990561e-08, 4.99506089e-08, 4.60075681e-08, 4.22977789e-08,
       3.80559071e-08, 3.38768568e-08, 3.12171619e-08, 2.97807119e-08,
       2.87980968e-08, 2.75429934e-08])

<input id='section-d5d161ba-b4f3-4fcd-8e18-f7dabffc6cbe' class='xr-section-summary-in' type='checkbox'  checked>Coordinates: (1)

lev

(lev)

float64

3.545 7.389 13.97 ... 970.6 992.6
<input id='attrs-3da3add9-f0f3-4d58-9a8a-56c9de371521' class='xr-var-attrs-in' type='checkbox' ><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg><input id='data-429a13ae-0a98-4ee7-9c61-8ecfa22bc7ad' class='xr-var-data-in' type='checkbox'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg>

long_name :

hybrid level at midpoints (1000*(A+B))

units :

level

positive :

down

standard_name :

atmosphere_hybrid_sigma_pressure_coordinate

formula_terms :

a: hyam b: hybm p0: P0 ps: PS

array([  3.544638,   7.388814,  13.967214,  23.944625,  37.23029 ,  53.114605,
        70.05915 ,  85.439115, 100.514695, 118.250335, 139.115395, 163.66207 ,
       192.539935, 226.513265, 266.481155, 313.501265, 368.81798 , 433.895225,
       510.455255, 600.5242  , 696.79629 , 787.70206 , 867.16076 , 929.648875,
       970.55483 , 992.5561  ])

<input id='section-91d7f139-76b4-49a1-aecc-ba38c73f5937' class='xr-section-summary-in' type='checkbox' disabled >Attributes: (0)

```python
ax = plt.figure(figsize=(10,8)).add_subplot(111)
ax.plot( O3_global * 1.E6, -np.log(ozone.lev/climlab.constants.ps) )
ax.set_xlabel('Ozone (ppm)', fontsize=16)
ax.set_ylabel('Pressure (hPa)', fontsize=16 )
yticks = np.array([1000., 750., 500., 250., 100., 50., 20., 10., 5.])
ax.set_yticks(-np.log(yticks/1000.))
ax.set_yticklabels(yticks)
ax.grid()
ax.set_title('Global, annual mean ozone concentration', fontsize = 24);
```

This shows that most of the ozone is indeed in the stratosphere, and peaks near the top of the stratosphere.

Now create a new column model object **on the same pressure levels as the ozone data**.  We are also going set an adjusted lapse rate of 6 K / km.

```python
# the RadiativeConvectiveModel is pre-defined in climlab
#  It contains the same components are our previous model
#   But here we are specifying a different set of vertical levels.
oz_col = climlab.RadiativeConvectiveModel(lev = ozone.lev, adj_lapse_rate=6)
print(oz_col)
```

    climlab Process of type <class 'climlab.model.column.RadiativeConvectiveModel'>.
    State variables and domain shapes:
      Ts: (1,)
      Tatm: (26,)
    The subprocess tree:
    Untitled: <class 'climlab.model.column.RadiativeConvectiveModel'>
       LW: <class 'climlab.radiation.greygas.GreyGas'>
       SW: <class 'climlab.radiation.greygas.GreyGasSW'>
       insolation: <class 'climlab.radiation.insolation.FixedInsolation'>
       convective adjustment: <class 'climlab.convection.convadj.ConvectiveAdjustment'>

Now we will do something new: let the column absorb some shortwave radiation. We will assume that the shortwave absorptivity is proportional to the ozone concentration we plotted above.

Now we need to weight the absorptivity by the pressure (mass) of each layer.

```python
# This number is an arbitrary parameter that scales how absorptive we are making the ozone
# in our grey gas model
ozonefactor = 75
dp = oz_col.Tatm.domain.lev.delta
epsSW = O3_global.values * dp * ozonefactor
```

We want to use the field `epsSW` as the absorptivity for our SW radiation model.

Let's see what the absorptivity is current set to:

```python
print(oz_col.subprocess['SW'].absorptivity)
```

    [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
     0. 0.]

It defaults to zero.

Before changing this (putting in the ozone), let's take a look at the shortwave absorption in the column:

```python
oz_col.compute_diagnostics()
```

```python
oz_col.diagnostics['SW_absorbed_atm']
```

    array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0.])

Let's now put in the ozone:

```python
oz_col.subprocess['SW'].absorptivity = epsSW
print(oz_col.subprocess['SW'].absorptivity)
```

    [3.20948549e-03 3.37750296e-03 4.71182551e-03 4.57614201e-03
     3.47591203e-03 2.24450924e-03 1.18884331e-03 7.11369788e-04
     5.50761612e-04 4.84170273e-04 4.47141487e-04 4.16507314e-04
     3.70212131e-04 3.11733073e-04 2.62922861e-04 2.40936639e-04
     2.45147939e-04 2.65307555e-04 2.87482272e-04 2.95567946e-04
     2.67120872e-04 2.16427978e-04 1.66169127e-04 1.15468088e-04
     6.79353134e-05 3.81013280e-05]

Let's check how this changes the SW absorption:

```python
oz_col.compute_diagnostics()
oz_col.SW_absorbed_atm
```

    array([1.40571621, 1.47671285, 2.05685574, 1.99236565, 1.50916587,
           0.97239284, 0.51429089, 0.30750441, 0.23797743, 0.20913838,
           0.19309134, 0.17981756, 0.1597929 , 0.13452308, 0.11343944,
           0.10393806, 0.10574109, 0.11442201, 0.12396838, 0.12743553,
           0.11515129, 0.09328389, 0.07161233, 0.04975714, 0.02927232,
           0.01641659])

It is now non-zero, and largest near the top of the column (also top of the array) where the ozone concentration is highest.

Now it's time to run the model out to radiative-convective equilibrium

```python
oz_col.integrate_years(1.)
```

    Integrating for 365 steps, 365.2422 days, or 1.0 years.
    Total elapsed time is 0.9993368783782377 years.

```python
print(oz_col.ASR - oz_col.OLR)
```

    [-0.00396053]

And let's now see what we got!

```python
result_list.append(oz_col.state)
name_list.append('Radiative-Convective equilibrium with O3')
```

```python
#  Make a plot to compare observations, Radiative Equilibrium, Radiative-Convective Equilibrium, and RCE with ozone!
plot_soundings(result_list, name_list)
```

And we finally have something that looks looks like the tropopause, with temperature increasing above at approximately the correct rate.

There are still plenty of discrepancies between this model solution and the observations, including:

- Tropopause temperature is too warm, by about 15 degrees.
- Surface temperature is too cold

There are a number of parameters we might adjust if we wanted to improve the fit, including:

- Longwave absorptivity
- Surface albedo

Feel free to experiment! (That's what models are for, after all).

### The take home message

The dominant effect of stratospheric ozone is to vastly increase the radiative equilibrium temperature in the ozone layer. The temperature needs to be higher so that the longwave emission can balance the shortwave absorption.

Without ozone to absorb incoming solar radiation, the **temperature does not increase with height**.

This simple grey-gas model illustrates this principle very clearly.

____________

## Credits

This notebook is part of [The Climate Laboratory](https://brian-rose.github.io/ClimateLaboratoryBook), an open-source textbook developed and maintained by [Brian E. J. Rose](http://www.atmos.albany.edu/facstaff/brose/index.html), University at Albany.

It is licensed for free and open consumption under the
[Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/) license.

Development of these notes and the [climlab software](https://github.com/brian-rose/climlab) is partially supported by the National Science Foundation under award AGS-1455071 to Brian Rose. Any opinions, findings, conclusions or recommendations expressed here are mine and do not necessarily reflect the views of the National Science Foundation.
____________

```python

```


# Chapter 2 Random Variables Part I

#### *Zhuo Jianchao*

Feb 9, 2020 *Rev 1*

## Random Variables

For elements in sample space, is it tedious to keep notations like $HH, HT, TH, TT$? In many cases, we don't care specific outcomes, instead we care some characteristics associated with them.

We can introduce an "encoding mechanism", say, $X(\cdot)$, which takes into one possible outcome and produce one encoded number to transform different outcomes into integers, like

$$
X(HH)=1\\
X(HT)=2\\
X(TH)=3\\
X(TT)=4$$

Sometimes, this mechanism has analytical benefits. In an experiment to roll a two three times, the sample space is

$$S=\{HH,HT,TH,HH\}$$

If in this experiment, what we consider is how many times heads show up. We can follow textual intuition to encode like

$$
X(HH)=2\\
X(HT)=1\\
X(TH)=1\\
X(TT)=0\\
$$

This "encoding mechanism" is called a **random variable**, which we'll give a formal definition, and discuss in more details.

Before we can really dive into random variable, we first need to introduce some prerequisite concepts.

### Definition 1 Measurable Function

Recall from Chapter 1 Part II, where we introduce the concept of *measurable space*. For every random experiment, we have a sample space $S$, and an associated $\sigma$-algebra $\mathbb{B}$, then $(S, \mathbb{B})$ is a measurable space.

Let's say there are two sample space $X$ and $Y$, and their corresponding $\sigma$-algebra $\mathcal{A}$ and $\mathcal{B}$ respectively, then $(X,\mathcal{A})$ and $(Y,\mathcal{B})$ are two measurable space.

>A function $f: X \rightarrow Y$ is $(\mathcal{A}, \mathcal{B})$-measurable if and only if
>$$f^{-1}(B) \in \mathcal{A} \text{ for every } B \in \mathcal{B}$$

Axiomatical statement looks abstract and overwhelming. We can instead impose more practical meanings on these symbols, and try to better understand them.

### Example 1.1

Let's roll a dice once with three sides, $1, 2, 3$ respectively. The sample space for this random experiment is $X$, then
$$X=\{1,2,3\}$$

The $\sigma$-algebra associated with $X$ is $\mathcal{A}$, then
$$\mathcal{A}=\{\emptyset, \{1\}, \{2\}, \{3\}, \{1,2\}, \{1,3\}, \{2,3\}, \{1,2,3\}\}$$

So $(X,\mathcal{A})$ is a measurable space.

If we care how many times $1$ shows up, then the new sample space  $Y$ is now
$$Y=\{\emptyset, \{0\}, \{1\}, \{0,1\}\}$$

And the $\sigma$-algebra associated with $Y$, $\mathcal{B}$ is

$$\mathcal{B}=\{\emptyset, \{0\}, \{1\}, \{0,1\}\}$$

Now we defind a function $f(\cdot)$ to transform sample space $X$ to $Y$ by counting how many times head shows up in each element of $\mathcal{A}$ by the following rules

$$ \begin{align}
f(\emptyset)=\emptyset \tag{1} \\
f(\{1\})=1 \tag{2}\\
f(\{2\})=0 \\
f(\{3\})=0 \\
f(\{1,2\})=\{0,1\} \tag{3}\\
f(\{1,3\})=\{0,1\} \\
f(\{2,3\})=0 \\
f(\{1,2,3\})=\{0,1\}
\end{align}
$$

Take three of them to illustrate the transforming rules,
* $(1)$ means we can't get something out of nothing. An event of nothing happening is still an event of nothing happening in other sample space;
* $(2)$ tells us the event of the number rolled being $1$ in $\mathcal{A}$ is the event that the number of head is $1$ in $\mathcal{B}$;
* $(3)$ indicates that the event of the number roll is $1$ **or** $2$ in $\mathcal{A}$ is the event that the number of head is $0$ or $1$ in $\mathcal{B}$.

All these rules follow same interpretations.

Why do we transform every element in the $\sigma$-algebra instead of basic outcome in sample space?
> Recall how probability function is defined where it is defined on the measurable sets, **events**, not to basic outcome, that's the reason why we are required to transform between elements of two $\sigma$-algebra generated by two sample space separately if we are to transform one sample space into another.

Notice the funtion $f$ transforms all elements of $\mathcal{A}$ into elements of $\mathcal{B}$. Now let's check the definition of measurable funtion which requires that a set of elements generated by every element in $\mathcal{B}$ through the reverse transform is included in $\mathcal{A}$.

Still confusing? There are four elements in $\mathcal{B}$, which we take reverse transform one by one.
1. $\emptyset$: $f^{-1}(\emptyset)=\emptyset \in \mathcal{A}$
2. $\{0\}$: $f^{-1}(\{0\})=\{2,3,\{2,3\}\} \subset \mathcal{A}$
3. $\{1\}$: $f^{-1}(\{1\})=\{1\} \in \mathcal{A}$
4. $\{0,1\}$: $f^{-1}(\{0,1\})=\{\{1,2\},\{1,3\}\{1,2,3\}\} \subset \mathcal{A}$

which satisfies the requirement, then we say the transform $f(\cdot)$ is a **measurable function**.

This function transforming $\mathcal{A}$ generated by $X$ into $\mathcal{B}$ generated by $Y$ is called **measurable** because the target space $\mathcal{B}$ can be constructed using measurable sets in $\mathcal{A}$, then $\mathcal{B}$ is measurable.

***Notice*** that a measurable function mapping one sample space into another only concerns properties of two $\sigma$-algebra regardless of the probability function defined on it.

The measurable function in this example is actually a **random variable**, with these knowledge we've learned so far, we can have a formal definition of it.

### Definition 2 Random Variable

A random variable, $X(\cdot)$ is a measurable function from the probability space $(S,\mathbb{B},P)$ to the measurable space $(\Omega, \Sigma, P')$, where $\Omega \subset \mathbb{R}$, $\Sigma$ is the $\sigma$-algebra generated by $\Omega$ such that for each basic outcome $s \in S$, there exits a corresponding unique real number  $X(s) \subset \Omega$.

Specifically, $X: S \rightarrow \Omega$.

### Definition 3 Induced Probability Function

We've mentioned that the measurability of a function only concerns the $\sigma$-algebras instead of the probability measure defined on them. Here we should continue by discussing the probability function.

Since the probability space $(\Omega, \Sigma, P')$ is constructed by $(S,\mathbb{B},P)$, the probability function $P'$ defined on the transformed probability space can be induced from original probability space.

Let's step back to our **example 1.1**, where we roll a trihedral dice. The sample space $S=\{1,2,3\}$.

The $\sigma$-algebra generated by $S$, $\mathbb{B}$ is
$$\mathbb{B}= \{\emptyset, \{1\}, \{2\}, \{3\}, \{1,2\}, \{1,3\}, \{2,3\}, \{1,2,3\}\}$$

On the measurable space $(S,\mathbb{B})$, define a probability function $P:\mathbb{B} \rightarrow [0,1]$, whose values are determined by this experiment's nature.

$$
P(\emptyset)=0\\
P(\{1\})=\frac{1}{3}\\
P(\{2\})=\frac{1}{3}\\
P(\{3\})=\frac{1}{3}\\
P(\{1,2\})=\frac{2}{3}\\
P(\{1,3\})=\frac{2}{3}\\
P(\{2,3\})=\frac{2}{3}\\
P(\{1,2,3\})=1
$$

What we care is the number of heads showing up, then we define a random variable $X:S \rightarrow \Omega \subset \mathbb{R}$, where $\Omega=\{0,1\}$ whose basic outcomes are numbers of $1$ showing up.

This random variable transforms one sample space into another by the following rules we've mentioned before.

$$
X(\emptyset)=\emptyset \\
X(\{1\})=1 \\
X(\{2\})=0 \\
X(\{3\})=0 \\
X(\{1,2\})=\{0,1\}\\
X(\{1,3\})=\{0,1\} \\
X(\{2,3\})=0 \\
X(\{1,2,3\})=\{0,1\}
$$

And $\sigma$-algebra generated by $\Omega$, $\Sigma$, is
$$\Sigma=\{\emptyset, \{0\}, \{1\}, \{0,1\}\}$$

On the measurable space $(\Omega, \Sigma)$, the probability function $P_{X}:\Sigma \rightarrow [0,1]$ of the random variable $X$ is induced by the probability function $P$.

For any event $A \subset \Sigma$, $P_X (A)=P(s \in S:X(s) \in A)$

There are four elements in $\Sigma$, we consider one by one,
1. $\emptyset$: $P_X (\emptyset)=0$
2. $\{0\}$: $X(\{2\})=X(\{3\})=0$, then $P_X (\{0\})=P(\{2\})+P(\{3\})=\frac{2}{3}$
3. $\{1\}$: $X(\{1\})=1$, then $P_X (\{1\})=\frac{1}{3}$
4. $\{0,1\}$: $X(\{2\})=X(\{3\})=0, X(\{1\})=1$, then $P_X (\{0,1\})=P(\{1\})+P(\{2\})+P(\{3\})=1$

The induced probability function $P_X (\cdot)$ now assigns probability to all elements in $\Sigma$.

Chapter 2 Random Variables/Chapter 2 Random Variables Part I.ipynb


```python
# 그래프, 수학 기능 추가
# Add graph and math features
import pylab as py
import numpy as np

```

# 1차 적분
First Order Numerical Integration

[](https://www.youtube.com/watch?v=1p0NHR5w0Lc)

다시 면적이 1인 반원을 생각해 보자.
Again, let's think about the half circle with area of 1.

$$
\begin{align}
    \pi r^2 &= 2 \\
    r^2 &= \frac{2}{\pi} \\
    r &= \sqrt{\frac{2}{\pi}}
\end{align}
$$

```python
r = py.sqrt(2.0 / py.pi)

```

```python
def half_circle(x):
    return py.sqrt(np.abs(r**2 - x**2))

```

$$
y = \sqrt{r^2 - x^2}
$$

```python
x_array = py.linspace(-r, r)
y_plus = half_circle(x_array)

py.fill_between(x_array, y_plus)

py.axis('equal')
py.grid(True)

```

이번에는 사다리꼴 규칙을 이용해서 구해 보기로 하자.

This time, let's use the trapezoid rule to find its area.

## 사다리꼴 규칙
Trapezoid Rule

다음과 같은 사다리꼴을 생각해 보자.
Let's think about a trapezoid as follows.

```python
x_array = (0, 1)
y_array = (1, 2)

py.fill_between(x_array, y_array)
py.axis('equal')
py.axis('off')

py.text(-0.25, 0.5, '$y_i$')
py.text(1.15, 1, '$y_{i+1}$')
py.text(0.5, -0.3, '$\Delta x$')

```

사다리꼴의 면적은 다음과 같다.

Area of a trapezoid is as follows.

$$
a_i=\frac{1}{2} \left( y_i + y_{i+1} \right) \Delta x
$$

## 1차 적분
First order numerical integration

마찬가지로 일정 간격으로 $x$ 좌표를 나누어 보자.

Same as before, let's divide $x$ coordinates in a constant interval.

```python
d = r * 2.0

n = 10

x_interval = d / n

x_array = py.linspace(-r, r)
y_plus = half_circle(x_array)

x_array_bar = py.arange(-r, r+x_interval*0.1, x_interval)
y_array_bar = half_circle(x_array_bar)
x_interval = x_array_bar[1]-x_array_bar[0]

py.fill_between(x_array, y_plus)

xp, yp = x_array_bar[0], y_array_bar[0]
for x, y in zip(x_array_bar.tolist()[1:], y_array_bar.tolist()[1:]):
    py.fill_between((xp, x), (yp, y), alpha=0.5, color=py.random((1, 3)))
    xp, yp = x, y

py.axis('equal')
py.grid(True)

```

사다리꼴의 면적을 하나씩 구해서 더해보자.
Let's accumulate the area of trapezoids.

$$
    Area = \sum_{k=0}^{n-1} F_k
$$

$$
    F_k = \frac{\Delta x}{2}\left[f(x_k)+f(x_{k+1})\right]
$$

```python
def num_int_1(f, xi, xe, delta_x):
    x_array = py.arange(xi, xe+delta_x*0.1, delta_x)

    integration_result = 0.0
    xp = x_array[0]
    yp = f(xp)

    for x_i in x_array[1:]:

        y_i = f(x_i)
        area_i = 0.5 * (yp + y_i) * (x_i - xp)
        xp, yp = x_i, y_i
        integration_result += area_i

    return integration_result

```

```python
n = 10
result = num_int_1(half_circle, -r, r, 2*r/n)
print('result =', result)

```

예상한 값 1에 더 비슷한 값을 얻기 위해 더 잘게 나누어 보자

To obtain the result closer to the expected value of 1, let's divide with a narrower interval.

```python
n = 100
result = num_int_1(half_circle, -r, r, 2*r/n)
print('result =', result)

```

도전 과제 1 : 다른 조건이 같을 때 0차 적분과 사다리꼴 적분의 오차를 비교해 보시오. 필요하면 해당 파이썬 함수를 복사하시오.
Try this 1 : Compare the errors of the zeroth and first order integrations of the half circle example above using the same conditions. Duplicate the python function if necessary.

도전 과제 2 : 길이 $L=3[m]$ 인 외팔보가 분포 하중 $\omega=50sin\left(\frac{1}{2L}\pi x\right)[N/m]$을 받고 있을 때 전단력과 굽힘모멘트를 구하시오.
Try this 2 : Calculate shear force and bending moment of a cantilever with length $L=3m$ under distributed load $\omega=50sin\left(\frac{1}{2L}\pi x\right)[N/m]$.

(ref : C 4.4, Pytel, Kiusalaas & Sharma, Mechanics of Materials, 2nd Ed, SI, Cengage Learning, 2011.)

## Final Bell
마지막 종

```python
# stackoverfow.com/a/24634221
import os
os.system("printf '\a'");

```

```python

```