RFVelCalc.cpp

Go to the documentation of this file.
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       //we initialize the receiver function calculation with a shift of 5 seconds
00014           //this enables us catch the full waveform of the initial correlation peak in most cases
00015           //there might be a better way to do this
00016           RFCalculator(5, mysigma, myc, false, themethod)
00017       {
00018         //with normalization absolute velocity estimation does not work
00019         //so we make sure the RF is not normalized
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         //we need filtered versions of the two components
00049         //so create copies that we can work on
00050         ttsdata FilteredR(RadRec.GetData().size()), FilteredZ(
00051             VerRec.GetData().size());
00052         //make sure all old stuff is deleted before we do another calculation
00053         AppVel.clear();
00054         Velocities.clear();
00055         Periods.clear();
00056         //in debug mode we perform some extra checks
00057         assert(FilteredR.size() == FilteredZ.size());
00058         assert(fcmp(RadRec.GetDt(),VerRec.GetDt(),std::numeric_limits<double>::epsilon())==0);
00059         //we have to compensate for the shift of 5 seconds that we use above
00060         const double relshift = 5.0
00061             / (RadRec.GetDt() * RadRec.GetData().size());
00062         //at the moment we calculate apparent velocities at periods independent of the receiver function parameters
00063         //we specify the width in seconds
00064         for (double width = 0.1; width < 40; width *= 1.1)
00065           {
00066             //calculate the width of the filter relative to the length of the whole component
00067             double sigma = width / (RadRec.GetDt() * RadRec.GetData().size());
00068             //window the component with a truncated squared cosine window
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             // and sum up the values, this is eq. 5 in Svenningsen
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             //calculate the apparent velocity
00080             double vsapp = sin(0.5 * atan2(rvalue, zvalue)) / slowness;
00081             //store the apparent velocity values and the periods
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   }

Generated on Tue May 4 16:52:15 2010 for GPLIB++ by  doxygen 1.5.8