f.Enr_Fisher <- function (
			GS.ls, 
			GS_names.chv,
			exp.genes, 
			uni.genes)

{

# INPUT REQUIREMENTS
# - no redundancy in gene-sets

# 1) PRE-PROCESSING

# Reduce everything to the universe

f.int_uni <- function (input.genes)
	{return (intersect (input.genes, uni.genes))}

GS.ls <- lapply (GS.ls, f.int_uni)

exp.genes <- intersect (exp.genes, uni.genes)

# Defining enr.df

row.n <- length (GS.ls)

# columns of < enr.df > are: 
# - GO ID, 
# - term name, 
# - number of GO term genes in the universe ("SplG"), 
# - number of GO term genes in the sample ("UniG"), 
# - uncorrected p-value
# - ratio = (sample.GOterm.length / sample.tot.length) / (uni.GOterm.length / uni.tot.length)

enr.df <- data.frame (
				 	GS_ID     = character (row.n),
			     	GS_name   = character (row.n),
			     	GS_size   = integer (row.n),
			     	enr_n     = integer (row.n),
			     	pvalue    = numeric (row.n),
			     	ratio     = numeric (row.n),
			     	stringsAsFactors = F)


# 2) COMPUTING ENRICHMENT

# computed outside cycle

enr.df$GS_ID   <- names (GS.ls)
enr.df$GS_name <- GS_names.chv[enr.df$GS_ID]
enr.df$GS_size <- unlist (lapply (GS.ls, length))

# global variables of the functionalized cycle

exp.n <- length (exp.genes)
uni.n <- length (uni.genes)

output.nv <- numeric (3)

# functionalized cycle
	
f.Enr_Fisher_Unit <- function (GS.genes)
	{
	enr.n    <- length (intersect (exp.genes, GS.genes))
	GS.n     <- length (GS.genes)

	table.mx <- matrix (
					ncol = 2, 
					nrow = 2, 
					data = c (
						enr.n, 
						GS.n  - enr.n, 
						exp.n - enr.n, 
						uni.n - (GS.n + exp.n - enr.n)
						), 
					byrow = T
					)

	# number of enriched genes
	output.nv[1] <- enr.n
	# p-value
	output.nv[2] <- fisher.test (table.mx, alternative = "greater")$p.value
    # ratio
	output.nv[3] <- (enr.n / exp.n) / (GS.n / uni.n)
	
	names (output.nv) <- c ("enr_n", "pvalue", "ratio")
						
	return (output.nv)
	}

enr.ls <- lapply (GS.ls, f.Enr_Fisher_Unit)

enr.df[, c ("enr_n", "pvalue", "ratio")] <- as.data.frame (t ( as.matrix (as.data.frame (enr.ls))))

# sorting by increasing p-value

enr.df <- enr.df[order (enr.df$pvalue, decreasing = F), ]

return (enr.df)

}                                                                                                      