2019-01-16 19:40:08 +00:00
|
|
|
#!/usr/bin/env python3
|
2019-05-07 16:11:23 +00:00
|
|
|
import os, sys
|
2019-07-19 08:15:10 +00:00
|
|
|
from importlib import util as importlibutil
|
2019-01-16 19:40:08 +00:00
|
|
|
import argparse
|
|
|
|
import configparser
|
|
|
|
|
|
|
|
# Deals with Configuration file
|
|
|
|
class ConfigParser:
|
|
|
|
def __init__(self, configFile, fileList, common):
|
|
|
|
self.configFile = configFile
|
|
|
|
self.fileList = fileList
|
|
|
|
self.funcParams = {}
|
|
|
|
self.funcSeq = {}
|
|
|
|
self.optionSeq = []
|
|
|
|
self.common = common
|
|
|
|
|
|
|
|
# Parse Config File
|
|
|
|
def readConfig(self):
|
|
|
|
# Open the file Cautiously
|
|
|
|
with open(self.configFile) as config:
|
|
|
|
content = config.readlines()
|
|
|
|
|
|
|
|
# Setting up and reading config
|
|
|
|
Config = configparser.ConfigParser()
|
|
|
|
Config.optionxform = str
|
2019-05-07 16:11:23 +00:00
|
|
|
Config.read_file(content)
|
2019-01-16 19:40:08 +00:00
|
|
|
|
|
|
|
# Reading the function sequence followed by input parameters
|
|
|
|
# followed by the function parameters
|
|
|
|
self.common, seqOption = self.__readConfigSection(Config, "Common")
|
|
|
|
self.optionSeq = Config.sections()[1:]
|
|
|
|
for section in self.optionSeq:
|
|
|
|
dictionary, seqOption = self.__readConfigSection(Config, section)
|
|
|
|
|
|
|
|
# Noting the function name and removing from dictionary
|
|
|
|
funcName = seqOption[0]
|
|
|
|
del dictionary[funcName]
|
|
|
|
self.funcSeq[section] = funcName
|
|
|
|
|
|
|
|
# Creating params for the function
|
|
|
|
self.funcParams[section] = self.__dictToParams(funcName, dictionary)
|
|
|
|
|
|
|
|
print("Completed Parsing the Configuration file")
|
|
|
|
|
|
|
|
# Executes the command parsed from the configuaration file
|
|
|
|
def runCmd(self):
|
|
|
|
import subprocess as SP
|
|
|
|
for section in self.optionSeq:
|
|
|
|
ifunc = self.funcSeq[section]
|
|
|
|
print("Running: %s"%ifunc)
|
|
|
|
print(self.funcParams[section])
|
|
|
|
|
|
|
|
func_modules = self.__import(ifunc)
|
|
|
|
func_modules.main(self.funcParams[section])
|
|
|
|
|
|
|
|
# Generating the config using the file list
|
|
|
|
def generateConfig(self, configFile):
|
|
|
|
|
|
|
|
# Setting up reading config
|
|
|
|
Config = configparser.ConfigParser(delimiters=':')
|
|
|
|
Config.optionxform = str
|
|
|
|
|
|
|
|
# Create the section in the Config
|
|
|
|
self.__generateConfigSection(Config, "Common", self.common)
|
|
|
|
|
|
|
|
# Reading the parameters from each function in the list
|
|
|
|
for i, ifile in enumerate(self.fileList):
|
|
|
|
section = "Function-%s"%(i+1)
|
|
|
|
func_modules = self.__import(ifile)
|
|
|
|
parser = func_modules.createParser()
|
|
|
|
|
|
|
|
# Reading the arguments for the function
|
|
|
|
args, types = self.__readParserArgs(parser)
|
|
|
|
|
|
|
|
# Appending the function name as the first argument
|
|
|
|
args.insert(0, ifile)
|
|
|
|
|
|
|
|
# Create the section in the Config
|
|
|
|
self.__generateConfigSection(Config, section, args)
|
|
|
|
|
|
|
|
# Writing our configuration file
|
|
|
|
with open(self.configFile, 'w') as configfile:
|
|
|
|
Config.write(configfile)
|
|
|
|
|
|
|
|
# Converts the dictionary from Config file to parameter list
|
|
|
|
def __dictToParams(self, fileName, dictionary):
|
|
|
|
params = []
|
|
|
|
# Creating params with dictionary
|
|
|
|
for key in dictionary.keys():
|
|
|
|
if dictionary[key] == 'True':
|
|
|
|
# For binary parameters
|
|
|
|
params.append('--%s'%key)
|
|
|
|
elif not dictionary[key]:
|
|
|
|
continue
|
|
|
|
elif dictionary[key] == 'False':
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
params.append('--%s'%key)
|
|
|
|
params.append(dictionary[key])
|
|
|
|
|
|
|
|
return params
|
|
|
|
|
|
|
|
# Writes the arguments in each section
|
|
|
|
def __generateConfigSection(self, config, section, subsection):
|
|
|
|
config[section] = {}
|
|
|
|
|
|
|
|
# Writing empty section to create the config file
|
|
|
|
for isubsec in subsection:
|
|
|
|
config[section][isubsec] = ''
|
|
|
|
|
|
|
|
# Looks for string between $ sysmbols in the common subheading in config file
|
|
|
|
def __parseString(self, iString):
|
2021-07-02 03:42:39 +00:00
|
|
|
if iString == '':
|
2019-01-16 19:40:08 +00:00
|
|
|
return iString
|
|
|
|
elif isinstance(self.common, (dict)):
|
|
|
|
# Case when "common" parameters are read from the configuration file
|
|
|
|
for commonStr in self.common.keys():
|
|
|
|
key = '$' + commonStr + '$'
|
|
|
|
iString = iString.replace(key, self.common[commonStr])
|
|
|
|
return iString
|
|
|
|
else:
|
|
|
|
return iString
|
|
|
|
|
|
|
|
# Maps each section to its arguments in a dictionary
|
|
|
|
def __readConfigSection(self, Config, section):
|
|
|
|
import collections
|
|
|
|
dict1 = {}
|
|
|
|
seqOptions = []
|
|
|
|
options = collections.OrderedDict(Config.items(section))
|
|
|
|
options = list(options.items())
|
|
|
|
for option, ip in options:
|
|
|
|
dict1[option] = self.__parseString(ip)
|
|
|
|
seqOptions.append(option)
|
|
|
|
|
|
|
|
return (dict1, seqOptions)
|
|
|
|
|
|
|
|
# Get attributes from the parser
|
|
|
|
def __readParserArgs(self, parser):
|
|
|
|
iargs = []
|
|
|
|
types = []
|
|
|
|
numArgs = len(parser._actions) - 1
|
|
|
|
|
|
|
|
# Skipping the help argument
|
|
|
|
for i in range(numArgs):
|
|
|
|
options = parser._actions[i+1]
|
|
|
|
iargs.append(options.option_strings[1][2:])
|
|
|
|
types.append(options.type)
|
|
|
|
|
|
|
|
return iargs, types
|
|
|
|
|
|
|
|
# Importing the functions from the filename
|
|
|
|
def __import(self, name, globals=None, locals=None, fromlist=None):
|
|
|
|
# Fast path: see if the module has already been imported.
|
|
|
|
try:
|
|
|
|
return sys.modules[name]
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# If any of the following calls raises an exception,
|
|
|
|
# there's a problem we can't handle -- let the caller handle it.
|
2019-07-19 08:15:10 +00:00
|
|
|
spec = importlibutil.find_spec(name)
|
2019-01-16 19:40:08 +00:00
|
|
|
|
|
|
|
try:
|
2019-05-07 16:11:23 +00:00
|
|
|
return spec.loader.load_module()
|
|
|
|
except ImportError:
|
|
|
|
print('module {} not found'.format(name))
|
2019-01-16 19:40:08 +00:00
|
|
|
|
|
|
|
# Check existence of the input file
|
|
|
|
def check_if_files_exist(Files, ftype='input'):
|
|
|
|
for ifile in Files:
|
|
|
|
if not os.path.exists(ifile):
|
|
|
|
print("Error: specified %s file %s does not exist" % (ftype, ifile))
|
|
|
|
else:
|
|
|
|
print("Reading specified %s file: %s" %(ftype, ifile))
|
|
|
|
|
|
|
|
|
|
|
|
# Set up option parser and parse command-line args
|
|
|
|
def parse_args():
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser( description='Sentinel Processing Wrapper')
|
|
|
|
parser.add_argument('-s', type=str, dest='start', default=None,
|
|
|
|
help='Specify the start step in the config file. eg: -s Function-4')
|
|
|
|
parser.add_argument('-e', type=str, dest='end', default=None,
|
|
|
|
help='Specify the end step in the config file. eg: -e Function-8')
|
|
|
|
parser.add_argument('-c', type=str, dest='config', default=None,
|
|
|
|
help='Specify config file other than sentinel.ini')
|
|
|
|
parser.add_argument('-n', dest='createConfig', action='store_true', default=False,
|
|
|
|
help='Create a config file')
|
|
|
|
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
|
|
def main(start = None, end = None):
|
|
|
|
# config file creation or parsing
|
|
|
|
config = 'sentinel.ini' if configFile is None else configFile
|
|
|
|
|
|
|
|
common = ['outputDir', \
|
2020-07-02 19:40:49 +00:00
|
|
|
'referenceDir', \
|
|
|
|
'secondaryDir', \
|
|
|
|
'referenceOrbit', \
|
|
|
|
'secondaryOrbit', \
|
2019-01-16 19:40:08 +00:00
|
|
|
'dem', \
|
|
|
|
'swathnum']
|
|
|
|
|
|
|
|
fileList = ['Sentinel1A_TOPS', \
|
|
|
|
'topo',\
|
|
|
|
'geo2rdr',\
|
|
|
|
'estimateOffsets_withDEM',\
|
2020-07-02 19:40:49 +00:00
|
|
|
'derampSecondary',\
|
2019-01-16 19:40:08 +00:00
|
|
|
'resamp_withDEM',\
|
|
|
|
'overlap_withDEM',\
|
|
|
|
'estimateAzimuthMisreg',\
|
|
|
|
'estimateOffsets_withDEM',\
|
|
|
|
'resamp_withDEM',\
|
|
|
|
'generateIgram',\
|
|
|
|
'merge_withDEM']
|
|
|
|
|
|
|
|
# Creating ConfigParser object
|
|
|
|
cfgParser = ConfigParser(config, fileList, common)
|
|
|
|
|
|
|
|
# Empty Configuration creation
|
|
|
|
if createConfig is True:
|
|
|
|
print("Creating Configuration File")
|
|
|
|
cfgParser.generateConfig(config)
|
|
|
|
print("Configuration File Created: %s"%(config))
|
|
|
|
return
|
|
|
|
|
|
|
|
# Parse through the configuration file and convert them into terminal cmds
|
|
|
|
cfgParser.readConfig()
|
|
|
|
|
|
|
|
# #################################
|
|
|
|
if not start is None and not end is None:
|
|
|
|
if start in cfgParser.optionSeq and end in cfgParser.optionSeq:
|
|
|
|
ind_start = cfgParser.optionSeq.index(start)
|
|
|
|
ind_end = cfgParser.optionSeq.index(end)
|
|
|
|
cfgParser.optionSeq = cfgParser.optionSeq[ind_start:ind_end+1]
|
|
|
|
else:
|
|
|
|
print("Warning start and end was not found")
|
|
|
|
|
|
|
|
print ("Functions to be executed:")
|
|
|
|
print (cfgParser.optionSeq)
|
|
|
|
# Run the commands on the Terminal
|
|
|
|
cfgParser.runCmd()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
# Parse the input arguments
|
|
|
|
args = parse_args()
|
|
|
|
configFile, createConfig = args.config, args.createConfig
|
|
|
|
|
|
|
|
# Main engine
|
|
|
|
main(args.start,args.end)
|
|
|
|
|