#!/usr/bin/env python3 ######################## #Author: Heresh Fattahi ####################### import os, glob , sys import datetime noMCF = 'False' defoMax = '2' maxNodes = 72 class config(object): """ A class representing the config file """ def __init__(self, outname): self.f= open(outname,'w') self.f.write('[Common]'+'\n') self.f.write('') self.f.write('##########################'+'\n') def configure(self,inps): for k in inps.__dict__.keys(): setattr(self, k, inps.__dict__[k]) self.plot = 'False' self.misreg_az = None self.misreg_rng = None self.multilook_tool = None self.no_data_value = None def Sentinel1_TOPS(self,function): self.f.write('##########################'+'\n') self.f.write(function+'\n') self.f.write('Sentinel1_TOPS : ' + '\n') self.f.write('dirname : ' + self.dirName+'\n') self.f.write('swaths : ' + self.swaths+'\n') if self.orbit_type == 'precise': self.f.write('orbitdir : '+self.orbit_dirname+'\n') else: self.f.write('orbit : '+self.orbit_file+'\n') self.f.write('outdir : ' + self.outDir + '\n') self.f.write('auxdir : ' + self.aux_dirname + '\n') if self.bbox is not None: self.f.write('bbox : ' + self.bbox + '\n') self.f.write('pol : ' + self.polarization + '\n') self.f.write('##########################' + '\n') def computeAverageBaseline(self, function): self.f.write('##########################'+'\n') self.f.write(function + '\n') self.f.write('computeBaseline : '+'\n') self.f.write('master : ' + self.master + '\n') self.f.write('slave : ' + self.slave + '\n') self.f.write('baseline_file : ' + self.baselineFile + '\n') def computeGridBaseline(self, function): self.f.write('##########################'+'\n') self.f.write(function + '\n') self.f.write('baselineGrid : '+'\n') self.f.write('master : ' + self.master + '\n') self.f.write('slave : ' + self.slave + '\n') self.f.write('baseline_file : ' + self.baselineFile + '\n') def topo(self,function): self.f.write('##########################'+'\n') self.f.write('#Call topo to produce master geometry files'+'\n') self.f.write(function + '\n') self.f.write('topo : ' + '\n') self.f.write('master : ' + self.outDir + '\n') self.f.write('dem : ' + self.dem + '\n') self.f.write('geom_masterDir : ' + self.geom_masterDir + '\n') self.f.write('##########################' + '\n') def geo2rdr(self,function): self.f.write('##########################' + '\n') self.f.write(function + '\n') self.f.write('geo2rdr :' + '\n') self.f.write('slave : ' + self.slaveDir + '\n') self.f.write('master : ' + self.masterDir + '\n') self.f.write('geom_masterDir : ' + self.geom_master + '\n') self.f.write('coregSLCdir : ' + self.coregSlaveDir + '\n') self.f.write('overlap : ' + self.overlapTrueOrFalse + '\n') if self.useGPU: self.f.write('useGPU : True \n') else: self.f.write('useGPU : False\n') if self.misreg_az is not None: self.f.write('azimuth_misreg : ' + self.misreg_az + '\n') if self.misreg_rng is not None: self.f.write('range_misreg : ' + self.misreg_rng + '\n') def resamp_withCarrier(self,function): self.f.write('##########################' + '\n') self.f.write(function + '\n') self.f.write('resamp_withCarrier : ' + '\n') self.f.write('slave : ' + self.slaveDir + '\n') self.f.write('master : ' + self.masterDir + '\n') #self.f.write('interferogram_prefix :' + self.interferogram_prefix + '\n') self.f.write('coregdir : ' + self.coregSlaveDir + '\n') self.f.write('overlap : ' + self.overlapTrueOrFalse + '\n') if self.misreg_az is not None: self.f.write('azimuth_misreg : ' + self.misreg_az + '\n') if self.misreg_rng is not None: self.f.write('range_misreg : ' + self.misreg_rng + '\n') def generateIgram(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('generateIgram : ' + '\n') self.f.write('master : ' + self.masterDir + '\n') self.f.write('slave : ' + self.slaveDir + '\n') self.f.write('interferogram : ' + self.interferogramDir + '\n') self.f.write('flatten : ' + self.flatten + '\n') self.f.write('interferogram_prefix : ' + self.interferogram_prefix +'\n') self.f.write('overlap : ' + self.overlapTrueOrFalse + '\n') if self.misreg_az is not None: self.f.write('azimuth_misreg : ' + self.misreg_az + '\n') if self.misreg_rng is not None: self.f.write('range_misreg : ' + self.misreg_rng + '\n') self.f.write('###################################' + '\n') def overlap_withDEM(self,function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('overlap_withDEM : '+'\n') self.f.write('interferogram : ' + self.interferogramDir +'\n') self.f.write('master_dir : ' + self.masterDir+'\n') self.f.write('slave_dir : ' + self.slaveDir+'\n') self.f.write('overlap_dir : ' + self.overlapDir+'\n') def azimuthMisreg(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('estimateAzimuthMisreg : ' + '\n') self.f.write('overlap_dir : ' + self.overlapDir + '\n') self.f.write('out_azimuth : ' + self.misregFile + '\n') self.f.write('coh_threshold : ' + self.esdCoherenceThreshold + '\n') self.f.write('plot : ' + self.plot + '\n') def rangeMisreg(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('estimateRangeMisreg : ' + '\n') self.f.write('master : ' + self.masterDir + '\n') self.f.write('slave : ' + self.slaveDir + '\n') self.f.write('out_range : ' + self.misregFile + '\n') self.f.write('snr_threshold : ' + self.snrThreshold + '\n') def mergeBurst(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('mergeBursts : ' + '\n') try: self.f.write('stack : ' + self.stack +'\n') except: pass self.f.write('inp_master : ' + self.master +'\n') self.f.write('dirname : ' + self.dirName + '\n') self.f.write('name_pattern : ' + self.namePattern + '\n') self.f.write('outfile : ' + self.mergedFile + '\n') self.f.write('method : ' + self.mergeBurstsMethod + '\n') self.f.write('aligned : ' + self.aligned + '\n') self.f.write('valid_only : ' + self.validOnly + '\n') self.f.write('use_virtual_files : ' + self.useVirtualFiles + '\n') self.f.write('multilook : ' + self.multiLook + '\n') self.f.write('range_looks : ' + self.rangeLooks + '\n') self.f.write('azimuth_looks : ' + self.azimuthLooks + '\n') if self.multilook_tool: self.f.write('multilook_tool : ' + self.multilook_tool + '\n') if self.no_data_value is not None: self.f.write('no_data_value : ' + self.no_data_value + '\n') def mergeSwaths(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('mergeSwaths : ' + '\n') self.f.write('input : ' + self.inputDirs + '\n') self.f.write('file : ' + self.fileName + '\n') self.f.write('metadata : ' + self.metadata + '\n') self.f.write('output : ' + self.outDir +'\n') def multiLook(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('looks_withDEM : ' + '\n') self.f.write('input : ' + self.input + '\n') self.f.write('output : ' + self.output + '\n') self.f.write('range : ' + self.rangeLooks + '\n') self.f.write('azimuth : ' + self.azimuthLooks + '\n') def FilterAndCoherence(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('FilterAndCoherence : ' + '\n') self.f.write('input : ' + self.input + '\n') self.f.write('filt : ' + self.filtName + '\n') self.f.write('coh : ' + self.cohName + '\n') self.f.write('strength : ' + self.filtStrength + '\n') def unwrap(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('unwrap : ' + '\n') self.f.write('ifg : ' + self.ifgName + '\n') self.f.write('unw : ' + self.unwName + '\n') self.f.write('coh : ' + self.cohName + '\n') self.f.write('nomcf : ' + self.noMCF + '\n') self.f.write('master : ' + self.master + '\n') self.f.write('defomax : ' + self.defoMax + '\n') self.f.write('alks : ' + self.rangeLooks + '\n') self.f.write('rlks : ' + self.azimuthLooks + '\n') self.f.write('method : ' + self.unwMethod + '\n') def unwrapSnaphu(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') self.f.write('unwrapSnaphu : ' + '\n') self.f.write('ifg : ' + self.ifgName + '\n') self.f.write('unw : ' + self.unwName + '\n') self.f.write('coh : ' + self.cohName + '\n') self.f.write('nomcf : ' + self.noMCF + '\n') self.f.write('master : ' + self.master + '\n') self.f.write('defomax : ' + self.defoMax + '\n') self.f.write('alks : ' + self.rangeLooks + '\n') self.f.write('rlks : ' + self.azimuthLooks + '\n') def denseOffset(self, function): self.f.write('###################################'+'\n') self.f.write(function + '\n') # CPU or GPU self.f.write('denseOffsets : ' + '\n') #self.f.write('DenseOffsets : ' + '\n') #self.f.write('cuDenseOffsets : ' + '\n') self.f.write('master : ' + self.master + '\n') self.f.write('slave : ' + self.slave + '\n') self.f.write('outprefix : ' + self.output + '\n') #self.f.write('ww : 256\n') #self.f.write('wh : 128\n') def finalize(self): self.f.close() class run(object): """ A class representing a run which may contain several functions """ #def __init__(self): def configure(self,inps, runName): for k in inps.__dict__.keys(): setattr(self, k, inps.__dict__[k]) self.runDir = os.path.join(self.work_dir, 'run_files') if not os.path.exists(self.runDir): os.makedirs(self.runDir) self.run_outname = os.path.join(self.runDir, runName) print ('writing ', self.run_outname) self.config_path = os.path.join(self.work_dir,'configs') if not os.path.exists(self.config_path): os.makedirs(self.config_path) self.runf= open(self.run_outname,'w') def unpackSLC(self, acquisitionDates, safe_dict): swath_path = self.work_dir if not os.path.exists(self.config_path): os.makedirs(self.config_path) for slcdate in acquisitionDates: configName = os.path.join(self.config_path,'config_'+slcdate) configObj = config(configName) configObj.configure(self) configObj.dirName = safe_dict[slcdate].safe_file configObj.orbit_file = safe_dict[slcdate].orbit configObj.orbit_type = safe_dict[slcdate].orbitType configObj.swaths = self.swath_num configObj.outDir = os.path.join(self.work_dir, 'slc/' + slcdate) configObj.geom_masterDir = os.path.join(self.work_dir, 'geom_slc/' + slcdate) configObj.dem = os.path.join(self.work_dir, configObj.dem) configObj.Sentinel1_TOPS('[Function-1]') configObj.topo('[Function-2]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n') def unpackStackMasterSLC(self, safe_dict): swath_path = self.work_dir if not os.path.exists(self.config_path): os.makedirs(self.config_path) configName = os.path.join(self.config_path,'config_master') configObj = config(configName) configObj.configure(self) configObj.dirName = safe_dict[self.master_date].safe_file configObj.orbit_file = safe_dict[self.master_date].orbit configObj.orbit_type = safe_dict[self.master_date].orbitType configObj.swaths = self.swath_num configObj.outDir = os.path.join(self.work_dir, 'master') configObj.geom_masterDir = os.path.join(self.work_dir, 'geom_master') configObj.dem = os.path.join(self.work_dir, configObj.dem) configObj.Sentinel1_TOPS('[Function-1]') configObj.topo('[Function-2]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n') def unpackSlavesSLC(self, stackMasterDate, slaveList, safe_dict): for slave in slaveList: configName = os.path.join(self.config_path,'config_slave_'+slave) outdir = os.path.join(self.work_dir,'slaves/'+slave) configObj = config(configName) configObj.configure(self) configObj.dirName = safe_dict[slave].safe_file configObj.orbit_file = safe_dict[slave].orbit configObj.orbit_type = safe_dict[slave].orbitType configObj.swaths = self.swath_num configObj.outDir = outdir configObj.Sentinel1_TOPS('[Function-1]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n') def averageBaseline(self, stackMasterDate, slaveList): for slave in slaveList: configName = os.path.join(self.config_path,'config_baseline_'+slave) configObj = config(configName) configObj.configure(self) configObj.master = os.path.join(self.work_dir,'master/') configObj.slave = os.path.join(self.work_dir,'slaves/'+slave) configObj.baselineFile = os.path.join(self.work_dir,'baselines/' + stackMasterDate +'_' + slave + '/' + stackMasterDate +'_'+ slave + '.txt') configObj.computeAverageBaseline('[Function-1]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n') def gridBaseline(self, stackMasterDate, slaveList): for slave in slaveList: configName = os.path.join(self.config_path,'config_baselinegrid_'+slave) configObj = config(configName) configObj.configure(self) configObj.master = os.path.join(self.work_dir,'master/') configObj.slave = os.path.join(self.work_dir,'slaves/'+slave) configObj.baselineFile = os.path.join(self.work_dir, 'merged/baselines/' + slave + '/' + slave ) configObj.computeGridBaseline('[Function-1]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n') # also add the master in itself to be consistent with the SLC dir configName = os.path.join(self.config_path,'config_baselinegrid_master') configObj = config(configName) configObj.configure(self) configObj.master = os.path.join(self.work_dir,'master/') configObj.slave = os.path.join(self.work_dir,'master/') configObj.baselineFile = os.path.join(self.work_dir, 'merged/baselines/' + stackMasterDate + '/' + stackMasterDate) configObj.computeGridBaseline('[Function-1]') configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n') def extractOverlaps(self): self.runf.write(self.text_cmd + 'subsetMaster.py -m ' + os.path.join(self.work_dir, 'master') + ' -g ' + os.path.join(self.work_dir, 'geom_master') + '\n') def overlap_geo2rdr_resample(self, slaveList): for slave in slaveList: master = self.master_date configName = os.path.join(self.config_path ,'config_resamp_overlap_'+slave) ########### configObj = config(configName) configObj.configure(self) configObj.slaveDir = os.path.join(self.work_dir, 'slaves/'+slave) configObj.masterDir = os.path.join(self.work_dir, 'master') configObj.geom_master = os.path.join(self.work_dir, 'geom_master') configObj.coregSlaveDir = os.path.join(self.work_dir, 'coreg_slaves/'+slave) configObj.overlapTrueOrFalse = 'True' configObj.geo2rdr('[Function-1]') ########### configObj.interferogram_prefix = 'coarse' configObj.masterDir = os.path.join(self.work_dir,'master') configObj.resamp_withCarrier('[Function-2]') ########### configObj.finalize() del configObj self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n') def pairs_misregistration(self, dateList, safe_dict): # generating overlap interferograms, estimate azimuth misregistration for each pair: pairs = [] num_overlap_connections = int(self.num_overlap_connections) + 1 for i in range(len(dateList)-1): for j in range(i+1,i+num_overlap_connections): if j orbit_start_date_time and self.start_date_time < orbit_stop_date_time: self.orbit = os.path.join(orbitDir,orbit) self.orbitType = 'precise' match = True break if not match: print ("*****************************************") print (self.date) print ("orbit was not found in the "+orbitDir) # It should go and look online print ("downloading precise or restituted orbits ...") restitutedOrbitDir = os.path.join(workDir ,'orbits/' + self.date) if os.path.exists(restitutedOrbitDir): orbitFile = glob.glob(os.path.join(restitutedOrbitDir,'*.EOF'))[0] #fields = orbitFile.split('_') fields = os.path.basename(orbitFile).split('_') orbit_start_date_time = datetime.datetime.strptime(fields[6].replace('V',''), datefmt) orbit_stop_date_time = datetime.datetime.strptime(fields[7].replace('.EOF',''), datefmt) if self.start_date_time > orbit_start_date_time and self.start_date_time < orbit_stop_date_time: print ("restituted orbit already exists.") self.orbit = orbitFile self.orbitType = 'restituted' #if not os.path.exists(restitutedOrbitDir): else: os.makedirs(restitutedOrbitDir) cmd = 'fetchOrbit.py -i ' + self.safe_file + ' -o ' + restitutedOrbitDir print(cmd) os.system(cmd) orbitFile = glob.glob(os.path.join(restitutedOrbitDir,'*.EOF')) self.orbit = orbitFile[0] self.orbitType = 'restituted' # an example for writing job files when using clusters """ def writeJobFile(runFile): jobName = runFile + '.job' dirName = os.path.dirname(runFile) with open(runFile) as ff: nodes = len(ff.readlines()) if nodes >maxNodes: nodes = maxNodes f = open (jobName,'w') f.write('#!/bin/bash '+ '\n') f.write('#PBS -N Parallel_GNU'+ '\n') f.write('#PBS -l nodes=' + str(nodes) + '\n') jobTxt='''#PBS -V #PBS -l walltime=05:00:00 #PBS -q default #PBS -m bae -M hfattahi@gps.caltech.edu echo Working directory is $PBS_O_WORKDIR cd $PBS_O_WORKDIR echo Running on host `hostname` echo Time is `date` ### Define number of processors NPROCS=`wc -l < $PBS_NODEFILE` echo This job has allocated $NPROCS cpus # Tell me which nodes it is run on echo " " echo This jobs runs on the following processors: echo `cat $PBS_NODEFILE` echo " " # # Run the parallel with the nodelist and command file # ''' f.write(jobTxt+ '\n') f.write('parallel --sshloginfile $PBS_NODEFILE -a ' + os.path.basename(runFile) + '\n') f.write('') f.close() """