GPLIB++
mtucorr.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <fstream>
4 #include <vector>
5 #include "ShortCorr.h"
6 #include "convert.h"
7 #include "WFunc.h"
8 #include "TimeSeriesData.h"
9 
10 using namespace std;
11 using namespace gplib;
12 
13 string version = "$Id: mtucorr.cpp 1816 2009-09-07 11:28:35Z mmoorkamp $";
14 
15 //! Calculate the correlation between the filed component and a spike and write the correlation to a file
16 void CalcCorrAndWrite(ttsdata &Data, ttsdata &Short, ttsdata &Corr, string name)
17  {
18  ofstream outfile(name.c_str());
19  ShortCorr(Data.begin(), Data.end(), Short.begin(), Short.end(),
20  Corr.begin());
21  copy(Corr.begin(), Corr.end(), ostream_iterator<double> (outfile, "\n"));
22  }
23 
24 //! Find the next spike by examining the first difference
25 void FindNextSpike(ttsdata::iterator &currstart, ttsdata &Data, ttsdata &Spike,
26  const int trailpoints, const int decaypoints, const double diffthreshold)
27  {
28  ttsdata diffdata;
29  diffdata.reserve(Data.size());
30  adjacent_difference(Data.begin(), Data.end(), back_inserter(diffdata));
31  ttsdata::iterator currdiff = diffdata.begin() + distance(Data.begin(),
32  currstart) + trailpoints;
33  ttsdata::iterator currdata = currstart + trailpoints;
34  bool spikefound = false;
35  Spike.assign(trailpoints + decaypoints, 0.0);
36  while (!spikefound && (currdata + decaypoints < Data.end()))
37  {
38  if (*currdiff > diffthreshold)
39  {
40  copy(currdata - trailpoints, currdata + decaypoints, Spike.begin());
41  spikefound = true;
42  currstart = currdata;
43  }
44  ++currdiff;
45  ++currdata;
46  }
47  }
48 
49 //! Remove spikes with the given form from the time-series
50 double RemoveSpike(ttsdata &Data, ttsdata &Spike, const double corrthreshold,
51  const int minspikeavg, string outname, const size_t iteration)
52  {
53  ttsdata Corr(Data.size(), 0.0);
54  SubMean(Spike.begin(), Spike.end());
55  CalcCorrAndWrite(Data, Spike, Corr, outname + stringify(iteration)
56  + ".corr");
57 
58  ttsdata::iterator datait = Data.begin();
59  ttsdata::iterator corrit = Corr.begin();
60  const int shortsize = Spike.size();
61  double spikecount = 0;
62  ttsdata avgspike(Spike.size(), 0.0);
63  while (datait + shortsize < Data.end()) //first iteration, create average
64  {
65  if (*corrit > corrthreshold)
66  {
67  ttsdata currsegment(datait, datait + shortsize);
68  SubMean(currsegment.begin(), currsegment.end());
69  transform(currsegment.begin(), currsegment.end(), avgspike.begin(),
70  avgspike.begin(), plus<double> ());
71  spikecount += 1.0;
72  }
73  ++datait;
74  ++corrit;
75  }
76  cout << " No. of spikes before average: " << spikecount << " ";
77  if (spikecount < minspikeavg)
78  {
79  cout << " below threshold of: " << minspikeavg << " not used." << endl;
80  return 0.0;
81  }
82  else
83  {
84  cout << endl;
85  double maxamp = *max_element(avgspike.begin(), avgspike.end());
86  transform(avgspike.begin(), avgspike.end(), avgspike.begin(),
87  boost::bind(multiplies<double> (), _1, 1. / maxamp)); //normalize maximum
88  ofstream avgfile((static_cast<std::string> ("spike") + stringify(
89  iteration) + static_cast<std::string> (".avg")).c_str());
90  copy(avgspike.begin(), avgspike.end(), ostream_iterator<double> (
91  avgfile, "\n"));
92 
93  spikecount = 0.0;
94 
95  CalcCorrAndWrite(Data, avgspike, Corr, outname + stringify(iteration)
96  + ".avg.corr");
97  datait = Data.begin();
98  corrit = Corr.begin();
99  while (datait + shortsize < Data.end()) //second iteration, remove average
100  {
101  if (*corrit > corrthreshold)
102  {
103  ttsdata currsegment(datait, datait + shortsize);
104  SubMean(currsegment.begin(), currsegment.end());
105  double segmaxamp = *max_element(currsegment.begin(),
106  currsegment.end());
107  ttsdata avgadjust(avgspike.begin(), avgspike.end());
108  transform(avgadjust.begin(), avgadjust.end(),
109  avgadjust.begin(), boost::bind(multiplies<double> (), _1,
110  segmaxamp));
111  transform(datait, datait + shortsize, avgadjust.begin(),
112  datait, minus<double> ());
113  spikecount += 1.0;
114  }
115  ++datait;
116  ++corrit;
117  }
118  cout << " No. of spikes after average: " << spikecount << endl;
119  }
120  return spikecount;
121  }
122 
123 //! The program mtucorr tries to identify spikes in the electric field of MT time-series data and remove them.
124 int main(int argc, char *argv[])
125  {
126  TimeSeriesData TsData;
127 
128  string masterfilename, shortfilename;
129 
130  double corrthreshold = 0.9;
131  double diffthreshold = 10000;
132  int trailpoints = 5;
133  int decaypoints = 20;
134  int iterations = 50;
135  int minspikeavg = 10;
136 
137  cout
138  << " This is mtucorr: Substract spikeform from a mtu time series for cow-fence denoising"
139  << endl << endl;
140  cout
141  << " Usage mtucorr You will have to enter the mtufilename and a number of parameters that determine which spike will be removed"
142  << endl;
143  cout
144  << " The output will have the same name as the Master filename with ending appended"
145  << endl << endl;
146  cout << " This is Version: " << version << endl << endl;
147 
148  cout << "Time Series filename: ";
149  cin >> masterfilename;
150  TsData.GetData(masterfilename);
151  cout << "Minimum differential spike height: ";
152  cin >> diffthreshold;
153  cout << "Number of trailing points: ";
154  cin >> trailpoints;
155  cout << "Number of decay points: ";
156  cin >> decaypoints;
157  cout << "Minimum correlation: ";
158  cin >> corrthreshold;
159  cout << "Minimum number of samples in average: ";
160  cin >> minspikeavg;
161  cout << "Number of Iterations: ";
162  cin >> iterations;
163  ttsdata ShortData;
164 
165  ttsdata::iterator currexstart = TsData.GetData().GetEx().GetData().begin();
166  ttsdata::iterator curreystart = TsData.GetData().GetEy().GetData().begin();
167  ttsdata::iterator currhxstart = TsData.GetData().GetHx().GetData().begin();
168  ttsdata::iterator currhystart = TsData.GetData().GetHy().GetData().begin();
169  double exspikes = 0;
170  double eyspikes = 0;
171  for (int i = 0; i < iterations; ++i)
172  {
173  cout << "Iteration: " << i + 1 << endl;
174  cout << " Ex Component" << endl;
175 
176  FindNextSpike(currexstart, TsData.GetData().GetEx().GetData(),
177  ShortData, trailpoints, decaypoints, diffthreshold);
178  exspikes += RemoveSpike(TsData.GetData().GetEx().GetData(), ShortData,
179  corrthreshold, minspikeavg, masterfilename, i);
180  cout << " Ey Component" << endl;
181  FindNextSpike(curreystart, TsData.GetData().GetEy().GetData(),
182  ShortData, trailpoints, decaypoints, diffthreshold);
183  eyspikes += RemoveSpike(TsData.GetData().GetEy().GetData(), ShortData,
184  corrthreshold, minspikeavg, masterfilename, i);
185  }
186  cout << "Total Spikes removed: " << endl;
187  cout << " Ex: " << exspikes << endl;
188  cout << " Ey: " << eyspikes << endl;
189  ofstream cleanfile((masterfilename + ".ex.clean").c_str());
190  copy(TsData.GetData().GetEx().GetData().begin(),
191  TsData.GetData().GetEx().GetData().end(), ostream_iterator<double> (
192  cleanfile, "\n"));
193  TsData.WriteAsMtu(masterfilename + ".clean");
194  }
195 
double RemoveSpike(ttsdata &Data, ttsdata &Spike, const double corrthreshold, const int minspikeavg, string outname, const size_t iteration)
Remove spikes with the given form from the time-series.
Definition: mtucorr.cpp:50
std::vector< double > & GetData()
Access for data vector, for ease of use and efficiency we return a reference.
TimeSeries & GetData()
return a reference to the actual object stored in the pointer
TimeSeriesComponent & GetEx()
Definition: TimeSeries.h:47
void SubMean(InputIterator begin, InputIterator end, typename std::iterator_traits< InputIterator >::value_type mean)
Substract the mean from each element in the container, mean is passed as a parameter.
Definition: statutils.h:85
int main(int argc, char *argv[])
The program mtucorr tries to identify spikes in the electric field of MT time-series data and remove ...
Definition: mtucorr.cpp:124
TimeSeriesComponent & GetHy()
Definition: TimeSeries.h:39
void WriteAsMtu(std::string filename_base)
Write data to file in Phoenix MTU format.
void CalcCorrAndWrite(ttsdata &Data, ttsdata &Short, ttsdata &Corr, string name)
Calculate the correlation between the filed component and a spike and write the correlation to a file...
Definition: mtucorr.cpp:16
TimeSeriesData stores a pointer to the different components of magnetotelluric data and provides func...
void ShortCorr(_InputIterator masterbegin, _InputIterator masterend, _InputIterator shortbegin, _InputIterator shortend, _OutputIterator outbegin)
Calculate the correlation between a short time series and a master time series.
Definition: ShortCorr.h:18
void FindNextSpike(ttsdata::iterator &currstart, ttsdata &Data, ttsdata &Spike, const int trailpoints, const int decaypoints, const double diffthreshold)
Find the next spike by examining the first difference.
Definition: mtucorr.cpp:25
string version
Definition: mtucorr.cpp:13
const int iterations
Definition: perftest.cpp:15
TimeSeriesComponent & GetEy()
Definition: TimeSeries.h:51
TimeSeriesComponent & GetHx()
Access function for Hx, returns reference for efficiency.
Definition: TimeSeries.h:35