GPLIB++
levjoint.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include "Iso1DMTObjective.h"
3 #include "MTStation.h"
4 #include "gentypes.h"
5 #include "SeismicDataComp.h"
6 #include "AbsVelRecObjective.h"
7 #include "CLevmarConf.h"
8 #include "lm.h"
9 #include "MTFitSetup.h"
10 #include "SurfaceWaveData.h"
11 #include <boost/bind.hpp>
12 #include <boost/shared_ptr.hpp>
13 
14 using namespace std;
15 using namespace gplib;
16 
17 CLevmarConf Configuration("levmar.conf");
19 boost::shared_ptr<const SeismicDataComp> RecData(new SeismicDataComp(
20  Configuration.recinputdata, SeismicDataComp::sac));
24  Configuration.sigma, Configuration.wlevel, Configuration.slowness);
25 
26 void misfit(double *p, double *x, int m, int n, void *data)
27  {
28  const unsigned int nlayers = m / 3;
29  const unsigned int nparam = nlayers * 2;
30  ttranscribed mtmember(nparam), recmember(nparam);
31  for (unsigned int i = 0; i < nparam; ++i)
32  {
33  mtmember(i) = p[i];
34  }
35  for (unsigned int i = 0; i < nparam; ++i)
36  recmember(i) = p[i + nlayers];
37  int offset = 0;
38  if (Configuration.weights.at(0) > 0)
39  {
40  MTObjective.CalcPerformance(mtmember);
41  for (size_t i = 0; i < MTObjective.GetMisfit().size(); ++i)
42  {
43  x[i] = MTObjective.GetMisfit()(i) * Configuration.weights.at(0);
44  }
45  offset = MTObjective.GetMisfit().size();
46  }
47  if (Configuration.weights.at(1) > 0)
48  {
49  RecObjective.CalcPerformance(recmember);
50  for (size_t i = 0; i < RecObjective.GetMisfit().size(); ++i)
51  {
52  x[i + offset] = RecObjective.GetMisfit()(i)
53  * Configuration.weights.at(1);
54  }
55  }
56  }
57 
58 int main()
59  {
60 
61  string version = "$Id: levjoint.cpp 1816 2009-09-07 11:28:35Z mmoorkamp $";
62  cout << endl << endl;
63  cout << "Program " << version << endl;
64  cout << " Levenberg Marquardt to jointly invert seismic and MT data "
65  << endl;
66  cout << " look at levmar.conf for configuration and setup " << endl;
67  cout << " output files will be of the form " << endl;
68  cout << " best_lev + ending " << endl;
69 
70  Configuration.GetData("levmar.conf");
71  try
72  {
73  MTData.GetData(Configuration.mtinputdata);
74  //RecData.GetData(Configuration.recinputdata,SeismicDataComp::sac);
75  RFAbsVel.ReadAscii(Configuration.rfabsveldata);
76  } catch (FatalException &e)
77  {
78  cerr << e.what() << endl;
79  return -1;
80  }
81 
82  //we have to do this again becuase the global objects were initialized with the wrong inputdata
85  RecCalc::trfmethod rfmethod = RecCalc::specdiv;
86  if (Configuration.recmethod == "iterdecon")
87  {
88  rfmethod = RecCalc::iterdecon;
89  }
91  Configuration.sigma, Configuration.wlevel, Configuration.slowness,
92  rfmethod);
98 
99  const int nlayers = Configuration.minres.size();
100  const int nparams = nlayers * 3;
101  ttranscribed mtmember(nlayers * 2), recmember(nlayers * 2);
102  copy(Configuration.startres.begin(), Configuration.startres.end(),
103  mtmember.begin());
104  copy(Configuration.startthick.begin(), Configuration.startthick.end(),
105  mtmember.begin() + nlayers);
106  copy(Configuration.startthick.begin(), Configuration.startthick.end(),
107  recmember.begin());
108  copy(Configuration.startsvel.begin(), Configuration.startsvel.end(),
109  recmember.begin() + nlayers);
110  MTObjective.CalcPerformance(mtmember);
111  RecObjective.CalcPerformance(recmember);
112 
113  //double p[nparams],lb[nparams],ub[nparams];
114  double *p = new double[nparams];
115  double *lb = new double[nparams];
116  double *ub = new double[nparams];
117  double *x;
118 
119  int n = 0;
120  if (Configuration.weights.at(0) > 0)
121  n += MTObjective.GetSynthData().size();
122  if (Configuration.weights.at(1) > 0)
123  n += RecObjective.GetSynthData().size();
124 
125  if (n == 0)
126  {
127  cerr << "One weight has to be > 0 !";
128  return 100;
129  }
130  x = new double[n];
131  double opts[LM_OPTS_SZ], info[LM_INFO_SZ];
132 
133  opts[0] = LM_INIT_MU;
134  opts[1] = 1E-15;
135  opts[2] = 1E-15;
136  opts[3] = 1E-20;
137  opts[4] = LM_DIFF_DELTA; // relevant only if the finite difference jacobian version is used
138 
139  for (int i = 0; i < nlayers; ++i)
140  {
141  p[i] = Configuration.startres.at(i);
142  lb[i] = Configuration.minres.at(i);
143  ub[i] = Configuration.maxres.at(i);
144  }
145  for (int i = 0; i < nlayers; ++i)
146  {
147  p[i + nlayers] = Configuration.startthick.at(i);
148  lb[i + nlayers] = Configuration.minthick.at(i);
149  ub[i + nlayers] = Configuration.maxthick.at(i);
150  }
151  for (int i = 0; i < nlayers; ++i)
152  {
153  p[i + 2 * nlayers] = Configuration.startsvel.at(i);
154  lb[i + 2 * nlayers] = Configuration.minsvel.at(i);
155  ub[i + 2 * nlayers] = Configuration.maxsvel.at(i);
156  }
157 
158  for (int i = 0; i < n; i++)
159  x[i] = 0.0;
160 
161  double ret = dlevmar_bc_dif(misfit, p, x, nparams, n, lb, ub,
162  Configuration.maxiter, opts, info, NULL, NULL, NULL); // no jacobian
163  cout << "Levenberg-Marquardt returned " << ret << " in " << info[5]
164  << "iter, reason " << info[6] << endl;
165 
166  cout << endl << " Minimization info:" << endl;
167  for (int i = 0; i < LM_INFO_SZ; ++i)
168  cout << info[i] << " ";
169  cout << endl;
170 
171  ttranscribed mtbest(nlayers * 2), recbest(nlayers * 2);
172  for (int i = 0; i < nlayers * 2; ++i)
173  {
174  mtbest(i) = p[i];
175  recbest(i) = p[i + nlayers];
176  }
177  cout << endl;
178  double mtdiff = MTObjective.CalcPerformance(mtbest);
179  double recfit = RecObjective.CalcPerformance(recbest);
180 
181  cout << "MT-Fit: " << mtdiff << " Rec-Fit: " << recfit << endl;
182  ostringstream filename;
183  filename << "best_lev";
184 
185  cout << " Saved as : " << filename.str() << endl;
186  MTObjective.WriteData(filename.str());
187  MTObjective.WriteModel(filename.str() + "_mt.mod");
188  MTObjective.WritePlot(filename.str() + "_mt.plot");
189  RecObjective.WriteData(filename.str() + ".rec");
190  RecObjective.WriteModel(filename.str() + "_rec.mod");
191  RecObjective.WritePlot(filename.str() + "_rec");
192  delete[] x;
193  delete[] p;
194  delete[] lb;
195  delete[] ub;
196  return 0;
197  }
void SetRecWeight(const double w)
Set the relative weight for the pure receiver function.
trfmethod
There are several ways to calculate receiver functions.
Definition: RecCalc.h:18
void SetupMTFitParameters(const tConfObject &Configuration, C1DMTObjective &Objective)
Definition: MTFitSetup.h:8
ublas::vector< double > ttranscribed
Definition: gentypes.h:21
MTStation Best
Definition: levjoint.cpp:18
double CalcPerformance(const ttranscribed &member)
For serial execution CalcPerformance calls the three Parallel functions for more convenient use...
void misfit(double *p, double *x, int m, int n, void *data)
Definition: levjoint.cpp:26
virtual void WriteData(const std::string &filename)
Write current data to a file.
void WritePlot(const std::string &filename)
Write the current model to ascii file for plotting.
virtual void WriteData(const std::string &filename)
Write out the receiver function and absolute velocity data, the absolute velocity data gets ...
boost::shared_ptr< const SeismicDataComp > RecData(new SeismicDataComp(Configuration.recinputdata, SeismicDataComp::sac))
virtual void WritePlot(const std::string &filename)
write the current model for plotting to a file
virtual void GetData(const std::string filename)
read in data from file, determines format by ending
Definition: MTStation.cpp:597
A class to read, write and store fundamental mode surface wave dispersion data.
CLevmarConf Configuration("levmar.conf")
const tdata & GetSynthData()
Return the current synthetic data.
int main()
Definition: levjoint.cpp:58
void SetErrorLevel(const double level)
Set the errorlevel for fit, this is relative to the maximum amplitude, not for each individual data p...
The class MTStation is used to store the transfer functions and related information for a MT-site...
Definition: MTStation.h:17
void SetAbsVelWeight(const double w)
Set the relative weight for the absolute velocity information.
SurfaceWaveData RFAbsVel
Definition: levjoint.cpp:22
virtual void ReadAscii(const std::string &filename)
Read a file in general ascii format, i.e lines with period velocity each.
const tmisfit & GetMisfit()
Return the misfit vector.
void WriteModel(const std::string &filename)
Write the current model to ascii file for calculations.
This objective function calculates the weighted misfit for a receiver function and the corresponding ...
void SetPoisson(const double ratio)
Set poisson's ratio, at the moment the same for all layers, used for calculating P-velocity.
AbsVelRecObjective RecObjective(RecData, RFAbsVel, Configuration.shift, Configuration.sigma, Configuration.wlevel, Configuration.slowness)
string version
Definition: makeinput.cpp:16
This class implements the forward calculation for a 1D isotropic MT model.
void SetTimeWindow(const double start, const double end)
Set the time window used for misfit calculations, start and end are in seconds.
virtual void WriteModel(const std::string &filename)
write the current model to a file
MTStation MTData
Definition: levjoint.cpp:18
The basic exception class for all errors that arise in gplib.
Iso1DMTObjective MTObjective(MTData)