atmospheric_lidar/scripts/licel2scc_depol.py

Thu, 13 Sep 2018 14:15:34 +0300

author
Iannis B <ioannis@inoe.ro>
date
Thu, 13 Sep 2018 14:15:34 +0300
changeset 155
4a596849c721
parent 107
2f3f75e5b99e
child 160
db28629317fa
permissions
-rw-r--r--

Merge from 151:d89be5efc39c

ulalume3@64 1 """ Command line tool to convert Licel binary files to SCC NetCDF format.
ulalume3@64 2 """
ulalume3@64 3 import argparse
ulalume3@64 4 import glob
ulalume3@64 5 import importlib
ulalume3@64 6 import logging
ulalume3@64 7 import os
ulalume3@64 8 import sys
ulalume3@64 9
ulalume3@64 10 from ..licel_depol import LicelCalibrationMeasurement
ulalume3@67 11 from ..__init__ import __version__
ulalume3@64 12
i@103 13 logger = logging.getLogger(__name__)
i@103 14
ulalume3@64 15
i@101 16 def create_custom_class(custom_netcdf_parameter_path, use_id_as_name=False, temperature=25., pressure=1020.,
i@101 17 licel_timezone='UTC'):
ulalume3@64 18 """ This funtion creates a custom LicelLidarMeasurement subclass,
ulalume3@64 19 based on the input provided by the users.
ulalume3@64 20
ulalume3@64 21 Parameters
ulalume3@64 22 ----------
i@103 23 custom_netcdf_parameter_path : str
ulalume3@64 24 The path to the custom channels parameters.
i@103 25 use_id_as_name : bool
ulalume3@64 26 Defines if channels names are descriptive or transient digitizer IDs.
i@103 27 temperature : float
ulalume3@64 28 The ground temperature in degrees C (default 25.0).
i@103 29 pressure : float
ulalume3@64 30 The ground pressure in hPa (default: 1020.0).
i@101 31 licel_timezone : str
i@101 32 String describing the timezone according to the tz database.
ulalume3@64 33
ulalume3@64 34 Returns
ulalume3@64 35 -------
ulalume3@64 36 CustomLidarMeasurement:
ulalume3@64 37 A custom sub-class of LicelLidarMeasurement
ulalume3@64 38 """
ulalume3@64 39
ulalume3@64 40 custom_netcdf_parameters = read_settings_file(custom_netcdf_parameter_path)
ulalume3@64 41
ulalume3@64 42 class CustomLidarMeasurement(LicelCalibrationMeasurement):
ulalume3@64 43 extra_netcdf_parameters = custom_netcdf_parameters
ulalume3@64 44
ulalume3@69 45 def __init__(self, plus45_files=None, minus45_files=None):
i@101 46 super(CustomLidarMeasurement, self).__init__(plus45_files, minus45_files, use_id_as_name,
i@101 47 licel_timezone=licel_timezone)
ulalume3@64 48
ulalume3@92 49 def set_PT(self):
ulalume3@64 50 ''' Sets the pressure and temperature at station level. This is used if molecular_calc parameter is
ulalume3@64 51 set to 0 (i.e. use US Standard atmosphere).
ulalume3@64 52
ulalume3@64 53 The results are stored in the info dictionary.
ulalume3@64 54 '''
ulalume3@64 55
ulalume3@64 56 self.info['Temperature'] = temperature
ulalume3@64 57 self.info['Pressure'] = pressure
ulalume3@64 58
ulalume3@64 59 return CustomLidarMeasurement
ulalume3@64 60
ulalume3@64 61
ulalume3@64 62 def read_settings_file(settings_path):
ulalume3@64 63 """ Read the settings file.
ulalume3@64 64
ulalume3@64 65 The file should contain python code."""
ulalume3@64 66 if not os.path.isfile(settings_path):
ulalume3@64 67 logging.error("The provided settings path does not correspond to a file.")
ulalume3@64 68 sys.exit(1)
ulalume3@64 69
ulalume3@64 70 dirname, basename = os.path.split(settings_path)
ulalume3@64 71 sys.path.append(dirname)
ulalume3@64 72
ulalume3@64 73 module_name, _ = os.path.splitext(basename)
ulalume3@64 74 settings = importlib.import_module(module_name)
ulalume3@64 75 return settings
ulalume3@64 76
ulalume3@64 77
ulalume3@64 78 def main():
ulalume3@64 79 # Define the command line argument
ulalume3@68 80 parser = argparse.ArgumentParser(description="A program to convert Licel binary files from depolarization calibration measurements to the SCC NetCDF format.")
ulalume3@64 81 parser.add_argument("parameter_file", help="The path to a parameter file linking licel and SCC channels.")
ulalume3@69 82 parser.add_argument("plus45_string", help="Search string for plus 45 degree files")
ulalume3@69 83 parser.add_argument("minus45_string", help="Search string for minus 45 degree files")
ulalume3@64 84 parser.add_argument("-i", '--id_as_name',
ulalume3@64 85 help="Use transient digitizer ids as channel names, instead of descriptive names",
ulalume3@64 86 action="store_true")
ulalume3@64 87 parser.add_argument("-m", "--measurement_id", help="The new measurement id", default=None)
ulalume3@64 88 parser.add_argument("-n", "--measurement_number",
ulalume3@64 89 help="The measurement number for the date from 00 to 99. Used if no id is provided",
ulalume3@64 90 default="00")
ulalume3@64 91 parser.add_argument("-t", "--temperature", type=float,
ulalume3@64 92 help="The temperature (in C) at lidar level, required if using US Standard atmosphere",
ulalume3@64 93 default="25")
ulalume3@64 94 parser.add_argument("-p", "--pressure", type=float,
ulalume3@64 95 help="The pressure (in hPa) at lidar level, required if using US Standard atmosphere",
ulalume3@64 96 default="1020")
i@101 97 parser.add_argument('--licel_timezone', help="String describing the timezone according to the tz database.",
i@101 98 default="UTC", dest="licel_timezone",
i@101 99 )
ulalume3@64 100 # Verbosity settings from http://stackoverflow.com/a/20663028
ulalume3@64 101 parser.add_argument('-d', '--debug', help="Print dubuging information.", action="store_const",
ulalume3@64 102 dest="loglevel", const=logging.DEBUG, default=logging.INFO,
ulalume3@64 103 )
ulalume3@64 104 parser.add_argument('-s', '--silent', help="Show only warning and error messages.", action="store_const",
ulalume3@64 105 dest="loglevel", const=logging.WARNING
ulalume3@64 106 )
victor@106 107 parser.add_argument('-D', '--dark_measurements', help="Location of files containing dark measurements. Use relative path and filename wildcars, see 'files' parameter for example.",
victor@106 108 default="", dest="dark_files"
victor@106 109 )
ulalume3@67 110 parser.add_argument('--version', help="Show current version.", action='store_true')
ulalume3@64 111
ulalume3@64 112 args = parser.parse_args()
ulalume3@64 113
ulalume3@64 114 # Get the logger with the appropriate level
ulalume3@64 115 logging.basicConfig(format='%(levelname)s: %(message)s', level=args.loglevel)
ulalume3@64 116 logger = logging.getLogger(__name__)
ulalume3@64 117
ulalume3@64 118 #coloredlogs.install(fmt='%(levelname)s: %(message)s', level=args.loglevel)
ulalume3@64 119
ulalume3@67 120 if args.version:
ulalume3@67 121 print("Version: %s" % __version__)
ulalume3@67 122 sys.exit(0)
ulalume3@67 123
ulalume3@64 124 # Get a list of files to convert
ulalume3@64 125 plus45_files = glob.glob(args.plus45_string)
ulalume3@64 126 minus45_files = glob.glob(args.minus45_string)
ulalume3@64 127
ulalume3@64 128 if len(plus45_files)==0 or len(minus45_files)==0:
ulalume3@64 129 logger.error("No files found when searching for %s and %s." % (plus45_files, minus45_files))
ulalume3@64 130 sys.exit(1)
ulalume3@64 131
ulalume3@64 132 # Read the files
ulalume3@64 133 logger.info("Reading {0} files from {1}".format(len(plus45_files), args.plus45_string))
ulalume3@64 134 logger.info("Reading {0} files from {1}".format(len(minus45_files), args.minus45_string))
ulalume3@64 135
ulalume3@64 136 CustomLidarMeasurement = create_custom_class(args.parameter_file, args.id_as_name, args.temperature,
i@101 137 args.pressure, args.licel_timezone)
ulalume3@64 138
ulalume3@64 139 measurement = CustomLidarMeasurement(plus45_files, minus45_files)
victor@106 140
victor@106 141 # Get a list of files containing dark measurements
victor@106 142 if args.dark_files != "":
victor@106 143 dark_files = glob.glob(args.dark_files)
victor@106 144
victor@106 145 if dark_files:
victor@106 146 logger.debug("Using %s as dark measurements files!" % ', '.join(dark_files))
victor@106 147 measurement.dark_measurement = CustomLidarMeasurement(dark_files, dark_files)
victor@106 148 else:
victor@106 149 logger.warning('No dark measurement files found when searching for %s. Will not use any dark measurements.' % args.dark_files)
ulalume3@64 150
ulalume3@64 151 try:
ulalume3@64 152 measurement = measurement.subset_by_scc_channels()
ulalume3@64 153 except ValueError as err:
ulalume3@64 154 logging.error(err)
ulalume3@64 155 sys.exit(1)
ulalume3@64 156
ulalume3@64 157 # Save the netcdf
ulalume3@64 158 logger.info("Saving netcdf")
ulalume3@64 159 measurement.set_measurement_id(args.measurement_id, args.measurement_number)
ulalume3@92 160 measurement.save_as_SCC_netcdf()
ulalume3@64 161 logger.info("Created file %s" % measurement.scc_filename)

mercurial