def __call__(self, m): D, P = self.datacoder, self.parameterizer ZTOP, VP, VS, RH = P.inv( m) #recover model from parameterized array (m) values = dispersion(ZTOP, VP, VS, RH, \ D.waves, D.types, D.modes, D.freqs, self.h, self.dcl, self.dcr) return D(values) #convert dispersion data to coded array (d)
def fun(mms): ztop, vp, vs, rh = mms try: overvalues = dispersion(ztop, vp, vs, rh, overwaves, overtypes, overmodes, overfreqs, h=0.005, dcl=0.005, dcr=0.005) except KeyboardInterrupt: raise except Exception as e: h = ztop[1:] - ztop[:-1] # assume failuer was caused by rounding issues h[h <= 0.001] = 0.001001 ztop = np.concatenate(([0.], h.cumsum())) try: #again overvalues = dispersion(ztop, vp, vs, rh, overwaves, overtypes, overmodes, overfreqs, h=0.005, dcl=0.005, dcr=0.005) except KeyboardInterrupt: raise except Exception as giveup: overvalues = np.nan * np.ones(len(overwaves)) return mms, overvalues
def fun(i, modeli): ztopi, logvsi, logpri, logrhi = \ modeli[IZ], modeli[IVS], modeli[IPR], modeli[IRH] n = len(ztopi) ilayer = i % n if ilayer == n - 1: Hi = 1.e50 # thickness of the half-space else: Hi = ztopi[ilayer + 1] - ztopi[ilayer] try: logvaluesi = lognofail( dispersion(ztopi, np.exp(logvsi + logpri), np.exp(logvsi), np.exp(logrhi), waves, types, modes, freqs, h=h, dcl=dcl, dcr=dcr)) except CPiSDomainError as err: print("error during gradient computation %s" % str(err)) return i, None except: raise if norm: # sensitivity corrected from the layer thicknesses DVAVPi = (logvaluesi - logvalues0) / (modeli[i] - model0[i]) / Hi else: # absolute sensitivity regardless the thickness differences DVAVPi = (logvaluesi - logvalues0) / (modeli[i] - model0[i]) return i, DVAVPi
dm = depthmodel_from_arrays(ztop, vp, vs, rh) # dipsersion parameters # f = np.logspace(np.log10(0.1), np.log10(500.), 100) # frequency array, km/s : ERROR : example of missing modes as reported by Herrmann !!!!! f = np.logspace(np.log10(0.1), np.log10(10.), 100) # frequency array, km/s # dispersion curves curves = [('R', 'C', 0, f), ('R', 'C', 1, f), ('R', 'C', 2, f), ('R', 'C', 3, f), ('R', 'C', 4, f), ('R', 'C', 5, f), ('R', 'C', 6, f)] # compute dispersion laws Waves, Types, Modes, Freqs = zip(*curves) waves, types, modes, freqs = igroupbywtm(Waves, Types, Modes, Freqs) values = dispersion(ztop, vp, vs, rh, waves, types, modes, freqs) laws = mklaws(waves, types, modes, freqs, values, dvalues=None) c0, c1, c2, c3 = laws[:4] if __name__ == "__main__": from srfpython import * plt.figure() dm.show(gca()) plt.legend() plt.figure() for law in laws: law.show(gca()) plt.legend() showme()
def sker17(ztop, vp, vs, rh, \ waves, types, modes, freqs, dz=0.001, dlogvs=0.01, dlogpr=0.01, dlogrh=0.01, norm=True, h = 0.005, dcl = 0.005, dcr = 0.005): """sker17 : compute finite difference sensitivity kernels for surface waves dispersion curves input: -> depth model ztop, vp, vs, rh : lists or arrays, see dispersion -> required dispersion points waves, types, modes, freqs : lists or arrays, see dispersion -> sensitivity kernel computation dz = depth increment in km dlogvs = increment to apply to the logarithm of vs dlogpr = increment to apply to the logarithm of vp/vs dlogrh = increment to apply to the logarithm of rho norm = if True, I divide the sensitivity values by the thickness of each layer => this corrects for the difference of sensitivity due to the variable thicknesss -> Herrmann's parameters, see CPS documentation h, dcl, dcr = passed to dispersion output: -> yields a tuple (w, t, m, F, DLOGVADZ, DLOGVADLOGVS, DLOGVADLOGPR, DLOGVADLOGRH) for each wave, type and mode w = string, wave letter (L = Love or R = Rayleigh) t = string, type letter (C = phase or U = group) m = int, mode number (0= fundamental) F = array, 1D, frequency array in Hz DLOGVADZ = array, 2D, [normed] sensitivity kernel relative to top depth of each layer (lines) and frequency (columns) DLOGVADLOGVS = array, 2D, [normed] sensitivity kernel relative to Pwave velocity of each layer (lines) and frequency (columns) DLOGVADLOGPR = array, 2D, [normed] sensitivity kernel relative to Swave velocity of each layer (lines) and frequency (columns) DLOGVADLOGRH = array, 2D, [normed] sensitivity kernel relative to density of each layer (lines) and frequency (columns) note that these arrays might contain nans see also : sker17_1 dispersion """ waves, types, modes, freqs = [ np.asarray(_) for _ in waves, types, modes, freqs ] nlayer = len(ztop) H = np.array(ztop) # NOT ASARRAY H[:-1], H[-1] = H[1:] - H[:-1], np.inf #layer thickness in km model0 = np.concatenate((ztop, np.log(vs), np.log(vp / vs), np.log(rh))) dmodel = np.concatenate( (dz * np.ones_like(ztop), dlogvs * np.ones_like(vs), dlogpr * np.ones_like(vs), dlogrh * np.ones_like(rh))) logvalues0 = lognofail( dispersion(ztop, vp, vs, rh, waves, types, modes, freqs, h=h, dcl=dcl, dcr=dcr)) IZ = np.arange(nlayer) IVS = np.arange(nlayer, 2 * nlayer) IPR = np.arange(2 * nlayer, 3 * nlayer) IRH = np.arange(3 * nlayer, 4 * nlayer) DVADP = np.zeros((4 * nlayer, len(waves)), float) * np.nan # ---- # parallel # ---- def fun(i, modeli): ztopi, logvsi, logpri, logrhi = \ modeli[IZ], modeli[IVS], modeli[IPR], modeli[IRH] n = len(ztopi) ilayer = i % n if ilayer == n - 1: Hi = 1.e50 # thickness of the half-space else: Hi = ztopi[ilayer + 1] - ztopi[ilayer] try: logvaluesi = lognofail( dispersion(ztopi, np.exp(logvsi + logpri), np.exp(logvsi), np.exp(logrhi), waves, types, modes, freqs, h=h, dcl=dcl, dcr=dcr)) except CPiSDomainError as err: print("error during gradient computation %s" % str(err)) return i, None except: raise if norm: # sensitivity corrected from the layer thicknesses DVAVPi = (logvaluesi - logvalues0) / (modeli[i] - model0[i]) / Hi else: # absolute sensitivity regardless the thickness differences DVAVPi = (logvaluesi - logvalues0) / (modeli[i] - model0[i]) return i, DVAVPi # ---- def gen(): for i in xrange(1, 4 * len(ztop)): modeli = model0.copy() modeli[i] += dmodel[i] yield Job(i, modeli) # ---- with MapSync(fun, gen()) as ma: for _, (i, DVAVPi), _, _ in ma: if DVAVPi is None: continue DVADP[i, :] = DVAVPi for w, t, m, F, Iwtm in groupbywtm(waves, types, modes, freqs, np.arange(len(waves))): DLOGVADZ = DVADP[IZ, :][:, Iwtm] DLOGVADLOGPR = DVADP[IPR, :][:, Iwtm] DLOGVADLOGVS = DVADP[IVS, :][:, Iwtm] DLOGVADLOGRH = DVADP[IRH, :][:, Iwtm] DLOGVADZ, DLOGVADLOGVS, DLOGVADLOGPR, DLOGVADLOGRH = \ [np.ma.masked_where(np.isnan(_), _) for _ in [DLOGVADZ, DLOGVADLOGVS, DLOGVADLOGPR, DLOGVADLOGRH]] yield w, t, m, F, DLOGVADZ, DLOGVADLOGVS, DLOGVADLOGPR, DLOGVADLOGRH