package inversionsrechnung_fit_LNVT;

# Everything related to the inversion of the kernel matrix
# version implemented here: fit an LNVT to the data

#require 5.000;
#require Exporter;

use strict;
use warnings;
use vars qw(@ISA);
#use Carp;

use PDL;
use PDL::Core;
use PDL::Math;
use PDL::Primitive;
use PDL::Complex;
#use Proc::Background; # for running background processes (in this case: inversion)
use File::Spec; # for OS-agnostic file and path names
use Wx;

# This is the script doing the inversion
my $inversion_script = File::Spec->rel2abs(File::Spec->catfile(File::Spec->curdir(),'alpha_schaetz_LNVT_Faran_PGV_calc_frontend.pl'));
# Results of the inversion in this file
my $result_file =File::Spec->rel2abs('result.txt');

use attenuation;
use material;

use inversionsrechnung;

use lib qw( Module );
use Helos;
use Faran_lsg_pdl;

@ISA=qw(inversionsrechnung);

my $xm = pdl [0];

my $c_L;

my $h_L;
my $h_T;
my $g;

# Umrechnung Np/m/MHz -> dB/cm/MHz
my $dB = 20/log(10) / 100;

sub new {
  my( $this ) = shift;
  my $class = ref($this) || $this;
  my $newInst={};
  bless($newInst, $class);

  #printf "new inversionsrechnung\n";
  $newInst->Initialize;
  return $newInst;
}

sub Initialize {
  my ($this) = @_;
  #printf "Initialize $this\n";
  $this->{SIGMA_LN_INI}= 0.1;
  $this->inversionsrechnung::Initialize; # call parent
}

sub start_calculation {
  my ($this, $process) = @_;
  # Process is a pointer to a process variable
  #
  # Write material properties to files
  #$this->{fluid_properties}->write_property_file("fluid.txt");
  #$this->{particle_properties}->write_property_file("particle.txt");
  # Write attenuation data to file
  #$this->{attn}->write_alpha("alpha_meas.txt");
  # initiate calculation by calling the relevant script
  #my $proc1 = Proc::Background->new($inversion_script, "-k example_alpha.txt", "-P particle.txt", "-F fluid.txt");
  #Wx::ExecuteCommand($inversion_script . " -k example_alpha.txt -P particle.txt -F fluid.txt",0,);
  #my $fit_process_id =Wx::ExecuteCommand("perl ". $inversion_script . " -k alpha_meas.txt -P particle.txt -F fluid.txt",# -r $result_file",
  my $fit_process_id =Wx::ExecuteCommand("perl ". $inversion_script . " -s 1",# -r $result_file",
  #my $fit_process_id =Wx::ExecuteCommand("ls -la",
                     0,  # asynchronous execution
                     $process);
  $this->{attn}->output_alpha($process);
  $this->{fluid_properties}->output_property_data($process,"fluid");
  $this->{particle_properties}->output_property_data($process, "particle");
  $this->output_initial_data($process);
  $process->CloseOutput();
  return($fit_process_id);
}

# Get the results from the output of the inversion script
# stored in results.txt

sub read_results {
  my ($this) = @_;
  my $ret_val=0;
  open (FILE,"$result_file") or return(0);
  # Read lines, until we reach EOF.
  my $linebuf="";
  while (!eof(FILE) && ($linebuf=<FILE>) ){
    chomp($linebuf);
  }
  # Take the last line before eof, and extract the values of x50, sigma_ln and phi
  unless ( ($linebuf =~ "x50 ") && ($linebuf =~ ", sigma_ln ") && ($linebuf =~ ", phi ")) {
    #$this->{status_display}->AppendText("Could not determine result.\n");
    return($ret_val);
  }
  my @fields = split(", ", $linebuf);
  my @x50_fields = split(" ",$fields[0]);
  my @sigmaln_fields = split(" ",$fields[1]);
  my @phi_fields= split(" ",$fields[2]);
  $this->x50($x50_fields[1]);
  $this->sigma_ln($sigmaln_fields[1]);
  $this->c($phi_fields[1]);
  $ret_val=1;
  return($ret_val);
}

sub sigma_ln_ini {
  my $this = shift;
  if (@_) { $this->{SIGMA_LN_INI} = shift }
  return $this->{SIGMA_LN_INI};
}

sub output_initial_data {
  my ($this, $process) = @_;
  my $a =$process->GetOutputStream;
  # Header
  print $a "Begin of initial data\n";
  # Data
  my $x50=$this->{X_50_INI}/1e6;
  print $a "x_50 $x50\n";
  print $a "sigma_ln $this->{SIGMA_LN_INI}\n";
  my $phi =$this->{PHI_INI}/100;
  print $a "phi $phi\n";
  # "Footer"
  print $a "End of initial data\n";
  return 1;
}

1;
