Skip to content
Snippets Groups Projects
Commit 7b692f11 authored by Christoph Knote's avatar Christoph Knote
Browse files

Updates to documentation

parent 4acec5d0
No related branches found
No related tags found
No related merge requests found
/.coverage
*.egg-info
__pycache__
docs/build/html
... to make git keep a possibly empty directory ...
\ No newline at end of file
......@@ -30,8 +30,7 @@ release = '2.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
extensions = ['sphinx.ext.autodoc']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
......
......@@ -17,7 +17,7 @@ The ICARTT data format is described here: https://www-air.larc.nasa.gov/missions
Installation
------------
.. include:: ../../icartt/INSTALL.rst
.. include:: ../../INSTALL.rst
Example
------------
......@@ -54,12 +54,13 @@ Variable
^^^^^^^^^^
.. autoclass:: Variable
:members:
Dataset
^^^^^^^^^^
.. autoclass:: Dataset
:members:
Indices and tables
==================
......
icartt
============================
icartt is an ICARTT file format reader and writer
The ICARTT data format is described here: https://www-air.larc.nasa.gov/missions/etc/IcarttDataFormat.htm
.. contents::
:local:
:depth: 2
Installation
------------
.. include:: ../../icartt/INSTALL.rst
Example
------------
::
import icartt
# load a new dataset from an existing file
ict = icartt.Dataset('path/to/example.ict')
# list variable names
ict.varnames
# e.g. ['Fractional_Day', 'UTC', 'JDAY', 'INDEX', 'FLIGHT', 'LOCAL_SUN_TIME', ...
# get data for variable 'UTC':
ict['UTC']
# some metadata
ict.organization
ict.dataSource
ict.mission
# write to (other) file:
with open('path/to/output.ict', 'wb') as f:
ict.write(f)
API
----
.. module:: icartt
Variable
^^^^^^^^^^
.. autoclass:: Variable
Dataset
^^^^^^^^^^
.. autoclass:: Dataset
......@@ -56,34 +56,47 @@ class StandardNormalComments(collections.UserList):
self.ingest(contents)
class Variable(collections.UserList):
'''
A Variable is a ICARTT variable description with name, units, scale and missing value.
'''An ICARTT variable description with name, units, scale and missing value.
:param name: Name of the variable
:type name: str
:param units: Units of the variable
:type units: str
:param longname: Long name of the variable
:type longname: str
:param scale: Scaling factor for the variable
:type scale: float, defaults to 1.0
:param miss: Missing value for the variable
:type miss: float, defaults to -99999.0
:param splitChar: Split character for text representation
:type splitChar: str, defaults to ","
'''
@property
def desc(self):
'''
Return variable description string as it appears in an ICARTT file
'''Variable description string as it appears in an ICARTT file
:return: description string
:rtype: str
'''
return self.splitChar.join( [ str(self.name), str(self.units), str(self.longname) ] )
def append(self, *argv):
'''
Append data to a variable. Depending on type (independent, dependent variable),
'''Append data to a variable. Depending on type (independent, dependent variable),
all identifying (bounded and unbounded) independent variables need to be given.
Examples:
- file type 1001, add value of independent variable:
ivar.append(234.4)
- file type 1001, add value of dependent variable:
ivar.append(234.4, 18.2)
- file type 2110, add value of independent (unbounded) variable:
ivar.append(234.4)
- file type 2110, add value of independent (bounded) variable:
ivar.append(234.4, 9148.2)
- file type 2110, add value of dependent variable:
ivar.append(234.4, 9148.2, 34.2)
:param ivar: value of the independent (unbounded) variable
:type ivar: float
:param ibvar: value of the independent (bounded) variable
:type ibvar: float, optional
:param dvar: value of the dependent variable
:type dvar: float, optional
'''
sanitized = lambda z: float(z) if not float(z) == float(self.miss) else float('NaN')
......@@ -102,6 +115,8 @@ class Variable(collections.UserList):
self.data.append( x )
def __init__(self, name, units, longname, scale=1.0, miss=-99999.0, splitChar=","):
'''Constructor method
'''
self.name = name
self.units = units
self.longname = longname
......@@ -113,14 +128,24 @@ class Variable(collections.UserList):
self.data = []
class Dataset:
'''
An ICARTT dataset that can be created from scratch or read from a file,
'''An ICARTT dataset that can be created from scratch or read from a file,
manipulated, and then written to a file.
:param f: file path or file handle to use
:type f: str or file handle or stream object, defaults to None
:param loadData: load data as well (or only header if False)?
:type loadData: bool, defaults to "True"
:param splitChar: splitting character used to separate fields in a line
:type splitChar: str, defaults to ","
'''
@property
def nheader(self):
'''
Header line count
'''Header line count
:return: line count
:rtype: int
'''
total = -1
if self.format == 1001:
......@@ -129,37 +154,50 @@ class Dataset:
# 2: IVAR + IBVAR
total = 16 + 2 + len(self.AUXVARS) + len(self.DVARS) + len(self.SCOM) + len(self.NCOM)
return total
@property
def VARS(self):
'''
Variables (independent + dependent + auxiliary)
'''
vars = { self.IVAR.name: self.IVAR, **self.DVARS }
if self.format == 2110:
vars = { self.IBVAR.name: self.IBVAR, **vars, **self.AUXVARS }
return vars
@property
def varnames(self):
'''
Names of variables (independent and dependent)
'''Names of variables (independent and dependent)
:return: list of variable names
:rtype: list
'''
return [ x for x in self.VARS.keys() ]
@property
def times(self):
'''
Time steps of the data contained.
'''Time steps of the data
:return: list of time steps
:rtype: list
'''
return [ self.dateValid + datetime.timedelta(seconds=x) for x in self.IVAR ]
@property
def VARS(self):
'''Variables (independent + dependent + auxiliary)
:return: dictionary of all variables
:rtype: dict of Variable(s)
'''
vars = { self.IVAR.name: self.IVAR, **self.DVARS }
if self.format == 2110:
vars = { self.IBVAR.name: self.IBVAR, **vars, **self.AUXVARS }
return vars
def __getitem__(self, name):
'''
Shortcut to enable access to variable data by name
'''Shortcut to enable access to variable data by name
:return: variable data
:rtype: list
'''
return self.VARS[name]
def write_header(self, f=sys.stdout):
'''
Write header to file handle <f>
'''Write header
:param f: handle to write to
:type f: file handle or StringIO stream, defaults to sys.stdout
'''
def prnt(txt):
f.write(str(txt) + "\n")
......@@ -232,8 +270,10 @@ class Dataset:
prnt([ p(ibval, self.IBVAR) ] + [ p(dval[1], DVAR) for DVAR in self.DVARS.values() for dval in DVAR if (dval[0][0] == ival) and (dval[0][1] == ibval) ])
def write_data(self, f=sys.stdout):
'''
Write data to file handle <f>
'''Write data
:param f: handle to write to
:type f: file handle or StringIO stream, defaults to sys.stdout
'''
def prnt_data(vars):
f.write( str(self.splitChar.join([ str(x) for x in vars ])) + "\n")
......@@ -243,18 +283,25 @@ class Dataset:
elif self.format == 2110:
nul = self._write_data_2110(prnt=prnt_data)
else:
print("huh?")
warnings.warn("Unknown file format {:d}".format(self.format))
def write(self, f=sys.stdout):
'''
Write to file handle <f>
'''Write header and data
:param f: handle to write to
:type f: file handle or StringIO stream, defaults to sys.stdout
'''
self.write_header(f=f)
self.write_data(f=f)
def make_filename(self, date_format='%Y%m%d'):
'''
Create ICARTT-compliant file name based on the information contained in the dataset
'''Create ICARTT-compliant file name based on the information contained in the dataset
:param date_format: date format to use when parsing
:type date_format: str, defaults to '%Y%m%d'
:return: file name generated
:rtype: string
'''
fn = self.dataID + "_" +self.locationID + "_" +datetime.datetime.strftime(self.dateValid, date_format)
fn += "_R" + str(self.revision) if not self.revision is None else ""
......@@ -264,8 +311,7 @@ class Dataset:
return fn + ".ict"
def read_header(self):
'''
Read the ICARTT header (from file)
'''Read the ICARTT header (from file)
'''
class Filehandle_with_linecounter:
def __init__(self, f, splitChar):
......@@ -426,12 +472,12 @@ class Dataset:
if self.nheader != nheader_suggested:
warnings.warn("Number of header lines suggested in line 1 ({:d}) do not match actual header lines read ({:d})".format(nheader_suggested, self.nheader))
def extract_items_1001(self, raw):
def _extract_items_1001(self, raw):
for cur in range(len(raw)):
self.IVAR.append(raw[cur][0])
nul = [ self.DVARS[key].append(raw[cur][0], raw[cur][i+1]) for i, key in enumerate(self.DVARS) ]
def extract_items_2110(self, raw):
def _extract_items_2110(self, raw):
cur = 0
num_var_name = list(self.AUXVARS.keys())[0]
while cur < len(raw):
......@@ -444,8 +490,7 @@ class Dataset:
cur += 1 + nprimary
def read_data(self):
'''
Read ICARTT data (from file)
'''Read ICARTT data (from file)
'''
if self.input_fhandle.closed:
self.input_fhandle = open(self.input_fhandle.name)
......@@ -454,17 +499,16 @@ class Dataset:
raw = [ line.split(self.splitChar) for line in self.input_fhandle ]
if self.format == 1001:
nul = self.extract_items_1001(raw)
nul = self._extract_items_1001(raw)
elif self.format == 2110:
nul = self.extract_items_1001(raw)
nul = self._extract_items_1001(raw)
else:
warnings.warn("Unknown file format: {:d}, could not read data.".format(self.format))
self.input_fhandle.close()
def read(self):
'''
Read ICARTT data and header
'''Read ICARTT data and header
'''
self.read_header()
self.read_data()
......@@ -477,10 +521,7 @@ class Dataset:
pass
def __init__(self, f=None, loadData=True, splitChar=","):
'''
:param string/file f: file path or file object to use
:param bool loadData: load data as well (or only header if False)?
:param string splitChar: the splitting character used to separate fields in a line
'''Constructor method
'''
self.format = 1001
self.version = None
......@@ -538,3 +579,22 @@ class Dataset:
self.read_header()
if loadData:
self.read_data()
'''
- file type 1001, add value of independent variable:
ivar.append(234.4)
- file type 1001, add value of dependent variable:
ivar.append(234.4, 18.2)
- file type 2110, add value of independent (unbounded) variable:
ivar.append(234.4)
- file type 2110, add value of independent (bounded) variable:
ivar.append(234.4, 9148.2)
- file type 2110, add value of dependent variable:
ivar.append(234.4, 9148.2, 34.2)
'''
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment