Skip to content

Commit

Permalink
add dd_weight option
Browse files Browse the repository at this point in the history
  • Loading branch information
xumi1993 committed Jul 24, 2024
1 parent e17ead8 commit 68ef327
Showing 1 changed file with 21 additions and 19 deletions.
40 changes: 21 additions & 19 deletions pytomoatt/src_rec.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ def count_events_per_station(self):
"num_events"
].transform("max")

def generate_double_difference(self, type='cs', max_azi_gap=15, max_dist_gap=2.5, recalc_baz=False):
def generate_double_difference(self, type='cs', max_azi_gap=15, max_dist_gap=2.5, dd_weight='aravge', recalc_baz=False):
"""
Generate double difference data
Expand All @@ -1240,6 +1240,7 @@ def generate_double_difference(self, type='cs', max_azi_gap=15, max_dist_gap=2.5
:type max_azi_gap: float, optional
:param max_dist_gap: Maximum distance gap for selecting events, defaults to 2.5
:type max_dist_gap: float, optional
:param dd_weight: Weighting method for double difference, options: ``average``, ``multiply``, defaults to ``average``
:param recalc_baz: Recalculate azimuth and back azimuth, defaults to False
:type recalc_baz: bool, optional
Expand All @@ -1250,20 +1251,20 @@ def generate_double_difference(self, type='cs', max_azi_gap=15, max_dist_gap=2.5
self.calc_distaz()

if type == 'cs':
self._generate_cs(max_azi_gap, max_dist_gap)
self._generate_cs(max_azi_gap, max_dist_gap, dd_weight)
elif type == 'cr':
self._generate_cr(max_azi_gap, max_dist_gap)
self._generate_cr(max_azi_gap, max_dist_gap, dd_weight)
elif type == 'both':
self._generate_cs(max_azi_gap, max_dist_gap)
self._generate_cr(max_azi_gap, max_dist_gap)
self._generate_cs(max_azi_gap, max_dist_gap, dd_weight)
self._generate_cr(max_azi_gap, max_dist_gap, dd_weight)
else:
self.log.SrcReclog.error(
"Only 'cs', 'cr' or 'both' are supported for type of double difference"
)

self.update()

def _generate_cs(self, max_azi_gap, max_dist_gap):
def _generate_cs(self, max_azi_gap, max_dist_gap, dd_weight='average'):
names, _ = setup_rec_points_dd('cs')
self.rec_points_cs = pd.DataFrame(columns=names)
src = self.rec_points.groupby("src_index")
Expand Down Expand Up @@ -1303,7 +1304,7 @@ def _generate_cs(self, max_azi_gap, max_dist_gap):
"stel2": stels[j],
"phase": f"{phases[i]},cs",
"tt": tts[i] - tts[j],
"weight": (weights[i] + weights[j]) / 2,
"weight": self._cal_dd_weight(weights[i], weights[j], dd_weight),
}
# set src_index to index
dd_data.append(data_row)
Expand All @@ -1313,7 +1314,7 @@ def _generate_cs(self, max_azi_gap, max_dist_gap):
"rec_points_cs after generation: {}".format(self.rec_points_cs.shape)
)

def _generate_cr(self, max_azi_gap, max_dist_gap):
def _generate_cr(self, max_azi_gap, max_dist_gap, dd_weight='average'):
names, _ = setup_rec_points_dd('cr')
self.rec_points_cr = pd.DataFrame(columns=names)
src_id = self.src_points["event_id"].values
Expand Down Expand Up @@ -1357,7 +1358,8 @@ def _generate_cr(self, max_azi_gap, max_dist_gap):
"evdp2": src_dp[src_index],
"phase": f"{rec_phases[i]},cr",
"tt": tts[i] - tts[j],
"weight": (src_weights[src_index]+rec_weights[i])/2,
# "weight": (src_weights[src_index]+rec_weights[i])/2,
"weight": self._cal_dd_weight(src_weights[src_index], rec_weights[i], dd_weight),
}
results.append(data_row)

Expand All @@ -1381,6 +1383,14 @@ def _calc_weights(self, lat, lon, scale):
dist_ref = scale * np.mean(dist)
om = np.exp(-((dist / dist_ref) ** 2)) * points.shape[0]
return 1 / np.mean(om, axis=0)

def _cal_dd_weight(self, w1, w2, dd_weight='average'):
if dd_weight == "average":
return (w1 + w2) / 2
elif dd_weight == "multiply":
return w1 * w2
else:
raise ValueError("Only 'average' or 'multiply' are supported for dd_weight")

def geo_weighting(self, scale=0.5, obj="both", dd_weight="average"):
"""Calculating geographical weights for sources
Expand All @@ -1393,14 +1403,6 @@ def geo_weighting(self, scale=0.5, obj="both", dd_weight="average"):
:param dd_weight: Weighting method for double difference data, options: ``average`` or ``multiply``, defaults to ``average``
"""

def cal_dd_weight(w1, w2):
if dd_weight == "average":
return (w1 + w2) / 2
elif dd_weight == "multiply":
return w1 * w2
else:
raise ValueError("Only 'average' or 'multiply' are supported for dd_weight")

if obj == "src" or obj == "both":
self.src_points["weight"] = self._calc_weights(
self.src_points["evla"], self.src_points["evlo"], scale
Expand All @@ -1420,13 +1422,13 @@ def cal_dd_weight(w1, w2):
for i, row in self.rec_points_cs.iterrows():
w1 = self.receivers.loc[self.receivers['staname'] == row['staname1'], 'weight'].values[0]
w2 = self.receivers.loc[self.receivers['staname'] == row['staname2'], 'weight'].values[0]
self.rec_points_cs.loc[i, 'weight'] = cal_dd_weight(w1, w2)
self.rec_points_cs.loc[i, 'weight'] = self._cal_dd_weight(w1, w2, dd_weight)

if not self.rec_points_cr.empty:
for i, row in self.rec_points_cr.iterrows():
w1 = self.receivers.loc[self.receivers['staname'] == row['staname'], 'weight'].values[0]
w2 = self.src_points.loc[self.src_points['event_id'] == row['event_id2'], 'weight'].values[0]
self.rec_points_cr.loc[i, 'weight'] = cal_dd_weight(w1, w2)
self.rec_points_cr.loc[i, 'weight'] = self._cal_dd_weight(w1, w2, dd_weight)

def add_noise(self, range_in_sec=0.1, mean_in_sec=0.0, shape="gaussian"):
"""Add random noise on travel time
Expand Down

0 comments on commit 68ef327

Please sign in to comment.