atmospheric_lidar/scripts/licel2scc.py

Sun, 26 Feb 2017 22:28:30 +0200

author
Iannis <ulalume3@yahoo.com>
date
Sun, 26 Feb 2017 22:28:30 +0200
changeset 64
6d6512752932
parent 58
c97f146dfa32
child 66
51b799247d67
permissions
-rw-r--r--

Licel2scc calibration measurement.

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@48 10
ioannis@48 11 from ..licel import LicelLidarMeasurement
ioannis@48 12
ioannis@48 13
ioannis@48 14 def create_custom_class(custom_netcdf_parameter_path, use_id_as_name=False, temperature=25., pressure=1020.):
ioannis@48 15 """ This funtion creates a custom LicelLidarMeasurement subclass,
ioannis@48 16 based on the input provided by the users.
ioannis@48 17
ioannis@48 18 Parameters
ioannis@48 19 ----------
ioannis@48 20 custom_netcdf_parameter_path: str
ioannis@48 21 The path to the custom channels parameters.
ioannis@48 22 use_id_as_name: bool
ioannis@48 23 Defines if channels names are descriptive or transient digitizer IDs.
ioannis@48 24 temperature: float
ioannis@48 25 The ground temperature in degrees C (default 25.0).
ioannis@48 26 pressure: float
ioannis@48 27 The ground pressure in hPa (default: 1020.0).
ioannis@48 28
ioannis@48 29 Returns
ioannis@48 30 -------
ioannis@48 31 CustomLidarMeasurement:
ioannis@48 32 A custom sub-class of LicelLidarMeasurement
ioannis@48 33 """
ioannis@48 34
ioannis@48 35 custom_netcdf_parameters = read_settings_file(custom_netcdf_parameter_path)
ioannis@48 36
ioannis@48 37 class CustomLidarMeasurement(LicelLidarMeasurement):
ioannis@48 38 extra_netcdf_parameters = custom_netcdf_parameters
ioannis@48 39
ioannis@48 40 def __init__(self, filelist=None):
ioannis@48 41 super(CustomLidarMeasurement, self).__init__(filelist, use_id_as_name)
ioannis@48 42
ioannis@48 43 def get_PT(self):
ioannis@48 44 ''' Sets the pressure and temperature at station level. This is used if molecular_calc parameter is
ioannis@48 45 set to 0 (i.e. use US Standard atmosphere).
ioannis@48 46
ioannis@48 47 The results are stored in the info dictionary.
ioannis@48 48 '''
ioannis@48 49
ioannis@48 50 self.info['Temperature'] = temperature
ioannis@48 51 self.info['Pressure'] = pressure
ioannis@48 52
ioannis@48 53 return CustomLidarMeasurement
ioannis@48 54
ioannis@48 55
ioannis@48 56 def read_settings_file(settings_path):
ioannis@48 57 """ Read the settings file.
ioannis@48 58
ioannis@48 59 The file should contain python code."""
ioannis@48 60 if not os.path.isfile(settings_path):
ioannis@58 61 logging.error("The provided settings path does not correspond to a file.")
ioannis@58 62 sys.exit(1)
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@56 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@56 96 parser.add_argument('-s', '--silent', help="Show only warning and error messages.", 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@58 103 logging.basicConfig(format='%(levelname)s: %(message)s', level=args.loglevel)
ioannis@55 104 logger = logging.getLogger(__name__)
ioannis@55 105
ioannis@58 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