Skip to content

Commit

Permalink
Merge pull request #14 from spectraphilic/figure-cache
Browse files Browse the repository at this point in the history
Introduce a cache for figures that removes the need of the explicit FIG param
  • Loading branch information
FrancescAlted committed Oct 6, 2016
2 parents c3961c3 + a16f7e4 commit 72fca39
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 223 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ python:
- 2.7
- 3.5

before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start

script:
- py.test reflexible -v --cov reflexible --cov-report term-missing
# reflexible is far from being PEP8 compatible yet, but in the future maybe wise to use the line below...
Expand Down
2 changes: 2 additions & 0 deletions reflexible/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@ def print_versions():
"uio_examples/HelloWorld_V9.02/outputs"),
}


# Import the public functions here
from .tests.all import test
from . import conv2netcdf4
from .scripts.create_ncfile import create_ncfile
from .data_structures import (Header, Command, Release,
ReleasePoint, Ageclass)
from .utils import Structure, CacheDict

from .base_read import read_trajectories
14 changes: 8 additions & 6 deletions reflexible/data_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ def __init__(self, path=None, nested=False, absolute_path=True):
self.nested = nested
self.absolute_path = absolute_path

# check for nested or not, assumes only two nc files in
# check for nested or not, assumes only two nc files in
# output directory
if nested:
ncfile = [d for d in files if 'nest' in d][0]
Expand Down Expand Up @@ -513,10 +513,12 @@ def __getitem__(self, item):
d = FD.grid_dates[pointspec]
c = FD[(nspec, d)]
c.slabs = get_slabs(self.Heightnn, c.data_cube)
c.total_column = np.squeeze(np.sum(c.data_cube, axis=2))
c.foot_print = c.data_cube[:,:,0]

return c


# TODO: Following John, the get_slabs function should be deprecated
def get_slabs(Heightnn, grid):
"""Preps grid for plotting.
Expand Down Expand Up @@ -659,7 +661,7 @@ def min(self):


class Command(object):
""" General COMMAND input for Flexpart
""" General COMMAND input for Flexpart
#TODO: use properties ??
"""
Expand Down Expand Up @@ -707,10 +709,10 @@ def __init__(self, **options):
'MDOMAINFILL': [0,
'''If MDOMAINFILL is set to 1, the first box specified in file RELEASES is used as the domain where domain-filling trajectory calculations are to be done. Particles are initialized uniformly distributed (according to the air mass distribution) in that domain at the beginning of the simulation, and are created at the boundaries throughout the simulation perio'''],
'IND_SOURCE': [1, '''IND_SOURCE switches between different units for concentrations at the source NOTE that in backward simulations the release of computational particles takes place at the "receptor" and the sampling of particles at the "source".
1=mass units (for bwd-runs = concentration)
1=mass units (for bwd-runs = concentration)
2=mass mixing ratio units'''],
'IND_RECEPTOR': [1, '''IND_RECEPTOR switches between different units for concentrations at the receptor
1=mas s units (concentrations)
1=mas s units (concentrations)
2=mas s mixing ratio units'''],
'MQUASILAG': [0,
'''MQUASILAG indicates whether particles shall be numbered consecutively (1) or with their release location number (0). The first option allows tracking of individual particles using the partposit output files'''],
Expand Down Expand Up @@ -809,7 +811,7 @@ def to_file(self, cfile):


class Ageclass(object):
""" General COMMAND input for Flexpart
""" General COMMAND input for Flexpart
"""

Expand Down
109 changes: 2 additions & 107 deletions reflexible/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import matplotlib.pyplot as plt
from mpl_toolkits import basemap

from reflexible import Structure

# mpl.use("Agg")
# mp.interactive(False)
# mpl.use('Agg')
Expand All @@ -28,20 +30,6 @@
__version__ = "0.03"


class Structure(dict):

def __getattr__(self, attr):
return self[attr]

def __setattr__(self, attr, value):
self[attr] = value

def set_with_dict(self, D):
""" set attributes with a dict """
for k in D.keys():
self.__setattr__(k, D[k])


def map_regions(map_region='default', map_par=None, fig_par=None):
"""Given a `map_region`, return the associated parameters in mapping DB.
Expand Down Expand Up @@ -243,99 +231,6 @@ def draw_grid(m, xdiv=10., ydiv=5., location=[1, 0, 0, 1],
return m_p, m_m


def get_FIGURE(fig=None, ax=None, m=None, map_region=None,
getm=True, map_par=None, fig_par=None,
image=None):
"""
This is a core function, used throughout this module. It is called
by various functions. The idea is that I create a :class:`Structure` that
contains the figure, ax, and m instance. I also add a field for "indices".
I'm not sure this all makes the most sense, but it is what I came up with
in order to be able to reuse figures. This saves a huge amount of time, as
creating then basemap instance can be time consuming.
This whole concept overall really needs to be reviewed!
.. note::
Generally you won't use this function direction.
USAGE::
> FIG = get_FIGURE()
or
> FIG = get_FIGURE(map_region='polarcat')
Returns
This will return the "FIG" object, which has attributes: `fig`, `ax`,
`m`, and `indices`. The indices are used for deleting lines, texts,
collections, etc. if and when we are reusing the figure instance. The
indices basically give us a reference to the *empty* map, so we can
delete lines without losing meridians or parallels for example.
============ ======================================
keys description
============ ======================================
fig a pyplot.fig instance, use
plt.figure(FIG.fig.number) to make the
fig active (for example to use
plt.savefig('filename.png')
m The basemap instance so you can do:
x,y = FIG.m(lon,lat)
ax The axes
indices with index for texts, images, lines,
and collections
============ ======================================
"""
FIGURE = Structure()

if getm:
if m is None:
if image:
fig, m = get_base_image(image, map_region=map_region,
map_par=map_par,
fig_par=fig_par,
)
else:

fig, m = get_base1(map_region=map_region,
map_par=map_par,
fig_par=fig_par,
fig=fig,
)

FIGURE.fig = fig
FIGURE.m = m
FIGURE.ax = fig.gca()
elif m is None:
FIGURE.m = None
else:
FIGURE.m = m

if fig is None:
FIGURE.fig = plt.figure()
fig = FIGURE.fig
else:
FIGURE.fig = fig

if ax is None:
FIGURE.ax = fig.gca()
ax = FIGURE.ax
else:
FIGURE.ax = ax

FIGURE.indices = Structure()
FIGURE.indices.texts = len(FIGURE.ax.texts)
FIGURE.indices.images = len(FIGURE.ax.images)
FIGURE.indices.collections = len(FIGURE.ax.collections)
FIGURE.indices.lines = len(FIGURE.ax.lines)

print("Using figure: %s" % FIGURE.fig.number)
return FIGURE


def get_base1(map_region=1,
figname=None,
fig=None,
Expand Down

0 comments on commit 72fca39

Please sign in to comment.