GPLIB++
SeismicDataComp.cpp
Go to the documentation of this file.
1 #include "SeismicDataComp.h"
2 #include <algorithm>
3 #include <fstream>
4 #include <cassert>
5 #include <boost/numeric/conversion/cast.hpp>
6 #include <boost/filesystem/operations.hpp>
7 #include <boost/cstdint.hpp>
8 #include "FatalException.h"
9 
10 using namespace std;
11 
12 namespace gplib
13  {
14  SeismicDataComp::SeismicDataComp() :
15  stla(0), stlo(0), stel(0), stdp(0), evla(0), evlo(0), evel(0), evdp(0),
16  mag(0), dist(0), az(0), baz(0), gcarc(0), b(0), dataformat(sac)
17  {
18  }
19 
20  SeismicDataComp::SeismicDataComp(const std::string &filename,
21  tseismicdataformat format) :
22  stla(0), stlo(0), stel(0), stdp(0), evla(0), evlo(0), evel(0), evdp(0),
23  mag(0), dist(0), az(0), baz(0), gcarc(0), b(0), dataformat(sac)
24  {
25  ReadData(filename, format);
26  }
27 
29  {
30  }
31 
33  {
34  this->stla = source.stla;
35  this->stlo = source.stlo;
36  this->stel = source.stel;
37  this->stdp = source.stdp;
38  this->evla = source.evla;
39  this->evlo = source.evlo;
40  this->evel = source.evel;
41  this->evdp = source.evdp;
42  this->mag = source.mag;
43  this->dist = source.dist;
44  this->az = source.az;
45  this->baz = source.baz;
46  this->gcarc = source.gcarc;
47  this->b = source.b;
48  }
49 
51  {
52  if (this == &source)
53  return *this;
54  CopyHeader(source);
55  this->dataformat = source.dataformat;
57  return *this;
58  }
59 
60  void SeismicDataComp::ReadAscii(const std::string &filename)
61  {
62  ifstream infile(filename.c_str());
63  double time, amp, oldtime;
64 
65  infile >> oldtime >> amp;
66  if (infile.good())
67  GetData().push_back(amp);
68  else
69  throw FatalException("Cannot read from file: " + filename);
70  b = oldtime;
71  infile >> time >> amp;
72  assert(time - oldtime > 0.0);
73  GetData().push_back(amp);
74  SetDt(time - oldtime);
75  if (!GetData().empty() && infile.good())
76  GetData().clear();
77  while (infile.good())
78  {
79  infile >> time >> amp;
80  if (infile.good())
81  GetData().push_back(amp);
82  }
83  }
84 
85  void SeismicDataComp::ReadSac(const std::string &filename)
86  {
87  boost::int32_t ihd[40];
88  float fhd[70];
89  char chd[8][24];
90  ifstream infile(filename.c_str());
91  infile.read((char *) (&fhd), 70 * 4); /*Read Sac Float Field*/
92  if (infile.fail()) //if reading fails
93  {
94  throw FatalException("Cannot read from file: " + filename);
95  }
96  else
97  {
98 
99  infile.read((char *) (&ihd), 40 * 4); /*Read Sac Int Field*/
100  infile.read((char *) (&chd), 24 * 8); /*Read Sac Char. Field*/
101 
102  stla = fhd[31];
103  stlo = fhd[32];
104  stel = fhd[33];
105  stdp = fhd[34];
106  evla = fhd[35];
107  evlo = fhd[36];
108  evel = fhd[37];
109  evdp = fhd[38];
110  mag = fhd[39];
111  dist = fhd[50];
112  az = fhd[51];
113  baz = fhd[52];
114  gcarc = fhd[53];
115  boost::int32_t npts = ihd[9];
116  assert(fhd[0] > 0.0);
117  SetDt(fhd[0]);
118  b = fhd[5];
119  assert(npts > 0);
120  float *temp = new float[npts]; //allocate memory for data
121  infile.read((char *) (temp), npts * sizeof(float)); //read data part of SAC file
122  if (!GetData().empty())
123  GetData().clear();
124  copy(temp, temp + npts, back_inserter(GetData()));
125 
126  //Data.assign(npts,0);
127  //for (int i = 0; i < npts; ++i)
128  // Data.at(i) = temp[i];
129  delete[] temp;
130  //ShiftStart(static_cast<int>(ceil(b/dt)));
131  }
132  }
133 
134  int SeismicDataComp::ReadData(const std::string &filename,
135  tseismicdataformat format)
136  {
137  if (!boost::filesystem::exists(filename))
138  throw FatalException("File does not exist : " + filename);
139  switch (format)
140  {
141  case sac:
142  ReadSac(filename);
143  break;
144  case ascii:
145  ReadAscii(filename);
146  break;
147  case unknownseis:
148  cerr << "Unknown dataformat ! Cannot read " << filename << endl;
149  return -100;
150  break;
151  default:
152  cerr << "Unknown dataformat ! Cannot read " << filename << endl;
153  return -100;
154  break;
155  }
156  SetName(filename);
157  return 0;
158  }
159 
160  int SeismicDataComp::WriteAsSac(const std::string &filename) const
161  {
162  int npts;
163  boost::int32_t ihd[40];
164  float fhd[70];
165  char chd[8][24];
166  ofstream outfile;
167  float *temp = NULL;
168  int i;
169 
170  outfile.open(filename.c_str());
171 
172  npts = GetData().size();
173 
174  temp = new float[npts]; //allocate memory for data
175  std::string dummyline = "-12345 -12345 -12345 ";
176  copy(GetData().begin(), GetData().end(), temp);
177  for (i = 0; i < 40; i++)
178  ihd[i] = -12345;
179  for (i = 0; i < 70; i++)
180  fhd[i] = -12345.00;
181  for (i = 0; i < 8; i++)
182  std::copy(dummyline.begin(), dummyline.end(), chd[i]);
183 
184  /*Set essential sac parameters*/
185  ihd[35] = 1; /*Sets file to evenly spaced*/
186  ihd[15] = 1; /*Sets file type to Timeseries*/
187  ihd[6] = 6; /*Variable Name Internal */
188 
189  fhd[31] = stla;
190  fhd[32] = stlo;
191  fhd[33] = stel;
192  fhd[34] = stdp;
193  fhd[35] = evla;
194  fhd[36] = evlo;
195  fhd[37] = evel;
196  fhd[38] = evdp;
197  fhd[39] = mag;
198  fhd[50] = dist;
199  fhd[51] = az;
200  fhd[52] = baz;
201  fhd[53] = gcarc;
202 
203  ihd[9] = npts;
204  fhd[0] = GetDt();
205  fhd[5] = b;
206 
207  outfile.write((char *) (&fhd), 70 * 4); /*Write Sac Float Field*/
208  outfile.write((char *) (&ihd), 40 * 4); /*Write Sac Int Field*/
209  outfile.write((char *) (&chd), 24 * 8); /*Write Sac Char. Field*/
210  outfile.write((char *) (temp), npts * sizeof(float)); //write data part of SAC file
211  outfile.close();
212  delete[] temp;
213  return (0);
214  }
215 
216  int SeismicDataComp::WriteAsAscii(const std::string &filename) const
217  {
218  ofstream outfile(filename.c_str());
219 
220  for (unsigned int i = 0; i < GetData().size(); ++i)
221  {
222  outfile << b + i * GetDt() << " " << GetData().at(i) << endl;
223  }
224  return 0;
225  }
226 
228  {
229  switch (dataformat)
230  {
231  case sac:
232  WriteAsSac(GetName());
233  break;
234  case ascii:
236  break;
237  case unknownseis:
238  cerr << "Unknown dataformat ! Cannot write " << GetName() << endl;
239  return -100;
240  break;
241  default:
242  cerr << "Unknown dataformat ! Cannot write !" << GetName() << endl;
243  return -100;
244  break;
245  }
246  return 0;
247  }
248  }
int ReadData(const std::string &filename, tseismicdataformat format=sac)
Read in data from a file, as we cannot determine the type from the ending we have to provide it...
std::vector< double > & GetData()
Access for data vector, for ease of use and efficiency we return a reference.
void CopyHeader(const SeismicDataComp &source)
Copy the information in the header from another object.
std::string GetName() const
Return name of the component.
void SetDt(const double dt)
Set delta t in s.
void SetName(const std::string &n)
Modify name of the component.
int WriteBack() const
Write the data in the format it was read in and with the same filename.
double GetDt() const
Return dt in s.
virtual SeismicDataComp & operator=(const SeismicDataComp &source)
int WriteAsSac(const std::string &filename) const
Write the data in sac binary format.
int WriteAsAscii(const std::string &filename) const
Write the data in plain ascii format.
The basic exception class for all errors that arise in gplib.
TimeSeriesComponent & operator=(const TimeSeriesComponent &source)