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