> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encodebox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration

> Migrate from query_event / filter_event to EventFrame and Cohort.

The pre-unified exports (`query_event`, `filter_event`, cohort helpers, …) remain importable from `encodebox` and keep their signatures. Each call emits a `DeprecationWarning` naming the replacement.

```python theme={null}
import warnings
warnings.filterwarnings("default", category=DeprecationWarning, module="encodebox")
```

## Quick map

| Legacy                                        | Replacement                                                                                               |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `query_event(...)`                            | `db.diagnosis.matching(...)`                                                                              |
| `filter_event(..., occurrence, gap, limit)`   | `EventFrame.occurring(...)` / `.first_per_patient()`                                                      |
| `query_enrollment(...)`                       | `Database(...).enrollment`                                                                                |
| `compute_followup(...)`                       | `EventFrame.with_followup(...)`                                                                           |
| `compute_age(...)`                            | `EventFrame.with_age(...)`                                                                                |
| `derive_continuous_enrollment(...)`           | `Database(...).enrollment` + EventFrame verbs                                                             |
| `inclusion_criteria_*`                        | `Cohort(...).include(...)` / `.exclude(...)`                                                              |
| `generate_final_cohort` / `cohort_attrition*` | `Cohort(...).to_df()` / `.attrition()`                                                                    |
| `rwe_study(...)`                              | `Cohort(...)`                                                                                             |
| `compute_prevalence` / `compute_incidence`    | Still `eb.compute_prevalence` / `eb.compute_incidence` (deprecated; no EventFrame/Cohort replacement yet) |

## Semantic traps

### Occurrence counting

|                     | Legacy `filter_event` | New `EventFrame.occurring` |
| ------------------- | --------------------- | -------------------------- |
| Default count       | **Rows**              | **Distinct dates**         |
| Same-day duplicates | Count as 2            | Count as 1                 |

Opt into legacy-style row counting with `occurring(..., count_distinct_on=None)`.

### Gap definition

|                             | Legacy `gap=`                 | New `gap_days=`                           |
| --------------------------- | ----------------------------- | ----------------------------------------- |
| Meaning                     | Span: `max(date) − min(date)` | Consecutive distinct-date gaps (`lead()`) |
| SPAN\_TRAP (Jan 1/11/21/31) | **kept** at `gap=30`          | **dropped** at `gap_days=30`              |

<Warning>
  Do not assume `gap=30` and `gap_days=30` select the same patients.
</Warning>

### Index date after a gap filter

After `occurring(gap_days=...)`, `first_per_patient()` / `with_index_date()` use the **first date of the first qualifying consecutive pair**, not the earliest event on the patient.

## Side-by-side examples

### Query + filter → EventFrame

```python theme={null}
# Legacy
events = eb.query_event(
    connector="postgres_local_sentinel",
    code=[["E11"]], code_type=["10"], domain=["diagnosis"],
    match=["start with"], engine=conn,
)
filtered = eb.filter_event(events, occurrence="[2,]", gap=30, limit="first")

# New
db = eb.connect(..., connector="postgres_local_sentinel")
filtered = (
    db.diagnosis
    .matching("E11", code_type="10", match="starts_with")
    .occurring(at_least=2, gap_days=30)
    .with_index_date()
    .first_per_patient()
)
```

### Inclusion ladder → Cohort

```python theme={null}
cohort = (
    eb.Cohort("study", database=db)
    .entry(filtered, index="first")
    .include(db.demographic.age_at_index(18, 89))
    .include(db.enrollment.covering_index(days_before=365, days_after=0))
)
attrition = cohort.attrition()
final = cohort.to_df()
```

## What stays

* Connector registry (`register_connector`, `list_connectors`, …)
* `connect` without `connector=` still returns an engine
* `domain_code_type_map`
* Sentinel CDM YAML connectors unchanged
