Análise das séries sintéticas de vazões afluentes

Os arquivos vazaofXXX.dat contêm as séries sintéticas de vazões naturais afluentes geradas pelo modelo NEWAVE durante a simulação forward. Estes arquivos são essenciais para análise de cenários hidrológicos e planejamento operativo das usinas hidrelétricas. IMPORTANTE: Foi gerado um arquivo vazaof.dat reduzido utlizando o próprio módulo inewave para fins de demonstração com apenas 1 UHE. Em um caso real, utilize o arquivo gerado pelo NEWAVE.

import plotly.express as px
import plotly.io as pio

from inewave.newave import Vazaof

pio.templates.default = "ggplot2"

# Leitura do arquivo vazaof
arq_vazaof = Vazaof.read("./newave/vazaof.dat")

Configuração da leitura de arquivos binários

IMPORTANTE: Os arquivos vazaof são binários e requerem configuração específica baseada nas dimensões do estudo. Estes parâmetros devem corresponder exatamente ao caso de estudo:

# Exemplo de configuração típica (ajustar conforme o caso)
numero_forwards = 200  # Número de séries forward
numero_uhes = 150  # Número de UHEs
numero_estagios = 60  # Número de estágios de planejamento
numero_estagios_th = 12  # Número de estágios do horizonte térmico

print("Configuração da leitura:")
print(f"- Séries forward: {numero_forwards}")
print(f"- UHEs: {numero_uhes}")
print(f"- Estágios: {numero_estagios}")
print(f"- Estágios térmicos: {numero_estagios_th}")
Configuração da leitura:
- Séries forward: 200
- UHEs: 150
- Estágios: 60
- Estágios térmicos: 12

Estrutura dos dados de vazão

As séries sintéticas são organizadas por estágio, UHE e série forward:

series = arq_vazaof.series
print(f"Total de registros de vazão: {len(series)}")
print("\nPrimeiros registros:")
print(series.head())

print("\nEstatísticas básicas:")
print(series.describe())

print(f"\nUHEs representadas: {series['uhe'].nunique()}")
print(f"Estágios: {series['estagio'].min()} a {series['estagio'].max()}")
print(f"Séries: {series['serie'].nunique()}")
Total de registros de vazão: 2361600

Primeiros registros:
   estagio  uhe  serie  valor
0      -11    1      1  383.0
1      -11    1      2  383.0
2      -11    1      3  399.0
3      -11    1      4  399.0
4      -11    1      5  160.0

Estatísticas básicas:
            estagio           uhe         serie       valor
count  2.361600e+06  2.361600e+06  2.361600e+06   56.000000
mean   2.450000e+01  8.250000e+01  1.005000e+02  173.839821
std    2.078261e+01  4.734185e+01  5.773432e+01  110.835856
min   -1.100000e+01  1.000000e+00  1.000000e+00   40.000000
25%    6.750000e+00  4.175000e+01  5.075000e+01  103.000000
50%    2.450000e+01  8.250000e+01  1.005000e+02  146.555000
75%    4.225000e+01  1.232500e+02  1.502500e+02  192.450000
max    6.000000e+01  1.640000e+02  2.000000e+02  399.000000

UHEs representadas: 164
Estágios: -11 a 60
Séries: 200

Análise por UHE (Usina Hidrelétrica)

Análise da distribuição de vazões por usina:

print("Distribuição de vazões por UHE (primeiras 10 usinas):")
vazao_por_uhe = (
    series.groupby("uhe")
    .agg({"valor": ["count", "mean", "std", "min", "max"]})
    .round(2)
)
vazao_por_uhe.columns = ["registros", "media", "desvio", "minimo", "maximo"]
print(vazao_por_uhe.head(10))

# Identificando UHEs com maior vazão média
print("\nTop 10 UHEs com maior vazão média:")
top_uhes = vazao_por_uhe.nlargest(10, "media")
print(top_uhes[["media", "desvio"]])
Distribuição de vazões por UHE (primeiras 10 usinas):
     registros   media  desvio  minimo  maximo
uhe
1           56  173.84  110.84    40.0   399.0
2            0     NaN     NaN     NaN     NaN
3            0     NaN     NaN     NaN     NaN
4            0     NaN     NaN     NaN     NaN
5            0     NaN     NaN     NaN     NaN
6            0     NaN     NaN     NaN     NaN
7            0     NaN     NaN     NaN     NaN
8            0     NaN     NaN     NaN     NaN
9            0     NaN     NaN     NaN     NaN
10           0     NaN     NaN     NaN     NaN

Top 10 UHEs com maior vazão média:
      media  desvio
uhe
1    173.84  110.84
2       NaN     NaN
3       NaN     NaN
4       NaN     NaN
5       NaN     NaN
6       NaN     NaN
7       NaN     NaN
8       NaN     NaN
9       NaN     NaN
10      NaN     NaN

Análise temporal das vazões

Avaliando a evolução das vazões ao longo dos estágios:

# Vazão média por estágio
vazao_por_estagio = (
    series.groupby("estagio")["valor"].agg(["mean", "std"]).reset_index()
)

print("Vazão média por estágio (primeiros 12 estágios):")
print(vazao_por_estagio.head(12))

# Gráfico da evolução temporal
fig = px.line(
    vazao_por_estagio,
    x="estagio",
    y="mean",
    title="Evolução da Vazão Afluente Média por Estágio",
    labels={"mean": "Vazão Média (hm³)", "estagio": "Estágio"},
)
fig.add_scatter(
    x=vazao_por_estagio["estagio"],
    y=vazao_por_estagio["mean"] + vazao_por_estagio["std"],
    mode="lines",
    line=dict(width=0),
    showlegend=False,
    hovertemplate=None,
    hoverinfo="skip",
)
fig.add_scatter(
    x=vazao_por_estagio["estagio"],
    y=vazao_por_estagio["mean"] - vazao_por_estagio["std"],
    mode="lines",
    line=dict(width=0),
    fill="tonexty",
    fillcolor="rgba(0,100,80,0.2)",
    name="±1 Desvio Padrão",
    hovertemplate=None,
    hoverinfo="skip",
)
fig
Vazão média por estágio (primeiros 12 estágios):
    estagio        mean         std
0       -11  173.839821  110.835856
1       -10         NaN         NaN
2        -9         NaN         NaN
3        -8         NaN         NaN
4        -7         NaN         NaN
5        -6         NaN         NaN
6        -5         NaN         NaN
7        -4         NaN         NaN
8        -3         NaN         NaN
9        -2         NaN         NaN
10       -1         NaN         NaN
11        0         NaN         NaN


Análise sazonal das vazões

Identificando padrões sazonais nas vazões afluentes:

# Assumindo que os primeiros 12 estágios representam meses
series_sazonais = series[series["estagio"] <= 12].copy()

if len(series_sazonais) > 0:
    # Vazão média por mês
    vazao_mensal = (
        series_sazonais.groupby("estagio")["valor"]
        .agg(["mean", "std"])
        .reset_index()
    )

    meses_nomes = [
        "Jan",
        "Fev",
        "Mar",
        "Abr",
        "Mai",
        "Jun",
        "Jul",
        "Ago",
        "Set",
        "Out",
        "Nov",
        "Dez",
    ]
    vazao_mensal["mes_nome"] = vazao_mensal["estagio"].map(
        lambda x: meses_nomes[x - 1] if x <= 12 else f"Est{x}"
    )

    print("Padrão sazonal das vazões afluentes:")
    print(vazao_mensal[["mes_nome", "mean", "std"]].round(1))

    # Gráfico sazonal
    fig = px.bar(
        vazao_mensal,
        x="mes_nome",
        y="mean",
        error_y="std",
        title="Padrão Sazonal das Vazões Afluentes",
        labels={"mean": "Vazão Média (hm³)", "mes_nome": "Mês"},
    )
    fig
Padrão sazonal das vazões afluentes:
   mes_nome   mean    std
0       Jan  173.8  110.8
1       Fev    NaN    NaN
2       Mar    NaN    NaN
3       Abr    NaN    NaN
4       Mai    NaN    NaN
5       Jun    NaN    NaN
6       Jul    NaN    NaN
7       Ago    NaN    NaN
8       Set    NaN    NaN
9       Out    NaN    NaN
10      Nov    NaN    NaN
11      Dez    NaN    NaN
12      Jan    NaN    NaN
13      Fev    NaN    NaN
14      Mar    NaN    NaN
15      Abr    NaN    NaN
16      Mai    NaN    NaN
17      Jun    NaN    NaN
18      Jul    NaN    NaN
19      Ago    NaN    NaN
20      Set    NaN    NaN
21      Out    NaN    NaN
22      Nov    NaN    NaN
23      Dez    NaN    NaN

Análise de variabilidade hidrológica

Comparando diferentes séries para avaliar a incerteza hidrológica:

# Selecionando uma UHE específica para análise detalhada
uhe_analise = series["uhe"].iloc[0]  # Primeira UHE disponível
series_uhe = series[series["uhe"] == uhe_analise]

if len(series_uhe) > 0:
    print(f"Análise de variabilidade - UHE {uhe_analise}:")

    # Estatísticas por série
    stats_por_serie = (
        series_uhe.groupby("serie")["valor"].agg(["mean", "std"]).reset_index()
    )

    print("Estatísticas das séries forward:")
    print(
        f"- Vazão média entre séries: {stats_por_serie['mean'].mean():.1f} hm³"
    )
    print(
        f"- Desvio padrão entre médias: {stats_por_serie['mean'].std():.1f} hm³"
    )
    print(
        f"- Coeficiente de variação: {stats_por_serie['mean'].std() / stats_por_serie['mean'].mean() * 100:.1f}%"
    )

    # Distribuição das médias por série
    fig = px.histogram(
        stats_por_serie,
        x="mean",
        title=f"Distribuição da Vazão Média por Série - UHE {uhe_analise}",
        labels={"mean": "Vazão Média (hm³)", "count": "Frequência"},
    )
    fig
Análise de variabilidade - UHE 1:
Estatísticas das séries forward:
- Vazão média entre séries: 173.8 hm³
- Desvio padrão entre médias: 110.8 hm³
- Coeficiente de variação: 63.8%

Análise de cenários extremos

Identificando cenários de vazão alta e baixa:

# Vazão total por série (somando todas as UHEs e estágios)
vazao_total_serie = series.groupby("serie")["valor"].sum().reset_index()
vazao_total_serie = vazao_total_serie.sort_values("valor")

# Identificando cenários extremos
p10 = vazao_total_serie["valor"].quantile(0.10)
p90 = vazao_total_serie["valor"].quantile(0.90)

cenarios_secos = vazao_total_serie[vazao_total_serie["valor"] <= p10]
cenarios_umidos = vazao_total_serie[vazao_total_serie["valor"] >= p90]

print("Análise de cenários hidrológicos extremos:")
print(f"Cenários secos (≤P10): {len(cenarios_secos)} séries")
print(f"Cenários úmidos (≥P90): {len(cenarios_umidos)} séries")
print(f"Vazão P10: {p10:.0f} hm³")
print(f"Vazão P90: {p90:.0f} hm³")
print(f"Relação P90/P10: {p90 / p10:.2f}")

print("\nSéries dos cenários mais secos:")
print(cenarios_secos["serie"].tolist()[:10])  # Primeiras 10

print("\nSéries dos cenários mais úmidos:")
print(cenarios_umidos["serie"].tolist()[:10])  # Primeiras 10
Análise de cenários hidrológicos extremos:
Cenários secos (≤P10): 144 séries
Cenários úmidos (≥P90): 20 séries
Vazão P10: 0 hm³
Vazão P90: 161 hm³
/home/runner/work/inewave/inewave/examples/plot_vazaof.py:231: RuntimeWarning:

divide by zero encountered in scalar divide

Relação P90/P10: inf

Séries dos cenários mais secos:
[64, 63, 62, 61, 60, 59, 58, 57, 120, 119]

Séries dos cenários mais úmidos:
[54, 51, 56, 49, 23, 24, 44, 47, 52, 46]

Comparação entre usinas hidrelétricas

Analisando correlações e diferenças entre UHEs:

# Selecionando algumas UHEs para análise de correlação
uhes_principais = series["uhe"].value_counts().head(10).index.tolist()

if len(uhes_principais) > 1:
    # Criando matriz UHE x série para análise de correlação
    series_subset = series[series["uhe"].isin(uhes_principais)]

    # Calculando vazão média por UHE e série
    vazao_media_uhe_serie = (
        series_subset.groupby(["uhe", "serie"])["valor"].mean().reset_index()
    )

    pivot_vazao = vazao_media_uhe_serie.pivot_table(
        index="serie", columns="uhe", values="valor"
    )

    # Matriz de correlação entre UHEs
    correlacao_uhes = pivot_vazao.corr()

    print("Correlação entre UHEs principais (5x5):")
    print(correlacao_uhes.iloc[:5, :5].round(3))

    # Contribuição de cada UHE para o total
    contrib_uhe = (
        series.groupby("uhe")["valor"].sum().sort_values(ascending=False)
    )
    contrib_uhe_pct = (contrib_uhe / contrib_uhe.sum() * 100).round(1)

    print("\nTop 10 UHEs por contribuição total:")
    for uhe, pct in contrib_uhe_pct.head(10).items():
        print(f"UHE {uhe}: {pct}%")
Correlação entre UHEs principais (5x5):
uhe    1
uhe
1    1.0

Top 10 UHEs por contribuição total:
UHE 1: 100.0%
UHE 2: 0.0%
UHE 3: 0.0%
UHE 4: 0.0%
UHE 5: 0.0%
UHE 6: 0.0%
UHE 7: 0.0%
UHE 8: 0.0%
UHE 9: 0.0%
UHE 10: 0.0%

Análise de consistência hidrológica

Verificando propriedades hidrológicas das séries:

def analisar_consistencia_hidrologica(df):
    """Análise de consistência das séries de vazão"""
    resultados = {}

    # 1. Verificar vazões negativas
    vazoes_negativas = df[df["valor"] < 0]
    resultados["vazoes_negativas"] = len(vazoes_negativas)

    # 2. Verificar vazões extremamente altas (outliers)
    q99 = df["valor"].quantile(0.99)
    q01 = df["valor"].quantile(0.01)
    outliers_altos = df[df["valor"] > q99 * 3]  # 3x o P99
    outliers_baixos = df[df["valor"] < q01 * 0.1]  # <10% do P01

    resultados["outliers_altos"] = len(outliers_altos)
    resultados["outliers_baixos"] = len(outliers_baixos)

    # 3. Verificar completude dos dados
    total_esperado = (
        df["serie"].nunique() * df["uhe"].nunique() * df["estagio"].nunique()
    )
    resultados["completude_pct"] = len(df) / total_esperado * 100

    # 4. Estatísticas básicas
    resultados["vazao_media_global"] = df["valor"].mean()
    resultados["vazao_std_global"] = df["valor"].std()
    resultados["cv_global"] = df["valor"].std() / df["valor"].mean()

    return resultados


print("Análise de consistência hidrológica:")
consistencia = analisar_consistencia_hidrologica(series)

print(f"- Vazões negativas: {consistencia['vazoes_negativas']} registros")
print(f"- Outliers altos: {consistencia['outliers_altos']} registros")
print(f"- Outliers baixos: {consistencia['outliers_baixos']} registros")
print(f"- Completude dos dados: {consistencia['completude_pct']:.1f}%")
print(f"- Vazão média global: {consistencia['vazao_media_global']:.1f} hm³")
print(f"- Coef. variação global: {consistencia['cv_global']:.3f}")

if consistencia["vazoes_negativas"] > 0:
    print("⚠️ Atenção: Vazões negativas detectadas")
if consistencia["completude_pct"] < 95:
    print("⚠️ Atenção: Dados incompletos detectados")
Análise de consistência hidrológica:
- Vazões negativas: 0 registros
- Outliers altos: 0 registros
- Outliers baixos: 0 registros
- Completude dos dados: 100.0%
- Vazão média global: 173.8 hm³
- Coef. variação global: 0.638

Processamento para análises externas

Preparando dados para exportação:

# Resumo estatístico por UHE
resumo_uhe = (
    series.groupby("uhe")["valor"]
    .agg([
        "count",
        "mean",
        "std",
        "min",
        "max",
        lambda x: x.quantile(0.1),  # P10
        lambda x: x.quantile(0.5),  # P50
        lambda x: x.quantile(0.9),  # P90
    ])
    .round(2)
)
resumo_uhe.columns = [
    "registros",
    "media",
    "desvio",
    "minimo",
    "maximo",
    "P10",
    "P50",
    "P90",
]

print("Resumo estatístico por UHE (primeiras 10):")
print(resumo_uhe.head(10))

# Vazões agregadas por estágio
vazoes_agregadas = (
    series.groupby("estagio")
    .agg({"valor": ["sum", "mean", "std", "count"]})
    .round(2)
)
vazoes_agregadas.columns = ["total", "media", "desvio", "registros"]

print("\nVazões agregadas por estágio (primeiros 12):")
print(vazoes_agregadas.head(12))
Resumo estatístico por UHE (primeiras 10):
     registros   media  desvio  minimo  maximo   P10     P50    P90
uhe
1           56  173.84  110.84    40.0   399.0  48.0  146.56  383.0
2            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
3            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
4            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
5            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
6            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
7            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
8            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
9            0     NaN     NaN     NaN     NaN   NaN     NaN    NaN
10           0     NaN     NaN     NaN     NaN   NaN     NaN    NaN

Vazões agregadas por estágio (primeiros 12):
           total   media  desvio  registros
estagio
-11      9735.03  173.84  110.84         56
-10         0.00     NaN     NaN          0
-9          0.00     NaN     NaN          0
-8          0.00     NaN     NaN          0
-7          0.00     NaN     NaN          0
-6          0.00     NaN     NaN          0
-5          0.00     NaN     NaN          0
-4          0.00     NaN     NaN          0
-3          0.00     NaN     NaN          0
-2          0.00     NaN     NaN          0
-1          0.00     NaN     NaN          0
 0          0.00     NaN     NaN          0

Exportação de resultados processados

print("\nOpções de exportação disponíveis:")
print("1. Séries originais: arq_vazaof.series")
print("2. Resumo por UHE: resumo_uhe")
print("3. Vazões por estágio: vazao_por_estagio")
print("4. Vazões agregadas: vazoes_agregadas")
print("5. Cenários extremos: cenarios_secos, cenarios_umidos")

# Exemplos de exportação:
# resumo_uhe.to_csv('resumo_vazoes_uhe.csv')
# vazao_por_estagio.to_csv('vazoes_por_estagio.csv', index=False)
Opções de exportação disponíveis:
1. Séries originais: arq_vazaof.series
2. Resumo por UHE: resumo_uhe
3. Vazões por estágio: vazao_por_estagio
4. Vazões agregadas: vazoes_agregadas
5. Cenários extremos: cenarios_secos, cenarios_umidos

Total running time of the script: (0 minutes 5.900 seconds)

Gallery generated by Sphinx-Gallery