# detect_all_events function: cgmguru and iglu-compatible event preprocessing

## Relationship to iglu

`cgmguru::detect_all_events()` is an independent C++/Rcpp implementation of event calculation and CGM summary output. Its preprocessing is designed to be compatible with the event grid semantics used by `iglu`: subject-specific reading intervals, a midnight-aligned full-day grid, interpolation up to `inter_gap`, removal of larger gap-masked rows, and segment-wise event classification.

When `reading_minutes` is omitted or `NULL`, cgmguru calculates it automatically per subject from the median positive timestamp spacing in the input data.

The `iglu` package is used here as a formal reference, source of public example datasets, and comparison target. cgmguru does not call `iglu` at runtime for its core algorithms.

## Datasets

We use two CGM example datasets shipped with `iglu`:

- `example_data_5_subject`: 5 subjects
- `example_data_hall`: 19 subjects

    data(example_data_5_subject, package = "iglu")
    data(example_data_hall, package = "iglu")

    # Base-R summaries (no external dependencies)
    summary_5 <- data.frame(
      rows = nrow(example_data_5_subject),
      subjects = length(unique(example_data_5_subject$id)),
      time_min = min(example_data_5_subject$time),
      time_max = max(example_data_5_subject$time),
      gl_min = min(example_data_5_subject$gl, na.rm = TRUE),
      gl_max = max(example_data_5_subject$gl, na.rm = TRUE)
    )

    summary_5
    #>    rows subjects            time_min            time_max gl_min gl_max
    #> 1 13866        5 2015-02-24 17:31:29 2015-06-19 08:59:36     50    400

    cat("Note: The 'iglu' package is not available; vignette examples are skipped.\n")

## iglu: episode_calculation

`iglu::episode_calculation()` identifies hypo/hyperglycemia episodes.

    iglu_episodes_5 <- iglu::episode_calculation(
      data = example_data_5_subject
    )
    print(iglu_episodes_5)
    #> # A tibble: 35 × 7
    #>    id        type  level avg_ep_per_day avg_ep_duration avg_ep_gl total_episodes
    #>    <fct>     <chr> <chr>          <dbl>           <dbl>     <dbl>          <dbl>
    #>  1 Subject 1 hypo  lv1           0.0899            35        68.6              1
    #>  2 Subject 1 hypo  lv2           0                  0        NA                0
    #>  3 Subject 1 hypo  exte…         0                  0        NA                0
    #>  4 Subject 1 hyper lv1           1.44              80.3     200.              16
    #>  5 Subject 1 hyper lv2           0.180             30       264.               2
    #>  6 Subject 1 hypo  lv1_…         0.0899            35        68.6              1
    #>  7 Subject 1 hyper lv1_…         1.26              79.6     195.              14
    #>  8 Subject 2 hypo  lv1           0                  0        NA                0
    #>  9 Subject 2 hypo  lv2           0                  0        NA                0
    #> 10 Subject 2 hypo  exte…         0                  0        NA                0
    #> # ℹ 25 more rows

    iglu_episodes_hall <- iglu::episode_calculation(
      data = example_data_hall
    )
    print(iglu_episodes_hall)
    #> # A tibble: 133 × 7
    #>    id        type  level avg_ep_per_day avg_ep_duration avg_ep_gl total_episodes
    #>    <chr>     <chr> <chr>          <dbl>           <dbl>     <dbl>          <dbl>
    #>  1 1636-69-… hypo  lv1            0.468            15        68.1              3
    #>  2 1636-69-… hypo  lv2            0                 0        NA                0
    #>  3 1636-69-… hypo  exte…          0                 0        NA                0
    #>  4 1636-69-… hyper lv1            0.623            57.5     201.               4
    #>  5 1636-69-… hyper lv2            0                 0        NA                0
    #>  6 1636-69-… hypo  lv1_…          0.468            15        68.1              3
    #>  7 1636-69-… hyper lv1_…          0.623            57.5     201.               4
    #>  8 1636-69-… hypo  lv1            0                 0        NA                0
    #>  9 1636-69-… hypo  lv2            0                 0        NA                0
    #> 10 1636-69-… hypo  exte…          0                 0        NA                0
    #> # ℹ 123 more rows

## cgmguru: detect_all_events

    all_events_5 <- detect_all_events(example_data_5_subject)
    print(all_events_5)
    #> $events_long_df
    #> # A tibble: 40 × 6
    #>    id        type  level    total_episodes avg_ep_per_day avg_episode_duration…¹
    #>    <chr>     <chr> <chr>             <int>          <dbl>                  <dbl>
    #>  1 Subject 1 hypo  lv1                   1           0.09                      0
    #>  2 Subject 1 hypo  lv2                   0           0                         0
    #>  3 Subject 1 hypo  extended              0           0                         0
    #>  4 Subject 1 hypo  lv1_excl              1           0.09                      0
    #>  5 Subject 1 hyper lv1                  16           1.44                      0
    #>  6 Subject 1 hyper lv2                   2           0.18                      0
    #>  7 Subject 1 hyper extended              0           0                         0
    #>  8 Subject 1 hyper lv1_excl             14           1.26                      0
    #>  9 Subject 2 hypo  lv1                   0           0                         0
    #> 10 Subject 2 hypo  lv2                   0           0                         0
    #> # ℹ 30 more rows
    #> # ℹ abbreviated name: ¹​avg_episode_duration_below_54
    #>
    #> $summary_df
    #> # A tibble: 5 × 22
    #>   id         TIR  TITR TBR70  TBR54 TAR180 TAR250    CV    SD mean_glucose   GMI
    #>   <chr>    <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl>        <dbl> <dbl>
    #> 1 Subject…  91.8 74.0  0.156 0        8.08  0.375 0.267  33.0         123.  6.26
    #> 2 Subject…  25.8  3.28 0     0       74.2  26.5   0.241  52.7         219.  8.54
    #> 3 Subject…  81.3 49.8  0.316 0       18.4   5.44  0.290  44.5         154.  6.98
    #> 4 Subject…  94.9 67.4  0.326 0.0271   4.75  0     0.224  29.0         130.  6.41
    #> 5 Subject…  62.0 29.6  0.102 0       37.9  11.5   0.335  58.4         175.  7.49
    #> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear <dbl>,
    #> #   hypo_lv1_event_count <int>, hypo_lv2_event_count <int>,
    #> #   hypo_extended_event_count <int>, hypo_lv1_excl_event_count <int>,
    #> #   hyper_lv1_event_count <int>, hyper_lv2_event_count <int>,
    #> #   hyper_extended_event_count <int>, hyper_lv1_excl_event_count <int>

    all_events_hall <- detect_all_events(example_data_hall)
    print(all_events_hall)
    #> $events_long_df
    #> # A tibble: 152 × 6
    #>    id          type  level  total_episodes avg_ep_per_day avg_episode_duration…¹
    #>    <chr>       <chr> <chr>           <int>          <dbl>                  <dbl>
    #>  1 1636-69-001 hypo  lv1                 3           0.47                      0
    #>  2 1636-69-001 hypo  lv2                 0           0                         0
    #>  3 1636-69-001 hypo  exten…              0           0                         0
    #>  4 1636-69-001 hypo  lv1_e…              3           0.47                      0
    #>  5 1636-69-001 hyper lv1                 4           0.62                      0
    #>  6 1636-69-001 hyper lv2                 0           0                         0
    #>  7 1636-69-001 hyper exten…              0           0                         0
    #>  8 1636-69-001 hyper lv1_e…              4           0.62                      0
    #>  9 1636-69-026 hypo  lv1                 0           0                         0
    #> 10 1636-69-026 hypo  lv2                 0           0                         0
    #> # ℹ 142 more rows
    #> # ℹ abbreviated name: ¹​avg_episode_duration_below_54
    #>
    #> $summary_df
    #> # A tibble: 19 × 22
    #>    id        TIR  TITR TBR70  TBR54 TAR180 TAR250    CV    SD mean_glucose   GMI
    #>    <chr>   <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl>        <dbl> <dbl>
    #>  1 1636-6…  96.8  87.4 0.703 0       2.54    0    0.252  27.2        108.   5.90
    #>  2 1636-6…  99.6  86.4 0.110 0       0.329   0    0.173  19.9        115.   6.06
    #>  3 1636-6…  99.7  96.9 0.112 0       0.168   0    0.140  15.1        108.   5.90
    #>  4 1636-6…  97.8  89.4 0.901 0       1.27    0    0.222  24.3        109.   5.92
    #>  5 1636-6… 100    96.6 0     0       0       0    0.141  14.6        103.   5.78
    #>  6 1636-6… 100    94.4 0     0       0       0    0.148  16.7        113.   6.02
    #>  7 1636-7…  97.2  89.4 1.50  0.214   1.34    0    0.196  22.1        113.   6.01
    #>  8 1636-7…  96.9  85.3 2.82  0       0.325   0    0.197  22.5        114.   6.03
    #>  9 2133-0…  94.0  73.8 0.898 0       5.11    0    0.226  28.6        127.   6.34
    #> 10 2133-0…  97.7  94.0 1.17  0       1.17    0    0.176  19.2        109.   5.92
    #> 11 2133-0…  99.8  91.3 0     0       0.164   0    0.187  20.4        110.   5.93
    #> 12 2133-0…  88.3  80.2 0     0      11.7     1.85 0.311  39.3        127.   6.34
    #> 13 2133-0…  98.5  89.5 1.42  0.0548  0.110   0    0.210  22.4        107.   5.86
    #> 14 2133-0…  91.1  70.5 0.665 0       8.26    0    0.247  32.1        130.   6.42
    #> 15 2133-0…  93.3  90.5 6.68  0.657   0       0    0.202  20.0         99.3  5.69
    #> 16 2133-0…  94.6  93.7 5.42  0       0       0    0.146  13.3         91.1  5.49
    #> 17 2133-0…  99.3  95.0 0.421 0.0527  0.316   0    0.165  16.8        102.   5.74
    #> 18 2133-0…  92.9  81.0 5.70  0       1.39    0    0.249  26.8        108.   5.89
    #> 19 2133-0…  94.7  86.9 4.56  0.138   0.738   0    0.229  23.9        104.   5.81
    #> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear <dbl>,
    #> #   hypo_lv1_event_count <int>, hypo_lv2_event_count <int>,
    #> #   hypo_extended_event_count <int>, hypo_lv1_excl_event_count <int>,
    #> #   hyper_lv1_event_count <int>, hyper_lv2_event_count <int>,
    #> #   hyper_extended_event_count <int>, hyper_lv1_excl_event_count <int>

## Speed comparison

We compare performance using `microbenchmark` on both datasets. Each benchmark contrasts `iglu::episode_calculation()` with `cgmguru::detect_all_events()`.

    library(microbenchmark)
    library(iglu)

    # example_data_5_subject
    bench_5 <- microbenchmark(
      episode_calculation = iglu::episode_calculation(example_data_5_subject),
      detect_all_events   = cgmguru::detect_all_events(example_data_5_subject),
      times = 10,
      unit = "ms"
    )
    print(bench_5)
    #> Unit: milliseconds
    #>                 expr        min         lq       mean     median       uq
    #>  episode_calculation 297.762746 299.478760 303.789217 300.198330 301.5620
    #>    detect_all_events   3.132072   3.253965   3.442713   3.303165   3.4645
    #>         max neval cld
    #>  331.663719    10  a
    #>    4.653131    10   b

    # example_data_hall (all subjects)
    bench_hall <- microbenchmark(
      episode_calculation = iglu::episode_calculation(example_data_hall),
      detect_all_events   = cgmguru::detect_all_events(example_data_hall),
      times = 10,
      unit = "ms"
    )
    print(bench_hall)
    #> Unit: milliseconds
    #>                 expr        min         lq       mean     median         uq
    #>  episode_calculation 844.767280 849.185891 876.747067 865.876704 918.930663
    #>    detect_all_events   8.822298   9.129183   9.343068   9.146034   9.299948
    #>        max neval cld
    #>  927.73217    10  a
    #>   11.27352    10   b

    cat("Note: Installed 'iglu' version has a different 'episode_calculation' API; iglu examples are skipped.\n")

## References

- Broll S, Urbanek J, Buchanan D, Chun E, Muschelli J, Punjabi N, and Gaynanova I. Interpreting blood glucose data with R package iglu. PLoS One. 2021;16(4):e0248560. doi:10.1371/journal.pone.0248560.
- Chun E, Fernandes JN, and Gaynanova I. An Update on the iglu Software Package for Interpreting Continuous Glucose Monitoring Data. Diabetes Technology & Therapeutics. 2024;26(12):939-950. doi:10.1089/dia.2024.0154.
- iglu package site and citation guidance: https://irinagain.github.io/iglu/ and https://irinagain.github.io/iglu/authors.html.