atmospheric_lidar/scripts/licel2scc.py

Thu, 16 Feb 2017 16:35:42 +0200

author
Ioannis <ioannis@inoe.ro>
date
Thu, 16 Feb 2017 16:35:42 +0200
changeset 55
e1961b511b3d
parent 54
357138ffbeaf
child 56
853ab74421c1
permissions
-rw-r--r--

Added logging and collored logging through CLI.

ioannis@48 1 """ Command line tool to convert Licel binary files to SCC NetCDF format.
ioannis@48 2 """
ioannis@55 3 import argparse
ioannis@55 4 import glob
ioannis@55 5 import importlib
ioannis@55 6 import logging
ioannis@48 7 import os
ioannis@48 8 import sys
ioannis@55 9
ioannis@55 10 import coloredlogs
ioannis@48 11
ioannis@48 12 from ..licel import LicelLidarMeasurement
ioannis@48 13
ioannis@48 14
ioannis@48 15 def create_custom_class(custom_netcdf_parameter_path, use_id_as_name=False, temperature=25., pressure=1020.):
ioannis@48 16 """ This funtion creates a custom LicelLidarMeasurement subclass,
ioannis@48 17 based on the input provided by the users.
ioannis@48 18
ioannis@48 19 Parameters
ioannis@48 20 ----------
ioannis@48 21 custom_netcdf_parameter_path: str
ioannis@48 22 The path to the custom channels parameters.
ioannis@48 23 use_id_as_name: bool
ioannis@48 24 Defines if channels names are descriptive or transient digitizer IDs.
ioannis@48 25 temperature: float
ioannis@48 26 The ground temperature in degrees C (default 25.0).
ioannis@48 27 pressure: float
ioannis@48 28 The ground pressure in hPa (default: 1020.0).
ioannis@48 29
ioannis@48 30 Returns
ioannis@48 31 -------
ioannis@48 32 CustomLidarMeasurement:
ioannis@48 33 A custom sub-class of LicelLidarMeasurement
ioannis@48 34 """
ioannis@48 35
ioannis@48 36 custom_netcdf_parameters = read_settings_file(custom_netcdf_parameter_path)
ioannis@48 37
ioannis@48 38 class CustomLidarMeasurement(LicelLidarMeasurement):
ioannis@48 39 extra_netcdf_parameters = custom_netcdf_parameters
ioannis@48 40
ioannis@48 41 def __init__(self, filelist=None):
ioannis@48 42 super(CustomLidarMeasurement, self).__init__(filelist, use_id_as_name)
ioannis@48 43
ioannis@48 44 def get_PT(self):
ioannis@48 45 ''' Sets the pressure and temperature at station level. This is used if molecular_calc parameter is
ioannis@48 46 set to 0 (i.e. use US Standard atmosphere).
ioannis@48 47
ioannis@48 48 The results are stored in the info dictionary.
ioannis@48 49 '''
ioannis@48 50
ioannis@48 51 self.info['Temperature'] = temperature
ioannis@48 52 self.info['Pressure'] = pressure
ioannis@48 53
ioannis@48 54 return CustomLidarMeasurement
ioannis@48 55
ioannis@48 56
ioannis@48 57 def read_settings_file(settings_path):
ioannis@48 58 """ Read the settings file.
ioannis@48 59
ioannis@48 60 The file should contain python code."""
ioannis@48 61 if not os.path.isfile(settings_path):
ioannis@48 62 raise IOError("The provided settings path does not correspond to a file.")
ioannis@48 63
ioannis@48 64 dirname, basename = os.path.split(settings_path)
ioannis@48 65 sys.path.append(dirname)
ioannis@48 66
ioannis@48 67 module_name, _ = os.path.splitext(basename)
ioannis@48 68 settings = importlib.import_module(module_name)
ioannis@48 69 return settings
ioannis@48 70
ioannis@48 71
ioannis@48 72 def main():
ioannis@48 73 # Define the command line argument
ioannis@48 74 parser = argparse.ArgumentParser(description="A program to convert LICEL binary files to the SCC NetCDF format.")
ioannis@48 75 parser.add_argument("parameter_file", help="The path to a parameter file linking licel and SCC channels.")
ioannis@48 76 parser.add_argument("directory", nargs='?', help="Directory containing licel files (default '.')", default='.')
ioannis@55 77 parser.add_argument("search_string", nargs='?', help="Search string for files in directory (default '*.*')",
ioannis@55 78 default="*.*")
ioannis@48 79 parser.add_argument("-i", '--id_as_name',
ioannis@48 80 help="Use transient digitizer ids as channel names, instead of descriptive names",
ioannis@48 81 action="store_true")
ioannis@48 82 parser.add_argument("-m", "--measurement_id", help="The new measurement id", default=None)
ioannis@48 83 parser.add_argument("-n", "--measurement_number",
ioannis@48 84 help="The measurement number for the date from 00 to 99. Used if no id is provided",
ioannis@48 85 default="00")
ioannis@48 86 parser.add_argument("-t", "--temperature", type=float,
ioannis@48 87 help="The temperature (in C) at lidar level, required if using US Standard atmosphere",
ioannis@48 88 default="25")
ioannis@48 89 parser.add_argument("-p", "--pressure", type=float,
ioannis@48 90 help="The pressure (in hPa) at lidar level, required if using US Standard atmosphere",
ioannis@48 91 default="1020")
ioannis@55 92 # Verbosity settings from http://stackoverflow.com/a/20663028
ioannis@55 93 parser.add_argument('-d', '--debug', help="Print dubuging information.", action="store_const",
ioannis@55 94 dest="loglevel", const=logging.DEBUG, default=logging.INFO,
ioannis@55 95 )
ioannis@55 96 parser.add_argument('-s', '--silent', help="Show processing information.", action="store_const",
ioannis@55 97 dest="loglevel", const=logging.WARNING
ioannis@55 98 )
ioannis@55 99
ioannis@48 100 args = parser.parse_args()
ioannis@48 101
ioannis@55 102 # Get the logger with the appropriate level
ioannis@55 103 #logging.basicConfig(format='%(levelname)s: %(message)s', level=args.loglevel)
ioannis@55 104 logger = logging.getLogger(__name__)
ioannis@55 105
ioannis@55 106 coloredlogs.install(fmt='%(levelname)s: %(message)s', level=args.loglevel)
ioannis@55 107
ioannis@48 108 # Get a list of files to convert
ioannis@48 109 search_str = os.path.join(args.directory, args.search_string)
ioannis@48 110 files = glob.glob(search_str)
ioannis@48 111
ioannis@48 112 if files:
ioannis@48 113 # Read the files
ioannis@55 114 logger.info("Reading {0} files from {1}".format(len(files), args.directory))
ioannis@48 115 CustomLidarMeasurement = create_custom_class(args.parameter_file, args.id_as_name, args.temperature,
ioannis@48 116 args.pressure)
ioannis@48 117 measurement = CustomLidarMeasurement(files)
ioannis@55 118 try:
ioannis@55 119 measurement = measurement.subset_by_scc_channels()
ioannis@55 120 except ValueError as err:
ioannis@55 121 logging.error(err)
ioannis@55 122 sys.exit(1)
ioannis@48 123 # Save the netcdf
ioannis@55 124 logger.info("Saving netcdf")
ioannis@48 125 measurement.set_measurement_id(args.measurement_id, args.measurement_number)
ioannis@48 126 measurement.save_as_netcdf()
ioannis@55 127 logger.info("Created file %s" % measurement.scc_filename)
ioannis@48 128 else:
ioannis@55 129 logger.error("No files found when searching for %s." % search_str)
ioannis@55 130 sys.exit(1)

mercurial