GPLIB++
MTStationList.cpp
Go to the documentation of this file.
1 #include "MTStationList.h"
2 #include "StationParser.h"
3 #include "FatalException.h"
4 #include "convert.h"
5 #include "stringcompare.h"
6 #include "NumUtil.h"
7 #include <fstream>
8 #include <iostream>
9 #include <iomanip>
10 #include <utility>
11 #include <boost/bind.hpp>
12 using namespace std;
13 
14 namespace gplib
15  {
16  MTStationList::MTStationList(double freqtol):
17  tolerance(freqtol)
18  {
19  }
20 
22  {
23  }
24 
25  void MTStationList::GetData(const std::string filename)
26  {
27  ifstream infile(filename.c_str());
28 
29  if (infile)
30  {
31  //first parse the file with the station information
32  StationParser parser;
33  parser.ParseFile(infile);
34  //go through all the station names and read in the data for each station
35  for (unsigned int i = 0; i < parser.Stationnames.size(); ++i)
36  {
37  cout << "Working on file " << parser.Stationnames.at(i) << endl;
38  try
39  {
40  MTStation CurrentStation;
41  CurrentStation.GetData(parser.Stationnames.at(i));
42  //we can have a stationfile with lat/lon information or without it
43  //if yes we use this as position information
44  if (parser.HasLatLong.at(i))
45  {
46  CurrentStation.SetLongitude(parser.Longitudes.at(i));
47  CurrentStation.SetLatitude(parser.Latitudes.at(i));
48  }
49  StationData.push_back(CurrentStation);
50  } catch (FatalException &e)
51  {
52  cerr << e.what() << " Skipping file !" << endl;
53  }
54  }
55  }
56  else
57  {
58  throw FatalException("File not found: " + filename);
59  }
60  //if we did read in some data we create an index of common frequencies in each file
61  if (!StationData.empty())
62  {
63  FindCommon();
64  }
65  }
66 
68  {
69  return (StationData.at(loc));
70  }
71 
72  void MTStationList::WriteList(const std::string filename)
73  {
74  ofstream outfile(filename.c_str());
75  for (vector<MTStation>::iterator CurrentStation = StationData.begin(); CurrentStation
76  != StationData.end(); CurrentStation++)
77  {
78  outfile << CurrentStation->GetName();
79  outfile << setfill(' ') << setw(15) << resetiosflags(ios::fixed);
80  outfile << CurrentStation->GetLongitude() << " ";
81  outfile << setfill(' ') << setw(15) << resetiosflags(ios::fixed);
82  outfile << CurrentStation->GetLatitude();
83  outfile << endl;
84  }
85  }
86 
88  {
89  //for each station in the station list we write back the data in the original format
90  for (std::vector<MTStation>::iterator CurrentStation =
91  StationData.begin(); CurrentStation != StationData.end(); CurrentStation++)
92  CurrentStation->WriteBack();
93  }
94 
95  void MTStationList::FindCommon(void)
96  {
97  trealdata masterfrequencies(StationData.begin()->GetFrequencies());
98 
99  commonfrequencies.clear();
100  for (unsigned int i = 0; i < masterfrequencies.size(); ++i)
101  {
102  bool iscommon = true;
103  for (size_t j = 0; j < StationData.size(); ++j)
104  {
105  bool foundfrequency = false;
106  size_t k = 0;
107  while ((foundfrequency == false) && (k
108  < StationData.at(j).GetFrequencies().size()))
109  {
110  if (fcmp(masterfrequencies.at(i),
111  StationData.at(j).GetFrequencies().at(k), tolerance)
112  == 0)
113  foundfrequency = true;
114  ++k;
115  }
116  // if foundfrequency is false once, iscommon will be false for the rest of the loop
117  iscommon = (iscommon && foundfrequency);
118  }
119  if (iscommon)
120  commonfrequencies.push_back(masterfrequencies.at(i));
121  }
122  tindexvector indices(commonfrequencies.size(), -1);
123  cfindices.assign(StationData.size(), indices);
124  for (unsigned int i = 0; i < commonfrequencies.size(); ++i)
125  {
126  for (unsigned int j = 0; j < StationData.size(); ++j)
127  {
128  double bestfit = 1e32;
129  for (size_t k = 0; k < StationData.at(j).GetFrequencies().size(); ++k)
130  {
131  if ((fcmp(commonfrequencies.at(i),
132  StationData.at(j).GetFrequencies().at(k), tolerance)
133  == 0) && (abs(commonfrequencies.at(i) - StationData.at(
134  j).GetFrequencies().at(k)) < bestfit))
135  {
136  cfindices.at(j).at(i) = k;
137  bestfit = commonfrequencies.at(i)
138  - StationData.at(j).GetFrequencies().at(k);
139  }
140  }
141  }
142  }
143  }
144 
145  //here starts the implementation of some free functions that don't belong to the class itself, but are associated with it
146 
147  //! returns if station a and b have the same name
148  class HasSameName: public std::binary_function<MTStation, MTStation, bool>
149  {
150  public:
151  bool inline operator()(MTStation a, MTStation b)
152  {
153  // if a does not precede b and b does not precede a, they have the same name , concept of equivalence,
154  //Effective STL Item 19, page 84
155  return !ciStringCompare(a.GetName(), b.GetName())
156  && !ciStringCompare(b.GetName(), a.GetName());
157  }
158  };
159 
161  tStationList &SlaveList)
162  {
163  std::vector<std::pair<MTStation*, MTStation*> > CorrespondingSites;
164  for (size_t i = 0; i < MasterList.size(); ++i)
165  {
166  tStationList::iterator slaveit = find_if(SlaveList.begin(),
167  SlaveList.end(), boost::bind(HasSameName(), MasterList.at(i),
168  _1)); //find site with same name in SlaveList
169  if (slaveit != SlaveList.end())
170  CorrespondingSites.push_back(std::make_pair(&MasterList.at(i),
171  &*slaveit));
172  else
173  std::cerr << "Not found: " << MasterList.at(i).GetName()
174  << std::endl;
175  }
176  return CorrespondingSites;
177  }
178  }
MTStation & at(int loc)
Get a reference to a site at a given index.
void WriteAllData()
Write the data of each station to an individual file.
void WriteList(const std::string filename="station.list")
Write the names of the sites in the current list to a file.
std::string GetName()
Definition: MTStation.h:104
virtual void GetData(const std::string filename)
read in data from file, determines format by ending
Definition: MTStation.cpp:597
std::vector< std::pair< MTStation *, MTStation * > > tStatSyncPair
Definition: MTStationList.h:57
tStatSyncPair FindCorrespondingSites(tStationList &MasterList, tStationList &SlaveList)
Take two different site Lists of arguments and return a vector of pairs that point to the sites that ...
The class MTStation is used to store the transfer functions and related information for a MT-site...
Definition: MTStation.h:17
returns if station a and b have the same name
void SetLatitude(double lat)
Definition: MTStation.h:88
std::vector< MTStation > tStationList
Definition: MTStationList.h:14
void GetData(const std::string filename)
Read a list of filenames and the associated data in those files to fill the list. ...
void SetLongitude(double lon)
Definition: MTStation.h:96
bool operator()(MTStation a, MTStation b)
The basic exception class for all errors that arise in gplib.