# LUCID Serial Tutorial: 6 Consecutive Parallel Stages with Monotone Missingness

## 1) Why This Tutorial

Monotone missingness describes a study where, once a subject drops out at some stage of a longitudinal or multi-stage design, they stay missing at every later stage too – a common real-world pattern (e.g. cohort attrition over repeated visits), as opposed to sporadic missingness that comes and goes independently at each stage. A 6-stage serial model, with each stage itself a 2-layer parallel submodel, is a large, deeply-nested architecture: this tutorial exists to confirm that the package’s serial fitting and missing-data handling actually hold up at that scale and under a realistic, worsening missingness pattern – not to teach a new API. Every function it calls (`estimate_lucid()`, `summary()`, `boot_lucid()`) is demonstrated in depth in the 3-model tutorials; this file is a stress test of the same functions on a harder topology.

This tutorial demonstrates a stress-test architecture that mirrors a real production pattern:

- LUCID in serial with 6 consecutive stages
- each stage is a parallel submodel with 2 omics layers
- K = 2 for every layer in every stage
- no penalties (`Rho_G = Rho_Z_Mu = Rho_Z_Cov = 0`)

Missing-data design in this tutorial:

- stage-wise listwise missingness increases with stage
- once a subject is listwise-missing at stage `s`, it stays missing at all later stages (monotone pattern)

Goal: verify this design runs with the current missing-data mechanism and inspect stage-wise missingness summaries.

## 2) Setup

    library(LUCIDus)

## 3) Simulate Associated Data (Not Independent Noise)

Key design choices:

1. `G`, `CoG`, `CoY` are correlated.
2. Stage latent signals are serially dependent (`stage s` depends on `stage s-1`).
3. Each stage-layer `Z` is generated from latent stage signal + exposures + shared component.
4. `Y` is associated with final-stage latent structure and exposure/covariates.

    make_serial_six_parallel_data <- function(n = 60, pG = 5, pZ = 3, seed = 5252) {
      set.seed(seed)

      # Exposure block
      G <- matrix(rnorm(n * pG), nrow = n, ncol = pG)
      colnames(G) <- paste0("G", seq_len(pG))

      # Covariates linked to exposures (induced association)
      CoG <- cbind(
        cov1 = G[, 1] + rnorm(n, sd = 0.25),
        cov2 = G[, 2] - 0.5 * G[, 3] + rnorm(n, sd = 0.25)
      )
      CoY <- CoG

      # Serial latent signals
      eta <- matrix(0, nrow = n, ncol = 6)
      x <- matrix(0, nrow = n, ncol = 6)

      eta[, 1] <- 0.9 * G[, 1] - 0.7 * G[, 2] + 0.4 * CoG[, 1] + rnorm(n, sd = 0.5)
      x[, 1] <- as.numeric(eta[, 1] > median(eta[, 1]))

      for (s in 2:6) {
        eta[, s] <- 0.7 * as.numeric(scale(eta[, s - 1])) +
          0.5 * G[, 1] - 0.4 * G[, 3] + 0.35 * x[, s - 1] + rnorm(n, sd = 0.6)
        x[, s] <- as.numeric(eta[, s] > median(eta[, s]))
      }

      # 6 stages; each stage has 2 parallel layers
      Z <- vector("list", 6)
      names(Z) <- paste0("stage", seq_len(6))

      for (s in seq_len(6)) {
        shared <- rnorm(n, sd = 0.35)

        layer1 <- cbind(
          1.2 * x[, s] + 0.5 * G[, 1] + shared + rnorm(n, sd = 0.45),
          0.9 * x[, s] - 0.3 * G[, 2] + shared + rnorm(n, sd = 0.45),
          0.7 * x[, s] + 0.4 * G[, 4] + shared + rnorm(n, sd = 0.45)
        )

        layer2 <- cbind(
          -1.0 * x[, s] + 0.45 * G[, 2] + shared + rnorm(n, sd = 0.45),
          -0.8 * x[, s] - 0.35 * G[, 1] + shared + rnorm(n, sd = 0.45),
          -0.6 * x[, s] + 0.30 * G[, 5] + shared + rnorm(n, sd = 0.45)
        )

        colnames(layer1) <- paste0("s", s, "_L1_f", seq_len(pZ))
        colnames(layer2) <- paste0("s", s, "_L2_f", seq_len(pZ))

        Z[[s]] <- list(layer1 = layer1, layer2 = layer2)
      }

      # Outcome associated with final latent stage + exposure/covariate terms
      Y <- 0.8 * x[, 6] + 0.45 * G[, 1] - 0.25 * G[, 2] + 0.35 * CoY[, 2] + rnorm(n, sd = 0.7)

      list(G = G, Z = Z, Y = as.numeric(Y), CoG = CoG, CoY = CoY)
    }

    d <- make_serial_six_parallel_data(seed = 5252)
    str(d, max.level = 2)

    ## List of 5
    ##  $ G  : num [1:60, 1:5] 3.026 0.713 1.496 -0.296 1.384 ...
    ##   ..- attr(*, "dimnames")=List of 2
    ##  $ Z  :List of 6
    ##   ..$ stage1:List of 2
    ##   ..$ stage2:List of 2
    ##   ..$ stage3:List of 2
    ##   ..$ stage4:List of 2
    ##   ..$ stage5:List of 2
    ##   ..$ stage6:List of 2
    ##  $ Y  : num [1:60] 2.016 0.429 1.026 1.21 0.679 ...
    ##  $ CoG: num [1:60, 1:2] 3.148 1.039 0.974 -0.544 1.125 ...
    ##   ..- attr(*, "dimnames")=List of 2
    ##  $ CoY: num [1:60, 1:2] 3.148 1.039 0.974 -0.544 1.125 ...
    ##   ..- attr(*, "dimnames")=List of 2

## 4) Inject Monotone Stage-Wise Missingness

Policy encoded here:

- listwise-missing row counts by stage: `0, 4, 8, 12, 16, 20`
- if subject `i` is listwise missing at stage `s`, then subject `i` is also listwise missing at all later stages
- add light sporadic missingness that also increases with stage

    apply_monotone_missingness <- function(d, pZ = 3) {
      listwise_n_by_stage <- c(0, 4, 8, 12, 16, 20)

      for (s in seq_len(6)) {
        if (listwise_n_by_stage[s] > 0) {
          miss_rows <- seq_len(listwise_n_by_stage[s])
          d$Z[[s]]$layer1[miss_rows, ] <- NA
          d$Z[[s]]$layer2[miss_rows, ] <- NA
        }

        spor_rows <- seq_len(min(nrow(d$G), s + 1))
        d$Z[[s]]$layer1[spor_rows, 1] <- NA
        d$Z[[s]]$layer2[spor_rows, pZ] <- NA
      }

      d$listwise_n_by_stage <- listwise_n_by_stage
      d
    }

    d_miss <- apply_monotone_missingness(d)
    d_miss$listwise_n_by_stage

    ## [1]  0  4  8 12 16 20

## 5) Fit Serial Model (6 Parallel Stages, K = 2 per Layer)

Notes:

- no penalties (`Rho_* = 0`)
- stage topology is `list(list(2,2), ..., list(2,2))` with length 6

    K6 <- replicate(6, list(2, 2), simplify = FALSE)

    set.seed(5252)
    serial_fit <- estimate_lucid(
      lucid_model = "serial",
      G = d_miss$G,
      Z = d_miss$Z,
      Y = d_miss$Y,
      CoG = d_miss$CoG,
      CoY = d_miss$CoY,
      family = "normal",
      K = K6,
      Rho_G = 0,
      Rho_Z_Mu = 0,
      Rho_Z_Cov = 0,
      max_itr = 6,
      max_tot.itr = 36,
      tol = 1e-2,
      seed = 5252,
      verbose = FALSE
    )

    ## Fitting LUCID serial model (6 stages)...

    ##   Stage 1/6 (parallel) finished: log-likelihood = -349.251.

    ##   Stage 2/6 (parallel) finished: log-likelihood = -323.580.

    ##   Stage 3/6 (parallel) finished: log-likelihood = -296.120.

    ##   Stage 4/6 (parallel) finished: log-likelihood = -281.957.

    ##   Stage 5/6 (parallel) finished: log-likelihood = -252.147.

    ##   Stage 6/6 (parallel) finished: log-likelihood = -298.761.
    ## Finished LUCID serial model.

    class(serial_fit)

    ## [1] "lucid_serial"

    length(serial_fit$submodel)

    ## [1] 6

    sapply(serial_fit$submodel, class)

    ## [1] "lucid_parallel" "lucid_parallel" "lucid_parallel" "lucid_parallel"
    ## [5] "lucid_parallel" "lucid_parallel"

### 5.1) Verbose Logging Demo (`verbose = TRUE`)

This small extra fit demonstrates detailed per-iteration logging behavior for serial mode.

    K2 <- replicate(2, list(2, 2), simplify = FALSE)

    # Smaller two-stage subset to keep verbose demo fast.
    n_demo <- 30
    d_demo <- list(
      G = d_miss$G[1:n_demo, , drop = FALSE],
      Z = lapply(d_miss$Z[1:2], function(stage) {
        list(
          layer1 = stage$layer1[1:n_demo, , drop = FALSE],
          layer2 = stage$layer2[1:n_demo, , drop = FALSE]
        )
      }),
      Y = d_miss$Y[1:n_demo],
      CoG = d_miss$CoG[1:n_demo, , drop = FALSE],
      CoY = d_miss$CoY[1:n_demo, , drop = FALSE]
    )

    set.seed(5251)
    serial_fit_verbose <- estimate_lucid(
      lucid_model = "serial",
      G = d_demo$G,
      Z = d_demo$Z,
      Y = d_demo$Y,
      CoG = d_demo$CoG,
      CoY = d_demo$CoY,
      family = "normal",
      K = K2,
      Rho_G = 0,
      Rho_Z_Mu = 0,
      Rho_Z_Cov = 0,
      max_itr = 2,
      max_tot.itr = 8,
      tol = 1e-2,
      seed = 5251,
      verbose = TRUE
    )

    ## Fitting LUCID serial model (Stage 1/2)...
    ## Intializing imputation of missing values in 'Z' via LOD / sqrt(2)
    ##
    ## Intializing imputation of missing values in 'Z' via LOD / sqrt(2)
    ##
    ## Fitting LUCID in Parallel model (K = 2, Rho_G = 0, Rho_Z_Mu = 0, Rho_Z_Cov = 0) (K = 2, Rho_G = 0, Rho_Z_Mu = 0, Rho_Z_Cov = 0)
    ## iteration 1 : E-step finished.
    ## iteration 1: log-likelihood = -154.324
    ## iteration 2 : E-step finished.
    ## iteration 2: log-likelihood = -153.513

    ## Finished LUCID parallel model: log-likelihood = -153.513.
    ##
    ## Fitting LUCID serial model (Stage 2/2)...
    ## Fitting LUCID in Parallel model (K = 2, Rho_G = 0, Rho_Z_Mu = 0, Rho_Z_Cov = 0) (K = 2, Rho_G = 0, Rho_Z_Mu = 0, Rho_Z_Cov = 0)
    ## iteration 1 : E-step finished.
    ## iteration 1: log-likelihood = -187.426
    ## iteration 2 : E-step finished.
    ## iteration 2: log-likelihood = -187.240

    ## Finished LUCID parallel model: log-likelihood = -187.240.
    ##
    ## Success: LUCID serial model constructed!

## 6) Verify Stage-Wise Missingness Summary

We check that recorded listwise row counts match the monotone design.

    listwise_l1 <- vapply(serial_fit$missing_summary$stage, function(ms) {
      as.integer(ms$layer_summary$listwise_rows[1])
    }, integer(1))

    listwise_l2 <- vapply(serial_fit$missing_summary$stage, function(ms) {
      as.integer(ms$layer_summary$listwise_rows[2])
    }, integer(1))

    data.frame(
      stage = 1:6,
      expected_listwise = d_miss$listwise_n_by_stage,
      observed_layer1 = listwise_l1,
      observed_layer2 = listwise_l2
    )

    ##   stage expected_listwise observed_layer1 observed_layer2
    ## 1     1                 0               0               0
    ## 2     2                 4               4               4
    ## 3     3                 8               8               8
    ## 4     4                12              12              12
    ## 5     5                16              16              16
    ## 6     6                20              20              20

    stopifnot(all(listwise_l1 == d_miss$listwise_n_by_stage))
    stopifnot(all(listwise_l2 == d_miss$listwise_n_by_stage))
    stopifnot(all(diff(listwise_l1) >= 0))

## 7) Confirm Final-Stage Numerical Stability

Even with aggressive later-stage missingness, final-stage posterior probabilities should remain finite.

    last_stage <- serial_fit$submodel[[6]]

    all(is.finite(last_stage$inclusion.p[[1]]))

    ## [1] TRUE

    all(is.finite(last_stage$inclusion.p[[2]]))

    ## [1] TRUE

    stopifnot(all(is.finite(last_stage$inclusion.p[[1]])))
    stopifnot(all(is.finite(last_stage$inclusion.p[[2]])))

By stage 6, 20 of `nrow(d_miss$G)` subjects have been listwise-missing since stage 5 or earlier – carrying no direct omics information into this stage’s own likelihood term. The check above confirms that accumulated missingness alone doesn’t drive the posterior to `NaN`/`Inf`, which is the failure mode this section exists to rule out.

## 8) User-Facing Summary Output

The full `summary()` report – the same one every other vignette uses, unchanged by this model’s size – prints one feature-selection overview and one set of coefficient tables per stage. With 6 stages, each itself a 2-layer parallel submodel, this is the single largest printed report any vignette in this package produces; scanning it top to bottom confirms every stage’s missingness profile, selection, and coefficients all look sane before trusting the fit for anything downstream.

    summary(serial_fit)

    ##
    ## ====================================================
    ## LUCID Serial: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : normal
    ##   Number of observations : 60
    ##   Number of stages       : 6
    ##   Stage 1               : parallel (K = 2,2)
    ##   Stage 2               : parallel (K = 2,2)
    ##   Stage 3               : parallel (K = 2,2)
    ##   Stage 4               : parallel (K = 2,2)
    ##   Stage 5               : parallel (K = 2,2)
    ##   Stage 6               : parallel (K = 2,2)
    ##
    ## Missing-data profile by stage
    ##   Stage 1
    ##     Layer 1 listwise/sporadic rows : 0 / 2
    ##     Layer 2 listwise/sporadic rows : 0 / 2
    ##   Stage 2
    ##     Layer 1 listwise/sporadic rows : 4 / 0
    ##     Layer 2 listwise/sporadic rows : 4 / 0
    ##   Stage 3
    ##     Layer 1 listwise/sporadic rows : 8 / 0
    ##     Layer 2 listwise/sporadic rows : 8 / 0
    ##   Stage 4
    ##     Layer 1 listwise/sporadic rows : 12 / 0
    ##     Layer 2 listwise/sporadic rows : 12 / 0
    ##   Stage 5
    ##     Layer 1 listwise/sporadic rows : 16 / 0
    ##     Layer 2 listwise/sporadic rows : 16 / 0
    ##   Stage 6
    ##     Layer 1 listwise/sporadic rows : 20 / 0
    ##     Layer 2 listwise/sporadic rows : 20 / 0
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -1801.81
    ##   BIC                    : 4700.91
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Stage-wise detailed parameter estimates
    ##
    ## --- Stage 1 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 0 / 60 (0.0%)
    ##   Layer 1 sporadic rows : 2 / 60 (3.3%)
    ##   Layer 1 missing cells : 2 / 180 (1.1%)
    ##   Layer 2 listwise rows : 0 / 60 (0.0%)
    ##   Layer 2 sporadic rows : 2 / 60 (3.3%)
    ##   Layer 2 missing cells : 2 / 180 (1.1%)
    ##
    ## Feature selection overview
    ##   G features selected    : 5 / 5 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 5 / 5 (100.0%)
    ##     Layer 2              : 5 / 5 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -349.25
    ##   BIC                    : 911.41
    ##   Number of parameters   : 52
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s1_L1_f1 -0.25923098   1.7766753
    ## s1_L1_f2 -0.07087825   1.0212576
    ## s1_L1_f3  0.02796816   0.8084774
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s1_L2_f1  -1.2140937  0.21626421
    ## s1_L2_f2  -1.1713477  0.15440970
    ## s1_L2_f3  -0.5157522  0.02402461
    ##
    ## (2) E: intercept and odds ratio of being assigned to each latent cluster for each exposure for each layer
    ## Layer 1
    ##
    ##                            beta           OR
    ## (Intercept).cluster2 -2.1425889 1.173506e-01
    ## G1.cluster2           7.1860279 1.320846e+03
    ## G2.cluster2           3.3538197 2.861181e+01
    ## G3.cluster2          -4.0637126 1.718510e-02
    ## G4.cluster2          -1.7529953 1.732542e-01
    ## G5.cluster2           3.7899420 4.425383e+01
    ## cov1.cluster2         0.5203088 1.682547e+00
    ## cov2.cluster2        -6.7670005 1.151142e-03
    ##
    ## Layer 2
    ##
    ##                             beta           OR
    ## (Intercept).cluster2 -0.47824432 6.198707e-01
    ## G1.cluster2          -7.23309223 7.222839e-04
    ## G2.cluster2          10.62829698 4.128675e+04
    ## G3.cluster2          -2.94054526 5.283691e-02
    ## G4.cluster2           0.03096535 1.031450e+00
    ## G5.cluster2           0.25659661 1.292524e+00
    ## cov1.cluster2         3.11139707 2.245239e+01
    ## cov2.cluster2        -6.88871079 1.019227e-03
    ##
    ##
    ## --- Stage 2 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 4 / 60 (6.7%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 12 / 180 (6.7%)
    ##   Layer 2 listwise rows : 4 / 60 (6.7%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 12 / 180 (6.7%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -323.58
    ##   BIC                    : 819.12
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s2_L1_f1 -0.32476364   1.5770726
    ## s2_L1_f2  0.03621375   1.0082170
    ## s2_L1_f3  0.01434587   0.7739294
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s2_L2_f1  -0.9345513   0.1586644
    ## s2_L2_f2  -1.1641792   0.2081802
    ## s2_L2_f3  -0.6181080   0.1895868
    ##
    ## (2) E: intercept and odds ratio of being assigned to each latent cluster for each cluster from the previous serial stage (for each layer)
    ## Layer 1
    ##
    ##                                       beta          OR
    ## (Intercept).cluster2            -0.2345533  0.79092411
    ## Stage1.Layer1.cluster2.cluster2  3.0061229 20.20889549
    ## Stage1.Layer2.cluster2.cluster2 -2.9934749  0.05011299
    ##
    ## Layer 2
    ##
    ##                                       beta         OR
    ## (Intercept).cluster2             0.9763921 2.65486053
    ## Stage1.Layer1.cluster2.cluster2 -2.9861738 0.05048022
    ## Stage1.Layer2.cluster2.cluster2  1.5837012 4.87295814
    ##
    ##
    ## --- Stage 3 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 8 / 60 (13.3%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 24 / 180 (13.3%)
    ##   Layer 2 listwise rows : 8 / 60 (13.3%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 24 / 180 (13.3%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -296.12
    ##   BIC                    : 764.20
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s3_L1_f1  -0.3133371   1.5309424
    ## s3_L1_f2  -0.1356417   0.9311460
    ## s3_L1_f3   0.1989601   0.8251488
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s3_L2_f1  -0.6947063  0.36149336
    ## s3_L2_f2  -0.5201382 -0.04672601
    ## s3_L2_f3  -0.4876534  0.83015288
    ##
    ## (2) E: intercept and odds ratio of being assigned to each latent cluster for each cluster from the previous serial stage (for each layer)
    ## Layer 1
    ##
    ##                                       beta           OR
    ## (Intercept).cluster2             0.3386909 1.403110e+00
    ## Stage2.Layer1.cluster2.cluster2  6.0688887 4.322001e+02
    ## Stage2.Layer2.cluster2.cluster2 -6.7814384 1.134642e-03
    ##
    ## Layer 2
    ##
    ##                                       beta          OR
    ## (Intercept).cluster2            -4.1231203  0.01619391
    ## Stage2.Layer1.cluster2.cluster2 -0.1080911  0.89754586
    ## Stage2.Layer2.cluster2.cluster2  3.2698368 26.30704652
    ##
    ##
    ## --- Stage 4 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 12 / 60 (20.0%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 36 / 180 (20.0%)
    ##   Layer 2 listwise rows : 12 / 60 (20.0%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 36 / 180 (20.0%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -281.96
    ##   BIC                    : 735.88
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s4_L1_f1  -0.4247369   1.1626366
    ## s4_L1_f2  -0.2351415   0.6619763
    ## s4_L1_f3  -0.1777889   0.7520117
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s4_L2_f1  -0.8871681   0.3195956
    ## s4_L2_f2  -0.8313317   0.3952578
    ## s4_L2_f3  -0.6999865   0.3092289
    ##
    ## (2) E: intercept and odds ratio of being assigned to each latent cluster for each cluster from the previous serial stage (for each layer)
    ## Layer 1
    ##
    ##                                       beta          OR
    ## (Intercept).cluster2            -0.8654305   0.4208703
    ## Stage3.Layer1.cluster2.cluster2  5.3281366 206.0536649
    ## Stage3.Layer2.cluster2.cluster2 -1.2556081   0.2849025
    ##
    ## Layer 2
    ##
    ##                                       beta       OR
    ## (Intercept).cluster2             0.4462967 1.562515
    ## Stage3.Layer1.cluster2.cluster2 -2.0653098 0.126779
    ## Stage3.Layer2.cluster2.cluster2  1.8718092 6.500045
    ##
    ##
    ## --- Stage 5 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 16 / 60 (26.7%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 48 / 180 (26.7%)
    ##   Layer 2 listwise rows : 16 / 60 (26.7%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 48 / 180 (26.7%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -252.15
    ##   BIC                    : 676.26
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s5_L1_f1  -0.2996022   1.2611756
    ## s5_L1_f2  -0.1630761   0.5999957
    ## s5_L1_f3   0.1113482   0.5636818
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s5_L2_f1  -1.0062271  0.27218989
    ## s5_L2_f2  -1.1786110  0.07458108
    ## s5_L2_f3  -0.7027253  0.12793040
    ##
    ## (2) E: intercept and odds ratio of being assigned to each latent cluster for each cluster from the previous serial stage (for each layer)
    ## Layer 1
    ##
    ##                                       beta           OR
    ## (Intercept).cluster2             -2.170905 1.140743e-01
    ## Stage4.Layer1.cluster2.cluster2  12.798914 3.618243e+05
    ## Stage4.Layer2.cluster2.cluster2 -10.681740 2.296040e-05
    ##
    ## Layer 2
    ##
    ##                                      beta           OR
    ## (Intercept).cluster2             3.513576 3.356809e+01
    ## Stage4.Layer1.cluster2.cluster2 -7.218582 7.328406e-04
    ## Stage4.Layer2.cluster2.cluster2  5.643075 2.823295e+02
    ##
    ##
    ## --- Stage 6 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 20 / 60 (33.3%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 60 / 180 (33.3%)
    ##   Layer 2 listwise rows : 20 / 60 (33.3%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 60 / 180 (33.3%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -298.76
    ##   BIC                    : 794.05
    ##   Number of parameters   : 48
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Y (continuous outcome): intercept, effects of each non-reference latent cluster for each layer of Y (and effect of covariates if included)
    ##                   Gamma
    ## (Intercept) -0.05913686
    ## Layer1_LC2   0.06078451
    ## Layer2_LC2   1.05110540
    ## cov1         0.34504269
    ## cov2         0.25584470
    ##
    ## (2) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##          mu_cluster1 mu_cluster2
    ## s6_L1_f1   1.5605963 -0.38155266
    ## s6_L1_f2   0.8935406  0.05500217
    ## s6_L1_f3   0.9361158  0.05836151
    ##
    ## Layer 2
    ##
    ##          mu_cluster1 mu_cluster2
    ## s6_L2_f1  0.02787015  -0.8944043
    ## s6_L2_f2  0.07880488  -0.9214000
    ## s6_L2_f3  0.17140060  -0.7804256
    ##
    ## (3) E: intercept and odds ratio of being assigned to each latent cluster for each cluster from the previous serial stage (for each layer)
    ## Layer 1
    ##
    ##                                       beta          OR
    ## (Intercept).cluster2             0.3766627  1.45741261
    ## Stage5.Layer1.cluster2.cluster2 -3.0656751  0.04662235
    ## Stage5.Layer2.cluster2.cluster2  2.5017497 12.20382830
    ##
    ## Layer 2
    ##
    ##                                        beta        OR
    ## (Intercept).cluster2            -0.04097893 0.9598494
    ## Stage5.Layer1.cluster2.cluster2  0.83420130 2.3029739
    ## Stage5.Layer2.cluster2.cluster2 -1.58901626 0.2041263

## 9) Bootstrap Inference (Serial Model)

Because this model is already fit with zero penalties, we can directly run bootstrap CI.

Practical note:

- this architecture is relatively heavy (6 serial stages, each stage parallel),
- so we use a small `R` in the tutorial for runtime.
- in analysis runs, increase `R` for more stable intervals.

    set.seed(5253)

    serial_boot <- boot_lucid(
      G = d_miss$G,
      Z = d_miss$Z,
      Y = d_miss$Y,
      CoG = d_miss$CoG,
      CoY = d_miss$CoY,
      model = serial_fit,
      R = 2,
      conf = 0.90
    )

    # Stage-wise bootstrap objects are returned under $stage
    length(serial_boot$stage)

    ## [1] 6

    names(serial_boot$stage[[1]])

    ## [1] "beta"  "mu"    "gamma"

`length(serial_boot$stage)` should read 6: `boot_lucid()` resamples subjects once and refits the entire 6-stage chain on each resample, then reports one set of bootstrap replicates per stage, mirroring the fit’s own `submodel` structure.

## 10) Summary With Bootstrap CI

This summary prints the same model tables plus CI columns for supported parameter blocks.

    summary(serial_fit, boot.se = serial_boot)

    ##
    ## ====================================================
    ## LUCID Serial: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : normal
    ##   Number of observations : 60
    ##   Number of stages       : 6
    ##   Stage 1               : parallel (K = 2,2)
    ##   Stage 2               : parallel (K = 2,2)
    ##   Stage 3               : parallel (K = 2,2)
    ##   Stage 4               : parallel (K = 2,2)
    ##   Stage 5               : parallel (K = 2,2)
    ##   Stage 6               : parallel (K = 2,2)
    ##
    ## Missing-data profile by stage
    ##   Stage 1
    ##     Layer 1 listwise/sporadic rows : 0 / 2
    ##     Layer 2 listwise/sporadic rows : 0 / 2
    ##   Stage 2
    ##     Layer 1 listwise/sporadic rows : 4 / 0
    ##     Layer 2 listwise/sporadic rows : 4 / 0
    ##   Stage 3
    ##     Layer 1 listwise/sporadic rows : 8 / 0
    ##     Layer 2 listwise/sporadic rows : 8 / 0
    ##   Stage 4
    ##     Layer 1 listwise/sporadic rows : 12 / 0
    ##     Layer 2 listwise/sporadic rows : 12 / 0
    ##   Stage 5
    ##     Layer 1 listwise/sporadic rows : 16 / 0
    ##     Layer 2 listwise/sporadic rows : 16 / 0
    ##   Stage 6
    ##     Layer 1 listwise/sporadic rows : 20 / 0
    ##     Layer 2 listwise/sporadic rows : 20 / 0
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -1801.81
    ##   BIC                    : 4700.91
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Stage-wise detailed parameter estimates
    ##
    ## --- Stage 1 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 0 / 60 (0.0%)
    ##   Layer 1 sporadic rows : 2 / 60 (3.3%)
    ##   Layer 1 missing cells : 2 / 180 (1.1%)
    ##   Layer 2 listwise rows : 0 / 60 (0.0%)
    ##   Layer 2 sporadic rows : 2 / 60 (3.3%)
    ##   Layer 2 missing cells : 2 / 180 (1.1%)
    ##
    ## Feature selection overview
    ##   G features selected    : 5 / 5 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 5 / 5 (100.0%)
    ##     Layer 2              : 5 / 5 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -349.25
    ##   BIC                    : 911.41
    ##   Number of parameters   : 52
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                             estimate  norm_lower norm_upper sig
    ## Layer1.s1_L1_f1.cluster1 -0.25923098 -0.79361335 0.88693388
    ## Layer1.s1_L1_f2.cluster1 -0.07087825 -0.14553608 0.04977206
    ## Layer1.s1_L1_f3.cluster1  0.02796816 -0.02311424 0.18098680
    ## Layer1.s1_L1_f1.cluster2  1.77667527  1.58629484 2.12963448   *
    ## Layer1.s1_L1_f2.cluster2  1.02125760  0.99943648 1.37665268   *
    ## Layer1.s1_L1_f3.cluster2  0.80847737  0.62159663 1.18330380   *
    ##
    ## Layer 2
    ##
    ##                             estimate  norm_lower  norm_upper sig
    ## Layer2.s1_L2_f1.cluster1 -1.21409366 -1.64451591 -0.96462446   *
    ## Layer2.s1_L2_f2.cluster1 -1.17134774 -1.86438089 -0.72311410   *
    ## Layer2.s1_L2_f3.cluster1 -0.51575219 -0.81882942  0.04689113
    ## Layer2.s1_L2_f1.cluster2  0.21626421 -0.01569531  0.61542538
    ## Layer2.s1_L2_f2.cluster2  0.15440970 -0.07734336  0.51817365
    ## Layer2.s1_L2_f3.cluster2  0.02402461 -0.53383939  0.20885447
    ##
    ## (2) E: cluster-assignment coefficients (log-odds scale) for each exposure for each layer, with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                        estimate  norm_lower norm_upper           OR
    ## (Intercept).cluster2 -2.1425889  -6.9850429  0.2053811 1.173506e-01
    ## G1.cluster2           7.1860279   9.1883008 13.3802560 1.320846e+03
    ## G2.cluster2           3.3538197  -0.1173109  7.6398951 2.861181e+01
    ## G3.cluster2          -4.0637126  -8.1629158 -2.5783536 1.718510e-02
    ## G4.cluster2          -1.7529953  -6.7730296  2.9787589 1.732542e-01
    ## G5.cluster2           3.7899420  -3.5665146 11.9221808 4.425383e+01
    ## cov1.cluster2         0.5203088  -2.0928351 -0.1364221 1.682547e+00
    ## cov2.cluster2        -6.7670005 -15.9519034  0.6438246 1.151142e-03
    ##                          OR_lower     OR_upper sig
    ## (Intercept).cluster2 9.256235e-04 1.227993e+00
    ## G1.cluster2          9.782016e+03 6.470999e+05   *
    ## G2.cluster2          8.893087e-01 2.079526e+03
    ## G3.cluster2          2.850301e-04 7.589886e-02   *
    ## G4.cluster2          1.144223e-03 1.966340e+01
    ## G5.cluster2          2.825416e-02 1.505696e+05
    ## cov1.cluster2        1.233370e-01 8.724743e-01   *
    ## cov2.cluster2        1.180800e-07 1.903748e+00
    ##
    ## Layer 2
    ##
    ##                         estimate norm_lower norm_upper           OR
    ## (Intercept).cluster2 -0.47824432  -2.153376   8.945538 6.198707e-01
    ## G1.cluster2          -7.23309223 -52.418713  86.298505 7.222839e-04
    ## G2.cluster2          10.62829698 -56.492475  42.116627 4.128675e+04
    ## G3.cluster2          -2.94054526  -4.929223   6.362262 5.283691e-02
    ## G4.cluster2           0.03096535  -1.285787   2.389459 1.031450e+00
    ## G5.cluster2           0.25659661  -6.182917  11.589230 1.292524e+00
    ## cov1.cluster2         3.11139707 -57.627794  29.516401 2.245239e+01
    ## cov2.cluster2        -6.88871079 -20.953604  25.208781 1.019227e-03
    ##                          OR_lower     OR_upper sig
    ## (Intercept).cluster2 1.160916e-01 7.673576e+03
    ## G1.cluster2          1.717285e-23 3.012760e+37
    ## G2.cluster2          2.921660e-25 1.954423e+18
    ## G3.cluster2          7.232119e-03 5.795556e+02
    ## G4.cluster2          2.764331e-01 1.090759e+01
    ## G5.cluster2          2.064397e-03 1.079292e+05
    ## cov1.cluster2        9.387866e-26 6.588858e+12
    ## cov2.cluster2        7.942653e-10 8.872268e+10
    ##
    ##
    ## --- Stage 2 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 4 / 60 (6.7%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 12 / 180 (6.7%)
    ##   Layer 2 listwise rows : 4 / 60 (6.7%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 12 / 180 (6.7%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -323.58
    ##   BIC                    : 819.12
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                             estimate norm_lower  norm_upper sig
    ## Layer1.s2_L1_f1.cluster1 -0.32476364 -0.7426353 -0.36636475   *
    ## Layer1.s2_L1_f2.cluster1  0.03621375 -0.4114942  0.20647259
    ## Layer1.s2_L1_f3.cluster1  0.01434587 -0.4302874 -0.09155984   *
    ## Layer1.s2_L1_f1.cluster2  1.57707264  1.3378131  2.12564670   *
    ## Layer1.s2_L1_f2.cluster2  1.00821699  0.8852328  1.18515137   *
    ## Layer1.s2_L1_f3.cluster2  0.77392945  0.7544277  0.97289729   *
    ##
    ## Layer 2
    ##
    ##                            estimate  norm_lower norm_upper sig
    ## Layer2.s2_L2_f1.cluster1 -0.9345513 -1.18486439 -0.3299740   *
    ## Layer2.s2_L2_f2.cluster1 -1.1641792 -1.33395777 -1.1883889   *
    ## Layer2.s2_L2_f3.cluster1 -0.6181080 -0.52869893 -0.4672291   *
    ## Layer2.s2_L2_f1.cluster2  0.1586644 -0.02575317  0.1085187
    ## Layer2.s2_L2_f2.cluster2  0.2081802  0.36216746  0.3639570   *
    ## Layer2.s2_L2_f3.cluster2  0.1895868 -0.20071352  0.3496443
    ##
    ## (2) E: cluster-assignment coefficients (log-odds scale) for each cluster from the previous serial stage (for each layer), with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                                   estimate norm_lower norm_upper          OR
    ## (Intercept).cluster2            -0.2345533 -0.5275514   2.287386  0.79092411
    ## Stage1.Layer1.cluster2.cluster2  3.0061229  2.4569013   3.421997 20.20889549
    ## Stage1.Layer2.cluster2.cluster2 -2.9934749 -4.6938575  -4.042293  0.05011299
    ##                                     OR_lower    OR_upper sig
    ## (Intercept).cluster2             0.590047991  9.84916224
    ## Stage1.Layer1.cluster2.cluster2 11.668597753 30.63052787   *
    ## Stage1.Layer2.cluster2.cluster2  0.009151317  0.01755716   *
    ##
    ## Layer 2
    ##
    ##                                   estimate norm_lower norm_upper         OR
    ## (Intercept).cluster2             0.9763921  0.3586997  0.8025441 2.65486053
    ## Stage1.Layer1.cluster2.cluster2 -2.9861738 -4.7768049 -1.4015125 0.05048022
    ## Stage1.Layer2.cluster2.cluster2  1.5837012  2.4207720  3.8864259 4.87295814
    ##                                     OR_lower   OR_upper sig
    ## (Intercept).cluster2             1.431466896  2.2312101   *
    ## Stage1.Layer1.cluster2.cluster2  0.008422868  0.2462243   *
    ## Stage1.Layer2.cluster2.cluster2 11.254544073 48.7363862   *
    ##
    ##
    ## --- Stage 3 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 8 / 60 (13.3%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 24 / 180 (13.3%)
    ##   Layer 2 listwise rows : 8 / 60 (13.3%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 24 / 180 (13.3%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -296.12
    ##   BIC                    : 764.20
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                            estimate norm_lower norm_upper sig
    ## Layer1.s3_L1_f1.cluster1 -0.3133371 -0.3909362 -0.2595396   *
    ## Layer1.s3_L1_f2.cluster1 -0.1356417 -0.2215396 -0.1122738   *
    ## Layer1.s3_L1_f3.cluster1  0.1989601 -0.3071382  0.4285289
    ## Layer1.s3_L1_f1.cluster2  1.5309424  1.2542982  1.7754245   *
    ## Layer1.s3_L1_f2.cluster2  0.9311460  0.5525322  1.2567254   *
    ## Layer1.s3_L1_f3.cluster2  0.8251488  0.8968467  0.9973711   *
    ##
    ## Layer 2
    ##
    ##                             estimate   norm_lower  norm_upper sig
    ## Layer2.s3_L2_f1.cluster1 -0.69470634 -0.007620766  0.12246931
    ## Layer2.s3_L2_f2.cluster1 -0.52013817 -0.030556747  0.40226715
    ## Layer2.s3_L2_f3.cluster1 -0.48765339 -0.559267829 -0.01069365   *
    ## Layer2.s3_L2_f1.cluster2  0.36149336  0.531092947  1.25080102   *
    ## Layer2.s3_L2_f2.cluster2 -0.04672601 -0.247231088  0.41447547
    ## Layer2.s3_L2_f3.cluster2  0.83015288  1.520150904  2.22864465   *
    ##
    ## (2) E: cluster-assignment coefficients (log-odds scale) for each cluster from the previous serial stage (for each layer), with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                                   estimate norm_lower norm_upper           OR
    ## (Intercept).cluster2             0.3386909 -0.7106238   2.509950 1.403110e+00
    ## Stage2.Layer1.cluster2.cluster2  6.0688887  3.6377378   8.195110 4.322001e+02
    ## Stage2.Layer2.cluster2.cluster2 -6.7814384 -8.7273253  -7.451612 1.134642e-03
    ##                                     OR_lower     OR_upper sig
    ## (Intercept).cluster2            4.913376e-01 1.230431e+01
    ## Stage2.Layer1.cluster2.cluster2 3.800576e+01 3.623188e+03   *
    ## Stage2.Layer2.cluster2.cluster2 1.620954e-04 5.805048e-04   *
    ##
    ## Layer 2
    ##
    ##                                   estimate norm_lower norm_upper          OR
    ## (Intercept).cluster2            -4.1231203 -12.348769  -9.032837  0.01619391
    ## Stage2.Layer1.cluster2.cluster2 -0.1080911   1.100694   6.079315  0.89754586
    ## Stage2.Layer2.cluster2.cluster2  3.2698368   4.267486   8.417789 26.30704652
    ##                                     OR_lower     OR_upper sig
    ## (Intercept).cluster2            4.335087e-06 1.194232e-04   *
    ## Stage2.Layer1.cluster2.cluster2 3.006251e+00 4.367301e+02   *
    ## Stage2.Layer2.cluster2.cluster2 7.134203e+01 4.526883e+03   *
    ##
    ##
    ## --- Stage 4 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 12 / 60 (20.0%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 36 / 180 (20.0%)
    ##   Layer 2 listwise rows : 12 / 60 (20.0%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 36 / 180 (20.0%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -281.96
    ##   BIC                    : 735.88
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                            estimate norm_lower norm_upper sig
    ## Layer1.s4_L1_f1.cluster1 -0.4247369 -0.9958713 -0.4661303   *
    ## Layer1.s4_L1_f2.cluster1 -0.2351415 -0.3815243 -0.1199789   *
    ## Layer1.s4_L1_f3.cluster1 -0.1777889 -0.8801466  0.3664514
    ## Layer1.s4_L1_f1.cluster2  1.1626366  1.1189991  1.1291377   *
    ## Layer1.s4_L1_f2.cluster2  0.6619763  0.4157009  0.7212194   *
    ## Layer1.s4_L1_f3.cluster2  0.7520117  0.4056094  0.7426555   *
    ##
    ## Layer 2
    ##
    ##                            estimate  norm_lower norm_upper sig
    ## Layer2.s4_L2_f1.cluster1 -0.8871681 -0.83999723 -0.7253571   *
    ## Layer2.s4_L2_f2.cluster1 -0.8313317 -1.40157111 -0.4104110   *
    ## Layer2.s4_L2_f3.cluster1 -0.6999865 -1.09210019 -0.6094454   *
    ## Layer2.s4_L2_f1.cluster2  0.3195956  0.13846992  0.2830234   *
    ## Layer2.s4_L2_f2.cluster2  0.3952578  0.05234972  0.7100608   *
    ## Layer2.s4_L2_f3.cluster2  0.3092289  0.20098883  0.4179397   *
    ##
    ## (2) E: cluster-assignment coefficients (log-odds scale) for each cluster from the previous serial stage (for each layer), with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                                   estimate norm_lower norm_upper          OR
    ## (Intercept).cluster2            -0.8654305 -11.404738  -5.469946   0.4208703
    ## Stage3.Layer1.cluster2.cluster2  5.3281366   8.267649  10.224493 206.0536649
    ## Stage3.Layer2.cluster2.cluster2 -1.2556081   2.773614   8.790164   0.2849025
    ##                                     OR_lower     OR_upper sig
    ## (Intercept).cluster2            1.114257e-05 4.211460e-03   *
    ## Stage3.Layer1.cluster2.cluster2 3.895780e+03 2.757025e+04   *
    ## Stage3.Layer2.cluster2.cluster2 1.601641e+01 6.569308e+03   *
    ##
    ## Layer 2
    ##
    ##                                   estimate norm_lower norm_upper       OR
    ## (Intercept).cluster2             0.4462967  2.1628010  4.4102290 1.562515
    ## Stage3.Layer1.cluster2.cluster2 -2.0653098 -4.7935742 -1.9579723 0.126779
    ## Stage3.Layer2.cluster2.cluster2  1.8718092  0.3098809  0.8825582 6.500045
    ##                                  OR_lower   OR_upper sig
    ## (Intercept).cluster2            8.6954599 82.2883019   *
    ## Stage3.Layer1.cluster2.cluster2 0.0082828  0.1411443   *
    ## Stage3.Layer2.cluster2.cluster2 1.3632628  2.4170751   *
    ##
    ##
    ## --- Stage 5 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 16 / 60 (26.7%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 48 / 180 (26.7%)
    ##   Layer 2 listwise rows : 16 / 60 (26.7%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 48 / 180 (26.7%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -252.15
    ##   BIC                    : 676.26
    ##   Number of parameters   : 42
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                            estimate norm_lower norm_upper sig
    ## Layer1.s5_L1_f1.cluster1 -0.2996022 -0.8882838 0.07489369
    ## Layer1.s5_L1_f2.cluster1 -0.1630761 -1.1629042 0.21029478
    ## Layer1.s5_L1_f3.cluster1  0.1113482  0.2590135 0.66042835   *
    ## Layer1.s5_L1_f1.cluster2  1.2611756  0.8747669 2.16118165   *
    ## Layer1.s5_L1_f2.cluster2  0.5999957  0.1880085 1.54315740   *
    ## Layer1.s5_L1_f3.cluster2  0.5636818  0.2781253 0.51088743   *
    ##
    ## Layer 2
    ##
    ##                             estimate norm_lower norm_upper sig
    ## Layer2.s5_L2_f1.cluster1 -1.00622711 -1.0903533 -0.8796766   *
    ## Layer2.s5_L2_f2.cluster1 -1.17861099 -1.4072148 -0.9414385   *
    ## Layer2.s5_L2_f3.cluster1 -0.70272528 -0.6624194 -0.1962498   *
    ## Layer2.s5_L2_f1.cluster2  0.27218989 -0.2243491  0.9035287
    ## Layer2.s5_L2_f2.cluster2  0.07458108 -0.3429528  0.3628809
    ## Layer2.s5_L2_f3.cluster2  0.12793040 -0.4286360  0.4602318
    ##
    ## (2) E: cluster-assignment coefficients (log-odds scale) for each cluster from the previous serial stage (for each layer), with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                                   estimate norm_lower norm_upper           OR
    ## (Intercept).cluster2             -2.170905  -6.258755   -2.90168 1.140743e-01
    ## Stage4.Layer1.cluster2.cluster2  12.798914  19.573464   26.98979 3.618243e+05
    ## Stage4.Layer2.cluster2.cluster2 -10.681740 -21.793861  -16.56249 2.296040e-05
    ##                                     OR_lower     OR_upper sig
    ## (Intercept).cluster2            1.913627e-03 5.493086e-02   *
    ## Stage4.Layer1.cluster2.cluster2 3.166995e+08 5.266437e+11   *
    ## Stage4.Layer2.cluster2.cluster2 3.428044e-10 6.412100e-08   *
    ##
    ## Layer 2
    ##
    ##                                  estimate norm_lower norm_upper           OR
    ## (Intercept).cluster2             3.513576   4.519565   7.655325 3.356809e+01
    ## Stage4.Layer1.cluster2.cluster2 -7.218582 -12.182219 -10.342349 7.328406e-04
    ## Stage4.Layer2.cluster2.cluster2  5.643075   6.245093  10.854133 2.823295e+02
    ##                                     OR_lower     OR_upper sig
    ## (Intercept).cluster2            9.179563e+01 2.111862e+03   *
    ## Stage4.Layer1.cluster2.cluster2 5.120704e-06 3.223852e-05   *
    ## Stage4.Layer2.cluster2.cluster2 5.154773e+02 5.174757e+04   *
    ##
    ##
    ## --- Stage 6 (parallel) ---
    ##
    ## ====================================================
    ## LUCID Parallel: Model Summary
    ## ====================================================
    ##
    ## Model specification
    ##   Family                 : gaussian
    ##   Number of observations : 60
    ##   Clusters per layer     : 2, 2
    ##
    ## Missing-data profile by layer
    ##   Layer 1 listwise rows : 20 / 60 (33.3%)
    ##   Layer 1 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 1 missing cells : 60 / 180 (33.3%)
    ##   Layer 2 listwise rows : 20 / 60 (33.3%)
    ##   Layer 2 sporadic rows : 0 / 60 (0.0%)
    ##   Layer 2 missing cells : 60 / 180 (33.3%)
    ##
    ## Feature selection overview
    ##   G features selected    : 2 / 2 (100.0%)
    ##   G features by layer
    ##     Layer 1              : 2 / 2 (100.0%)
    ##     Layer 2              : 2 / 2 (100.0%)
    ##   Z features
    ##     Layer 1 selected     : 3 / 3 (100.0%)
    ##     Layer 1 multi-cluster: 3
    ##     Layer 2 selected     : 3 / 3 (100.0%)
    ##     Layer 2 multi-cluster: 3
    ##
    ## Model fit statistics
    ##   Log-likelihood         : -298.76
    ##   BIC                    : 794.05
    ##   Number of parameters   : 48
    ##
    ## Regularization
    ##   Rho_G                  : 0.000
    ##   Rho_Z_Mu               : 0.000
    ##   Rho_Z_Cov              : 0.000
    ##
    ## Detailed parameter estimates
    ## (1) Y (continuous outcome): intercept, effects of each non-reference latent cluster for each layer of Y (and effect of covariates if included)
    ##                   Gamma  norm_lower norm_upper sig
    ## (Intercept) -0.05913686 -0.29501682  0.2502420
    ## Layer1_LC2   0.06078451 -0.19695520  0.2392204
    ## Layer2_LC2   1.05110540  0.63753139  1.5544808   *
    ## cov1         0.34504269  0.01954345  0.4241201   *
    ## cov2         0.25584470  0.12566303  0.5266616   *
    ##
    ## (2) Z: mean of omics data for each latent cluster of each layer
    ## Layer 1
    ##
    ##                             estimate norm_lower norm_upper sig
    ## Layer1.s6_L1_f1.cluster1  1.56059632  0.8366922  4.9034304   *
    ## Layer1.s6_L1_f2.cluster1  0.89354060  1.1651722  2.1268096   *
    ## Layer1.s6_L1_f3.cluster1  0.93611581 -0.6884367  3.0001803
    ## Layer1.s6_L1_f1.cluster2 -0.38155266 -2.9643424 -0.2248744   *
    ## Layer1.s6_L1_f2.cluster2  0.05500217 -0.5627217 -0.3004916   *
    ## Layer1.s6_L1_f3.cluster2  0.05836151 -1.2420110  0.5665753
    ##
    ## Layer 2
    ##
    ##                             estimate norm_lower  norm_upper sig
    ## Layer2.s6_L2_f1.cluster1  0.02787015 -0.6160551  1.09786091
    ## Layer2.s6_L2_f2.cluster1  0.07880488 -0.2418875  0.45295601
    ## Layer2.s6_L2_f3.cluster1  0.17140060 -0.1230959  0.77714140
    ## Layer2.s6_L2_f1.cluster2 -0.89440432 -1.0805042 -0.82878093   *
    ## Layer2.s6_L2_f2.cluster2 -0.92139998 -1.2668090  0.03064748
    ## Layer2.s6_L2_f3.cluster2 -0.78042556 -0.9207449 -0.75246468   *
    ##
    ## (3) E: cluster-assignment coefficients (log-odds scale) for each cluster from the previous serial stage (for each layer), with bootstrap interval and the odds ratio (exp of each column). `sig` marks intervals excluding the null.
    ## Layer 1
    ##
    ##                                   estimate norm_lower norm_upper          OR
    ## (Intercept).cluster2             0.3766627  -3.334395   2.233794  1.45741261
    ## Stage5.Layer1.cluster2.cluster2 -3.0656751  -6.218274  -6.078432  0.04662235
    ## Stage5.Layer2.cluster2.cluster2  2.5017497   1.365089  11.008612 12.20382830
    ##                                    OR_lower     OR_upper sig
    ## (Intercept).cluster2            0.035636131 9.335220e+00
    ## Stage5.Layer1.cluster2.cluster2 0.001992682 2.291766e-03   *
    ## Stage5.Layer2.cluster2.cluster2 3.916072952 6.039201e+04   *
    ##
    ## Layer 2
    ##
    ##                                    estimate norm_lower norm_upper        OR
    ## (Intercept).cluster2            -0.04097893  0.6152230  1.4249365 0.9598494
    ## Stage5.Layer1.cluster2.cluster2  0.83420130  0.2542921  0.4418189 2.3029739
    ## Stage5.Layer2.cluster2.cluster2 -1.58901626 -3.2943156 -2.8372619 0.2041263
    ##                                   OR_lower   OR_upper sig
    ## (Intercept).cluster2            1.85006903 4.15759372   *
    ## Stage5.Layer1.cluster2.cluster2 1.28954842 1.55553406   *
    ## Stage5.Layer2.cluster2.cluster2 0.03709342 0.05858586   *

Every coefficient table above now also carries the `sig` column (see the 3-model tutorials for its exact definition); at `R = 2` replicates the resulting intervals are for demonstrating the output format only, not for drawing conclusions about which effects are real.

## 11) Interpretation Notes for Real Data Use

- This run confirms the architecture executes with monotone missingness and stage-wise increasing listwise NA.
- In your real data, if a late stage has too many all-missing rows, initialization may become unstable; increase `N` or reduce missingness severity if needed.
- Keep this as a smoke/regression template for your real 6-stage serial-parallel pipeline.

## 12) Session Info

    sessionInfo()

    ## R version 4.4.0 (2024-04-24)
    ## Platform: aarch64-apple-darwin20
    ## Running under: macOS 26.6.2
    ##
    ## Matrix products: default
    ## BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
    ## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
    ##
    ## locale:
    ## [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    ##
    ## time zone: America/Los_Angeles
    ## tzcode source: internal
    ##
    ## attached base packages:
    ## [1] stats     graphics  grDevices utils     datasets  methods   base
    ##
    ## other attached packages:
    ## [1] plotly_4.11.0 ggplot2_4.0.2 LUCIDus_3.2.1
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] tidyr_1.3.1        sass_0.4.10        generics_0.1.4     shape_1.4.6.1
    ##  [5] stringi_1.8.7      lattice_0.22-7     hms_1.1.4          digest_0.6.39
    ##  [9] magrittr_2.0.4     evaluate_1.0.5     grid_4.4.0         RColorBrewer_1.1-3
    ## [13] iterators_1.0.14   fastmap_1.2.0      foreach_1.5.2      jsonlite_2.0.0
    ## [17] glmnet_4.1-10      Matrix_1.7-4       progress_1.2.3     nnet_7.3-20
    ## [21] survival_3.8-3     mclust_6.1.2       httr_1.4.7         purrr_1.2.0
    ## [25] crosstalk_1.2.2    viridisLite_0.4.2  scales_1.4.0       lazyeval_0.2.2
    ## [29] codetools_0.2-20   networkD3_0.4.1    jquerylib_0.1.4    cli_3.6.5
    ## [33] rlang_1.1.6        crayon_1.5.3       splines_4.4.0      withr_3.0.2
    ## [37] cachem_1.1.0       yaml_2.3.11        tools_4.4.0        dplyr_1.1.4
    ## [41] boot_1.3-32        vctrs_0.6.5        R6_2.6.1           lifecycle_1.0.4
    ## [45] htmlwidgets_1.6.4  pkgconfig_2.0.3    glasso_1.11        bslib_0.9.0
    ## [49] pillar_1.11.1      gtable_0.3.6       data.table_1.17.8  glue_1.8.0
    ## [53] Rcpp_1.1.0         tidyselect_1.2.1   xfun_0.54          tibble_3.3.0
    ## [57] data.tree_1.2.0    knitr_1.50         dichromat_2.0-0.1  farver_2.1.2
    ## [61] htmltools_0.5.9    igraph_2.2.1       labeling_0.4.3     rmarkdown_2.30
    ## [65] compiler_4.4.0     prettyunits_1.2.0  S7_0.2.1