/***************************************************************************
**
**  This file is part of gpgridsearch.
**
**  gpgridsearch is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  gpgridsearch is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2016-04-25
**  Copyright: 2016-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "ModelWorker.h"
#include "Reader.h"

/*!
  \class ModelWorker ModelWorker.h
  \brief Brief description of class still missing

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
ModelWorker::ModelWorker(const Reader * p, const GridGenerator * gg)
  : _groundModel(p->groundModel()),
    _targets(p->targets()),
    _mainGenerator(gg)
{
  TRACE;
  _parameters=p;
  _groundModel.initFinalProfiles();
  _groundModel.toParameters(_parameterSpace);
  _parameterSpace.setVariableParameters();
  _vp=_groundModel.find("Vp");
  _vs=_groundModel.find("Vs" );
  _rho=_groundModel.find("Rho");
  _nu=_groundModel.find("Nu");
  _poissonCondition=new PoissonCondition(_vp, _vs, _nu);
  _parameterSpace.addCondition(_poissonCondition);
}

/*!
  Description of destructor still missing
*/
ModelWorker::~ModelWorker()
{
  TRACE;
}

void ModelWorker::run(int index)
{
  TRACE;
  GridGenerator * gg=_mainGenerator->subset(index);
  do {
    gg->model(_parameterSpace);
    if(_parameterSpace.isOk()) {
      // Parameter set now ready for transformation into layered model
      _groundModel.updateFinalProfiles();
      _poissonCondition->setVp();
      Seismic1DModel * m =DCReportBlock::surfaceWaveModel(_vp->resampledProfile().depths(),
                                                          _vp->resampledProfile().values(),
                                                          _vs->resampledProfile().values(),
                                                          _rho->resampledProfile().values());
      double totalMisfit=0.0;
      double totalWeight=0.0;
      bool ok=true;
      _targets.surfaceMisfit(totalMisfit, totalWeight, m, 0.0, ok);
      if(ok && totalWeight>0.0) {
        double misfit=totalMisfit/totalWeight;
        ReportWriter * r=_parameters->beginWriteReport();
        r->addModel(misfit, 0, 0, 0);
        Profile vp=m->vpProfile();
        Profile vs=m->vsProfile();
        Profile rho=m->rhoProfile();
        DCReportBlock::write(r, _targets, &vp, &vs, &rho);
        _parameters->endWriteReport();
      }
      delete m;
    }
  } while (gg->next());
  delete gg;
}
