00001 #include <iostream>
00002 #include <numeric>
00003 #include <algorithm>
00004 #include <boost/bind.hpp>
00005 #include <boost/cast.hpp>
00006 #include <gsl/gsl_math.h>
00007 #include "CollapseModel.h"
00008 #include "SeisTools.h"
00009 #include "convert.h"
00010 #include "C1DRecObjective.h"
00011 #include "miscfunc.h"
00012 #include "FatalException.h"
00013
00014 using namespace std;
00015
00016 namespace gplib
00017 {
00018 C1DRecObjective::C1DRecObjective(
00019 boost::shared_ptr<const SeismicDataComp> TheRecData, const int myshift,
00020 const double mysigma, const double myc, const double myslowness,
00021 const RecCalc::trfmethod method, const bool normalized) :
00022 RecCalculator(myshift, mysigma, myc, true, method), ObservedData(
00023 TheRecData)
00024 {
00025 slowness = myslowness;
00026 poisson = sqrt(3.);
00027
00028 SetErrorLevel(0.01);
00029
00030 startpoint = 0;
00031 endpoint = ObservedData->GetData().size();
00032
00033
00034 const double recmaxamp = *max_element(ObservedData->GetData().begin(),
00035 ObservedData->GetData().end());
00036 const bool isone = gsl_fcmp(recmaxamp, 1.0, 1e-4) == 0;
00037 if (isone && !normalized)
00038 throw FatalException(
00039 "Input data has maximum amplitude of 1, but no normalization used");
00040 if (!isone && normalized)
00041 throw FatalException(
00042 "Input data does not have an amplitude of 1, but normalization is used");
00043 RecCalculator.SetNormalize(normalized);
00044 }
00045
00046 C1DRecObjective::~C1DRecObjective()
00047 {
00048 }
00049
00050 C1DRecObjective::C1DRecObjective(const C1DRecObjective &Old) :
00051 PlottableObjective(Old), RecSynthData(Old.RecSynthData), slowness(
00052 Old.slowness), Model(Old.Model), RecCalculator(Old.RecCalculator),
00053 errorlevel(Old.errorlevel), errorvalue(Old.errorvalue), poisson(
00054 Old.poisson), startpoint(Old.startpoint), endpoint(Old.endpoint),
00055 ObservedData(Old.ObservedData)
00056 {
00057 }
00058
00059 void C1DRecObjective::SetTimeWindow(const double start, const double end)
00060 {
00061
00062
00063
00064 startpoint = max(boost::numeric_cast<size_t>(0), boost::numeric_cast<
00065 size_t>((start - ObservedData->GetB()) / ObservedData->GetDt()));
00066
00067 endpoint = min(boost::numeric_cast<size_t>((end - ObservedData->GetB())
00068 / ObservedData->GetDt()), ObservedData->GetData().size());
00069
00070 if (endpoint < startpoint)
00071 throw FatalException("Start index " + stringify(startpoint)
00072 + " and end index " + stringify(endpoint)
00073 + " do not make sense !");
00074 }
00075
00076 C1DRecObjective& C1DRecObjective::operator=(const C1DRecObjective& source)
00077 {
00078 if (this == &source)
00079 return *this;
00080 PlottableObjective::operator=(source);
00081 RecSynthData = source.RecSynthData;
00082 slowness = source.slowness;
00083 Model = source.Model;
00084 RecCalculator = source.RecCalculator;
00085 poisson = source.poisson;
00086 errorlevel = source.errorlevel;
00087 errorvalue = source.errorvalue;
00088 startpoint = source.startpoint;
00089 endpoint = source.endpoint;
00090 ObservedData = source.ObservedData;
00091 return *this;
00092 }
00093
00094 void C1DRecObjective::PreParallel(const ttranscribed &member)
00095 {
00096 const unsigned int nfulllayers = member.size() / 2;
00097
00098 Model.SetSlowness(slowness);
00099 ttranscribed thickness(nfulllayers), velocity(nfulllayers);
00100 copy(member.begin(), member.begin() + nfulllayers, thickness.begin());
00101 copy(member.begin() + nfulllayers, member.begin() + 2 * nfulllayers,
00102 velocity.begin());
00103 CollapseModel(thickness, velocity);
00104 const unsigned int ncolllayers = velocity.size();
00105 Model.Init(ncolllayers);
00106 copy(thickness.begin(), thickness.end(), Model.SetThickness().begin());
00107 copy(velocity.begin(), velocity.end(), Model.SetSVelocity().begin());
00108 transform(velocity.begin(), velocity.end(), Model.SetDensity().begin(),
00109 CalcDensity());
00110 transform(velocity.begin(), velocity.end(),
00111 Model.SetPVelocity().begin(), boost::bind(multiplies<double> (),
00112 _1, poisson));
00113 Model.SetDt(ObservedData->GetDt());
00114 Model.SetNpts(ObservedData->GetData().size());
00115 RecCalculator.SynthPreParallel(GetParallelID(), Model, RecSynthData,
00116 true);
00117 }
00118
00119 double C1DRecObjective::PostParallel(const ttranscribed &member)
00120 {
00121 RecCalculator.SynthPostParallel(GetParallelID(), Model, RecSynthData,
00122 true);
00123 SetMisfit().resize(endpoint - startpoint);
00124 SetSynthData().resize(endpoint - startpoint);
00125 double returnvalue = 0.0;
00126
00127 for (int i = startpoint; i < endpoint; ++i)
00128
00129 {
00130
00131
00132
00133 returnvalue += CalcMisfit(ObservedData->GetData().at(i),
00134 RecSynthData.GetData().at(i), errorvalue, 0.0, i - startpoint);
00135 }
00136
00137 RecSynthData.CopyHeader(*ObservedData.get());
00138 SetRMS(pow(returnvalue / (endpoint - startpoint), 1.0
00139 / GetFitExponent()));
00140 return GetRMS();
00141 }
00142
00143 void C1DRecObjective::SafeParallel(const ttranscribed &member)
00144 {
00145 RecCalculator.SynthSafeParallel(GetParallelID(), Model, RecSynthData,
00146 true);
00147 }
00148 }