unit uCEGH_explorer;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  xmatdefs,
  fddp,
  matreal, matent,
  uhermitaprox,
  uregresion,
  udisnormcan,
  uAuxiliares,
  uverdoc,
  umodelosintcegh,
  WRFFTI01, WRFFTF01,
  Math, uestimadoryrellenado,
  uProbabilidadTransicion,
  uradiacionsolar,
  ugraficador,
  ExtCtrls, uhurst, autoco;


type

  { TForm1 }

  TForm1 = class(TForm)
    btCargarCEGH: TButton;
    eArchi: TEdit;
    OpenDialog1: TOpenDialog;
    procedure btCargarCEGHClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    cegh: TModeloCEGH;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure ProcesarDeformadores(
          nombreSerie: string;
          Deformadores: TDAOf_ddp_VectDeMuestras );
var
  f: textfile;
  v: TVectR;
  ve, pe20, pe80: TVectR;
  diario_ve, diario_pe20, diario_pe80: TVectR;
  anual_ve, anual_pe20, anual_pe80: TVectR;

  Deformador: Tf_ddp_VectDeMuestras;
  dEstacion: array[0..3] of array[0..23] of TVectR;
  cnt: array[0..3] of array[0..23] of integer;
  kEstacion, kHora: integer;
  NPFD: integer;
  NPasos: integer;
  kPaso: integer;

  g: TGrafico;
  sx, sy: TSerieGrafico;
  dias, horas: TVectR;
  kDia, jPaso: integer;
  c1, c2, c3: TCajaGraficoXY;

begin
 NPasos:= length( Deformadores );
 Deformador:= Deformadores[0];
 NPFD:= Deformador.a.n;
 ve:= TVectR.Create_Init( length( Deformadores ) );
 pe20:= TVectR.Create_Init( length( Deformadores ) );
 pe80:= TVectR.Create_Init( length( Deformadores ) );

 for kEstacion:= 0 to 3 do
  for kHora:= 0 to 23 do
  begin
    dEstacion[kEstacion][kHora]:= TVectR.Create_Init( NPFD );
    cnt[kEstacion][kHora]:= 0;
  end;

 diario_ve:= TVectR.Create_Init( 24 * 4);
 diario_pe20:= TVectR.Create_init( 24* 4 );
 diario_pe80:= TVectR.Create_init( 24* 4 );

 anual_ve:= TVectR.Create_Init( 8760 div 24 );
 anual_pe20:= TVectR.Create_init( 8760 div 24 );
 anual_pe80:= TVectR.Create_init( 8760 div 24 );

 for kPaso:=  1 to NPasos do
 begin
   jPaso:= ( trunc( ( kPaso -1 ) + ( 8760 / 8 ) ) mod 8760 ) + 1;
   Deformador:= Deformadores[kPaso-1];
   kEstacion:= trunc((jPaso -1 )/8760 * 4) ;
   kHora:= (kPaso-1) mod 24;
   dEstacion[kEstacion][kHora].sum( Deformador.a );
   inc( cnt[kEstacion][kHora] );

   ve.pon_e( kPaso, Deformador.a.promedio );
   pe20.pon_e( kPaso, Deformador.a.pe_VaR( 0.2 ));
   pe80.pon_e( kPaso, Deformador.a.pe_VaR( 0.8 ));
 end;

 // Ahora promediamos los perfiles diarios estacionales.
 // y tomamos los valores de interés para graficar
 for kEstacion:= 0 to 3 do
  for kHora:= 0 to 23 do
  begin
    v:= dEstacion[kEstacion][kHora];
    v.PorReal( 1/cnt[kEstacion][kHora] );
    kPaso:= kEstacion * 24 + kHora +1;
    diario_ve.pon_e( kPaso, v.promedio );
    diario_pe20.pon_e( kPaso, v.pe_VaR( 0.2 ));
    diario_pe80.pon_e( kPaso, v.pe_VaR( 0.8 ));
  end;

 horas:= TVectR.Create_init( 24 * 4 );
 for kHora:= 1 to horas.n  do
  horas.pon_e( kHora, kHora-1 );

 g:= TGrafico.Create( 'g1', TG_DispersionXY , 0);
// g.eje_x.Forzar_vmin(0);
// g.eje_x.Forzar_vmax( 24*4);
 g.eje_x.Forzar_ndivs( 4*4 );

 g.eje_x.FloatFormat_NDigitos:=12;
 g.eje_x.FloatFormat_NDecimales:=0;
 g.eje_y.FloatFormat_NDigitos:= 12;
 g.eje_y.FloatFormat_NDecimales:= 0;

  g.eje_x.titulo:= 'hora ( 0 Verano, 24 Otoño, 48 Invierno, 72 Primavera ) ';
  if pos( 'KTM_', nombreSerie  ) <> 0 then
  begin
//    g.eje_y.Forzar_vmin( 0 );
//    g.eje_y.Forzar_vmax( 1 );
    g.eje_y.Forzar_ndivs( 10 );
    g.eje_y.titulo:= 'índice de claridad [p.u.]';
    g.eje_y.FloatFormat_NDecimales:= 2;
  end
  else if pos( 'TMP_', nombreSerie ) <> 0 then
  begin
//    g.eje_y.Forzar_vmin( 0 );
//    g.eje_y.Forzar_vmax( 35 );
    g.eje_y.Forzar_ndivs( 7 );
    g.eje_y.titulo:= 'Temperatura [°C]';
  end
  else
  begin  // V_
//    g.eje_y.Forzar_vmin( -12 );
//    g.eje_y.Forzar_vmax( 12 );
    g.eje_y.Forzar_ndivs( 24 );
    g.eje_y.titulo:= '[m/s]';
  end;

  c1:= TCajaGraficoXY.Create( 24-0.9, g.eje_y.v_min_forzado, 24-0.1,  g.eje_y.v_max_forzado, '' );
  c2:= TCajaGraficoXY.Create( 48-0.9, g.eje_y.v_min_forzado, 48-0.1,  g.eje_y.v_max_forzado, '' );
  c3:= TCajaGraficoXY.Create( 72-0.9, g.eje_y.v_min_forzado, 72-0.1,  g.eje_y.v_max_forzado, '' );

  c1.colorArea:= clLtGray;  c1.colorLinea:= clWhite;  g.AddCajaXY( c1 );
  c2.colorArea:= clLtGray;  c2.colorLinea:= clWhite;  g.AddCajaXY( c2 );
  c3.colorArea:= clLtGray;  c3.colorLinea:= clWhite;  g.AddCajaXY( c3 );

  c1:= TCajaGraficoXY.Create(
       8, g.eje_y.v_max_forzado - 0.1*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       20, g.eje_y.v_max_forzado - 0.2*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       'Verano' );
  c1.colorLinea:= clNone;
  c1.colorArea:= clNone;
  g.AddCajaXY( c1 );

  c1:= TCajaGraficoXY.Create(
       24+8, g.eje_y.v_max_forzado - 0.1*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       24+20, g.eje_y.v_max_forzado - 0.2*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       'Otoño' );
  c1.colorLinea:= clNone;
  c1.colorArea:= clNone;
  g.AddCajaXY( c1 );

  c1:= TCajaGraficoXY.Create(
       48+8, g.eje_y.v_max_forzado - 0.1*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       48+20, g.eje_y.v_max_forzado - 0.2*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       'Invierno' );
  c1.colorLinea:= clNone;
  c1.colorArea:= clNone;
  g.AddCajaXY( c1 );

  c1:= TCajaGraficoXY.Create(
       72+8, g.eje_y.v_max_forzado - 0.1*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       72+20, g.eje_y.v_max_forzado - 0.2*(  g.eje_y.v_max_forzado -  g.eje_y.v_min_forzado ),
       'Primavera' );
  c1.colorLinea:= clNone;
  c1.colorArea:= clNone;
  g.AddCajaXY( c1 );


  g.Titulo:='Perfil diario por estación '+ NombreSerie;
 sx:= TSerieGrafico.Create( 'hora', horas, nil, g, '', true );
 g.AddSerie( sx );
 sy:= TSerieGrafico.Create( 'VE', diario_ve,sx, g );
 g.AddSerie( sy );
 sy:= TSerieGrafico.Create( 'PE_20%', diario_pe20, sx, g );
 g.AddSerie( sy );
 sy:= TSerieGrafico.Create( 'PE_80%', diario_pe80, sx, g );
 g.AddSerie( sy );

 g.SaveJPG('c:\basura\PerfilDiarioEstacional_'+nombreSerie+'.jpg', 1200, 600 );
 g.Free;

 horas.Free;

 dias:= TVectR.Create_init( 8760 div 24);
 if pos( 'KTM_', nombreSerie  ) <> 0 then
 begin
   for kDia:= 1 to dias.n  do
   begin
     dias.pon_e( kDia, (kDia-1)/365*12 );
     anual_ve.pon_e( kDia, ve.maxVentana( (kDia-1)* 24 +1, 24 ) ) ;
     anual_pe20.pon_e( kDia, pe20.maxVentana( (kDia-1)* 24 +1, 24 ) ) ;
     anual_pe80.pon_e( kDia, pe80.maxVentana( (kDia-1)* 24 +1, 24 ) ) ;
   end;
 end
 else
 begin
   for kDia:= 1 to dias.n  do
   begin
     dias.pon_e( kDia, (kDia-1)/365*12 );
     anual_ve.pon_e( kDia, ve.promedioVentana( (kDia-1)* 24 +1, 24 ) ) ;
     anual_pe20.pon_e( kDia, pe20.promedioVentana( (kDia-1)* 24 +1, 24 ) ) ;
     anual_pe80.pon_e( kDia, pe80.promedioVentana( (kDia-1)* 24 +1, 24 ) ) ;
   end;
 end;


 g:= TGrafico.Create( 'g1', TG_DispersionXY , 0);
 g.Titulo:= 'Cilo anual. '+ NombreSerie;
 g.eje_x.Forzar_vmin(0);
 g.eje_x.Forzar_vmax( 12 );
 g.eje_x.Forzar_ndivs( 12 );
 g.eje_x.FloatFormat_NDigitos:=12;
 g.eje_x.FloatFormat_NDecimales:=0;
 g.eje_y.FloatFormat_NDigitos:= 12;
 g.eje_y.FloatFormat_NDecimales:= 0;
 g.eje_x.titulo:= 'mes';
  if pos( 'KTM_', nombreSerie  ) <> 0 then
  begin
    g.eje_y.Forzar_vmin( 0 );
    g.eje_y.Forzar_vmax( 1 );
    g.eje_y.Forzar_ndivs( 10 );
    g.eje_y.titulo:= 'Máximo diario del índice de claridad [p.u.]';
    g.eje_y.FloatFormat_NDecimales:= 2;
  end
  else if pos( 'TMP_', nombreSerie ) <> 0 then
  begin
    g.eje_y.Forzar_vmin( 0 );
    g.eje_y.Forzar_vmax( 35 );
    g.eje_y.Forzar_ndivs( 7 );
    g.eje_y.titulo:= 'Temperatura [°C]';
  end
  else
  begin  // V_
    g.eje_y.Forzar_vmin( -12 );
    g.eje_y.Forzar_vmax( 12 );
    g.eje_y.Forzar_ndivs( 24 );
    g.eje_y.titulo:= '[m/s]';
  end;



 sx:= TSerieGrafico.Create( 'hora', dias, nil, g, '', true );
 g.AddSerie( sx );
 sy:= TSerieGrafico.Create( 'VE', anual_ve,sx, g );
 g.AddSerie( sy );
 sy:= TSerieGrafico.Create( 'PE_20%', anual_pe20, sx, g );
 g.AddSerie( sy );
 sy:= TSerieGrafico.Create( 'PE_80%', anual_pe80, sx, g );
 g.AddSerie( sy );
 g.SaveJPG('c:\basura\PerfilAnual_'+nombreSerie+'.jpg', 1200, 600 );
 g.Free;

 dias.Free;


  // salvataje a archivo
  setSeparadoresGlobales;


  setSeparadoresLocales;

// Destrucción de instancias
  ve.Free;
  pe20.Free;
  pe80.Free;

  for kEstacion:= 0 to 3 do
   for kHora:= 0 to 23 do
     dEstacion[kEstacion][kHora].Free;

  diario_ve.Free;
  diario_pe20.Free;
  diario_pe80.Free;
  anual_ve.Free;
  anual_pe20.Free;
  anual_pe80.Free;

end;

procedure TForm1.btCargarCEGHClick(Sender: TObject);
var
 archi: string;
 Deformadores: TDAOf_ddp_VectDeMuestras; // = array of Tf_ddp_VectDeMuestras;
 kSerie: integer;
begin
 if not OpenDialog1.Execute then
   exit;
 archi := OpenDialog1.FileName;
 cegh := TModeloCEGH.CreateFromArchi(archi);
 eArchi.Text:= archi;

 for kSerie:= 0 to cegh.nBornesSalida-1 do
 begin
  Deformadores:= cegh.funcionesDeformantes[kSerie];
  procesarDeformadores( cegh.NombresDeBornes_Publicados[kSerie], Deformadores );
 end;

end;

end.

