#! /usr/bin/env python # -*- coding: latin-1 -*- ######################################################################################## # caltrack_browse_factory.py # # Description : This script build the browses of the calxtract products (variables issued of many sensors under the CALIOP subtrace) # # Ex : ./caltrack_browse_factory.py -i /home/pascal/DATA/CALXTRACT/calxtract_2007:01:03T00:10:31_2007:01:03T23:14:54.hdf -v # python caltrack_browse_factory.py -i /disk1/projets/pascal/calxtract/data/calxtract_2007-01-05T02-23-27ZD.hdf -v # # Usage : ./production_calxtract.py ... # # type ./production_calxtract.py --help for options details # # Input : # -i [MANDATORY] The full path to the input file (ie: a calxtract product) # -o The full path to the output file. If not precised, the output filename will be the input filename, with the ".hdf" extension replaced by "" # # Output : 0 if run end normally | 1 or 2 if something has gone wrong # # Warning : # - If the directory that contains the output file given in the command line arguments doesn't exist, the script will create it # # Limitations : # - # # Author : ICARE/CGTD/UDEV Nicolas PASCAL ######################################################################################## import os,os.path,glob,sys import re import tempfile from optparse import OptionParser import calendar import datetime, time from pyhdf import SD from pylab import * from matplotlib.dates import DateFormatter import numpy ##### APPLICATION ##### __VERSION__="0.0.0" __APP__="caltrack_browse_factory" __DEBUG__=False __RUN_PROCESS__=True ##### RETURN CODES ##### ERROR_FLAG_INPUTS=1 # command line or inputs error ERROR_FLAG_PROCESS=2 # error during the process ERROR_FLAG_GENERIC=3 # all other errors SUCCESS_PROCESS=0 # successful run return code ##### DEFAULT PATHES ##### DEFAULT_APP_DIR =os.environ['HOME']+"depot/calxtract/tools" # path to the application APP_NAME ="production_calxtract.py" # name of the application executable ##### EXCEPTIONS ##### BadCommandLineOption='BadCommandLineOption' ProcessError='ProcessError' ##### TIME CONSTANTS ##### # DAO time starts at 1993:01:01T00:00:00, and epoch one at 1970:01:01T00:00:00 -> difference of 23 years + 6 days for bissextile years ; 23.*365.*24.*3600.+(6.*24.*3600.)=725 846 400 sec. from 1970/01/01T00:00:00 to 1993/01/01T00:00:00 NB_SEC_EPOCH_2_TAI93=725846400 ##### name of the SDS to browse ##### latitude_sds="Latitude" # name of the sds that contains the latitude data longitude_sds="Longitude" # name of the sds that contains the longitude data time_sds="Time" # name of the sds that contains the time data # set the characteristics of the sds data : each entry is set like : "sds_name":[threshold_min, threshold_max] sds_to_browse={ # "Latitude":[-90.,90.], # "Longitude":[-180.,180.], # "S_hgt":[-1.,1.], # "Echo_hgt":[-1.,10.], "BT_IR":[250.,330.], "BT12":[250.,330.], # "BT10_6":[150.,350.], # "BT8_7":[150.,350.], "Nb_Cld_Layer_5km":[0,10], # "Cld_Cover":[-0.1,1.1], # "Po2":[0.,1000.], # "Pray":[0.,1000.], "Ct_Pressure":[0.,1000.], # "Opt_Th":[0.,100.], # "Cld_Ph":[230.,250.] } # set the browses order sds_order=[ # "Latitude", # "Longitude", # "S_hgt", # "Echo_hgt", "BT_IR", "BT12", # "BT10_6", # "BT8_7", "Nb_Cld_Layer_5km", # "Cld_Cover", # "Opt_Th", # "Po2", # "Pray", "Ct_Pressure", # "Cld_Ph" ] class CalxtractBrowseFactory: parser=OptionParser() # The command line options parser # lat=None # Array containing the latitudes along track # lon=None # Array containing the longitudes along track # s_lat_lon=None # Array containing the (lat,lon) as strings time=None # Array containing the times along track date=None # Array containing the times along track converted into datetime objects date_min=None date_max=None hdf=None # An opened SD interface to the input file ##### command line options ##### verbose=False # display processing informations overwrite=False # overwrite existing output files flag app_dir=DEFAULT_APP_DIR # directory that contains the application executable app_name=APP_NAME # name of the application executable infile=None # full path of the input file outfile=None # full path of the output file def __init__(self): """ Constructor. Parse the command line arguments if any """ if self.verbose: print "\n" print " ################################### "+__APP__+" ####################################" print " # #" print " # ICARE-CGTD #" print " # version "+__VERSION__+" #" print " #######################################################################################" # sets the available command line options self.init_prog_options() # check the command line options validity self.validate_options() if self.verbose: print " -------------------------------------- Parametres -------------------------------------" print " - -" print " - -Input- -" print " - Input file : "+self.infile print " - -" print " - -Output- -" print " - Output file : "+self.outfile print " ---------------------------------------------------------------------------------------" # run the process self.process() def process(self): """ The process can e split in the following actions : 1- Load the geolocation data (lat,lon,time) 2- Build the graphes of all sds we want to build the browse 3- Concatenate the different browses """ # open the SD interface self.hdf=SD.SD(self.infile) # load the lat,lon,time data self.load_geolocation_data() # build the graphes self.build_browse() def load_geolocation_data(self): """ Read the lat, lon, time data """ if self.verbose: print "Load the geolocation data" # read the latitudes # sds=self.hdf.select(latitude_sds) # self.lat=sds.get() # # read the longitudes # sds=self.hdf.select(longitude_sds) # self.lon=sds.get() # read the times sds=self.hdf.select(time_sds) self.time=sds.get( start=(2304),count=(121) ) self.date=[] for t in self.time: d=datetime.datetime.fromtimestamp(t+NB_SEC_EPOCH_2_TAI93) self.date.append(date2num(d)) # use pylab time convention self.date_min=amin(self.date) self.date_max=amax(self.date) # self.s_lat_lon=[] # # build the array used as axis graduation # for i in range(len(self.lat)): # self.s_lat_lon.append("("+str(self.lat[i])+","+str(self.lon[i])+")") def build_browse(self): """ Build the graph of all sds """ # initialize the browse figure(1) # build the graphes of 1D SDS # sds_to_browse={"S_hgt":[0.,10.]} i_graph=1 # index of each drown graph nb_var=len(sds_to_browse) for sds_name in sds_order: if self.verbose: print "Draw the browse of "+sds_name limits=sds_to_browse[sds_name] # init the graph p=subplot(nb_var,1,i_graph) # add the titles if p.is_first_row(): title("CALXTRACT DATA ("+self.infile[-23:-4]+")") # load the sds data sds=self.hdf.select(sds_name) data=numpy.clip(sds.get(start=(2304),count=(121)),limits[0],limits[1]) # plot the data # plot(self.s_lat_lon, data) # plot the dates using a formatter date_formatter=DateFormatter("%H") plot_date(self.date,data, "b:.",markersize=5, markerfacecolor="r", markeredgecolor="b") p.xaxis.set_major_formatter(date_formatter) # rotate the x ticks labels xticks=p.get_xticklabels() setp(xticks,fontsize=8) yticks=p.get_yticklabels() setp(yticks,fontsize=8) # add the labels ylabel(sds_name,fontsize=8) grid(True) # set the axis range axis([self.date_min,self.date_max,limits[0],limits[1]]) if p.is_last_row(): xlabel("time (hour)",fontsize=8) i_graph+=1 show() ############################ ### COMMAND LINE PARSING ### ############################ def init_prog_options(self): """ Sets the available program options, and their default values """ self.parser.add_option("-i","--input_file", action="store", default="", type="string",dest="infile",help="An input file issued of calxtract") self.parser.add_option("-o","--output_file", action="store", default="", type="string",dest="outfile",help="The output file") self.parser.add_option("-v", "--verbose", action="store_true", dest="verbose", \ help="Print out processing informations") self.parser.add_option("-x", "--overwrite", action="store_true", dest="overwrite", \ help="Overwrite existing files") # check the number of command line arguments if len(sys.argv)<3: self.parser.print_help() msg="\nNot enough command-line options\n" raise BadCommandLineOption,msg # parse the command line arguments (options, args) = self.parser.parse_args() # set program options self.outfile=options.outfile self.infile=options.infile self.verbose=options.verbose self.overwrite=options.overwrite def validate_options(self): """ Check if the command line options are valid. If not, throws an exception describing the problem """ if (self.infile==None or self.infile=="" or not os.path.exists(self.infile)): msg="Invalid input file : "+self.infile raise BadCommandLineOption,msg if (self.outfile==None or self.outfile==""): # set a default output file self.outfile=os.path.splitext(self.infile)[0]+".png" # if the output file directory doesn't exist, create it output_dir=os.path.dirname(self.outfile) if (not os.path.exists(output_dir)): print "The output file directory "+output_dir+" doesn't exist -> create it\n" os.makedirs(output_dir) """ Main script """ def main(): # parse command line options try: print "\n ---------- CALTRACK BROWSE FACTORY SCRIPT -------------\n" prog=CalxtractBrowseFactory() except BadCommandLineOption,msg: print msg print " ---------- end of CALTRACK BROWSE FACTORY with status "+str(ERROR_FLAG_INPUTS)+" -------------" sys.exit(ERROR_FLAG_INPUTS) except ProcessError,msg: print msg print " ---------- end of CALTRACK BROWSE FACTORY with status "+str(ERROR_FLAG_PROCESS)+" -------------" sys.exit(ERROR_FLAG_PROCESS) except : print " ---------- end of CALTRACK BROWSE FACTORY with status "+str(ERROR_FLAG_GENERIC)+" -------------" sys.exit(ERROR_FLAG_GENERIC) # all works good print " ---------- end of CALTRACK BROWSE FACTORY with status "+str(SUCCESS_PROCESS)+" -------------" sys.exit(SUCCESS_PROCESS) if __name__ == "__main__": main()