Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions esmvalcore/cmor/tables/custom/CMOR_intppgt.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
SOURCE: CMIP5
!============
variable_entry: intppgt
!============
modeling_realm: ocnBgchem
!----------------------------------
! Variable attributes:
!----------------------------------
standard_name:
units: Pg yr-1
cell_methods: time: mean area: where sea
cell_measures: area: areacello
long_name: Global Total Primary Organic Carbon Production by All Types of Phytoplankton
comment: Global Total of Vertically integrated total primary (organic carbon) production by phytoplankton.
!----------------------------------
! Additional variable information:
!----------------------------------
dimensions: time
type: real
!----------------------------------
!
89 changes: 89 additions & 0 deletions esmvalcore/preprocessor/_derive/intppgt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Derivation of variable `intppgt`."""
import iris
import numpy as np

from ._baseclass import DerivedVariableBase


def calculate_total_flux(intpp_cube, cube_area):
"""
Calculate the area of unmasked cube cells.

Requires a cube with two spacial dimensions. (no depth coordinate).

Parameters
----------
cube: iris.cube.Cube
Data Cube
cube_area: iris.cube.Cube
Cell area Cube

Returns
-------
numpy.array:
An numpy array containing the total flux of CO2.
"""
data = []
times = intpp_cube.coord('time')

intpp_cube.data = np.ma.array(intpp_cube.data)
for time_itr in np.arange(len(times.points)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to use iris.analysis.SUM to aggregate over the required dimensions?


total_flux = intpp_cube[time_itr].data * cube_area.data

total_flux = np.ma.masked_where(intpp_cube[time_itr].data.mask,
total_flux)
data.append(total_flux.sum())

######
# Create a small dummy output array
data = np.array(data)
return data


class DerivedVariable(DerivedVariableBase):
"""Derivation of variable `intppgt`."""

# Required variables
required = [
{
'short_name': 'intpp',
# 'mip': 'Omon',
'fx_files': [
'areacello',
],
},
]

@staticmethod
def calculate(cubes):
"""Compute longwave cloud radiative effect."""
intpp_cube = cubes.extract_strict(
iris.Constraint(name='net_primary_mole_productivity_of_carbon_by_'
'phytoplankton'))

try:
cube_area = cubes.extract_strict(iris.Constraint(name='cell_area'))
except iris.exceptions.ConstraintMismatchError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this happens, cube_area will be undefined and the code below will fail, so I think it is not a good idea to let this pass

pass

total_flux = calculate_total_flux(intpp_cube, cube_area)

# Dummy result cube
result = intpp_cube.collapsed(
['latitude', 'longitude'],
iris.analysis.MEAN,
)

# TODO: Load seconds per year from model calendar.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do your to do?

days_per_year = 365.
seconds_per_day = 24*60*60.
g_per_mol = 12.011
total_flux = total_flux * g_per_mol * days_per_year * seconds_per_day

# Convert to Pg yr-1
result.data = total_flux * 1E-15

# These units are set in the CMOR table.
result.units = 'Pg yr-1'
return result
11 changes: 9 additions & 2 deletions esmvalcore/preprocessor/_multimodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,22 @@ def _put_in_cube(template_cube, cube_data, statistic, t_axis):
t_axis,
standard_name='time',
units=template_cube.coord('time').units)
lats = template_cube.coord('latitude')
lons = template_cube.coord('longitude')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes seem unrelated to deriving the variable? Would it make sense to put this in a separate pull request?

coord_names = [c.long_name for c in template_cube.coords()]
if 'latitude' in coord_names:
lats = template_cube.coord('latitude')
if 'longitude' in coord_names:
lats = template_cube.coord('longitude')

# no plevs
if len(template_cube.shape) == 3:
lons = template_cube.coord('longitude')
cspec = [(times, 0), (lats, 1), (lons, 2)]
# plevs
elif len(template_cube.shape) == 4:
plev = template_cube.coord('air_pressure')
lats = template_cube.coord('latitude')
lons = template_cube.coord('longitude')
cspec = [(times, 0), (plev, 1), (lats, 2), (lons, 3)]
elif len(template_cube.shape) == 1:
cspec = [
Expand Down