GPLIB++
DelayFilter.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <algorithm>
4 #include <cmath>
5 #include <sstream>
6 #include <numeric>
7 #include "TimeSeriesData.h"
8 #include "StackedSpectrum.h"
9 #include "WFunc.h"
10 #include <boost/bind.hpp>
11 
12 using namespace std;
13 using namespace gplib;
14 
15 string version = "$Id: DelayFilter.cpp 1816 2009-09-07 11:28:35Z mmoorkamp $";
16 
17 void SubShiftedComponent(vector<double> &Original, vector<double> &Shifted,
18  const int shiftsteps)
19  {
20  transform(Original.begin(), Original.end() - shiftsteps, Shifted.begin()
21  + shiftsteps, Original.begin(), minus<double> ());
22  const double factor = 1. / sqrt(2.);
23  transform(Original.begin(), Original.end(), Original.begin(), boost::bind(
24  multiplies<double> (), _1, factor));
25  }
26 
27 void FindSpikeDistances(const vector<double> &ts)
28  {
29  const int blocklength = 2400;
30  const int nsegments = ts.size() / blocklength;
31  const double threshold = 1e4;
32  double spikedist = 0;
33  int spikecount = 0;
34  vector<double>::const_iterator currstart(ts.begin()), currend(ts.begin()
35  + blocklength);
36  vector<double> differences(blocklength, 0.0);
37  for (int i = 0; i < nsegments; ++i)
38  {
39  adjacent_difference(currstart, currend, differences.begin());
40  vector<double>::iterator firstspike = find_if(differences.begin(),
41  differences.end(), boost::bind(greater<double> (), boost::bind(
42  (double(*)(double)) &abs, _1), threshold)); //find first with absolute difference greater threshold
43  vector<double>::iterator nextspike = firstspike;
44  while (nextspike != differences.end())
45  {
46  nextspike = find_if(firstspike + 1, differences.end(), boost::bind(
47  greater<double> (), boost::bind((double(*)(double)) &abs, _1),
48  threshold)); //find first with absolute difference greater threshold
49  if (nextspike != currend)
50  {
51  spikedist += distance(firstspike, nextspike);
52  ++spikecount;
53  }
54  firstspike = nextspike;
55  }
56  currstart += blocklength;
57  currend += blocklength;
58  }
59  cout << "Spike count: " << spikecount << " Avg. Dist: " << spikedist
60  / spikecount << endl;
61  }
62 
63 int main()
64  {
65  TimeSeriesData OriginalData, ShiftedData;
66 
67  string infilename, outfilename, search;
68  int seglength = 2400;
69  double freqstep;
70  int startindex, endindex, maxindex = 0;
71  const double searchstart = 0.2;
72  const double searchend = 1.0;
73  double absmax = 0;
74  int shiftsteps;
75 
76  cout << "This is dfilter: Apply a delay filter to MT time series file"
77  << endl << endl;
78  cout << "At this point no command line parameters, only interactive."
79  << endl << endl;
80  cout << "This is Version: " << version << endl << endl;
81 
82  cout << "Input Filename: ";
83  cin >> infilename;
84  OriginalData.GetData(infilename);
85  cout << "Output Filename: ";
86  cin >> outfilename;
87  cout << " Enter 'a' for automatic, or number of points to shift: ";
88  cin >> search;
89  freqstep = OriginalData.GetData().GetSamplerate() * 1. / seglength;
90  if (search == "a")
91  {
92  vector<complex<double> > ExSpectrum(seglength / 2 + 1);
93 
94  cout << "Performing search" << endl;
95  FindSpikeDistances(OriginalData.GetData().GetEx().GetData());
96  StackedSpectrum(OriginalData.GetData().GetEx().GetData().begin(),
97  OriginalData.GetData().GetEx().GetData().end(), ExSpectrum.begin(),
98  seglength, Hanning());
99 
100  startindex = round(searchstart / freqstep);
101  endindex = round(searchend / freqstep);
102  for (int i = startindex; i < endindex; ++i)
103  {
104  if (abs(ExSpectrum.at(i)) > absmax)
105  {
106  maxindex = i;
107  absmax = abs(ExSpectrum.at(i));
108  }
109  }
110  shiftsteps = round(OriginalData.GetData().GetSamplerate() / (maxindex
111  * freqstep)) - 1;
112  cout << "Spike frequency: " << maxindex * freqstep << " Height: "
113  << absmax << endl;
114  }
115  else
116  {
117  istringstream convStream(search);
118  convStream >> shiftsteps;
119  maxindex = OriginalData.GetData().GetSamplerate() / (shiftsteps
120  * freqstep);
121  }
122 
123  cout << "Shifted by: " << shiftsteps << " exact: "
124  << OriginalData.GetData().GetSamplerate() / (maxindex * freqstep)
125  << endl;
126  ShiftedData = OriginalData;
127 
128  SubShiftedComponent(OriginalData.GetData().GetEx().GetData(),
129  ShiftedData.GetData().GetEx().GetData(), shiftsteps);
130  SubShiftedComponent(OriginalData.GetData().GetEy().GetData(),
131  ShiftedData.GetData().GetEy().GetData(), shiftsteps);
132  SubShiftedComponent(OriginalData.GetData().GetHx().GetData(),
133  ShiftedData.GetData().GetHx().GetData(), shiftsteps);
134  SubShiftedComponent(OriginalData.GetData().GetHy().GetData(),
135  ShiftedData.GetData().GetHy().GetData(), shiftsteps);
136  SubShiftedComponent(OriginalData.GetData().GetHz().GetData(),
137  ShiftedData.GetData().GetHz().GetData(), shiftsteps);
138 
139  OriginalData.WriteAsMtu(outfilename);
140  return 0;
141  }
std::vector< double > & GetData()
Access for data vector, for ease of use and efficiency we return a reference.
void SubShiftedComponent(vector< double > &Original, vector< double > &Shifted, const int shiftsteps)
Definition: DelayFilter.cpp:17
TimeSeries & GetData()
return a reference to the actual object stored in the pointer
TimeSeriesComponent & GetEx()
Definition: TimeSeries.h:47
double GetSamplerate()
The samplerate is stored in each component, we just return the samplerate of Hx assuming they are all...
Definition: TimeSeries.h:71
TimeSeriesComponent & GetHy()
Definition: TimeSeries.h:39
void WriteAsMtu(std::string filename_base)
Write data to file in Phoenix MTU format.
int main()
Definition: DelayFilter.cpp:63
string version
Definition: DelayFilter.cpp:15
TimeSeriesData stores a pointer to the different components of magnetotelluric data and provides func...
void FindSpikeDistances(const vector< double > &ts)
Definition: DelayFilter.cpp:27
This functor returns the weighting factor for the Hanning window, given the relative position (0...
Definition: WFunc.h:31
TimeSeriesComponent & GetEy()
Definition: TimeSeries.h:51
TimeSeriesComponent & GetHz()
Definition: TimeSeries.h:43
void StackedSpectrum(InputIterator tsbegin, InputIterator tsend, OutputIterator freqbegin, const size_t seglength, WindowFunctype WFunc)
This template is used to calculate stacked spectra for example for power spectrum estimation...
TimeSeriesComponent & GetHx()
Access function for Hx, returns reference for efficiency.
Definition: TimeSeries.h:35