3#include "mspass/algorithms/TimeWindow.h"
4#include "mspass/algorithms/algorithms.h"
5#include "mspass/seismic/Ensemble.h"
6#include "mspass/seismic/PowerSpectrum.h"
7#include "mspass/seismic/Seismogram.h"
8#include "mspass/seismic/TimeSeries.h"
9#include "mspass/utility/Metadata.h"
10#include "mspass/utility/MsPASSError.h"
11#include "mspass/utility/VectorStatistics.h"
15namespace mspass::algorithms::amplitudes {
26enum class ScalingMethod {
32const std::string scale_factor_key(
"calib");
60template <
typename Tdata>
61double scale(Tdata &d,
const ScalingMethod method,
const double level,
63 if ((method == ScalingMethod::ClipPerc) && (level <= 0.0 || level > 1.0))
65 "scale function: illegal perf level specified for clip percentage "
66 "scale - must be between 0 and 1\nData unaltered - may cause "
67 "downstream problems",
68 mspass::utility::ErrorSeverity::Suspect);
74 if (d.is_defined(scale_factor_key)) {
75 newcalib = d.get_double(scale_factor_key);
81 ampwindow.
start = d.t0();
82 ampwindow.
end = d.endtime();
85 ampwindow.
end = std::min(win.
end, d.endtime());
86 if (ampwindow.
start > ampwindow.
end) {
88 ss <<
"scale: amplitude measurement window [" << win.
start <<
", "
89 << win.
end <<
"] has no intersection with data "
90 <<
"range [" << d.t0() <<
", " << d.endtime() <<
"]";
92 ss.str(), mspass::utility::ErrorSeverity::Invalid);
96 windowed_data = mspass::algorithms::WindowData(d, ampwindow);
97 double amplitude, dscale;
99 case ScalingMethod::Peak:
100 amplitude = PeakAmplitude(windowed_data);
102 case ScalingMethod::ClipPerc:
103 amplitude = PercAmplitude(windowed_data, level);
105 case ScalingMethod::MAD:
106 amplitude = MADAmplitude(windowed_data);
108 case ScalingMethod::RMS:
110 amplitude = RMSAmplitude(windowed_data);
113 if (amplitude > 0.0) {
114 dscale = level / amplitude;
117 d.put(scale_factor_key, newcalib);
119 std::stringstream ss;
120 ss <<
"Data array is all 0s and cannot be scaled";
121 d.elog.log_error(
"scale", ss.str(),
122 mspass::utility::ErrorSeverity::Complaint);
125 d.put(scale_factor_key, newcalib);
156template <
typename Tdata>
159 const ScalingMethod &method,
const double level,
161 if ((method == ScalingMethod::ClipPerc) && (level <= 0.0 || level > 1.0))
163 "scale_ensemble_members function: illegal perf level specified for "
164 "clip percentage scale - must be between 0 and 1\nData unaltered - may "
165 "cause downstream problems",
166 mspass::utility::ErrorSeverity::Suspect);
168 typename std::vector<Tdata>::iterator dptr;
169 std::vector<double> amps;
170 amps.reserve(d.
member.size());
171 for (dptr = d.
member.begin(); dptr != d.
member.end(); ++dptr) {
173 thisamp = scale(*dptr, method, level, win);
174 amps.push_back(thisamp);
201template <
typename Tdata>
203 const ScalingMethod &method,
const double level,
204 const bool use_mean) {
205 if ((method == ScalingMethod::ClipPerc) && (level <= 0.0 || level > 1.0))
207 "scale_ensemble function: illegal perf level specified for clip "
208 "percentage scale - must be between 0 and 1\nData unaltered - may "
209 "cause downstream problems",
210 mspass::utility::ErrorSeverity::Suspect);
214 typename std::vector<Tdata>::iterator dptr;
215 std::vector<double> amps;
216 amps.reserve(d.
member.size());
217 for (dptr = d.
member.begin(); dptr != d.
member.end(); ++dptr) {
222 case ScalingMethod::Peak:
223 amplitude = PeakAmplitude(*dptr);
225 case ScalingMethod::ClipPerc:
226 amplitude = PercAmplitude(*dptr, level);
228 case ScalingMethod::MAD:
229 amplitude = MADAmplitude(*dptr);
231 case ScalingMethod::RMS:
233 amplitude = RMSAmplitude(*dptr);
235 if ((amplitude > 0.0) && std::isfinite(amplitude))
236 amps.push_back(std::log(amplitude));
241 if (amps.size() == 1) {
242 avgamp = amps.front();
246 avgamp = ampstats.mean();
248 avgamp = ampstats.median();
253 avgamp = std::exp(avgamp);
259 double dscale = level / avgamp;
261 for (dptr = d.
member.begin(); dptr != d.
member.end(); ++dptr) {
265 if (dptr->is_defined(scale_factor_key)) {
266 calib = dptr->get_double(scale_factor_key);
271 dptr->put(scale_factor_key, calib);
280template <
class T> std::vector<T> normalize(
const std::vector<T> &d) {
282 std::vector<T> result;
286 for (
size_t i = 0; i < N; ++i) {
287 d_nrm += (d[i] * d[i]);
288 result.push_back(d[i]);
291 for (
size_t i = 0; i < N; ++i)
341 return 20.0 * log10(ratio);
403 const double snr_threshold,
const double tbp,
404 const double fhs = -1.0,
405 const bool fix_high_edge_to_fhs =
false);
Defines a time window.
Definition TimeWindow.h:12
double start
Definition TimeWindow.h:17
double end
Definition TimeWindow.h:21
Holds parameters defining a passband computed from snr.
Definition amplitudes.h:304
double low_edge_f
Definition amplitudes.h:307
double bandwidth() const
Definition amplitudes.h:332
double bandwidth_fraction() const
Definition amplitudes.h:325
double high_edge_f
Definition amplitudes.h:309
double f_range
Definition amplitudes.h:315
double low_edge_snr
Definition amplitudes.h:311
double high_edge_snr
Definition amplitudes.h:313
Vector (three-component) seismogram data object.
Definition CoreSeismogram.h:39
Scalar time series data object.
Definition CoreTimeSeries.h:17
Metadata-bearing container for a collection of seismic data objects.
Definition Ensemble.h:14
std::vector< Tdata > member
Container holding data objects.
Definition Ensemble.h:25
Definition PowerSpectrum.h:11
Base class for error object thrown by MsPASS library routines.
Definition MsPASSError.h:38
Generic object to compute common robust statistics from a vector container of data.
Definition VectorStatistics.h:16