1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU Lesser General Public License as published
7 //  by the Free Software Foundation; either version 3.0 of the License, or
8 //  any later version.
9 //
10 //  The GPSTk is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with GPSTk; if not, write to the Free Software Foundation,
17 //  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 //  This software was developed by Applied Research Laboratories at the
20 //  University of Texas at Austin.
21 //  Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 /// @file StatsFilterHit.hpp
40 /// A class used by stats filters (FirstDiffFilter, WindowFilter and FDiffFilter)
41 /// to hold results of the filters. StatsFilterHit is a simple class that contains
42 /// an index into the data array, the type of event (beginning-of-data, outlier,
43 /// slip, etc), the number of points in data arrays (just a delta index) and
44 /// the number of good points following the event. It has a
45 /// member function asString() that is used in the filter dump() routines.
46 
47 #ifndef STATISTICAL_FILTER_HIT_INCLUDE
48 #define STATISTICAL_FILTER_HIT_INCLUDE
49 
50 //------------------------------------------------------------------------------------
51 // TD NB pffrac is never used.
52 // NB WindowFilter does not find outliers
53 //------------------------------------------------------------------------------------
54 //------------------------------------------------------------------------------------
55 /// The 'results' object used by the filters to indicate presence of 'events' :
56 /// outlier(s), a slip or the beginning-of-data (BOD).
57 /// Each filter's analyze() function returns a std::vector of one or more these
58 /// objects; always with at least one element: the first is usually a BOD, but if
59 /// there are outliers at the start, it can be type outlier.
60 /// Calling the filter's getStats(FilterHit) will return statistics on the filter
61 /// quantities (not the data) in the segment that _begins_ at the event.
62 template <class T> class FilterHit
63 {
64 public:
65    /// enum used to indicate the kind of event in this result
66    typedef enum EventType {
67       BOD = 0,          ///< beginning of data
68       outlier,          ///< outlier(s) - npts is the number of outliers
69       slip,             ///< slip (discontinuity)
70       other             ///< never used?
71    } event;
72 
73    /// empty and only constructor
FilterHit()74    FilterHit() : index(-1), type(BOD), npts(0), ngood(0), score(0),
75                  step(T(0)), sigma(T(0)), dx(T(0)),
76                  haveStats(false) { }
77 
78    // member data
79    event type;          ///< type of event: BOD, outlier(s), slip, other
80 
81    unsigned int index;  ///< index in the data array(s) at which this event occurs
82    unsigned int npts;   ///< number of data points in this segment (= a delta index)
83    unsigned int ngood;  ///< number of good (flag==0) points in this segment
84    unsigned int score;  ///< weight of slip (=100 except >=lim for getMaybeSlips(lim))
85 
86    T step;              ///< for a slip, an estimate of the step in the data
87    T sigma;             ///< for a slip, RSS future and past sigma on the data
88    T dx;                ///< step in xdata: before SLIP or after OUT
89 
90    bool haveStats;      ///< set true when getStats() is called
91    // see getStats() - meanings depend on filter
92    T min,max,med,mad;   ///< robust stats on the filter quantities (not data)
93 
94    std::string msg;     ///< message from analysis
95 
96    /// convenience routines
isBOD(void)97    bool isBOD(void) { return (type == BOD); }
isOutlier(void)98    bool isOutlier(void) { return (type == outlier); }
isSlip(void)99    bool isSlip(void) { return (type == slip); }
100 
101    /// return the analysis message
analMsg(void) const102    std::string analMsg(void) const
103       { return msg; }
104 
105    /// return as a single string with just type, index and npts
asString(const int osp=3) const106    std::string asString(const int osp=3) const
107    {
108       std::stringstream oss;
109       switch(type) {
110          case BOD: oss << "BOD"; break;
111          case outlier: oss << "OUT"; break;
112          case slip: oss << "SLIP"; break;
113          default: case other: oss << "other"; break;
114       }
115       oss << std::fixed << std::setprecision(osp);
116 
117       // ind npts step dx sig score - be sure this order matches asStringRead()
118       oss << " " << index << " " << npts << " " << dx;
119       if(type == slip) oss << " " << step << " " << sigma << " " << score;
120       else             oss << " ?" << " ?" << " ?";
121 
122       return oss.str();
123    }
124 
125    /// return as a single human-readable string giving all the relevant info
asStringRead(const int osp=3) const126    std::string asStringRead(const int osp=3) const
127    {
128       std::stringstream oss;
129       switch(type) {
130          case BOD: oss << "BOD"; break;
131          case outlier: oss << "OUT"; break;
132          case slip: oss << "SLIP"; break;
133          default: case other: oss << "other"; break;
134       }
135       oss << " ind=" << index << " npts=" << npts
136             << std::fixed << std::setprecision(osp)
137             << " x_gap=" << dx;
138       if(type == slip) oss << " step=" << step << " sig=" << sigma
139                            << " score=" << score << (score<100 ? " SMALL":"");
140 
141       return oss.str();
142    }
143 
144    /// return as a longer single string containing asString() plus stats
145    /// @param osp precision for fixed format
asStatsString(const int osp=3) const146    std::string asStatsString(const int osp=3) const
147    {
148       std::stringstream oss;
149       oss << asString(osp) << std::fixed << std::setprecision(osp);
150       if(!haveStats)
151          oss << "; NoSt";
152       else
153          oss << " min=" << min << " max=" << max << " med=" << med << " mad=" << mad;
154       return oss.str();
155    }
156 
157 }; // end class FilterHit
158 
159 //------------------------------------------------------------------------------------
160 //------------------------------------------------------------------------------------
161 #endif   // #define STATISTICAL_FILTER_HIT_INCLUDE
162