Skip to content

Commit e8da2d9

Browse files
authored
Bash script edits to make stackSentinel.py faster in places (#225)
* plumb in num-process for time consuming steps * refine num-process speed enhancements * refine num-process speed enhancements * dedicated function for writing batch processes * refine num-process speed enhancements * fix indents Co-authored-by: Russell Grew <[email protected]>
1 parent 0c54c9d commit e8da2d9

File tree

2 files changed

+107
-26
lines changed

2 files changed

+107
-26
lines changed

contrib/stack/topsStack/Stack.py

Lines changed: 106 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python3
22
########################
33
#Author: Heresh Fattahi
44

@@ -13,6 +13,7 @@
1313
maxNodes = 72
1414

1515

16+
1617
class config(object):
1718
"""
1819
A class representing the config file
@@ -242,6 +243,7 @@ def unwrapSnaphu(self, function):
242243
self.f.write('defomax : ' + self.defoMax + '\n')
243244
self.f.write('rlks : ' + self.rangeLooks + '\n')
244245
self.f.write('alks : ' + self.azimuthLooks + '\n')
246+
self.f.write('numProcess : ' + self.numProcess + '\n')
245247

246248
def denseOffset(self, function):
247249
self.f.write('###################################'+'\n')
@@ -258,6 +260,18 @@ def denseOffset(self, function):
258260
#self.f.write('ww : 256\n')
259261
#self.f.write('wh : 128\n')
260262

263+
def write_wrapper_config2run_file(self, configName, line_cnt, numProcess = 1):
264+
# dispassionate list of commands for single process
265+
if numProcess == 1:
266+
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
267+
# aggregate background commands between wait blocks for speed gains
268+
elif numProcess > 1:
269+
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + ' &\n')
270+
if line_cnt == numProcess:
271+
self.runf.write('wait\n\n')
272+
line_cnt = 0
273+
return line_cnt
274+
261275
def finalize(self):
262276
self.f.close()
263277

@@ -286,6 +300,7 @@ def unpackSLC(self, acquisitionDates, safe_dict):
286300
swath_path = self.work_dir
287301
os.makedirs(self.config_path, exist_ok=True)
288302

303+
line_cnt = 0
289304
for slcdate in acquisitionDates:
290305
configName = os.path.join(self.config_path,'config_unpack_'+slcdate)
291306
configObj = config(configName)
@@ -300,8 +315,10 @@ def unpackSLC(self, acquisitionDates, safe_dict):
300315
configObj.Sentinel1_TOPS('[Function-1]')
301316
configObj.topo('[Function-2]')
302317
configObj.finalize()
318+
319+
line_cnt += 1
320+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
303321
del configObj
304-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
305322

306323
def unpackStackReferenceSLC(self, safe_dict):
307324
swath_path = self.work_dir
@@ -320,11 +337,14 @@ def unpackStackReferenceSLC(self, safe_dict):
320337
configObj.Sentinel1_TOPS('[Function-1]')
321338
configObj.topo('[Function-2]')
322339
configObj.finalize()
340+
341+
line_cnt = 1
342+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
323343
del configObj
324-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
325344

326345
def unpackSecondarysSLC(self, stackReferenceDate, secondaryList, safe_dict):
327346

347+
line_cnt = 0
328348
for secondary in secondaryList:
329349
configName = os.path.join(self.config_path,'config_secondary_'+secondary)
330350
outdir = os.path.join(self.work_dir,'secondarys/'+secondary)
@@ -337,11 +357,14 @@ def unpackSecondarysSLC(self, stackReferenceDate, secondaryList, safe_dict):
337357
configObj.outDir = outdir
338358
configObj.Sentinel1_TOPS('[Function-1]')
339359
configObj.finalize()
360+
361+
line_cnt += 1
362+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
340363
del configObj
341-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n')
342364

343365
def averageBaseline(self, stackReferenceDate, secondaryList):
344366

367+
line_cnt = 0
345368
for secondary in secondaryList:
346369
configName = os.path.join(self.config_path,'config_baseline_'+secondary)
347370
configObj = config(configName)
@@ -351,10 +374,14 @@ def averageBaseline(self, stackReferenceDate, secondaryList):
351374
configObj.baselineFile = os.path.join(self.work_dir,'baselines/' + stackReferenceDate +'_' + secondary + '/' + stackReferenceDate +'_'+ secondary + '.txt')
352375
configObj.computeAverageBaseline('[Function-1]')
353376
configObj.finalize()
377+
378+
line_cnt += 1
379+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
354380
del configObj
355-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n')
356381

357382
def gridBaseline(self, stackReferenceDate, secondaryList):
383+
384+
line_cnt = 0
358385
for secondary in secondaryList:
359386
configName = os.path.join(self.config_path,'config_baselinegrid_'+secondary)
360387
configObj = config(configName)
@@ -364,8 +391,10 @@ def gridBaseline(self, stackReferenceDate, secondaryList):
364391
configObj.baselineFile = os.path.join(self.work_dir, 'merged/baselines/' + secondary + '/' + secondary )
365392
configObj.computeGridBaseline('[Function-1]')
366393
configObj.finalize()
394+
395+
line_cnt += 1
396+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
367397
del configObj
368-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n')
369398
# also add the reference in itself to be consistent with the SLC dir
370399
configName = os.path.join(self.config_path,'config_baselinegrid_reference')
371400
configObj = config(configName)
@@ -375,8 +404,10 @@ def gridBaseline(self, stackReferenceDate, secondaryList):
375404
configObj.baselineFile = os.path.join(self.work_dir, 'merged/baselines/' + stackReferenceDate + '/' + stackReferenceDate)
376405
configObj.computeGridBaseline('[Function-1]')
377406
configObj.finalize()
407+
408+
line_cnt = 1
409+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
378410
del configObj
379-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName+'\n')
380411

381412

382413
def extractOverlaps(self):
@@ -386,6 +417,7 @@ def extractOverlaps(self):
386417

387418
def geo2rdr_offset(self, secondaryList, fullBurst='False'):
388419

420+
line_cnt = 0
389421
for secondary in secondaryList:
390422
reference = self.reference_date
391423
if fullBurst == 'True':
@@ -407,10 +439,14 @@ def geo2rdr_offset(self, secondaryList, fullBurst='False'):
407439
configObj.overlapTrueOrFalse = 'True'
408440
configObj.geo2rdr('[Function-1]')
409441
configObj.finalize()
442+
443+
line_cnt += 1
444+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
410445
del configObj
411-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
412446

413447
def resample_with_carrier(self, secondaryList, fullBurst='False'):
448+
449+
line_cnt = 0
414450
for secondary in secondaryList:
415451
reference = self.reference_date
416452
if fullBurst == 'True':
@@ -433,13 +469,17 @@ def resample_with_carrier(self, secondaryList, fullBurst='False'):
433469
configObj.overlapTrueOrFalse = 'True'
434470
configObj.resamp_withCarrier('[Function-1]')
435471
configObj.finalize()
472+
473+
line_cnt += 1
474+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
436475
del configObj
437-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
476+
438477

439478
def pairs_misregistration(self, dateList, safe_dict):
440479
# generating overlap interferograms, estimate azimuth misregistration for each pair:
441480
pairs = []
442481
num_overlap_connections = int(self.num_overlap_connections) + 1
482+
443483
for i in range(len(dateList)-1):
444484
for j in range(i+1,i+num_overlap_connections):
445485
if j<len(dateList):
@@ -450,6 +490,8 @@ def pairs_misregistration(self, dateList, safe_dict):
450490
safe_dict[date].slc_overlap = os.path.join(self.work_dir , 'coreg_secondarys/'+date)
451491
safe_dict[self.reference_date].slc = os.path.join(self.work_dir , 'reference')
452492
safe_dict[self.reference_date].slc_overlap = os.path.join(self.work_dir , 'reference')
493+
494+
line_cnt = 0
453495
for pair in pairs:
454496
reference = pair[0]
455497
secondary = pair[1]
@@ -479,11 +521,12 @@ def pairs_misregistration(self, dateList, safe_dict):
479521
configObj.rangeMisreg('[Function-4]')
480522
configObj.finalize()
481523

482-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
524+
line_cnt += 1
525+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
526+
del configObj
483527
########################
484528

485529

486-
487530
def timeseries_misregistration(self):
488531
#inverting the misregistration offsets of the overlap pairs to estimate the offsets of each date
489532
self.runf.write(self.text_cmd + 'invertMisreg.py -i ' + os.path.join(self.work_dir,'misreg/azimuth/pairs/') + ' -o ' + os.path.join(self.work_dir,'misreg/azimuth/dates/') + '\n')
@@ -499,6 +542,8 @@ def generate_burstIgram(self, dateList, safe_dict, pairs):
499542
for date in dateList:
500543
safe_dict[date].slc = os.path.join(self.work_dir, 'coreg_secondarys/'+date)
501544
safe_dict[self.reference_date].slc = os.path.join(self.work_dir , 'reference')
545+
546+
line_cnt = 0
502547
for pair in pairs:
503548
reference = pair[0]
504549
secondary = pair[1]
@@ -514,14 +559,19 @@ def generate_burstIgram(self, dateList, safe_dict, pairs):
514559
configObj.overlapTrueOrFalse = 'False'
515560
configObj.generateIgram('[Function-1]')
516561
configObj.finalize()
562+
563+
line_cnt += 1
564+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
517565
del configObj
518566

519-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
567+
520568

521569
def igram_mergeBurst(self, dateList, safe_dict, pairs):
522570
for date in dateList:
523571
safe_dict[date].slc = os.path.join(self.work_dir, 'coreg_secondarys/'+date)
524572
safe_dict[self.reference_date].slc = os.path.join(self.work_dir , 'reference')
573+
574+
line_cnt = 0
525575
for pair in pairs:
526576
reference = pair[0]
527577
secondary = pair[1]
@@ -543,12 +593,14 @@ def igram_mergeBurst(self, dateList, safe_dict, pairs):
543593
configObj.stack = os.path.join(self.work_dir, 'stack')
544594
configObj.mergeBurst('[Function-1]')
545595
configObj.finalize()
546-
del configObj
547596

548-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
597+
line_cnt += 1
598+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
599+
del configObj
549600

550601
def mergeSecondarySLC(self, secondaryList, virtual='True'):
551602

603+
line_cnt = 0
552604
for secondary in secondaryList:
553605
configName = os.path.join(self.config_path,'config_merge_' + secondary)
554606
configObj = config(configName)
@@ -566,7 +618,11 @@ def mergeSecondarySLC(self, secondaryList, virtual='True'):
566618
configObj.stack = os.path.join(self.work_dir, 'stack')
567619
configObj.mergeBurst('[Function-1]')
568620
configObj.finalize()
569-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
621+
622+
line_cnt += 1
623+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
624+
del configObj
625+
570626

571627
def mergeReference(self, stackReference, virtual='True'):
572628

@@ -585,7 +641,10 @@ def mergeReference(self, stackReference, virtual='True'):
585641
configObj.multiLook = 'False'
586642
configObj.mergeBurst('[Function-1]')
587643
configObj.finalize()
588-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
644+
645+
line_cnt = 1
646+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
647+
del configObj
589648

590649
geometryList = ['lat*rdr', 'lon*rdr', 'los*rdr', 'hgt*rdr', 'shadowMask*rdr','incLocal*rdr']
591650
multiookToolDict = {'lat*rdr': 'gdal', 'lon*rdr': 'gdal', 'los*rdr': 'gdal' , 'hgt*rdr':"gdal", 'shadowMask*rdr':"isce",'incLocal*rdr':"gdal"}
@@ -610,10 +669,14 @@ def mergeReference(self, stackReference, virtual='True'):
610669
configObj.stack = os.path.join(self.work_dir, 'stack')
611670
configObj.mergeBurst('[Function-1]')
612671
configObj.finalize()
613-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
672+
673+
line_cnt += 1
674+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
675+
del configObj
614676

615677
def mergeSLC(self, aquisitionDates, virtual='True'):
616678

679+
line_cnt = 0
617680
for slcdate in aquisitionDates:
618681
configName = os.path.join(self.config_path,'config_merge_' + slcdate)
619682
configObj = config(configName)
@@ -630,9 +693,14 @@ def mergeSLC(self, aquisitionDates, virtual='True'):
630693
configObj.stack = os.path.join(self.work_dir, 'stack')
631694
configObj.mergeBurst('[Function-1]')
632695
configObj.finalize()
633-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
696+
697+
line_cnt += 1
698+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
699+
634700

635701
geometryList = ['lat*rdr', 'lon*rdr', 'los*rdr', 'hgt*rdr', 'shadowMask*rdr','incLocal*rdr']
702+
703+
g_line_cnt = 0
636704
for i in range(len(geometryList)):
637705
pattern = geometryList[i]
638706
configName = os.path.join(self.config_path,'config_merge_' + slcdate + '_' +pattern.split('*')[0])
@@ -650,10 +718,14 @@ def mergeSLC(self, aquisitionDates, virtual='True'):
650718
configObj.stack = os.path.join(self.work_dir, 'stack')
651719
configObj.mergeBurst('[Function-1]')
652720
configObj.finalize()
653-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
721+
722+
g_line_cnt += 1
723+
g_line_cnt = configObj.write_wrapper_config2run_file(configName, g_line_cnt)
724+
del configObj
654725

655726
def filter_coherence(self, pairs):
656727

728+
line_cnt = 0
657729
for pair in pairs:
658730
reference = pair[0]
659731
secondary = pair[1]
@@ -673,9 +745,15 @@ def filter_coherence(self, pairs):
673745
#configObj.filtStrength = str(self.filtStrength)
674746
configObj.FilterAndCoherence('[Function-1]')
675747
configObj.finalize()
676-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
748+
749+
line_cnt += 1
750+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
751+
del configObj
752+
677753

678754
def unwrap(self, pairs):
755+
756+
line_cnt = 0
679757
for pair in pairs:
680758
reference = pair[0]
681759
secondary = pair[1]
@@ -693,10 +771,14 @@ def unwrap(self, pairs):
693771
configObj.unwMethod = self.unwMethod
694772
configObj.unwrap('[Function-1]')
695773
configObj.finalize()
696-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
774+
775+
line_cnt += 1
776+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt, self.numProcess)
777+
del configObj
697778

698779
def denseOffsets(self, pairs):
699780

781+
line_cnt = 0
700782
for pair in pairs:
701783
reference = pair[0]
702784
secondary = pair[1]
@@ -709,9 +791,10 @@ def denseOffsets(self, pairs):
709791
configObj.output = os.path.join(self.work_dir , 'merged/dense_offsets/'+reference+'_'+secondary + '/' + reference+'_'+secondary)
710792
configObj.denseOffset('[Function-1]')
711793
configObj.finalize()
712-
del configObj
713-
self.runf.write(self.text_cmd + 'SentinelWrapper.py -c ' + configName + '\n')
714794

795+
line_cnt += 1
796+
line_cnt = configObj.write_wrapper_config2run_file(configName, line_cnt)
797+
del configObj
715798

716799
def finalize(self):
717800
self.runf.close()
@@ -966,8 +1049,6 @@ def get_orbit(self, orbitDir, workDir, margin=60.0):
9661049
self.orbit = orbitFile[0]
9671050
self.orbitType = 'restituted'
9681051

969-
970-
9711052
# an example for writing job files when using clusters
9721053

9731054
"""

contrib/stack/topsStack/stackSentinel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def createParser():
167167
help='Allow App to use GPU when available')
168168

169169
parser.add_argument('--num-proc', '--num-process', dest='numProcess', type=int, default=1,
170-
help='number of parallel processes (for topo only) (default: %(default)s).')
170+
help='number of parallel processes (where applicable) (default: %(default)s).')
171171

172172
parser.add_argument('-u', '--unw_method', dest='unwMethod', type=str, default='snaphu', choices=['icu', 'snaphu'],
173173
help='Unwrapping method (default: %(default)s).')

0 commit comments

Comments
 (0)