Improved documentation, changelong, and support for numpy doc strings.

Wed, 28 Feb 2018 12:04:10 +0200

author
Iannis <i.binietoglou@impworks.gr>
date
Wed, 28 Feb 2018 12:04:10 +0200
changeset 132
dc48952c383d
parent 131
7225c844bdc5
child 133
67d5e518a813

Improved documentation, changelong, and support for numpy doc strings.

atmospheric_lidar/__init__.py file | annotate | diff | comparison | revisions
atmospheric_lidar/generic.py file | annotate | diff | comparison | revisions
atmospheric_lidar/raymetrics.py file | annotate | diff | comparison | revisions
changelog.rst file | annotate | diff | comparison | revisions
docs/apidocs.rst file | annotate | diff | comparison | revisions
docs/conf.py file | annotate | diff | comparison | revisions
setup.py file | annotate | diff | comparison | revisions
--- a/atmospheric_lidar/__init__.py	Tue Feb 27 18:41:06 2018 +0200
+++ b/atmospheric_lidar/__init__.py	Wed Feb 28 12:04:10 2018 +0200
@@ -1,1 +1,1 @@
-__version__ = '0.2.14'
\ No newline at end of file
+__version__ = '0.3.0'
\ No newline at end of file
--- a/atmospheric_lidar/generic.py	Tue Feb 27 18:41:06 2018 +0200
+++ b/atmospheric_lidar/generic.py	Wed Feb 28 12:04:10 2018 +0200
@@ -79,8 +79,8 @@
         Update the info dictionary, variables, and dimensions of the measurement object
         based on the information found in the channels objects.
         
-        Note
-        ----
+        Notes
+        -----
         Reading of the scan_angles parameter is not implemented.
         """
         # Initialize
@@ -295,8 +295,8 @@
 
         This method is here just for testing.
         
-        Note
-        ----       
+        Notes
+        -----
         This method should not be called if processing the data with the SCC. The SCC
         performs this operations anyway. 
         """
@@ -976,7 +976,7 @@
         cmap_label : str
            Label for the colorbar. Ignored if add_colorbar is False.
         cb_format : str
-           
+           Colorbar tick format string.
         vmin : float
            Minimum value for the color scale.
         vmax : float
--- a/atmospheric_lidar/raymetrics.py	Tue Feb 27 18:41:06 2018 +0200
+++ b/atmospheric_lidar/raymetrics.py	Wed Feb 28 12:04:10 2018 +0200
@@ -1,25 +1,81 @@
 """ Code to read Raymetrics version of Licel binary files."""
-import datetime
 import logging
 
-import numpy as np
-import pytz
-
 from .licel import LicelFile, LicelLidarMeasurement, LicelChannel, PhotodiodeChannel
 
 logger = logging.getLogger(__name__)
 
 
 class ScanningFile(LicelFile):
+    """ Raymetrics is using a custom version of licel file format to store scanning lidar measurements.
+     
+    The file includes one extra line describing the scan strategy of the dataset. The extra parameters are:
+    
+    `azimuth_start`
+        Start azimuth angle for the scan, relative to instrument zero position (degrees).
+    
+    `azimuth_stop`
+        Stop azimuth angle for the scan, relative to instrument zero position (degrees).
+        
+    `azimuth_step` 
+        Step of the azimuth scan (degrees).
+
+    `zenith_start` 
+        Start zenith angle for the scan, relative to *nadir* (degrees). Take care that this is actually
+        nadir angle. Vertical measurements correspond to -90.
+
+    `zenith_stop` 
+        Stop zenith angle for the scan, relative to *nadir* (degrees). Take care that this is actually
+        nadir angle. Vertical measurements correspond to -90.
+
+    `zenith_step` 
+        Step of the zenith scan (degrees).
+
+    `azimuth_offset`
+        Offset of instrument zero from North (degrees). Using this value you can convert `azimuth_start` and
+        `azimuth_stop` to absolute values.
+
+    Moreover, four new parameters are added in the second line of the file:
+
+    `zenith_angle`
+        Zenith angle of the current file. Take care that this is actually
+        nadir angle. Vertical measurements correspond to -90.
+
+    `azimuth_angle`
+        Azimuth angle of the current file. Value relative to instrument zero position.
+
+    `temperature`
+        Ambient temperature (degrees C)
+
+    `pressure`
+        Ambient pressure (hPa)
+    """
+
+    # Specifications of the header lines.
     licel_file_header_format = ['filename',
                                 'start_date start_time end_date end_time altitude longitude latitude zenith_angle azimuth_angle temperature pressure',
                                 # Appart from Site that is read manually
-                                'azimuth_start azimuth_stop azimuth_step zenith_start zenith_finish zenith_step azimuth_offset',
+                                'azimuth_start azimuth_stop azimuth_step zenith_start zenith_stop zenith_step azimuth_offset',
                                 'LS1 rate_1 LS2 rate_2 number_of_datasets', ]
+
+    # Specifications of the channel lines in the header
     licel_file_channel_format = 'active analog_photon laser_used number_of_datapoints 1 HV bin_width wavelength d1 d2 d3 d4 ADCbits number_of_shots discriminator ID'
 
     def _read_rest_of_header(self, f):
-        """ Read the rest of the header lines, after line 2. """
+        """ Read the third and fourth row of  of the header lines.
+
+        The first two rows are read in the licel class.
+
+        Parameters
+        ----------
+        f : file
+           An open file-like object.
+
+        Returns
+        -------
+        raw_info : dict
+           A dictionary containing all parameters of the third and fourth line of the header.
+        """
         raw_info = {}
 
         third_line = f.readline()
@@ -30,6 +86,7 @@
         return raw_info
 
     def _assign_properties(self):
+        """ Assign scanning-specific parameters found in the header as object properties."""
         super(ScanningFile, self)._assign_properties()
         self.azimuth_angle = float(self.raw_info['altitude'])
         self.temperature = float(self.raw_info['temperature'])
@@ -38,12 +95,14 @@
         self.azimuth_stop = float(self.raw_info['azimuth_stop'])
         self.azimuth_step = float(self.raw_info['azimuth_step'])
         self.zenith_start = float(self.raw_info['zenith_start'])
-        self.zenith_finish = float(self.raw_info['zenith_finish'])
+        self.zenith_stop = float(self.raw_info['zenith_stop'])
         self.zenith_step = float(self.raw_info['zenith_step'])
         self.azimuth_offset = float(self.raw_info['azimuth_offset'])
 
 
 class ScanningChannel(LicelChannel):
+    """ A class representing measurements of a specific lidar channel, during a scanning measurement. """
+
     def __init__(self):
         super(ScanningChannel, self).__init__()
 
@@ -51,28 +110,43 @@
         self.azimuth_stop = None
         self.azimuth_step = None
         self.zenith_start = None
-        self.zenith_finish = None
+        self.zenith_stop = None
         self.zenith_step = None
         self.azimuth_offset = None
         self.zenith_angles = []
         self.azimuth_angles = []
 
     def append_file(self, current_file, file_channel):
+        """ Keep track of scanning-specific variable properties of each file. """
         super(ScanningChannel, self).append_file(current_file, file_channel)
         self.zenith_angles.append(current_file.zenith_angle)
         self.azimuth_angles.append(current_file.azimuth_angle)
 
     def _assign_properties(self, current_file, file_channel):
+        """ Assign scanning-specific properties as object properties. Check that these are unique,
+        i.e. that all files belong to the same measurements set.
+
+        Parameters
+        ----------
+        current_file : ScanningFile object
+           A ScanningFile object being imported
+        file_channel : LicelChannelData object
+           A specific LicelChannelData object holding data found in the file.
+        """
         super(ScanningChannel, self)._assign_properties(current_file, file_channel)
         self._assign_unique_property('azimuth_start', current_file.azimuth_start)
         self._assign_unique_property('azimuth_stop', current_file.azimuth_stop)
         self._assign_unique_property('azimuth_step', current_file.azimuth_step)
         self._assign_unique_property('zenith_start', current_file.zenith_start)
-        self._assign_unique_property('zenith_finish', current_file.zenith_finish)
+        self._assign_unique_property('zenith_stop', current_file.zenith_stop)
         self._assign_unique_property('zenith_step', current_file.zenith_step)
 
 
 class ScanningLidarMeasurement(LicelLidarMeasurement):
+    """ A class representing a scanning measurement set.
+
+    It useses `ScanningFile` and `ScanningChannel` classes for handling the data.
+    """
     file_class = ScanningFile
     channel_class = ScanningChannel
     photodiode_class = PhotodiodeChannel
--- a/changelog.rst	Tue Feb 27 18:41:06 2018 +0200
+++ b/changelog.rst	Wed Feb 28 12:04:10 2018 +0200
@@ -4,6 +4,23 @@
 Unreleased
 ----------
 
+0.3.0 - 2018-02-28
+------------------
+Fixed
+~~~~~
+- Bug when calculating physical units for Licel analog signals
+
+Added
+~~~~~
+- Initial support of Raymetrics scanning files.
+- Initial experimental support of cloud masking when converting licel to SCC format.
+- Added support for overlap and lidar ratio file names in SCC format.
+
+
+Changed
+~~~~~~~
+- Improvements on DIVA format.
+
 0.2.14 - 2018-01-10
 -------------------
 Fixed
--- a/docs/apidocs.rst	Tue Feb 27 18:41:06 2018 +0200
+++ b/docs/apidocs.rst	Wed Feb 28 12:04:10 2018 +0200
@@ -1,7 +1,6 @@
 API documentation
 =================
 
-
 Generic classes
 ---------------
 .. automodule:: atmospheric_lidar.generic
@@ -14,6 +13,12 @@
    :members:
 
 
+Raymetrics scanning classes
+---------------------------
+.. automodule:: atmospheric_lidar.raymetrics
+   :members:
+
+
 Scripts
 -------
 
--- a/docs/conf.py	Tue Feb 27 18:41:06 2018 +0200
+++ b/docs/conf.py	Wed Feb 28 12:04:10 2018 +0200
@@ -35,7 +35,11 @@
     MOCK_MODULES = ['netCDF4', 'numpy', 'scipy', 'matplotlib', 'matplotlib.ticker']
     sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
 
-# -- General configuration ------------------------------------------------
+# NumpyDoc options, to work with autosummary
+numpydoc_show_class_members = False
+# class_members_toctree = False
+
+# -- General `onfiguration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
 #
@@ -45,10 +49,13 @@
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = ['sphinx.ext.autodoc',
-            'sphinx.ext.intersphinx',
-            'sphinx.ext.todo',
-            'sphinx.ext.mathjax',
-            'sphinx.ext.viewcode']
+              'sphinx.ext.autosummary',
+              'sphinx.ext.intersphinx',
+              'sphinx.ext.todo',
+              'sphinx.ext.mathjax',
+              'sphinx.ext.viewcode',
+              'numpydoc',
+              ]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
--- a/setup.py	Tue Feb 27 18:41:06 2018 +0200
+++ b/setup.py	Wed Feb 28 12:04:10 2018 +0200
@@ -52,6 +52,7 @@
           "numpy",
           "matplotlib",
           "sphinx",
+          "numpydoc",
           "pytz",
           "pyyaml",
       ],

mercurial