00001 #include "MTStation.h"
00002 #include "miscfunc.h"
00003
00004
00005 #ifdef HAVEANTLR
00006 #include "EDILexer.hpp"
00007 #include "EDIParser.hpp"
00008 #include "JLexer.hpp"
00009 #include "JParser.hpp"
00010 #endif
00011 #include <iomanip>
00012 #include <iterator>
00013 #include <string>
00014 #include "FatalException.h"
00015 #include <boost/filesystem/operations.hpp>
00016 #include <boost/filesystem/convenience.hpp>
00017 #include <boost/bind.hpp>
00018 #include <functional>
00019 #include <fstream>
00020 #include <cassert>
00021 #include "Util.h"
00022 using namespace std;
00023
00024 namespace gplib
00025 {
00026 void TrimFilename(string &name)
00027 {
00028 size_t slashpos = name.find('/', 0);
00029 if (slashpos != string::npos)
00030 name = name.substr(slashpos + 1);
00031 size_t dotpos = name.find('.', 0);
00032 if (dotpos != string::npos)
00033 name.erase(dotpos);
00034 }
00035
00036 void MTStation::InitialSetup()
00037 {
00038 latitude = 0;
00039 longitude = 0;
00040 elevation = 0;
00041 azimuth = 0;
00042 }
00043
00044 MTStation::MTStation()
00045 {
00046 InitialSetup();
00047 }
00048
00049 MTStation::~MTStation()
00050 {
00051 }
00052
00053 MTStation::MTStation(const std::string filename)
00054 {
00055 InitialSetup();
00056 GetData(filename);
00057 }
00058
00059 MTStation::MTStation(const int size) :
00060 MTData(size)
00061 {
00062 InitialSetup();
00063 Assign(size);
00064 }
00065 void MTStation::AssignAll(const int nfreq)
00066 {
00067 Assign(nfreq);
00068 }
00069 void MTStation::Assign(const int nfreq)
00070 {
00071 MTData.assign(nfreq, MTTensor());
00072 TFData.assign(nfreq, MagneticTF());
00073 }
00074
00075
00076
00077
00078
00079 void MTStation::Update()
00080 {
00081
00082 }
00083
00084
00085 void MTStation::DoRotate(const int i, const double angle)
00086 {
00087 dcomp newxx, newxy, newyx, newyy;
00088 newxx = MTData.at(i).Zxx * std::pow(cos(angle), 2) + (MTData.at(i).Zxy
00089 + MTData.at(i).Zyx) * sin(angle) * cos(angle) + MTData.at(i).Zyy
00090 * std::pow(sin(angle), 2);
00091 newxy = MTData.at(i).Zxy * std::pow(cos(angle), 2) - (MTData.at(i).Zxx
00092 - MTData.at(i).Zyy) * sin(angle) * cos(angle) - MTData.at(i).Zyx
00093 * std::pow(sin(angle), 2);
00094 newyx = MTData.at(i).Zyx * std::pow(cos(angle), 2) - (MTData.at(i).Zxx
00095 - MTData.at(i).Zyy) * sin(angle) * cos(angle) - MTData.at(i).Zxy
00096 * std::pow(sin(angle), 2);
00097 newyy = MTData.at(i).Zyy * std::pow(cos(angle), 2) - (MTData.at(i).Zxy
00098 + MTData.at(i).Zyx) * sin(angle) * cos(angle) + MTData.at(i).Zxx
00099 * std::pow(sin(angle), 2);
00100 MTData.at(i).Zxx = newxx;
00101 MTData.at(i).Zxy = newxy;
00102 MTData.at(i).Zyx = newyx;
00103 MTData.at(i).Zyy = newyy;
00104 MTData.at(i).rotangle += angle;
00105 }
00106
00107
00108
00109
00110 void MTStation::Rotate(const double rotangle)
00111 {
00112 for (unsigned int i = 0; i < MTData.size(); ++i)
00113 {
00114 DoRotate(i, rotangle);
00115 }
00116 Update();
00117 }
00118
00119
00120
00121 void MTStation::Rotate(void)
00122 {
00123 for (unsigned int i = 0; i < MTData.size(); ++i)
00124 {
00125 DoRotate(i, -MTData.at(i).rotangle);
00126 }
00127 Update();
00128 }
00129
00130
00131 trealdata MTStation::GetFrequencies() const
00132 {
00133 trealdata temp(MTData.size());
00134 transform(MTData.begin(), MTData.end(), temp.begin(), mem_fun_ref(
00135 &MTTensor::GetFrequency));
00136 return temp;
00137 }
00138
00139 void MTStation::SetFrequencies(const trealdata &freqs)
00140 {
00141
00142 const unsigned int nfreqs = freqs.size();
00143 if (MTData.size() != nfreqs)
00144 {
00145 MTData.resize(nfreqs);
00146 TFData.resize(nfreqs);
00147 }
00148 for (unsigned int i = 0; i < nfreqs; ++i)
00149 MTData.at(i).frequency = freqs.at(i);
00150 assert(MTData.size() == TFData.size());
00151
00152 }
00153 #ifdef HAVEANTLR
00154 void MTStation::ReadEdi(const std::string filename)
00155 {
00156 using namespace antlr;
00157 ifstream infile(filename.c_str());
00158 const double invalid = 1e30;
00159
00160 if (infile)
00161 {
00162 try
00163 {
00164 EDILexer lexer(infile);
00165 EDIParser parser(lexer);
00166 parser.edi_file();
00167 latitude = parser.latitude;
00168 longitude = parser.longitude;
00169 elevation = parser.elevation;
00170 azimuth = parser.azimuth;
00171 name = filename;
00172 TrimFilename(name);
00173 unsigned int valfreqs = 0;
00174 for (unsigned int i = 0; i < parser.frequency.size(); ++i)
00175 {
00176 if (abs(parser.DataXX.at(i)) > invalid)
00177 {
00178 parser.frequency.at(i) = 0;
00179 }
00180 else
00181 {
00182 valfreqs++;
00183 }
00184 }
00185
00186
00187
00188 azimuth += parser.rotangles.at(0) * 180. / PI;
00189 Assign(valfreqs);
00190 unsigned int mtindex = 0;
00191
00192
00193
00194 for (unsigned int i = 0; i < parser.rotangles.size(); ++i)
00195 {
00196 if (abs(parser.DataXX.at(i)) < invalid)
00197 {
00198 MTData.at(mtindex).frequency = parser.frequency.at(i);
00199 MTData.at(mtindex).rotangle = parser.rotangles.at(i)
00200 * PI / 180.;
00201 MTData.at(mtindex).Zxx = parser.DataXX.at(i);
00202 MTData.at(mtindex).Zxy = parser.DataXY.at(i);
00203 MTData.at(mtindex).Zyx = parser.DataYX.at(i);
00204 MTData.at(mtindex).Zyy = parser.DataYY.at(i);
00205 MTData.at(mtindex).dZxx = parser.dDataXX.at(i);
00206 MTData.at(mtindex).dZxy = parser.dDataXY.at(i);
00207 MTData.at(mtindex).dZyx = parser.dDataYX.at(i);
00208 MTData.at(mtindex).dZyy = parser.dDataYY.at(i);
00209 mtindex++;
00210 }
00211 }
00212 mtindex = 0;
00213 if (parser.DataZY.empty() == false)
00214 {
00215 for (unsigned int i = 0; i < parser.DataZY.size(); ++i)
00216 {
00217 if (abs(parser.DataZX.at(i)) < invalid)
00218 {
00219 TFData.at(mtindex).frequency = parser.frequency.at(
00220 i);
00221 TFData.at(mtindex).Tx = parser.DataZX.at(i);
00222 TFData.at(mtindex).Ty = parser.DataZY.at(i);
00223 TFData.at(mtindex).dTx = parser.dDataZX.at(i);
00224 TFData.at(mtindex).dTy = parser.dDataZY.at(i);
00225 mtindex++;
00226 }
00227 }
00228 }
00229 }
00230 catch (ANTLRException& e)
00231 {
00232 cerr << "Parse exception: " << e.toString() << endl;
00233 }
00234 Update();
00235 }
00236 else
00237 {
00238 throw FatalException("File not found: " + filename);
00239 }
00240 }
00241 #endif
00242
00243 void MTStation::ReadPek1D(const std::string filename)
00244 {
00245 ifstream infile(filename.c_str());
00246 if (infile)
00247 {
00248 const double convfactor = 1. / (1000. * mu);
00249 double period, rxx, imxx, rxy, imxy, ryx, imyx, ryy, imyy;
00250 while (infile.good())
00251 {
00252 infile >> period >> rxx >> imxx >> rxy >> imxy >> ryx >> imyx
00253 >> ryy >> imyy;
00254
00255 if (infile.good())
00256 {
00257 MTTensor CurrentImp;
00258 CurrentImp.frequency = 1. / period;
00259 CurrentImp.Zxx = (rxx + I * imxx) * convfactor;
00260 CurrentImp.Zxy = (rxy + I * imxy) * convfactor;
00261 CurrentImp.Zyx = (ryx + I * imyx) * convfactor;
00262 CurrentImp.Zyy = (ryy + I * imyy) * convfactor;
00263 MTData.push_back(CurrentImp);
00264 TFData.push_back(MagneticTF());
00265 }
00266 }
00267 name = filename;
00268 TrimFilename(name);
00269 }
00270 else
00271 {
00272 throw FatalException("File not found: " + filename);
00273 }
00274 }
00275
00276 #ifdef HAVEANTLR
00277 void MTStation::ReadJ(const std::string filename)
00278 {
00279
00280 using namespace antlr;
00281 ifstream infile(filename.c_str());
00282
00283 if (infile)
00284 {
00285 try
00286 {
00287 JLexer lexer(infile);
00288 JParser parser(lexer);
00289 parser.jfile();
00290 latitude = parser.latitude;
00291 longitude = parser.longitude;
00292 elevation = parser.elevation;
00293 azimuth = parser.azimuth;
00294 name = parser.name;
00295 TrimFilename(name);
00296 Assign(parser.frequency.size());
00297
00298
00299 if (parser.zassigned == false && parser.rassigned == false)
00300 {
00301 cerr << "No MT data in file !" << endl;
00302 }
00303 else
00304 {
00305 for (unsigned int i = 0; i < parser.frequency.size(); ++i)
00306 {
00307 MTData.at(i).frequency = parser.frequency.at(i);
00308 MTData.at(i).rotangle = parser.azimuth;
00309 MTData.at(i).Zxx = parser.DataXX.at(i);
00310 MTData.at(i).Zxy = parser.DataXY.at(i);
00311 MTData.at(i).Zyx = parser.DataYX.at(i);
00312 MTData.at(i).Zyy = parser.DataYY.at(i);
00313 MTData.at(i).dZxx = parser.dDataXX.at(i);
00314 MTData.at(i).dZxy = parser.dDataXY.at(i);
00315 MTData.at(i).dZyx = parser.dDataYX.at(i);
00316 MTData.at(i).dZyy = parser.dDataYY.at(i);
00317 MTData.at(i).Rx = parser.Rx.at(i);
00318 MTData.at(i).Ry = parser.Ry.at(i);
00319 }
00320 }
00321 if (parser.tassigned)
00322 {
00323 for (unsigned int i = 0; i < parser.DataZY.size(); ++i)
00324 {
00325 TFData.at(i).frequency = parser.frequency.at(i);
00326 TFData.at(i).Tx = parser.DataZX.at(i);
00327 TFData.at(i).Ty = parser.DataZY.at(i);
00328 TFData.at(i).dTx = parser.dDataZX.at(i);
00329 TFData.at(i).dTy = parser.dDataZY.at(i);
00330 TFData.at(i).Rz = parser.Rz.at(i);
00331 }
00332 }
00333 }
00334 catch (ANTLRException& e)
00335 {
00336 cerr << "Parse exception: " << e.toString() << endl;
00337 }
00338 Update();
00339 }
00340 else
00341 {
00342 throw FatalException("File not found: " + filename);
00343 }
00344
00345 }
00346 #endif
00347
00348 void MTStation::ReadMtt(const std::string filename)
00349 {
00350 ifstream infile;
00351 double currentreal, currentimag;
00352 int nentries = 0;
00353 infile.open(filename.c_str());
00354 while (infile.good())
00355 {
00356 infile >> currentreal;
00357 ++nentries;
00358 }
00359 infile.close();
00360 if (((nentries - 1) % 23) != 0)
00361 throw FatalException("Number of records does not match expected: "
00362 + filename);
00363 const int nrecords = (nentries - 1) / 23;
00364 Assign(nrecords);
00365 infile.open(filename.c_str());
00366 int currentrecord = 0;
00367 if (infile)
00368 {
00369 while (infile.good())
00370 {
00371 infile >> currentreal;
00372 if (infile.good())
00373 {
00374 MTData.at(currentrecord).frequency = currentreal;
00375 TFData.at(currentrecord).frequency = currentreal;
00376 infile >> currentreal;
00377 MTData.at(currentrecord).Nu = currentreal;
00378 infile >> currentreal >> currentimag;
00379 MTData.at(currentrecord).Zxx = (currentreal + I
00380 * currentimag);
00381 infile >> currentreal >> currentimag;
00382 MTData.at(currentrecord).Zxy = (currentreal + I
00383 * currentimag);
00384 infile >> currentreal >> currentimag;
00385 MTData.at(currentrecord).Zyx = (currentreal + I
00386 * currentimag);
00387 infile >> currentreal >> currentimag;
00388 MTData.at(currentrecord).Zyy = (currentreal + I
00389 * currentimag);
00390 infile >> currentreal;
00391 MTData.at(currentrecord).dZxx = currentreal;
00392 infile >> currentreal;
00393 MTData.at(currentrecord).dZxy = currentreal;
00394 infile >> currentreal;
00395 MTData.at(currentrecord).dZyx = currentreal;
00396 infile >> currentreal;
00397 MTData.at(currentrecord).dZyy = currentreal;
00398 infile >> currentreal >> currentimag;
00399 TFData.at(currentrecord).Tx = currentreal + I * currentimag;
00400 infile >> currentreal >> currentimag;
00401 TFData.at(currentrecord).Ty = currentreal + I * currentimag;
00402 infile >> currentreal;
00403 TFData.at(currentrecord).dTx = currentreal;
00404 infile >> currentreal;
00405 TFData.at(currentrecord).dTy = currentreal;
00406 infile >> currentreal;
00407 MTData.at(currentrecord).Rx = currentreal;
00408 infile >> currentreal;
00409 MTData.at(currentrecord).Ry = currentreal;
00410 infile >> currentreal;
00411 TFData.at(currentrecord).Rz = currentreal;
00412 ++currentrecord;
00413 }
00414 }
00415 infile.close();
00416 name = filename;
00417 TrimFilename(name);
00418 }
00419 else
00420 {
00421 throw FatalException("File not found: " + filename);
00422 }
00423 Update();
00424 }
00425
00426 void MTStation::GetData(const string filename)
00427 {
00428 if (!boost::filesystem::exists(filename))
00429 throw FatalException("File does not exist : " + filename);
00430 string ending = boost::filesystem::extension(filename);
00431 if (ending == "")
00432 {
00433 cerr << "File has no extension ! " << filename << endl;
00434 dataformat = unknown;
00435 throw FatalException("File has no extension ! " + filename);
00436 }
00437 if (ending == ".mtt")
00438 {
00439 ReadMtt(filename);
00440 dataformat = mtt;
00441 }
00442 else if (ending == ".dat" || ending == ".j")
00443 {
00444 #ifdef HAVEANTLR
00445 ReadJ(filename);
00446 dataformat = j;
00447 #else
00448 throw FatalException("Did not compile with .j support");
00449 #endif
00450 }
00451 else if (ending == ".edi")
00452 {
00453 #ifdef HAVEANTLR
00454 ReadEdi(filename);
00455 dataformat = edi;
00456 #else
00457 throw FatalException("Did not compile with .edi support");
00458 #endif
00459 }
00460 else if (ending == ".pek")
00461 {
00462 ReadPek1D(filename);
00463 dataformat = pek;
00464 }
00465 else
00466 {
00467 dataformat = unknown;
00468 throw FatalException("File not recognised: " + filename);
00469 }
00470 assert(MTData.size() == TFData.size());
00471 Rotate();
00472
00473 }
00474
00475 void MTStation::WriteData(const std::string filename)
00476 {
00477 name = filename;
00478 WriteBack();
00479 }
00480
00481 void MTStation::WriteBack()
00482 {
00483 switch (dataformat)
00484 {
00485 case mtt:
00486 WriteAsMtt(name.c_str());
00487 break;
00488 case j:
00489 WriteAsJ(name.c_str());
00490 break;
00491 case edi:
00492 WriteAsEdi(name.c_str());
00493 break;
00494 default:
00495 throw FatalException(
00496 "Unknown File Format for Writing ! This should not happen");
00497 }
00498
00499 }
00500
00501 void MTStation::WriteAsMtt(const string filename)
00502 {
00503 Update();
00504 WriteMtt((filename + ".mtt").c_str());
00505 }
00506
00507 void MTStation::WriteAsEdi(const string filename)
00508 {
00509 throw FatalException("WriteAsEdi not implemented yet !");
00510 }
00511
00512 void MTStation::WriteJBlock(boost::function<complex<double> (
00513 const MTTensor*)> Comp, boost::function<double(const MTTensor*)> Err,
00514 ofstream &outfile, const double convfactor)
00515 {
00516 for (unsigned int i = 0; i < MTData.size(); ++i)
00517 {
00518 if (MTData.at(i).frequency != 0)
00519 {
00520 outfile << setfill(' ') << setw(15)
00521 << resetiosflags(ios::fixed) << 1. / MTData.at(i).frequency
00522 << " ";
00523 outfile << setfill(' ') << setw(15) << convfactor
00524 * boost::bind(Comp, &MTData.at(i))().real() << " ";
00525 outfile << setfill(' ') << setw(15) << convfactor
00526 * boost::bind(Comp, &MTData.at(i))().imag() << " ";
00527 outfile << setfill(' ') << setw(15) << convfactor
00528 * boost::bind(Err, &MTData.at(i))() << " ";
00529 outfile << setfill(' ') << setw(15) << setiosflags(ios::fixed)
00530 << 1.000 << " " << endl;
00531 }
00532 }
00533 }
00534
00535 void MTStation::WriteAsJ(const string filename)
00536 {
00537 ofstream outfile;
00538 outfile.open((filename + ".j").c_str());
00539 int actfreqs = 0;
00540 const double convfactor = 4. * acos(-1.) * 1e-4;
00541
00542 outfile << "# J-File Produced by CJData.cpp" << endl;
00543 outfile << ">LATITUDE = " << latitude << endl;
00544 outfile << ">LONGITUDE = " << longitude << endl;
00545 outfile << ">ELEVATION = " << elevation << endl;
00546 outfile << ">AZIMUTH = " << azimuth << endl;
00547 outfile << name << endl;
00548 for (unsigned int i = 0; i < MTData.size(); ++i)
00549 if (MTData.at(i).frequency != 0)
00550 actfreqs++;
00551 outfile << "ZXX S.I." << endl;
00552 outfile << actfreqs << endl;
00553
00554 WriteJBlock(&MTTensor::GetZxx, &MTTensor::GetdZxx, outfile, convfactor);
00555 outfile << "ZXY S.I." << endl;
00556 outfile << actfreqs << endl;
00557 WriteJBlock(&MTTensor::GetZxy, &MTTensor::GetdZxy, outfile, convfactor);
00558
00559 outfile << "ZYX S.I." << endl;
00560 outfile << actfreqs << endl;
00561 WriteJBlock(&MTTensor::GetZyx, &MTTensor::GetdZyx, outfile, convfactor);
00562
00563 outfile << "ZYY S.I." << endl;
00564 outfile << actfreqs << endl;
00565 WriteJBlock(&MTTensor::GetZyy, &MTTensor::GetdZyy, outfile, convfactor);
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 outfile.close();
00581 }
00582
00583 void MTStation::WriteMtt(const std::string filename)
00584 {
00585 ofstream outfile;
00586
00587 outfile.open(filename.c_str());
00588 vector<int> mttindex(MTData.size());
00589
00590 assert(MTData.size() == TFData.size());
00591 for (unsigned int i = 0; i < MTData.size(); ++i)
00592 {
00593
00594 if (MTData.at(i).frequency > 0)
00595 {
00596 outfile << setw(9) << setfill(' ') << setprecision(4)
00597 << setiosflags(ios::scientific) << MTData.at(i).frequency;
00598 outfile << " " << resetiosflags(ios::scientific)
00599 << setprecision(5) << MTData.at(i).Nu << "\n";
00600
00601 outfile << setw(9) << setfill(' ') << setprecision(4)
00602 << setiosflags(ios::fixed) << MTData.at(i).Zxx.real()
00603 << " ";
00604 outfile << setw(9) << setfill(' ') << setprecision(4)
00605 << setiosflags(ios::fixed) << MTData.at(i).Zxx.imag()
00606 << " ";
00607 outfile << setw(9) << setfill(' ') << setprecision(4)
00608 << setiosflags(ios::fixed) << MTData.at(i).Zxy.real()
00609 << " ";
00610 outfile << setw(9) << setfill(' ') << setprecision(4)
00611 << setiosflags(ios::fixed) << MTData.at(i).Zxy.imag()
00612 << " ";
00613 outfile << setw(9) << setfill(' ') << setprecision(4)
00614 << setiosflags(ios::fixed) << MTData.at(i).Zyx.real()
00615 << " ";
00616 outfile << setw(9) << setfill(' ') << setprecision(4)
00617 << setiosflags(ios::fixed) << MTData.at(i).Zyx.imag()
00618 << " ";
00619 outfile << setw(9) << setfill(' ') << setprecision(4)
00620 << setiosflags(ios::fixed) << MTData.at(i).Zyy.real()
00621 << " ";
00622 outfile << setw(9) << setfill(' ') << setprecision(4)
00623 << setiosflags(ios::fixed) << MTData.at(i).Zyy.imag()
00624 << " ";
00625 outfile << "\n";
00626 outfile << setw(9) << setfill(' ') << setprecision(4)
00627 << setiosflags(ios::fixed) << MTData.at(i).dZxx << " ";
00628 outfile << setw(9) << setfill(' ') << setprecision(4)
00629 << setiosflags(ios::fixed) << MTData.at(i).dZxy << " ";
00630 outfile << setw(9) << setfill(' ') << setprecision(4)
00631 << setiosflags(ios::fixed) << MTData.at(i).dZyx << " ";
00632 outfile << setw(9) << setfill(' ') << setprecision(4)
00633 << setiosflags(ios::fixed) << MTData.at(i).dZyy << " ";
00634 outfile << setw(9) << setfill(' ') << setprecision(4)
00635 << setiosflags(ios::fixed) << TFData.at(i).Tx.real() << " ";
00636 outfile << setw(9) << setfill(' ') << setprecision(4)
00637 << setiosflags(ios::fixed) << TFData.at(i).Tx.imag() << " ";
00638 outfile << setw(9) << setfill(' ') << setprecision(4)
00639 << setiosflags(ios::fixed) << TFData.at(i).Ty.real() << " ";
00640 outfile << setw(9) << setfill(' ') << setprecision(4)
00641 << setiosflags(ios::fixed) << TFData.at(i).Ty.imag() << " ";
00642 outfile << "\n";
00643 outfile << setw(9) << setfill(' ') << setprecision(4)
00644 << setiosflags(ios::fixed) << TFData.at(i).dTx << " ";
00645 outfile << setw(9) << setfill(' ') << setprecision(4)
00646 << setiosflags(ios::fixed) << TFData.at(i).dTy << " ";
00647 outfile << setw(9) << setfill(' ') << setprecision(4)
00648 << setiosflags(ios::fixed) << MTData.at(i).Rx << " ";
00649 outfile << setw(9) << setfill(' ') << setprecision(4)
00650 << setiosflags(ios::fixed) << MTData.at(i).Ry << " ";
00651 outfile << setw(9) << setfill(' ') << setprecision(4)
00652 << setiosflags(ios::fixed) << TFData.at(i).Rz << " ";
00653 outfile << "\n" << resetiosflags(ios::fixed);
00654
00655 }
00656
00657 }
00658 outfile.close();
00659 }
00660 MTStation::MTStation(const MTStation &old) :
00661 latitude(old.latitude), longitude(old.longitude),
00662 elevation(old.elevation), name(old.name), azimuth(old.azimuth),
00663 MTData(old.MTData), TFData(old.TFData),
00664
00665 dataformat(old.dataformat)
00666 {
00667 Update();
00668 }
00669 MTStation& MTStation::operator=(const MTStation& source)
00670 {
00671 if (this == &source)
00672 return *this;
00673
00674 copy(source.MTData.begin(), source.MTData.end(), back_inserter(
00675 this->MTData));
00676 copy(source.TFData.begin(), source.TFData.end(), back_inserter(
00677 this->TFData));
00678
00679 this->latitude = source.latitude;
00680 this->longitude = source.longitude;
00681 this->elevation = source.elevation;
00682 this->azimuth = source.azimuth;
00683 this->name = source.name;
00684 this->dataformat = source.dataformat;
00685 this->Update();
00686 return *this;
00687 }
00688 }