o
    9%j=                     @   sJ  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 Z						d*de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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d tt|	t|B tj||	 }W d   n1 sdw   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over)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"   &rA   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
    _ACUMZh_z%Y%m%d%H.)strftime)r*   r   r   rC   r   r   r   accum_filename   s    rG   c                 C   sl  | \}}}}}}}}ddl }	tj|| d| d}
tj|
dd t||d |d}tj|
|}|rCtj|rC||d	 |ddfS t||||}|du rW||d	 dd
dfS zA|	j|		||||t
j||d|d	 t|d t|d t|d |d ddt
j t|	jd
|d ||d	 |ddfW S  ty } z||d	 dt|dfW  Y d}~S d}~ww )z/Worker paralelo para gerar um COG de acumulado.r   NrD   r   Texist_okr   r   r   arquivo ausenteFmmr   r   r   z%Y-%m-%dT%H:%M:%SZzEta03/BESM run )
variabledescriptionunitsr%   r   r   r   r   modelZnodata)metadata	overviews)
export_cogospathjoinmakedirsrG   existsrA   Z	write_cogZ_prepare_arrayr   VAR_DESCgetstrrF   RUN_TAGZNODATA	Exception)argsr)   varwincog_dirr   r,   rR   skip_existingZecogvar_dirfnamefpatharrer   r   r   _accum_cog_worker   sB   




"rh   Tr   ra   rR   rb   verboseworkersc                    sh  ddl m}m}	 tjdd t ddd tjD }
 fdd	tjD }t|}|rmt	d
  dt dttj d| d| 
 D ] }t	d|d dd|d dd|d dd|d 
d  qL|dkr|D ]P}t|\}}}}}|r|dkr|rt	d| d| d|  qs|dkr|rt	d| d| d|  qs|
| | |rt	d|rd nd! dtj|  qs|
S ||d"^fd#d|D }|	|D ]G}| \}}}}}|r|r|dkrd$nd%}t	d| d| d| d|  q|
| | |r t	d|rd nd! dtj|  qW d&   |
S 1 s-w   Y  |
S )'aS  
    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.
    workers     : processos paralelos (1 = serial)
    r   )ProcessPoolExecutoras_completedTrH   rJ   c                 S      i | ]}|g qS r   r   .0vr   r   r   
<dictcomp>$      z3export_all_accumulations_as_cog.<locals>.<dictcomp>c                    s*   g | ]}D ]}|| fqqS r   r   )ro   r_   r`   )r   ra   r)   rR   r,   rb   r$   r   r   
<listcomp>&  s    z3export_all_accumulations_as_cog.<locals>.<listcomp>[accum] Periodo: h |  janelas x z variaveis = z acumulados | workers=z  r   Z10sz  FH r   3d-r   z  val. r   z
%Y%m%d %HZr   rK   	  [ERRO]  : 
  [AVISO] ZSKIPzOK  )max_workersc                    s   i | ]	}  t||qS r   )submitrh   )ro   r?   )poolr   r   rq   C  s    z[AVISO]z[ERRO]N)concurrent.futuresrk   rl   rT   rW   r(   r   PRECIP_VARSlenprintrF   rh   r"   rU   basenameresult)r)   ra   r   r,   rR   rb   ri   rj   rk   rl   savedtasksn_totalr   taskr_   Zwtypere   errZskippedfutsfuttagr   )r   ra   r)   rR   r   r,   rb   r$   r   export_all_accumulations_as_cog  sl   

(
$ &
r   
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
d|dd}|rQtd| dt| dttj d tjD ]}	tj	
||	 d| d}
tj|
dd |D ]}t|	|d |tjd}tj	
|
|}t| |	||}|du r|rtd|	 d|d  d qlz:t||	tr||	i |d
n||	d
}|j|	||d ||d ||d  ||	 | |rtd!|  W ql ty } z|rtd"|	 d|d  d#|  W Y d}~qld}~ww qT|S )$z
    Gera figuras PNG dos acumulados de precipitacao.

    Parameters
    ----------
    accum_hours : periodo do acumulo em horas (padrao: 24)
    r   NTrH   rJ   c                 S   rm   r   r   rn   r   r   r   rq   d  rr   z*plot_all_accumulations.<locals>.<dictcomp>P   x      i,  i  )   r   r   0   H   2      (   <   d   )ZPRECZPRCVZPRGErt   ru   rv   z
 variaveisrD   r   r   )r   rC   r|   rz   r   z: arquivo ausente)r*   datar   r   r%   Zoutput_pathvmaxz  OK  ry   r{   )Z
plot_utilsrT   rW   r(   r   r   rZ   r   r   rU   rV   rG   FIG_EXTrA   
isinstancedictZplot_accumulationr"   r]   )r)   r   r   r,   ri   Zpur$   r   Z
vmax_tabler_   rc   r`   rd   re   rf   r   rg   r   r   r   plot_all_accumulationsR  s^   



0	r   )NNNr   )F)r   rB   )r   FFFTr   )r   FT)__doc__rT   numpyr5   r   r   typingr   r   r   r   r2   intr(   r[   boolndarrayrA   rG   rh   r   r   r   r   r   r   <module>   s    *
o
/
+	
I