GPLIB++
calcrec.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <string>
3 #include <algorithm>
4 #include <boost/math/constants/constants.hpp>
5 #include "Util.h"
6 #include "RecCalc.h"
7 #include "CalcRecConf.h"
8 #include "SeismicDataComp.h"
9 #include "FatalException.h"
10 #include "FilterFunc.h"
11 #include "statutils.h"
12 #include "miscfunc.h"
13 #include "NumUtil.h"
14 #include "RFVelCalc.h"
15 
16 /*! \file
17  * This program calculates a receiver function from single radial and vertical components.
18  * When started the program only asks for the name of the files for these two components.
19  * The output receiver function has the same name as the radial component with .rec appended.
20  * All other aspects of the calculation are specified in the file calcrec.conf in the directory
21  * in which the program is executed.
22  *
23  * The parameters for that file are as follows:
24  *
25  * <TABLE>
26  * <TR> <TD> <B>Name </B></TD> <TD> <B>Description </B></TD></TR>
27  * <TR> <TD> recmethod </TD> <TD> Can be specdiv for spectral division method or iterdecon for iterative deconvolution. </TD></TR>
28  * <TR> <TD> omega </TD> <TD>The center of the gaussian used to filter the receiver function during estimation. </TD> </TR>
29  * <TR> <TD> sigma </TD> <TD>The width of the gaussian used to filter the receiver function during estimation.
30  * Larger values mean a more broad band reciever function that contains more detailed structure but is also susceptible to noise.</TD> </TR>
31  * <TR> <TD> shift </TD> <TD>The shift in seconds of the initial correlation peak. This is purely used for display purposes. </TD> </TR>
32  * <TR> <TD> cc </TD> <TD>(only specdiv) The waterlevel relative to the maximum autopower of the vertical component. </TD> </TR>
33  * <TR> <TD> upperfreq </TD> <TD>The upper frequency in Hz for the bandpass filter, if negative or not set it is ignored </TD> </TR>
34  * <TR> <TD> lowerfreq </TD> <TD>The lower frequency in Hz for the bandpass filter, if negative or not set it is ignored </TD> </TR>
35  * </TABLE>
36  * More details about these parameters can be found for example in
37  * Langston, 1979, JGR 84(B9) 4749-4762
38  * Liggoria, 1999, BSSA 89(5), 1395-1400
39  */
40 using namespace std;
41 using namespace gplib;
42 
43 string version = "$Id: calcrec.cpp 1881 2014-02-25 16:20:58Z mmoorkamp $";
44 
45 int main(int argc, char *argv[])
46  {
47  // write some info
48  cout << " This is datarec: Calculate receiver functions from input data" << endl;
49  cout << " Reads in radial and vertical components in SAC format" << endl;
50  cout << " Outputs a file with the name of the radial component and .rec appended"
51  << endl;
52  cout << " Some behaviour can be configured with the file calcrec.conf" << endl;
53  cout << " This is Version: " << version << endl << endl;
54  string modelfilename;
55 
56  CalcRecConf Config(argc, argv);
57  SeismicDataComp Radial, Vertical;
58  ResPkModel Model;
59  string outfilename;
60  try
61  {
62  //get the settings from the configuration file
63  Config.GetData("calcrec.conf");
64  //the default method is spectral division
65  RecCalc::trfmethod rfmethod = RecCalc::specdiv;
66  if (Config.recmethod == "iterdecon")
67  {
68  rfmethod = RecCalc::iterdecon;
69  }
70  string radfilename, verfilename;
71 
72  radfilename = AskFilename("Radial Component: ");
73  verfilename = AskFilename("Vertical Component: ");
74 
75  //the receiver function name is determined from the radial component
76  outfilename = radfilename + ".rec";
77  //read in the two components
78  Radial.ReadData(radfilename);
79  Vertical.ReadData(verfilename);
80  if (Config.upperfreq > 0.0 && Config.lowerfreq > 0.0
81  && Config.upperfreq > Config.lowerfreq)
82  {
83  const double lowfilfreq = Config.lowerfreq * Radial.GetDt();
84  const double upfilfreq = Config.upperfreq * Radial.GetDt();
85  SimpleBp Bandpass(lowfilfreq, upfilfreq);
86  std::transform(Radial.GetData().begin(), Radial.GetData().end(),
87  Radial.GetData().begin(), Bandpass);
88  std::transform(Vertical.GetData().begin(), Vertical.GetData().end(),
89  Vertical.GetData().begin(), Bandpass);
90  }
91  SeismicDataComp PComp(Vertical), SComp(Radial);
92  if (Config.rotate)
93  {
94  RFVelCalc RFVel(Config.sigma, Config.cc, rfmethod);
95  double p = Config.p;
96  if (p < 0.0)
97  {
98  std::cerr << "Need to set ray parameter p " << std::endl;
99  return 100;
100  }
101  ttsdata AppVel;
102  //do the calculation and write to a file
103  RFVel.CalcRFVel(p, Radial, Vertical, AppVel);
104  double beta_est = Config.beta; //AppVel.at(0);
105  double alpha_est = beta_est * sqrt(3.0);
106 
107  double qa = sqrt(std::pow(alpha_est, -2) - pow2(p));
108  double qb = sqrt(std::pow(beta_est, -2) - pow2(p));
109  double Vpz = (1.0 - 2.0 * pow2(beta_est) * pow2(p)) / (2.0 * alpha_est * qa);
110  double Vsr = (1.0 - 2.0 * pow2(beta_est) * pow2(p)) / (2.0 * beta_est * qb);
111  double Vpr = p * pow2(beta_est) / alpha_est;
112  double Vsz = -p * beta_est;
113  std::vector<double> VerNew(Vertical.GetData().size()), RadNew(
114  Vertical.GetData().size());
115  for (size_t i = 0; i < Vertical.GetData().size(); ++i)
116  {
117  VerNew.at(i) = Vpr * Radial.GetData().at(i)
118  + Vpz * Vertical.GetData().at(i);
119  RadNew.at(i) = Vsr * Radial.GetData().at(i)
120  + Vsz * Vertical.GetData().at(i);
121  }
122  std::copy(RadNew.begin(), RadNew.end(), SComp.GetData().begin());
123  std::copy(VerNew.begin(), VerNew.end(), PComp.GetData().begin());
124  SComp.WriteAsSac("s.comp");
125  PComp.WriteAsSac("p.comp");
126  }
127  //initialize the object to calculate receiver functions with some essential parameters
128  RecCalc Receiver(Config.shift, Config.sigma, Config.cc, false, rfmethod);
129  //do we want the initial correlation peak to have an amplitude of 1 ?
130  Receiver.SetNormalize(Config.normalize);
131  SeismicDataComp RecFunc;
132  //calculate the receiver function
133  if (Config.prec)
134  {
135  Receiver.CalcRecData(SComp, PComp, RecFunc);
136  }
137  else
138  {
139  Receiver.CalcRecData(PComp, SComp, RecFunc);
140 
141  }
142  //write out a sac file with the receiver function
143  RecFunc.WriteAsSac(outfilename);
144  } catch (FatalException &e)
145  {
146  cerr << e.what() << endl; // if something fails print error
147  return -1; // and stop execution
148  }
149  }
trfmethod
There are several ways to calculate receiver functions.
Definition: RecCalc.h:18
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.
Definition: RecCalc.h:14
std::vector< double > & GetData()
Access for data vector, for ease of use and efficiency we return a reference.
std::string recmethod
Definition: CalcRecConf.h:37
void GetData(std::string filename)
Definition: CalcRecConf.cpp:32
void SetNormalize(const bool what)
Change whether the output receiver function is normalized to a maximum amplitude of 1...
Definition: RecCalc.h:55
void CalcRecData(const SeismicDataComp &RadComp, const SeismicDataComp &VerComp, SeismicDataComp &Receiver)
Calculate Receiver functions from two data components.
Definition: RecCalc.cpp:173
This class implements the method to calculate absolute S-Wave velocities from Receiver function data ...
Definition: RFVelCalc.h:13
void CalcRFVel(const double slowness, const SeismicDataComp &RadComp, const SeismicDataComp &VerComp, ttsdata &AppVel)
Calculate absolute velocities from the radial and vertical components of the seismogram.
Definition: RFVelCalc.cpp:97
int main(int argc, char *argv[])
Definition: calcrec.cpp:45
double GetDt() const
Return dt in s.
string version
Definition: calcrec.cpp:43
This class stores and writes model for the respktn 1D seismic code that we use for receiver function ...
Definition: ResPkModel.h:18
int WriteAsSac(const std::string &filename) const
Write the data in sac binary format.
The basic exception class for all errors that arise in gplib.