00001 #include "MultiRecCalc.h"
00002 #include "TimeFrequency.h"
00003 #include "CFatalException.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 MultiRecCalc::MultiRecCalc(const int myshift, const double myomega,
00013 const double mysigma, const double myc) :
00014 c(myc), omega(myomega), sigma(mysigma), shift(myshift)
00015 {
00016 }
00017
00018 MultiRecCalc::~MultiRecCalc()
00019 {
00020 }
00021
00022
00023 void MultiRecCalc::CalcRecData(const std::vector<SeismicDataComp> &RadComp,
00024 const std::vector<SeismicDataComp> &VerComp, SeismicDataComp &Receiver)
00025 {
00026 if (RadComp.size() != VerComp.size())
00027 throw CFatalException("Not the same number of stations for vertical and radial components !");
00028 const unsigned int compsize = RadComp.front().GetData().size();
00029 const unsigned int ncomp = RadComp.size();
00030 const double omegastep = 2. * PI/(RadComp.front().GetDt() * RadComp.front().GetData().size());
00031 gplib::rvec ConcatRad(compsize*ncomp), ConcatVer(compsize*ncomp);
00032 for (unsigned int i = 0; i < ncomp; ++i)
00033 {
00034 if (RadComp.at(i).GetData().size() != compsize || VerComp.at(i).GetData().size() != compsize)
00035 throw CFatalException("Incompatible sizes for Vertical or Radial component.");
00036 copy(RadComp.at(i).GetData().begin(), RadComp.at(i).GetData().end(), ConcatRad.begin()+i*compsize);
00037 copy(VerComp.at(i).GetData().begin(), VerComp.at(i).GetData().end(), ConcatVer.begin()+i*compsize);
00038 }
00039 gplib::cmat radtfspectrum = TimeFrequency(ConcatRad.begin(),
00040 ConcatRad.end(), compsize, Steep());
00041 gplib::cmat vertfspectrum = TimeFrequency(ConcatVer.begin(),
00042 ConcatVer.end(), compsize, Steep());
00043 gplib::cvec RecSpec(compsize/2+1);
00044 RecSpec *= 0.0;
00045 for (unsigned int i = 0; i < radtfspectrum.size1(); ++i)
00046 {
00047 complex<double> delta = *max_element(column(vertfspectrum,i).begin(), column(vertfspectrum,i).end(), gplib::absLess<tcomp,tcomp>()) *c;
00048 delta *= conj(delta);
00049
00050 for (unsigned int j = 0; j < radtfspectrum.size2(); ++j)
00051 {
00052 RecSpec(j) += CalcSpectralElement(delta)(radtfspectrum(i, j),
00053 vertfspectrum(i, j));
00054
00055 }
00056 }
00057 const double denom = 1./(4.0 * sigma*sigma);
00058 for (unsigned int i = 0; i < RecSpec.size(); ++i)
00059 {
00060 double freq = omegastep * i;
00061 RecSpec(i) *= exp(- (freq*freq)*denom);
00062 }
00063 Receiver.SetB(0.0);
00064 Receiver.SetDt(RadComp.front().GetDt());
00065 Receiver.GetData().assign(compsize, 0.0);
00066 TsSpectrum Spectrum(false);
00067 Spectrum.CalcTimeSeries(RecSpec.begin(), RecSpec.end(), Receiver.GetData().begin(), Receiver.GetData().end());
00068 const int shiftpoints =boost::numeric_cast<size_t>(shift/RadComp.front().GetDt());
00069 rotate(Receiver.GetData().begin(),Receiver.GetData().end()-shiftpoints,Receiver.GetData().end());
00070 const double maxamp = 1./ *max_element(Receiver.GetData().begin(),Receiver.GetData().end());
00071 transform(Receiver.GetData().begin(),Receiver.GetData().end(),Receiver.GetData().begin(),boost::bind(multiplies<double>(),_1,maxamp));
00072 }