00001 #include "RFVelCalc.h"
00002 #include "WFunc.h"
00003 #include <numeric>
00004 #include <fstream>
00005 #include <cassert>
00006 #include "CFatalException.h"
00007 #include <gsl/gsl_math.h>
00008
00009 RFVelCalc::RFVelCalc(const double myomega, const double mysigma,
00010 const double myc, const RecCalc::trfmethod themethod) :
00011 RFCalculator(0, myomega, mysigma, myc, false, themethod)
00012 {
00013 RFCalculator.SetNormalize(false);
00014 }
00015
00016 RFVelCalc::~RFVelCalc()
00017 {
00018 }
00019
00020 RFVelCalc::RFVelCalc(const RFVelCalc &Old) :
00021 RFCalculator(Old.RFCalculator), Velocities(Old.Velocities),
00022 Periods(Old.Periods)
00023 {
00024
00025 }
00026
00027 RFVelCalc& RFVelCalc::operator=(const RFVelCalc& source)
00028 {
00029 if (this == &source) return *this;
00030 RFCalculator = source.RFCalculator;
00031 Velocities = source.Velocities;
00032 Periods = source.Periods;
00033 return *this;
00034 }
00035
00036 void RFVelCalc::AbsVelCalc(const double slowness,
00037 const SeismicDataComp &RadRec, const SeismicDataComp &VerRec,
00038 ttsdata &AppVel)
00039 {
00040 ttsdata FilteredR(RadRec.GetData().size()), FilteredZ(VerRec.GetData().size());
00041 AppVel.clear();
00042 Velocities.clear();
00043 Periods.clear();
00044 assert(FilteredR.size() == FilteredZ.size());
00045 assert(gsl_fcmp(RadRec.GetDt(),VerRec.GetDt(),GSL_DBL_EPSILON)==0);
00046 for (double width = 0.1; width < 40; width *= 1.1)
00047 {
00048 double sigma = width/(RadRec.GetDt()*RadRec.GetData().size());
00049 ApplyWindow(RadRec.GetData().begin(), RadRec.GetData().end(), FilteredR.begin(), TruncCosSq(sigma));
00050 ApplyWindow(VerRec.GetData().begin(), VerRec.GetData().end(), FilteredZ.begin(), TruncCosSq(sigma));
00051 double rvalue = accumulate(FilteredR.begin(), FilteredR.end(), 0.0);
00052 double zvalue = accumulate(FilteredZ.begin(), FilteredZ.end(), 0.0);
00053 if (zvalue == 0.0)
00054 throw CFatalException("Zero amplitude for Z-Receiver function !");
00055 double angle = atan(rvalue/zvalue);
00056 double vsapp = sin(0.5 * angle)/slowness;
00057 AppVel.push_back(vsapp);
00058 Velocities.push_back(vsapp);
00059 Periods.push_back(width);
00060 }
00061 }
00062
00063 void RFVelCalc::CalcRFVelFromRec(const double slowness,
00064 const SeismicDataComp &RRec, const SeismicDataComp &VerComp,
00065 ttsdata &AppVel)
00066 {
00067 SeismicDataComp ZRecFunc;
00068 RFCalculator.CalcRecData(VerComp, VerComp, ZRecFunc);
00069 AbsVelCalc(slowness, RRec, ZRecFunc, AppVel);
00070 }
00071
00072 void RFVelCalc::CalcRFVel(const double slowness,
00073 const SeismicDataComp &RadComp, const SeismicDataComp &VerComp,
00074 ttsdata &AppVel)
00075 {
00076 SeismicDataComp RRecFunc, ZRecFunc;
00077 RFCalculator.CalcRecData(RadComp, VerComp, RRecFunc);
00078 RFCalculator.CalcRecData(VerComp, VerComp, ZRecFunc);
00079 AbsVelCalc(slowness, RRecFunc, ZRecFunc, AppVel);
00080 }
00081
00082 void RFVelCalc::WriteVelocities(const std::string filename)
00083 {
00084 std::ofstream outfile(filename.c_str());
00085 for (size_t i = 0; i < Velocities.size(); ++i)
00086 outfile << Periods.at(i) << " " << Velocities.at(i) << std::endl;
00087 }