GPLIB++
1dinvga.cpp
Go to the documentation of this file.
1 /*!
2  * \file
3  * The program 1dinvga is the core joint inversion program for MT, receiver functions
4  * and surface wave data. It reads in its settings from the configuration file <CODE> 1dinvga.conf </CODE>, described
5  * below, and produces several log files and the final data, model(s) and plot file(s) for each
6  * inverted dataset.
7  *
8  <H2> General Configuration in 1dinvga.conf </H2>
9  The options in <CODE> 1dinvga.conf </CODE> are as follows:
10  <H3> General program options </H3>
11  <TABLE>
12  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
13  <TR> <TD>verbose</TD> <TD> false </TD> <TD> Print detailed information about all models used in the invbersion, only useful for debugging</TD></TR>
14  <TR> <TD>outputbase</TD> <TD> </TD> <TD> The start of the name of all logfiles. This can also be specified on the command lin.e</TD> </TR>
15  <TR> <TD>threads</TD><TD> 1 </TD> <TD>If the program has been compiled with openmp support, this specifies the number of simultaneous threads. </TD></TR>
16  </TABLE>
17 
18  <H3> Genetic algorithm options </H3>
19  <TABLE>
20  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
21  <TR> <TD>gatype</TD> <TD> </TD> <TD> Can be either <CODE>anneal</CODE> or <CODE> pareto</CODE>. If set to <CODE>anneal</CODE> we use an annealing type GA that minimizes
22  a weighted sum of the objective functions with the weights specified below. For this type of GA we also have to specify inittemp and coolingratio.
23  If set to <CODE> pareto</CODE>, we use NSGA-II as described by Deb et al. (2002). In this case inittemp and coolingratio are ignored. </TD></TR>
24  <TR> <TD>inittemp</TD><TD> </TD> <TD>(For GA type <CODE>anneal</CODE>)The initial temperature in the cooling schedule. High values mean that there will be no big differences in
25  probability between well fitting models and bad fitting models. Low values make those differences much more severe. If set to negative values the temperature
26  will be determined from the average misfit values in the first iteration. </TD> </TR>
27  <TR> <TD>annealinggeneration</TD><TD> </TD><TD>(For GA type <CODE>anneal</CODE>) The generation number when the initial tempature is divided by coolingratio to enforce stronger
28  discrimination between good and bad fitting models.</TD></TR>
29  <TR> <TD>coolingratio</TD><TD> </TD><TD>(For GA type <CODE>anneal</CODE>) The value by which inittemp is divided at generation <CODE>annealinggeneration</CODE>
30  Higher values mean stronger discrimination.</TD>/TR>
31  <TR> <TD>popsize</TD><TD> </TD><TD>The population size for the genetic algorithm. Typical values 50...1000 </TD></TR>
32  <TR> <TD>generations</TD><TD> </TD><TD>The number of generations for the GA to run.Typical values 50...500. </TD>/TR>
33  <TR> <TD>mutationprob</TD><TD> </TD><TD>The probability for a mutation within one member, typically 0.1...0.2. The probability for mutation of
34  individual bits is calculated from this number depending on the length of the encoding specified below. </TD></TR>
35  <TR> <TD>crossoverprob</TD><TD> </TD><TD>The probability for two model to perform crossover. Typically 0.4...0.7. </TD></TR>
36  <TR> <TD>elitist</TD><TD> </TD><TD>Do we want to keep the best model(s) from the last generation (true), or fully depend
37  on crossover and mutation with the risk of loosing good models (false). </TD></TR>
38  </TABLE>
39  <H3> Data information</H3>
40 
41  <TABLE>
42  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
43  <TR> <TD>recinfofile</TD><TD> </TD><TD>The file containing information about the receiver function data. This file is decribed below. </TD></TR>
44  <TR> <TD>mtinputdata</TD><TD> </TD><TD>The name of the file containing the MT impedances </TD></TR>
45  <TR> <TD>dispdata</TD><TD> </TD><TD>The name of the file containing the Rayleigh wave dispersion data</TD></TR>
46  </TABLE>
47 
48  <H3> Error floor information </H3>
49  <TABLE>
50  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
51  <TR> <TD>tensorerror</TD> <TD> 0.02</TD> <TD>Error floor for MT impedances, if selected below </TD></TR>
52  <TR> <TD>reserror </TD> <TD>0.02 </TD> <TD>Error floor for MT apparent resistivities, if selected below </TD></TR>
53  <TR> <TD>phaseerror </TD> <TD>0.02 </TD><TD>Error floor for MT phase, if selected below </TD></TR>
54  <TR> <TD>surferror </TD><TD>0.02 </TD><TD>Error floor for Rayleigh wave dispersion data </TD></TR>
55  </TABLE>
56 
57  <H3> Global receiver function parameters </H3>
58  <TABLE>
59  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
60  <TR> <TD>poisson</TD><TD> </TD><TD> Poissons ratio, we calculate Vp from Vs using this ratio</TD></TR>
61  <TR> <TD>normrec</TD><TD> true </TD><TD> Are we inverting receiver functions that have been normalized to a maximum amplitude of 1 ?</TD></TR>
62  <TR> <TD>starttime</TD><TD> </TD><TD>Start of the fit window in seconds. Any data in the receiver function before this time is ignored. </TD></TR>
63  <TR> <TD>endtime</TD><TD> </TD><TD>End of the fit window in seconds. Any data in the receiver function after this time is ignored. </TD></TR>
64  <TR> <TD>recmethod</TD><TD> </TD><TD>Method used to calculate the measured data. Can be <CODE>specdiv</CODE> for spectral division,
65  or <CODE>iterdecon</CODE> for iterative deconvolution. </TD></TR>
66  </TABLE>
67 
68  <H3> MT data parameters </H3>
69  <TABLE>
70  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
71  <TR> <TD>mode</TD><TD> </TD><TD>Which component of the tensor to fit. Can be <CODE>xy</CODE> or <CODE>yx</CODE>. </TD></TR>
72  <TR> <TD>mtfit</TD><TD> </TD><TD>Which aspect of the MT data to fit. Possible values are shown in the table below. </TD></TR>
73  </TABLE>
74 
75  <H3> Possible mtfit values </H3>
76  <TABLE>
77  <TR> <TD> <B>Name</B> </TD> <TD><B>Description</B></TD> </TR>
78  <TR> <TD> appres </TD> <TD>Fit only apparent resistivity of selected mode</TD> </TR>
79  <TR> <TD> phase </TD> <TD>Fit only phase of selected mode</TD> </TR>
80  <TR> <TD> resphase </TD> <TD>Fit apparent resistivity and phase of selected mode</TD> </TR>
81  <TR> <TD> berd </TD> <TD>Fit Berdichevskiy invariant. This is independent of selected mode</TD> </TR>
82  <TR> <TD> det</TD> <TD>Fit determinant of impedance tensor. This is independent of selected mode.</TD> </TR>
83  </TABLE>
84 
85  <H3> Regularization and fit information </H3>
86  <TABLE>
87  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
88  <TR> <TD>usevrefmodel </TD><TD> false </TD><TD>Do we want to regularize the seismic parameters by the difference to a reference model (true/false) ? </TD></TR>
89  <TR> <TD>vrefmodel</TD><TD> </TD><TD>If true above, the name of the reference model file. </TD></TR>
90  <TR> <TD>mtfitexponent </TD><TD> 2</TD><TD>The exponent for the difference between measured and calculated data. Higher exponents penalize
91  any departure from the measured data. This ensures a tighter fit, but also increases the influence of noise.</TD></TR>
92  <TR> <TD>recfitexponent </TD><TD>2 </TD><TD>Same for receiver function data. </TD></TR>
93  <TR> <TD>surffitexponent </TD><TD> 2</TD><TD>Same for dispersion data. </TD></TR>
94  </TABLE>
95 
96 
97  <H3> Parameter encoding </H3>
98  The number of layers is determined by the number of entries, it has to be equal for all
99  encoding parameters.
100  <TABLE>
101  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
102  <TR> <TD>thickbase</TD><TD> </TD><TD>Minimum thickness for each layer in km </TD></TR>
103  <TR> <TD>thickstep</TD><TD> </TD><TD>Stepsize for each layer in km </TD></TR>
104  <TR> <TD>thicksizes</TD><TD> </TD><TD>Number of bits used to encode the thickness of each layer </TD></TR>
105  <TR> <TD>resbase</TD><TD> </TD><TD>Base 10 logarithm of the minimum resistivity, i.e. 0 corresponds to 1 Ohm.m </TD></TR>
106  <TR> <TD>resstep</TD><TD> </TD><TD>Stepsize for base 10 logarithm of resistivity </TD></TR>
107  <TR> <TD>ressizes</TD><TD> </TD><TD>Number of bits used to encode resistivity </TD></TR>
108  <TR> <TD>svelbase</TD><TD> </TD><TD>Minimum S-Wave velocity for each layer in km/s </TD></TR>
109  <TR> <TD>svelstep</TD><TD> </TD><TD>Stepsize for S_Wave velocity for each layer </TD></TR>
110  <TR> <TD>svelsizes</TD><TD> </TD><TD>Number of bits used to encode Vs </TD></TR>
111  </TABLE>
112 
113  <H3> Weighting of datasets </H3>
114  <TABLE>
115  <TR> <TD> <B>Name</B> </TD> <TD><B> Default</B></TD> <TD><B>Description</B></TD>
116  <TR> <TD>weights</TD> <TD> </TD> <TD>These are the weights for the different objective functions. The current version needs exactly 5 weights.
117  They correspond to MT misfit, Receiver function misfit, Surface Wave Misfit, Seismic Regularization and MT regularization, respectively.
118  If a weight is set to zero the calculation of the misfit is completely disabled and the inversion thus runs faster. For pareto type inversion
119  the value of weight is irrelevant as long as it is different from zero. For annealing it determines the influence of the corresponding dataset. </TD></TR>
120  </TABLE>
121 
122  <H2> Recinfo file </H2>
123  The recinfo file contains information about the different receiver functions we are trying to fit. Each
124  line in the file corresponds to one receiver function and requires the following entries
125  <TABLE>
126  <TR> <TD>Ray parameter in s/km </TD>
127  <TD>\f$ \sigma\f$ for gaussian filter </TD> <TD> Waterlevel </TD> <TD>Relative error </TD> <TD>Shift in s </TD> <TD> Type of data </TD>
128  <TD>Filename </TD></TR>
129  </TABLE>
130  Type of data is a single character. If it is 'a' we are also fitting absolute velocity information as calculated by the
131  program rfvel and described in Svenningsen, GJI 170, 2007. In this case the following
132  additional fields are needed
133  <TABLE>
134  <TR> <TD>Weight for RF </TD> <TD>Weight for absolute velocities </TD> <TD>Filename for absolute velocities </TD> </TR>
135  </TABLE>
136  If data type is any other character we only fit receiver function information and the absolute velocity information cannot be there.
137  <H2> Other features</H2>
138  - You can gracefully stop the inversion any time by creating a file called "abort" in the working directory.
139  The inversion will stop after the current iteration and will write out the usual information about best models etc.
140  This is useful when the chosen number of generations was too high and the algorithm has already reached an acceptable solution.
141  The file is automatically deleted.
142  */
143 
144 #include <iostream>
145 #include <iomanip>
146 #include <fstream>
147 #include <algorithm>
148 #include <numeric>
149 #include <sstream>
150 #include <string>
151 #include <boost/bind.hpp>
152 #include <boost/shared_ptr.hpp>
153 #include <boost/filesystem.hpp>
154 #include <boost/date_time/posix_time/posix_time.hpp>
155 #include "GA.h"
156 #include "Iso1DMTObjective.h"
157 #include "MTStation.h"
158 #include "AbsVelRecObjective.h"
159 #include "Multi1DRecObjective.h"
160 #include "SeismicDataComp.h"
161 #include "CombinedRoughness.h"
162 #include "SeismicModelDiff.h"
163 #include "ResPkModel.h"
164 #include "SurfaceWaveObjective.h"
165 #include "SurfaceWaveData.h"
166 #include "Adaptors.h"
167 #include "MTFitSetup.h"
168 #include "Util.h"
169 #include "MTRoughness.h"
170 #include "SurfaceWaveData.h"
171 #include "FileAbort.h"
172 #include "SeisTools.h"
173 #include "IsoJointConf.h"
174 #include "MTInvConf.h"
175 #include "SurfInvConf.h"
176 #include "RecInvConf.h"
177 #include "GAConf.h"
178 
179 using namespace std;
180 using namespace gplib;
181 
183  {
185  };
186 
187 typedef boost::shared_ptr<GeneralObjective> pCGeneralObjective;
188 
189 //! Set the annealing GA temperature parameter, we should only call this function if we are SURE that it is an AnnealinGA
190 void SetupAnnealingGA(boost::shared_ptr<GeneralGA> &GA, const double inittemp,
191  const int annealinggeneration, const double coolingratio)
192  {
193  // we get the temperature from the configuration file
194  double InitTemperature = inittemp;
195  // if it is negative we determine it by performing one iteration
196  if (inittemp < 0)
197  {
198  double avgcombfit = 0;
199  GA->DoIteration(0, false);
200  //we calculate the average fit across all objective functions
201  avgcombfit = accumulate(GA->GetAvgFit().begin(), GA->GetAvgFit().end(),
202  0.0);
203  // for negative temperatures we calculate the actual temperature from the average fit
204  InitTemperature = avgcombfit * abs(inittemp);
205  }
206  AnnealingGA *AnnealGA = dynamic_cast<AnnealingGA*> (GA.get());
207  //we set the annealing parameters for the GA
208  AnnealGA->SetParams(InitTemperature, annealinggeneration, coolingratio);
209  }
210 
211 //! Use the information stored in recinforfile to setup the multi receiver function objective function
212 void SetupRecObjective(const string recinfofile,
213  Multi1DRecObjective &RecObjective, const bool normrec,
214  RecCalc::trfmethod rfmethod)
215  {
216  ifstream recinfo(recinfofile.c_str());
217  double slowness, sigma, cc, recerror, recweight, absweight;
218  int shift;
219  string recinputdata, absinputdata;
220  char wantabsvel; // do we want absolute velocities as well
221  //as long as we can read from recinfofile
222  while (recinfo.good())
223  {
224  //assume we do not want absolute velocity information
225  wantabsvel = 'r';
226  //read the mandatory values from the file
227  recinfo >> slowness >> sigma >> cc >> recerror >> shift >> wantabsvel
228  >> recinputdata;
229  // if we want absolute velocities we have to read in additional information
230  if (wantabsvel == 'a')
231  {
232  recinfo >> recweight >> absweight >> absinputdata;
233  }
234  //if reading all values succeeded
235  if (recinfo.good())
236  {
237  //create a shared pointer to a new receiver function data object
238  boost::shared_ptr<const SeismicDataComp> RecData(
239  new SeismicDataComp(recinputdata, SeismicDataComp::sac));
240  //if we need absolute velocity information
241  if (wantabsvel == 'a')
242  {
243  //read in data from the input file
244  SurfaceWaveData AbsVelData;
245  AbsVelData.ReadAscii(absinputdata);
246  // add an objective function that fits receiver functions and absolute velocities
247  RecObjective.AddAbsVelFunction(RecData, AbsVelData, shift,
248  sigma, cc, slowness, rfmethod, recerror, normrec,
249  absweight, recweight);
250  }
251  //if we don't want absolute velocity information
252  else
253  {
254  ResPkModel::WaveType InWave = ResPkModel::PWave;
255  if (wantabsvel == 's')
256  {
257  InWave = ResPkModel::SWave;
258  }
259  //add an objective function that only considers standard receiver functions
260  RecObjective.AddRecFunction(RecData, shift, sigma, cc,
261  slowness, rfmethod, recerror, normrec, InWave);
262  }
263  }
264  }
265  }
266 
267 int main(int argc, char *argv[])
268  {
269  //we report the total run time at the end so we record when we started
270  boost::posix_time::ptime starttime =
271  boost::posix_time::microsec_clock::local_time();
272  //output some information about the program
273  string version = "$Id: 1dinvga.cpp 1888 2015-04-09 13:40:29Z mmoorkamp $";
274  cout << endl << endl;
275  cout << "Program " << version << endl;
276  cout << "Genetic algorithm to jointly invert seismic and MT data " << endl;
277  cout << "look at 1dinvga.conf for configuration and setup " << endl;
278  cout << "The root name of log-files can be overwritten by using " << endl;
279  cout << "1dinvga newrootname " << endl;
280 
281 
282  MTInvConf MTConf;
283  RecInvConf RecConf;
284  SurfInvConf SurfConf;
285  IsoJointConf JointConf;
286  GAConf GaConf;
287 
290  SurfaceWaveData DispData;
291  UniformRNG Random;
292 
293  std::ifstream conffile("1dinvga.conf");
294 
295  MTConf.GetData(conffile);
296  conffile.clear();
297  conffile.seekg(0, std::ios::beg);
298  RecConf.GetData(conffile);
299  conffile.clear();
300  conffile.seekg(0, std::ios::beg);
301  SurfConf.GetData(conffile);
302  conffile.clear();
303  conffile.seekg(0, std::ios::beg);
304  JointConf.GetData(conffile);
305  conffile.clear();
306  conffile.seekg(0, std::ios::beg);
307  GaConf.GetData(conffile);
308 
309  ttranscribed transcribed;
310  tgatype GAtype = pareto;
311 
312  string outputbase;
313  // we can specify the start of the names of the log files on the command line or in the configuration file
314  if (argc > 1)
315  outputbase = argv[1];
316  else
317  outputbase = JointConf.outputbase;
318  //initialize the streams for the log files
319  //the ones that are always written out get the filename
320  ofstream fitstat((outputbase + ".ftst").c_str());
321  ofstream rankfile((outputbase + ".rank").c_str());
322  ofstream frontfile((outputbase + ".front").c_str());
323  //the optional ones are left without a filename
324  ofstream misfitfile;
325  ofstream valuefile;
326  ofstream probfile;
327  ofstream distancefile;
328  // in most cases we do not need all of these values
329  //so we only write them if the user insists
330  if (JointConf.verbose)
331  {
332  misfitfile.open((outputbase + ".msft").c_str());
333  valuefile.open((outputbase + ".vals").c_str());
334  probfile.open((outputbase + ".probs").c_str());
335  distancefile.open((outputbase + ".dist").c_str());
336  }
337  //we do some very basic consistency checking
338  if ((JointConf.thickbase.size() != JointConf.resbase.size())
339  || (JointConf.thickbase.size() != JointConf.svelbase.size()))
340  {
341  cerr << "Configuration of genes is not consistent ! ";
342  return 100;
343  }
344  // we have three different types of inversion parameters
345  const int nparam = 3;
346  //determine the sizes of a number of GA structures from the configuration file
347  const int genes = (JointConf.thickbase.size()
348  + JointConf.resbase.size() + JointConf.svelbase.size());
349  const int popsize = GaConf.popsize;
350  const int maxgen = GaConf.generations;
351  const int paramlength = genes / nparam;
352  ttranscribed basevalues(genes);
353  ttranscribed stepsizes(genes);
354  tsizev genesizes(genes);
355 
356  misfitfile << popsize << " " << maxgen << " " << endl;
357  valuefile << genes << " " << popsize << " " << maxgen << endl;
358  //copy the vectors from the congiguration object to the GA
359  copy(JointConf.resbase.begin(), JointConf.resbase.end(),
360  basevalues.begin());
361  copy(JointConf.resstep.begin(), JointConf.resstep.end(),
362  stepsizes.begin());
363  copy(JointConf.ressizes.begin(), JointConf.ressizes.end(),
364  genesizes.begin());
365  //the GA vectors are just concatenations of the different parameters
366  copy(JointConf.thickbase.begin(), JointConf.thickbase.end(),
367  basevalues.begin() + paramlength);
368  copy(JointConf.thickstep.begin(), JointConf.thickstep.end(),
369  stepsizes.begin() + paramlength);
370  copy(JointConf.thicksizes.begin(), JointConf.thicksizes.end(),
371  genesizes.begin() + paramlength);
372 
373  copy(JointConf.svelbase.begin(), JointConf.svelbase.end(),
374  basevalues.begin() + 2 * paramlength);
375  copy(JointConf.svelstep.begin(), JointConf.svelstep.end(),
376  stepsizes.begin() + 2 * paramlength);
377  copy(JointConf.svelsizes.begin(), JointConf.svelsizes.end(),
378  genesizes.begin() + 2 * paramlength);
379 
380  const int totalgenesize = accumulate(genesizes.begin(), genesizes.end(), 0);
381  //create the objects for the genetic algorithm
382  BinaryPopulation Population(popsize, totalgenesize, Random, true);
383  BinaryTournamentSelect Select(Random, boost::bind(
384  &GeneralPopulation::GetProbabilities, boost::ref(Population)),
385  boost::bind(&GeneralPopulation::GetCrowdingDistances, boost::ref(
386  Population)));
387  StandardPropagation Propagator(&Select, &Population, &Random);
388  double indmutationprob = 1.0 - std::pow(1.0 - GaConf.mutationprob, 1.
389  / totalgenesize); // we specify the overall probability for mutation in config file
390  cout << "Individual Mutation set to: " << indmutationprob << endl;
391  Propagator.SetParams(indmutationprob, GaConf.crossoverprob);
392  GrayTranscribe Transcribe(basevalues, stepsizes, genesizes);
393 
394  //read in data
395  try
396  {
397  boost::shared_ptr<Multi1DRecObjective> RecObjective(
398  new Multi1DRecObjective());
399  //we only read the data that has positive weights in the inversion
400  if (JointConf.weights.at(0) > 0)
401  {
402  MTData.GetData(MTConf.mtinputdata);
403  }
404  if (JointConf.weights.at(1) > 0)
405  {
406  RecCalc::trfmethod rfmethod = RecCalc::specdiv;
407  if (RecConf.recmethod == "iterdecon")
408  {
409  rfmethod = RecCalc::iterdecon;
410  }
411  //use the information in the recinfofile to initialize the RF objective function
412  SetupRecObjective(RecConf.recinfofile, *RecObjective.get(),
413  RecConf.normrec, rfmethod);
414  }
415  if (JointConf.weights.at(2) > 0)
416  {
417  DispData.ReadFile(SurfConf.dispdata);
418  }
419  //setup MT Objective function
420  boost::shared_ptr<Iso1DMTObjective> MTObjective(new Iso1DMTObjective(
421  MTData));
422  SetupMTFitParameters(MTConf, *MTObjective);
423  MTObjective->SetFitExponent(MTConf.mtfitexponent);
424 
425  //setup RF objective function
426  RecObjective->SetPoisson(JointConf.poisson);
427  RecObjective->SetTimeWindow(RecConf.starttime,
428  RecConf.endtime);
429 
430  //setup surface wave data
431  boost::shared_ptr<SurfaceWaveObjective> SurfObjective(
432  new SurfaceWaveObjective(DispData));
433  SurfObjective->SetFitExponent(SurfConf.surffitexponent);
434  SurfObjective->SetPoisson(JointConf.poisson);
435  SurfObjective->SetErrorLevel(SurfConf.surferror);
436 
437  //setup Regularization
438  boost::shared_ptr<GeneralObjective> RecRegularization;
439  //if we don't want a reference model regularization
440  // we regularize by smoothness over resistivity and velocity
441  if (!JointConf.usevrefmodel)
442  {
443  RecRegularization = boost::shared_ptr<GeneralObjective>(
444  new CombinedRoughness);
445  }
446  //otherwise we regularize with a reference model
447  else
448  {
449  //we check if the file exists
450  if (!boost::filesystem::exists(JointConf.vrefmodel))
451  {
452  cerr
453  << "Cannot find reference model for regularization ! Exiting !"
454  << endl;
455  return 100;
456  }
457  //get the model from the file
458  ResPkModel VRefModel;
459  VRefModel.ReadModel(JointConf.vrefmodel);
460  // and initialize the regularization object
461  RecRegularization = boost::shared_ptr<GeneralObjective>(
462  new SeismicModelDiff(VRefModel));
463  }
464  //MT is always regularized by smoothness
465  //this can create some redundancy and should be changed in the future
466  boost::shared_ptr<GeneralObjective> MTRegularization(new MTRoughness());
467  //create the vector of objective functions for the GA
468  vector<pCGeneralObjective> ObjVector;
469  ObjVector.push_back(MTObjective);
470  ObjVector.push_back(RecObjective);
471  ObjVector.push_back(SurfObjective);
472  ObjVector.push_back(RecRegularization);
473  ObjVector.push_back(MTRegularization);
474 
475  boost::shared_ptr<GeneralGA> GA;
476  const size_t nthreads =1;
477  if (GaConf.gatype == "pareto")
478  {
479  GAtype = pareto;
480  boost::shared_ptr<ParetoGA> Pareto(new ParetoGA(&Propagator,
481  &Population, &Transcribe, ObjVector, nthreads));
482  GA = Pareto;
483  }
484  else if (GaConf.gatype == "anneal")
485  {
486  GAtype = anneal;
487  boost::shared_ptr<AnnealingGA> Annealing(new AnnealingGA(
488  &Propagator, &Population, &Transcribe, ObjVector,
489  nthreads));
490  GA = Annealing;
491  }
492  else
493  {
494  cerr << "Invalid GA type in configuration file." << endl;
495  cerr << " Has to be either 'pareto' or 'anneal' !" << endl;
496  return 100;
497  }
498  GA->SetWeights(JointConf.weights);
499  //Setting up indices for forward modelling
500  GeneralGA::tparamindv ParamIndices;
501  const int nmtparam = 2 * JointConf.resbase.size();
502  std::vector<int> LocalIndices;
503  //generate Indices 0 .. nmtparam for MT Objective function
504  generate_n(back_inserter(LocalIndices), nmtparam, IntSequence(0));
505  ParamIndices.push_back(LocalIndices);
506  const int nseisparam = 2 * JointConf.thickbase.size();
507  LocalIndices.clear();
508  // generate Indice thickbase .. thickbase+nseisparam for rf and surface wave data
509  generate_n(back_inserter(LocalIndices), nseisparam, IntSequence(
510  JointConf.thickbase.size()));
511  ParamIndices.push_back(LocalIndices);
512  ParamIndices.push_back(LocalIndices);
513  const int nmodelparam = 3 * JointConf.thickbase.size();
514  LocalIndices.clear();
515  //generate Indices 0 .. nmodelparam for Regularization Objective function
516  generate_n(back_inserter(LocalIndices), nmodelparam, IntSequence(0));
517  ParamIndices.push_back(LocalIndices);
518  ParamIndices.push_back(LocalIndices); // we push back twice, because both Regularization functionals work with all parameters
519  GA->SetParameterIndices(ParamIndices);
520  GA->SetElitist(GaConf.elitist);
521 
522  if (GAtype == anneal)
523  {
524  SetupAnnealingGA(GA,GaConf.inittemp,GaConf.annealinggeneration,GaConf.coolingratio );
525  Population.InitPop();
526  }
527  //Population.PrintPopulation(cout);
528  for (int i = 0; i < maxgen; ++i)
529  {
530  GA->DoIteration(i, i == (maxgen - 1));
531  if (JointConf.verbose) // in most cases we do not need all of these values
532  {
533  GA->PrintMisfit(misfitfile);
534  GA->PrintTranscribed(valuefile);
535  Population.PrintProbabilities(probfile);
536  Population.PrintDistances(distancefile);
537  }
538  GA->PrintBestMisfit(frontfile);
539 
540  fitstat << i << " ";
541  GA->PrintFitStat(fitstat);
542  if (WantAbort()) //if we want to exit prematurely
543  {
544  RemoveAbort();
545  // set counter to two before the last generation
546  // this way we do the last iteration for the GA which might have some special treatment
547  // and do everything that follows below to store the models and plots
548  i = maxgen - 2;
549  }
550  }
551 
552  int bestcount = 0;
553  // at the end we only want to output the unique models
554  // so we initialize a new UniquePop object that keeps track
555  UniquePop FinalUnique;
556  tfitvec bestfit(ObjVector.size());
557  tpopmember member(Population.GetGenesize());
558  //Get the indices of the models in the pareto front
559  vector<int> BestIndices(GA->GetBestModelIndices());
560  const int noutmodels = GA->GetNBestmodels();
561  const int nobjective = ObjVector.size();
562  //We have to translate between the parameters in the GA and the parameters
563  // for the objective functions
564  GeneralGA::tparamvector LocalParameters(nobjective);
565  //we allocate memory for each parameter set and objective function
566  for (int i = 0; i < nobjective; ++i)
567  {
568  LocalParameters.at(i).resize(ParamIndices.at(i).size(), false);
569  }
570  // we write the parameters for the unique final models into a file for overview
571  ofstream finalmodels((outputbase + ".final").c_str());
572  //for all good models including duplicates
573  for (int h = 0; h < noutmodels; ++h)
574  {
575  //get the genetic string for the current best model
576  member = row(Population.GetPopulation(), BestIndices.at(h));
577  //translate into numerical values
578  transcribed = Transcribe.GetValues(member);
579  //copy the right portion of the vector for each objective function
580  GA->SetupParams(transcribed, LocalParameters);
581  //if we haven't calculated the model before
582  if (!FinalUnique.Find(transcribed, bestfit))
583  {
584  //write out some information
585  cout << "Best: " << h << " Index : " << BestIndices.at(h)
586  << " ";
587  //recalculate the data, we didn't store this during the inversion
588  //we only calculate if we have a weight greater 0
589  for (int f = 0; f < nobjective; ++f)
590  {
591  if (JointConf.weights.at(f) > 0)
592  {
593  bestfit(f) = ObjVector.at(f)->CalcPerformance(
594  LocalParameters.at(f));
595  }
596  else
597  {
598  bestfit(f) = 0;
599  }
600  cout << setw(6) << setfill(' ') << setprecision(4)
601  << bestfit(f) << " ";
602  }
603  // write out the fit information and the index of the model
604  //so we can find the right files when looking at tradeoff etc.
605  copy(bestfit.begin(), bestfit.end(), ostream_iterator<double> (
606  finalmodels, " "));
607  cout << " " << h;
608  finalmodels << " " << bestcount << endl;
609  ostringstream filename;
610  filename << "best_" << bestcount;
611  //save all models, data and plots if the weight for the dataset
612  // is different from zero, we have to treat data and regularization differently
613  // so we cannot condense it with the for/if combination above that goes over all objectives
614  cout << " Saved as : " << filename.str();
615  if (JointConf.weights.at(0) > 0)
616  {
617  MTObjective->WriteModel(filename.str() + "_mt.mod");
618  MTObjective->WritePlot(filename.str() + "_mt.plot");
619  MTObjective->WriteData(filename.str());
620  }
621  if (JointConf.weights.at(1) > 0)
622  {
623  RecObjective->WriteData(filename.str() + ".rec");
624  RecObjective->WriteModel(filename.str() + "_rec.mod");
625  RecObjective->WritePlot(filename.str() + "_rec");
626  }
627  if (JointConf.weights.at(2) > 0)
628  {
629  SurfObjective->WriteData(filename.str() + ".disp");
630  SurfObjective->WriteModel(filename.str() + "_disp.mod");
631  SurfObjective->WritePlot(filename.str() + "_disp.plot");
632  }
633  filename.str("");
634  //store the model and fit, so we do not recalculate
635  FinalUnique.Insert(bestfit, transcribed);
636  bestcount++;
637  cout << endl;
638  }
639  }
640  //if we want verbose information
641  if (JointConf.verbose)
642  {
643  //print all the good models in raw form to a file
644  ofstream bestfile((outputbase + ".best").c_str());
645  FinalUnique.PrintAll(bestfile);
646  // and print the unique population members in the whole run
647  ofstream uniquepop((outputbase + ".unpop").c_str());
648  GA->PrintUniquePop(uniquepop);
649  }
650  //write out some run time information
651  boost::posix_time::ptime endtime =
652  boost::posix_time::microsec_clock::local_time();
653  std::cout << "Total Runtime: " << endtime - starttime << std::endl;
654  } catch (FatalException &e)
655  {
656  cerr << e.what() << endl;
657  return -1;
658  }
659  }
int generations
Definition: GAConf.h:23
trfmethod
There are several ways to calculate receiver functions.
Definition: RecCalc.h:18
void GetData(std::ifstream &instream)
Calculate the roughness for the MT part of a joint MT-seismic model as used by 1dinvga.
Definition: MTRoughness.h:7
void SetupMTFitParameters(const tConfObject &Configuration, C1DMTObjective &Objective)
Definition: MTFitSetup.h:8
virtual void ReadModel(const std::string filename)
Read the model in its native format from a file.
Definition: ResPkModel.cpp:92
ublas::vector< double > ttranscribed
Definition: gentypes.h:21
std::string gatype
Definition: GAConf.h:26
void AddRecFunction(boost::shared_ptr< const SeismicDataComp > TheRecData, int myshift, double mysigma, double myc, double myslowness, RecCalc::trfmethod method, double errorlevel, bool normalized, ResPkModel::WaveType InWave)
Add another reciever function to fit.
std::string recmethod
Definition: RecInvConf.h:22
double inittemp
Definition: GAConf.h:21
Generate uniformly distributed random numbers, this is basically a wrapper for the boost random numbe...
Definition: UniformRNG.h:19
bool Insert(const tfitvec &fitness, const ttranscribed &popmember)
Definition: UniquePop.cpp:17
Implements binary tournament selection for genetic algorithms.
void f(vector< double > &v1, vector< double > &v2, vector< double > &v3, vector< double > &v4)
Definition: perftest.cpp:17
int popsize
Definition: GAConf.h:20
A population that is encoded as a simple binary string.
double crossoverprob
Definition: GAConf.h:25
void AddAbsVelFunction(boost::shared_ptr< const SeismicDataComp > TheRecData, SurfaceWaveData &AbsVel, const int myshift, const double mysigma, const double myc, const double myslowness, const RecCalc::trfmethod method, const double errorlevel, const bool normalized, const double absvelweight, const double recweight)
Add another receiver function with absolute velocity transformation.
std::string vrefmodel
Definition: IsoJointConf.h:26
This class calculates the misfit between observed surface wave dispersion data and the data calculate...
std::vector< double > thickstep
Definition: IsoJointConf.h:28
bool Find(const ttranscribed &popmember, tfitvec &fitness)
Definition: UniquePop.cpp:25
std::vector< double > thickbase
Definition: IsoJointConf.h:27
std::vector< double > resstep
Definition: IsoJointConf.h:31
AnnealingGA implements a genetic algorithm with an annealing style objective function.
Definition: AnnealingGA.h:15
This class is used to model several receiver functions simultaneously.
void GetData(std::ifstream &instream)
Definition: GAConf.cpp:28
virtual void GetData(const std::string filename)
read in data from file, determines format by ending
Definition: MTStation.cpp:597
CombinedRoughness calculates the roughness of a joint MT- receiver functions model without considerat...
void h(vector< double > &v1, vector< double > &v2, vector< double > &v3, vector< double > &v4)
Definition: perftest.cpp:40
std::vector< double > weights
Definition: IsoJointConf.h:36
A class to read, write and store fundamental mode surface wave dispersion data.
void SetParams(const double mutation, const double crossover)
boost::shared_ptr< PlottableObjective > MTObjective
Definition: cadianiso.cpp:16
virtual ttranscribed GetValues(const tpopmember &member)
Re-Implements the function from BinaryTranscribe.
void SetupAnnealingGA(boost::shared_ptr< GeneralGA > &GA, const double inittemp, const int annealinggeneration, const double coolingratio)
Set the annealing GA temperature parameter, we should only call this function if we are SURE that it ...
Definition: 1dinvga.cpp:190
std::vector< gplib::rvec > tparamvector
We provide some typedefs that are used in other parts as well.
Definition: GeneralGA.h:29
std::vector< double > svelstep
Definition: IsoJointConf.h:34
This is the standard propagation class that generates a new population from the old one...
C1DRecObjective RecObjective(RecData, Configuration.shift, Configuration.omega, Configuration.sigma, Configuration.wlevel, Configuration.slowness)
The class MTStation is used to store the transfer functions and related information for a MT-site...
Definition: MTStation.h:17
ublas::vector< bool > tpopmember
Definition: gentypes.h:22
int annealinggeneration
Definition: GAConf.h:27
SeismicModelDiff calculates the roughness of a joint MT- receiver functions model compared to a seism...
std::vector< std::vector< int > > tparamindv
Definition: GeneralGA.h:32
SurfaceWaveData RFAbsVel
Definition: levjoint.cpp:22
void GetData(std::ifstream &instream)
Definition: SurfInvConf.cpp:30
CMTStation MTData
Definition: cadijoint.cpp:15
void PrintAll(std::ostream &output)
Definition: UniquePop.cpp:36
double coolingratio
Definition: GAConf.h:22
void SetupRecObjective(const string recinfofile, Multi1DRecObjective &RecObjective, const bool normrec, RecCalc::trfmethod rfmethod)
Use the information stored in recinforfile to setup the multi receiver function objective function...
Definition: 1dinvga.cpp:212
std::vector< double > svelbase
Definition: IsoJointConf.h:33
void GetData(std::ifstream &instream)
Definition: MTInvConf.cpp:25
std::vector< int > ressizes
Definition: IsoJointConf.h:32
virtual void ReadAscii(const std::string &filename)
Read a file in general ascii format, i.e lines with period velocity each.
bool elitist
Definition: GAConf.h:28
This class stores a single unique copy of each population member that is added to it...
Definition: UniquePop.h:17
void GetData(std::ifstream &instream)
Definition: RecInvConf.cpp:25
std::string outputbase
Definition: IsoJointConf.h:23
tgatype
Definition: mtanisoga.cpp:34
This class implements the Gray code representation of a binary string and the corresponding transcrip...
std::vector< double > resbase
Definition: IsoJointConf.h:30
std::string dispdata
Definition: SurfInvConf.h:22
double mutationprob
Definition: GAConf.h:24
string version
Definition: makeinput.cpp:16
ublas::vector< double > tfitvec
Definition: gentypes.h:23
std::string recinfofile
Definition: RecInvConf.h:21
Implements a genetic algorithm based on the concept of pareto-optimality, best suited for multi-objec...
Definition: ParetoGA.h:17
This class implements the forward calculation for a 1D isotropic MT model.
int main(int argc, char *argv[])
Definition: 1dinvga.cpp:267
std::string mtinputdata
Definition: MTInvConf.h:28
void ReadFile(const std::string &filename)
Read data from file, depending on the extension.
std::vector< int > svelsizes
Definition: IsoJointConf.h:35
ublas::vector< int > tsizev
Definition: gentypes.h:27
This class stores and writes model for the respktn 1D seismic code that we use for receiver function ...
Definition: ResPkModel.h:18
SeismicDataComp RecData
Definition: cadijoint.cpp:16
void SetParams(const double InitT, const int AnnealG, const double AnnealR)
Set the parameters for the annealing process.
Definition: AnnealingGA.cpp:35
std::vector< int > thicksizes
Definition: IsoJointConf.h:29
boost::shared_ptr< GeneralObjective > pCGeneralObjective
Definition: 1dinvga.cpp:187
The basic exception class for all errors that arise in gplib.