9 #include <boost/bind.hpp>
10 #include <boost/cast.hpp>
11 #include <boost/filesystem.hpp>
15 #include <sys/types.h>
27 RecCalc::RecCalc(
int myshift,
double mysigma,
double myc,
bool multicalc,
29 method(themethod), Spectrum(multicalc), c(myc), sigma(mysigma), shift(myshift), normalize(
36 method(Old.method), Spectrum(Old.Spectrum), c(Old.c), sigma(Old.sigma), shift(
37 Old.shift), normalize(Old.normalize), RadComp(Old.RadComp), VerComp(
47 method = source.method;
48 Spectrum = source.Spectrum;
52 normalize = source.normalize;
53 RadComp = source.RadComp;
54 VerComp = source.VerComp;
65 const double omegastep = 2. * PI / (RComp.
GetDt() * RComp.
GetData().size());
67 ttsdata LocalRad(RComp.
GetData());
68 ttsdata LocalVer(VComp.
GetData());
70 if (LocalRad.size() > LocalVer.size())
71 LocalRad.erase(LocalRad.end() - (LocalRad.size() - LocalVer.size()),
73 else if (LocalVer.size() > LocalRad.size())
74 LocalVer.erase(LocalVer.end() - (LocalVer.size() - LocalRad.size()),
77 SubMean(LocalVer.begin(), LocalVer.end());
78 SubMean(LocalRad.begin(), LocalRad.end());
83 tcompdata RadSpec(LocalRad.size() / 2 + 1);
84 tcompdata VerSpec(LocalVer.size() / 2 + 1);
86 Spectrum.
CalcSpectrum(LocalRad.begin(), LocalRad.end(), RadSpec.begin(),
88 Spectrum.
CalcSpectrum(LocalVer.begin(), LocalVer.end(), VerSpec.begin(),
90 tcompdata RecSpec(RadSpec.size(), 0);
92 Receiver.
GetData().assign(LocalRad.size(), 0);
94 tcomp cmaxelem = *max_element(VerSpec.begin(), VerSpec.end(),
95 gplib::absLess<tcomp, tcomp>());
96 cmaxelem *= conj(cmaxelem) * c;
99 const double denom = 1. / (4.0 * sigma * sigma);
101 transform(RadSpec.begin(), RadSpec.end(), VerSpec.begin(), RecSpec.begin(),
104 const dcomp phaseshift(0, shift);
111 for (
size_t i = 0; i < RecSpec.size(); ++i)
113 double freq = omegastep * i;
114 RecSpec[i] *= exp(-(freq * freq) * denom - phaseshift * freq);
121 void RecCalc::IterativeDeconvolution(
const SeismicDataComp &RComp,
122 const SeismicDataComp &VComp, SeismicDataComp &Receiver)
124 gplib::rvec Filter(RComp.GetData().size());
125 const double dt = RComp.GetDt();
126 double normfactor = 1.;
127 const int shiftpoints = boost::numeric_cast<
int>(shift / dt);
128 const double variancesq = sigma * dt * sigma * dt;
129 const unsigned int maxit = 100;
130 const double minimprove = 1e-6;
131 const int maxpoints = Filter.size() / 2;
133 for (
int i = 0; i <= maxpoints; ++i)
135 Filter(i) = normfactor * exp(-std::pow((i - shiftpoints), 2.) * variancesq);
136 Filter(Filter.size() - i - 1) = normfactor
137 * exp(-std::pow((-i - 1 - shiftpoints), 2.) * variancesq);
140 gplib::rvec RadFilter(RComp.GetData().size()), VerFilter(VComp.GetData().size());
141 copy(RComp.GetData().begin(), RComp.GetData().end(), RadFilter.begin());
142 copy(VComp.GetData().begin(), VComp.GetData().end(), VerFilter.begin());
143 SubMean(RadFilter.begin(), RadFilter.end());
144 SubMean(VerFilter.begin(), VerFilter.end());
145 Convolve(RadFilter, Filter, RadFilter, Spectrum);
146 Convolve(VerFilter, Filter, VerFilter, Spectrum);
147 gplib::rvec Current(RadFilter), Output(RadFilter);
149 IterDecon Decon(VerFilter.size(), Spectrum);
150 const double power = ublas::prec_inner_prod(RadFilter, RadFilter);
151 double error = power;
152 double lasterror = 1.;
153 double improvement = 1.;
154 unsigned int iter = 0;
155 while (improvement > minimprove && iter < maxit)
157 Decon.AdaptFilter(VerFilter, Current);
158 Decon.CalcOutput(VerFilter, Output);
160 Current = RadFilter - Output;
161 error = ublas::prec_inner_prod(Current, Current) / power;
162 improvement = lasterror - error;
167 std::cout <<
"Iterations: " << iter <<
" Error: " << error << std::endl;
168 Convolve(Decon.GetWeights(), Filter, Current, Spectrum);
169 Receiver.GetData().assign(Current.size(), 0);
170 copy(Current.begin(), Current.end(), Receiver.GetData().begin());
180 IterativeDeconvolution(RadComp, VerComp, Receiver);
183 SpectralDivision(RadComp, VerComp, Receiver);
187 Receiver.
SetB(-shift);
213 int result = std::system((
"bash ./" + filename).c_str());
216 "Problem in synthetic receiver function calculation !");
222 RadComp.
ReadData(filename +
".mod_sp.r");
223 VerComp.
ReadData(filename +
".mod_sp.z");
228 CleanFiles(filename);
trfmethod
There are several ways to calculate receiver functions.
int ReadData(const std::string &filename, tseismicdataformat format=sac)
Read in data from a file, as we cannot determine the type from the ending we have to provide it...
This class is used to calculate receiver functions from seismic data.
std::vector< double > & GetData()
Access for data vector, for ease of use and efficiency we return a reference.
void SynthSafeParallel(const std::string &filename, ResPkModel &Model, SeismicDataComp &Receiver, const bool cleanfiles=false)
All operations that are safe to execute in parallel.
virtual void WriteRunFile(const std::string &filename)
Write out a script that performs a forward calculation for the current model.
void SubMean(InputIterator begin, InputIterator end, typename std::iterator_traits< InputIterator >::value_type mean)
Substract the mean from each element in the container, mean is passed as a parameter.
This functor rises steeply at the edges and then has a wide range where it is unity.
void CalcRecSynth(const std::string &filename, ResPkModel &Model, SeismicDataComp &Receiver, const bool cleanfiles=false)
Calculate synthetic receiver funtions from a model.
void SynthPostParallel(const std::string &filename, ResPkModel &Model, SeismicDataComp &Receiver, const bool cleanfiles=false)
Operations of the synthetic receiver function calculation that are not safe in parallel and hafe to b...
void CopyHeader(const SeismicDataComp &source)
Copy the information in the header from another object.
void CalcRecData(const SeismicDataComp &RadComp, const SeismicDataComp &VerComp, SeismicDataComp &Receiver)
Calculate Receiver functions from two data components.
void SetB(const double theb)
void SynthPreParallel(const std::string &filename, ResPkModel &Model, SeismicDataComp &Receiver, const bool cleanfiles=false)
The three Synth*Parallel methods provide alternative acces to the steps in CalcRecSynth for safe para...
void SetDt(const double dt)
Set delta t in s.
RecCalc & operator=(const RecCalc &source)
RecCalc(int myshift, double mysigma, double myc, bool multicalc=false, trfmethod themethod=iterdecon)
The constructor takes the essential parameters that shouldn't change during different calculations...
virtual void WriteModel(const std::string filename)
Write the model in its native format to a file.
double GetDt() const
Return dt in s.
This class calculates one spectral element of the receiver function from the two input spectral eleme...
This class stores and writes model for the respktn 1D seismic code that we use for receiver function ...
The basic exception class for all errors that arise in gplib.