# -*- coding: utf-8 -*- #!/usr/local/bin/python """ Description : ------------- Verification options and arguments from the command line Usage : ------- Example : --------- Prerequisites : --------------- python >= 2.5 ; not tested but probably all versions Numpy Author : -------- CGTD-ICARE/UDEV Nicolas THOMAS ( nicolas.thomas-at-icare.univ-lille1.fr ) License : --------- This file must be used under the terms of the CeCILL. This source file is licensed as described in the file COPYING, which you should have received as part of this distribution. The terms are also available at http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt History : --------- v0.0.0 : 2009/12/01 - creation """ import re import os import sys from numpy import * from optparse import OptionParser from calendar import * from PcfReader import PcfReader from pyhdf.SD import* import warnings warnings.filterwarnings("ignore") from datetime import * def prog_options( list_parameters ): usage = "usage : %prog Input_files [options]" parser = OptionParser(usage) parser.usage = "Average_processor.py [options]" parser.usage+="\n\nArgs:" parser.usage+="\n Some examples of HDF files :" parser.usage+="\n for SEVIRI : SEVIRI_AER_OC_20090901.0600.hdf" parser.usage+="\n for PARASOL : ATM_ANG_D_0803.hdf" parser.usage+="\n for MODIS : MYD08_D3.A2008362.005.2008364073240.hdf\n" parser.usage+="\n" parser.usage+="Some examples to use the program :\n" parser.usage+="\t python Average_processor.py ATM_ANG_D_0801.hdf ATM_ANG_D_0802.hdf -b 2008-01-09 -c 2008-02-15 -r PARASOL will produce the browses during a given period at daily between 2008/01/09 and 2008/02/15 for the variable Angstrom Exponent product PR_ATM, Sensor PARASOL\n" parser.usage+="\n" parser.usage+="\t python Average_processor.py ATM_TAUA_D_0812.hdf ATM_TAUA_D_0901.hdf will produce the browses for a period up to the monthly or seasonal scale (Ex :2008-12 2009-01) for the variable Aerosol Optical Thickness at 865 nm product PR_ATM, sensor PARASOL\n" parser.usage+="\n" parser.usage+="\t python Average_processor.py -d Aerosol_Optical_Depth SEVIRI_AER_OC_20080101.0600.hdf SEVIRI_AER_OC_20080101.0615.hdf SEVIRI_AER_OC_20080101.0630.hdf -r SEVIRI will produce the results between 06h and 06h30 for the 2008-01-01 for the variable Aerosol_Optical_Depth product AER_OC, sensor SEVIRI\n" parser.usage+="\n" parser.usage+="\t python Average_processor.py -d Effective_Radius_Ocean_Mean -r MODIS MYD08_D3.A2008363.005.2009015024325.hdf MYD08_D3.A2008361.005.2008363040147.hdf MYD08_D3.A2008364.005.2009013070810.hdf MYD08_D3.A2008362.005.2008364073240.hdf will produce the browses during a given period at daily between 2008/12/25 and 2008/12/29 for the variable Effective_Radius_Ocean_Mean product MYD08_D3, Sensor MODIS\n" parser.usage+="\n\nOptions :" parser.usage+="\n Subsetting's option : " parser.usage+="\n <-s row_min row_max col_min col_max> to select an interest area." parser.usage+="\n" parser.usage+="\n Maximum value's option :" parser.usage+="\n <-m 250> to choose the maximum value for the average image (not for SEVIRI)" parser.usage+="\n" parser.usage+="\n Minimum value's option :" parser.usage+="\n <-n 50> to choose the minimum value for the average image (not for SEVIRI)" parser.usage+="\n" parser.usage+="\n Fixed_Value :" parser.usage+="\n <-l name of fixed value> shows the fixed values and speeds up the computation time example: space and land values for SEVIRI ex : -l LAND_VAL,FAILED_VAL. It's different of fill value" parser.usage+="\n" parser.usage+="\n Hdf file compression :" parser.usage+="\n <-g> Use this option to disable compression" parser.usage+="\n Print program's informations :" parser.usage+="\n <-e> Use this option to print program's informations" parser.usage+="\n Additional statistics (standard deviation, min max per pixel:" parser.usage+="\n <-k> Use this option to disable obtain additional statistics" parser.usage+="\n Provides the statistical results to png file :" parser.usage+="\n <-y> Use this option to execute os.system() and obtain the results to png file" parser.add_option("-f", "--output_id",type="string",dest="output_id",default=None,help="give a prefix of output file for HDF, PCf or PNG format") parser.add_option("-s", "--subsetting",type="int",nargs=4,dest="subsetting",default=None, help="This option requires 4 arguments, row_min row_max col_min col_max") parser.add_option("-d", "--dataset",type="string",dest="dataset",default = None, help="This option is required if a dataset must be read in each HDF file to calculate the average, example : Aerosol_Optical_Depth or Angstrom_Exponent for Seviri") parser.add_option("-b","--date_start",type="string",dest="date_start",default = None, help="This option is useful to calculate the average in the case of variable product PR_ATM and must be written like this YYYY-MM-DD") parser.add_option("-c","--date_end",type="string",dest="date_end",default = None,help="This option is useful to calculate the average in the case of variable product PR_ATM and must be written like this YYYY-MM-DD") parser.add_option("-o","--output_directory",action="store", default=os.getcwd(), type="string",dest="output_directory",help="indicates an output directory") parser.add_option("-r","--sensor",type="string",dest="sensor",default = None,help="To specify the name of the sensor (PARASOL, MODIS...)") parser.add_option("-v","--prod_id",type="string",dest="prod_id",default = None, help="To specify the name of the product (PR_ATM,...)") parser.add_option("-m","--valmax",type="string",dest="valmax",action='store',default = None,help="In the case of Parasol sensor indicates the maximum value for range") parser.add_option("-n","--valmin",type="string",dest="valmin",action='store',default = None,help="In the case of Parasol sensor indicates the minimal value for range") parser.add_option("-g","--compress",dest="compress",action='store_false',default = True,help="hdf file compression") parser.add_option("-e","--verbose",dest="verbose",action='store_true',default = False,help="print program's informations") parser.add_option("-k","--stats",dest="stats",action='store_true',default = False,help="Extra statistics calculated (std, min max per pixel)") parser.add_option("-y","--command_line",dest="command_line",action='store_true',default = False,help="Execute os.system()") parser.add_option("-l","--fixed_value",dest="fixed_value",type="string",default = None,help="name of fill value, it is possible that the file has multiple values like SEVIRI (LAND_VAL,SPACE_VAL) ") parser.add_option("-p", "--step",type="int",nargs=1,dest="step",default=None,help="allows to choose the step of list of files") if len ( sys.argv ) < 2 : parser.print_help ( ) raise ValueError ( "\nMissing command-line options" ) (options, args) = parser.parse_args() if options.dataset is not None : if re.search(',',options.dataset): options.dataset=options.dataset.split(',') else : options.dataset=options.dataset.split() if re.search('.pcf',list_parameters[1]) : pcf_file=list_parameters[1] pcf_reader=PcfReader(pcf_file) key=pcf_reader.cfg_dic.keys() if str(pcf_reader.get('subsetting')[1:-1])!='None' : options.subsetting=str(pcf_reader.get('subsetting')[1:-1]) options.subsetting=options.subsetting.split(',') options.output_id=str(pcf_reader.get('output_id')[1:-1]) if str(pcf_reader.get('dataset')[1:-1])!='None' : options.dataset=str(pcf_reader.get('dataset')[1:-1]) if re.search(',',options.dataset): options.dataset=options.dataset.split(',') else : options.dataset=options.dataset.split() options.sensor=str(pcf_reader.get('sensor')[1:-1]) options.date_end=str(pcf_reader.get('date_end')[1:-1]) options.date_start=str(pcf_reader.get('date_start')[1:-1]) options.prod_id=str(pcf_reader.get('prod_id')[1:-1]) if str(pcf_reader.get('fixed_value')[1:-1])!='None' : options.fixed_value=str(pcf_reader.get('fixed_value')[1:-1]) if str(pcf_reader.get('valmax')[1:-1])!='None' : options.valmax=str(pcf_reader.get('valmax')[1:-1]) if str(pcf_reader.get('valmin')[1:-1])!='None' : options.valmin=str(pcf_reader.get('valmin')[1:-1]) args=pcf_reader.v_get('Input_files') if str(pcf_reader.get('compress')[1:-1])!='True' : options.compress=False if str(pcf_reader.get('verbose')[1:-1])!='False' : options.verbose=True if str(pcf_reader.get('stats')[1:-1])!='False' : options.stats=True if str(pcf_reader.get('command_line')[1:-1])!='False' : options.stats=True if options.sensor is None : msg="Error : the sensor's name must be indicated. Example : -r SEVIRI, -r PARASOL, -r MODIS, ..." raise ValueError(msg) val_max=options.valmax val_min=options.valmin if val_max != None and val_min != None and int(val_min)>=int(val_max) : msg='val_min is greater than or equal to val_max' raise ValueError(msg) if options.verbose is True : print "Sensor : %s, Prod_id : %s, Date_start : %s, Date_end : %s, Filename : %s, Subsetting : %s, Dataset : %s, Output directory : %s, Valmax : %s, Valmin : %s, Compression : %s, Verbose : %s, Stats : %s, Command_line : %s, Step : %s"%(options.sensor,options.prod_id,options.date_start,options.date_end,options.output_id,options.subsetting,options.dataset,options.output_directory,options.valmax,options.valmin,options.compress,options.verbose,options.stats,options.command_line,options.step) print "\n" return options,args # #_____________________________________________________ # def get_input_files (args,options) : input_files=[] if len(options.dataset)>1 : i=0 for name in args : test=os.path.exists(name) if test==True : input_files.append(name) else : del options.dataset[i] i+=1 else : for name in args : test=os.path.exists(name) if test==True : input_files.append(name) args=input_files if len(args)==0. : raise ValueError ( "Not file found") if len(args)==1. : raise ValueError ( "not enough files to compute statistic") if options.step is not None : s=range(1,len(args),options.step) args=delete(args,s) if len(args)==0. : raise ValueError ( "Not file found") if len(args)==1. : raise ValueError ( "not enough files to compute statistic") if options.verbose is True : print 'args :',args return args,options.dataset # #_____________________________________________________ # def get_name_sds(options,args): if options.dataset is None : hdf_name=args[0] hdf_file = SD(hdf_name) sds_name=hdf_file.datasets().keys()[0] else : sds_name=options.dataset[0] if len(options.dataset) == 1 : hdf_name=args[0] hdf_file = SD(hdf_name) datasets=hdf_file.datasets().keys() chaine=[] for name in datasets : chaine=append(chaine,name) if str(name)==str(sds_name): NAME=True break else : NAME=False if NAME is not True : msg="Error : the dataset's name ("+str(sds_name)+ ")is not correct, it must be one of them :"+str(chaine) raise ValueError(msg) if options.verbose is True : print "sds_name :",sds_name print "\n" return sds_name # #_____________________________________________________ # def get_read(options,args): data_read={} size=len(options.dataset) if size == 1 : for file in args : data_read[file]=options.dataset else : i=0 for file in args: if i==0 : data_read[file]=options.dataset[i] else : if args[i]==args[i-1] : data_read[file]+=' '+options.dataset[i] else : data_read[file]=options.dataset[i] i+=1 d=data_read.values() l=len(d) for i in range(0,l) : data_read[data_read.keys()[i]]=d[i].split(' ') return data_read # #_____________________________________________________ # def image_size(args,sds_name,options): if not re.search('.hdf',args[0]): msg="Invalid parameter : no parameter input is a file .hdf" raise ValueError(msg) hdf_name=args[0] hdf_file = SD(hdf_name) sds=hdf_file.select(sds_name).get() lin,col=sds.shape if options.verbose is True : print "\n" print "sds read for informations:",sds_name print "image's size : rows=",lin," cols=",col return lin,col # #_____________________________________________________ # def subsetting(options,lin,col): coordinates=options.subsetting if coordinates == None : coordinates=[0,int(lin),0,int(col)] #____ SUBSETTING ___ row_min=int(coordinates[0]) row_max=int(coordinates[1]) col_min=int(coordinates[2]) col_max=int(coordinates[3]) if row_min<0 or row_min>int(lin) : msg="Invalid coordinate : row_min must be between 0 and "+str(lin)+" row_min="+str(row_min) raise ValueError(msg) if row_max<0 or row_max>int(lin) : msg="Invalid coordinate : row_max must be between 0 and "+str(lin)+" row_max="+str(row_max) raise ValueError(msg) if col_min<0 or col_min>int(col): msg="Invalid coordinate : col_min must be between 0 and "+str(col)+" col_min="+str(col_min) raise ValueError(msg) if col_max<0 or col_max>int(col): msg="Invalid coordinate : col_max must be between 0 and "+str(col)+" col_max="+str(col_max) raise ValueError(msg) if row_min>=row_max or col_min>=col_max: msg="Invalid coordinates : row_min >= row_max or col_min >= col_max row_min="+str(row_min)+" row_max="+str(row_max)+" col_min="+str(col_min)+" col_max="+str(col_max) raise ValueError(msg) return row_min,row_max,col_min,col_max # #_____________________________________________________ # def get_data_read (data_read): input_files={} liste='' for name in sort(data_read.keys()) : f=name.split('/')[-1] liste+=str(f)+'\n' nb_car=len(liste) max_car=65000. nb_chunk=ceil(nb_car / max_car) if nb_chunk < 2 : name='input_files' input_files[name]=liste else : for i in range(0,int(nb_chunk)): i+=1 name='input_files_chunk_'+str(i) input_files[name]=[] if len(liste)>int(max_car) : for j in flipud( range (0,int(max_car) ) ): if liste[j]== '\n' : break input_files[name]=liste[:j] liste=liste[j+1:] else : input_files[name]=liste return input_files # # def mean_2_hdf(SDS,attributes_list,data_read,options,out_val_list): if options.output_id is None : filename=options.output_directory+'/'+options.sensor+'.hdf' else : filename=options.output_directory+'/'+options.output_id+'.hdf' if os.path.exists(filename): filehdf=SD(filename, SDC.WRITE|SDC.TRUNC) else:filehdf=SD(filename, SDC.WRITE|SDC.CREATE) list_name=data_read.keys()[0].split('/') setattr(filehdf,'File Creation Date',date.today().strftime("%A %d. %B %Y")) setattr(filehdf,'Author','ICARE C.G.T.D') setattr(filehdf,'HDFEOSVersion',str('HDF4')) setattr(filehdf,'Sensor',str(list_name[3])) setattr(filehdf,'Product identification',str(list_name[4])) input_files=get_data_read (data_read) for name in input_files : setattr(filehdf,name,input_files[name]) sds_Keys=attributes_list['sds'] if options.dataset >1 and str(list_name[4]) == 'PR_ATM' : options.dataset=data_read.values()[0][0][:-2] else : options.dataset=options.dataset[0] for keys in SDS : name=options.dataset+'_'+keys #S=SDS[keys][:].astype(int16) # changer format SDC.FLOAT64 sds=filehdf.create(name,SDC.FLOAT64,(SDS[keys].shape[0],SDS[keys].shape[1])) if options.compress is True : deflate_level=6 sds.setcompress(SDC.COMP_DEFLATE,deflate_level) sds[:]=SDS[keys][:] #sds[:]=S if keys !='nb_data': for i in range(len(sds_Keys)): setattr(sds,str(sds_Keys.keys()[i]),sds_Keys.values()[i]) if options.sensor != 'SEVIRI' : sds.setfillvalue(out_val_list['_fill_value']) else : sds.setfillvalue(255) sds.endaccess() filehdf.end() return filename