MultiRecCalc.cpp
Go to the documentation of this file.00001 #include "MultiRecCalc.h"
00002 #include "TimeFrequency.h"
00003 #include "FatalException.h"
00004 #include "CRFSpecElement.h"
00005 #include "TsSpectrum.h"
00006 #include "WFunc.h"
00007 #include "VecMat.h"
00008 #include "Adaptors.h"
00009
00010 namespace ublas = boost::numeric::ublas;
00011 using namespace std;
00012
00013 namespace gplib
00014 {
00015 MultiRecCalc::MultiRecCalc(const int myshift, const double mysigma,
00016 const double myc) :
00017 c(myc), sigma(mysigma), shift(myshift)
00018 {
00019 }
00020
00021 MultiRecCalc::~MultiRecCalc()
00022 {
00023 }
00024
00025 void MultiRecCalc::CalcRecData(
00026 const SeismicStationList::tseiscompvector &RadComp,
00027 const SeismicStationList::tseiscompvector &VerComp,
00028 SeismicDataComp &Receiver)
00029 {
00030 if (RadComp.size() != VerComp.size())
00031 throw FatalException(
00032 "Not the same number of stations for vertical and radial components !");
00033 const unsigned int compsize = RadComp.front()->GetData().size();
00034 const unsigned int ncomp = RadComp.size();
00035 const double omegastep = 2. * PI / (RadComp.front()->GetDt()
00036 * RadComp.front()->GetData().size());
00037 gplib::rvec ConcatRad(compsize * ncomp), ConcatVer(compsize * ncomp);
00038 for (unsigned int i = 0; i < ncomp; ++i)
00039 {
00040 if (RadComp.at(i)->GetData().size() != compsize
00041 || VerComp.at(i)->GetData().size() != compsize)
00042 throw FatalException(
00043 "Incompatible sizes for Vertical or Radial component.");
00044 copy(RadComp.at(i)->GetData().begin(),
00045 RadComp.at(i)->GetData().end(), ConcatRad.begin() + i
00046 * compsize);
00047 copy(VerComp.at(i)->GetData().begin(),
00048 VerComp.at(i)->GetData().end(), ConcatVer.begin() + i
00049 * compsize);
00050 }
00051 gplib::cmat radtfspectrum = TimeFrequency(ConcatRad.begin(),
00052 ConcatRad.end(), compsize, Steep());
00053 gplib::cmat vertfspectrum = TimeFrequency(ConcatVer.begin(),
00054 ConcatVer.end(), compsize, Steep());
00055 gplib::cvec RecSpec(compsize / 2 + 1);
00056 RecSpec *= 0.0;
00057 for (unsigned int i = 0; i < radtfspectrum.size1(); ++i)
00058 {
00059 complex<double> delta = *max_element(
00060 column(vertfspectrum, i).begin(),
00061 column(vertfspectrum, i).end(), gplib::absLess<tcomp, tcomp>())
00062 * c;
00063 delta *= conj(delta);
00064
00065 for (unsigned int j = 0; j < radtfspectrum.size2(); ++j)
00066 {
00067 RecSpec(j) += CalcSpectralElement(delta)(radtfspectrum(i, j),
00068 vertfspectrum(i, j));
00069 }
00070 }
00071 const double denom = 1. / (4.0 * sigma * sigma);
00072 for (unsigned int i = 0; i < RecSpec.size(); ++i)
00073 {
00074 double freq = omegastep * i;
00075 RecSpec(i) *= exp(-(freq * freq) * denom);
00076 }
00077 Receiver.SetB(0.0);
00078 Receiver.SetDt(RadComp.front()->GetDt());
00079 Receiver.GetData().assign(compsize, 0.0);
00080 TsSpectrum Spectrum(false);
00081 Spectrum.CalcTimeSeries(RecSpec.begin(), RecSpec.end(),
00082 Receiver.GetData().begin(), Receiver.GetData().end());
00083 const int shiftpoints = boost::numeric_cast<size_t>(shift
00084 / RadComp.front()->GetDt());
00085 rotate(Receiver.GetData().begin(), Receiver.GetData().end()
00086 - shiftpoints, Receiver.GetData().end());
00087 const double maxamp = 1. / *max_element(Receiver.GetData().begin(),
00088 Receiver.GetData().end());
00089 transform(Receiver.GetData().begin(), Receiver.GetData().end(),
00090 Receiver.GetData().begin(), boost::bind(multiplies<double> (), _1,
00091 maxamp));
00092 }
00093 }