unit utractorcito_gui;


interface

uses
  Classes,
  process,
  ufechas,
  SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls, ExtCtrls,
  AutoEsca,
  wrffti01, wrfftf01,
  uInterpreteDeParametros, uConstantesSimSEE, uglobs,
  xmatdefs, matreal,
  usalasdejuego, uInicioYFinal,
  uestados,
  uhiperplanos,
  uplot, uauxiliares,
  Math,
  uAdministradorDeEstadosMultiPlano,
  uadministradordeestadoscerebro,
  ulearningcfcerebros,
  utrayectorias_xcdpcf,
  useriestemporales,
  uparsimoniat,
  utractorcito_rch;

type

  { TfTractorcitoGUI }

  TfTractorcitoGUI = class(TForm)
    btCargarTodosLosCFs: TButton;
    btGenArchiEstrellasIni: TButton;
    btGenCF: TButton;
    btGenerarSemillas: TButton;
    btPlotRangoCFs: TButton;
    btPlotRangoTrys: TButton;
    btSelArchiCF: TButton;
    btSelArchiEstrellasIni: TButton;
    btSelArchiSemillas: TButton;
    btSelSala: TButton;
    btOptSim: TButton;
    btContarTrys: TButton;
    Button1: TButton;
    btSerializar: TButton;
    Button2: TButton;
    Button3: TButton;
    btGenRN: TButton;
    Button4: TButton;
    Button5: TButton;
    cbParsimonia: TCheckBox;
    ColorDialog1: TColorDialog;
    eArchiCF: TEdit;
    eArchiEstrellasIni: TEdit;
    eArchiSala: TEdit;
    eArchiSemillas: TEdit;
    eArrayNeuronasPorCapasIntermedias: TEdit;
    eEstructura: TEdit;
    eParsimonia_nArmonicos: TEdit;
    eParsimonia_nPotencias: TEdit;
    eNArmonicos: TEdit;
    eIter1: TEdit;
    eIter2: TEdit;
    eIter1trys: TEdit;
    eIter2trys: TEdit;
    e_dtFin: TEdit;
    e_dtIni: TEdit;
    e_kCronica1: TEdit;
    e_kCronica2: TEdit;
    e_nEstrellas: TEdit;
    e_nHiperplanos: TEdit;
    e_RadioEstrellitas: TEdit;
    e_SemillaMadre_Cronicas: TEdit;
    e_SemillaMadre_Estrellitas: TEdit;
    gbCF: TGroupBox;
    gbControles: TGroupBox;
    gbEstrellitas: TGroupBox;
    gbPolitica: TGroupBox;
    gbSala: TGroupBox;
    gbSemillas: TGroupBox;
    GroupBox1: TGroupBox;
    Image1: TImage;
    Label1: TLabel;
    Label2: TLabel;
    lblNPotencias: TLabel;
    lbl_arrayNeuronasPorCapasIntermedias: TLabel;
    PaintBox1: TImage;
    lblNArmonicos: TLabel;
    lblIter1: TLabel;
    lblArchiCF: TLabel;
    lblArchiEstrellasIni: TLabel;
    lblIter2: TLabel;
    lblIter1trys: TLabel;
    lblIter2trys: TLabel;
    lblSala: TLabel;
    lblSemillas: TLabel;
    lbl_dtIni: TLabel;
    lbl_kCronica1: TLabel;
    lbl_kCronica2: TLabel;
    lbl_NEstrellas: TLabel;
    lbl_NHiperplanos: TLabel;
    lbl_Radio: TLabel;
    lbl_SemillaMadre_Cronicas: TLabel;
    lbl_SemillaMadre_Estrellitas: TLabel;
    lgl_dtFin: TLabel;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    PageControl: TPageControl;
    PaintBox2: TPaintBox;
    Panel1: TPanel;
    Panel2: TPanel;
    panel_botonera_trys: TPanel;
    rbOpt: TRadioButton;
    rbSim: TRadioButton;
    TabSheet1: TTabSheet;
    tsCFs: TTabSheet;
    tsTrayectorias: TTabSheet;
    tsConfig: TTabSheet;
    tsSimular: TTabSheet;
    procedure btContarTrysClick(Sender: TObject);
    procedure btGenArchiEstrellasIniClick(Sender: TObject);
    procedure btGenCFClick(Sender: TObject);
    procedure btGenerarSemillasClick(Sender: TObject);
    procedure btGenRNClick(Sender: TObject);
    procedure btPlotRangoCFsClick(Sender: TObject);
    procedure btPlotRangoTrysClick(Sender: TObject);
    procedure btSelArchiCFClick(Sender: TObject);
    procedure btSelArchiEstrellasIniClick(Sender: TObject);
    procedure btSelArchiSemillasClick(Sender: TObject);
    procedure btSelSalaClick(Sender: TObject);
    procedure btSerializarClick(Sender: TObject);
    procedure btOptSimClick(Sender: TObject);
    procedure btCargarTodosLosCFsClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  private

  public
    carpetaSala: string;
    TodosLosCfs: array of TAdminEstados;
    Escalas_min, Escalas_max: TDAOfNReal;

    procedure PlotIter(aCF: TAdminEstadosMultiPlano; aColor: TColor;
      pen_width: integer);

    procedure PlotAproFourier(kCanal: integer; nCanales: integer;
      jArmonico: TDAOfNReal; A0: NReal; A_, B_: TDAOfNReal; nPasosTm1: integer;
      aColor: TColor; pen_width: integer; aCF: TAdminEstadosMultiPlano);


    procedure ActualizarEscalas(kEscala: integer; nuevoValor: NReal);

  end;

var
  fTractorcitoGUI: TfTractorcitoGUI;

implementation

{$R *.lfm}

{ TfTractorcitoGUI }

procedure TfTractorcitoGUI.btSelSalaClick(Sender: TObject);
var
  sala: TSalaDeJuego;

begin
  OpenDialog1.Filter := 'Sala SimSEE|*.ese';
  if OpenDialog1.Execute then
  begin
    eArchiSala.Text := OpenDialog1.FileName;
    uInicioYFinal.AlInicio;
    sala := usalasdejuego.cargarSala(0, eArchiSala.Text, '', True);
    e_dtIni.Text := sala.globs.fechaIniSim.AsStr;
    e_dtFin.Text := sala.globs.fechaFinSim.AsStr;
    carpetaSala := sala.dirSala;
    sala.Free;
    uInicioYFinal.AlFinal;
  end;
end;


procedure Write_FFTSeries(seriesDeDatos: TSeriesDeDatos; aCF: TAdminEstadosMultiPlano);
var
  sal: textfile;
  kSerie, kPunto: integer;
  coA, coB: TDAOfNreal;
  A0: NReal;
  fft_base: TWRFFT_base;
  dT: NReal;
  ro2acum: NReal;

  alfa, beta: TDAOfNReal;
  jArmonico: TDAOfNReal;
  kArmonico: TDAOfNInt;

  A_, B_: TDAOfNReal;
  nArmonicos: integer;
  k: integer;
  aColor: TColor;

begin
  fft_base := TWRFFT_base.Create(seriesDeDatos.NPuntos);
  dT := seriesDeDatos.NPuntos * seriesDeDatos.dtEntreMuestras;

  nArmonicos := StrToInt(fTractorcitoGUI.eNArmonicos.Text);
  if fTractorcitoGUI.ColorDialog1.Execute then
    aColor := fTractorcitoGUI.ColorDialog1.Color
  else
    aColor := clYellow;

  setlength(jArmonico, nArmonicos);
  setlength(alfa, nArmonicos);
  setlength(beta, nArmonicos);
  setlength(kArmonico, nArmonicos);
  setlength(A_, nArmonicos);
  setlength(B_, nArmonicos);

  for k := 0 to nArmonicos - 1 do
  begin
    // jArmonico / dT = frecuencia en 1/días
    // jArmonicoAnual = dT / 365.2425
    // kArmonicoAnual = jArmonico - 1 ; porque los coeficientes están indexados desde CERO.
    jArmonico[k] := (k + 1) * dT / 365.2425;
    kArmonico[k] := trunc(jArmonico[k] - 1);
    beta[k] := frac(jArmonico[k]);
    alfa[k] := 1 - beta[k];
  end;

  setlength(coA, fft_base.NBarrasLaterales);
  setlength(coB, fft_base.NBarrasLaterales);
  for kSerie := 1 to seriesDeDatos.NSeries do
  begin
    //   seriesDeDatos.series[kserie-1].aplicar_hanning;

    WRFFTF01.FFTF(fft_base, seriesDeDatos.Series[kSerie - 1].pv[1], A0, coA[0], coB[0]);
    assignfile(sal, 'FFT_serie_' + IntToStr(kSerie) + '.xlt');
    rewrite(sal);
    writeln(sal, 'A0: ', A0);
    writeln(sal, '1/f [días]', #9, 'f [1/días]', #9, 'ro2Acum');
    ro2acum := sqr(a0) / 2.0;
    for kPunto := 0 to high(coA) do
    begin
      ro2acum := ro2acum + sqr(coA[kPunto]) + sqr(coB[kPunto]);
      writeln(sal, dT / (kPunto + 1), #9, (kPunto + 1) / dT, #9, ro2acum);
    end;
    closefile(sal);

    for k := 0 to nArmonicos - 1 do
    begin
      A_[k] := coA[kArmonico[k]] * alfa[k] + coA[kArmonico[k] + 1] * beta[k];
      B_[k] := coB[kArmonico[k]] * alfa[k] + coB[kArmonico[k] + 1] * beta[k];
    end;
    fTractorcitoGUI.PlotAproFourier(kSerie - 1, seriesDeDatos.NSeries,
      jArmonico, A0, A_, B_, seriesDeDatos.NPuntos, aColor, 4, aCF);

  end;
  fft_base.Free;
  setlength(coA, 0);
  setlength(coB, 0);
end;



procedure Write_FFTSeries_AnualMovil(seriesDeDatos: TSeriesDeDatos; nAnios: double);
var
  sal: textfile;
  kSerie, kPunto: integer;
  coA, coB: TDAOfNreal;
  A0: NReal;
  fft_base: TWRFFT_base;
  dT: NReal;
  kVentana, kVentanaHasta, AnchoVentana: integer;
  v: TVectR;
  aSerie: TVectR;
  kArmonicoAnual: integer;
  alfa: NReal; // peso de kArmonicoAnual
  beta: NReal; // peso de kArmonicoANual+1 ; alfa + beta = 1
  a, b, ro, fase: NReal;
begin
  dT := nAnios * 365.2425; // Ancho de la ventana en días

  // Cantidad de muestras de la ventana
  AnchoVentana := trunc(dT / seriesDeDatos.dtEntreMuestras);

  // jArmonico / dT = frecuencia en 1/días
  // jArmonicoAnual = dT / 365.2425
  // kArmonicoAnual = jArmonico - 1 ; porque los coeficientes están indexados desde CERO.
  alfa := nAnios / AnchoVentana;
  kArmonicoAnual := trunc(alfa - 1);
  beta := frac(alfa);
  alfa := 1 - beta;


  fft_base := TWRFFT_base.Create(AnchoVentana);
  dT := AnchoVentana * seriesDeDatos.dtEntreMuestras;
  v := TVectR.Create_Init(AnchoVentana);

  // k del dato de la última ventana entera.
  kVentanaHasta := seriesDeDatos.NPuntos - AnchoVentana + 1;

  setlength(coA, fft_base.NBarrasLaterales);
  setlength(coB, fft_base.NBarrasLaterales);
  for kSerie := 1 to seriesDeDatos.NSeries do
  begin
    assignfile(sal, 'FFT_A0A1B1_anualMovil' + IntToStr(kSerie) + '.xlt');
    rewrite(sal);
    aSerie := seriesDeDatos.series[kserie - 1];
    writeln(sal, 'kVentana', #9, 'dtInicio', #9, 'A0', #9, 'ro', #9, 'fase');
    for kVentana := 1 to kVentanaHasta do
    begin
      v.CopyFromTo(kVentana, kVentana + AnchoVentana - 1, 1, aSerie);
      v.aplicar_hanning;
      WRFFTF01.FFTF(fft_base, v.pv[1], A0, coA[0], coB[0]);

      a := coA[kArmonicoAnual] * alfa + coA[kArmonicoAnual + 1] * beta;
      b := coB[kArmonicoAnual] * alfa + coB[kArmonicoAnual + 1] * beta;
      ro := sqrt(sqr(a) + sqr(b));
      fase := arctan(b / a);
      writeln(sal, kVentana, #9, seriesDeDatos.dtMuestra(kVentana), #9, A0, #9,
        ro, #9, fase);
    end;
    closefile(sal);
  end;
  fft_base.Free;
  setlength(coA, 0);
  setlength(coB, 0);
end;


procedure TfTractorcitoGUI.btSerializarClick(Sender: TObject);
var
  aCF: TAdminEstadosMultiPlano;
  aCHP: TConjuntoDeHiperplanos;
  aHP: THiperPlano;
  sts: TSeriesDeDatos;
  kPasoT: integer;
  j: integer;
  kIter: integer;
  kParam: integer;

begin
  kIter := high(TodosLosCfs);
  aCF := TodosLosCfs[kIter] as TAdminEstadosMultiPlano;
  aCHP := aCF.conjuntosDeHiperPlanos[1];
  aHP := aCHP.hiperPlanos[0];

  sts := TSeriesDeDatos.CreateVacia(aCF.fechaIni.dt, aCF.horasDelPaso, aCF.nPuntosT - 1);
  for kParam := 0 to high(aHP.a) do
    sts.AddSerie('dCF/dX_' + IntToStr(kParam));
  sts.AddSerie('C0');

  for kPasoT := 1 to aCF.nPuntosT - 1 do
  begin
    aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
    aHP := aCHP.hiperPlanos[0];
    for j := 0 to high(aHP.A) do
      sts.GetSerie(j).pon_e(kPasoT, aHP.A[j]);
    j := high(aHP.A) + 1;
    sts.GetSerie(j).pon_e(kPasoT, aHP.C0);
  end;
  sts.WriteToArchi('series_iter_' + IntToStr(kIter) + '.sas');
  Write_FFTSeries(sts, aCF);
  aCF.WriteToArchi('CFAproFourier' + eNArmonicos.Text + 'kIter' +
    IntToStr(kIter) + '.xlt');

  Write_FFTSeries_AnualMovil(sts, 5);
  sts.Free;
end;

procedure TfTractorcitoGUI.btOptSimClick(Sender: TObject);
var
  params: TInterpreteParametros;
begin
  params := TInterpreteParametros.Create(False);
  params.addor('sala', eArchiSala.Text);
  params.addor('CF', eArchiCF.Text);


  params.addor('dtIni', e_dtIni.Text );
  params.addor('dtFin', e_dtFin.Text );

  params.addor('estrellas', eArchiEstrellasIni.Text);
  params.addor('archisemillas', eArchiSemillas.Text);
  params.addor('trayectorias', 'trayectorias.bin');

  params.addor('semilla', e_SemillaMadre_Cronicas.Text);
  params.addor('nCronicas', IntToStr(StrToInt(e_kCronica2.Text) -
    StrToInt(e_kCronica1.Text)));
  {$IFDEF DEBUG}
  params.addor('nHilos', '0');
  {$ELSE}
  params.addor('nHilos', '-1');
  {$ENDIF}

  if rbOpt.Checked then
    params.addor('xo', 'opt')
  else
    params.addor('xo', 'sim');

  if cbParsimonia.Checked then
    params.addor( 'parsimonia', '1' )
  else
    params.addor( 'parsimonia', '0' );

  params.addor( 'npots', eParsimonia_nPotencias.text );
  params.addor( 'narms', eParsimonia_nArmonicos.text );

  xo_sim(params);
  params.Free;
end;

procedure TfTractorcitoGUI.btCargarTodosLosCFsClick(Sender: TObject);
var
  cnt: integer;
  k: integer;
begin
  cnt := ultimo_CFsYTrys(CarpetaSala);
  if cnt >= 0 then
  begin
    if TodosLosCfs <> nil then
    begin
      for k := 0 to high(TodosLosCfs) do
        TodosLosCfs[k].Free;
    end;
    setlength(TodosLosCfs, cnt + 1);
    for k := 0 to high(TodosLosCfs) do
    begin
      writeln('Cargando CF_', k);
      TodosLosCfs[k] := TAdminEstados.CreateReadFromArchi(
        archi_CF_of_iter(CarpetaSala, k));
    end;
  end;
  eIter1.Text := '0';
  eIter2.Text := IntToStr(cnt);
  writeln('Se cargaron un total de ', (cnt + 1), ' CFs.');
end;

procedure TfTractorcitoGUI.Button1Click(Sender: TObject);
var
  params: TInterpreteParametros;
  s: string;
begin
  params := TInterpreteParametros.Create(False);
  params.addor('sala', eArchiSala.Text);
  params.addor('CF', eArchiCF.Text);
  params.addor('dtIni', e_dtIni.Text);
  params.addor('dtFin', e_dtFin.Text);

  params.addor('estrellas', eArchiEstrellasIni.Text);
  params.addor('archisemillas', eArchiSemillas.Text);
  params.addor('trayectorias', 'trayectorias.bin');

  params.addor('semilla', '31');
  params.addor('nCronicas', '100');
  params.addor('nHilos', '-1');
  params.addor('xo', 'opt');

  s := uConstantesSimSEE.getDir_Bin;
  {$IFDEF WINDOWS}
  s := s + 'tractorcito';
  {$ELSE}
  s := s + 'tractorcito';
  {$ENDIF}
  s := s + params.getcmdline_str;
  Memo1.Lines.Text := s;
  params.Free;

end;

procedure TfTractorcitoGUI.Button2Click(Sender: TObject);
var
  prc: TProcess;
  script: TStringList;
  i, j: integer;
  x, y, z, r: double;
  tmpfile: string;
  pngfile: string;
  CF: TAdminEstados;
  archiCF: string;

  NX, NY: integer;
  XMIN, XMAX, YMIN, YMAX: NReal;

begin

  if not OpenDialog1.Execute then
    exit;
  archiCF := OpenDialog1.FileName;

  uInicioYFinal.AlInicio;

  CF := TAdminEstados.CreateReadFromArchi(archiCF);

  uInicioYFinal.AlFinal;

  NX := 100;
  NY := 100;
  XMIN := CF.xr_def[0].x[0];
  XMAX := CF.xr_def[0].x[high(CF.xr_def[0].x)];
  YMIN := CF.xr_def[1].x[0];
  YMAX := CF.xr_def[0].x[high(CF.xr_def[0].x)];

  pngfile := ExtractFileName(ChangeFileExt(GetTempFilename('.', 'IMG'), '.png'));

  prc := TProcess.Create(nil);
  try
    script := TStringList.Create;
    try
      // Prepare gnuplot to write to a png file
      script.Add(Format('set terminal png size %d, %d', [Image1.Width, Image1.Height]));
      script.Add(Format('set output "%s"', [pngfile]));

      // Chart title
      script.Add('set title "Costo Futuro Opt-Clásica"');

      // Plot command
      script.Add('splot "-" using 1:2:3 with points \');

      // create some data; append them to script (by using 'file name' parameter "-")
      DefaultFormatSettings.DecimalSeparator := '.';
      for i := 0 to NX - 1 do
      begin
        x := XMIN + (XMAX - XMIN) * i / (NX - 1);
        CF.xr[0] := x;
        for j := 0 to NY - 1 do
        begin
          y := YMIN + (YMAX - YMIN) * j / (NY - 1);
          CF.xr[1] := y;
          z := CF.costoContinuo(52);
          script.Add(Format('%f %f %f', [x, y, z]));
        end;
      end;
      script.Add('end');    // this closes the data section

      tmpfile := GetTempFileName('.', 'TEMP');
      script.SaveToFile(tmpfile);
    finally
      script.Free;
    end;

    // run gnuplot and execute the script
    {$IFDEF WINDOWS}
    prc.Executable := 'd:\programme\gnuplot\bin\gnuplot.exe';
    {$ELSE}
    prc.Executable := '/usr/bin/gnuplot';
    {$ENDIF}
    prc.Parameters.Add(tmpfile);
    prc.Options := prc.Options + [poWaitOnExit];
    prc.Execute;

    // load image created by the script into the TImage component
    Image1.Picture.LoadfromFile(pngfile);


  finally
    CF.Free;
    prc.Free;
    DeleteFile(pngFile);
    DeleteFile(tmpFile);
  end;
end;

procedure TfTractorcitoGUI.Button3Click(Sender: TObject);
var
  k, i, j: integer;
  x, y, z, r: double;
  CF: TAdminEstados;
  archiCF: string;

  NX, NY: integer;
  XMIN, XMAX, YMIN, YMAX, ZMin, ZMax, dz: NReal;

  graficas: TGraficas;
  aCanal1, aCanal2: TCanalGrafico;
  aSerie1, aSerie2: TSerieXY;

  vx, vy: TVectR;
  vm, grad_x, grad_y: TMatR;

  rescod: integer;
  dcdx_inc, dcdx_dec, xrpos: NReal;

  niveles: TDAOfNReal;
  ce: NReal;

  dxGrid: NReal;
  ndivs: integer;

  xp, yp: integer;
  ra: NReal;

begin

  if not OpenDialog1.Execute then
    exit;
  archiCF := OpenDialog1.FileName;

  uInicioYFinal.AlInicio;

  CF := TAdminEstados.CreateReadFromArchi(archiCF);

  uInicioYFinal.AlFinal;

  graficas := TGraficas.Create;
  graficas.subplot(Image1.Canvas, Image1.Width, Image1.Height, 1,
    2, nil, nil, false );
  aCanal1 := graficas.getCanal(0, 0);
  aCanal2 := graficas.getCanal(0, 1);

  aCanal1.CajaSeries;
  aCanal2.CajaSeries;

  aSerie1 := aCanal1.AddSerieXY('CF1_VBon');
  aSerie2 := aCanal2.AddSerieXY('CF2_VBon_H_CF');


  XMIN := CF.xr_def[0].x[0];
  XMAX := CF.xr_def[0].x[high(CF.xr_def[0].x)];
  YMIN := CF.xr_def[1].x[0];
  YMAX := CF.xr_def[1].x[high(CF.xr_def[1].x)];

  aSerie2.SetEscalaX(xmin, xmax);
  aSerie2.SetEscalaY(ymin, ymax);


  NX := 100;
  NY := 10;

  aCanal1.xlabel(CF.xr_def[0].nombre);
  aCanal1.ylabel('Valor del agua.');

  //  aCanal2.Title('Costo Futuro');
  aCanal2.xlabel(CF.xr_def[0].nombre);
  aCanal2.ylabel(CF.xr_def[1].nombre);


  ndivs := 8;
  Escala125N(xmin, xmax, dxGrid, ndivs, 1);

  aCanal2.EjeX(xmin, xmax, ndivs, '[Hm3]', '%8.0f', True, False, 0);

  aCanal2.EjeY(ymin, ymax, 8, '[gn]', '%2.2f', True, False, 0);


  aSerie1.pen_color := clBlue;
  aSerie1.activar;

  aSerie1.SetEscalaX(xmin, xmax);
  aCanal1.EjeX(xmin, xmax, ndivs, '[Hm3]', '%8.0f', True, True, 0);


  vx := TVectR.Create_Init(nx);
  vy := TVectR.Create_Init(ny);
  vm := TMatR.Create_Init(nx, ny);

  ZMin := 1e100;
  ZMax := -ZMin;

  for i := 0 to NX - 1 do
  begin
    x := XMIN + (XMAX - XMIN) * i / (NX - 1);
    CF.xr[0] := x;
    vx.pon_e(i + 1, x);

    ce := (1000.0 * 9.8 * (CF.xr_def[0].xToy(x) - 7.05) * 0.86 / 3600.0);

    for j := 0 to NY - 1 do
    begin
      y := YMIN + (YMAX - YMIN) * j / (NY - 1);
      CF.xr[1] := y;
      vy.pon_e(j + 1, y);
      CF.devxr_continuo(0, 52, dCdx_inc, dcdx_dec, rescod, xrpos);
      z := -(dcdx_inc + dcdx_dec) / 2;
      if z < zmin then
        zmin := z;
      if z > zmax then
        zmax := z;
      vm.pon_e(i + 1, j + 1, z);
    end;
  end;

  ndivs := 8;
  Escala125N(zmin, zmax, dxGrid, ndivs, 1);
  aSerie1.SetEscalaY(zmin, zmax);
  aCanal1.EjeY(zmin, zmax, ndivs, 'USD/Hm3', '%12.0f', True, True, 0);

  //  aCanal1.Title( 'Valor del agua' );
  //  aCanal1.EjeY2(0, 1, 10, '[n]', '%2.2f', true, 2 );
  //  aCanal1.ylabel2('coquito' );

  aCanal1.CajaSeries;


  for j := 0 to NY - 1 do
  begin
    for i := 0 to NX - 1 do
    begin
      x := vx.e(i + 1);
      z := vm.e(i + 1, j + 1);
      if (i = 0) then
      begin
        aSerie1.pen_color := aCanal1.NextColor;
        aSerie1.activar;
        aSerie1.go(x, z);
      end
      else
        aSerie1.lineTo(x, z);
    end;
  end;

  aCanal1.TitulosYGrillas;

  vx.Free;
  vy.Free;
  vm.Free;


  ZMin := 1e100;
  ZMax := -ZMin;

  for i := aCanal2.xp1 to aCanal2.xp1 + aCanal2.dxp do
  begin
    for j := aCanal2.yp1 to aCanal2.yp1 + aCanal2.dyp do
    begin
      x := aSerie2.xOf(i);
      y := aSerie2.yOf(j);
      CF.xr[0] := x;
      CF.xr[1] := y;
      CF.ActualizarEstadoGlobal(52);
      z := CF.costoContinuo(52);
      if z < Zmin then
        ZMin := z;
      if z > Zmax then
        Zmax := z;
    end;
  end;

  dz:=  Zmax - Zmin;
  if dz < 1e-10 then
    dz:= 1.0;

  aCanal2.CajaSeries;

  for i := aCanal2.xp1 to aCanal2.xp1 + aCanal2.dxp do
  begin
    for j := aCanal2.yp1 to aCanal2.yp1 + aCanal2.dyp do
    begin
      x := aSerie2.xOf(i);
      y := aSerie2.yOf(j);
      CF.xr[0] := x;
      CF.xr[1] := y;
      CF.ActualizarEstadoGlobal(52);
      z := CF.costoContinuo(52);

      (*
      CF.devxr_continuo( 1, 52, dCdx_inc, dcdx_dec, rescod, xrpos );
      if rescod > 0 then
        z:= dcdx_inc
      else if rescod < 0 then
        z:= dcdx_dec
      else
        z:= ( dcdx_inc + dcdx_dec ) / 2;
//      writeln( i, ', ', j, ', ', x, ', ', y, ', ', (z - zmin) / (zmax-zmin) );
      *)
      graficas.canvas.Pixels[i, j] :=
        ColorGradienteAzulRojo((z - zmin) /dz);
    end;
  end;

  vx := TVectR.Create_init(100);
  vy := TVectR.Create_init(100);
  vm := TMatR.Create_init(100, 100);
  for k := 1 to vx.n do
    vx.pon_e(k, aSerie2.escalaX.r1 + (k - 1) * aSerie2.escalaX.dr / (vx.n - 1));
  for j := 1 to vy.n do
    vy.pon_e(j, aSerie2.escalaY.r1 + (j - 1) * aSerie2.escalaY.dr / (vy.n - 1));

  for k := 1 to vx.n do
  begin
    CF.xr[0] := vx.e(k);
    for j := 1 to vy.n do
    begin
      CF.xr[1] := vy.e(j);
      vm.pon_e(k, j, CF.costoContinuo(52));
    end;
  end;

  setlength(niveles, 10);
  for k := 0 to high(niveles) do
    niveles[k] := zmin + k * (zmax - zmin) / high(niveles);

  PlotCurvasIsoNivel(aSerie2, vm, vx, vy, niveles, False);


  grad_x := TMatR.Create_init(9, 9);
  grad_y := TMatR.Create_init(9, 9);
  for i := 1 to grad_x.nf do
  begin
    y := aSerie2.yOf(round(aCanal2.yp1 + i * aCanal2.dyp / (grad_y.nf + 1)));
    for j := 1 to grad_x.nc do
    begin
      x := aSerie2.xOf(round(aCanal2.xp1 + j * aCanal2.dxp / (grad_x.nc + 1)));
      CF.xr[0] := x;
      CF.xr[1] := y;
      CF.devxr_continuo(0, 52, dCdx_inc, dcdx_dec, rescod, xrpos);
      z := -(dcdx_inc + dcdx_dec) / 2;
      grad_x.pon_e(i, j, z);
      CF.devxr_continuo(1, 52, dCdx_inc, dcdx_dec, rescod, xrpos);
      z := -(dcdx_inc + dcdx_dec) / 2;
      grad_y.pon_e(i, j, z);
    end;
  end;

  // buscamos el gradiente de mayor módulo para escalar
  r := 0;
  for i := 1 to grad_x.nf do
  begin
    for j := 1 to grad_x.nc do
    begin
      ra := sqrt(sqr(grad_x.e(i, j)) + sqr(grad_y.e(i, j)));
      if ra > r then
        r := ra;
    end;
  end;

  grad_x.PorReal(1 / (aCanal2.xmax - aCanal2.xmin));
  grad_y.PorReal(1 / (aCanal2.ymax - aCanal2.ymin));

  grad_x.MinMax(zmin, zmax);
  z := max(abs(zmin), abs(zmax));

  grad_y.MinMax(zmin, zmax);
  z := max(z, max(abs(zmin), abs(zmax)));

  grad_y.PorReal(1 / z);

  for i := 1 to grad_x.nf do
  begin
    y := aSerie2.yOf(round(aCanal2.yp1 + i * aCanal2.dyp / (grad_y.nf + 1)));
    for j := 1 to grad_x.nc do
    begin
      x := aSerie2.xOf(round(aCanal2.xp1 + j * aCanal2.dxp / (grad_x.nc + 1)));
      aSerie2.flecha(x, y, grad_x.e(i, j), grad_y.e(i, j), clYellow, 0.05);
    end;
  end;

  grad_x.Free;
  grad_y.Free;

  aCanal2.TitulosYGrillas;
  CF.Free;
end;

procedure TfTractorcitoGUI.Button4Click(Sender: TObject);
var
  archiCF, architrys: string;
  CF: TAdminEstados;
  trayectorias: TTrayectorias;
  kPaso: integer;
  aTrayectoria: TTrayectoria;
  puntosTrayectoria: TPuntosTrayectoria;
  aPuntoTrayectoria: TPuntoTrayectoria;
  aproxCF: TVectR;
  idx: TDAOfNInt;
  k: integer;
  e2: NReal;
  parsimonia: TParsimonia;

  eMaxAbs: NReal;
begin
  if not OpenDialog1.Execute then
    exit;
  archiCF := OpenDialog1.FileName;

  if not OpenDialog1.Execute then
    exit;
  archiTrys := OpenDialog1.FileName;

  uInicioYFinal.AlInicio;
  CF := TAdminEstados.CreateReadFromArchi(archiCF);
  trayectorias := TTrayectorias.CreateFromArchi(architrys);
  uInicioYFinal.AlFinal;

  parsimonia:= TParsimonia.Create( 365.2425/7.0, 365.2425, 1, 1 , (CF as TAdminEstadosCerebro).Cerebros[1].DimParametros );
  eMaxAbs := AjusteCFCerebro(CF as TAdminEstadosCerebro, Trayectorias, parsimonia, 0.7);
  parsimonia.Free;


  CF.WriteToArchi('calibrado.xlt');

  (*

    // fijamos un paso de tiempo de exploración
    kPaso := 50;
    puntosTrayectorias:= trayectorias.GetPuntosOfkPaso( kPaso-1 );
    aproxCF:= TVectR.Create_Init(  length( puntosTrayectoria ) );
    for k:= 0 to high( puntosTrayectoria ) do
    begin
      aPuntoTrayectoria:= puntosTrayectoria[k];
      for j:= 1 to aPuntoTrayectoria.X.Xr.n do
        CF.xr[j-1]:= aPuntoTrayectoria.X.Xr.e( j );
      for j:= 1 to aPuntoTrayectoria.X.xd.n do
        CF.xd[j-1]:= aPuntoTrayectoria.X.Xd.e( j );
      CF.ActualizarEstadoGlobal( 50 );
      aproxCF.pon_e(k+1, CF.costoContinuo( kPaso ) );
      idx[ k+1 ]:= k+1;
    end;




    setlength( aproxCF, 0 );
    setlength( puntosTrayectorias, 0 );

      *)

  CF.Free;
  Trayectorias.Free;
end;

procedure TfTractorcitoGUI.Button5Click(Sender: TObject);
var
  params: TInterpreteParametros;
  aNeuronasPorCapasIntermedias: TCaption;
begin

   if eArchiSala.Text = '' then
  begin
    ShowMessage('Debe seleccionar una sala primero!');
    exit;
  end;

  if not FileExists(eArchiSala.Text) then
  begin
    ShowMessage('El archivo de Sala: ' + eArchiSala.Text + ' no existe!');
    exit;
  end;

  if eArchiCF.Text = '' then
    eArchiCF.Text := carpetaSala + DirectorySeparator + 'CF_RN_.xlt';

  params := TInterpreteParametros.Create(False);
  params.addor('sala', eArchiSala.Text);
  params.addor('CF', eArchiCF.Text);
  params.addor('dtIni', e_dtIni.Text);
  params.addor('dtFin', e_dtFin.Text);

  aNeuronasPorCapasIntermedias := eEstructura.Text;
  aNeuronasPorCapasIntermedias := trim(aNeuronasPorCapasIntermedias);
  while pos(' ', aNeuronasPorCapasIntermedias) > 0 do
    Delete(aNeuronasPorCapasIntermedias, pos(' ', aNeuronasPorCapasIntermedias), 1);
  params.addor('ArrNPCI', aNeuronasPorCapasIntermedias);


  xo_cf_Cerebro_especifico(params);
  params.Free;


end;


procedure TfTractorcitoGUI.PlotIter(aCF: TAdminEstadosMultiPlano;
  aColor: TColor; pen_width: integer);
var
  nCanales: integer;

  aCHP: TConjuntoDeHiperplanos;
  aHP: THiperPlano;
  kCanal: integer;
  nPasosTm1: integer;
  kPasoT: integer;

  graficas: TGraficas;
  aCanal: TCanalGrafico;
  aSerie: TSerieXY;

begin
  nPasosTm1 := high(aCF.conjuntosDeHiperPlanos);

  nCanales := length(Escalas_min);

  graficas := TGraficas.Create;
  graficas.subplot(PaintBox1.canvas, PaintBox1.Width, PaintBox1.Height,
    nCanales, 1, nil, nil, false );


  kPasoT := 1;
  aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
  aHP := aCHP.hiperPlanos[0];

  for kCanal := 0 to high(aHP.A) do
  begin
    aCanal := graficas.getCanal(kCanal, 0);
    aSerie := aCanal.AddSerieXY('Iter_' + IntToStr(kCanal));
    aSerie.pen_width := pen_width;
    aSerie.pen_color := aColor;
    aSerie.activar;
    aSerie.SetEscalaX(1, nPasosTm1);
    aSerie.SetEscalaY(Escalas_min[kCanal], Escalas_max[kCanal]);
    {$IFDEF SATURAR_CANALES}
    if aHP.A[kCanal] > 1e9 then
      aHP.A[kCanal]:=1e9;
    if aHP.A[kCanal] < -1e9 then
      aHP.A[kCanal]:=-1e9;
    {$ENDIF}

    aSerie.go(1, aHP.A[kCanal]);

    for kPasoT := 2 to nPasosTm1 do
    begin
      aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
      aHP := aCHP.hiperPlanos[0];

      {$IFDEF SATURAR_CANALES}
      if aHP.A[kCanal] > 1e9 then
        aHP.A[kCanal]:=1e9;
      if aHP.A[kCanal] < -1e9 then
        aHP.A[kCanal]:=-1e9;
      {$ENDIF}

      aSerie.lineTo(kPasoT, aHP.A[kCanal]);
    end;
  end;

  kCanal := high(escalas_min);
  aCanal := graficas.getCanal(kCanal, 0);
  aSerie := aCanal.AddSerieXY('Iter_' + IntToStr(kCanal));
  aSerie.pen_width := pen_width;
  aSerie.pen_color := aColor;
  aSerie.activar;
  aSerie.SetEscalaX(1, nPasosTm1);
  aSerie.SetEscalaY(Escalas_min[kCanal], Escalas_max[kCanal]);
  aSerie.go(1, aHP.C0);
  for kPasoT := 2 to nPasosTm1 do
  begin
    aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
    aHP := aCHP.hiperPlanos[0];
    {$IFDEF SATURAR_CANALES}
    if aHP.C0 > 1e9 then
      aHP.C0:=1e9;
    if aHP.C0 < -1e9 then
      aHP.C0:=-1e9;
    {$ENDIF}
    aSerie.lineTo(kPasoT, aHP.C0);
  end;

  graficas.Free;
end;

procedure TfTractorcitoGUI.PlotAproFourier(kCanal: integer; nCanales: integer;
  jArmonico: TDAOfNReal; A0: NReal; A_, B_: TDAOfNReal; nPasosTm1: integer;
  aColor: TColor; pen_width: integer; aCF: TAdminEstadosMultiPlano);
var
  kPasoT: integer;
  graficas: TGraficas;
  aCanal: TCanalGrafico;
  aSerie: TSerieXY;
  w: NReal;
  aCHP: TConjuntoDeHiperplanos;
  aHP: THiperPlano;
  aVal: NReal;

  function aprof(kT: integer): NReal;
  var
    k: integer;
    res: NReal;
  begin
    res := A0;
    for k := 0 to high(jArmonico) do
      res := res + A_[k] * cos(jArmonico[k] * w * kT) + B_[k] *
        sin(jArmonico[k] * w * kT);
    Result := res;
  end;

begin
  graficas := TGraficas.Create;
  graficas.subplot(PaintBox1.canvas, PaintBox1.Width, PaintBox1.Height,
    nCanales, 1, nil, nil, false );

  w := 2 * pi / nPasosTm1;

  aCanal := graficas.getCanal(kCanal, 0);
  aSerie := aCanal.AddSerieXY('AproFourier_' + IntToStr(kCanal));
  aSerie.pen_width := pen_width;
  aSerie.pen_color := aColor;
  aSerie.activar;
  aSerie.SetEscalaX(1, nPasosTm1);
  aSerie.SetEscalaY(Escalas_min[kCanal], Escalas_max[kCanal]);

  aCHP := aCF.conjuntosDeHiperPlanos[1];
  aHP := aCHP.hiperPlanos[0];
  aVal := aprof(1);
  if kCanal < length(aHP.A) then
    aHP.A[kCanal] := aVal
  else
    aHP.C0 := aval;

  aSerie.go(1, aVal);
  for kPasoT := 2 to nPasosTm1 do
  begin
    aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
    aHP := aCHP.hiperPlanos[0];
    aVal := aprof(kPasoT);
    if kCanal < length(aHP.A) then
      aHP.A[kCanal] := aVal
    else
      aHP.C0 := aval;
    aSerie.lineTo(kPasoT, aVal);
  end;

  graficas.Free;
end;

procedure TfTractorcitoGUI.ActualizarEscalas(kEscala: integer; nuevoValor: NReal);
begin
  if nuevoValor < Escalas_min[kEscala] then
    Escalas_min[kEscala] := nuevoValor
  else if nuevoValor > Escalas_max[kEscala] then
    Escalas_max[kEscala] := nuevoValor;
end;

procedure TfTractorcitoGUI.btSelArchiSemillasClick(Sender: TObject);
begin
  OpenDialog1.Filter := 'Archivo de Semillas|*.txt';
  OpenDialog1.InitialDir := carpetaSala;
  if OpenDialog1.Execute then
  begin
    eArchiSemillas.Text := OpenDialog1.FileName;
  end;
end;

procedure TfTractorcitoGUI.btSelArchiCFClick(Sender: TObject);
begin
  OpenDialog1.Filter := 'Archivo CF|*.bin; *.xlt';
  OpenDialog1.InitialDir := carpetaSala;
  if OpenDialog1.Execute then
  begin
    eArchiCF.Text := OpenDialog1.FileName;
  end;
end;

procedure TfTractorcitoGUI.btSelArchiEstrellasIniClick(Sender: TObject);
begin
  OpenDialog1.Filter := 'Archivo Estrellitas|*.txt; *.xlt';
  OpenDialog1.InitialDir := carpetaSala;
  if OpenDialog1.Execute then
  begin
    eArchiEstrellasIni.Text := OpenDialog1.FileName;
  end;
end;

procedure TfTractorcitoGUI.btGenCFClick(Sender: TObject);
var
  params: TInterpreteParametros;

begin
  if eArchiSala.Text = '' then
  begin
    ShowMessage('Debe seleccionar una sala primero!');
    exit;
  end;


  if not FileExists(eArchiSala.Text) then
  begin
    ShowMessage('El archivo de Sala: ' + eArchiSala.Text + ' no existe!');
    exit;
  end;

  if eArchiCF.Text = '' then
    eArchiCF.Text := carpetaSala + DirectorySeparator + 'CF_nhp_' +
      e_NHiperplanos.Text + '.xlt';

  params := TInterpreteParametros.Create(False);
  params.addor('sala', eArchiSala.Text);
  params.addor('CF', eArchiCF.Text);

  params.addor('dtIni', e_dtIni.Text);
  params.addor('dtFin', e_dtFin.Text);
  params.addor('nHiperplanos', e_NHiperplanos.Text);

  xo_cf_mp_nulo(params);
  params.Free;

end;

procedure TfTractorcitoGUI.btGenerarSemillasClick(Sender: TObject);
var
  semillas: TDAofNInt;
begin

  if eArchiSala.Text = '' then
  begin
    ShowMessage('Debe seleccionar una sala primero!');
    exit;
  end;

  if not FileExists(eArchiSala.Text) then
  begin
    ShowMessage('El archivo de Sala: ' + eArchiSala.Text + ' no existe!');
    exit;
  end;

  if eArchiSemillas.Text = '' then
    eArchiSemillas.Text := carpetaSala + 'Semillas.xlt';

  GenSemillas(semillas, StrToInt(e_SemillaMadre_Cronicas.Text),
    StrToInt(e_kCronica1.Text), StrToInt(e_kCronica2.Text));

  WriteSemillas(semillas, eArchiSemillas.Text);
  setlength(semillas, 0);
end;

procedure TfTractorcitoGUI.btGenRNClick(Sender: TObject);
var
  params: TInterpreteParametros;
  aNeuronasPorCapasIntermedias: string;

begin
  if eArchiSala.Text = '' then
  begin
    ShowMessage('Debe seleccionar una sala primero!');
    exit;
  end;

  if not FileExists(eArchiSala.Text) then
  begin
    ShowMessage('El archivo de Sala: ' + eArchiSala.Text + ' no existe!');
    exit;
  end;

  if eArchiCF.Text = '' then
    eArchiCF.Text := carpetaSala + DirectorySeparator + 'CF_RN_.xlt';

  params := TInterpreteParametros.Create(False);
  params.addor('sala', eArchiSala.Text);
  params.addor('CF', eArchiCF.Text);
  params.addor('dtIni', e_dtIni.Text);
  params.addor('dtFin', e_dtFin.Text);

  aNeuronasPorCapasIntermedias := eArrayNeuronasPorCapasIntermedias.Text;
  aNeuronasPorCapasIntermedias := trim(aNeuronasPorCapasIntermedias);
  while pos(' ', aNeuronasPorCapasIntermedias) > 0 do
    Delete(aNeuronasPorCapasIntermedias, pos(' ', aNeuronasPorCapasIntermedias), 1);
  params.addor('ArrNPCI', aNeuronasPorCapasIntermedias);

  xo_cf_Cerebro_nulo(params);
  params.Free;

end;

procedure TfTractorcitoGUI.btPlotRangoCFsClick(Sender: TObject);
var
  aCF: TAdminEstadosMultiPlano;
  aCHP: TConjuntoDeHiperplanos;
  aHP: THiperPlano;
  j: integer;
  nPasosTm1: integer;
  kPasoT: integer;
  kIter: integer;
  kIterDesde: integer;
  kIterHasta, nCfs: integer;
  aColor: TColor;

begin
  kIterDesde := StrToInt(eIter1.Text);
  kIterHasta := StrToInt(eIter2.Text);

  // primero calculamos los promedio de los coeficientes del hiperplano
  // de la última iteración disponible y luego ploteamos los coeficientes
  // en por unidad de su promedio.
  aCF := TodosLosCfs[high(TodosLosCfs)] as TAdminEstadosMultiPlano;

  if aCF.nHiperplanosPorPasoT <> 1 then
    raise Exception.Create('Por ahora este método es para un solo hiperplano!!!');

  setlength(escalas_min, aCF.nVarsContinuas + aCF.nVarsDiscretas + 1);
  setlength(escalas_max, aCF.nVarsContinuas + aCF.nVarsDiscretas + 1);
  vclear(escalas_min);
  vsumr(escalas_min, 1e100);
  vclear(escalas_max);
  vsumr(escalas_min, -1e100);

  // incluimos la tapa final del último paso por eso el m1 (más 1).
  nPasosTm1 := high(aCF.conjuntosDeHiperPlanos);

  // me salteo la primer semana por el ruido de un solo punto de arranque
  for kPasoT := 2 to nPasosTm1 do
  begin
    aCHP := aCF.conjuntosDeHiperPlanos[kPasoT];
    aHP := aCHP.hiperPlanos[0];
    for j := 0 to high(aHP.A) do
      actualizarEscalas(j, aHP.A[j]);
    j := high(escalas_min);
    actualizarEscalas(j, aHP.C0);
  end;



  // bien ahora vamos a plotear
  for kIter := kIterDesde to kIterHasta do
  begin
    aCF := TodosLosCfs[kIter] as TAdminEstadosMultiPlano;
    nCfs:=Length(TodosLosCfs);
    aColor := ColorGradienteAzulRojo(kIter / nCfs);
    if kIter < high(TodosLosCfs) then
      PlotIter(aCF, aColor, 1)
    else
      PlotIter(aCF, aColor, 2);

    application.ProcessMessages;
    // sleep( 5 );
  end;

end;

procedure TfTractorcitoGUI.btPlotRangoTrysClick(Sender: TObject);
var
  graficas: TGraficas;
  aCanal: TCanalGrafico;
  aSerie: TSerieXYZ;
  archi: string;
  aCF: TAdminEstadosMultiPlano;
  atrys: TTrayectorias;

  kTrayectoria: integer;
  kPaso: integer;
  x1, x2, CF: NReal;
  aTrayectoria: TTrayectoria;
  aPunto: TPuntoTrayectoria;
begin
  graficas := TGraficas.Create;
  graficas.subplot(PaintBox2.Canvas, PaintBox2.Width, PaintBox2.Height, 1,
    1, nil, nil, false );
  aCanal := graficas.getCanal(0, 0);
  aSerie := aCanal.AddSerieXYZ('CF');

  archi := archi_CF_of_iter(CarpetaSala, 1);
  aCF := TAdminEstadosMultiPlano.CreateReadFromArchi(archi) as TAdminEstadosMultiPlano;

  archi := archi_try_of_iter(CarpetaSala, 1);
  atrys := TTrayectorias.CreateFromXLTArchi(archi);

  aSerie.SetEscalaX(0, length(atrys.Trayectorias[0].puntos));
  aSerie.SetEscalaY(-3, 3);
  aSerie.SetEscalaZ(0, 10000);

  for kTrayectoria := 0 to atrys.nTrayectorias - 1 do
  begin
    aTrayectoria := atrys.Trayectorias[kTrayectoria];
    aPunto := aTrayectoria.puntos[0];
    aSerie.activar;
    aSerie.pen_color := aSerie.canal.NextColor;
    aSerie.go(0, aPunto.X.Xr.e(2), aPunto.X.Xr.e(1));
    for kPaso := 1 to high(aTrayectoria.puntos) do
    begin
      aPunto := aTrayectoria.puntos[kPaso];
      aSerie.lineto(kPaso, aPunto.X.Xr.e(2), aPunto.X.Xr.e(1));
    end;
  end;

  graficas.Free;
  atrys.Free;
  aCF.Free;
end;

procedure TfTractorcitoGUI.btGenArchiEstrellasIniClick(Sender: TObject);
var
  sala: TSalaDeJuego;
  NubeDeEstrellas: TNubeDePuntos_XEstado;
  nEstrellas: integer;
  x, xx: TEstadoX;
  k, j: integer;
  Radio, r: NReal;

begin
  if eArchiSala.Text = '' then
  begin
    ShowMessage('Debe seleccionar una sala primero!');
    exit;
  end;

  if not FileExists(eArchiSala.Text) then
  begin
    ShowMessage('El archivo de Sala: ' + eArchiSala.Text + ' no existe!');
    exit;
  end;

  if eArchiEstrellasIni.Text = '' then
    eArchiEstrellasIni.Text := carpetaSala + 'EstrellasIni.xlt';


  uInicioYFinal.AlInicio;
  sala := usalasdejuego.cargarSala(0, eArchiSala.Text, '', True);
  chdir(sala.dirSala);

  sala.globs.ObligarDisponibilidad_1_ := sala.globs.ObligarDisponibilidad_1_Sim;
  sala.globs.EstadoDeLaSala := CES_SIMULANDO;
  sala.globs.kTrayectoria := 1;

  sala.PrepararMemoriaYListados;
  sala.Armar_lst_BarridoFijarEstadoDeActoresYFuentesToEstrella;

  sala.Preparar_CrearCF_y_regsitrar_variables_de_estado(False);

  sala.PrepararActualizadorFichasLPD(True);
  sala.InicioSim;
  sala.Sim_Cronica_Inicio;

  // Actualiza los parámemtros dinámicos de todos los Entes (Actores, Fuentes, etc.)
  sala.globs.ActualizadorLPD.ActualizarFichasHasta(sala.globs.FechaInicioDelpaso);

  // EVENTO: PrepararPaso_as
  //    Actores + Flucar antes de sorteos
  sala.PrepararPaso_as;

  // EVENTO: SorteosDelPaso( true )
  //    Fuentes (sorteo y calcula bornes calculados) + Actores
  sala.SorteosDelPasoSim(True);

  sala.fuentes_ActualizarEstadoGlobal(False);
  sala.actores_ActualizarEstadoGlobal(False);

  NEstrellas := StrToInt(e_nEstrellas.Text);
  NubeDeEstrellas := TNubeDePuntos_XEstado.CreateFromCF(sala.globs.CF, NEstrellas);

  // Ahora tenemos el estado inicial para usar de CENTRO
  //  sala.globs.CF.xr   sala.globs.CF.xd

{ Ahor alrededor del centro genermos estrellas con la dispersión del radio en cada dirección
   para eso, primero se calcula la posición en por unidad de las variables (escala del espacio)
   luego se genera
}


  x := NubeDeEstrellas.EstadosIniciales[0];
  x.Set_xrxd(sala.globs.CF.xr, sala.globs.CF.xd);

  Radio := StrToFloat(e_RadioEstrellitas.Text);

  randSeed := StrToInt(e_SemillaMadre_Estrellitas.Text);

  for k := 1 to nEstrellas - 1 do
  begin
    xx := NubeDeEstrellas.EstadosIniciales[k];
    for j := 1 to xx.Xr.n do
    begin
      r := 2.0 * (random - 0.5) * Radio;
      if r < 0 then
        xx.Xr.pon_e(j, x.Xr.e(j) + r *
          (xx.Xr.e(j) - sala.globs.CF.xr_def[j - 1].minval))
      else
        xx.Xr.pon_e(j, x.Xr.e(j) + r * (sala.globs.CF.xr_def[j - 1].maxval -
          xx.Xr.e(j)));
    end;
    for j := 1 to xx.Xd.n do
    begin
      r := 2.0 * (random - 0.5) * Radio;
      if r < 0 then
        xx.Xd.pon_e(j, round(x.xd.e(j) + r * (xx.Xd.e(j) -
          sala.globs.CF.xd_def[j - 1].minval)))
      else
        xx.Xd.pon_e(j, round(x.xd.e(j) + r *
          (sala.globs.CF.xd_def[j - 1].maxval - xx.Xd.e(j))));
    end;
  end;

  sala.Free;

  NubeDeEstrellas.WriteToArchiXLT(eArchiEstrellasIni.Text);

  NubeDeEstrellas.Free;

  uInicioYFinal.AlFinal;
end;

procedure TfTractorcitoGUI.btContarTrysClick(Sender: TObject);
var
  cnt: integer;
begin
  cnt := ultimo_CFsYTrys(CarpetaSala);
  if cnt > 0 then
  begin
    eIter1trys.Text := IntToStr(0);
    eIter2trys.Text := IntToStr(cnt);
  end
  else
  begin
    eIter1trys.Text := IntToStr(0);
    eIter2trys.Text := IntToStr(0);
  end;
end;

end.
