00001 #include "SeismicDataComp.h"
00002 #include <algorithm>
00003 #include <fstream>
00004 #include <cassert>
00005 #include <boost/numeric/conversion/cast.hpp>
00006 #include <boost/filesystem/operations.hpp>
00007 #include <boost/cstdint.hpp>
00008 #include "CFatalException.h"
00009
00010 using namespace std;
00011
00012 SeismicDataComp::SeismicDataComp():
00013 stla(0), stlo(0), stel(0), stdp(0), evla(0), evlo(0), evel(0), evdp(0),
00014 mag(0), dist(0), az(0), baz(0), gcarc(0), b(0), dataformat(sac)
00015 {
00016 }
00017
00018 SeismicDataComp::SeismicDataComp(const std::string &filename, tseismicdataformat format):
00019 stla(0), stlo(0), stel(0), stdp(0), evla(0), evlo(0), evel(0), evdp(0),
00020 mag(0), dist(0), az(0), baz(0), gcarc(0), b(0), dataformat(sac)
00021 {
00022 GetData(filename,format);
00023 }
00024
00025 SeismicDataComp::~SeismicDataComp()
00026 {
00027 }
00028
00029 void SeismicDataComp::CopyHeader(const SeismicDataComp& source)
00030 {
00031 this->stla = source.stla;
00032 this->stlo= source.stlo;
00033 this->stel= source.stel;
00034 this->stdp= source.stdp;
00035 this->evla= source.evla;
00036 this->evlo= source.evlo;
00037 this->evel= source.evel;
00038 this->evdp= source.evdp;
00039 this->mag= source.mag;
00040 this->dist= source.dist;
00041 this->az= source.az;
00042 this->baz= source.baz;
00043 this->gcarc= source.gcarc;
00044 this->b = source.b;
00045 }
00046
00047 SeismicDataComp& SeismicDataComp::operator= (const SeismicDataComp& source)
00048 {
00049 if (this == &source) return *this;
00050 CopyHeader(source);
00051 this->dataformat = source.dataformat;
00052 TimeSeriesComponent::operator=(source);
00053 return *this;
00054 }
00055
00056 void SeismicDataComp::ReadAscii(const std::string &filename)
00057 {
00058 ifstream infile(filename.c_str());
00059 double time, amp, oldtime;
00060
00061 infile >> oldtime >> amp;
00062 if (infile.good())
00063 GetData().push_back(amp);
00064 else
00065 throw CFatalException("Cannot read from file: "+filename);
00066 b = oldtime;
00067 infile >> time >> amp;
00068 assert(time - oldtime > 0.0);
00069 GetData().push_back(amp);
00070 SetDt(time - oldtime);
00071 if (!GetData().empty() && infile.good())
00072 GetData().clear();
00073 while (infile.good())
00074 {
00075 infile >> time >> amp;
00076 if (infile.good())
00077 GetData().push_back(amp);
00078 }
00079 }
00080
00081 void SeismicDataComp::ReadSac(const std::string &filename)
00082 {
00083 boost::int32_t ihd[40];
00084 float fhd[70];
00085 char chd[8][24];
00086 ifstream infile(filename.c_str());
00087 infile.read((char *)(&fhd), 70*4);
00088 if (infile.fail())
00089 {
00090 throw CFatalException("Cannot read from file: "+filename);
00091 }
00092 else
00093 {
00094
00095 infile.read((char *)(&ihd), 40*4);
00096 infile.read((char *)(&chd), 24*8);
00097
00098 stla =fhd[31];
00099 stlo =fhd[32];
00100 stel =fhd[33];
00101 stdp =fhd[34];
00102 evla =fhd[35];
00103 evlo =fhd[36];
00104 evel =fhd[37];
00105 evdp =fhd[38];
00106 mag =fhd[39];
00107 dist =fhd[50];
00108 az =fhd[51];
00109 baz =fhd[52];
00110 gcarc =fhd[53];
00111 boost::int32_t npts=ihd[9];
00112 assert(fhd[0] > 0.0);
00113 SetDt(fhd[0]);
00114 b=fhd[5];
00115 assert(npts > 0);
00116 float *temp = new float[npts];
00117 infile.read((char *)(temp), npts*sizeof(float));
00118 if (!GetData().empty())
00119 GetData().clear();
00120 copy(temp, temp+npts, back_inserter(GetData()));
00121
00122
00123
00124
00125 delete []temp;
00126
00127 }
00128 }
00129
00130 void SeismicDataComp::ReadHeaderAscii(const std::string &filename)
00131 {
00132 ifstream infile(filename.c_str());
00133 double amp;
00134 char currentline[255];
00135 const int headerlines = 12;
00136
00137 infile.getline(currentline, 255, ':');
00138 double delta;
00139 infile >> delta;
00140 SetDt(delta);
00141 for (int i = 0; i < headerlines; ++i)
00142 infile.getline(currentline, 255);
00143 if (!GetData().empty() && infile.good())
00144 GetData().clear();
00145 while (infile.good())
00146 {
00147 infile >> amp;
00148 if (infile.good())
00149 GetData().push_back(amp);
00150 }
00151 SetName(filename);
00152 }
00153
00154 void SeismicDataComp::ReadSKS(const std::string &filename)
00155 {
00156 ifstream infile(filename.c_str(), ios::binary);
00157 int intdummy;
00158 float floatdummy;
00159 int npts = 0;
00160
00161 if (!infile)
00162 {
00163 cerr << "Error opening file: "<< filename << endl;
00164 }
00165 infile.read((char *)&intdummy, sizeof(int));
00166 infile.read((char *)&floatdummy, sizeof(float));
00167 infile.read((char *)&intdummy, sizeof(int));
00168
00169 infile.read((char *)&intdummy, sizeof(int));
00170 for (int i = 0; i < 5; ++i)
00171 infile.read((char *)&intdummy, sizeof(int));
00172 infile.read((char *)&intdummy, sizeof(int));
00173
00174 infile.read((char *)&intdummy, sizeof(int));
00175 for (int i = 0; i < 6; ++i)
00176 infile.read((char *)&intdummy, sizeof(int));
00177 infile.read((char *)&intdummy, sizeof(int));
00178
00179 infile.read((char *)&intdummy, sizeof(int));
00180 infile.read((char *)&npts, sizeof(int));
00181 infile.read((char *)&intdummy, sizeof(int));
00182 infile.read((char *)&floatdummy, sizeof(float));
00183 SetDt(floatdummy);
00184 infile.read((char *)&intdummy, sizeof(int));
00185
00186 infile.read((char *)&intdummy, sizeof(int));
00187 infile.read((char *)&intdummy, sizeof(int));
00188 infile.read((char *)&intdummy, sizeof(int));
00189 infile.read((char *)&intdummy, sizeof(int));
00190
00191 GetData().assign(npts, 0);
00192 infile.read((char *)&intdummy, sizeof(int));
00193 infile.read((char *)&floatdummy, sizeof(float));
00194 for (int i = 0; i < npts; ++i)
00195 {
00196 infile.read((char *)&floatdummy, sizeof(float));
00197 GetData().at(i) = floatdummy;
00198 }
00199 infile.read((char *)&intdummy, sizeof(int));
00200
00201 }
00202
00203 int SeismicDataComp::GetData(const std::string &filename,
00204 tseismicdataformat format)
00205 {
00206 if (!boost::filesystem::exists(filename))
00207 throw CFatalException("File does not exist : "+filename);
00208 switch (format)
00209 {
00210 case sac:
00211 ReadSac(filename);
00212 break;
00213 case sks:
00214 ReadSKS(filename);
00215 break;
00216 case head:
00217 ReadHeaderAscii(filename);
00218 break;
00219 case ascii:
00220 ReadAscii(filename);
00221 break;
00222 case unknownseis:
00223 cerr << "Unknown dataformat ! Cannot read "<< filename << endl;
00224 return -100;
00225 break;
00226 default:
00227 cerr << "Unknown dataformat ! Cannot read "<< filename << endl;
00228 return -100;
00229 break;
00230 }
00231 SetName(filename);
00232 return 0;
00233 }
00234
00235 int SeismicDataComp::WriteAsSac(const std::string &filename) const
00236 {
00237 int npts;
00238 int ihd[40];
00239 float fhd[70];
00240 char chd[8][24];
00241 ofstream outfile;
00242 float *temp= NULL;
00243 int i;
00244
00245 outfile.open(filename.c_str());
00246
00247 npts = GetData().size();
00248
00249 temp=new float[npts];
00250
00251 copy(GetData().begin(), GetData().end(), temp);
00252 for (i=0; i<40; i++)
00253 ihd[i]=-12345;
00254 for (i=0; i<70; i++)
00255 fhd[i]=-12345.00;
00256 for (i=0; i<8; i++)
00257 sprintf(chd[i], "-12345 -12345 -12345 ");
00258
00259 ihd[35]=1;
00260 ihd[15]=1;
00261 ihd[6]=6;
00262
00263 fhd[31] = stla;
00264 fhd[32] = stlo;
00265 fhd[33] = stel;
00266 fhd[34] = stdp;
00267 fhd[35] = evla;
00268 fhd[36] = evlo;
00269 fhd[37] = evel;
00270 fhd[38] = evdp;
00271 fhd[39] = mag;
00272 fhd[50] = dist;
00273 fhd[51] = az;
00274 fhd[52] =baz;
00275 fhd[53] = gcarc;
00276
00277 ihd[9] = npts;
00278 fhd[0] = GetDt();
00279 fhd[5] = b;
00280
00281 outfile.write((char *)(&fhd), 70*4);
00282 outfile.write((char *)(&ihd), 40*4);
00283 outfile.write((char *)(&chd), 24*8);
00284 outfile.write((char *)(temp), npts*sizeof(float));
00285 outfile.close();
00286 delete []temp;
00287 return (0);
00288 }
00289
00290 int SeismicDataComp::WriteAsHeaderAscii(const std::string &filename) const
00291 {
00292 return -100;
00293 }
00294
00295 int SeismicDataComp::WriteAsSKS(const std::string &filename) const
00296 {
00297 ofstream outfile(filename.c_str(), ios::binary);
00298 int intdummy = 0;
00299 float floatdummy = 0;
00300 const int npts = GetData().size();
00301
00302 outfile.write((char *)&intdummy, sizeof(int));
00303 outfile.write((char *)&floatdummy, sizeof(float));
00304 outfile.write((char *)&intdummy, sizeof(int));
00305
00306 outfile.write((char *)&intdummy, sizeof(int));
00307 for (int i = 0; i < 5; ++i)
00308 outfile.write((char *)&intdummy, sizeof(int));
00309 outfile.write((char *)&intdummy, sizeof(int));
00310
00311 outfile.write((char *)&intdummy, sizeof(int));
00312 for (int i = 0; i < 6; ++i)
00313 outfile.write((char *)&intdummy, sizeof(int));
00314 outfile.write((char *)&intdummy, sizeof(int));
00315
00316 outfile.write((char *)&intdummy, sizeof(int));
00317 outfile.write((char *)&npts, sizeof(int));
00318 outfile.write((char *)&intdummy, sizeof(int));
00319 floatdummy = GetDt();
00320 outfile.write((char *)&floatdummy, sizeof(float));
00321 outfile.write((char *)&intdummy, sizeof(int));
00322
00323 outfile.write((char *)&intdummy, sizeof(int));
00324 outfile.write((char *)&intdummy, sizeof(int));
00325 outfile.write((char *)&intdummy, sizeof(int));
00326 outfile.write((char *)&intdummy, sizeof(int));
00327
00328 outfile.write((char *)&intdummy, sizeof(int));
00329 outfile.write((char *)&floatdummy, sizeof(float));
00330
00331 float *temp=new float[npts];
00332 copy(GetData().begin(), GetData().end(), temp);
00333 outfile.write((char *)(temp), npts*sizeof(float));
00334 outfile.write((char *)&intdummy, sizeof(int));
00335 delete []temp;
00336 return 0;
00337 }
00338
00339 int SeismicDataComp::WriteAsAscii(const std::string &filename) const
00340 {
00341 ofstream outfile(filename.c_str());
00342
00343 for (unsigned int i = 0; i < GetData().size(); ++i)
00344 {
00345 outfile << b + i * GetDt() << " " << GetData().at(i) << endl;
00346 }
00347 return 0;
00348 }
00349
00350 int SeismicDataComp::WriteBack() const
00351 {
00352 switch (dataformat)
00353 {
00354 case sac:
00355 WriteAsSac(GetName());
00356 break;
00357 case sks:
00358 WriteAsSKS(GetName());
00359 break;
00360 case head:
00361 WriteAsHeaderAscii(GetName());
00362 break;
00363 case ascii:
00364 WriteAsAscii(GetName());
00365 break;
00366 case unknownseis:
00367 cerr << "Unknown dataformat ! Cannot write " << GetName() << endl;
00368 return -100;
00369 break;
00370 default:
00371 cerr << "Unknown dataformat ! Cannot write !"<< GetName() << endl;
00372 return -100;
00373 break;
00374 }
00375 return 0;
00376 }
00377