Project: s41467-024-45706-0 | Function: run_peak_aen (r)

system: You are an expert R programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow R best practices and maintain consistent code style.
Return **only** the complete R function code.

user: Complete this R function:

**DESCRIPTION:** Core function implementing adaptive elastic net (AEN) regression to model gene expression from chromatin accessibility peaks. Includes bootstrap validation, distance-based peak selection, and regularization parameters.

**KEY TERMS:** {
  "lambda2": "regularization parameter",
  "gamma": "adaptive weight parameter",
  "ci_cutoff": "confidence interval cutoff",
  "max_distance": "peak-to-gene distance threshold"
}

**CONTEXT CODE:** #' Run adaptive elastic net to identify CREs regulating target genes
#'
#' This function will identify putative cis-regultory elements for each of the
#' inputted genes. It takes as input your Seurat object, the pseudocell matrices
#' generated by prepare_pseudocell_matrix, the list of genes that you wish to model,
#' and parameters for running the adaptive elastic net and parallelization.
#' Genes without genomic peaks (mitochondrial) in the provided Annotation
#' are excluded, and names are printed if verbose is TRUE. The function
#' returns information for each modeled gene as a list. Each gene's entry 
#' in this list is a list containing the following information:
#' the coefficient of determination calculated during the cross validation step
#' with the calculated lambda.min value, the trained model object, and a 
#' data frame with regulatory weights and standard errors for all
#' statistically significant CREs. Regulatory weights for non-significant CREs
#' are set to 0 for future analysis if desired.
#'
#' @param seurat A Seurat object
#' @param pseudocell_mat Pseudocell expression matrix to use
#' @param pseudocell_mat_peaks Pseudocell chromatin accessibility matrix to use
#' @param gene_list Names of genes to model
#' @param lambda2 Parameter for quadratic L2 penalty for regularization
#' @param gamma Positive constant for calculating adaptive weights
#' @param ci_cutoff Confidence interval cutoff used to determine whether an estimated non-zero coefficient should be kept
#' @param pval_cutoff As an alternative, p value cutoff to use in order to calculate ci_cutoff. E.g. p value of 0.5 corresponds to 95% CI.
#' @param set_nonsig_to_zero Boolean to determine whether non-significant coefficient estimates should be set to zero
#' @param max_distance Max distance from modeled gene's TSS to include CREs for building gene regulatory network model
#' @param train_fraction Fraction of pseudocells used for training during cross-validation step
#' @param num_bootstraps Number of bootstrap samples
#' @param bootstrap Boolean if set to false, will not perform bootstrapping
#' @param num_threads Number of threads to use for multithreading
#' @param globals_maxsize If running into RAM problems during multithreading, can use this parameter to set future.globals.maxSize if not done manually
#' @param verbose Boolean to determine whether to run silently
#' @param bs_seed Seed for reproducibility in determining bootstrap seeds, set to NULL if not needed
#' @param multi_seed Seed for reproducibility during multithreaded model training, set to NULL if not needed
#'
#' @return list of lists per modeled gene, containing modeling and CRE gene regulatory network information
#' @export
#'
run_peak_aen <- function(seurat,
                         pseudocell_mat,
                         pseudocell_mat_peaks,
                         gene_list,
                         lambda2 = 0.5,
                         gamma = 1,
                         ci_cutoff = 1.96,
                         pval_cutoff = NULL,
                         set_nonsig_to_zero = TRUE,
                         max_distance = 250000,
                         train_fraction = 0.8,
                         num_bootstraps = 100,
                         bootstrap = TRUE,
                         num_threads = 16,
                         globals_maxsize = NULL,
                         verbose = TRUE,
                         bs_seed = 943126,
                         multi_seed = 6283408,
                         peak_assay = "peaks") {
  stop("Function implementation has been masked")

  if (is.null(gene_list)) {
    stop("gene_list must be provided")
} else {
  # Handle gene list for promoter-only mode (TF modeling using promoter peaks only)
  if (!is.null(gene_list)) {
    if (inherits(gene_list, "list")) {
      gene_list <- unlist(gene_list, use.names = FALSE)
    }
    # Retrieve TSS for provided genes and filter out those missing genomic annotations
    tss <- Signac::GetTSS(seurat, genes = gene_list)
    initial_genes <- rownames(tss)
  } else {
    # Use genes from peak AEN results (already have linked CREs) if no gene_list provided
    if (is.null(aen_results_peaks)) {
      stop("aen_results_peaks must be provided when gene_list is NULL in promoter_only mode")
    }
    initial_genes <- names(aen_results_peaks)
    # Retrieve TSS for AEN-derived genes and filter missing annotations
    tss <- Signac::GetTSS(seurat, genes = initial_genes)
    initial_genes <- rownames(tss)
  }

  # Early return if no valid initial genes remain
  if (length(initial_genes) == 0) {
    if (verbose) {
      message("No valid genes found in input or AEN results (check genome annotations).")
    }
    return(list())
  }

  # Define promoter regions (symmetric around TSS using threshold)
  promoter_regions <- GenomicRanges::promoters(
    tss = tss[initial_genes, ],
    upstream = promoter_threshold,
    downstream = promoter_threshold
  )

  # Retrieve peaks from the specified assay and validate
  peaks <- Signac::GetPeaks(seurat, assay = peak_assay)
  if (length(peaks) == 0) {
    if (verbose) {
      message("No peaks found in assay: ", peak_assay, " (check assay name or peak data).")
    }
    return(list())
  }

  # Find overlaps between promoter regions and peaks
  overlap_hits <- GenomicRanges::findOverlaps(
    query = promoter_regions,
    subject = peaks,
    type = "any"
  )

  # Filter genes with at least one overlapping promoter peak
  genes_with_promoter_peaks <- unique(GenomicRanges::queryHits(overlap_hits))
  modeled_genes <- initial_genes[genes_with_promoter_peaks]

  # Report excluded genes if verbose
  if (verbose && length(modeled_genes) < length(initial_genes)) {
    excluded_genes <- setdiff(initial_genes, modeled_genes)
    message(
      "Excluded ", length(excluded_genes), " genes without promoter peaks (threshold: ",
      promoter_threshold, " bp): ", paste(excluded_genes, collapse = ", ")
    )
  }

  # Early return if no genes remain after promoter peak filtering
  if (length(modeled_genes) == 0) {
    if (verbose) {
      message("No genes retained after promoter peak filtering (check threshold/peak data).")
    }
    return(list())
  }
}

#' Run adaptive elastic net to identify TFs regulating target genes
#'
#' This function will identify putative transcription factors regulating each of
#' the inputted genes. It takes as input your Seurat object, the returned value


Complete the function implementation replacing "stop("Not implemented")".