Initial classed to read diva L0 data format.

Fri, 02 Nov 2018 13:23:53 +0200

author
Iannis B <ioannis@inoe.ro>
date
Fri, 02 Nov 2018 13:23:53 +0200
changeset 165
392a714d12a2
parent 164
e4915d84dd7d
child 166
ab21bd91bc09

Initial classed to read diva L0 data format.

atmospheric_lidar/diva.py file | annotate | diff | comparison | revisions
atmospheric_lidar/licel.py file | annotate | diff | comparison | revisions
--- a/atmospheric_lidar/diva.py	Fri Oct 19 14:13:33 2018 +0300
+++ b/atmospheric_lidar/diva.py	Fri Nov 02 13:23:53 2018 +0200
@@ -17,7 +17,7 @@
 logger = logging.getLogger(__name__)
 
 
-class DivaMixin:
+class DivaConverterMixin:
 
     def save_as_diva_netcdf(self, output_path, parameter_file):
         """ Save the current data in the 'draft' DIVA format. """
@@ -29,8 +29,7 @@
         global_variables = parameters['global_variables']  # Shortcut
         channels = parameters['channels']
 
-
-        iso_date = datetime.datetime.utcnow().isoformat()
+        iso_date = datetime.datetime.utcnow().strftime('%Y-%d-%mT%H:%M:%SZ')
         python_file_name = os.path.basename(__file__)
 
         with netcdf.Dataset(output_path, 'w', format="NETCDF4") as f:
@@ -65,16 +64,16 @@
             longitude.long_name = 'system longitude'
             longitude.units = 'degrees_east'
 
-            laser_angle = f.createVariable('laser_zenith_angle', datatype='f4')
-            laser_angle.standard_name = 'sensor_zenith_angle'
-            laser_angle.long_name = 'zenith angle of emitted laser'
-            laser_angle.units = 'degree'
+            lidar_zenith_angle = f.createVariable('lidar_zenith_angle', datatype='f4')
+            lidar_zenith_angle.standard_name = 'sensor_zenith_angle'
+            lidar_zenith_angle.long_name = 'zenith angle of emitted laser'
+            lidar_zenith_angle.units = 'degree'
 
-            laser_azimuth = f.createVariable('laser_azimuth_angle', datatype='f4')
-            laser_azimuth.standard_name = 'sensor_azimuth_angle'
-            laser_azimuth.long_name = 'azimuth angle of emitted laser'
-            laser_azimuth.units = 'degree'
-            laser_azimuth.comment = 'Based on North. Optional'
+            lidar_azimuth = f.createVariable('lidar_azimuth_angle', datatype='f4')
+            lidar_azimuth.standard_name = 'sensor_azimuth_angle'
+            lidar_azimuth.long_name = 'azimuth angle of emitted laser'
+            lidar_azimuth.units = 'degree'
+            lidar_azimuth.comment = 'Based on North. Optional'
 
             altitude = f.createVariable('altitude', datatype='f4')
             altitude.standard_name = 'altitude'
@@ -84,7 +83,7 @@
             # Assign top-level variables
             latitude[:] = global_variables['latitude']
             longitude[:] = global_variables['longitude']
-            laser_angle[:] = global_variables['laser_pointing_angle']
+            lidar_zenith_angle[:] = global_variables['laser_pointing_angle']
             altitude[:] = global_variables['system_altitude']
 
             # Optional ancillary group
@@ -418,46 +417,85 @@
         return choices[pol_string]
 
 
-class DivaLidarMeasurement(BaseLidarMeasurement):
+class DivaLidarMeasurement(object):
+    """ A class to read raw lidar files in DIVA format.
 
-    def __init__(self, file_list):
+    Unlike other classes in this module, it does not inherit from BasicLidarMeasurement. This is done
+    to avoid all the burden of backward compatibility. In the future this could be hosted also as a separte moduel.
+    """
+
+    def __init__(self, file_path, import_now=True):
         """
         This is run when creating a new object.
 
         Parameters
         ----------
-        file_list : list or str
-           A list of the full paths to the input file(s).
+        file_path : str
+           Paths to the input netCDF file.
+        import_now : bool
+           If True, the file is imported when the object is created.
         """
-        if isinstance(file_list, str):
-            file_list = [file_list, ]
-        super(DivaLidarMeasurement, self).__init__(file_list=file_list)
+        self.file_path = file_path
+        self.file_name = os.path.basename(file_path)
+
+        if import_now:
+            self.import_file(file_path)
+
+    def import_file(self):
+        """ Import data from a single DIVA file.
+        """
+
+        logger.debug('Importing file {0}'.format(self.file_name))
+
+        self.channels = {}
 
-    def _import_file(self, filename):
-        """ Import data from a single DIVA file. """
+        with netcdf.Dataset(self.file_path) as input_file:
+            self.title = input_file.title
+            self.source = input_file.source
+            self.institution = input_file.institution
+            self.references = input_file.references
+            self.location = input_file.location
+            self.data_version = input_file.data_version
+            self.PI = input_file.PI
+            self.PI_email = input_file.PI_email
+            self.conversion_date_str = input_file.conversion_date
+            self.conversion_date = datetime.datetime.strptime(input_file.conversion_date, '%Y-%d-%mT%H:%M:%SZ')
+            self.comment = input_file.comment
+            self.conventions = input_file.Conventions
+            self.history = input_file.history
 
-        logger.debug('Importing file {0}'.format(filename))
-        current_file = self.file_class(filename, use_id_as_name=self.use_id_as_name, licel_timezone=self.licel_timezone)
-        self.durations[current_file.filename] = current_file.duration()
+            self.latitude = input_file.variables['latitude'][:]
+            self.longitude = input_file.variables['longitude'][:]
+
+            self.lidar_zenith_angle = input_file.variables['lidar_zenith_angle'][:]
+            self.lidar_azimuth_angle = input_file.variables['lidar_azimuth_angle'][:]
+            self.lidar_altitude = input_file.variables['altitude'][:]
+
+            ancillary = input_file.groups.pop('ancillary')
 
+            self.meteo_time = ancillary.variables['time'][:]
+            self.air_temperature_kelvin = ancillary.variable['air_temperature'][:]
+            self.air_pressure_hpa = ancillary.variable['air_pressure'][:]
 
-        self._create_or_append_channel(current_file)
-        file_laser_shots = []
-        self.laser_shots.append(file_laser_shots)
+            for group_name, group in input_file.groups.items():
+                channel_name = group_name[8:]  # Remove 'channel_' prefix
+                self.channels[channel_name] = DivaChannel(channel_name, group)
+
 
 
 class DivaChannel(object):
 
-    def __init__(self, file_name, channel_group):
+    def __init__(self, channel_name, group):
         """ This is run when first creating the object.
 
         Parameters
         ----------
-        file_name : str
-           The filename of the  diva dataset.
-        channel_group : str
-           The name of the netCDF4 group that holds the channel data.
+        channel_name : str
+           Name of the group
+        group : netCDF4.Group object
+           An open netcdf group to initialize.
         """
-        self.file_name = file_name
-        self.channel_group = channel_group
+        self.group_name = channel_name
 
+        self.
+
--- a/atmospheric_lidar/licel.py	Fri Oct 19 14:13:33 2018 +0300
+++ b/atmospheric_lidar/licel.py	Fri Nov 02 13:23:53 2018 +0200
@@ -7,7 +7,7 @@
 import pytz
 
 from .generic import BaseLidarMeasurement, LidarChannel
-from .diva import DivaMixin
+from .diva import DivaConverterMixin
 
 logger = logging.getLogger(__name__)
 
@@ -608,5 +608,6 @@
                                                                     channel.analog_photon_string, channel.resolution,
                                                                     channel.points))
 
-class LicelDivaLidarMeasurement(DivaMixin, LicelLidarMeasurement):
+
+class LicelDivaLidarMeasurement(DivaConverterMixin, LicelLidarMeasurement):
     pass
\ No newline at end of file

mercurial