Skip to content

Commit

Permalink
Merge pull request #10 from UV-CDAT/doc
Browse files Browse the repository at this point in the history
Doc
  • Loading branch information
doutriaux1 committed May 3, 2017
2 parents f2edadc + f30ecb2 commit e610ae0
Show file tree
Hide file tree
Showing 14 changed files with 1,730 additions and 1,037 deletions.
115 changes: 79 additions & 36 deletions Lib/ASCII.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,40 @@ def make_var(lap,id=None,shape=None):
lap.id=id
return lap


# TODO: need an actual 'vars.txt' file for the doctests
def readAscii( text_file ,header=0, ids=None, shape=None, next='------',separators=[';',',',':']):
"""Reads data from an ascii file
Usage :::
vars = genutil.ASCII.readAscii( text_file ,header=0, ids=None, shape=None, next='------',separators=[';',',',':'])
:::
Options :::
text_file :: ASCII File to read from.
header :: (0) Number of header lines, these lines will be skipped.
ids :: (None) use the values in this list as variable ids (1 per variable returned)
shape :: (None) use the tuple/list in this list as the final shape of the variable read.
next :: ('------') character string marking separation between variables
separators :: ([';',',', ':']) List of character recognized as column separator
Output :::
vars :: List containing transient(s) variable(s) possibly named after ids and reshaped from the 'shape' option.
"""
Reads data from an ascii file to generate a list of transient(s)/varable(s)
:Example:
.. doctest:: genutil_ASCII_readascii
>>> vars=genutil.ASCII.readAscii("vars.txt") # use default params
:param text_file: A string, containing the path to an ASCII File to read from.
:type text_file: str
:param header: Number of header lines, these lines will be skipped.
:type header: int
:param ids: List of values to use as variable ids (1 per variable returned)
:type ids: list
:param shape: use the tuple/list in this list as the final shape of the variable read.
:type shape: tuple or list
:param next: character string marking separation between variables (i.e. '------')
:type next: str
:param separators: ([';',',', ':']) List of characters recognized as column
separators. Can be represented as a list or a string.
If it is a string, separator characters must be space-delimited.
:type separators: list or str
:returns: List containing transient(s) variable(s) possibly named after ids and reshaped from the 'shape' option.
:rtype: list
"""
sep=[]
if isinstance(separators,str):
Expand Down Expand Up @@ -82,24 +100,49 @@ def readAscii( text_file ,header=0, ids=None, shape=None, next='------',separato
return vars[0]


def read_col( text_file ,header=0, cskip=0, cskip_type='columns', axis=False, ids=None, idrow=0, separators=[';',',', ':']):
""" Reads column-stored data from ASCII files
Usage:::
vars = genutil.ASCII.read_col( text_file ,header=0, cskip=0, cskip_type='columns', axis=False, ids=None, idrow=False, separators=[';',',', ':'])
Options :::
text_file :: ASCII File to read from.
header :: (0) Number of header lines, these lines will be skipped.
cskip :: (0) Number of 'column'/'character' to skip (dummy column)
cskip_type :: ('column') is 'cskip' a number of 'column' or 'character' to skip?
axis :: (False) Use as the values for the first column as variable axis (x values in y(x))
idrow :: (False) Is the first row representing the ids of var generated ?
ids :: (None) use the values in this list as variable ids (1 per column returned)
separators :: ([';',',', ':']) List of character recognized as column separator
Output :::
vars :: List containing 1 transient varialbe per column in the files.
Variable ids are optionaly determined by first row.
Variable axis may be the first column
def read_col( text_file ,header=0, cskip=0, cskip_type='columns', axis=False, ids=None, idrow=0,
separators=[';',',', ':']):
"""
Reads column-stored data from ASCII files
:Example:
.. doctest:: genutil_ASCII_read_col
>>> vars = genutil.ASCII.read_col("vars.txt") # use default params
:param text_file: ASCII File to read from.
:type text_file:
:param header: Number of header lines, these lines will be skipped.
:type header: int
:param cskip: Number of 'column'/'character' to skip (dummy column)
:type cskip: int
:param cskip_type: One of 'columns' or 'characters'. Specifies which should be skipped.
:type cskip_type: str
:param axis: Boolean flag indicating whether to use as the values for the first column as
variable axis (x values in y(x)).
:type axis: bool
:param idrow: Is the first row representing the ids of var generated.
:type idrow:
:param ids: (None) use the values in this list as variable ids (1 per column returned)
:type ids:
:param separators: ([';',',', ':']) List of characters recognized as column
separator. Can be represented as a list or a string.
If it is a string, separator characters must be space-delimited.
:type separators: list or str
:returns: List containing 1 transient variable per column in the files.
Variable ids are optionally determined by first row.
Variable axis may be the first column.
:rtype: list
"""

sep=[]
Expand All @@ -108,9 +151,9 @@ def read_col( text_file ,header=0, cskip=0, cskip_type='columns', axis=False, id
for s in separators:
sep.append(s)

f=open( text_file )
lst = f.readlines( )
f.close( )
f=open(text_file)
lst = f.readlines()
f.close()
lst=lst[header:]
if not isinstance(ids,(tuple,list)):
ids=[ids]
Expand Down
122 changes: 80 additions & 42 deletions Lib/Filler.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,40 @@
import cdat_info
class StringConstructor:
""" This Class aims at spotting keyword in string and replacing them
Usage
Filler=StringConstructor(template)
or
Filler=StringConstructor()
Filler.template=template
template is a string of form
template = 'my string here with %(keywords) in it'
You can have has many 'keyword' as you want, and use them as many times as you want
keywords are delimited on the left by %( and ) on the right
In order to construct the string (i.e. replace keywrods with some values:
"""
This class aims at spotting keywords in a string and replacing them
str=Filler(keyword='kwstr')
or
Filler.keyword='kwstr'
str=Filler()
:Usage:
Example:
structure='/pcmdi/amip/mo/%(variable)/%(model)/%(variable)_%(model).xml'
Filler=StringConstructor(structure)
Filler.variable='tas'
myfilename=Filler.construct(structure,model='ugamp-98a')
.. code-block:: python
print myfilename # '/pcmdi/amip/mo/tas/ugamp-98a/tas_ugamp-98a.xml'
>>> template = "templates are strings containing any number of %(keywords) using %(this_format)"
>>> Filler=StringConstructor(template)
# or
>>> Filler=StringConstructor()
>>> Filler.template=template
# In order to construct the string (i.e. replace keywords with some values):
>>> str=Filler(keywords='keywdstr',this_format='')
# or
>>> Filler.keyword='kwstr'
>>> Filler.this_format=''
>>> str=Filler()
template is a string of form: 'my string here with %(keywords) in it'
You can have has many keywords as you want, and use them as many times as you want.
Keywords are delimited on the left by %( and on the right by ).
"""
def __init__(self,template=None):
"""
Instantiates a StringConstructor object.
:param template: A string used by StringConstructor for keyword
replacement. template is a string of form:
'my string here with %(keywords) in it'.
There can be an unlimited number of keywords, delimited by %( on
the left and ) on the right.
"""
cdat_info.pingPCMDIdb("cdat","genutil.StringConstructor")
self.template=template
## ok we need to generate the keys and set them to empty it seems like a better idea
Expand Down Expand Up @@ -59,16 +64,29 @@ def keys(self,template=None):

def construct(self,template=None,**kw):
"""
construct, accepts a string with a unlimited number of keyword to replace
keyword to replace must be in the format %(keyword) within the string
keyword value are either passed as keyword to the construct function or preset
Example:
structure='/pcmdi/amip/mo/%(variable)/%(model)/%(variable)_%(model).xml'
Filler=StringConstructor()
Filler.variable='tas'
myfilename=Filler.construct(structure,model='ugamp-98a')
print myfilename
Accepts a string with an unlimited number of keywords to replace.
Keywords to replace must be in the format %(keyword) within the string.
Keyword values are either passed as keyword to the construct function or preset.
:Example:
.. doctest:: Filler_construct
>>> structure='/pcmdi/amip/mo/%(variable)/%(model)/%(variable)_%(model).xml'
>>> Filler=StringConstructor()
>>> Filler.variable='tas'
>>> myfilename=Filler.construct(structure,model='ugamp-98a')
>>> print myfilename
'/pcmdi/amip/mo/tas/ugamp-98a/tas_ugamp-98a.xml'
:param template: A string used by StringConstructor for keyword replacement.
template is a string of form: 'my string here with %(keywords) in it'.
There can be an unlimited number of keywords, delimited by %( on the left and ) on the right.
:type template: str
:param kw: Comma-delimited list of keyword to string value mappings, i.e.:
keyword1='kwd1 string',keyword2='kwd2 string', ...
:type kw: list
"""
if template is None:
template=self.template
Expand All @@ -82,6 +100,31 @@ def construct(self,template=None,**kw):
return template

def reverse(self,name,debug=False):
"""
The reverse function attempts to take a template and derive its keyword values based on name parameter.
:Example:
.. doctest:: Filler_reverse
>>> Filler=StringConstructor(template="%(a).%(b)")
>>> Filler.reverse("A.B")
{a:"A", b:"B"}
:param name: String to test the template's keyword values.
:type name: str
:param debug: Boolean flag to indicate whether or not to print debug output.
:type debug: bool
:returns: A dictionary mapping the StringConstructor's template's keywords to the corresponding values,
according to the format of the name parameter.
:rtype: dict
.. warning::
reverse makes its best effort at deriving keyword values from a string, but it is not guaranteed to work.
"""
out={}
template = self.template
for k in self.keys():
Expand Down Expand Up @@ -121,11 +164,6 @@ def reverse(self,name,debug=False):
def __call__(self,*args,**kw):
"""default call is construct function"""
return self.construct(*args,**kw)

Filler=StringConstructor()

if __name__=='__main__':
Filler.variable='tas'
structure='/pcmdi/amip/mo/%(variable)/%(model)/%(variable)_%(model).xml'
myfilename=Filler.construct(structure,model='*')
print myfilename

Filler=StringConstructor()
3 changes: 2 additions & 1 deletion Lib/Statusbar_Pmw.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Pmw, Tkinter
class Statusbar(Pmw.MegaWidget):
""" Megawidget containing a scale and an indicator.
"""
Megawidget containing a scale and an indicator.
"""

def show(self,value):
Expand Down
59 changes: 49 additions & 10 deletions Lib/arrayindexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,29 @@
def get(Array,Indices,axis=0):
"""
Arrayrrayindexing returns Array[Indices], indices are taken along dimension given with axis
Usage:
C=get(Array,Indices,axis=0) # i.e. C=Array[Indices]
Indices accepts negative value ,e.g: -1 is last element
:Example:
.. doctest:: arrayindexing_get
>>> import numpy as np
>>> Array=np.array([2,3,1,0,1,2,3])
>>> Indices=[0,-1, len(Array)-2] # get the first, last, and second-to-last indices of the array
>>> C=get(Array,Indices,axis=0) # i.e. C=Array[Indices]
:param Array: A cdms2 variable, or numpy array, to access the indices of
:type Array: cdms.tvariable.TransientVariable or numpy.array
:param Indices: List of integers specifying the indices of Array to access and return
.. note::
Negative index value will access indices starting from the end of the array.
i.e. -1 will be the last item.
:type Indices: list
:param axis: Axis of a cdms variable
:type axis: int or str
"""
## First some checks

Expand All @@ -28,11 +47,11 @@ def get(Array,Indices,axis=0):
if isinstance(Indices,int):
return Array[Indices]
if Indices.shape!=Array.shape[1:]:
raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)
raise "Error incompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)
else:
Array,Indices,weights,axis,ax=statistics.__checker(Array,Indices,None,axis)
if Indices.shape!=Array.shape:
raise "Error uncompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)
raise "Error incompatible shapes: "+str(Array.shape)+" and "+str(Indices.shape)

m=Array.mask
if not isinstance(Indices,int): Indices=Indices.data.astype('i') # Sometihng happened with masking of y by x mask
Expand All @@ -52,11 +71,31 @@ def get(Array,Indices,axis=0):
def set(Array,Indices,Values,axis=0):
"""
Arrayrrayindexing set Array[Indices] with Values, indices are taken along dimension given with axis
Usage:
Array=set(Array,Indices,Values,axis=0) # i.e. Array[Indices]=Values
Indices accepts negative value ,e.g: -1 is last element
:Example:
.. doctest:: arrayindexing_set
>>> import numpy as np
>>> Array=np.array([2,3,1,0,1,2,3])
>>> Indices=[0,-1, len(Array)-2] # get the first, last, and second-to-last indices of the array
>>> Values = [5, 7, 9]
>>> Array=set(Array,Indices,Values,axis=0) # i.e. Array[Indices]=Values
:param Array: A cdms2 variable, or numpy array, to set the indices of
:type Array: cdms.tvariable.TransientVariable or numpy.array
:param Indices: List of integers specifying the indices of Array to access and set.
.. note::
Negative index value will access indices starting from the end of the array.
i.e. -1 will be the last item.
:type Indices: list
:param axis: Axis of a cdms variable
:type axis: int or str
"""
## if Indices.ndim==0:
## Array[Indices]=Values
Expand Down
Loading

0 comments on commit e610ae0

Please sign in to comment.