GPLIB++
freqinter.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <vector>
4 #include "MTStationList.h"
5 #include "Util.h"
6 using namespace std;
7 using namespace gplib;
8 
9 void Interpolate(const std::vector<double> &xvalues, const std::vector<double> &yvalues,
10  const std::vector<double> &InterpX, std::vector<double> &InterpY)
11  {
12  const size_t ninter = InterpX.size();
13  size_t currindex = 0;
14  for (size_t i = 0; i < ninter; ++i)
15  {
16  while (xvalues[currindex] <= InterpX[i] && currindex <= xvalues.size())
17  ++currindex;
18  if ( currindex > xvalues.size())
19  {
20  InterpY.push_back(0.0);
21  }
22  else
23  {
24  if (currindex == 0 && InterpX[i] == xvalues[currindex])
25  {
26  InterpY.push_back(yvalues[currindex]);
27  }
28  else
29  {
30  if (currindex == xvalues.size() && InterpX[i] == xvalues[currindex - 1])
31  {
32  InterpY.push_back(yvalues[currindex - 1]);
33  }
34  else
35  {
36  double curry = yvalues[currindex - 1]
37  + (yvalues[currindex] - yvalues[currindex - 1])
38  / (xvalues[currindex] - xvalues[currindex - 1])
39  * (InterpX[i] - xvalues[currindex - 1]);
40  InterpY.push_back(curry);
41  }
42  }
43 
44  }
45  }
46  }
47 
48 void InterpolateError(const std::vector<double> &xvalues,
49  const std::vector<double> &yvalues, const std::vector<double> &InterpX,
50  std::vector<double> &InterpY)
51  {
52  const size_t ninter = InterpX.size();
53  size_t currindex = 0;
54  for (size_t i = 0; i < ninter; ++i)
55  {
56  while (xvalues[currindex] <= InterpX[i] && currindex <= xvalues.size())
57  ++currindex;
58  if ( currindex > xvalues.size())
59  {
60  InterpY.push_back(0.0);
61  }
62  else
63  {
64  if (currindex == 0 && InterpX[i] == xvalues[currindex])
65  {
66  InterpY.push_back(yvalues[currindex]);
67  }
68  else
69  {
70  if (currindex == xvalues.size() && InterpX[i] == xvalues[currindex - 1])
71  {
72  InterpY.push_back(yvalues[currindex - 1]);
73  }
74  else
75  {
76  double curry = std::max(yvalues[currindex - 1], yvalues[currindex]);
77  InterpY.push_back(curry);
78  }
79  }
80 
81  }
82  }
83  }
84 
85 void SetMissing(std::complex<double> &value, double &error)
86  {
87  value = std::complex<double>(1.0, 1.0);
88  error = 10.0;
89  }
90 
91 int main(int argc, char* argv[])
92  {
93  string version = "$Id: freqinter.cpp 1886 2014-10-29 12:38:46Z mmoorkamp $";
94  cout << endl << endl;
95  cout << "Program " << version << endl;
96  cout << " Read in several files with MT tensor data" << endl;
97  cout << " and keep interpolate between frequencies. The files will be written in"
98  << endl;
99  cout
100  << " .mtt format. If the input files were in that format they will be overwritten"
101  << endl;
102  cout << endl << endl;
103 
104  try
105  {
106  MTStationList MTSites;
107  std::string infilename;
108  //read the file with the name of stations either directly from the command line
109  if (argc > 1)
110  {
111  infilename = argv[1];
112  }
113  else
114  {
115  //or prompt for it.
116  infilename = AskFilename("Station Filename: ");
117  }
118 
119  MTSites.GetData(infilename);
120  const size_t nstats = MTSites.GetList().size();
121  //create a display of frequencies in the different files
122  //first column is the filename, then a column for each frequency
123  //in the first data files
124  std::cout << "Frequency matrix \n" << std::endl;
125  std::cout << std::setw(12) << "Filename ";
126  std::vector<double> MasterFreqs(MTSites.at(0).GetFrequencies());
127  for (double freq : MasterFreqs)
128  {
129  std::cout << std::setw(10) << freq << std::endl;
130  }
131  std::cout << std::endl;
132 
133  std::cout << "Frequencies per decade: ";
134  int freqperdec;
135  std::cin >> freqperdec;
136 
137  double minfreq = *std::min_element(MasterFreqs.begin(), MasterFreqs.end());
138  double maxfreq = *std::max_element(MasterFreqs.begin(), MasterFreqs.end());
139  double decades = log10(maxfreq) - log10(minfreq);
140  size_t nfreq = ceil(decades * freqperdec);
141  double freqstep = decades / nfreq;
142  std::vector<double> OutFreqs(nfreq);
143  for (size_t i = 0; i < nfreq; ++i)
144  {
145  OutFreqs.at(i) = pow10(log10(minfreq) + freqstep * i);
146  }
147 
148  std::cout << "Output frequencies: ";
149  std::copy(OutFreqs.begin(), OutFreqs.end(),
150  std::ostream_iterator<double>(std::cout, " "));
151  std::cout << "\n";
152 
153  MTStationList OutList;
154  //the relative tolerance with which we consider two frequencies equal
155  const double tolerance = 0.05;
156  for (size_t i = 0; i < nstats; ++i)
157  {
158  //for each site we output its name in the first column
159  std::cout << std::setw(10) << MTSites.at(i).GetName();
160  MTStation CurrStation(MTSites.at(i));
161  CurrStation.SetFrequencies(OutFreqs);
162  auto CurrData = MTSites.at(i).GetMTData();
163  std::vector<double> ZxxR, ZxxI, ZxyR, ZxyI, ZyxR, ZyxI, ZyyR, ZyyI, dZxx,
164  dZxy, dZyx, dZyy;
165  size_t nvals = CurrData.size();
166  for (size_t j = 0; j < nvals; ++j)
167  {
168  auto CurrTensor = CurrData.at(j);
169  ZxxR.push_back(std::real(CurrTensor.GetZxx()));
170  ZxxI.push_back(std::imag(CurrTensor.GetZxx()));
171  ZxyR.push_back(std::real(CurrTensor.GetZxy()));
172  ZxyI.push_back(std::imag(CurrTensor.GetZxy()));
173  ZyxR.push_back(std::real(CurrTensor.GetZyx()));
174  ZyxI.push_back(std::imag(CurrTensor.GetZyx()));
175  ZyyR.push_back(std::real(CurrTensor.GetZyy()));
176  ZyyI.push_back(std::imag(CurrTensor.GetZyy()));
177  dZxx.push_back(CurrTensor.GetdZxx());
178  dZxy.push_back(CurrTensor.GetdZxy());
179  dZyx.push_back(CurrTensor.GetdZyx());
180  dZyy.push_back(CurrTensor.GetdZyy());
181  }
182  std::vector<double> IZxxR, IZxxI, IZxyR, IZxyI, IZyxR, IZyxI, IZyyR, IZyyI,
183  IdZxx, IdZxy, IdZyx, IdZyy;
184  std::vector<double> SiteFreqs(MTSites.at(i).GetFrequencies());
185  Interpolate(SiteFreqs, ZxxR, OutFreqs, IZxxR);
186  Interpolate(SiteFreqs, ZxxI, OutFreqs, IZxxI);
187  Interpolate(SiteFreqs, ZxyR, OutFreqs, IZxyR);
188  Interpolate(SiteFreqs, ZxyI, OutFreqs, IZxyI);
189  Interpolate(SiteFreqs, ZyxR, OutFreqs, IZyxR);
190  Interpolate(SiteFreqs, ZyxI, OutFreqs, IZyxI);
191  Interpolate(SiteFreqs, ZyyR, OutFreqs, IZyyR);
192  Interpolate(SiteFreqs, ZyyI, OutFreqs, IZyyI);
193  InterpolateError(SiteFreqs, dZxx, OutFreqs, IdZxx);
194  InterpolateError(SiteFreqs, dZxy, OutFreqs, IdZxy);
195  InterpolateError(SiteFreqs, dZyx, OutFreqs, IdZyx);
196  InterpolateError(SiteFreqs, dZyy, OutFreqs, IdZyy);
197 
198  MTStation OutSite(nfreq);
199  OutSite.SetFrequencies(OutFreqs);
200  for (size_t j = 0; j < nfreq; ++j)
201  {
202  if (IZxxR[j] != 0.0 || IZxxI[j] != 0.0)
203  {
204  OutSite.SetMTData().at(j).SetZxx() = std::complex<double>(IZxxR[j],
205  IZxxI[j]);
206  OutSite.SetMTData().at(j).SetdZxx() = IdZxx[j];
207  }
208  else
209  {
210  SetMissing(OutSite.SetMTData().at(j).SetZxx(),
211  OutSite.SetMTData().at(j).SetdZxx());
212  }
213 
214  if (IZxyR[j] != 0.0 || IZxyI[j] != 0.0)
215  {
216  OutSite.SetMTData().at(j).SetZxy() = std::complex<double>(IZxyR[j],
217  IZxyI[j]);
218  OutSite.SetMTData().at(j).SetdZxy() = IdZxy[j];
219  }
220  else
221  {
222  SetMissing(OutSite.SetMTData().at(j).SetZxy(),
223  OutSite.SetMTData().at(j).SetdZxy());
224  }
225 
226  if (IZyxR[j] != 0.0 || IZyxI[j] != 0.0)
227  {
228  OutSite.SetMTData().at(j).SetZyx() = std::complex<double>(IZyxR[j],
229  IZyxI[j]);
230  OutSite.SetMTData().at(j).SetdZyx() = IdZyx[j];
231  }
232  else
233  {
234  SetMissing(OutSite.SetMTData().at(j).SetZyx(),
235  OutSite.SetMTData().at(j).SetdZyx());
236  }
237 
238  if (IZyyR[j] != 0.0 || IZyyI[j] != 0.0)
239  {
240  OutSite.SetMTData().at(j).SetZyy() = std::complex<double>(IZyyR[j],
241  IZyyI[j]);
242  OutSite.SetMTData().at(j).SetdZyy() = IdZyy[j];
243  }
244  else
245  {
246  SetMissing(OutSite.SetMTData().at(j).SetZyy(),
247  OutSite.SetMTData().at(j).SetdZyy());
248  }
249 
250  }
251  OutList.GetList().push_back(OutSite);
252  }
253 
254  //now we go through the sites again to mark the ones
255  //that are not in the master file
256  for (size_t i = 0; i < nstats; ++i)
257  {
258  OutList.at(i).WriteAsMtt(MTSites.at(i).GetName());
259  }
260  } catch (FatalException &e)
261  {
262  cerr << e.what() << endl;
263  return -1;
264  }
265  }
266 
MTStation & at(int loc)
Get a reference to a site at a given index.
void Interpolate(const std::vector< double > &xvalues, const std::vector< double > &yvalues, const std::vector< double > &InterpX, std::vector< double > &InterpY)
Definition: freqinter.cpp:9
std::string GetName()
Definition: MTStation.h:104
int main(int argc, char *argv[])
Definition: freqinter.cpp:91
The class MTStation is used to store the transfer functions and related information for a MT-site...
Definition: MTStation.h:17
void InterpolateError(const std::vector< double > &xvalues, const std::vector< double > &yvalues, const std::vector< double > &InterpX, std::vector< double > &InterpY)
Definition: freqinter.cpp:48
MTStationList holds a number of MTSites, usually associated with a single project, line, etc.
Definition: MTStationList.h:16
void SetMissing(std::complex< double > &value, double &error)
Definition: freqinter.cpp:85
tStationList & GetList()
Access to the complete vector of Stations.
Definition: MTStationList.h:31
void WriteAsMtt(const std::string filename)
Write data in goettingen .mtt format.
Definition: MTStation.cpp:681
void GetData(const std::string filename)
Read a list of filenames and the associated data in those files to fill the list. ...
string version
Definition: makeinput.cpp:16
const std::vector< MTTensor > & GetMTData() const
Get the full vector of Tensor elements read only.
Definition: MTStation.h:119
std::vector< MTTensor > & SetMTData()
Get the full vector of Tensor elements for reading and writing.
Definition: MTStation.h:124
trealdata GetFrequencies() const
return the available frequencies in a single vector
Definition: MTStation.cpp:136
void SetFrequencies(const trealdata &freqs)
Set the frequencies of the tensor elements, invalidates the previously stored impedance data...
Definition: MTStation.cpp:144
The basic exception class for all errors that arise in gplib.