def _stats(self, distribution_f0): distribution_f0 = Hvsr.correct_distribution(distribution_f0) if distribution_f0 == "lognormal": columns = ["Lognormal Median", "Lognormal Standard Deviation"] data = np.array([[ self.mean_f0_frq(distribution_f0), self.std_f0_frq(distribution_f0) ], [ 1 / self.mean_f0_frq(distribution_f0), self.std_f0_frq(distribution_f0) ]]) elif distribution_f0 == "normal": columns = ["Means", "Standard Deviation"] data = np.array([[ self.mean_f0_frq(distribution_f0), self.std_f0_frq(distribution_f0) ], [np.nan, np.nan]]) else: msg = f"`distribution_f0` of {distribution_f0} is not implemented." raise NotImplementedError(msg) df = DataFrame(data=data, columns=columns, index=[ "Fundamental Site Frequency, f0,AZ", "Fundamental Site Period, T0,AZ" ]) return df
def peak_index(curve): """Find index to the peak of the provided curve.""" curve = curve.reshape((1, curve.size)) pot_peak_indices, _ = Hvsr.find_peaks(curve) pot_peak_indices = pot_peak_indices[0] pot_peak_amp = curve[0, pot_peak_indices] pot_peak_index = np.argwhere(pot_peak_amp == np.max(pot_peak_amp))[0][0] return pot_peak_indices[pot_peak_index]
def _make_hvsr(self, method, resampling, bandwidth, f_low=None, f_high=None, azimuth=None): if method in ["squared-average", "geometric-mean"]: ffts = self.transform() hor = self._combine_horizontal_fd(method=method, ew=ffts["ew"], ns=ffts["ns"]) ver = ffts["vt"] del ffts elif method == "single-azimuth": hor = self._combine_horizontal_td(method=method, azimuth=azimuth) hor = FourierTransform.from_timeseries(hor) ver = FourierTransform.from_timeseries(self.vt) else: msg = f"`method`={method} has not been implemented." raise NotImplementedError(msg) self.meta["method"] = method self.meta["azimuth"] = azimuth if resampling["res_type"] == "linear": frq = np.linspace(resampling["minf"], resampling["maxf"], resampling["nf"]) elif resampling["res_type"] == "log": frq = np.geomspace(resampling["minf"], resampling["maxf"], resampling["nf"]) else: msg = f"`res_type`={resampling['res_type']} has not been implemented." raise NotImplementedError(msg) hor.smooth_konno_ohmachi_fast(frq, bandwidth) ver.smooth_konno_ohmachi_fast(frq, bandwidth) hor._amp /= ver._amp hvsr = hor del ver if self.ns.nseries == 1: window_length = max(self.ns.time) else: window_length = max(self.ns.time[0]) self.meta["Window Length"] = window_length return Hvsr(hvsr.amplitude, hvsr.frequency, find_peaks=False, f_low=f_low, f_high=f_high, meta=self.meta)
def _mean_factory(distribution, values, **kwargs): distribution = Hvsr.correct_distribution(distribution) if distribution == "normal": mean = np.mean([np.mean(x, **kwargs) for x in values], **kwargs) return mean elif distribution == "lognormal": mean = np.mean([np.mean(np.log(x), **kwargs) for x in values], **kwargs) return np.exp(mean) else: msg = f"distribution type {distribution} not recognized." raise NotImplementedError(msg)
def _make_hvsr(self, method, resampling, bandwidth, azimuth=None): if method in ["squared-average", "geometric-mean"]: ffts = self.transform() hor = self.combine_horizontals(method=method, horizontals=ffts) ver = ffts["vt"] del ffts elif method == "single-azimuth": hor = self.combine_horizontals(method=method, horizontals={"ew": self.ew, "ns": self.ns}, azimuth=azimuth) if isinstance(hor, WindowedTimeSeries): hor = FourierTransformSuite.from_timeseries(hor) ver = FourierTransformSuite.from_timeseries(self.vt) elif isinstance(hor, TimeSeries): hor = FourierTransform.from_timeseries(hor) ver = FourierTransform.from_timeseries(self.vt) else: raise NotImplementedError else: msg = f"`method`={method} has not been implemented." raise NotImplementedError(msg) self.meta["method"] = method self.meta["azimuth"] = azimuth if resampling["res_type"] == "linear": frq = np.linspace(resampling["minf"], resampling["maxf"], resampling["nf"]) elif resampling["res_type"] == "log": frq = np.geomspace(resampling["minf"], resampling["maxf"], resampling["nf"]) else: raise NotImplementedError hor.smooth_konno_ohmachi_fast(frq, bandwidth) ver.smooth_konno_ohmachi_fast(frq, bandwidth) hor.amp /= ver.amp hvsr = hor del ver if self.ns.n_windows == 1: window_length = max(self.ns.time) else: window_length = max(self.ns.time[0]) self.meta["Window Length"] = window_length return Hvsr(hvsr.amp, hvsr.frq, find_peaks=False, meta=self.meta)
def mc_peak_frq(self, distribution='log-normal'): """Frequency of the peak of the mean H/V curve. Parameters ---------- distribution : {'normal', 'log-normal'}, optional Refer to :meth:`mean_curve <Hvsr.mean_curve>` for details. Returns ------- float Frequency associated with the peak of the mean H/V curve. """ mc = self.mean_curve(distribution) return float(self.frq[np.where(mc == np.max(mc[Hvsr.find_peaks(mc)[0]]))])
def mc_peak_amp(self, distribution='log-normal'): """Amplitude of the peak of the mean H/V curve. Parameters ---------- distribution : {'normal', 'log-normal'}, optional Refer to :meth:`mean_curve <Hvsr.mean_curve>` for details. Returns ------- float Amplitude associated with the peak of the mean H/V curve. """ mc = self.mean_curve(distribution) return np.max(mc[Hvsr.find_peaks(mc)[0]])
def mc_peak_frq(self, distribution='lognormal'): """Frequency of the peak of the mean HVSR curve. Parameters ---------- distribution : {'normal', 'lognormal'}, optional Refer to :meth:`mean_curve <Hvsr.mean_curve>` for details. Returns ------- float Frequency associated with the peak of the mean HVSR curve. """ mc = self.mean_curve(distribution) mc = mc.reshape((1, mc.size)) i_low, i_high = self.hvsrs[0].i_low, self.hvsrs[0].i_high return self.frq[i_low + int(np.where(mc[0, i_low:i_high] == np.max(mc[0, Hvsr.find_peaks(mc[:, i_low:i_high], starting_index=i_low)[0]]))[0])]
def mc_peak_amp(self, distribution='lognormal'): """Amplitude of the peak of the mean HVSR curve. Parameters ---------- distribution : {'normal', 'lognormal'}, optional Refer to :meth:`mean_curve <Hvsr.mean_curve>` for details. Returns ------- float Amplitude associated with the peak of the mean HVSR curve. """ mc = self.mean_curve(distribution) mc = mc.reshape((1, mc.size)) i_low, i_high = self.hvsrs[0].i_low, self.hvsrs[0].i_high return np.max(mc[0, Hvsr.find_peaks(mc[:, i_low:i_high], starting_index=i_low)[0]])
def _std_factory(distribution, values, **kwargs): distribution = Hvsr.correct_distribution(distribution) n = len(values) mean = HvsrRotated._mean_factory(distribution, values, **kwargs) num = 0 wi2 = 0 if distribution == "normal": def _diff(value, mean): return value - mean elif distribution == "lognormal": def _diff(value, mean): return np.log(value) - np.log(mean) for value in values: i = len(value) diff = _diff(value, mean) wi = 1/(n*i) num += np.sum(diff*diff*wi, **kwargs) wi2 += wi*wi*i return np.sqrt(num/(1-wi2))
def _hvsrpy_style_lines(self, distribution_f0, distribution_mc): """Lines for hvsrpy-style file.""" # Correct distribution distribution_f0 = Hvsr.correct_distribution(distribution_f0) distribution_mc = Hvsr.correct_distribution(distribution_mc) # `f0` from windows mean_f = self.mean_f0_frq(distribution_f0) sigm_f = self.std_f0_frq(distribution_f0) ci_68_lower_f = self.nstd_f0_frq(-1, distribution_f0) ci_68_upper_f = self.nstd_f0_frq(+1, distribution_f0) # mean curve mc = self.mean_curve(distribution_mc) mc_peak_frq = self.mc_peak_frq(distribution_mc) mc_peak_amp = self.mc_peak_amp(distribution_mc) _min = self.nstd_curve(-1, distribution_mc) _max = self.nstd_curve(+1, distribution_mc) rejection = "False" if self.meta.get( 'Performed Rejection') is None else "True" nseries = self.hvsrs[0].nseries n_accepted = sum( [sum(hvsr.valid_window_indices) for hvsr in self.hvsrs]) n_rejected = self.azimuth_count * nseries - n_accepted lines = [ f"# hvsrpy output version {__version__}", f"# File Name (),{self.meta.get('File Name')}", f"# Window Length (s),{self.meta.get('Window Length')}", f"# Total Number of Windows per Azimuth (),{nseries}", f"# Total Number of Azimuths (),{self.azimuth_count}", f"# Frequency Domain Window Rejection Performed (),{rejection}", f"# Lower frequency limit for peaks (Hz),{self.hvsrs[0].f_low}", f"# Upper frequency limit for peaks (Hz),{self.hvsrs[0].f_high}", f"# Number of Standard Deviations Used for Rejection () [n],{self.meta.get('n')}", f"# Number of Accepted Windows (),{n_accepted}", f"# Number of Rejected Windows (),{n_rejected}", f"# Distribution of f0 (),{distribution_f0}" ] def fclean(number, decimals=4): return np.round(number, decimals=decimals) if distribution_f0 == "lognormal": mean_t = 1 / mean_f sigm_t = sigm_f ci_68_lower_t = np.exp(np.log(mean_t) - sigm_t) ci_68_upper_t = np.exp(np.log(mean_t) + sigm_t) lines += [ f"# Median f0 (Hz) [LMf0AZ],{fclean(mean_f)}", f"# Lognormal standard deviation f0 () [SigmaLNf0AZ],{fclean(sigm_f)}", f"# 68 % Confidence Interval f0 (Hz),{fclean(ci_68_lower_f)},to,{fclean(ci_68_upper_f)}", f"# Median T0 (s) [LMT0AZ],{fclean(mean_t)}", f"# Lognormal standard deviation T0 () [SigmaLNT0AZ],{fclean(sigm_t)}", f"# 68 % Confidence Interval T0 (s),{fclean(ci_68_lower_t)},to,{fclean(ci_68_upper_t)}", ] else: lines += [ f"# Mean f0 (Hz) [f0AZ],{fclean(mean_f)}", f"# Standard deviation f0 (Hz) [Sigmaf0AZ],{fclean(sigm_f)}", f"# 68 % Confidence Interval f0 (Hz),{fclean(ci_68_lower_f)},to,{fclean(ci_68_upper_f)}", f"# Mean T0 (s) [LMT0AZ],NAN", f"# Standard deviation T0 () [SigmaT0AZ],NAN", f"# 68 % Confidence Interval T0 (s),NAN", ] c_type = "Median" if distribution_mc == "lognormal" else "Mean" lines += [ f"# {c_type} Curve Distribution (),{distribution_mc}", f"# {c_type} Curve Peak Frequency (Hz) [f0mcAZ],{fclean(mc_peak_frq)}", f"# {c_type} Curve Peak Amplitude (),{fclean(mc_peak_amp)}", f"# Frequency (Hz),{c_type} Curve,1 STD Below {c_type} Curve,1 STD Above {c_type} Curve", ] _lines = [] for line in lines: _lines.append(line + "\n") for f_i, mean_i, bel_i, abv_i in zip(fclean(self.frq), fclean(mc), fclean(_min), fclean(_max)): _lines.append(f"{f_i},{mean_i},{bel_i},{abv_i}\n") return _lines
def _nth_std_factory(n, distribution, mean, std): return Hvsr._nth_std_factory(n=n, distribution=distribution, mean=mean, std=std)
def peak_index(curve): """Find index to the peak of the provided curve.""" pot_peak_indices, _ = Hvsr.find_peaks(curve) pot_peak_amp = curve[pot_peak_indices] pot_peak_index = np.argwhere(pot_peak_amp == np.max(pot_peak_amp))[0][0] return pot_peak_indices[pot_peak_index]