version  0.0.1
Defines the C++ API for MsPASS
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | List of all members
mspass::algorithms::SegmentVectorProperties Class Reference

Public Member Functions

 SegmentVectorProperties (const std::vector< TimeSeries > &segments)
 
 SegmentVectorProperties (const SegmentVectorProperties &parent)
 

Public Attributes

bool dt_constant
 
bool has_dead_components
 
bool is_sorted
 
bool has_overlaps
 
bool has_gaps
 
int number_live
 
int first_live
 
double t0
 
double endtime
 
double dt
 
size_t spliced_nsamp
 
ErrorLogger elog
 

Detailed Description

File scope class to enscapsulate set of possible data problems.

Merging multiple data segments to a single time series, which is a common need with continous data, is prone to a number of practical problems. Clock issues and the design of modern digitizers can cause a mismatch in time computed by dt*nsamp and data time tags with formats like miniseed. This can create apparent gaps or overlaps. This class is intended to be used to scan a vector of time-sorted segment to flag issues that need to be handled downstream in algorithms later in this file. Issues it addresses at present are:

  1. irregular dt
  2. segments marked dead
  3. overlaps
  4. gaps
  5. Computes the length of the data being merged. Callers should test that that number is not absurd and could cause a memory alloc fault.

All attributes of this class are intentionally public as it should be thought of as a struct with convenient constructors.

Constructor & Destructor Documentation

◆ SegmentVectorProperties() [1/3]

mspass::algorithms::SegmentVectorProperties::SegmentVectorProperties ( )
66 : elog() {
67 dt_constant = true;
68 has_dead_components = false;
69 is_sorted = true;
70 has_overlaps = false;
71 has_gaps = false;
72 number_live = 0;
73 first_live = 0;
74 t0 = 0.0;
75 endtime = 0.0;
76 dt = 0.0;
77 spliced_nsamp = 0;
78}

◆ SegmentVectorProperties() [2/3]

mspass::algorithms::SegmentVectorProperties::SegmentVectorProperties ( const std::vector< TimeSeries > &  segments)
95 {
96 /* Return a type conversion of the input when there is only one
97 segment - nothing to splice in that case. Error if it is empty */
98 if (segments.size() == 1) {
99 dt_constant = true;
100 has_dead_components = false;
101 is_sorted = true;
102 has_overlaps = false;
103 has_gaps = false;
104 if (segments[0].live()) {
105 number_live = 1;
106 first_live = 0;
107 t0 = segments[0].t0();
108 endtime = segments[0].endtime();
109 dt = segments[0].dt();
110 this->spliced_nsamp = segments[0].npts();
111 } else {
112 number_live = 0;
113 first_live = -1;
114 t0 = 0.0;
115 dt = 0.0;
116 endtime = 0.0;
117 this->spliced_nsamp = 0;
118 }
119 } else if (segments.size() == 0) {
120 dt_constant = true;
121 has_dead_components = false;
122 is_sorted = true;
123 has_overlaps = false;
124 has_gaps = false;
125 number_live = 0;
126 first_live = -1;
127 t0 = 0.0;
128 dt = 0.0;
129 endtime = 0.0;
130 this->spliced_nsamp = 0;
131 } else {
132 double test_dt, dtfrac;
133 double first_t0, previous_t0, previous_endtime;
134 /* This algorithm requires the test above that guarantees number of segments
135 is more than 1. Some complexity to handle a dead member 0 is needed. */
136 bool this_is_first(true);
137 has_overlaps = false;
138 is_sorted = true; // initialization
139 has_dead_components = false;
140 /* Declare a sample mismatch if nondimensional sample interval mismatch is
141 less than this constant. */
142 const double dt_fraction_mismatch(0.001);
143 for (size_t i = 0; i < segments.size(); ++i) {
144 if (segments[i].dead()) {
145 has_dead_components = true;
146 continue;
147 }
148 if (this_is_first) {
149 this->dt_constant = true;
150 this->first_live = i;
151 first_t0 = segments[i].t0();
152 previous_t0 = first_t0;
153 test_dt = segments[i].dt();
154 previous_endtime = segments[i].endtime();
155 this_is_first = false;
156 this->dt = test_dt;
157 this->t0 = first_t0;
158 this->number_live = 1;
159 } else {
160 /* This could be true multiple times if data were not sorted.
161 Purpose of this boolean is to define a serious error condition
162 that functions using this class must handle */
163 if (segments[i].t0() < previous_t0)
164 is_sorted = false;
165 /* Test for overlaps - note sign is important */
166 if ((previous_endtime + test_dt * TIME_TEAR_TOLERANCE) >
167 segments[i].t0())
168 has_overlaps = true;
169 /* test for gaps */
170 if ((segments[i].t0() - previous_endtime - test_dt) / test_dt >
171 TIME_TEAR_TOLERANCE)
172 has_gaps = true;
173 /* Check for sample interval mismatch */
174 dtfrac = fabs(segments[i].dt() - test_dt) / test_dt;
175 if (dtfrac > dt_fraction_mismatch)
176 dt_constant = false;
177 previous_endtime = segments[i].endtime();
178 previous_t0 = segments[i].t0();
179 ++this->number_live;
180 }
181 }
182 this->endtime = previous_endtime;
183 this->spliced_nsamp = lround((previous_endtime - this->t0) / this->dt);
184 ++this->spliced_nsamp; // nsamp is always one sample longer than intervals
185 }
186}

◆ SegmentVectorProperties() [3/3]

mspass::algorithms::SegmentVectorProperties::SegmentVectorProperties ( const SegmentVectorProperties parent)
81 : elog(parent.elog) {
82 dt_constant = parent.dt_constant;
83 has_dead_components = parent.has_dead_components;
84 is_sorted = parent.is_sorted;
85 has_overlaps = parent.has_overlaps;
86 has_gaps = parent.has_gaps;
87 number_live = parent.number_live;
88 first_live = parent.first_live;
89 t0 = parent.t0;
90 endtime = parent.endtime;
91 dt = parent.dt;
92 spliced_nsamp = parent.spliced_nsamp;
93}

The documentation for this class was generated from the following file: