nowcasting-sus 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nowcasting_sus-1.1.0/LICENSE +21 -0
- nowcasting_sus-1.1.0/MANIFEST.in +2 -0
- nowcasting_sus-1.1.0/PKG-INFO +228 -0
- nowcasting_sus-1.1.0/README.md +184 -0
- nowcasting_sus-1.1.0/nowcasting_sus/__init__.py +90 -0
- nowcasting_sus-1.1.0/nowcasting_sus/cli.py +187 -0
- nowcasting_sus-1.1.0/nowcasting_sus/data.py +321 -0
- nowcasting_sus-1.1.0/nowcasting_sus/models.py +512 -0
- nowcasting_sus-1.1.0/nowcasting_sus/plot.py +371 -0
- nowcasting_sus-1.1.0/nowcasting_sus/report.py +200 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/PKG-INFO +228 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/SOURCES.txt +21 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/dependency_links.txt +1 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/entry_points.txt +2 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/requires.txt +16 -0
- nowcasting_sus-1.1.0/nowcasting_sus.egg-info/top_level.txt +1 -0
- nowcasting_sus-1.1.0/pyproject.toml +80 -0
- nowcasting_sus-1.1.0/setup.cfg +4 -0
- nowcasting_sus-1.1.0/tests/test_cli.py +100 -0
- nowcasting_sus-1.1.0/tests/test_data.py +230 -0
- nowcasting_sus-1.1.0/tests/test_models.py +183 -0
- nowcasting_sus-1.1.0/tests/test_plot.py +262 -0
- nowcasting_sus-1.1.0/tests/test_report.py +211 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marcos Malveira
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nowcasting-sus
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Nowcasting bayesiano para dados do SINAN — correção de atraso de notificação em tempo real
|
|
5
|
+
Author-email: Marcos Malveira <mvmlima@hotmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/MVMLima/nowcasting-sus
|
|
8
|
+
Project-URL: Documentation, https://github.com/MVMLima/nowcasting-sus#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/MVMLima/nowcasting-sus
|
|
10
|
+
Project-URL: Changelog, https://github.com/MVMLima/nowcasting-sus/blob/main/CHANGELOG.md
|
|
11
|
+
Project-URL: Issues, https://github.com/MVMLima/nowcasting-sus/issues
|
|
12
|
+
Keywords: nowcasting,nowcast,bayesian,pymc,sinan,epidemiology,surveillance,health,dengue,chikungunya,arbovirus,brazil,sus,data-science,time-series,mcmc,markov-chain-monte-carlo
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Healthcare Industry
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Natural Language :: Portuguese (Brazilian)
|
|
25
|
+
Classifier: Operating System :: OS Independent
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: numpy>=1.24
|
|
30
|
+
Requires-Dist: pandas>=2.0
|
|
31
|
+
Requires-Dist: matplotlib>=3.7
|
|
32
|
+
Requires-Dist: pymc>=5.0
|
|
33
|
+
Requires-Dist: arviz>=0.16
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
38
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
39
|
+
Requires-Dist: twine>=4.0; extra == "dev"
|
|
40
|
+
Provides-Extra: test
|
|
41
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
42
|
+
Requires-Dist: pytest-cov>=4.0; extra == "test"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# nowcasting-sus
|
|
46
|
+
|
|
47
|
+
[](https://github.com/MVMLima/nowcasting-sus/actions/workflows/ci.yml)
|
|
48
|
+
[](https://pypi.org/project/nowcasting-sus/)
|
|
49
|
+
[](https://pypi.org/project/nowcasting-sus/)
|
|
50
|
+
[](https://opensource.org/licenses/MIT)
|
|
51
|
+
|
|
52
|
+
**Nowcasting bayesiano para dados do SINAN** — correção de atraso de notificação em tempo real usando PyMC.
|
|
53
|
+
|
|
54
|
+
> ⚕️ Desenvolvido no Departamento de Vigilância em Saúde da Secretaria de Estado de Saúde do Acre
|
|
55
|
+
> Agora open source para qualquer equipe de vigilância do Brasil.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## O Problema
|
|
60
|
+
|
|
61
|
+
Os dados do SINAN chegam **atrasados**. Não por falha do sistema — é da natureza da notificação epidemiológica:
|
|
62
|
+
|
|
63
|
+
1. Um caso ocorre (data de início dos sintomas)
|
|
64
|
+
2. Leva **dias ou semanas** até ser digitado no SINAN
|
|
65
|
+
3. Se você olha o número **bruto** de hoje, está sempre subestimando a realidade
|
|
66
|
+
|
|
67
|
+
O **nowcasting** (ou "previsão do presente") resolve isso: modela o padrão histórico de atraso de notificação e estima quantos casos **já ocorreram mas ainda não foram notificados**.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Instalação
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install nowcasting-sus
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Requisitos:** Python ≥ 3.10, PyMC ≥ 5.0
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Uso Rápido
|
|
82
|
+
|
|
83
|
+
### Python
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from nowcasting_sus.data import load_sinan, prepare_matrix
|
|
87
|
+
from nowcasting_sus.models import NowcastingModel, NowcastingModelDOW
|
|
88
|
+
from nowcasting_sus.plot import plot_nowcasting, plot_panel
|
|
89
|
+
|
|
90
|
+
# 1. Carregar dados do SINAN (qualquer CSV com DT_SIN_PRI e DT_NOTIFIC)
|
|
91
|
+
df = load_sinan("dados_sinan.csv")
|
|
92
|
+
|
|
93
|
+
# 2. Preparar matriz onset × delay para o modelo
|
|
94
|
+
nmat, dates, obs_t, obs_d, counts = prepare_matrix(df)
|
|
95
|
+
|
|
96
|
+
# 3. Ajustar modelo nowcasting
|
|
97
|
+
modelo = NowcastingModel()
|
|
98
|
+
idata = modelo.fit(obs_t, obs_d, counts, T=nmat.shape[0], D=nmat.shape[1])
|
|
99
|
+
|
|
100
|
+
# 4. Obter estimativas corrigidas
|
|
101
|
+
median, low, high = modelo.get_nowcast_ci()
|
|
102
|
+
# median[t] = casos esperados no dia t (já corrigindo atraso)
|
|
103
|
+
|
|
104
|
+
# 5. Visualizar
|
|
105
|
+
fig = plot_nowcasting(nmat, median, low, high, dates)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Modelo com Efeito de Dia da Semana (DOW)
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
import pandas as pd
|
|
112
|
+
|
|
113
|
+
modelo_dow = NowcastingModelDOW()
|
|
114
|
+
dow = pd.to_datetime(dates).dayofweek.values # 0=segunda .. 6=domingo
|
|
115
|
+
idata = modelo_dow.fit(obs_t, obs_d, counts, T=T, D=nmat.shape[1], dow=dow)
|
|
116
|
+
|
|
117
|
+
# Ver efeito de cada dia da semana
|
|
118
|
+
print(modelo_dow.get_dow_effect())
|
|
119
|
+
# Exemplo: {'Seg': 1.12, 'Dom': 0.65} → domingo tem 35% menos notificações
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### CLI — Relatório HTML
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
nowcasting-report dados_sinan.csv --agravo "Chikungunya" --uf "Bahia" -o boletim.html
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Gera um boletim epidemiológico completo com:
|
|
129
|
+
- Resumo executivo (observado × estimado × não notificados)
|
|
130
|
+
- Tabela com estimativas dos últimos 14 dias
|
|
131
|
+
- Interpretação automática dos resultados
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Modelos
|
|
136
|
+
|
|
137
|
+
| Modelo | Descrição | Quando usar |
|
|
138
|
+
|--------|-----------|-------------|
|
|
139
|
+
| `NowcastingModel` | Random Walk 1ª ordem + Negative Binomial | Uso geral, padrão |
|
|
140
|
+
| `NowcastingModelDOW` | RW1 + NB + efeito dia da semana (ZeroSumNormal) | Quando há padrão claro de menor notificação em fins de semana |
|
|
141
|
+
|
|
142
|
+
### Parâmetros Ajustáveis
|
|
143
|
+
|
|
144
|
+
| Parâmetro | Default | Descrição |
|
|
145
|
+
|-----------|---------|-----------|
|
|
146
|
+
| `sigma_rw` | 0.1 | Suavidade da tendência temporal (menor = mais suave) |
|
|
147
|
+
| `alpha_nb` | 10.0 | Dispersão da NegativeBinomial (maior = menos dispersão) |
|
|
148
|
+
| `alpha_scale` | 3.0 | Escala do prior Dirichlet para distribuição de atraso |
|
|
149
|
+
| `sigma_dow` | 0.3 | (DOW) Magnitude do efeito dia da semana |
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Estrutura do Pacote
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
nowcasting-sus/
|
|
157
|
+
├── nowcasting_sus/
|
|
158
|
+
│ ├── __init__.py # Exporta API pública
|
|
159
|
+
│ ├── data.py # Carga e preparação de dados SINAN
|
|
160
|
+
│ ├── models.py # Modelos PyMC (NowcastingModel, NowcastingModelDOW)
|
|
161
|
+
│ ├── plot.py # Visualização (curva, painel, efeito DOW)
|
|
162
|
+
│ ├── report.py # Geração de boletim HTML
|
|
163
|
+
│ └── cli.py # Interface de linha de comando
|
|
164
|
+
├── tests/ # Suite de testes (65+ testes, pytest)
|
|
165
|
+
├── examples/ # Exemplos de uso
|
|
166
|
+
├── .github/workflows/ # CI/CD automatizado
|
|
167
|
+
└── pyproject.toml # Configuração do pacote
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Exemplo Completo
|
|
173
|
+
|
|
174
|
+
Veja [`examples/example_real.py`](examples/example_real.py) para um pipeline completo que:
|
|
175
|
+
1. Carrega dados do SINAN
|
|
176
|
+
2. Ajusta modelo base e modelo DOW
|
|
177
|
+
3. Gera gráfico de painel 2×3
|
|
178
|
+
4. Exporta relatório HTML
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## API Detalhada
|
|
183
|
+
|
|
184
|
+
### `data.load_sinan(filepath, date_onset, date_notif, max_delay, min_year)`
|
|
185
|
+
Carrega CSV do SINAN, valida colunas, converte datas, calcula delay e filtra registros inválidos.
|
|
186
|
+
|
|
187
|
+
### `data.prepare_matrix(df, max_delay)`
|
|
188
|
+
Converte DataFrame em matriz `T × D` (dias de onset × dias de delay) para o modelo.
|
|
189
|
+
|
|
190
|
+
### `models.NowcastingModel.fit(obs_t, obs_d, counts, T, D, draws, tune, chains)`
|
|
191
|
+
Ajusta o modelo MCMC via PyMC. Retorna `arviz.InferenceData`.
|
|
192
|
+
|
|
193
|
+
### `models.NowcastingModel.get_nowcast_ci(prob=0.95)`
|
|
194
|
+
Retorna `(mediana, inferior, superior)` — estimativas nowcast na escala original (casos/dia).
|
|
195
|
+
|
|
196
|
+
### `plot.plot_nowcasting(...)`, `plot.plot_panel(...)`, `plot.plot_dow_effect(...)`
|
|
197
|
+
Funções de visualização. Todas retornam `matplotlib.figure.Figure`.
|
|
198
|
+
|
|
199
|
+
### `report.generate_report(...)`
|
|
200
|
+
Gera boletim epidemiológico em HTML. Aceita parâmetros personalizados (agravo, UF, CID).
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Contribuindo
|
|
205
|
+
|
|
206
|
+
Contribuições são bem-vindas!
|
|
207
|
+
|
|
208
|
+
1. Fork o repositório
|
|
209
|
+
2. Crie uma branch: `git checkout -b minha-feature`
|
|
210
|
+
3. Faça suas alterações
|
|
211
|
+
4. Execute os testes: `pytest tests/ -v`
|
|
212
|
+
5. Envie um PR
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Licença
|
|
217
|
+
|
|
218
|
+
MIT — use, modifique e distribua livremente. Atribuição apreciada.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Contato
|
|
223
|
+
|
|
224
|
+
**Marcos Malveira** — mvmlima@hotmail.com
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
**Prefira dados corrigidos a dados atrasados.** 🧬📈
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# nowcasting-sus
|
|
2
|
+
|
|
3
|
+
[](https://github.com/MVMLima/nowcasting-sus/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/nowcasting-sus/)
|
|
5
|
+
[](https://pypi.org/project/nowcasting-sus/)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**Nowcasting bayesiano para dados do SINAN** — correção de atraso de notificação em tempo real usando PyMC.
|
|
9
|
+
|
|
10
|
+
> ⚕️ Desenvolvido no Departamento de Vigilância em Saúde da Secretaria de Estado de Saúde do Acre
|
|
11
|
+
> Agora open source para qualquer equipe de vigilância do Brasil.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## O Problema
|
|
16
|
+
|
|
17
|
+
Os dados do SINAN chegam **atrasados**. Não por falha do sistema — é da natureza da notificação epidemiológica:
|
|
18
|
+
|
|
19
|
+
1. Um caso ocorre (data de início dos sintomas)
|
|
20
|
+
2. Leva **dias ou semanas** até ser digitado no SINAN
|
|
21
|
+
3. Se você olha o número **bruto** de hoje, está sempre subestimando a realidade
|
|
22
|
+
|
|
23
|
+
O **nowcasting** (ou "previsão do presente") resolve isso: modela o padrão histórico de atraso de notificação e estima quantos casos **já ocorreram mas ainda não foram notificados**.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Instalação
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install nowcasting-sus
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Requisitos:** Python ≥ 3.10, PyMC ≥ 5.0
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Uso Rápido
|
|
38
|
+
|
|
39
|
+
### Python
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from nowcasting_sus.data import load_sinan, prepare_matrix
|
|
43
|
+
from nowcasting_sus.models import NowcastingModel, NowcastingModelDOW
|
|
44
|
+
from nowcasting_sus.plot import plot_nowcasting, plot_panel
|
|
45
|
+
|
|
46
|
+
# 1. Carregar dados do SINAN (qualquer CSV com DT_SIN_PRI e DT_NOTIFIC)
|
|
47
|
+
df = load_sinan("dados_sinan.csv")
|
|
48
|
+
|
|
49
|
+
# 2. Preparar matriz onset × delay para o modelo
|
|
50
|
+
nmat, dates, obs_t, obs_d, counts = prepare_matrix(df)
|
|
51
|
+
|
|
52
|
+
# 3. Ajustar modelo nowcasting
|
|
53
|
+
modelo = NowcastingModel()
|
|
54
|
+
idata = modelo.fit(obs_t, obs_d, counts, T=nmat.shape[0], D=nmat.shape[1])
|
|
55
|
+
|
|
56
|
+
# 4. Obter estimativas corrigidas
|
|
57
|
+
median, low, high = modelo.get_nowcast_ci()
|
|
58
|
+
# median[t] = casos esperados no dia t (já corrigindo atraso)
|
|
59
|
+
|
|
60
|
+
# 5. Visualizar
|
|
61
|
+
fig = plot_nowcasting(nmat, median, low, high, dates)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Modelo com Efeito de Dia da Semana (DOW)
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import pandas as pd
|
|
68
|
+
|
|
69
|
+
modelo_dow = NowcastingModelDOW()
|
|
70
|
+
dow = pd.to_datetime(dates).dayofweek.values # 0=segunda .. 6=domingo
|
|
71
|
+
idata = modelo_dow.fit(obs_t, obs_d, counts, T=T, D=nmat.shape[1], dow=dow)
|
|
72
|
+
|
|
73
|
+
# Ver efeito de cada dia da semana
|
|
74
|
+
print(modelo_dow.get_dow_effect())
|
|
75
|
+
# Exemplo: {'Seg': 1.12, 'Dom': 0.65} → domingo tem 35% menos notificações
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### CLI — Relatório HTML
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
nowcasting-report dados_sinan.csv --agravo "Chikungunya" --uf "Bahia" -o boletim.html
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Gera um boletim epidemiológico completo com:
|
|
85
|
+
- Resumo executivo (observado × estimado × não notificados)
|
|
86
|
+
- Tabela com estimativas dos últimos 14 dias
|
|
87
|
+
- Interpretação automática dos resultados
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Modelos
|
|
92
|
+
|
|
93
|
+
| Modelo | Descrição | Quando usar |
|
|
94
|
+
|--------|-----------|-------------|
|
|
95
|
+
| `NowcastingModel` | Random Walk 1ª ordem + Negative Binomial | Uso geral, padrão |
|
|
96
|
+
| `NowcastingModelDOW` | RW1 + NB + efeito dia da semana (ZeroSumNormal) | Quando há padrão claro de menor notificação em fins de semana |
|
|
97
|
+
|
|
98
|
+
### Parâmetros Ajustáveis
|
|
99
|
+
|
|
100
|
+
| Parâmetro | Default | Descrição |
|
|
101
|
+
|-----------|---------|-----------|
|
|
102
|
+
| `sigma_rw` | 0.1 | Suavidade da tendência temporal (menor = mais suave) |
|
|
103
|
+
| `alpha_nb` | 10.0 | Dispersão da NegativeBinomial (maior = menos dispersão) |
|
|
104
|
+
| `alpha_scale` | 3.0 | Escala do prior Dirichlet para distribuição de atraso |
|
|
105
|
+
| `sigma_dow` | 0.3 | (DOW) Magnitude do efeito dia da semana |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Estrutura do Pacote
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
nowcasting-sus/
|
|
113
|
+
├── nowcasting_sus/
|
|
114
|
+
│ ├── __init__.py # Exporta API pública
|
|
115
|
+
│ ├── data.py # Carga e preparação de dados SINAN
|
|
116
|
+
│ ├── models.py # Modelos PyMC (NowcastingModel, NowcastingModelDOW)
|
|
117
|
+
│ ├── plot.py # Visualização (curva, painel, efeito DOW)
|
|
118
|
+
│ ├── report.py # Geração de boletim HTML
|
|
119
|
+
│ └── cli.py # Interface de linha de comando
|
|
120
|
+
├── tests/ # Suite de testes (65+ testes, pytest)
|
|
121
|
+
├── examples/ # Exemplos de uso
|
|
122
|
+
├── .github/workflows/ # CI/CD automatizado
|
|
123
|
+
└── pyproject.toml # Configuração do pacote
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Exemplo Completo
|
|
129
|
+
|
|
130
|
+
Veja [`examples/example_real.py`](examples/example_real.py) para um pipeline completo que:
|
|
131
|
+
1. Carrega dados do SINAN
|
|
132
|
+
2. Ajusta modelo base e modelo DOW
|
|
133
|
+
3. Gera gráfico de painel 2×3
|
|
134
|
+
4. Exporta relatório HTML
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## API Detalhada
|
|
139
|
+
|
|
140
|
+
### `data.load_sinan(filepath, date_onset, date_notif, max_delay, min_year)`
|
|
141
|
+
Carrega CSV do SINAN, valida colunas, converte datas, calcula delay e filtra registros inválidos.
|
|
142
|
+
|
|
143
|
+
### `data.prepare_matrix(df, max_delay)`
|
|
144
|
+
Converte DataFrame em matriz `T × D` (dias de onset × dias de delay) para o modelo.
|
|
145
|
+
|
|
146
|
+
### `models.NowcastingModel.fit(obs_t, obs_d, counts, T, D, draws, tune, chains)`
|
|
147
|
+
Ajusta o modelo MCMC via PyMC. Retorna `arviz.InferenceData`.
|
|
148
|
+
|
|
149
|
+
### `models.NowcastingModel.get_nowcast_ci(prob=0.95)`
|
|
150
|
+
Retorna `(mediana, inferior, superior)` — estimativas nowcast na escala original (casos/dia).
|
|
151
|
+
|
|
152
|
+
### `plot.plot_nowcasting(...)`, `plot.plot_panel(...)`, `plot.plot_dow_effect(...)`
|
|
153
|
+
Funções de visualização. Todas retornam `matplotlib.figure.Figure`.
|
|
154
|
+
|
|
155
|
+
### `report.generate_report(...)`
|
|
156
|
+
Gera boletim epidemiológico em HTML. Aceita parâmetros personalizados (agravo, UF, CID).
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Contribuindo
|
|
161
|
+
|
|
162
|
+
Contribuições são bem-vindas!
|
|
163
|
+
|
|
164
|
+
1. Fork o repositório
|
|
165
|
+
2. Crie uma branch: `git checkout -b minha-feature`
|
|
166
|
+
3. Faça suas alterações
|
|
167
|
+
4. Execute os testes: `pytest tests/ -v`
|
|
168
|
+
5. Envie um PR
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Licença
|
|
173
|
+
|
|
174
|
+
MIT — use, modifique e distribua livremente. Atribuição apreciada.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Contato
|
|
179
|
+
|
|
180
|
+
**Marcos Malveira** — mvmlima@hotmail.com
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
**Prefira dados corrigidos a dados atrasados.** 🧬📈
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Nowcasting SUS — correção de atraso de notificação para dados do SINAN.
|
|
2
|
+
|
|
3
|
+
Nowcasting bayesiano que estima o número real de casos em tempo real,
|
|
4
|
+
corrigindo o atraso entre a data de início dos sintomas e a notificação.
|
|
5
|
+
|
|
6
|
+
Módulos disponíveis:
|
|
7
|
+
- data: carga e preparação de dados SINAN
|
|
8
|
+
- models: modelos PyMC (base e com efeito dia da semana)
|
|
9
|
+
- plot: visualização dos resultados
|
|
10
|
+
- report: geração de boletim epidemiológico
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
from importlib.metadata import version as _version
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"load_sinan",
|
|
23
|
+
"prepare_matrix",
|
|
24
|
+
"NowcastingModel",
|
|
25
|
+
"NowcastingModelDOW",
|
|
26
|
+
"plot_nowcasting",
|
|
27
|
+
"plot_panel",
|
|
28
|
+
"plot_dow_effect",
|
|
29
|
+
"generate_report",
|
|
30
|
+
"setup_logging",
|
|
31
|
+
"__version__",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
__version__ = _version("nowcasting-sus")
|
|
36
|
+
except Exception:
|
|
37
|
+
__version__ = "1.0.0"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def setup_logging(
|
|
41
|
+
level: int | str | None = None,
|
|
42
|
+
fmt: str | None = None,
|
|
43
|
+
) -> logging.Logger:
|
|
44
|
+
"""Configura o logger do pacote ``nowcasting_sus``.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
level : int or str, optional
|
|
49
|
+
Nível de logging. Pode ser ``logging.DEBUG``, ``"DEBUG"``, ``"INFO"``, etc.
|
|
50
|
+
Se ``None``, usa a variável de ambiente ``NOWCASTING_LOG_LEVEL`` ou ``INFO``.
|
|
51
|
+
fmt : str, optional
|
|
52
|
+
Formato da mensagem. Se ``None``, usa o formato padrão.
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
logging.Logger
|
|
57
|
+
Logger configurado.
|
|
58
|
+
"""
|
|
59
|
+
logger = logging.getLogger("nowcasting_sus")
|
|
60
|
+
|
|
61
|
+
# Só adiciona handler se ainda não houver
|
|
62
|
+
if logger.handlers:
|
|
63
|
+
return logger
|
|
64
|
+
|
|
65
|
+
if level is None:
|
|
66
|
+
level = os.environ.get("NOWCASTING_LOG_LEVEL", "INFO").upper()
|
|
67
|
+
|
|
68
|
+
if isinstance(level, str):
|
|
69
|
+
level = getattr(logging, level.upper(), logging.INFO)
|
|
70
|
+
|
|
71
|
+
logger.setLevel(level)
|
|
72
|
+
|
|
73
|
+
if fmt is None:
|
|
74
|
+
fmt = "[%(asctime)s] %(levelname)-8s %(name)s: %(message)s"
|
|
75
|
+
|
|
76
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
77
|
+
handler.setLevel(level)
|
|
78
|
+
handler.setFormatter(logging.Formatter(fmt, datefmt="%Y-%m-%d %H:%M:%S"))
|
|
79
|
+
logger.addHandler(handler)
|
|
80
|
+
|
|
81
|
+
return logger
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Configura logging na importação do pacote
|
|
85
|
+
_logger = setup_logging()
|
|
86
|
+
|
|
87
|
+
from nowcasting_sus.data import load_sinan, prepare_matrix # noqa: E402
|
|
88
|
+
from nowcasting_sus.models import NowcastingModel, NowcastingModelDOW # noqa: E402
|
|
89
|
+
from nowcasting_sus.plot import plot_nowcasting, plot_panel, plot_dow_effect # noqa: E402
|
|
90
|
+
from nowcasting_sus.report import generate_report # noqa: E402
|