Wed, 28 Feb 2018 12:04:10 +0200
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']