o
    C$jRB                     @   s  d Z ddlZddlZddlmZmZ ddlmZmZm	Z	 ddl
Z
ddlZ				d(dededed	ed
ee f
ddZ	d)dedededed
e	ej f
ddZ		d*deded	eded
ef
ddZ					d+deded	ededededed
eeee f fddZ			d,ded ed	ededed
eeee f fd!d"Z		d-ded ededed
eeee f f
d#d$Z	d)deded%eded
ejf
d&d'ZdS ).a  
accumulate.py -- Acumulados de precipitacao para PREC, PRCV e PRGE

Logica de acumulo:
------------------
O modelo tem saida HORARIA. A precipitacao NAO e definida na analise (hora 0),
portanto o acumulo NUNCA inclui o timestep 0.

Frequencia de acumulo configuravel via parametro accum_hours (padrao: 24).

Para accum_hours = 24 (convencao meteorologica):
  Duas janelas sao geradas em paralelo:
    ACUM00Z: acumula de 00Z a 00Z (validade em horario 00Z)
    ACUM12Z: acumula de 12Z a 12Z (validade em horario 12Z)

  Para run iniciando em 00Z (ex: 2026060400):
    ACUM00Z: soma FH 1-24  -> val. 2026060500 (00Z dia seguinte)
             soma FH 25-48 -> val. 2026060600
             ...
    ACUM12Z: soma FH 13-36 -> val. 2026060512
             soma FH 37-60 -> val. 2026060612
             ...
    Janela FH 109-132 seria o 5o ciclo, mas so ha FH ate 120
    -> janela incompleta -> DESCARTADA

  Para run iniciando em 12Z (ex: 2026060412):
    ACUM12Z: soma FH 1-24  -> val. 2026060512
    ACUM00Z: soma FH 13-36 -> val. 2026060600
             ...

Para outros periodos (ex: accum_hours = 6, 12, 48, 72):
  Janelas sequenciais comecando no FH dt_hours (primeiro FH disponivel):
    FH 1-6  -> val. YYYYMMDDHH   (accum_hours=6)
    FH 7-12 -> val. YYYYMMDDHH
    ...

Nomenclatura dos arquivos:
  PREC_ACUM24h_2026060500.tif   -- acumulo de 24h, validade 2026-06-05 00Z
  PREC_ACUM12h_2026060512.tif   -- acumulo de 12h, validade 2026-06-05 12Z
  PREC_ACUM6h_2026060506.tif    -- acumulo de  6h, validade 2026-06-05 06Z
    N)datetime	timedelta)ListDictOptional   t0ntimesdt_hoursaccum_hoursreturnc              
   C   s  | dur| nt j} |dur|nt j}|dur|nt j}|| dkr/td| d| d| d|d | }|| }|dkr| j}|dkrOd	|fd
d| fg}n|dkr^d
|fd	d| fg}n
d	|fd
d| fg}g }|D ]9\}	}
|
}||d |  |kr||d |  }| t|d }||	|||||d |d7 }||d |  |ks|ql|jdd d |S d| d}g }|}||d |  |kr||d |  }| t|d }|||||||d ||7 }||d |  |ks|S )u  
    Determina todas as janelas de acumulo validas para o run.

    Para accum_hours=24: gera janelas ACUM00Z e ACUM12Z (convencao sinótica).
    Para outros periodos: gera janelas sequenciais comecando no FH dt_hours.

    Janelas incompletas (menos de accum_hours/dt_hours arquivos disponiveis)
    sao automaticamente descartadas.

    Parameters
    ----------
    t0          : inicio do run (padrao: config.T0)
    ntimes      : numero de timesteps disponiveis (padrao: config.NTIMES)
    dt_hours    : intervalo de saida do modelo em horas (padrao: config.DT_HOURS)
    accum_hours : periodo de acumulo em horas (padrao: 24)
                  Deve ser multiplo de dt_hours.
                  Exemplos: 6, 12, 24, 48, 72

    Returns
    -------
    Lista de dicts ordenada por (validade, tipo):
      {
        'type'       : str   -- 'ACUM00Z' | 'ACUM12Z' | 'ACUM{N}h'
        'start_fh'   : int   -- primeiro FH incluido (em horas)
        'end_fh'     : int   -- ultimo FH incluido (em horas)
        'validity'   : datetime
        'n_steps'    : int   -- numero de arquivos somados
        'accum_hours': int   -- periodo do acumulo em horas
      }
    Nr   zaccum_hours=z nao e multiplo de dt_hours=z. Escolha um valor multiplo de zh.   r   ZACUM00ZZACUM12Z   hours)typestart_fhend_fhvalidityn_stepsr   c                 S   s   | d | d fS )Nr   r    )wr   r   A/dados/sismom/SisMOM/sismom_fig/Figuras_Eta/scripts/accumulate.py<lambda>   s    z*get_accumulation_windows.<locals>.<lambda>)keyZACUMh)	configT0NTIMESDT_HOURS
ValueErrorhourr   appendsort)r   r	   r
   r   Zmax_fhr   Zrun_hourZcycle_startswindows
accum_typer   fhr   r   labelr   r   r   get_accumulation_windows8   sx   $


r(   Fdata_dirvar_namewindow
sequentialc           
   	   C   s   t j}d}t|d D ]]}|d ||  }t jt|d }ztj| |||d}	W n ty3   Y  dS w |du r@tj	|	tj
d}tjdd tt|	t|B tj||	 }W d   n1 scw   Y  q|S )	a  
    Soma os campos de precipitacao de todos os FH dentro de uma janela.

    Parameters
    ----------
    data_dir   : diretorio com os arquivos .bin
    var_name   : nome da variavel (PREC, PRCV ou PRGE)
    window     : dict retornado por get_accumulation_windows()
    sequential : True se .bin usa marcadores Fortran

    Returns
    -------
    np.ndarray (NY, NX) em metros (unidade original), ou None se qualquer
    arquivo estiver ausente (janela incompleta -> descartada).
    Nr   r   r   r,   )dtypeignoreinvalid)r   r   ranger   r   reader
read_fieldFileNotFoundErrornp
zeros_likefloat32errstatewhereisnannan)
r)   r*   r+   r,   dtaccstepr&   tfieldr   r   r   compute_accumulation   s"   &rB   tifr   extc                 C   s    |  d| d| d d| S )z
    Gera o nome do arquivo de acumulado.

    Exemplos:
      PREC_ACUM24h_2026060500.tif
      PREC_ACUM12h_2026060512.tif
      PREC_ACUM6h_2026060506.tif
    Z_ACUMZh_%Y%m%d%H.)strftime)r*   r   r   rD   r   r   r   accum_filename   s    rH   Tcog_dir	overviewsskip_existingverbosec                 C   sF  ddl }tj|dd t|d}dd tjD }	|rZtd| d	t| d
ttj dt|ttj  d	 |D ] }
td|
d dd|
d dd|
d dd|
d d  q9tjD ]}|D ]}t	||d |d}tj
||}|rtj
|r|rtd|  |	| | qat| |||}|du r|rtd| d|d  d|d  d|d  d	 qazI|j|||||tj||d|d t|d t|d t|d |d dd tj t|jd!
|d" |	| | |rtd#|  W qa ty } z|rtd$| d|d  d%|  W Y d}~qad}~ww q]|	S )&a   
    Calcula e exporta todos os acumulados de PREC, PRCV e PRGE como COG GeoTIFF.

    Parameters
    ----------
    accum_hours : periodo do acumulo em horas (padrao: 24)
                  Para 24h: gera ACUM00Z e ACUM12Z.
                  Para outros valores: janelas sequenciais.
    r   NTexist_okr   c                 S      i | ]}|g qS r   r   .0vr   r   r   
<dictcomp>       z3export_all_accumulations_as_cog.<locals>.<dictcomp>z[accum] Periodo: zh | z janelas x z variaveis = z acumuladosz  r   Z10sz  FH r   3d-r     val. r   z
%Y%m%d %HZz  SKIP  z
  [AVISO]  z FHz: arquivo ausente -> descartadommr   z%Y-%m-%dT%H:%M:%SZzEta03/BESM run )
variabledescriptionunitsr%   r   r   r   r   modelZnodata)metadatarJ   z  OK  z	  [ERRO] : )
export_cogosmakedirsr(   r   PRECIP_VARSprintlenrG   rH   pathjoinexistsr"   rB   Z	write_cogZ_prepare_arrayVAR_DESCgetstrRUN_TAGZNODATA	Exception)r)   rI   r   r,   rJ   rK   rL   Zecogr$   savedr   varwinfnamefpatharrer   r   r   export_all_accumulations_as_cog   sx   


(







+rv   
output_dirc                 C   s  ddl }tj|dd t|d}dd tjD }dd	d
ddddddd
dddddd	ddd}tjD ]}	||	i ||d }
|D ]}t| |	||}|du rQqCt|	|d |tj	d}tj
||}d| d|d  d|d dd|d dd|d d  d!}zN|j||	|d |||jd"d|
d#	 tj
||	 d$|d d% d&tj	 }tj
|r||krt|| tj
|r||	 | |rtd'|  W qC ty } z|rtd(|	 d)|d  d*|  W Y d}~qCd}~ww q3|S )+z
    Gera figuras PNG dos acumulados de precipitacao.

    Parameters
    ----------
    accum_hours : periodo do acumulo em horas (padrao: 24)
    r   NTrM   rO   c                 S   rP   r   r   rQ   r   r   r   rT   I  rU   z*plot_all_accumulations.<locals>.<dictcomp>P   x      i,  i  )   r   r   0   H   <         (      )PRECPRCVPRGE   r   )r   rD   zAcum. zh (r   z)  [FH r   Z03drW   r   rX   z	%d/%m %HZ]rZ   )title_extraZ
convert_fnZunits_overrideZvmin_overrideZvmax_override_rE   rF   z  [PNG accum] z  [ERRO PNG accum] rY   r`   )Z
plot_utilsrb   rc   r(   r   rd   rk   rB   rH   FIG_EXTrg   rh   rG   Z
plot_fieldZm_to_mmri   renamer"   re   rn   )r)   rw   r   r,   rL   Zpur$   ro   Z
vmax_tablerp   vmaxrq   rt   rr   rs   r   autoru   r   r   r   plot_all_accumulations7  sj   

	'r   c                 C   s   t | |d||dS )zIAlias de compatibilidade -- chama plot_all_accumulations(accum_hours=24).r   )r)   rw   r   r,   rL   )r   )r)   rw   r,   rL   r   r   r   plot_all_24h_accumulations  s   r   t_endc              	      s    fdddD }d}|D ]<}t j| |||d}|du r!t|}tjdd tt|t|B tj|| }W d   n1 sDw   Y  q|S )zHLegado: acumulado 24h terminando em t_end (4 x 6h). Mantido para compat.c                    s   g | ]	} t |d  qS )r   )r   )rR   r   r   r   r   
<listcomp>  s    z,compute_24h_accumulation.<locals>.<listcomp>)   r   r{   r   Nr-   r/   r0   )r3   r4   r6   r7   r9   r:   r;   r<   )r)   r*   r   r,   Zwindows_4x6r>   r@   rA   r   r   r   compute_24h_accumulation  s   
&r   )NNNr   )F)r   rC   )r   FFFT)r   FT)FT)__doc__rb   numpyr6   r   r   typingr   r   r   r   r3   intr(   rl   boolndarrayrB   rH   rv   r   r   r   r   r   r   r   <module>   s    *
o
/

V
L
