Support of naming channels by order. In principle should not be required.

Fri, 14 Feb 2020 12:38:45 +0200

author
Ioannis <ioannis@inoe.ro>
date
Fri, 14 Feb 2020 12:38:45 +0200
changeset 186
97cabcc90f93
parent 185
44fabea9c60d
child 187
cfd92f537751

Support of naming channels by order. In principle should not be required.

atmospheric_lidar/licel.py file | annotate | diff | comparison | revisions
atmospheric_lidar/licelv2.py file | annotate | diff | comparison | revisions
atmospheric_lidar/raymetrics.py file | annotate | diff | comparison | revisions
--- a/atmospheric_lidar/licel.py	Tue Dec 10 13:24:02 2019 +0200
+++ b/atmospheric_lidar/licel.py	Fri Feb 14 12:38:45 2020 +0200
@@ -17,7 +17,7 @@
 class LicelChannelData:
     """ A class representing a single channel found in a single Licel file."""
 
-    def __init__(self, raw_info, raw_data, duration, use_id_as_name=False):
+    def __init__(self, raw_info, raw_data, duration, use_id_as_name=False, channel_name=None):
         """
         This is run when creating a new object.
 
@@ -32,11 +32,14 @@
         use_id_as_name : bool
            If True, the transient digitizer name (e.g. BT0) is used as a channel
            name. If False, a more descriptive name is used (e.g. '01064.o_an').
+        channel_name : str or None
+           If provided, it will override the automatic generated channel name. It can be used if names are not unique.
         """
         self.raw_info = raw_info
         self.raw_data = raw_data
         self.duration = duration
         self.use_id_as_name = use_id_as_name
+        self.channel_name_input = channel_name
         self._assign_properties()
 
     def _assign_properties(self):
@@ -90,6 +93,9 @@
         channel_name : str
            The channel name
         """
+        if self.channel_name_input is not None:
+            return self.channel_name_input
+
         if self.use_id_as_name:
             channel_name = self.id
         else:
@@ -168,7 +174,7 @@
     # If True, it corrects the old Raymetrics convention of zenith angle definition (zenith = -90 degrees)
     fix_zenith_angle = False
 
-    def __init__(self, file_path, use_id_as_name=False, licel_timezone="UTC", import_now=True):
+    def __init__(self, file_path, use_id_as_name=False, get_name_by_order=False, licel_timezone="UTC", import_now=True):
         """
         This is run when creating a new object.
 
@@ -179,6 +185,9 @@
         use_id_as_name : bool
            If True, the transient digitizer name (e.g. BT0) is used as a channel
            name. If False, a more descriptive name is used (e.g. '01064.o_an').
+        get_name_by_order : bool
+           If True, the channel name is given by the order of the channel in the file. In this case the
+           `use_id_as_name` variable is ignored.
         licel_timezone : str
            The timezone of dates found in the Licel files. Should match the available
            timezones in the TZ database.
@@ -191,6 +200,7 @@
         self.file_name = os.path.basename(file_path)
 
         self.use_id_as_name = use_id_as_name
+        self.get_name_by_order = get_name_by_order
         self.start_time = None
         self.stop_time = None
         self.licel_timezone = licel_timezone
@@ -214,7 +224,7 @@
             f.readline()
 
             # Import the data
-            for current_channel_info in self.channel_info:
+            for channel_no, current_channel_info in enumerate(self.channel_info):
                 raw_data = np.fromfile(f, 'i4', int(current_channel_info['number_of_datapoints']))
                 a = np.fromfile(f, 'b', 1)
                 b = np.fromfile(f, 'b', 1)
@@ -223,8 +233,13 @@
                     logger.warning("No end of line found after record. File could be corrupt: %s" % self.file_path)
                     logger.warning('a: {0}, b: {1}.'.format(a, b))
 
+                if self.get_name_by_order:
+                    channel_name = channel_no
+                else:
+                    channel_name = None
+
                 channel = self.channel_data_class(current_channel_info, raw_data, self.duration(),
-                                                  use_id_as_name=self.use_id_as_name)
+                                                  use_id_as_name=self.use_id_as_name, channel_name=channel_name)
 
                 # Assign the channel either as normal channel or photodiode
                 if channel.is_photodiode:
@@ -488,12 +503,13 @@
     channel_class = LicelChannel
     photodiode_class = PhotodiodeChannel
 
-    def __init__(self, file_list=None, use_id_as_name=False, licel_timezone='UTC'):
+    def __init__(self, file_list=None, use_id_as_name=False, get_name_by_order=False, licel_timezone='UTC'):
         self.raw_info = {}  # Keep the raw info from the files
         self.durations = {}  # Keep the duration of the files
         self.laser_shots = []
 
         self.use_id_as_name = use_id_as_name
+        self.get_name_by_order = get_name_by_order
         self.licel_timezone = licel_timezone
         self.photodiodes = {}
 
@@ -506,6 +522,7 @@
         else:
             logger.debug('Importing file {0}'.format(filename))
             current_file = self.file_class(filename, use_id_as_name=self.use_id_as_name,
+                                           get_name_by_order=self.get_name_by_order,
                                            licel_timezone=self.licel_timezone)
             self.raw_info[current_file.file_path] = current_file.raw_info
             self.durations[current_file.file_path] = current_file.duration()
--- a/atmospheric_lidar/licelv2.py	Tue Dec 10 13:24:02 2019 +0200
+++ b/atmospheric_lidar/licelv2.py	Fri Feb 14 12:38:45 2020 +0200
@@ -132,7 +132,7 @@
     # If True, it corrects the old Raymetrics convention of zenith angle definition (zenith = -90 degrees)
     fix_zenith_angle = False
 
-    def __init__(self, file_path, licel_timezone="UTC", import_now=True):
+    def __init__(self, file_path, licel_timezone="UTC", get_name_by_order=False, import_now=True):
         """
         This is run when creating a new object.
 
@@ -150,6 +150,7 @@
         """
         super(LicelFileV2, self).__init__(file_path=file_path,
                          use_id_as_name=False,  # Obsolete
+                         get_name_by_order=get_name_by_order,
                          licel_timezone=licel_timezone,
                          import_now=import_now)
 
@@ -316,12 +317,13 @@
     powermeter_class = PhotodiodeChannel
     standard_deviation_class = LicelV2Channel
 
-    def __init__(self, file_list=None, licel_timezone='UTC'):
+    def __init__(self, file_list=None, get_name_by_order=False, licel_timezone='UTC'):
 
         self.standard_deviations = {}
         self.powermeters = {}
 
         super(LicelLidarMeasurementV2, self).__init__(file_list=file_list,
+                                                      get_name_by_order=get_name_by_order,
                                                       use_id_as_name=False,
                                                       licel_timezone=licel_timezone)
 
--- a/atmospheric_lidar/raymetrics.py	Tue Dec 10 13:24:02 2019 +0200
+++ b/atmospheric_lidar/raymetrics.py	Fri Feb 14 12:38:45 2020 +0200
@@ -66,6 +66,7 @@
     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'
 
     fix_zenith_angle = True
+    skip_scan_overview_line = False  # Skip the 3d line containing azimuth_start, stop etc. Used to overcome a bug in some output files.
 
     def _read_rest_of_header(self, f):
         """ Read the third and fourth row of  of the header lines.
@@ -97,13 +98,23 @@
         self.azimuth_angle_raw = float(self.raw_info['azimuth_angle'])
         self.temperature = float(self.raw_info['temperature'])
         self.pressure = float(self.raw_info['pressure'])
-        self.azimuth_start_raw = float(self.raw_info['azimuth_start'])
-        self.azimuth_stop_raw = float(self.raw_info['azimuth_stop'])
-        self.azimuth_step = float(self.raw_info['azimuth_step'])
-        self.zenith_start_raw = float(self.raw_info['zenith_start'])
-        self.zenith_stop_raw = float(self.raw_info['zenith_stop'])
-        self.zenith_step = float(self.raw_info['zenith_step'])
-        self.azimuth_offset = float(self.raw_info['azimuth_offset'])
+
+        if not self.skip_scan_overview_line:
+            self.azimuth_start_raw = float(self.raw_info['azimuth_start'])
+            self.azimuth_stop_raw = float(self.raw_info['azimuth_stop'])
+            self.azimuth_step = float(self.raw_info['azimuth_step'])
+            self.zenith_start_raw = float(self.raw_info['zenith_start'])
+            self.zenith_stop_raw = float(self.raw_info['zenith_stop'])
+            self.zenith_step = float(self.raw_info['zenith_step'])
+            self.azimuth_offset = float(self.raw_info['azimuth_offset'])
+        else:
+            self.azimuth_start_raw = np.nan
+            self.azimuth_stop_raw = np.nan
+            self.azimuth_step = np.nan
+            self.zenith_start_raw = np.nan
+            self.zenith_stop_raw = np.nan
+            self.zenith_step = np.nan
+            self.azimuth_offset = 0
 
         self.azimuth_angle = (self.azimuth_angle_raw + self.azimuth_offset) % 360
         self.azimuth_start = (self.azimuth_start_raw + self.azimuth_offset) % 360
@@ -690,6 +701,10 @@
         return lat_out, lon_out, Z
 
 
+class ScanningFileMissingLine(ScanningFile):
+    skip_scan_overview_line = True
+
+
 class ScanningLidarMeasurement(LicelLidarMeasurement):
     """ A class representing a scanning measurement set.
 

mercurial