Skip to content

Commit 4d8c643

Browse files
committed
[issue_153] all remaining files merged with some changes from original
1 parent 7559e76 commit 4d8c643

File tree

3 files changed

+69
-26
lines changed

3 files changed

+69
-26
lines changed

pyrate/covariance.py

+43-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
the Matlab Pirate package.
2121
"""
2222
from __future__ import print_function
23+
from os.path import basename, join
2324
import logging
2425
from numpy import array, where, isnan, real, imag, sqrt, meshgrid
2526
from numpy import zeros, vstack, ceil, mean, exp, reshape
@@ -31,6 +32,8 @@
3132
from pyrate import shared
3233
from pyrate.shared import PrereadIfg
3334
from pyrate.algorithm import master_slave_ids
35+
from pyrate import ifgconstants as ifc
36+
from pyrate import config as cf
3437

3538
# distance division factor of 1000 converts to km and is needed to match
3639
# Matlab code output
@@ -64,17 +67,22 @@ def unique_points(points): # pragma: no cover
6467
return vstack([array(u) for u in set(points)])
6568

6669

67-
def cvd(ifg_path, params, r_dist, calc_alpha=False):
70+
def cvd(ifg_path, params, r_dist, calc_alpha=False,
71+
write_vals=False, save_acg=False):
6872
"""
69-
Calculate average covariance versus distance (autocorrelation) and its
70-
best fitting exponential function
73+
Calculate the 1D covariance function of an entire interferogram as the
74+
radial average of its 2D autocorrelation.
7175
7276
:param ifg_path: An interferogram.
7377
ifg: :py:class:`pyrate.shared.Ifg`.
74-
:param: params: dict
75-
dict of config params
78+
:param params: dict
79+
dictionary of configuration parameters
7680
:param calc_alpha: bool
77-
whether you calculate alpha.
81+
calculate alpha, the exponential length-scale of decay factor.
82+
:param write_vals: bool
83+
write maxvar and alpha values to interferogram metadata.
84+
:param save_acg: bool
85+
write acg and radial distance data to numpy array
7886
"""
7987

8088
if isinstance(ifg_path, str): # used during MPI
@@ -91,15 +99,36 @@ def cvd(ifg_path, params, r_dist, calc_alpha=False):
9199
else:
92100
phase = ifg.phase_data
93101

94-
maxvar, alpha = cvd_from_phase(phase, ifg, r_dist, calc_alpha)
102+
maxvar, alpha = cvd_from_phase(phase, ifg, r_dist, calc_alpha,
103+
save_acg=save_acg)
104+
105+
if write_vals:
106+
_add_metadata(ifg, maxvar, alpha)
95107

96108
if isinstance(ifg_path, str):
97109
ifg.close()
98110

99111
return maxvar, alpha
100112

101113

102-
def cvd_from_phase(phase, ifg, r_dist, calc_alpha):
114+
def _add_metadata(ifg, maxvar, alpha):
115+
"""convenience function for saving metadata to ifg"""
116+
md = ifg.meta_data
117+
md[ifc.PYRATE_MAXVAR] = str(maxvar) #.astype('str')
118+
md[ifc.PYRATE_ALPHA] = str(alpha) #.astype('str')
119+
ifg.write_modified_phase()
120+
121+
122+
def _save_cvd_data(acg, r_dist, ifg_path, outdir):
123+
""" function to save numpy array of autocorrelation data to disk"""
124+
data = np.column_stack((acg, r_dist))
125+
data_file = join(outdir, 'cvd_data_{b}.npy'.format(
126+
b=basename(ifg_path).split('.')[0]))
127+
np.save(file=data_file, arr=data)
128+
129+
130+
def cvd_from_phase(phase, ifg, r_dist, calc_alpha, save_acg=False,
131+
params=None):
103132
"""
104133
A convenience class reused in many places to compute cvd from phase data
105134
and a ifg class
@@ -110,6 +139,8 @@ def cvd_from_phase(phase, ifg, r_dist, calc_alpha):
110139
ifg: shared.Ifg class instance
111140
calc_alpha: bool, optional
112141
whether alpha is required
142+
save_acg: bool, optional
143+
write acg and radial distance data to numpy array
113144
114145
Return
115146
------
@@ -150,6 +181,10 @@ def cvd_from_phase(phase, ifg, r_dist, calc_alpha):
150181
indices_to_keep = r_dist < maxdist
151182
acg = acg[indices_to_keep]
152183

184+
# optionally save acg vs dist observations to disk
185+
if save_acg:
186+
_save_cvd_data(acg, r_dist, ifg.data_path, params[cf.TMPDIR])
187+
153188
if calc_alpha:
154189
# bin width for collecting data
155190
bin_width = max(ifg.x_size, ifg.y_size) * 2 / DISTFACT # km

pyrate/ref_phs_est.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def estimate_ref_phase(ifgs, params, refpx, refpy):
3838
:ref_phs: reference phase correction
3939
:ifgs: reference phase data removed list of ifgs
4040
"""
41-
_check_ref_phs_ifgs(ifgs)
41+
check_ref_phs_ifgs(ifgs)
4242

4343
# set reference phase as the average of the whole image (recommended)
4444
if params[cf.REF_EST_METHOD] == 1:
@@ -135,12 +135,10 @@ def est_ref_phs_method1(phase_data, comp):
135135
"""convenience function for ref phs estimate method 1 parallelisation"""
136136
ifgv = np.ravel(phase_data, order='F')
137137
ifgv[comp == 1] = np.nan
138-
# reference phase
139-
ref_ph = nanmedian(ifgv)
140-
return ref_ph
138+
return nanmedian(ifgv)
141139

142140

143-
def _check_ref_phs_ifgs(ifgs, preread_ifgs=None):
141+
def check_ref_phs_ifgs(ifgs, preread_ifgs=None):
144142
"""
145143
Function to check that the ref phase status of all ifgs are the same
146144
"""
@@ -149,6 +147,7 @@ def _check_ref_phs_ifgs(ifgs, preread_ifgs=None):
149147
raise ReferencePhaseError('Need to provide at least 2 ifgs')
150148

151149
if preread_ifgs: # check unless for mpi tests
150+
# preread_ifgs[i].metadata contains ifg metadata
152151
flags = [ifc.PYRATE_REF_PHASE in preread_ifgs[i].metadata
153152
for i in ifgs]
154153
else:

pyrate/scripts/run_pyrate.py

+22-13
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def create_ifg_dict(dest_tifs, params, tiles):
120120
mpiops.comm.barrier()
121121
preread_ifgs = OrderedDict(sorted(cp.load(open(preread_ifgs_file,
122122
'rb')).items()))
123-
log.info('finish converting phase_data to numpy '
123+
log.info('Finished converting phase_data to numpy '
124124
'in process {}'.format(mpiops.rank))
125125
return preread_ifgs
126126

@@ -270,14 +270,16 @@ def save_ref_pixel_blocks(grid, half_patch_size, ifg_paths, params):
270270

271271
def orb_fit_calc(ifg_paths, params, preread_ifgs=None):
272272
"""
273-
Orbital fit correction
273+
MPI wrapper for orbital fit correction
274274
275275
Parameters
276276
----------
277277
ifg_paths: list
278278
list of ifg paths
279279
params: dict
280280
parameters dict corresponding to config file
281+
preread_ifgs: dict, optional
282+
dict containing information regarding ifgs
281283
"""
282284
log.info('Calculating orbfit correction')
283285

@@ -300,15 +302,15 @@ def orb_fit_calc(ifg_paths, params, preread_ifgs=None):
300302
# Here we do all the multilooking in one process, but in memory
301303
# can use multiple processes if we write data to disc during
302304
# remove_orbital_error step
303-
# A performance comparison should be performed be performed for saving
304-
# multilooked files on disc vs in memory single process multilooking
305+
# A performance comparison should be made for saving multilooked
306+
# files on disc vs in memory single process multilooking
305307
if mpiops.rank == MASTER_PROCESS:
306308
orbital.remove_orbital_error(ifg_paths, params, preread_ifgs)
307309
mpiops.comm.barrier()
308-
log.info('Finished orbfit calculation in process {}'.format(mpiops.rank))
310+
log.info('Finished orbfit calculation')
309311

310312

311-
def ref_phase_estimation(ifg_paths, params, refpx, refpy):
313+
def ref_phase_estimation(ifg_paths, params, refpx, refpy, preread_ifgs=None):
312314
"""
313315
Reference phase estimation
314316
@@ -322,18 +324,27 @@ def ref_phase_estimation(ifg_paths, params, refpx, refpy):
322324
reference pixel x-coordinate
323325
refpy: float
324326
reference pixel y-coordinate
327+
preread_ifgs: dict
328+
dict containing information regarding ifgs
325329
"""
330+
# perform some checks on existing ifgs
331+
if preread_ifgs and mpiops.rank == MASTER_PROCESS:
332+
ifg_paths = sorted(preread_ifgs.keys())
333+
if mpiops.run_once(rpe.check_ref_phs_ifgs, ifg_paths, preread_ifgs):
334+
return # return if True condition returned
326335

327-
log.info('Estimating and removing reference phase')
328336
if params[cf.REF_EST_METHOD] == 1:
329337
# calculate phase sum for later use in ref phase method 1
330338
comp = phase_sum(ifg_paths, params)
339+
log.info('Computing reference phase via method 1')
331340
process_ref_phs = ref_phs_method1(ifg_paths, comp)
332341
elif params[cf.REF_EST_METHOD] == 2:
342+
log.info('Computing reference phase via method 2')
333343
process_ref_phs = ref_phs_method2(ifg_paths, params, refpx, refpy)
334344
else:
335345
raise ConfigException('Ref phase estimation method must be 1 or 2')
336346

347+
# Save reference phase numpy arrays to disk
337348
ref_phs_file = join(params[cf.TMPDIR], 'ref_phs.npy')
338349
if mpiops.rank == MASTER_PROCESS:
339350
ref_phs = np.zeros(len(ifg_paths), dtype=np.float64)
@@ -350,6 +361,7 @@ def ref_phase_estimation(ifg_paths, params, refpx, refpy):
350361
# send reference phase data to master process
351362
mpiops.comm.Send(process_ref_phs, dest=MASTER_PROCESS,
352363
tag=mpiops.rank)
364+
log.info('Completed reference phase estimation')
353365

354366

355367
def ref_phs_method2(ifg_paths, params, refpx, refpy):
@@ -443,7 +455,7 @@ def process_ifgs(ifg_paths, params, rows, cols):
443455
cols: int
444456
number of cols to break each ifg into
445457
"""
446-
if mpiops.size > 1: # turn of multiprocessing during mpi jobs
458+
if mpiops.size > 1: # turn of multiprocessing during mpi jobs
447459
params[cf.PARALLEL] = False
448460

449461
tiles = mpiops.run_once(get_tiles, ifg_paths[0], rows, cols)
@@ -504,10 +516,10 @@ def linrate_calc(ifg_paths, params, vcmt, tiles, preread_ifgs):
504516
"""
505517

506518
process_tiles = mpiops.array_split(tiles)
507-
log.info('Calculating linear rate')
519+
log.info('Calculating linear rate map')
508520
output_dir = params[cf.TMPDIR]
509521
for t in process_tiles:
510-
log.info('calculating lin rate of tile {}'.format(t.index))
522+
log.info('Calculating linear rate of tile {}'.format(t.index))
511523
ifg_parts = [shared.IfgPart(p, t, preread_ifgs) for p in ifg_paths]
512524
mst_grid_n = np.load(os.path.join(output_dir,
513525
'mst_mat_{}.npy'.format(t.index)))
@@ -641,9 +653,6 @@ def timeseries_calc(ifg_paths, params, vcmt, tiles, preread_ifgs):
641653
dict containing ifg characteristics for efficient computing
642654
643655
"""
644-
if not params[cf.TIME_SERIES_CAL]:
645-
log.info('Time series calculation not required.')
646-
return
647656
process_tiles = mpiops.array_split(tiles)
648657
log.info('Calculating time series')
649658
output_dir = params[cf.TMPDIR]

0 commit comments

Comments
 (0)