Skip to content

Commit

Permalink
Use OO program terms of 'field' and 'method' to avoid confision of ne…
Browse files Browse the repository at this point in the history
…tcdf attribute
  • Loading branch information
wkliao committed Sep 10, 2024
1 parent 4ec046e commit 065f6d0
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 84 deletions.
25 changes: 19 additions & 6 deletions docs/source/api/attribute_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@
Attributes
===========

NetCDF attributes can be created, accessed, and manipulated using python
dictionary-like syntax. An attribute can be associated to the file, referred to
as ``golbal attribute``, as well as to individual variable, referred to as
``variable's attribute``. Pythonic interfaces for accessing attributes are is
provided both in :class:`pnetcdf.File` (for global attributes) and the
:class:`pnetcdf.Variable` (for variable attributes).
In `object-oriented programming <https://en.wikipedia.org/wiki/Object-oriented_programming>`_,
a class contains fields (state variables containing data) and methods
(subroutines or procedures defining the object's behavior in code). ``Fields``
may also be known as members, attributes, or properties. To avoid confusion
with NetCDF's terminology of ``attribute``, this document uses `field` to refer
to a class's state variable.

NetCDF attributes are small, supplementary metadata that annotates variables or
files. NetCDF attribute is not a Python class by itself. Instead, it is a
field of python dictionary in class :class:`pnetcdf.File` and class
:class:`pnetcdf.Variable`. Their data types can be any allowed by the classic
NetCDF file formats. The most common data type is `text` for annotation
purpose. NetCDF attributes can be created, accessed, and manipulated using
python dictionary-like syntax. An attribute can be associated to a file,
referred to as ``golbal attribute``, as well as to individual variables,
referred to as ``variable's attribute``. Pythonic interfaces for accessing
attributes are is provided both in class :class:`pnetcdf.File` (for global
attributes) and class :class:`pnetcdf.Variable` (for variable attributes).
Example programs are `examples/global_attribute.py` and `examples/put_var.py`.

6 changes: 3 additions & 3 deletions docs/source/api/dimension_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ dimensions objects stored in the file.
:members: getfile, isunlimited
:exclude-members: name, size

Read-only Python Attributes of Dimension Class
The following class members are read-only and should not be modified by the
Read-only python fields of class :class:`pnetcdf.Dimension`
The following class fields are read-only and should not be modified by the
user.

.. attribute:: name

String name of Dimension instance. This class member is read-only and
String name of Dimension instance. This class field is read-only and
should not be modified by the user. To rename a dimension, use
:meth:`File.rename_dim` method.

Expand Down
4 changes: 2 additions & 2 deletions docs/source/api/file_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ of data and relations among data objects stored in a netCDF file.
inq_header_size, inq_put_size, inq_header_extent, inq_nreqs
:exclude-members: dimensions, variables, file_format, indep_mode, path

Read-only Python Attributes of File Class
The following class members are read-only and should not be modified by the
Read-only python fields of class :class:`pnetcdf.File`
The following class fields are read-only and should not be modified by the
user.

.. attribute:: dimensions
Expand Down
5 changes: 4 additions & 1 deletion docs/source/api/function_api.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
================
Other PnetCDF Utility Functions
Other pnetcdf class methods
================

PnetCDF class methods listed below are not associated with particular
instances of ``File`` or ``Variable``.

.. autofunction:: pnetcdf::libver
.. autofunction:: pnetcdf::strerror
.. autofunction:: pnetcdf::strerrno
Expand Down
4 changes: 2 additions & 2 deletions docs/source/api/variable_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ syntax.
chartostring


Read-only Python Attributes of Variable Class
The following class members are read-only and should not be modified
Read-only python fields of class :class:`pnetcdf.Variable`
The following class fields are read-only and should not be modified
directly by the user.

.. attribute:: name
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ netCDF files.

.. toctree::
:maxdepth: 1
:caption: Copyright Statement
:caption: Copyright

copyright

Expand Down
3 changes: 2 additions & 1 deletion docs/source/tutorial/basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ Dimensions
To retrieve the previous defined dimension instance from the file, you can
directly index the dictionary using variable name as the key. The dimension
information can be retrieved using following functions.
information can be retrieved using following python functions or ``Dimension``
class methods.

.. code-block:: Python
Expand Down
17 changes: 8 additions & 9 deletions docs/source/tutorial/compare_netcdf4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,21 @@ Difference in Programming Model

Data/Define Mode
NetCDF4-python library automatically switches between data and define mode
for the user by calling ``redef`` and ``enddef`` internally within the
define-mode operation functions. For performance reason, this is **not**
adopted in Pnetcdf-python. A manual call to :meth:`File.redef` is compulsory
to re-enter the define mode, following the C library convention. Similarly,
:meth:`File.enddef` is required before switching to data mode operations.
This design is based on considerations of the following aspects:
by calling ``redef`` and ``enddef`` internally. For performance reason, this
is **not** adopted in Pnetcdf-python. A manual call to :meth:`File.redef` is
compulsory to re-enter the define mode, following the C library convention.
Similarly, :meth:`File.enddef` is required before switching to data mode
operations. This design is based on considerations of the following aspects:

- Minimize overheads during consecutive define operations: Automatically
wrapping all define functions with :meth:`File.redef` and
wrapping all define methods with :meth:`File.redef` and
:meth:`File.enddef` could introduce significant overhead between
consecutive define operations. The netCDF4-python approach results in
unnecessary data/define mode switches, impacting performance.

- Avoid potential hanging when performing independent I/O: if
:meth:`File.enddef` is automatically embedded in all data mode operation
functions, the program will hang when partial processes are performing
:meth:`File.enddef` is automatically embedded in all data mode
methods, the program will hang when partial processes are performing
independent I/O (while others don't) because :meth:`File.enddef` is a
collective call which requires all processes to participate.

Expand Down
5 changes: 2 additions & 3 deletions src/pnetcdf/_Dimension.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ cdef class Dimension:

def __str__(self):
if not dir(self._file):
return 'Dimension object no longer valid'
return 'Dimension is not valid'
if self.isunlimited():
return "%r (unlimited): name = '%s', size = %s" %\
(type(self), self._name, len(self))
Expand All @@ -110,8 +110,7 @@ cdef class Dimension:
"""
getfile(self)
:return: the ``pnetcdf.File`` instance that this ``Dimension`` is a
member of.
:return: the ``pnetcdf.File`` instance that this ``Dimension`` belongs to.
:rtype: :class:`pnetcdf.File`
"""
Expand Down
24 changes: 12 additions & 12 deletions src/pnetcdf/_File.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cdef class File:
:type comm: mpi4py.MPI.Comm or None
:param info: [Optional]
MPI info object to use for file access. `None` defaults to
MPI info instance to use for file access. `None` defaults to
``MPI_INFO_NULL``.
:type info: mpi4py.MPI.Info or None
Expand Down Expand Up @@ -178,7 +178,7 @@ cdef class File:


def __dealloc__(self):
# close file when there are no references to object left
# close file when there are no references to it left
if self._isopen:
self._close(False)

Expand Down Expand Up @@ -296,8 +296,8 @@ cdef class File:
must be a positive integer or `-1`, which stands for "unlimited"
(default is `-1`). The return value is the `Dimension` class instance
describing the new dimension. To determine the current maximum size of
the dimension, use the `len` function on the `Dimension` instance. To
determine if a dimension is 'unlimited', use the
the dimension, use the python function `len()` on the `Dimension`
instance. To determine if a dimension is 'unlimited', use the
:meth:`Dimension.isunlimited` method of the `Dimension` instance.
:param str dimname: Name of the new dimension.
Expand Down Expand Up @@ -454,7 +454,7 @@ cdef class File:
# # containing all the netCDF attribute name/value pairs is provided by
# # the `__dict__` attribute of a `Variable` instance.

# # `Variable` instances behave much like array objects. Data can be
# # `Variable` instances behave much like arrays. Data can be
# # assigned to or retrieved from a variable with indexing and slicing
# # operations on the `Variable` instance. A `Variable` instance has six
# # Dataset standard attributes: `dimensions, dtype, shape, ndim, name`.
Expand Down Expand Up @@ -925,10 +925,10 @@ cdef class File:
"""
set_auto_chartostring(self, value)
Call :meth:`Variable.set_auto_chartostring` for all variables
contained in this `File`. Calling this function only affects existing
variables. Variables defined after calling this function will follow
the default behaviour.
Call :meth:`Variable.set_auto_chartostring` for all variables contained
in this `File`. Calling this method only affects existing variables.
Variables defined after calling this method will follow the default
behaviour.
:param value: True or False
:type value: bool
Expand Down Expand Up @@ -1026,7 +1026,7 @@ cdef class File:
"""
inq_info(self)
Returns an MPI info object containing all the file hints used by
Returns an MPI info instance containing all the file hints used by
PnetCDF library.
:rtype: mpi4py.MPI.Info
Expand Down Expand Up @@ -1106,7 +1106,7 @@ cdef class File:
return extent

cdef _get_dims(file):
# Private function to create `Dimension` instances for all the
# Private method to create `Dimension` instances for all the
# dimensions in a `File`
cdef int ierr, numdims, n, _file_id
cdef int *dimids
Expand All @@ -1132,7 +1132,7 @@ cdef _get_dims(file):
return dimensions

cdef _get_variables(file):
# Private function to create `Variable` instances for all the
# Private method to create `Variable` instances for all the
# variables in a `File`
cdef int ierr, numvars, n, nn, numdims, varid, classp, iendian, _file_id
cdef int *varids
Expand Down
26 changes: 12 additions & 14 deletions src/pnetcdf/_Variable.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ ctypedef MPI.Datatype Datatype
cdef class Variable:
"""
A PnetCDF variable is used to read and write netCDF data. They are
analogous to numpy array objects. See :meth:`Variable.__init__` for more
details.
analogous to numpy arrays. See :meth:`Variable.__init__` for more details.
.. note:: ``Variable`` instances should be created using the
:meth:`File.def_var` method of a :meth:`File` instance, not using this
Expand Down Expand Up @@ -102,7 +101,7 @@ cdef class Variable:
self._file = file
_file_id = self._file_id
#TODO: decide whether we need to check xtype at python-level
if isinstance(datatype, str): # convert to numpy datatype object
if isinstance(datatype, str): # convert to numpy data type object
datatype = np.dtype(datatype)
if isinstance(datatype, np.dtype):
if datatype.str[1:] in _supportedtypes:
Expand Down Expand Up @@ -161,7 +160,8 @@ cdef class Variable:

def __array__(self):
# numpy special method that returns a numpy array.
# allows numpy ufuncs to work faster on Variable objects
# This allows numpy Universal functions ufuncs to work faster on
# Variable instances.
return self[...]

def __repr__(self):
Expand Down Expand Up @@ -526,11 +526,10 @@ cdef class Variable:
self.chartostring = bool(chartostring)

def __getitem__(self, elem):
# This special method is used to index the netCDF variable
# using the "extended slice syntax". The extended slice syntax
# is a perfect match for the "start", "count" and "stride"
# arguments to the ncmpi_get_var() function, and is much more easy
# to use.
# This special method is used to index the netCDF variable using the
# "extended slice syntax". The extended slice syntax is a perfect match
# for the "start", "count" and "stride" arguments to the C function
# ncmpi_get_var(), and is much more easy to use.
start, count, stride, put_ind =\
_StartCountStride(elem,self.shape,dimensions=self.dimensions,file=self._file)
datashape = _out_array_shape(count)
Expand Down Expand Up @@ -593,11 +592,10 @@ cdef class Variable:
return data

def __setitem__(self, elem, data):
# This special method is used to assign to the netCDF variable
# using "extended slice syntax". The extended slice syntax
# is a perfect match for the "start", "count" and "stride"
# arguments to the ncmpi_put_var() function, and is much more easy
# to use.
# This special method is used to assign to the netCDF variable using
# "extended slice syntax". The extended slice syntax is a perfect match
# for the "start", "count" and "stride" arguments to the C function
# ncmpi_put_var(), and is much more easy to use.

# if _Encoding is specified for a character variable, convert
# numpy array of strings to a numpy array of characters with one more
Expand Down
Loading

0 comments on commit 065f6d0

Please sign in to comment.