├── pycovjson
├── __init__.py
├── cli
│ ├── __init__.py
│ ├── viewer.py
│ └── convert.py
├── test
│ ├── __init__.py
│ ├── testdata
│ │ └── jsont_template.json
│ └── test.py
├── writeNetCDF.py
├── write_netcdf.py
├── convert.py
├── model.py
├── write.py
└── read_netcdf.py
├── MANIFEST.in
├── readthedocs.yml
├── docs
├── source
│ ├── univ_reading.png
│ ├── core
│ │ ├── setup.rst
│ │ ├── read_netcdf.rst
│ │ ├── write.rst
│ │ ├── convert.rst
│ │ └── model.rst
│ ├── cli
│ │ └── cli.rst
│ ├── introduction.rst
│ ├── installation.md
│ ├── index.rst
│ ├── quickstart.rst
│ └── conf.py
├── environment.yml
├── Makefile
└── make.bat
├── meta.yml
├── docs.md
├── .travis.yml
├── LICENSE
├── .gitignore
├── setup.py
└── README.md
/pycovjson/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pycovjson/cli/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pycovjson/test/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include README.md
3 |
--------------------------------------------------------------------------------
/readthedocs.yml:
--------------------------------------------------------------------------------
1 | conda:
2 | file: docs/environment.yml
3 |
4 | python:
5 | version: 3.5
6 | setup_py_install: true
--------------------------------------------------------------------------------
/docs/source/univ_reading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Reading-eScience-Centre/pycovjson/HEAD/docs/source/univ_reading.png
--------------------------------------------------------------------------------
/docs/environment.yml:
--------------------------------------------------------------------------------
1 | name: pycovjson-docs
2 |
3 | dependencies:
4 | - python=3.5
5 | - numpy=1.11
6 | - pandas=0.18.1
7 | - netCDF4
8 |
9 |
--------------------------------------------------------------------------------
/docs/source/core/setup.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | pycovjson setup.py
4 | *******************
5 |
6 | .. autoclass:: setup
7 | :members:
8 |
--------------------------------------------------------------------------------
/docs/source/core/read_netcdf.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | read_netcdf.py
4 | **************
5 | .. module:: pycovjson.read_netcdf
6 |
7 | .. autoclass:: NetCDFReader
8 | :members:
9 |
--------------------------------------------------------------------------------
/docs/source/core/write.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | write.py
4 | ********
5 | .. module:: pycovjson.write
6 |
7 | .. autoclass:: Writer
8 | :members:
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs/source/core/convert.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | convert.py
4 | **********
5 |
6 | =======
7 | Convert
8 | =======
9 | Convert.py is a library API to group the read and write classes together into a single file,
10 | this allows it to be called in a much more simple way
11 |
12 | .. module:: pycovjson.convert
13 |
14 | .. autoclass:: main
15 | :members:
16 |
--------------------------------------------------------------------------------
/docs/source/core/model.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | model.py
4 | ********
5 | .. module:: pycovjson.model
6 |
7 | Coverage
8 | ========
9 | .. autoclass:: Coverage
10 | :members: to_dict
11 |
12 | Domain
13 | ======
14 | .. autoclass:: Domain
15 | :members:
16 |
17 | Range
18 | =====
19 | .. autoclass:: Range
20 | :members: __init__ , to_dict, populate
21 |
22 | TileSet
23 | =======
24 | .. autoclass:: TileSet
25 | :members:
--------------------------------------------------------------------------------
/meta.yml:
--------------------------------------------------------------------------------
1 | package:
2 | name: pycovjson
3 | version: "0.3.4"
4 |
5 | source:
6 |
7 | git_url: https://github.com/Reading-eScience-Centre/pycovjson.git
8 |
9 | requirements:
10 | build:
11 | - python
12 | - setuptools
13 | - hdf5
14 | run:
15 | - python
16 |
17 | test:
18 | imports:
19 | - pycovjson
20 |
21 | about:
22 | home: https://github.com/Reading-eScience-Centre/pycovjson
23 | license: BSD
24 | license_file: LICENSE
--------------------------------------------------------------------------------
/docs/source/cli/cli.rst:
--------------------------------------------------------------------------------
1 | Command Line Interface
2 | **********************
3 | .. module:: pycovjson.cli.convert
4 |
5 | Convert Module
6 | ==============
7 | .. autoclass:: main
8 |
9 | :members:
10 |
11 | Usage
12 | ^^^^^
13 | :: pycovjson-convert(*path to netcdf file*, *name of output file*, *[list of vars as strings]* [-t] *tiled* [-s] *tile_shape as list*
14 |
15 |
16 | Viewer Module
17 | =============
18 | .. module:: pycovjson.cli.viewer
19 |
20 | .. autoclass:: main
21 | :members:
22 |
23 | Usage
24 | ^^^^^
25 |
26 | :: pycovjson-viewer (netcdf file)
--------------------------------------------------------------------------------
/docs/source/introduction.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | Introduction to pycovjson
4 | **************************
5 |
6 | ============
7 | Introduction
8 | ============
9 | pycovjson is a python utility library for creating `CoverageJSON `_ files from common scientific data formats (e.g NetCDF).
10 |
11 | ==========================
12 | What does pycovjson offer?
13 | ==========================
14 | The library provides a packaged Python API for the generation of CoverageJSON which is compliant with the `CoverageJSON Format Specification `_.
--------------------------------------------------------------------------------
/pycovjson/writeNetCDF.py:
--------------------------------------------------------------------------------
1 | from netCDF4 import Dataset
2 |
3 | from numpy import arange, dtype
4 |
5 |
6 | nx = 4
7 | ny = 4
8 | nz = 4
9 | ncfile = Dataset('test_xy.nc', 'w')
10 | # create the output data.
11 | data_out = arange(nx * ny)
12 | print(data_out)
13 | data_out.shape = (nx, ny) # reshape to 3d array
14 | # create the x and y dimensions.
15 | ncfile.createDimension('x', nx)
16 | ncfile.createDimension('y', ny)
17 | # ncfile.createDimension('z', nz)
18 | data = ncfile.createVariable('data', dtype('float32').char, ('x', 'y'))
19 |
20 | data[:] = data_out
21 | # close the file.
22 | print(ncfile.variables)
23 | print("Wrote file!")
24 |
--------------------------------------------------------------------------------
/docs/source/installation.md:
--------------------------------------------------------------------------------
1 |
2 | Installation:
3 | =============
4 | If you already have netCDF4 and hdf5 installed, the installation process is simple.
5 | Open up a command line and type the following:
6 | ```
7 | $ pip install pycovjson
8 | ```
9 | If not, you will need to download [conda](http://anaconda.org) for your operating system,
10 | details of how to do this can be found [here.](http://conda.pydata.org/docs/install/quick.html)
11 | After you have installed conda, type the following in the command line:
12 | ```
13 | $ conda install netcdf4
14 | $ pip install pycovjson
15 | ```
16 | Conda will install all of the required binaries for your OS.
17 |
--------------------------------------------------------------------------------
/pycovjson/write_netcdf.py:
--------------------------------------------------------------------------------
1 | from netCDF4 import Dataset
2 |
3 | from numpy import arange, dtype
4 |
5 |
6 | nx = 4
7 | ny = 4
8 | nz = 1
9 | ncfile = Dataset('test_xyz.nc', 'w')
10 | # create the output data.
11 | data_out = arange(nx * ny* nz)
12 | print(data_out)
13 | data_out.shape = (nx, ny, nz) # reshape to 3d array
14 | # create the x and y dimensions.
15 | ncfile.createDimension('x', nx)
16 | ncfile.createDimension('y', ny)
17 | ncfile.createDimension('z', nz)
18 | data = ncfile.createVariable('data', dtype('float32').char, ('x', 'y','z'))
19 |
20 | data[:] = data_out
21 | # close the file.
22 | print(ncfile.variables)
23 | print("Wrote file!")
24 |
--------------------------------------------------------------------------------
/pycovjson/test/testdata/jsont_template.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "Coverage",
3 | "domain": {
4 | "type": "Domain",
5 | "domainType": "Grid",
6 | "axes": {
7 | "x": {
8 | "values": [
9 |
10 | ]
11 | },
12 | "y": {
13 | "values": [
14 | ]
15 | }
16 | },
17 | "referencing": [{
18 | "components": [],
19 | "system": {
20 | "type": "",
21 | "id": ""
22 | }
23 | }
24 | ]
25 |
26 |
27 | },
28 | "parameters": {
29 |
30 | },
31 | "ranges": {
32 |
33 |
34 | }}
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. pycovjson documentation master file, created by
2 | sphinx-quickstart on Mon Aug 29 13:17:47 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to pycovjson's documentation!
7 | =====================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 4
13 |
14 | introduction
15 | quickstart
16 | installation
17 | cli/cli
18 | core/model
19 | core/convert
20 | core/read_netcdf
21 | core/setup
22 | core/write
23 |
24 | Indices and tables
25 | ==================
26 |
27 | * :ref:`genindex`
28 | * :ref:`modindex`
29 | * :ref:`search`
30 |
--------------------------------------------------------------------------------
/pycovjson/convert.py:
--------------------------------------------------------------------------------
1 | from pycovjson.read_netcdf import NetCDFReader as Reader
2 | from pycovjson.write import Writer
3 | from pycovjson.model import TileSet
4 |
5 | def main(input_file, output_file, variable, tiled=False, tile_shape=[], axis=''):
6 |
7 |
8 | if output_file == None:
9 | output_file = 'coverage.json'
10 |
11 |
12 | def tile_by_axis(variable, axis):
13 | """
14 |
15 | :param variable:
16 | :param axis:
17 | :return: tile_shape
18 | """
19 | # Get shape of variable
20 | shape = Reader.get_shape(variable)
21 | # Set axis to slice by to 1
22 | TileSet.create_tileset()
23 | # Generate new tile shape
24 | return tile_shape
25 | if tiled:
26 | tile_shape = tile_by_axis(variable, axis)
27 |
28 | Writer(output_file, input_file, [variable], tiled=tiled, tile_shape=tile_shape).write()
29 |
30 |
31 | if __name__ == '__main__':
32 | main()
33 |
34 |
35 |
--------------------------------------------------------------------------------
/pycovjson/cli/viewer.py:
--------------------------------------------------------------------------------
1 | """
2 | Pycovjson - Command line viewer
3 | Author: rileywilliams
4 | Version: 0.1.0
5 | TODO - Add support for other formats and more customisation
6 | """
7 | import argparse
8 |
9 |
10 | from pycovjson.read_netcdf import NetCDFReader as Reader
11 |
12 |
13 | def main():
14 | parser = argparse.ArgumentParser(description='View Scientific Data files.')
15 | parser.add_argument('inputfile', action ='store',
16 | help='Name of input file')
17 |
18 | parser.add_argument('-v', '--variables,', dest='variables',
19 | help='Display variables', action='store_true')
20 |
21 | args = parser.parse_args()
22 | inputfile = args.inputfile
23 | variables = args.variables
24 | reader = Reader(inputfile)
25 | ds = reader.get_xarray()
26 | # TODO
27 | # if variables:
28 | # reader.get_vars_with_long_name(inputfile)
29 |
30 | print(ds)
31 |
32 |
33 | if __name__ == '__main__':
34 | main()
35 |
--------------------------------------------------------------------------------
/docs.md:
--------------------------------------------------------------------------------
1 | #Initial Documentation - Full Documentation in progress
2 |
3 | Implementations
4 | ---------------
5 |
6 | * **model.py**
7 | * model.py contains all of the classes for each component of the coverage object, as well as helper methods to generate dictionaries and create tilesets.
8 |
9 | * **write.py**
10 | * write.py contains all of the code for constructing and writing to CoverageJSON
11 |
12 | * **readNetCDFOOP.py**
13 | * readNetCDFOOP.py contains all of the code for reading the NetCDF data, as well as code for reformatting data.
14 |
15 | * **convert.py**
16 | * convert.py is the command line interface for pycovjson, used to convert files to CoverageJSON
17 |
18 | * **viewer.py**
19 | * viewer.py is the command line viewer, used to view netCDF files.
20 |
21 | In Progress
22 | -----------
23 | * API Docs
24 |
25 | Incomplete
26 | ----------
27 |
28 | * Tiling should be working in the current version of **pycovjson**,
29 | however it has not been tested properly.
30 | * Test classes still need to be implemented
31 | * convert.py could be extended to allow for slicing by dimension instead of specifying a shape manually
32 | * Support for more data formats
33 |
34 |
--------------------------------------------------------------------------------
/pycovjson/test/test.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from pycovjson.model import TileSet, Coverage, Reference
4 | import os
5 | import numpy as np
6 | import pycovjson
7 | from pycovjson.read_netcdf import NetCDFReader
8 |
9 |
10 | def test():
11 | dir_name = os.path.dirname(__file__)
12 |
13 | json_template = os.path.join(dir_name, '..', 'data', 'jsont_template.json')
14 |
15 | testfile = 'test_xy.nc'
16 | dataset_path = os.path.join(dir_name, 'testdata', testfile)
17 |
18 | dataset = np.arange(60)
19 | dataset.reshape(10, 6)
20 |
21 | urlTemplate = 'localhost:8080/'
22 |
23 | tile_shape = [2, 1]
24 | # tileSet = TileSet(tile_shape, urlTemplate, dataset)
25 |
26 | try:
27 | variable_names = NetCDFReader(testfile).get_var_names()
28 | except OSError:
29 | print('Error: ', OSError)
30 | # for tile in tileSet.get_tiles(tile_shape, 'data'):
31 | # print(tile, '\n')
32 | # variable_names = pycovjson.readNetCDFOOP.get_var_names(netcdf_dataset)
33 |
34 | assert len(variable_names) > 0
35 |
36 |
37 | def read():
38 | dir_name = os.path.dirname(__file__)
39 | testfile = 'test_xy.nc'
40 | dataset_path = os.path.join(dir_name, 'testdata', testfile)
41 |
42 | # 1.
43 | reader = NetCDFReader(dataset_path)
44 | coverage = reader.read()
45 |
46 | def test_convert():
47 | import pycovjson.convert
48 | pycovjson.convert('foam_2011-01-01.nc','coverage.covjson', ['SALTY'])
49 |
50 | test()
51 | test_convert()
52 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - '3.5'
4 | before_install:
5 | - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh
6 | - chmod +x miniconda.sh
7 | - "./miniconda.sh -b"
8 | - export PATH=/home/travis/miniconda2/bin:$PATH
9 | - hash -r
10 | - conda update --yes conda
11 | - conda info -a
12 | - conda create --yes -q -n test-environment python=$TRAVIS_PYTHON_VERSION xarray netCDF4
13 | - source activate test-environment
14 | install:
15 | - python setup.py install
16 | - wget https://www.dropbox.com/s/mmgxijdvhemdzoy/foam_2011-01-01.nc
17 | script:
18 | - pycovjson-convert -i foam_2011-01-01.nc -v SALTY
19 | - test -s coverage.covjson
20 |
21 |
22 | deploy:
23 | provider: pypi
24 | user: rileywilliams
25 | password:
26 | secure: eZeb5zRnUPVY1vezZwAZcmz0lPlGIccgHIM6xotC1VC8TneBl5nrpZaSnNgNULsbh8ZjdK6ucB4nQozJ7jPMeehJsTkZSvMAniAbK6c9vIcQ9nnflfTg3PMtpaIUGGc2HxjiNKQKJG3Cru+NfEbAEnVnJ0uswDD+EwBT5hIpUjsiMYL3j/9zilgd4SNShzaqwCI5lLjfpa4fWwMkTGgt0iMPzCJnC4j1vL6YBhuCmexcb160jWzh2C7GsIu3DXZRm7VIyfCNCk8nO87otiYE5CqQgS8KR5GiZQVKiOt7NFJ+6kQghwtuxIRZ307vCieiQY5iiWpgLvJVOqPFXNo4tVjdU27ymcTOyadmNnRamHRoEOFKWSXb4OGrbHvxUW/QdYE3TS/kscs1TZJQumrfuV1cBL9OhN4zjptXwmlswQkSny/aQ5pykYBB6K9jELJYG+N0XJMnteaFdQh5/URgm+qk6y07eVCxGuQzllDOHoauF7kJ2z2U/rBs/lxXXXKBFUVl7Zf73n8Tyg5Dwr85GF16oq1LEYDiqRVM3rgqE5a8+xWDOGDX2w/OtcNE75JNsn9ig7eVZiF7kphMSxhykjtL/OyP3fXCOWKDTrjEEzKXlgNjD7Ftz/+McuQslRhinMSCgoSVaNoKGvbSkxl3/LwS6Mz/b4vND1tW1SKsvvM=
27 | on:
28 | tags: true
29 | repo: Reading-eScience-Centre/pycovjson
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 The University of Reading.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of pycovjson nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 |
56 | # Flask stuff:
57 | instance/
58 | .webassets-cache
59 |
60 | # Scrapy stuff:
61 | .scrapy
62 |
63 | # Sphinx documentation
64 | docs/_build/
65 |
66 | # PyBuilder
67 | target/
68 |
69 | # IPython Notebook
70 | .ipynb_checkpoints
71 |
72 | # pyenv
73 | .python-version
74 |
75 | # celery beat schedule file
76 | celerybeat-schedule
77 |
78 | # dotenv
79 | .env
80 |
81 | # virtualenv
82 | venv/
83 | ENV/
84 |
85 | # Spyder project settings
86 | .spyderproject
87 |
88 | # Rope project settings
89 | .ropeproject
90 | /json_output_test.json
91 |
92 |
93 | # NetCDF Files
94 | /pycovjson/util.py
95 | /writeToJSON.py
96 | /.swp
97 | /pycovjson/data/
98 | /pycovjson/writeJSON.py
99 | /pycovjson/test/testdata/jsont_template.json
100 |
101 | # Eclipse Pydev
102 | .project
103 | .pydevproject
104 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | from setuptools import find_packages, setup
3 |
4 | # Package data
5 | # ------------
6 | _author = 'rileywilliams'
7 | _authorEmail = 'resc@reading.ac.uk'
8 | _classifiers = [
9 | 'Environment :: Console',
10 | 'Intended Audience :: Developers',
11 | 'Intended Audience :: Information Technology',
12 | 'Intended Audience :: Science/Research',
13 | 'Topic :: Scientific/Engineering',
14 | 'Development Status :: 4 - Beta',
15 | 'License :: OSI Approved :: BSD License',
16 | 'Operating System :: OS Independent',
17 | 'Programming Language :: Python :: 3',
18 | 'Topic :: Internet :: WWW/HTTP',
19 | 'Topic :: Software Development :: Libraries :: Python Modules',
20 | ]
21 | _description = 'Create CovJSON files from common scientific data formats'
22 | _downloadURL = 'http://pypi.python.org/pypi/pycovjson/'
23 | _requirements = ["xarray","numpy", "pandas", "pymongo"]
24 | _keywords = ['dataset', 'coverage', 'covjson']
25 | _license = 'Copyright :: University of Reading'
26 | _long_description = 'A python utility library for creating CovJSON files from common scientific data formats'
27 | _name = 'pycovjson'
28 | _namespaces = []
29 | _testSuite = 'pycovjson.test'
30 | _url = 'https://github.com/Reading-eScience-Centre/pycovjson'
31 | _version = '0.3.9'
32 | _zipSafe = True
33 | _entry_points = {'console_scripts' : ['pycovjson-convert = pycovjson.cli.convert:main', 'pycovjson-viewer = pycovjson.cli.viewer:main']}
34 |
35 | # Setup Metadata
36 | # --------------
37 |
38 |
39 | def _read(*rnames):
40 | return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
41 |
42 | _header = '*' * len(_name) + '\n' + _name + '\n' + '*' * len(_name)
43 |
44 | setup(
45 | author=_author,
46 | author_email=_authorEmail,
47 | classifiers=_classifiers,
48 | description=_description,
49 | download_url=_downloadURL,
50 | include_package_data=True,
51 | install_requires=_requirements,
52 | keywords=_keywords,
53 | license=_license,
54 | long_description=_long_description,
55 | name=_name,
56 | namespace_packages=_namespaces,
57 | packages=find_packages(),
58 | test_suite=_testSuite,
59 | url=_url,
60 | version=_version,
61 | zip_safe=_zipSafe,
62 | entry_points=_entry_points,
63 | )
64 |
--------------------------------------------------------------------------------
/docs/source/quickstart.rst:
--------------------------------------------------------------------------------
1 | .. # encoding: utf-8
2 |
3 | Quickstart
4 | **********
5 |
6 | Purpose
7 | -------
8 | The following document explains how to quickly get up and running with pycovjson. It explains how to execute the key commands and explains (at a high level) what those commands are doing e.g. what input and output we can expect. More detail on expressive use of the various API's including function level API documentation can be found in subsequent pages of this documentation guide.
9 |
10 | .. _data:
11 |
12 | CoverageJSON Generation
13 | -----------------------
14 |
15 | pycovjson-viewer
16 | ^^^^^^^^^^^^^^^^
17 | To quickly view the structure of a NetCDF file, pycovjson-viewer can be used. Usage is simple: ::
18 |
19 | $ pycovjson-viewer (netcdf file)
20 |
21 | Dimensions: (depth: 20, lat: 171, lon: 360)
22 | Coordinates:
23 | * depth (depth) float32 5.0 15.0 25.0 35.0 48.0 67.0 96.0 139.0 204.0 ...
24 | * lat (lat) float32 -81.0 -80.0 -79.0 -78.0 -77.0 -76.0 -75.0 -74.0 ...
25 | * lon (lon) float32 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 ...
26 | Data variables:
27 | ICEC (lat, lon) float64 nan nan nan nan nan nan nan nan nan nan nan ...
28 | ICETK (lat, lon) float64 nan nan nan nan nan nan nan nan nan nan nan ...
29 | M (lat, lon) float64 nan nan nan nan nan nan nan nan nan nan nan ...
30 | SALTY (depth, lat, lon) float64 nan nan nan nan nan nan nan nan nan ...
31 | TMP (depth, lat, lon) float64 nan nan nan nan nan nan nan nan nan ...
32 | U (lat, lon) float64 nan nan nan nan nan nan nan nan nan nan nan ...
33 | V (lat, lon) float64 nan nan nan nan nan nan nan nan nan nan nan ...
34 | Attributes:
35 | title: MET OFFICE FOAM GLOBAL 1 DEG DATA
36 | field_date: 2011-01-01 00:00:00
37 |
38 |
39 | pycovjson-convert
40 | ^^^^^^^^^^^^^^^^^
41 | This is very simple... ::
42 |
43 | #
44 |
45 | # pycovjson-convert -i foam.nc -o coverage.covjson -v [SALTY]
46 |
47 | More on using pycovjson functions later...
48 |
49 |
50 | .. _concl:
51 |
52 | Conclusion
53 | ----------
54 | That concludes the quick start. Hopefully this has been helpful in providing an overview of the main pycovjson features. If you have any issues with this document then please register them at the `issue tracker `_. Please use `labels `_ to classify your issue.
55 |
--------------------------------------------------------------------------------
/pycovjson/cli/convert.py:
--------------------------------------------------------------------------------
1 | """
2 | Pycovjson - Command line interface
3 | Author: rileywilliams
4 | Version: 0.1.0
5 | """
6 | import argparse
7 |
8 | from pycovjson.write import Writer
9 | from pycovjson.read_netcdf import NetCDFReader as Reader
10 |
11 |
12 | def main():
13 | """
14 | Command line interface for pycovjson - Converts Scientific Data Formats into CovJSON and saves to disk.
15 |
16 | :argument -i: Input file path.
17 | :argument -o: Output file name.
18 | :argument -t: Use Tiling.
19 | :argument -v: Which variable to populate coverage with.
20 | :argument -s: [tile shape]: Tile shape.
21 | :argument -n: Use interactive mode.
22 | :argument -u: MongoDB URL
23 |
24 |
25 | """
26 | parser = argparse.ArgumentParser(
27 | description='Convert Scientific Data Formats into CovJSON.')
28 | parser.add_argument('-i', '--input', dest='inputfile',
29 | help='Name of input file', required=True)
30 | parser.add_argument('-o', '--output', dest='outputfile',
31 | help='Name and location of output file', default='coverage.covjson')
32 | parser.add_argument('-t', '--tiled', action='store_true', help='Apply tiling')
33 | parser.add_argument('-s', '--shape', nargs='+',
34 | help='Tile shape, list', type=int)
35 | parser.add_argument('-v', dest='variable',
36 | help='Variable to populate coverage with', required=True)
37 | parser.add_argument('-n', '--interactive', action='store_true', help='Enter interactive mode')
38 | parser.add_argument('-u', '--endpoint_url', dest='endpoint_url', nargs=1,
39 | help='MongoDB endpoint for CovJSON persistence')
40 | args = parser.parse_args()
41 | inputfile = args.inputfile
42 | outputfile = args.outputfile
43 | variable = args.variable
44 | tiled = args.tiled
45 | tile_shape = args.shape
46 | interactive = args.interactive
47 | endpoint_url = args.endpoint_url
48 |
49 | if interactive:
50 | axis = input('Which Axis?', Reader.get_axis(variable))
51 |
52 | if tiled and len(tile_shape) == 0:
53 | reader = Reader(inputfile)
54 | shape_list = reader.get_shape(variable)
55 | dims = reader.get_dimensions(variable)
56 | print(list(zip(dims, shape_list)))
57 | tile_shape = input(
58 | 'Enter the shape tile shape as a list of comma separated integers')
59 | tile_shape = tile_shape.split(',')
60 | tile_shape = list(map(int, tile_shape))
61 | print(tile_shape)
62 | if outputfile == None:
63 | outputfile = outputfile.default
64 |
65 | Writer(outputfile, inputfile, [variable],
66 | tiled=tiled, tile_shape=tile_shape, endpoint_url=endpoint_url).write()
67 |
68 | if __name__ == '__main__':
69 | main()
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pycovjson
2 | [](https://travis-ci.org/Reading-eScience-Centre/pycovjson)
3 | [](https://pypi.python.org/pypi/pycovjson)
4 | [](https://www.python.org/downloads/)
5 | [](http://pycovjson.readthedocs.io/en/latest/)
6 | [](https://anaconda.org/conda-forge/pycovjson)
7 | [](https://anaconda.org/conda-forge/pycovjson)
8 |
9 | Create **[CovJSON](https://covjson.org/)** files from common scientific data formats(e.g NetCDF)
10 |
11 | ## Installation:
12 |
13 | ### From Pypi
14 | If you already have netCDF4 and hdf5 installed,
15 | open up a command line and type the following:
16 | ```
17 | $ pip install pycovjson
18 | ```
19 | If not, you will need to download conda for your operating system,
20 | details of how to do this can be found [here.](http://conda.pydata.org/docs/install/quick.html)
21 | After you have installed conda, type the following in the command line:
22 | ```
23 | $ conda install netcdf4
24 | $ pip install pycovjson
25 | ```
26 |
27 | ### Using Conda
28 | Installing `pycovjson` from the `conda-forge` channel can be achieved by adding `conda-forge` to your channels with:
29 |
30 | ```
31 | conda config --add channels conda-forge
32 | ```
33 |
34 | Once the `conda-forge` channel has been enabled, `pycovjson` can be installed with:
35 |
36 | ```
37 | conda install pycovjson
38 | ```
39 |
40 | It is possible to list all of the versions of `pycovjson` available on your platform with:
41 |
42 | ```
43 | conda search pycovjson --channel conda-forge
44 | ```
45 |
46 | ## Usage:
47 | Command line interface:
48 |
49 | **[pycovjson-convert](https://github.com/Reading-eScience-Centre/pycovjson/blob/master/pycovjson/cli/convert.py)** accepts 6 parameters, and can be run as followed
50 | ```
51 | $ pycovjson-convert -i *name of input file(NetCDF)* -o *name of output file* -v *variable* [-t] [-s] *tile shape as list*
52 | ```
53 |
54 | On running the script, a CoverageJSON file will be generated.
55 |
56 | **[pycovjson-viewer](https://github.com/Reading-eScience-Centre/pycovjson/blob/master/pycovjson/cli/viewer.py)** accepts up to 2 parameters:
57 | ```
58 | $ pycovjson-viewer [*-v display variable information only*] on running will display information about the input file.
59 | ```
60 | To be use in conjunction with **pycovjson-convert**.
61 |
62 | ## Examples
63 |
64 | ```
65 | $ pycovjson-viewer *name of netCDF file*
66 |
67 | $ pycovjson-convert -i melodies_landcover.nc -o coverage.json -v land_cover
68 | ```
69 |
70 | ## API Usage
71 |
72 | First see [](http://pycovjson.readthedocs.io/en/latest/)
73 |
74 | ### Convert.py
75 | Once pycovjson is installed, type the following at the top of your code:
76 | ```
77 | import pycovjson.convert
78 | ```
79 | Once imported you can then use the convert function within your projects.
80 |
81 | ### Examples
82 |
83 | ```
84 | pycovjson.convert('polcoms.nc', 'coverage.covjson', [sst])
85 | ```
86 | This will generate a file called coverage.covjson in the directory where the script is located.
87 |
88 | ## Supported formats
89 | Currently only NetCDF is supported. In order to support other formats only the reader function would need to be changed, as the pycovjson loads data into python data structures before writing to CovJSON.
90 |
91 | ## Project Roadmap
92 |
93 | The project roadmap can be found [here.](https://github.com/Reading-eScience-Centre/pycovjson/projects/1)
94 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " applehelp to make an Apple Help Book"
34 | @echo " devhelp to make HTML files and a Devhelp project"
35 | @echo " epub to make an epub"
36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
37 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
39 | @echo " text to make text files"
40 | @echo " man to make manual pages"
41 | @echo " texinfo to make Texinfo files"
42 | @echo " info to make Texinfo files and run them through makeinfo"
43 | @echo " gettext to make PO message catalogs"
44 | @echo " changes to make an overview of all changed/added/deprecated items"
45 | @echo " xml to make Docutils-native XML files"
46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
47 | @echo " linkcheck to check all external links for integrity"
48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
49 | @echo " coverage to run coverage check of the documentation (if enabled)"
50 |
51 | clean:
52 | rm -rf $(BUILDDIR)/*
53 |
54 | html:
55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
56 | @echo
57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
58 |
59 | dirhtml:
60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
61 | @echo
62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
63 |
64 | singlehtml:
65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
66 | @echo
67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
68 |
69 | pickle:
70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
71 | @echo
72 | @echo "Build finished; now you can process the pickle files."
73 |
74 | json:
75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
76 | @echo
77 | @echo "Build finished; now you can process the JSON files."
78 |
79 | htmlhelp:
80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
81 | @echo
82 | @echo "Build finished; now you can run HTML Help Workshop with the" \
83 | ".hhp project file in $(BUILDDIR)/htmlhelp."
84 |
85 | qthelp:
86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
87 | @echo
88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pycovjson.qhcp"
91 | @echo "To view the help file:"
92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pycovjson.qhc"
93 |
94 | applehelp:
95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
96 | @echo
97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
98 | @echo "N.B. You won't be able to view it unless you put it in" \
99 | "~/Library/Documentation/Help or install it in your application" \
100 | "bundle."
101 |
102 | devhelp:
103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
104 | @echo
105 | @echo "Build finished."
106 | @echo "To view the help file:"
107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pycovjson"
108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pycovjson"
109 | @echo "# devhelp"
110 |
111 | epub:
112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
113 | @echo
114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
115 |
116 | latex:
117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
118 | @echo
119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
121 | "(use \`make latexpdf' here to do that automatically)."
122 |
123 | latexpdf:
124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
125 | @echo "Running LaTeX files through pdflatex..."
126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
128 |
129 | latexpdfja:
130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
131 | @echo "Running LaTeX files through platex and dvipdfmx..."
132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
134 |
135 | text:
136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
137 | @echo
138 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
139 |
140 | man:
141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
142 | @echo
143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
144 |
145 | texinfo:
146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
147 | @echo
148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
149 | @echo "Run \`make' in that directory to run these through makeinfo" \
150 | "(use \`make info' here to do that automatically)."
151 |
152 | info:
153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
154 | @echo "Running Texinfo files through makeinfo..."
155 | make -C $(BUILDDIR)/texinfo info
156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
157 |
158 | gettext:
159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
160 | @echo
161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
162 |
163 | changes:
164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
165 | @echo
166 | @echo "The overview file is in $(BUILDDIR)/changes."
167 |
168 | linkcheck:
169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
170 | @echo
171 | @echo "Link check complete; look for any errors in the above output " \
172 | "or in $(BUILDDIR)/linkcheck/output.txt."
173 |
174 | doctest:
175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
176 | @echo "Testing of doctests in the sources finished, look at the " \
177 | "results in $(BUILDDIR)/doctest/output.txt."
178 |
179 | coverage:
180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
181 | @echo "Testing of coverage in the sources finished, look at the " \
182 | "results in $(BUILDDIR)/coverage/python.txt."
183 |
184 | xml:
185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
186 | @echo
187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
188 |
189 | pseudoxml:
190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
191 | @echo
192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
193 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
10 | set I18NSPHINXOPTS=%SPHINXOPTS% source
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. xml to make Docutils-native XML files
37 | echo. pseudoxml to make pseudoxml-XML files for display purposes
38 | echo. linkcheck to check all external links for integrity
39 | echo. doctest to run all doctests embedded in the documentation if enabled
40 | echo. coverage to run coverage check of the documentation if enabled
41 | goto end
42 | )
43 |
44 | if "%1" == "clean" (
45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
46 | del /q /s %BUILDDIR%\*
47 | goto end
48 | )
49 |
50 |
51 | REM Check if sphinx-build is available and fallback to Python version if any
52 | %SPHINXBUILD% 2> nul
53 | if errorlevel 9009 goto sphinx_python
54 | goto sphinx_ok
55 |
56 | :sphinx_python
57 |
58 | set SPHINXBUILD=python -m sphinx.__init__
59 | %SPHINXBUILD% 2> nul
60 | if errorlevel 9009 (
61 | echo.
62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
63 | echo.installed, then set the SPHINXBUILD environment variable to point
64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
65 | echo.may add the Sphinx directory to PATH.
66 | echo.
67 | echo.If you don't have Sphinx installed, grab it from
68 | echo.http://sphinx-doc.org/
69 | exit /b 1
70 | )
71 |
72 | :sphinx_ok
73 |
74 |
75 | if "%1" == "html" (
76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
80 | goto end
81 | )
82 |
83 | if "%1" == "dirhtml" (
84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
88 | goto end
89 | )
90 |
91 | if "%1" == "singlehtml" (
92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
93 | if errorlevel 1 exit /b 1
94 | echo.
95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
96 | goto end
97 | )
98 |
99 | if "%1" == "pickle" (
100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
101 | if errorlevel 1 exit /b 1
102 | echo.
103 | echo.Build finished; now you can process the pickle files.
104 | goto end
105 | )
106 |
107 | if "%1" == "json" (
108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
109 | if errorlevel 1 exit /b 1
110 | echo.
111 | echo.Build finished; now you can process the JSON files.
112 | goto end
113 | )
114 |
115 | if "%1" == "htmlhelp" (
116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
117 | if errorlevel 1 exit /b 1
118 | echo.
119 | echo.Build finished; now you can run HTML Help Workshop with the ^
120 | .hhp project file in %BUILDDIR%/htmlhelp.
121 | goto end
122 | )
123 |
124 | if "%1" == "qthelp" (
125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
129 | .qhcp project file in %BUILDDIR%/qthelp, like this:
130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pycovjson.qhcp
131 | echo.To view the help file:
132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pycovjson.ghc
133 | goto end
134 | )
135 |
136 | if "%1" == "devhelp" (
137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished.
141 | goto end
142 | )
143 |
144 | if "%1" == "epub" (
145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
149 | goto end
150 | )
151 |
152 | if "%1" == "latex" (
153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
157 | goto end
158 | )
159 |
160 | if "%1" == "latexpdf" (
161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
162 | cd %BUILDDIR%/latex
163 | make all-pdf
164 | cd %~dp0
165 | echo.
166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
167 | goto end
168 | )
169 |
170 | if "%1" == "latexpdfja" (
171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
172 | cd %BUILDDIR%/latex
173 | make all-pdf-ja
174 | cd %~dp0
175 | echo.
176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
177 | goto end
178 | )
179 |
180 | if "%1" == "text" (
181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
182 | if errorlevel 1 exit /b 1
183 | echo.
184 | echo.Build finished. The text files are in %BUILDDIR%/text.
185 | goto end
186 | )
187 |
188 | if "%1" == "man" (
189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
190 | if errorlevel 1 exit /b 1
191 | echo.
192 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
193 | goto end
194 | )
195 |
196 | if "%1" == "texinfo" (
197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
198 | if errorlevel 1 exit /b 1
199 | echo.
200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
201 | goto end
202 | )
203 |
204 | if "%1" == "gettext" (
205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
206 | if errorlevel 1 exit /b 1
207 | echo.
208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
209 | goto end
210 | )
211 |
212 | if "%1" == "changes" (
213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
214 | if errorlevel 1 exit /b 1
215 | echo.
216 | echo.The overview file is in %BUILDDIR%/changes.
217 | goto end
218 | )
219 |
220 | if "%1" == "linkcheck" (
221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
222 | if errorlevel 1 exit /b 1
223 | echo.
224 | echo.Link check complete; look for any errors in the above output ^
225 | or in %BUILDDIR%/linkcheck/output.txt.
226 | goto end
227 | )
228 |
229 | if "%1" == "doctest" (
230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
231 | if errorlevel 1 exit /b 1
232 | echo.
233 | echo.Testing of doctests in the sources finished, look at the ^
234 | results in %BUILDDIR%/doctest/output.txt.
235 | goto end
236 | )
237 |
238 | if "%1" == "coverage" (
239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
240 | if errorlevel 1 exit /b 1
241 | echo.
242 | echo.Testing of coverage in the sources finished, look at the ^
243 | results in %BUILDDIR%/coverage/python.txt.
244 | goto end
245 | )
246 |
247 | if "%1" == "xml" (
248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
249 | if errorlevel 1 exit /b 1
250 | echo.
251 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
252 | goto end
253 | )
254 |
255 | if "%1" == "pseudoxml" (
256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
257 | if errorlevel 1 exit /b 1
258 | echo.
259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
260 | goto end
261 | )
262 |
263 | :end
264 |
--------------------------------------------------------------------------------
/pycovjson/model.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import math
3 | from collections import OrderedDict
4 |
5 |
6 | class Coverage(object):
7 |
8 | def __init__(self, domain, ranges, params, reference):
9 | self.domain = domain.to_dict()
10 | self.range = ranges.to_dict()
11 | self.parameter = params.to_dict()
12 | self.reference = reference.to_list()
13 | self.type = 'Coverage'
14 |
15 | def to_dict(self):
16 | cov_dict = OrderedDict()
17 | cov_dict['type'] = self.type
18 | cov_dict['domain'] = self.domain
19 | cov_dict['domain']['referencing'] = self.reference
20 | cov_dict['parameters'] = self.parameter
21 | cov_dict['ranges'] = self.range
22 |
23 | return cov_dict
24 |
25 |
26 | class Domain(object):
27 |
28 | def __init__(self, domain_type, x_values=[], y_values=[], z_values=[], t_values=[]):
29 | self.domain_type = domain_type
30 |
31 | self.x_values = x_values
32 | self.y_values = y_values
33 | self.z_values = z_values
34 | self.t_values = t_values
35 | self.referencing = []
36 |
37 | def __str__(self):
38 | return 'Domain Type: ' + self.domain_type + '\nAxes:' + str(self.axes)
39 |
40 | def to_dict(self):
41 | domain_dict = OrderedDict()
42 | domain_dict['domainType'] = self.domain_type
43 | domain_dict['axes'] = {}
44 |
45 | domain_dict['axes']['x'] = {'values': self.x_values}
46 |
47 | domain_dict['axes']['y'] = {'values': self.y_values}
48 |
49 | domain_dict['axes']['t'] = {'values': self.t_values}
50 | domain_dict['axes']['z'] = {'values': self.z_values}
51 | if len(self.z_values) == 0:
52 | # domain_dict['axes']['z']= {'values' : self.z_values}
53 | domain_dict['axes'].pop('z', None)
54 | if len(self.t_values) == 0:
55 | # domain_dict['axes']['t']= {'values' : self.t_values}
56 | domain_dict['axes'].pop('t', None)
57 |
58 | domain_dict['referencing'] = []
59 | return domain_dict
60 |
61 |
62 | class Range(object):
63 |
64 | def __init__(self, range_type, data_type={}, axes=[], shape=[], values=[], variable_name='', tile_sets=[]):
65 | self.range_type = range_type
66 | self.data_type = data_type
67 | self.axis_names = axes
68 | self.shape = shape
69 | self.values = values
70 | self.variable_name = variable_name
71 | self.tile_sets = tile_sets
72 |
73 | def to_dict(self):
74 | range_dict = OrderedDict()
75 | range_dict[self.variable_name] = {}
76 |
77 | range_dict[self.variable_name]['type'] = self.range_type
78 | range_dict[self.variable_name]['dataType'] = self.data_type
79 | range_dict[self.variable_name]['axisNames'] = self.axis_names
80 | range_dict[self.variable_name]['shape'] = self.shape
81 | if self.range_type == 'TiledNdArray':
82 | range_dict[self.variable_name]['tileSets'] = self.tile_sets
83 |
84 | else:
85 |
86 | range_dict[self.variable_name]['values'] = self.values
87 |
88 | return range_dict
89 |
90 | def populate(self, data_type={}, axes=[], shape=[], values=[], variable_name=''):
91 | """
92 | Function to populate Range object with values
93 |
94 | """
95 | self.data_type = data_type
96 | self.axis_names = axes
97 | self.shape = shape
98 | self.values = values
99 | self.variable_name = variable_name
100 |
101 |
102 | class Parameter(object):
103 |
104 | def __init__(self, variable_name='', description='', unit='', symbol='', symbol_type='', observed_property='', op_id=None, label_langtag='en'):
105 | self.variable_name = variable_name
106 | self.param_type = 'Parameter'
107 | self.description = description
108 | self.unit = unit
109 | self.label_langtag = label_langtag
110 | self.symbol = symbol
111 | self.symbol_type = symbol_type
112 | self.observed_property = observed_property
113 | self.op_id = op_id
114 |
115 | def to_dict(self):
116 | param_dict = OrderedDict()
117 | param_dict[self.variable_name] = {}
118 | param_dict[self.variable_name]['type'] = self.param_type
119 | param_dict[self.variable_name]['description'] = self.description
120 | param_dict[self.variable_name]['unit'] = {}
121 | param_dict[self.variable_name]['unit'][
122 | 'label'] = {self.label_langtag: self.unit}
123 | param_dict[self.variable_name]['symbol'] = {}
124 | param_dict[self.variable_name]['symbol']['value'] = self.symbol
125 | param_dict[self.variable_name]['symbol']['type'] = self.symbol_type
126 | param_dict[self.variable_name]['observedProperty'] = {}
127 | param_dict[self.variable_name]['observedProperty']['id'] = self.op_id
128 | param_dict[self.variable_name]['observedProperty'][
129 | 'label'] = {self.label_langtag: self.observed_property}
130 | return param_dict
131 |
132 |
133 | class Reference(object):
134 |
135 | def __init__(self, obj_list):
136 | self.coordinates = []
137 | self.obj_list = obj_list
138 |
139 | def get_temporal(self, *args):
140 | return self.TemporalReferenceSystem(*args)
141 |
142 | def get_spatial2d(self, *args):
143 | return self.SpatialReferenceSystem2d(*args)
144 |
145 | def get_spatial3d(self, *args):
146 | return self.SpatialRefrenceSystem3d(*args)
147 |
148 | def to_list(self):
149 | item_list = []
150 |
151 | for elem in self.obj_list:
152 | item_list.append(elem.to_dict())
153 | #print('Item list:', item_list)
154 | return item_list
155 |
156 |
157 | class TemporalReferenceSystem(Reference):
158 |
159 | def __init__(self, cal=None):
160 | self.type = 'TemporalRS'
161 | self.coordinates = ['t']
162 |
163 | if (cal == None):
164 | self.cal = "Gregorian"
165 | else:
166 | self.cal = cal
167 |
168 | def to_dict(self):
169 | ref_dict = OrderedDict()
170 | ref_dict['coordinates'] = self.coordinates
171 | ref_dict['system'] = {}
172 | ref_dict['system']['type'] = self.type
173 | ref_dict['system']['calendar'] = self.cal
174 | return ref_dict
175 |
176 |
177 | class SpatialReferenceSystem2d(Reference):
178 |
179 | def __init__(self):
180 | self.id = "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
181 | self.type = 'GeographicCRS'
182 | Reference.coordinates = ['x', 'y']
183 |
184 | def set_type(self, new_type):
185 | """
186 | :type new_type: str
187 | """
188 | self.type = new_type
189 |
190 | def to_dict(self):
191 | ref_dict = OrderedDict()
192 | ref_dict['coordinates'] = self.coordinates
193 | ref_dict['system'] = {}
194 | ref_dict['system']['type'] = self.type
195 | ref_dict['system']['id'] = self.id
196 | return ref_dict
197 |
198 |
199 | class SpatialReferenceSystem3d(Reference):
200 |
201 | def __init__(self):
202 | self.id = "http://www.opengis.net/def/crs/EPSG/0/4979"
203 | self.type = 'GeographicCRS'
204 | Reference.coordinates = ['x', 'y', 'z']
205 |
206 | def set_type(self, new_type):
207 | """
208 | :type new_type: str
209 | """
210 | self.type = new_type
211 |
212 | def to_dict(self):
213 | ref_dict = OrderedDict()
214 | ref_dict['coordinates'] = self.coordinates
215 | ref_dict['system'] = {}
216 | ref_dict['system']['type'] = self.type
217 | ref_dict['system']['id'] = self.id
218 | return ref_dict
219 |
220 |
221 | class TileSet(object):
222 |
223 | def __init__(self, tile_shape, url_template):
224 | self.tile_shape = tile_shape # List containing shape
225 | self.url_template = url_template
226 |
227 | def create_tileset(self):
228 | tileset = []
229 | tile_dict = {}
230 | tile_dict['tileShape'] = self.tileShape
231 | tile_dict['urlTemplate'] = self.urlTemplate
232 | tileset.append(tile_dict)
233 | return tileset
234 |
235 | def get_url_template(self, val):
236 | self.val = val
237 |
238 | import re
239 | subject = self.url_template
240 | subject = re.sub(r"({).(})", self.val, subject, 0, re.IGNORECASE)
241 |
242 | def generate_url_template(self, axis_names):
243 | axis_names = axis_names
244 | if len(axis_names) == 1:
245 | url_template = '{' + axis_names[0] + '}.covjson'
246 | elif len(axis_names) == 2:
247 | url_template = '{' + axis_names[0] + \
248 | '}-{' + axis_names[1] + '}.covjson'
249 | elif len(axis_names) == 3:
250 | url_template = '{' + axis_names[0] + '}-{' + \
251 | axis_names[1] + '}-{' + axis_names[2] + '}.covjson'
252 |
253 | return url_template
254 |
255 | def get_tiles(self, tile_shape: object, array) -> object:
256 | """
257 | Function which yields a generator which can be leveraged to return tile arrays from an input array
258 | :param tile_shape:
259 |
260 | :param variable:
261 | :return:
262 | """
263 | array = array
264 | self.shape = array.shape
265 | # print(self.shape)
266 |
267 | def step(b, dim, tile_indices):
268 | if dim == len(array.shape):
269 | yield (b, tile_indices)
270 | return
271 |
272 | tile_count = math.ceil(self.shape[dim] / tile_shape[dim])
273 |
274 | for i in range(tile_count):
275 | c = b[tile_shape[dim] * i:tile_shape[dim] * (i + 1)]
276 | c = np.rollaxis(c, 1)
277 | tile_indices[dim] = i
278 | yield from step(c, dim + 1, tile_indices)
279 |
280 | yield from step(array, 0, [0] * len(self.shape))
281 |
282 | def get_array_shape(self):
283 | print(self.shape)
284 | return self.shape
285 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # pycovjson documentation build configuration file, created by
4 | # sphinx-quickstart on Mon Aug 29 13:17:47 2016.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 | import shlex
18 | import sphinx_rtd_theme
19 | from recommonmark.parser import CommonMarkParser
20 |
21 | source_parsers = {
22 | '.md': CommonMarkParser,
23 | }
24 | autoclass_content = 'both'
25 |
26 | # If extensions (or modules to document with autodoc) are in another directory,
27 | # add these directories to sys.path here. If the directory is relative to the
28 | # documentation root, use os.path.abspath to make it absolute, like shown here.
29 | #sys.path.insert(0, os.path.abspath('.'))
30 | sys.path.insert(0, os.path.abspath('../../'))
31 |
32 |
33 | # -- General configuration ------------------------------------------------
34 |
35 | # If your documentation needs a minimal Sphinx version, state it here.
36 | #needs_sphinx = '1.0'
37 |
38 | # Add any Sphinx extension module names here, as strings. They can be
39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
40 | # ones.
41 | extensions = [
42 | 'sphinx.ext.autodoc',
43 | 'sphinx.ext.doctest',
44 | 'sphinx.ext.coverage',
45 | 'sphinx.ext.mathjax',
46 | 'sphinx.ext.viewcode',
47 | ]
48 |
49 | # Add any paths that contain templates here, relative to this directory.
50 | templates_path = ['_templates']
51 |
52 | # The suffix(es) of source filenames.
53 | # You can specify multiple suffix as a list of string:
54 | # source_suffix = ['.rst', '.md']
55 | source_suffix = ['.rst', '.md']
56 |
57 | # The encoding of source files.
58 | #source_encoding = 'utf-8-sig'
59 |
60 | # The master toctree document.
61 | master_doc = 'index'
62 |
63 | # General information about the project.
64 | project = u'pycovjson'
65 | copyright = u'2016, University of Reading eScience Centre'
66 | author = u'rileywilliams - University of Reading eScience Centre'
67 |
68 | # The version info for the project you're documenting, acts as replacement for
69 | # |version| and |release|, also used in various other places throughout the
70 | # built documents.
71 | #
72 | # The short X.Y version.
73 | version = '0.3.7'
74 | # The full version, including alpha/beta/rc tags.
75 | release = '0.3.7'
76 |
77 | # The language for content autogenerated by Sphinx. Refer to documentation
78 | # for a list of supported languages.
79 | #
80 | # This is also used if you do content translation via gettext catalogs.
81 | # Usually you set "language" from the command line for these cases.
82 | language = None
83 |
84 | # There are two options for replacing |today|: either, you set today to some
85 | # non-false value, then it is used:
86 | #today = ''
87 | # Else, today_fmt is used as the format for a strftime call.
88 | #today_fmt = '%B %d, %Y'
89 |
90 | # List of patterns, relative to source directory, that match files and
91 | # directories to ignore when looking for source files.
92 | exclude_patterns = []
93 |
94 | # The reST default role (used for this markup: `text`) to use for all
95 | # documents.
96 | #default_role = None
97 |
98 | # If true, '()' will be appended to :func: etc. cross-reference text.
99 | #add_function_parentheses = True
100 |
101 | # If true, the current module name will be prepended to all description
102 | # unit titles (such as .. function::).
103 | #add_module_names = True
104 |
105 | # If true, sectionauthor and moduleauthor directives will be shown in the
106 | # output. They are ignored by default.
107 | #show_authors = False
108 |
109 | # The name of the Pygments (syntax highlighting) style to use.
110 | pygments_style = 'sphinx'
111 |
112 | # A list of ignored prefixes for module index sorting.
113 | #modindex_common_prefix = []
114 |
115 | # If true, keep warnings as "system message" paragraphs in the built documents.
116 | #keep_warnings = False
117 |
118 | # If true, `todo` and `todoList` produce output, else they produce nothing.
119 | todo_include_todos = False
120 |
121 |
122 | # -- Options for HTML output ----------------------------------------------
123 |
124 | # The theme to use for HTML and HTML Help pages. See the documentation for
125 | # a list of builtin themes.
126 | html_theme = 'sphinx_rtd_theme'
127 |
128 | # Theme options are theme-specific and customize the look and feel of a theme
129 | # further. For a list of options available for each theme, see the
130 | # documentation.
131 | #html_theme_options = {}
132 |
133 | # Add any paths that contain custom themes here, relative to this directory.
134 | #html_theme_path = []
135 |
136 | # The name for this set of Sphinx documents. If None, it defaults to
137 | # " v documentation".
138 | #html_title = None
139 |
140 | # A shorter title for the navigation bar. Default is the same as html_title.
141 | #html_short_title = None
142 |
143 | # The name of an image file (relative to this directory) to place at the top
144 | # of the sidebar.
145 | html_logo = os.path.join('.', 'univ_reading.png')
146 |
147 | # The name of an image file (within the static path) to use as favicon of the
148 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
149 | # pixels large.
150 | #html_favicon = None
151 |
152 | # Add any paths that contain custom static files (such as style sheets) here,
153 | # relative to this directory. They are copied after the builtin static files,
154 | # so a file named "default.css" will overwrite the builtin "default.css".
155 | html_static_path = ['_static']
156 |
157 | # Add any extra paths that contain custom files (such as robots.txt or
158 | # .htaccess) here, relative to this directory. These files are copied
159 | # directly to the root of the documentation.
160 | #html_extra_path = []
161 |
162 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
163 | # using the given strftime format.
164 | #html_last_updated_fmt = '%b %d, %Y'
165 |
166 | # If true, SmartyPants will be used to convert quotes and dashes to
167 | # typographically correct entities.
168 | #html_use_smartypants = True
169 |
170 | # Custom sidebar templates, maps document names to template names.
171 | #html_sidebars = {}
172 |
173 | # Additional templates that should be rendered to pages, maps page names to
174 | # template names.
175 | #html_additional_pages = {}
176 |
177 | # If false, no module index is generated.
178 | #html_domain_indices = True
179 |
180 | # If false, no index is generated.
181 | #html_use_index = True
182 |
183 | # If true, the index is split into individual pages for each letter.
184 | #html_split_index = False
185 |
186 | # If true, links to the reST sources are added to the pages.
187 | #html_show_sourcelink = True
188 |
189 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
190 | #html_show_sphinx = True
191 |
192 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
193 | #html_show_copyright = True
194 |
195 | # If true, an OpenSearch description file will be output, and all pages will
196 | # contain a tag referring to it. The value of this option must be the
197 | # base URL from which the finished HTML is served.
198 | #html_use_opensearch = ''
199 |
200 | # This is the file name suffix for HTML files (e.g. ".xhtml").
201 | #html_file_suffix = None
202 |
203 | # Language to be used for generating the HTML full-text search index.
204 | # Sphinx supports the following languages:
205 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
206 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
207 | #html_search_language = 'en'
208 |
209 | # A dictionary with options for the search language support, empty by default.
210 | # Now only 'ja' uses this config value
211 | #html_search_options = {'type': 'default'}
212 |
213 | # The name of a javascript file (relative to the configuration directory) that
214 | # implements a search results scorer. If empty, the default will be used.
215 | #html_search_scorer = 'scorer.js'
216 |
217 | # Output file base name for HTML help builder.
218 | htmlhelp_basename = 'pycovjsondoc'
219 |
220 | # -- Options for LaTeX output ---------------------------------------------
221 |
222 | latex_elements = {
223 | # The paper size ('letterpaper' or 'a4paper').
224 | #'papersize': 'letterpaper',
225 |
226 | # The font size ('10pt', '11pt' or '12pt').
227 | #'pointsize': '10pt',
228 |
229 | # Additional stuff for the LaTeX preamble.
230 | #'preamble': '',
231 |
232 | # Latex figure (float) alignment
233 | #'figure_align': 'htbp',
234 | }
235 |
236 | # Grouping the document tree into LaTeX files. List of tuples
237 | # (source start file, target name, title,
238 | # author, documentclass [howto, manual, or own class]).
239 | latex_documents = [
240 | (master_doc, 'pycovjson.tex', u'pycovjson Documentation',
241 | u'University of Reading eScience Centre', 'manual'),
242 | ]
243 |
244 | # The name of an image file (relative to this directory) to place at the top of
245 | # the title page.
246 | #latex_logo = None
247 |
248 | # For "manual" documents, if this is true, then toplevel headings are parts,
249 | # not chapters.
250 | #latex_use_parts = False
251 |
252 | # If true, show page references after internal links.
253 | #latex_show_pagerefs = False
254 |
255 | # If true, show URL addresses after external links.
256 | #latex_show_urls = False
257 |
258 | # Documents to append as an appendix to all manuals.
259 | #latex_appendices = []
260 |
261 | # If false, no module index is generated.
262 | #latex_domain_indices = True
263 |
264 |
265 | # -- Options for manual page output ---------------------------------------
266 |
267 | # One entry per manual page. List of tuples
268 | # (source start file, name, description, authors, manual section).
269 | man_pages = [
270 | (master_doc, 'pycovjson', u'pycovjson Documentation',
271 | [author], 1)
272 | ]
273 |
274 | # If true, show URL addresses after external links.
275 | #man_show_urls = False
276 |
277 |
278 | # -- Options for Texinfo output -------------------------------------------
279 |
280 | # Grouping the document tree into Texinfo files. List of tuples
281 | # (source start file, target name, title, author,
282 | # dir menu entry, description, category)
283 | texinfo_documents = [
284 | (master_doc, 'pycovjson', u'pycovjson Documentation',
285 | author, 'pycovjson', 'One line description of project.',
286 | 'Miscellaneous'),
287 | ]
288 |
289 | # Documents to append as an appendix to all manuals.
290 | #texinfo_appendices = []
291 |
292 | # If false, no module index is generated.
293 | #texinfo_domain_indices = True
294 |
295 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
296 | #texinfo_show_urls = 'footnote'
297 |
298 | # If true, do not generate a @detailmenu in the "Top" node's menu.
299 | #texinfo_no_detailmenu = False
300 |
--------------------------------------------------------------------------------
/pycovjson/write.py:
--------------------------------------------------------------------------------
1 | from pycovjson.model import Coverage, Domain, Parameter, Range, Reference, SpatialReferenceSystem2d, SpatialReferenceSystem3d, TemporalReferenceSystem, TileSet
2 | from pycovjson.read_netcdf import NetCDFReader as Reader
3 | import json
4 | from pymongo import MongoClient
5 | from pymongo.son_manipulator import SONManipulator
6 | import time
7 | import uuid
8 |
9 |
10 | class Writer(object):
11 | """Writer class"""
12 |
13 | def __init__(self, output_name: object, dataset_path: object, vars_to_write: object, endpoint_url: object, tiled=False, tile_shape=[]) -> object:
14 | """
15 | Writer class constructor
16 |
17 | :parameter output_name: Name of output file
18 | :parameter dataset_path: Path to dataset
19 | :parameter vars_to_write: List of variables to write
20 | :parameter tiled: Boolean value (default False)
21 | :parameter tile_shape: List containing shape of tiles
22 | :parameter endpoint_url: MongoDB endpoint for CovJSON persistence
23 | """
24 | self.output_name = output_name
25 | self.tile_shape = tile_shape
26 | self.vars_to_write = vars_to_write
27 | self.url_template = 'localhost:8080/{t}.covjson'
28 | self.tiled = tiled
29 | if tiled:
30 | self.range_type = 'TiledNdArray'
31 | else:
32 | self.range_type = 'NdArray'
33 | self.dataset_path = dataset_path
34 | self.reader = Reader(dataset_path)
35 | self.axis_dict = self.reader.get_axes()
36 | self.axis_list = list(self.axis_dict.keys())
37 | self.ref_list = []
38 | if 't' in self.axis_list and 'z' in self.axis_list:
39 | self.ref_list.append(TemporalReferenceSystem())
40 | self.ref_list.append(SpatialReferenceSystem3d())
41 |
42 | if 't' in self.axis_list and 'z' not in self.axis_list:
43 | self.ref_list.append(TemporalReferenceSystem())
44 | self.ref_list.append(SpatialReferenceSystem2d())
45 | elif 't' not in self.axis_list and 'z' not in self.axis_list:
46 | self.ref_list.append(SpatialReferenceSystem2d())
47 | if endpoint_url is not None:
48 | self.endpoint_url = endpoint_url
49 | else:
50 | self.endpoint_url = None
51 |
52 | def write(self):
53 | """
54 | Writes Coverage object to local disk or MongoDB
55 | """
56 |
57 | coverage = self._construct_coverage()
58 | if self.endpoint_url is not None:
59 | if self.tiled:
60 | self.save_covjson_tiled(coverage, self.endpoint_url)
61 | else:
62 | self._save_covjson(coverage, self.endpoint_url)
63 | else:
64 | if self.tiled:
65 | self.save_covjson_tiled(coverage, self.output_name)
66 | else:
67 | self._save_covjson(coverage, self.output_name)
68 |
69 | def _construct_coverage(self):
70 | """
71 | Constructs Coverage object from constituent parts
72 | :return: coverage object
73 | """
74 | coverage = Coverage(self._construct_domain(), self._construct_range(
75 | ), self._construct_params(), self._construct_refs()).to_dict()
76 | return coverage
77 |
78 | def _construct_domain(self):
79 | """
80 | Constructs Domain object, populates with values
81 | :return: domain object
82 | """
83 |
84 | domain_type = 'Grid'
85 | x_values = self.reader.get_x().flatten().tolist()
86 | y_values = self.reader.get_y().flatten().tolist()
87 | t_values = []
88 | z_values = []
89 |
90 | if 't' in self.axis_list:
91 |
92 | t_values = self.reader.get_t()
93 |
94 | if 'z' in self.axis_list:
95 |
96 | z_values = self.reader.get_z().flatten().tolist()
97 |
98 | domain = Domain(domain_type, x_values, y_values, z_values, t_values)
99 |
100 | return domain
101 |
102 | def _construct_params(self):
103 | """
104 | Construct parameter object from constituent parts
105 | :return: Parameter object
106 | """
107 | for variable in self.vars_to_write:
108 | description = self.reader.get_std_name(variable)
109 | unit = self.reader.get_units(variable)
110 | symbol = self.reader.dataset[variable].units
111 | label = self.reader.dataset[variable].long_name
112 | params = Parameter(description=description, variable_name=variable,
113 | symbol=symbol, unit=unit, observed_property=label)
114 |
115 | return params
116 |
117 | def _construct_refs(self):
118 | """
119 | Construct reference object
120 | :return: refs
121 | """
122 | refs = Reference(self.ref_list)
123 |
124 | return refs
125 |
126 | def _construct_range(self):
127 | """
128 | Construct range object
129 | :return: range
130 | """
131 | for variable in self.vars_to_write:
132 | print("Constructing Range from variable:", variable)
133 |
134 | axis_names = list(map(str.lower, list(self.reader.get_axis(variable))))
135 |
136 | if self.tiled:
137 | tile_set_obj = TileSet(self.tile_shape, self.urlTemplate)
138 | variable_type = self.reader.get_type(variable)
139 | variable_shape = self.reader.get_shape(variable)
140 | print('Variable shape:', variable_shape)
141 |
142 | count = 0
143 | for tile in tile_set_obj.get_tiles(self.tile_shape, self.reader.dataset[variable].values):
144 | count += 1
145 | covrange = {'ranges': Range('NdArray', data_type=variable_type, axes=tile[
146 | 1], shape=variable_shape, values=tile[0].flatten().tolist()).to_dict()}
147 | self.save_covjson_range(covrange, str(count) + '.covjson')
148 | url_template = tile_set_obj.generate_url_template(base_url='localhost:8080',
149 | axis_names=['t'])
150 | tileset = TileSet(variable_shape, url_template).create_tileset(self.tile_shape)
151 |
152 | covrange = Range('TiledNdArray', data_type=variable_type, variable_name=variable,
153 | axes=axis_names, tile_sets=tileset, shape=variable_shape)
154 | return covrange
155 | else:
156 |
157 | shape = self.reader.get_shape(variable)
158 | values = self.reader.get_values(variable).flatten().tolist()
159 | data_type = self.reader.get_type(variable)
160 | axes = self.reader.get_axis(variable)
161 | covrange = Range(range_type='NdArray', data_type=data_type, values=values, shape=shape,
162 | variable_name=variable, axes=axis_names)
163 |
164 | return covrange
165 |
166 | # Adapted from
167 | # https://github.com/the-iea/ecem/blob/master/preprocess/ecem/util.py -
168 | # letmaik
169 | def _save_json(self, obj, path, **kw):
170 | """Save json object to disk"""
171 | with open(path, 'w') as fp:
172 | print("Converting....")
173 | start = time.clock()
174 | jsonstr = json.dumps(obj, fp, cls=CustomEncoder, **kw)
175 | fp.write(jsonstr)
176 | stop = time.clock()
177 | print("Completed in: '%s' seconds." % (stop - start))
178 |
179 | def _save_covjson(self, obj, resource):
180 | """
181 | Skip indentation of certain fields to make JSON more compact but still human readable
182 | :param obj: the CovJSON object to write
183 | :param resource: either a local file path or a MongoDB endpoint
184 |
185 | """
186 |
187 | for axis in obj['domain']['axes'].values():
188 | self.compact(axis, 'values')
189 | for ref in obj['domain']['referencing']:
190 | self.no_indent(ref, 'coordinates')
191 | for covrange in obj['ranges'].values():
192 | self.no_indent(covrange, 'axisNames', 'shape')
193 | self.compact(covrange, 'values')
194 | self.save_json(obj, resource, indent=2)
195 |
196 | def save_covjson_tiled(self, obj, resource):
197 | """
198 | Skip indentation of certain fields to make JSON more compact but still human readable
199 | :param obj: the CovJSON object to write
200 | :param resource: either a local file path or a MongoDB endpoint
201 | """
202 |
203 | for axis in obj['domain']['axes'].values():
204 | self.compact(axis, 'values')
205 | for ref in obj['domain']['referencing']:
206 | self.no_indent(ref, 'coordinates')
207 |
208 | self.save_json(obj, resource, indent=2)
209 |
210 | def save_json(self, obj, resource, **kw):
211 | print("Attempting to write CovJSON manifestation to '%s'" % (resource))
212 | start = time.clock()
213 | if resource[0].startswith('mongo'):
214 | mongo_client = MongoDBClient(obj, resource).write()
215 | else:
216 | with open(resource, 'w') as fp:
217 | jsonstr = json.dumps(obj, cls=CustomEncoder, **kw)
218 | fp.write(jsonstr)
219 | stop = time.clock()
220 | print("Completed in: '%s' seconds." % (stop - start))
221 |
222 | def save_covjson_range(self, obj, path):
223 | for covrange in obj['ranges'].values():
224 | self.no_indent(covrange, 'axisNames', 'shape')
225 | self.compact(covrange, 'values')
226 | self.save_json(obj, path, indent=2)
227 |
228 | def compact(self, obj, *names):
229 | for name in names:
230 | obj[name] = Custom(obj[name], separators=(',', ':'))
231 |
232 | def no_indent(self, obj, *names):
233 | for name in names:
234 | obj[name] = Custom(obj[name])
235 |
236 |
237 | # From http://stackoverflow.com/a/25935321
238 | class Custom(object):
239 |
240 | def __init__(self, value, **custom_args):
241 | self.value = value
242 | self.custom_args = custom_args
243 |
244 |
245 | class CustomEncoder(json.JSONEncoder):
246 | """Custom Json Encoder class - Allows Json to be saved using custom format (no_indent, compact)"""
247 |
248 | def __init__(self, *args, **kwargs):
249 | super(CustomEncoder, self).__init__(*args, **kwargs)
250 | self._replacement_map = {}
251 |
252 | def default(self, o):
253 | if isinstance(o, Custom):
254 | key = uuid.uuid4().hex
255 | self._replacement_map[key] = json.dumps(o.value, **o.custom_args)
256 | return "@@%s@@" % (key,)
257 | else:
258 | return super(CustomEncoder, self).default(o)
259 |
260 | def encode(self, o):
261 | result = super(CustomEncoder, self).encode(o)
262 | for k, v in self._replacement_map.items():
263 | result = result.replace('"@@%s@@"' % (k,), v)
264 | return result
265 |
266 |
267 | class MongoDBClient(object):
268 | '''
269 | A client for persisting CovJSON objects into MongoDB
270 | '''
271 | def __init__(self, covjson_obj, endpoint_url):
272 | self.covjson_obj = covjson_obj
273 | self.endpoint_url = endpoint_url
274 |
275 | def write(self):
276 | """
277 | Make the MongoDB connection, get/create a DB and/or a Collection
278 | and insert the CovJSON Document into MongoDB
279 | """
280 | client = MongoClient(self.endpoint_url)
281 | db = client.covjson_db
282 | covjson_collection = db.covjsons
283 | covjson_collection.insert_one(json.loads(json.dumps(self.covjson_obj, cls=CustomEncoder)))
284 |
285 |
--------------------------------------------------------------------------------
/pycovjson/read_netcdf.py:
--------------------------------------------------------------------------------
1 | from pycovjson.model import Domain, Range, Parameter, Reference
2 | import xarray as xr
3 | from collections import OrderedDict
4 | import pandas as pd
5 | import numpy as np
6 | import re
7 |
8 | datetime_error = "Failed to decode times encoded in the standard NetCDF datetime format into datetime objects. Attempting less strict opening logic. Reason: "
9 | success_msg = "Successfully opened dataset with less strict logic."
10 |
11 | class NetCDFReader(object):
12 |
13 | def __init__(self, dataset_path):
14 | self.dataset_path = dataset_path
15 | try:
16 | try:
17 | self.dataset = xr.open_dataset(self.dataset_path)
18 | except ValueError as ve:
19 | print(datetime_error, ve)
20 | self.dataset = xr.open_dataset(self.dataset_path, decode_times=False)
21 | print(success_msg)
22 | except OSError:
23 | print('File not found.')
24 | exit()
25 |
26 | def read(self, file_path):
27 | self.file_path = file_path
28 | try:
29 | self.dataset = xr.open_dataset(self.file_path)
30 | except ValueError as ve:
31 | print(datetime_error, ve)
32 | self.dataset = xr.open_dataset(self.file_path, decode_times=False)
33 | print(success_msg)
34 | self.var_names = self.get_var_names(self.dataset)
35 |
36 | def print(self):
37 | print(self.dataset)
38 | return self.dataset
39 |
40 | def get_xarray(self):
41 | try:
42 | self.dataset = xr.open_dataset(self.dataset_path)
43 | except ValueError as ve:
44 | print(datetime_error, ve)
45 | self.dataset = xr.open_dataset(self.dataset_path, decode_times=False)
46 | print(success_msg)
47 | return self.dataset
48 |
49 | def close(self):
50 | self.dataset.close()
51 |
52 | @staticmethod
53 | def _get_domain(self):
54 | domain = Domain('Grid')
55 | return domain
56 |
57 | @staticmethod
58 | def _get_ranges(self):
59 | _range = Range()
60 | return _range
61 |
62 | @staticmethod
63 | def _get_params(self):
64 | params = Parameter()
65 | return params
66 |
67 | @staticmethod
68 | def _get_reference(self):
69 | reference = Reference()
70 | return reference
71 |
72 | @staticmethod
73 | def get_var_names(self, dataset):
74 | try:
75 | variable_names = [var for var in dataset.variables]
76 | return variable_names
77 | except Exception as e:
78 | print("Failed", e)
79 | return None
80 |
81 | def get_long_names(self, dataset):
82 | long_names = []
83 | for variable in self.get_var_names(dataset):
84 | try:
85 | long_names.append(dataset[variable].long_name)
86 | except:
87 | long_names.append(dataset[variable].name)
88 | return long_names
89 |
90 | def get_vars_with_long_name(self, dataset):
91 | try:
92 | long_names = self.get_long_names(dataset)
93 | vars_long_names = list(
94 | zip(self.get_var_names(dataset), long_names))
95 | return vars_long_names
96 | except:
97 | pass
98 |
99 | def get_shape(self, variable):
100 | """
101 | Get shape of specifed variable, as list
102 | :param variable: String specifying variable name
103 | :return: shape_list - List containing shape of specified variable
104 | """
105 | shape = self.dataset[variable].shape
106 | shape_list = []
107 |
108 | if len(shape) > 1:
109 | for val in shape:
110 | shape_list.append(val)
111 | else:
112 | shape_list.append(shape[0])
113 |
114 | return shape_list
115 |
116 | def is_y(self, var):
117 | """
118 | Detect whether or not specified variable is a y coord
119 | :param var:
120 | :return: Boolean value
121 | """
122 | y_list = ['lat', 'latitude', 'LATITUDE', 'Latitude', 'y']
123 | if self.get_units(var) == 'degrees_north' or self.get_name(var) in y_list:
124 | return True
125 | else:
126 | return False
127 |
128 | def is_x(self, var):
129 | """
130 | Detect whether or not specified variable is an x coord
131 | :param var:
132 | :return: Boolean value
133 | """
134 | x_list = ['lon', 'longitude', 'LONGITUDE', 'Longitude', 'x']
135 |
136 | if self.get_units(var) == 'degrees_east':
137 | return True
138 | if self.get_name(var) in x_list:
139 | return True
140 | if self.get_description(var) in x_list:
141 | return True
142 | else:
143 | return False
144 |
145 | def has_time(self):
146 | time_list = ['t', 'TIME', 'time', 's', 'seconds', 'Seconds', ]
147 | for var in self.var_names:
148 | if self.get_units(var) in time_list:
149 | return True
150 | if self.get_name in time_list:
151 | return True
152 | if var in time_list:
153 | return True
154 | else:
155 | return False
156 |
157 | def get_time(self):
158 | time_list = ['t', 'TIME', 'time', 's', 'seconds', 'Seconds']
159 | time_dict = {}
160 | for var in self.var_names:
161 | if self.get_units(var) in time_list or self.get_name(var) in time_list:
162 | time_dict[var] = True
163 | if len(self.get_shape(var)) == 1:
164 | time_var = var
165 | else:
166 | return False
167 | return time_var
168 |
169 | def get_values(self, variable):
170 | """
171 |
172 | :param variable:
173 | :return: variable values as ndarray
174 | """
175 | x = self.dataset[variable].values
176 | y = np.where(np.isnan(x), None, x)
177 |
178 | return y
179 |
180 | def get_type(self, variable):
181 | """
182 | :param dset: NetCDF dataset object
183 | :param variable: Specified
184 | :return: var_type with digits stripped
185 | """
186 | try:
187 | var_type = str(self.dataset[variable].dtype)
188 |
189 | return re.sub(r'[0-9]+', '', var_type)
190 |
191 | except Exception as e:
192 | raise e
193 |
194 | def get_dimensions(self, variable):
195 | """
196 | Return dimension of specified variable.
197 |
198 | :param variable: Input variable
199 | :return: Tuple - Array dimension of specified variable
200 | """
201 | try:
202 | var_dimension = self.dataset[variable].dims
203 | return var_dimension
204 | except:
205 | print("Error Occurred: No Dimensions detected... Exiting. ")
206 | exit()
207 |
208 | def get_std_name(self, variable):
209 | """
210 | Return standard name of variable.
211 |
212 | :param variable: input variable
213 | :return: name
214 | """
215 | try:
216 | std_name = self.dataset[variable].name
217 | return std_name
218 | except:
219 | return None
220 |
221 | def get_description(self, variable):
222 | """
223 |
224 | :param variable: input variable
225 | :return: long_name
226 | """
227 | try:
228 | return self.dataset[variable].long_name
229 | except:
230 | return None
231 |
232 | def get_name(self, variable):
233 | """
234 |
235 | :param variable: input variable
236 | :return: name - string
237 | """
238 | try:
239 | return self.dataset[variable].name
240 | except:
241 | return None
242 |
243 | def get_units(self, variable):
244 | """
245 | Return units of specified variable.
246 | :param variable:
247 | :return: units
248 | """
249 | try:
250 | units = self.dataset[variable].units
251 | return units
252 | except:
253 | return None
254 |
255 | def get_metadata(self, variable):
256 | """
257 | Returns metadata for a specified variable.
258 |
259 | :param variable: Name of specified
260 | :return: dset[variable]
261 | """
262 | return self.dataset[variable]
263 |
264 | def get_var_group(self, variable):
265 | """
266 | Return group which specified variable belongs to.
267 |
268 | :param variable:
269 | :return: group as string
270 | :type string
271 | """
272 | return self.dataset[variable].group()
273 |
274 | def get_axis(self, variable):
275 | try:
276 | axis = self.dataset[variable].axis
277 | axis = list(map(str.lower, list(axis)))
278 | return axis
279 | except:
280 | print("Variable '%s' has no axis attribute, executing fallback for manual axis value detection." % (variable))
281 | try:
282 | axes_list = []
283 | axes_dict = self.get_axes()
284 | for dim in self.dataset[variable].dims:
285 |
286 | index = (list(axes_dict.keys())[
287 | list(axes_dict.values()).index(dim)])
288 |
289 | axes_list.append(index)
290 |
291 | print("Manually detected axis as: '%s'" % (axes_list))
292 | return axes_list
293 | except:
294 | print('Error in axes_dict')
295 |
296 | def get_dims(self, variable):
297 | try:
298 | dims = self.dataset[variable].dims
299 | except:
300 | print("Error Occurred: No Dimensions detected... Exiting. ")
301 | exit()
302 |
303 | def convert_time(self, t_variable):
304 | """
305 | Formats time objects to CovJSON compliant strings.
306 |
307 | :param t_variable: Time Variable
308 | :return: list of formatted datetime strings
309 | """
310 | date_list = []
311 | times = self.dataset[t_variable].values
312 |
313 | for time in times:
314 | try:
315 | time = pd.to_datetime(str(time))
316 | date_list.append(time.strftime('%Y-%m-%dT%H:%M:%SZ'))
317 | except ValueError as ve:
318 | print("Error parsing and converting '%s' variable object to CovJSON compliant string." % (t_variable), ve)
319 |
320 | return date_list
321 |
322 | def extract_var_data(self, var_names):
323 | """
324 | Returns dictionary containing the values in each variable specified in the variable list.
325 |
326 | :type var_names: String
327 | :param var_names:
328 | :return variable_dict - Dictionary containing key-val pairs
329 | """
330 | variable_dict = {} # Declaring dictionary used to store key-val pairs, var_name as key and the array as the value
331 | try:
332 | for var in var_names:
333 | variable_dict[var] = self.dataset[var].values
334 | return variable_dict
335 | except Exception as e:
336 | print("An Error occured:", e)
337 | raise e
338 |
339 | def get_axes(self):
340 |
341 | axes_dict = OrderedDict()
342 | x_list = ['lon', 'longitude', 'LONGITUDE', 'Longitude', 'x', 'X']
343 | y_list = ['lat', 'latitude', 'LATITUDE', 'Latitude', 'y', 'Y']
344 | t_list = ['time', 'TIME', 't', 'T']
345 | z_list = ['depth', 'DEPTH']
346 | for coord in self.dataset.coords:
347 | try:
348 | if self.dataset[coord].axis == 'T':
349 | axes_dict['t'] = coord
350 | if self.dataset[coord].axis == 'Z':
351 | axes_dict['z'] = coord
352 | except:
353 | pass
354 |
355 | try:
356 | if self.dataset[coord].units == 'degrees_north':
357 | axes_dict['y'] = coord
358 | if self.dataset[coord].units == 'degrees_east':
359 | axes_dict['x'] = coord
360 | except:
361 | pass
362 |
363 | try:
364 | if self.dataset[coord].name.lower() == 'x':
365 | axes_dict['x'] = coord
366 |
367 | if self.dataset[coord].name.lower() == 'y':
368 | axes_dict['y'] = coord
369 |
370 | if self.dataset[coord].name.lower() == 'z':
371 | axes_dict['z'] = coord
372 | except:
373 | pass
374 |
375 | try:
376 | if self.dataset[coord].positive in ['up', 'down']:
377 | axes_dict['z'] = coord
378 | except:
379 | pass
380 |
381 | try:
382 | if coord in t_list or self.dataset[coord].standard_name in t_list or self.dataset[coord].name in t_list:
383 | axes_dict['t'] = coord
384 | if coord in z_list or self.dataset[coord].standard_name in z_list or self.dataset[coord].name in z_list:
385 | axes_dict['z'] = coord
386 | except:
387 | print("Error: DataArray does not include 'standard name' or 'name'.")
388 |
389 | if len(axes_dict) < 2:
390 | print('Error: File does not conform to CF Conventions')
391 | exit()
392 |
393 | return axes_dict
394 |
395 | def get_x(self):
396 | for elem in self.dataset.coords:
397 |
398 | if elem in ['lon', 'longitude', 'LONGITUDE', 'Longitude', 'x', 'X']:
399 | return self.dataset[elem].values
400 | try:
401 | if self.dataset[elem].axis == 'X':
402 | return self.dataset[elem].values
403 | if self.dataset[elem].name in ['lon', 'longitude', 'LONGITUDE', 'Longitude', 'x', 'X']:
404 | return self.dataset[elem].values
405 | if self.dataset[elem].units == 'degrees_east':
406 | return self.dataset[elem].values
407 | except AttributeError:
408 | pass
409 |
410 | def get_y(self):
411 |
412 | y_var = self.get_axes()['y']
413 | return self.dataset[y_var].values
414 |
415 | def get_t(self):
416 | axis_dict = self.get_axes()
417 | t_var = axis_dict['t']
418 | return self.convert_time(t_var)
419 |
420 | def get_z(self):
421 |
422 | for elem in self.dataset.coords:
423 | if type(self.dataset[elem]) in ['numpy.datetime64', 'numpy.datetime32', 'datetime.datetime']:
424 | return self.dataset[elem].values
425 |
426 | try:
427 | if self.dataset[elem].axis == 'Z':
428 | return self.dataset[elem].values
429 |
430 | if self.dataset[elem].positive in ['down', 'up']:
431 | return self.dataset[elem].values
432 |
433 | except:
434 | raise AttributeError
435 |
436 | if elem in ['z', 'Z', 'depth', 'DEPTH']:
437 | return self.dataset[elem].values
438 |
--------------------------------------------------------------------------------