Input:
import os
import numpy as np
import nibabel as nib
import argparse as ap
import pandas as pd
from tfce_mediation.tfce import CreateAdjSet
from tfce_mediation.pyfunc import write_vertStat_img, write_voxelStat_img, create_adjac_vertex, create_adjac_voxel, reg_rm_ancova_one_bs_factor, reg_rm_ancova_two_bs_factor, glm_typeI, glm_cosinor, calc_indirect, dummy_code, column_product, stack_ones, import_voxel_neuroimage, lm_residuals, dummy_code_cosine
			EXOG_B.append(dmy_leftvar)

			Tvalues_A = glm_typeI(dmy_rightvar,
						EXOG_A,
						dmy_covariates=dmy_covariates,
						output_fvalues = False,
						output_tvalues = True,
						output_reduced_residuals = False)[1]

			Tvalues_B = glm_typeI(data,
						EXOG_B,
						dmy_covariates=dmy_covariates,
						output_fvalues = False,
						output_tvalues = True,
						output_reduced_residuals = False)[1]

		else:
			print("ERROR: Invalid mediation type: %s" % medtype)
			quit()

		SobelZ  = calc_indirect(Tvalues_A, Tvalues_B, alg = "aroian")

		if opts.surfaceinputfolder:
			save_temporary_files('mediation', modality_type = surface,
				all_vertex = all_vertex,
				num_vertex_lh = num_vertex_lh,
				mask_lh = mask_lh,
				mask_rh = mask_rh,
				outdata_mask_lh = outdata_mask_lh,
				outdata_mask_rh = outdata_mask_rh,
				affine_mask_lh = affine_mask_lh,
				affine_mask_rh = affine_mask_rh,
				adjac_lh = adjac_lh,
				adjac_rh = adjac_rh,
				vdensity_lh = vdensity_lh,
				vdensity_rh = vdensity_rh,
				dmy_leftvar = dmy_leftvar,
				dmy_rightvar = dmy_rightvar,
				dmy_covariates = dmy_covariates,
				optstfce = optstfce,
				medtype = medtype,
				nonzero = nonzero.astype(np.float32, order = "C"),
				data = data.astype(np.float32, order = "C"))

			outdir = "output_mediation_%s" % (surface)
			if not os.path.exists(outdir):
				os.mkdir(outdir)
			os.chdir(outdir)

			write_vertStat_img('Zstat_%s' % medtype,
				SobelZ[:num_vertex_lh],
				outdata_mask_lh,
				affine_mask_lh,
				surface,
				'lh',
				mask_lh,
				calcTFCE_lh,
				mask_lh.shape[0],
				vdensity_lh)
			write_vertStat_img('Zstat_%s' % medtype,
				SobelZ[num_vertex_lh:],
				outdata_mask_rh,
				affine_mask_rh,
				surface,
				'rh',
				mask_rh,
				calcTFCE_rh,
				mask_rh.shape[0],
				vdensity_rh)

		if opts.volumetricinputs or opts.volumetricinputlist:
			save_temporary_files('mediation', modality_type = "volume",
				mask_index = mask_index,
				data_mask = data_mask,
				affine_mask = affine_mask,
				adjac = adjac,
				dmy_leftvar = dmy_leftvar,
				dmy_rightvar = dmy_rightvar,
				dmy_covariates = dmy_covariates,
				optstfce = optstfce,
				medtype = medtype,
				nonzero = nonzero.astype(np.float32, order = "C"),
				data = data.astype(np.float32, order = "C"))

			outdir = "output_mediation_volume"
			if not os.path.exists(outdir):
				os.mkdir(outdir)
			os.chdir(outdir)

			write_voxelStat_img('Zstat_%s' % medtype,
				SobelZ,
				data_mask,
				mask_index,
				affine_mask,
				calcTFCE,
				imgext)

	if opts.cosinormediation:
		medtype = 'Y'
		data = data[0] # There should only be one interval...
		time_var = pdCSV["%s" % opts.cosinormediation[0]]
		period = float(opts.cosinormediation[1])
		dmy_mediator = dummy_code(np.array(pdCSV[opts.cosinormediation[2]]), iscontinous = True, demean = demean_flag)
		print("Coding mediator %s as continous variable" % opts.cosinormediation[2])

		if opts.initcovar:
			init_covars, init_covarsnames = load_vars(pdCSV, variables = opts.initcovar, exog = [], names = [], demean_flag = False)
			dmy_init_covars = np.concatenate(init_covars,1)
			data = lm_residuals(data, dmy_init_covars)

		if opts.covariates:
			dmy_covariates = np.concatenate(covars,1)
		else:
			dmy_covariates = None

		EXOG = []
		EXOG.append(dmy_mediator)

Context:
tfce_mediation/pyfunc.py
def write_vertStat_img(statname, vertStat, outdata_mask, affine_mask, surf, hemi, bin_mask, TFCEfunc, all_vertex, density_corr = 1, TFCE = True):
	vertStat_out=np.zeros(all_vertex).astype(np.float32, order = "C")
	vertStat_out[bin_mask] = vertStat
	if TFCE:
		vertStat_TFCE = np.zeros_like(vertStat_out).astype(np.float32, order = "C")
		TFCEfunc.run(vertStat_out, vertStat_TFCE)
		outdata_mask[:,0,0] = vertStat_TFCE * (vertStat[np.isfinite(vertStat)].max()/100) * density_corr
		fsurfname = "%s_%s_%s_TFCE.mgh" % (statname,surf,hemi)
		os.system("echo %s_%s_%s,%f >> max_TFCE_contrast_values.csv" % (statname,surf,hemi, outdata_mask[np.isfinite(outdata_mask[:,0,0])].max()))
		nib.save(nib.freesurfer.mghformat.MGHImage(outdata_mask,affine_mask),fsurfname)
	outdata_mask[:,0,0] = vertStat_out
	fsurfname = "%s_%s_%s.mgh" % (statname,surf,hemi)
	nib.save(nib.freesurfer.mghformat.MGHImage(outdata_mask,affine_mask),fsurfname)
tfce_mediation/pyfunc.py
def reg_rm_ancova_two_bs_factor(data, dmy_factor1, dmy_factor2, dmy_subjects, dmy_covariates = None, data_format = 'short', output_sig = False, verbose = True, rand_array = None, use_reduced_residuals = False, output_reduced_residuals = False):
	"""
	Two factor repeated measure ANCOVA for longitudinal dependent variables
	Note: Type 1 Sum of Squares is used, therefore order matters

	Parameters
	----------
	data : array
		Data array (N_intervals, N_individuals, N_dependent variables)
	dmy_factor1 : array
		dummy coded factor 1
	dmy_factor2 : array
		dummy coded factor 2
	dmy_subjects : array
		dummy coded subjects

	Optional Parameters
	----------
	dmy_covariates : array
		dummy coded covariates of no interest
	rand_array : arrays
		randomised shuffled array (used for permutation testing)

	Optional Flags
	----------
	output_sig : bool
		outputs p-values of F-statistics
	verbose : bool
		prints the max F-statistics values and degrees of freedom
	use_reduced_residuals : bool
		The residuals after regressing the fixed effect exogenous variable(s) is shuffled for permutations testing.
	output_reduced_residuals : bool
		Outputs the residuals array after regressing the fixed effect exogenous variable(s).

	Returns
	-------
	F_a : array
		F-statistics of the between-subject factor1
	F_b : array
		F-statistics of the between-subject factor2
	F_ab : array
		F-statistics of the between-subject interaction of factor1*factor2
	F_s : array
		F-statistics of the within-subject interval
	F_sb : array
		F-statistics of the factor1*interval interaction
	F_sb : array
		F-statistics of the factor2*interval interaction
	F_sab : array
		F-statistics of the factor1*factor2*interval interaction

	Optional returns
	-------

	P_a : array
		P-statistics of the between-subject factor1
	P_b : array
		P-statistics of the between-subject factor2
	P_ab : array
		P-statistics of the between-subject interaction of factor1*factor2
	P_s : array
		P-statistics of the within-subject interval
	P_sa : array
		P-statistics of the factor1*interval interaction
	P_sb : array
		P-statistics of the factor2*interval interaction
	P_sab : array
		P-statistics of the factor1*factor2*interval interaction

	OR

	reduced_data : array
		Residuals array after regressing the fixed effect exogenous variable(s) in long format.

	"""

	if data_format == 'short':
		if data.ndim == 2:
			data = data[:,:,np.newaxis]
		# get shapes for df
		n = data.shape[1]
		s = data.shape[0]
		endog_arr = data.reshape(s*n,data.shape[2])
	elif data_format == 'long':
		n = len(dmy_factor1)
		s = len(data)/n
		endog_arr = data
	else:
		print("Error: data format must be short or long.")
	del data # reduce ram usage

	if dmy_factor1.ndim == 1:
		fa = 2
	else:
		fa = dmy_factor1.shape[1] + 1
	if dmy_factor2.ndim == 1:
		fb = 2
	else:
		fb = dmy_factor2.shape[1] + 1

	if rand_array is not None:
		if use_reduced_residuals:
			r_dmy_factor1_long = dmy_factor1
			r_dmy_factor2_long = dmy_factor2
			r_dmy_interaction_long = column_product(dmy_factor1,dmy_factor2)
			if dmy_covariates is not None:
				r_dmy_covars_long = dmy_covariates
			for i in range(s-1):
				r_dmy_factor1_long = np.concatenate((r_dmy_factor1_long,dmy_factor1),0)
				r_dmy_factor2_long = np.concatenate((r_dmy_factor2_long,dmy_factor2),0)
				r_dmy_interaction_long = np.concatenate((r_dmy_interaction_long,column_product(dmy_factor1,dmy_factor2)),0)
				if dmy_covariates is not None:
					r_dmy_covars_long = np.concatenate((r_dmy_covars_long, dmy_covariates),0)
			exog_vars = stack_ones(r_dmy_factor1_long)
			exog_vars = np.column_stack((exog_vars, r_dmy_factor2_long))
			exog_vars = np.column_stack((exog_vars, r_dmy_interaction_long))
			if dmy_covariates is not None:
				exog_vars = np.column_stack((exog_vars, r_dmy_covars_long))
			a = cy_lin_lstsqr_mat(exog_vars,endog_arr)
			endog_arr = endog_arr - np.dot(exog_vars,a)
			del a
		np.random.shuffle(endog_arr)
		dmy_factor1 = dmy_factor1[rand_array]
		dmy_factor2 = dmy_factor2[rand_array]
		if dmy_covariates is not None:
			dmy_covariates = dmy_covariates[rand_array]

	# code the interaction
	dmy_interaction = column_product(dmy_factor1, dmy_factor2)

	# convert to long form
	interval_long = np.zeros(n)
	dmy_factor1_long = dmy_factor1
	dmy_factor2_long = dmy_factor2
	dmy_interaction_long = dmy_interaction
	dmy_subjects_long = dmy_subjects
	if dmy_covariates is not None:
		dmy_covars_long = dmy_covariates

	for i in range(s-1):
		dmy_factor1_long = np.concatenate((dmy_factor1_long,dmy_factor1),0)
		dmy_factor2_long = np.concatenate((dmy_factor2_long,dmy_factor2),0)
		dmy_interaction_long = np.concatenate((dmy_interaction_long,dmy_interaction),0)
		dmy_subjects_long = np.concatenate((dmy_subjects_long,dmy_subjects),0)
		interval_long = np.concatenate((interval_long, np.ones(n)*(i+1)))
		if dmy_covariates is not None:
			dmy_covars_long = np.concatenate((dmy_covars_long, dmy_covariates),0)
	dmy_interval_long = dummy_code(interval_long, demean = False)

	# SS Totals
	exog_vars = stack_ones(dmy_subjects_long)
	SS_WithinSubjects = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_Total = np.sum((endog_arr - np.mean(endog_arr, axis = 0))**2, axis = 0)
	SS_BetweenSubjects = SS_Total - SS_WithinSubjects

	# SS between subject
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_factor2_long))
	exog_vars = np.column_stack((exog_vars, dmy_interaction_long))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
	if output_reduced_residuals:
		a, residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)
		reduced_data = endog_arr - np.dot(exog_vars,a)
		del a
	else:
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_cells_ab = SS_Total - residuals

	exog_vars = stack_ones(np.column_stack((dmy_factor1_long, dmy_factor2_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_ab = SS_cells_ab - (SS_Total - residuals)
	# correct SS_ab

	if dmy_covariates is not None:
		exog_vars = stack_ones(dmy_covars_long)
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_covars =(SS_Total - residuals)
	else:
		SS_covars = 0

	# SSb
	exog_vars = stack_ones(dmy_factor1_long)
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_a = (SS_Total - residuals) - SS_covars

	# SSa
	SS_b = SS_cells_ab - SS_covars - SS_ab - SS_a

	SS_WithinFactors = SS_BetweenSubjects - SS_a - SS_b - SS_ab - SS_covars

	# SS time
	exog_vars = stack_ones(dmy_interval_long)
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_s =  SS_Total - residuals

	# SS Cells s*a*b
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_factor2_long))
	exog_vars = np.column_stack((exog_vars, dmy_interaction_long))
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor2_long,dmy_interval_long)))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_interaction_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_cells_sab = SS_Total - residuals

	# SS Cells s*a*b
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_factor2_long))
	exog_vars = np.column_stack((exog_vars, dmy_interaction_long))
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor2_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_sab = SS_cells_sab - (SS_Total - residuals)

	# SS covariates (same as above int then minus int)
	if dmy_covariates is not None:
		exog_vars = stack_ones(dmy_covars_long)
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
		exog_vars = np.column_stack((exog_vars, dmy_interval_long))
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_cells_scovars = (SS_Total - residuals)
		exog_vars = stack_ones(dmy_covars_long)
		exog_vars = np.column_stack((exog_vars, dmy_interval_long))
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_scovars = SS_cells_scovars - (SS_Total - residuals)
	else:
		SS_scovars = 0

	# SS Cells s*a
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_Cells_sa = (SS_Total - residuals)

	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_sa = SS_Cells_sa - (SS_Total - residuals)

	# SS Cells s*b
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_factor2_long))
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor2_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_Cells_sb = (SS_Total - residuals)

	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_factor2_long))
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_sb = SS_Cells_sb - (SS_Total - residuals)

	SS_sWithinFactors = SS_WithinSubjects - SS_s - SS_sa - SS_sb - SS_sab - SS_scovars

	# Between subjects df
	df_BetweenSubjects  = n - 1
	df_a =  fa - 1
	df_b =  fb - 1
	df_ab =  df_a * df_b
	if dmy_covariates is not None:
		if dmy_covariates.ndim == 1:
			df_covars = 1
		else:
			df_covars = dmy_covariates.shape[1]
	else:
		df_covars = 0
	df_WithinFactors = df_BetweenSubjects - df_a - df_b - df_ab - df_covars

	# Within subjects df
	df_s = s - 1
	df_sa = df_a * df_s
	df_sb = df_b * df_s
	df_sab = df_ab * df_s
	df_sWithinFactor = df_WithinFactors * df_s

	# F-stats
	# Between subjects
	ms_WithinFactors = np.divide(SS_WithinFactors, df_WithinFactors)
	F_a = np.divide(np.divide(SS_a, df_a), ms_WithinFactors)
	F_b = np.divide(np.divide(SS_b, df_b), ms_WithinFactors)
	F_ab = np.divide(np.divide(SS_ab, df_ab), ms_WithinFactors)

	# Within subjects
	ms_sWithinFactor = np.divide(SS_sWithinFactors, df_sWithinFactor)
	F_s = np.divide(np.divide(SS_s, df_s), ms_sWithinFactor)
	F_sa = np.divide(np.divide(SS_sa, df_sa), ms_sWithinFactor)
	F_sb = np.divide(np.divide(SS_sb, df_sb), ms_sWithinFactor)
	F_sab = np.divide(np.divide(SS_sab, df_sab), ms_sWithinFactor)

	if verbose:
		print("Source\t\tDF\tF(Max)")
		print("Factor1\t\t(%d,%d)\t%.2f" % (df_a, df_WithinFactors, F_a.max()))
		print("Factor2\t\t(%d,%d)\t%.2f" % (df_b, df_WithinFactors, F_b.max()))
		print("F1*F2\t\t(%d,%d)\t%.2f" % (df_ab, df_WithinFactors, F_ab.max()))
		print("Time\t\t(%d,%d)\t%.2f" % (df_s, df_sWithinFactor, F_s.max()))
		print("F1*Time\t\t(%d,%d)\t%.2f" % (df_sa, df_sWithinFactor, F_sa.max()))
		print("F2*Time\t\t(%d,%d)\t%.2f" % (df_sb, df_sWithinFactor, F_sb.max()))
		print("F1*F2*Time\t(%d,%d)\t%.2f" % (df_sab, df_sWithinFactor, F_sab.max()))

	if output_sig:
		# Between subjects
		P_a = 1 - f.cdf(F_a,df_a,df_WithinFactors)
		P_b = 1 - f.cdf(F_b,df_b,df_WithinFactors)
		P_ab = 1 - f.cdf(F_ab,df_ab,df_WithinFactors)
		# Within subjects
		P_s = 1 - f.cdf(F_s,df_s,df_sWithinFactor)
		P_sa = 1 - f.cdf(F_sa,df_sa,df_sWithinFactor)
		P_sb = 1 - f.cdf(F_sb,df_sb,df_sWithinFactor)
		P_sab = 1 - f.cdf(F_sab,df_sab,df_sWithinFactor)
		return (F_a, F_b, F_ab, F_s, F_sa, F_sb, F_sab, P_a, P_b, P_ab, P_s, P_sa, P_sb, P_sab)
	else:
		if output_reduced_residuals:
			return (F_a, F_b, F_ab, F_s, F_sa, F_sb, F_sab, reduced_data)
		else:
			return (F_a, F_b, F_ab, F_s, F_sa, F_sb, F_sab)
tfce_mediation/pyfunc.py
def calc_indirect(ta, tb, alg = "aroian"):
	"""
	Calculates the indirect effect of simple mediation

	Parameters
	----------
	ta : array
		T-values from Path A
	tb : array
		T-values from Path B
	alg : string
		The algorithm used for mediation (default = "aroian")

	Returns
	---------
	SobelZ : array
		Sobel-Z statistics of the indirect effect.

	"""
	if alg == 'aroian':
		#Aroian variant
		SobelZ = 1/np.sqrt((1/(tb**2))+(1/(ta**2))+(1/(ta**2*tb**2)))
	elif alg == 'sobel':
		#Sobel variant
		SobelZ = 1/np.sqrt((1/(tb**2))+(1/(ta**2)))
	elif alg == 'goodman':
		#Goodman variant
		SobelZ = 1/np.sqrt((1/(tb**2))+(1/(ta**2))-(1/(ta**2*tb**2)))
	else:
		print("Unknown indirect test algorithm")
		exit()
	return SobelZ
tfce_mediation/pyfunc.py
def dummy_code_cosine(time, period = 24.0):
	"""
	Dummy codes a time variable into a cosine
	C1 = (2.0*Pi*time)/period)
	C2 = sin(2.0*Pi*time)/period)

	Parameters
	----------
	time : array
		1D array variable of any type
	period : float
		Defined period (i.e., for one entire cycle) for the time variable

	Returns
	---------
	cosine_curve : array
		2D array cos and sine curves

	"""

	cosine_curve = np.cos(np.divide(2.0*np.pi*time, period))
	cosine_curve = np.column_stack((cosine_curve,np.sin(np.divide(2.0*np.pi*time, period))))
	return cosine_curve
tfce_mediation/pyfunc.py
def dummy_code(variable, iscontinous = False, demean = True):
	"""
	Dummy codes a variable

	Parameters
	----------
	variable : array
		1D array variable of any type

	Returns
	---------
	dummy_vars : array
		dummy coded array of shape [(# subjects), (unique variables - 1)]

	"""
	if iscontinous:
		if demean:
			dummy_vars = variable - np.mean(variable,0)
		else:
			dummy_vars = variable
	else:
		unique_vars = np.unique(variable)
		dummy_vars = []
		for var in unique_vars:
			temp_var = np.zeros((len(variable)))
			temp_var[variable == var] = 1
			dummy_vars.append(temp_var)
		dummy_vars = np.array(dummy_vars)[1:] # remove the first column as reference variable
		dummy_vars = np.squeeze(dummy_vars).astype(np.int).T
		if demean:
			dummy_vars = dummy_vars - np.mean(dummy_vars,0)
	return dummy_vars
tfce_mediation/pyfunc.py
def create_adjac_vertex(vertices,faces): # basic version
	adjacency = [set([]) for i in range(vertices.shape[0])]
	for i in range(faces.shape[0]):
		adjacency[faces[i, 0]].add(faces[i, 1])
		adjacency[faces[i, 0]].add(faces[i, 2])
		adjacency[faces[i, 1]].add(faces[i, 0])
		adjacency[faces[i, 1]].add(faces[i, 2])
		adjacency[faces[i, 2]].add(faces[i, 0])
		adjacency[faces[i, 2]].add(faces[i, 1])
	return adjacency
tfce_mediation/pyfunc.py
def glm_cosinor(endog, time_var, exog = None, dmy_covariates = None, rand_array = None, interaction_var = None, period = [24.0], calc_MESOR = True, output_fit_only = False):
	"""
	COSINOR model using GLM

	Parameters
	----------
	endog : array
		Endogenous (dependent) variable array (Nsubjects, Nvariables)
	time_var : array
		Time variable [0-23.99] (Nsubjects).
	exog : array
		Exogenous (independent) dummy coded variables
		exog is an array of arrays (Nvariables, Nsubjects, Kvariable).
	dmy_covariates : array
		Dummy coded array of covariates of no interest.
	init_covars : array
		Dummy coded array of covariates for two-step regression.
	rand_array : array
		randomized array for permutations (Nsubjects).
	period : array
		Period(s) as an array of floats for cosinor model.
	Returns
	---------
	To-do
	"""

	n = endog.shape[0]
	# add cosinor terms
	num_period = len(period)
	exog_vars = np.ones((n))
	for i in range(num_period):
		exog_vars = np.column_stack((exog_vars,np.cos(np.divide(2.0*np.pi*time_var, period[i]))))
		exog_vars = np.column_stack((exog_vars,np.sin(np.divide(2.0*np.pi*time_var, period[i]))))

	if interaction_var is not None:
		for i in range(num_period):
			exog_vars = np.column_stack((exog_vars, exog_vars[i+1] * interaction_var))

	kvars = []
	# add other exogenous variables to the model (currently not implemented)
	if exog is not None:
		for var in exog:
			var = np.array(var)
			if var.ndim == 1:
				kvars.append((3))
			else:
				kvars.append((var.shape[1]))
			exog_vars = np.column_stack((exog_vars,var))

	# add covariates (i.e., exogenous variables that will not be outputed)
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covariates))
	exog_vars = np.array(exog_vars)

	if rand_array is not None:
		exog_vars = exog_vars[rand_array]

	# calculate model fit (Fmodel and R-sqr)
	k = exog_vars.shape[1]
	DF_Between = k - 1 # aka df model
	DF_Within = n - k # aka df residuals
	#DF_Total = n - 1

	a, SS_Residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog)
	if output_fit_only:
		AMPLITUDE = []
		ACROPHASE = []
		MESOR = a[0]
		for i in range(num_period):
			# beta, gamma
			AMPLITUDE.append(np.sqrt((a[1+(i*2),:]**2) + (a[2+(i*2),:]**2)))
			# Acrophase calculation
			if i == 0: # awful hack
				ACROPHASE = np.arctan(np.abs(np.divide(-a[2+(i*2),:], a[1+(i*2),:])))
				ACROPHASE = ACROPHASE[np.newaxis,:]
			else:
				temp_acro = np.arctan(np.abs(np.divide(-a[2+(i*2),:], a[1+(i*2),:])))
				temp_acro = temp_acro[np.newaxis,:]
				ACROPHASE = np.append(ACROPHASE,temp_acro, axis=0)
			ACROPHASE = np.array(ACROPHASE)
			ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] >= 0)] = -ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] >= 0)]
			ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] < 0)] = (-1*np.pi) + ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] < 0)]
			ACROPHASE[i, (a[2+(i*2),:] < 0) & (a[1+(i*2),:] <= 0)] = (-1*np.pi) - ACROPHASE[i, (a[2+(i*2),:] < 0) & (a[1+(i*2),:] <= 0)]
			ACROPHASE[i, (a[2+(i*2),:] <= 0) & (a[1+(i*2),:] > 0)] = (-2*np.pi) + ACROPHASE[i, (a[2+(i*2),:] <= 0) & (a[1+(i*2),:] > 0)]
		return MESOR, np.array(AMPLITUDE), np.array(ACROPHASE)
	else:
		SS_Total = np.sum((endog - np.mean(endog,0))**2,0)
		SS_Between = SS_Total - SS_Residuals
		MS_Residuals = (SS_Residuals / DF_Within)
		Fmodel = (SS_Between/DF_Between) / MS_Residuals
		# Calculates sigma sqr and T-value (intercept) for MESOR
		sigma = np.sqrt(SS_Residuals / DF_Within)
		invXX = np.linalg.inv(np.dot(exog_vars.T, exog_vars))

		if (calc_MESOR) or (exog is not None):
			if endog.ndim == 1:
				se = np.sqrt(np.diag(sigma * sigma * invXX))
				Tvalues = a / se
				MESOR = a[0]
				tMESOR = Tvalues[0]
				SE_MESOR = se[0]
				a = a[:, np.newaxis]
			else:
				num_depv = endog.shape[1]
				se = se_of_slope(num_depv,invXX,sigma**2,k)
				Tvalues = a / se
				MESOR = a[0,:]
				tMESOR = Tvalues[0,:]
				SE_MESOR = se[0,:]
			if exog is not None:
				tEXOG = Tvalues[(3+(2*(num_period-1))):,:]
			else:
				tEXOG = None
		else:
			MESOR = tMESOR = SE_MESOR = tEXOG = None

		AMPLITUDE = []
		ACROPHASE = []
		SE_ACROPHASE = []
		SE_AMPLITUDE = []
		tAMPLITUDE = []
		tACROPHASE = []

		for i in range(num_period):
			# beta, gamma
			AMPLITUDE.append(np.sqrt((a[1+(i*2),:]**2) + (a[2+(i*2),:]**2)))
			# Acrophase calculation
			if i == 0: # awful hack
				ACROPHASE = np.arctan(np.abs(np.divide(-a[2+(i*2),:], a[1+(i*2),:])))
				ACROPHASE = ACROPHASE[np.newaxis,:]
			else:
				temp_acro = np.arctan(np.abs(np.divide(-a[2+(i*2),:], a[1+(i*2),:])))
				temp_acro = temp_acro[np.newaxis,:]
				ACROPHASE = np.append(ACROPHASE,temp_acro, axis=0)

			# standard errors from error propagation
			SE_ACROPHASE.append(sigma * np.sqrt((invXX[(1+(i*2)),1+(i*2)]*np.sin(ACROPHASE[i])**2) + (2*invXX[1+(i*2),2+(i*2)]*np.sin(ACROPHASE[i])*np.cos(ACROPHASE[i])) + (invXX[2+(i*2),2+(i*2)]*np.cos(ACROPHASE[i])**2)) / AMPLITUDE[i])
			SE_AMPLITUDE.append(sigma * np.sqrt((invXX[(1+(i*2)),1+(i*2)]*np.cos(ACROPHASE[i])**2) - (2*invXX[1+(i*2),2+(i*2)]*np.sin(ACROPHASE[i])*np.cos(ACROPHASE[i])) + (invXX[2+(i*2),2+(i*2)]*np.sin(ACROPHASE[i])**2)))

			ACROPHASE = np.array(ACROPHASE)
			if rand_array is None:
				ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] >= 0)] = -ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] >= 0)]
				ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] < 0)] = (-1*np.pi) + ACROPHASE[i, (a[2+(i*2),:] > 0) & (a[1+(i*2),:] < 0)]
				ACROPHASE[i, (a[2+(i*2),:] < 0) & (a[1+(i*2),:] <= 0)] = (-1*np.pi) - ACROPHASE[i, (a[2+(i*2),:] < 0) & (a[1+(i*2),:] <= 0)]
				ACROPHASE[i, (a[2+(i*2),:] <= 0) & (a[1+(i*2),:] > 0)] = (-2*np.pi) + ACROPHASE[i, (a[2+(i*2),:] <= 0) & (a[1+(i*2),:] > 0)]
			# t values
			tAMPLITUDE.append(np.divide(AMPLITUDE[i], SE_AMPLITUDE[i]))
			tACROPHASE.append(np.divide(1.0, SE_ACROPHASE[i]))

		# Do not output R-squared during permutations testing.
		if rand_array is None:
			R2 = 1 - (SS_Residuals/SS_Total)
		else:
			R2 = None
		return R2, MESOR, SE_MESOR, np.array(AMPLITUDE), np.array(SE_AMPLITUDE), np.array(ACROPHASE), np.array(SE_ACROPHASE), Fmodel, tMESOR, np.abs(tAMPLITUDE), np.abs(tACROPHASE), np.array(tEXOG)
tfce_mediation/pyfunc.py
def write_voxelStat_img(statname, voxelStat, out_path, data_index, affine, TFCEfunc, imgext = '.nii.gz', TFCE = True):
	if TFCE:
		voxelStat_out = voxelStat.astype(np.float32, order = "C")
		voxelStat_TFCE = np.zeros_like(voxelStat_out).astype(np.float32, order = "C")
		TFCEfunc.run(voxelStat_out, voxelStat_TFCE)
		out_path[data_index] = voxelStat_TFCE * (voxelStat_out.max()/100)
		nib.save(nib.Nifti1Image(out_path,affine),"%s_TFCE%s" % (statname, imgext))
		os.system("echo %s,%f >> max_TFCE_contrast_values.csv" % (statname,out_path.max()))
	out_path[data_index] = voxelStat
	nib.save(nib.Nifti1Image(out_path,affine),"%s%s" % (statname, imgext))
tfce_mediation/pyfunc.py
def column_product(arr1, arr2):
	"""
	Multiply two dummy codes arrays

	Parameters
	----------
	arr1 : array
		2D array variable dummy coded array (nlength, nvars)

	arr2 : array
		2D array variable dummy coded array (nlength, nvars)

	Returns
	---------
	prod_arr : array
		dummy coded array [nlength, nvars(arr1)*nvars(arr2)]

	"""
	l1 = len(arr1)
	l2 = len(arr2)
	if l1 == l2:
		arr1 = np.array(arr1)
		arr2 = np.array(arr2)
		prod_arr = []
		if arr1.ndim == 1:
			prod_arr = (arr1*arr2.T).T
		elif arr2.ndim == 1:
			prod_arr = (arr2*arr1.T).T
		else:
			for i in range(arr1.shape[1]):
				prod_arr.append((arr1[:,i]*arr2.T).T)
			prod_arr = np.array(prod_arr)
			if prod_arr.ndim == 3:
				prod_arr = np.concatenate(prod_arr, axis=1)
		prod_arr[prod_arr==0]=0
		return prod_arr
	else:
		print("Error: arrays must be of same length")
		quit()
tfce_mediation/pyfunc.py
def create_adjac_voxel(data_index, data_mask, num_voxel, dirtype=26): # default is 26 directions
	ind = np.where(data_index)
	dm = np.zeros_like(data_mask)
	x_dim, y_dim, z_dim = data_mask.shape
	adjacency = [set([]) for i in range(num_voxel)]
	label = 0
	for x,y,z in zip(ind[0],ind[1],ind[2]):
		dm[x,y,z] = label
		label += 1
	for x,y,z in zip(ind[0],ind[1],ind[2]):
		xMin=max(x-1, 0)
		xMax=min(x+1, x_dim-1)
		yMin=max(y-1, 0)
		yMax=min(y+1, y_dim-1)
		zMin=max(z-1, 0)
		zMax=min(z+1, z_dim-1)
		local_area = dm[xMin:xMax+1,yMin:yMax+1,zMin:zMax+1]
		if int(dirtype)==6:
			if local_area.shape!=(3,3,3): # check to prevent calculating adjacency at walls
				local_area = dm[x,y,z]
			else:
				local_area = local_area * np.array([0,0,0,0,1,0,0,0,0,0,1,0,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0]).reshape(3,3,3)
		cV = int(dm[x,y,z])
		for j in local_area[local_area>0]:
			adjacency[cV].add(int(j))
	# convert to list
	adjacency = np.array([[x for x in sorted(i) if x != index] for index, i in enumerate(adjacency)]) # just convoluted enough
	adjacency[0] = []
	return adjacency
tfce_mediation/pyfunc.py
def lm_residuals(endog, exog):
	"""
	"""
	if exog.ndim == 1:
		exog = stack_ones(exog)
	if np.mean(exog[:,0]) != 1:
		exog = stack_ones(exog)
	a = cy_lin_lstsqr_mat(exog,endog)
	endog = endog - np.dot(exog,a)
	return endog
tfce_mediation/pyfunc.py
def stack_ones(arr):
	"""
	Add a column of ones to an array

	Parameters
	----------
	arr : array

	Returns
	---------
	arr : array
		array with a column of ones

	"""
	return np.column_stack([np.ones(len(arr)),arr])
tfce_mediation/pyfunc.py
def reg_rm_ancova_one_bs_factor(data, dmy_factor1, dmy_subjects, data_format = 'short', dmy_covariates = None, output_sig = False, verbose = True, rand_array = None, use_reduced_residuals = False, output_reduced_residuals = False):
	"""
	One factor repeated measure ANCOVA for longitudinal dependent variables

	Parameters
	----------
	data : array
		Data array (N_intervals, N_individuals, N_dependent variables)
	dmy_factor1 : array
		dummy coded factor 1
	dmy_subjects : array
		dummy coded subjects

	Optional Parameters
	----------
	dmy_covariates : array
		dummy coded covariates of no interest

	Optional Flags
	----------
	output_sig : bool
		outputs p-values of F-statistics

	Returns
	-------
	F_a : array
		F-statistics of the between-subject factor1
	F_s : array
		F-statistics of the within-subject interval
	F_sa : array
		F-statistics of the factor1*interval interaction

	Optional returns
	-------

	P_a : array
		P-statistics of the between-subject factor1
	P_s : array
		P-statistics of the within-subject interval
	P_sa : array
		P-statistics of the factor1*interval interaction

	"""

	if data_format == 'short':
		if data.ndim == 2:
			data = data[:,:,np.newaxis]
		# get shapes for df
		s = data.shape[0]
		n = data.shape[1]
		endog_arr = data.reshape(s*n,data.shape[2])
	elif data_format == 'long':
		n = len(dmy_factor1)
		s = len(data)/n
		endog_arr = data
	else:
		print("Error: data format must be short or long.")

	#ram clean-up
	del data

	if dmy_factor1.ndim == 1:
		fa = 2
	else:
		fa = dmy_factor1.shape[1] + 1

	if rand_array is not None:
		if use_reduced_residuals:
			r_dmy_factor1_long = dmy_factor1
			if dmy_covariates is not None:
				r_dmy_covars_long = dmy_covariates
			for i in range(s-1):
				r_dmy_factor1_long = np.concatenate((r_dmy_factor1_long,dmy_factor1),0)
				if dmy_covariates is not None:
					r_dmy_covars_long = np.concatenate((r_dmy_covars_long, dmy_covariates),0)
			exog_vars = stack_ones(r_dmy_factor1_long)
			if dmy_covariates is not None:
				exog_vars = np.column_stack((exog_vars, r_dmy_covars_long))
			a = cy_lin_lstsqr_mat(exog_vars,endog_arr)
			endog_arr = endog_arr - np.dot(exog_vars,a)
		np.random.shuffle(endog_arr)
		dmy_factor1 = dmy_factor1[rand_array]
		if dmy_covariates is not None:
			dmy_covariates = dmy_covariates[rand_array]

	# convert to exogenous variables to long form
	interval_long = np.zeros(n)
	dmy_factor1_long = dmy_factor1
	dmy_subjects_long = dmy_subjects
	if dmy_covariates is not None:
		dmy_covars_long = dmy_covariates
	for i in range(s-1):
		dmy_factor1_long = np.concatenate((dmy_factor1_long,dmy_factor1),0)
		dmy_subjects_long = np.concatenate((dmy_subjects_long,dmy_subjects),0)
		interval_long = np.concatenate((interval_long, np.ones(n)*(i+1)))
		if dmy_covariates is not None:
			dmy_covars_long = np.concatenate((dmy_covars_long, dmy_covariates),0)
	dmy_interval_long = dummy_code(interval_long, demean = False)

	# SS Totals
	exog_vars = stack_ones(dmy_subjects_long)
	endog_arr = np.squeeze(endog_arr)
	SS_WithinSubjects = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_Total = np.sum((endog_arr - np.mean(endog_arr, axis = 0))**2, axis = 0)
	SS_BetweenSubjects = SS_Total - SS_WithinSubjects

	# SS between subject
	exog_vars = stack_ones(dmy_factor1_long)
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
	if output_reduced_residuals:
		a, residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)
		reduced_data = endog_arr - np.dot(exog_vars,a)
		del a
	else:
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_cells_a = SS_Total - residuals

	if dmy_covariates is not None:
		exog_vars = stack_ones(dmy_covars_long)
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_covars =(SS_Total - residuals)
	else:
		SS_covars = 0

	SS_a = SS_cells_a - SS_covars
	SS_WithinFactors = SS_BetweenSubjects - SS_a - SS_covars

	# SS time
	exog_vars = stack_ones(dmy_interval_long)
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_s =  SS_Total - residuals

	# SS covariates (same as above int then minus int)
	if dmy_covariates is not None:
		exog_vars = stack_ones(dmy_covars_long)
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
		exog_vars = np.column_stack((exog_vars, dmy_interval_long))
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_cells_scovars = (SS_Total - residuals)
		exog_vars = stack_ones(dmy_covars_long)
		exog_vars = np.column_stack((exog_vars, dmy_interval_long))
		residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
		SS_scovars = SS_cells_scovars - (SS_Total - residuals)
	else:
		SS_scovars = 0

	# SS Cells s*a
	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	exog_vars = np.column_stack((exog_vars, column_product(dmy_factor1_long,dmy_interval_long)))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_Cells_sa = (SS_Total - residuals)

	exog_vars = stack_ones(dmy_factor1_long)
	exog_vars = np.column_stack((exog_vars, dmy_interval_long))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covars_long))
		exog_vars = np.column_stack((exog_vars, column_product(dmy_covars_long,dmy_interval_long)))
	residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog_arr)[1]
	SS_sa = SS_Cells_sa - (SS_Total - residuals)

	SS_sWithinFactors = SS_WithinSubjects - SS_s - SS_sa - SS_scovars

	# Between subjects df
	df_BetweenSubjects  = n - 1
	df_a =  fa - 1
	if dmy_covariates is not None:
		if dmy_covariates.ndim == 1:
			df_covars = 1
		else:
			df_covars = dmy_covariates.shape[1]
	else:
		df_covars = 0
	df_WithinFactors = df_BetweenSubjects - df_a - df_covars

	# Within subjects df
	df_s = s - 1
	df_sa = df_a * df_s
	df_sWithinFactor = df_WithinFactors * df_s

	# F-stats
	# Between subjects
	ms_WithinFactors = np.divide(SS_WithinFactors, df_WithinFactors)
	F_a = np.divide(np.divide(SS_a, df_a), ms_WithinFactors)

	# Within subjects
	ms_sWithinFactor = np.divide(SS_sWithinFactors, df_sWithinFactor)
	F_s = np.divide(np.divide(SS_s, df_s), ms_sWithinFactor)

	F_sa = np.divide(np.divide(SS_sa, df_sa), ms_sWithinFactor)

	if verbose:
		print("Source\t\tDF\tF(Max)")
		print("Factor\t\t(%d,%d)\t%.2f" % (df_a, df_WithinFactors, F_a.max()))
		print("Time\t\t(%d,%d)\t%.2f" % (df_s, df_sWithinFactor, F_s.max()))
		print("Factor*Time\t(%d,%d)\t%.2f" % (df_sa, df_sWithinFactor, F_sa.max()))

	if output_sig:
		# Between subjects
		P_a = 1 - f.cdf(F_a,df_a,df_WithinFactors)
		# Within subjects
		P_s = 1 - f.cdf(F_s,df_s,df_sWithinFactor)
		P_sa = 1 - f.cdf(F_sa,df_sa,df_sWithinFactor)
		return (F_a, F_s, F_sa, P_a, P_s, P_sa)
	else:
		if output_reduced_residuals:
			return (F_a, F_s, F_sa, reduced_data)
		else:
			return (F_a, F_s, F_sa)
tfce_mediation/pyfunc.py
def import_voxel_neuroimage(image_path, mask_index = None):
	"""
	Low-RAM voxel-image importer using nibabel

	Parameters
	----------
	image_path : string
		PATH/TO/IMAGE

	Flags
	----------
	mask_index : index array (bool or binary)
		Masks the image by non-zero index (Default = None)

	Returns
	-------
	image : array
		nibable image object

	OR

	image_data : array
		numpy array of masked image data

	"""
	if not os.path.exists(image_path):
		print('Error: %s not found' % image_path)
		quit()
	base, file_ext = os.path.splitext(image_path)
	if file_ext == '.gz':
		file_ext = os.path.splitext(base)[1]
		if file_ext == '.nii':
			if os.path.getsize(image_path) < 50000000:
				image = nib.load(image_path)
				image_data = image.get_data()
			else:
				tempname = str(uuid.uuid4().hex) + '.nii'
				os.system("zcat %s > %s" % (image_path,tempname))
				image = nib.load(tempname)
				image_data = image.get_data()
				os.system("rm %s" % tempname)
		else:
			print('Error: filetype for %s is not supported' % image_path)
	elif file_ext == '.nii':
		image = nib.load(image_path)
		image_data = image.get_data()
	elif file_ext == '.mnc':
		image = nib.load(image_path)
		image_data = image.get_data()
	else:
		print('Error filetype for %s is not supported' % file_ext)
		quit()
	print("Imported:\t%s" % image_path)
	if mask_index is not None:
		image_data = image_data[mask_index]
		return image_data
	else:
		return image, image_data
tfce_mediation/pyfunc.py
def glm_typeI(endog, exog, dmy_covariates = None, output_fvalues = True, output_tvalues = False, output_pvalues = False, verbose = True, rand_array = None, use_reduced_residuals = False, output_reduced_residuals = False, exog_names = None):
	"""
	Generalized ANCOVA using Type I Sum of Squares

	Parameters
	----------
	endog : array
		Endogenous (dependent) variable array (Nsubjects, Nvariables)
	exog : array
		Exogenous (independent) dummy coded variables
		exog is an array of arrays (Nvariables, Nsubjects, Kvariable)
	dmy_covariates : array
		Dummy coded array of covariates of no interest

	Returns
	---------
	To-do
	"""

	n = endog.shape[0]

	kvars = []
	exog_vars = np.ones((n))
	for var in exog:
		var = np.array(var)
		if var.ndim == 1:
			kvars.append((1))
		else:
			kvars.append((var.shape[1]))
		exog_vars = np.column_stack((exog_vars,var))
	if dmy_covariates is not None:
		exog_vars = np.column_stack((exog_vars, dmy_covariates))
	exog_vars = np.array(exog_vars)

	if rand_array is not None:
		if use_reduced_residuals:
			a = cy_lin_lstsqr_mat(exog_vars,endog)
			endog = endog - np.dot(exog_vars,a)
		exog_vars = exog_vars[rand_array]

	if output_reduced_residuals:
		a = cy_lin_lstsqr_mat(exog_vars,endog)
		reduced_data = endog - np.dot(exog_vars,a)

	k = exog_vars.shape[1]

	DF_Between = k - 1 # aka df model
	DF_Within = n - k # aka df residuals
	DF_Total = n - 1

	SS_Total = np.sum((endog - np.mean(endog,0))**2,0)
	a, SS_Residuals = cy_lin_lstsqr_mat_residual(exog_vars,endog)

	if output_fvalues:
		SS_Between = SS_Total - SS_Residuals
		MS_Residuals = (SS_Residuals/DF_Within)
		Fvalues = (SS_Between/DF_Between) / MS_Residuals

		if verbose:
			print("Source\t\tDF\tF(Max)")
			print("Model\t\t(%d,%d)\t%.2f" % (DF_Between, DF_Within, Fvalues.max()))

		# F value for exog
		Fvar = []
		Pvar = []
		start = 1
		for i, col in enumerate(kvars):
			stop = start + col
			SS_model = np.array(SS_Total - cy_lin_lstsqr_mat_residual(np.delete(exog_vars,np.s_[start:stop],1),endog)[1])
			Ftemp = (SS_Between - SS_model)/(MS_Residuals*kvars[i])
			Fvar.append(Ftemp)
			if verbose:
				if exog_names is not None:
					print("%s\t\t(%d,%d)\t%.2f" % (exog_names[i], col, DF_Within, Ftemp.max()))
				else:
					print("Exog%d\t\t(%d,%d)\t%.2f" % ((i+1), col, DF_Within, Ftemp.max()))
			start += col
			if output_pvalues:
				Pvar.append(f.sf(Fvar[i],col,DF_Within))

	if output_tvalues:
		sigma2 = np.sum((endog - np.dot(exog_vars,a))**2,axis=0) / (n - k)
		invXX = np.linalg.inv(np.dot(exog_vars.T, exog_vars))
		if endog.ndim == 1:
			se = np.sqrt(np.diag(sigma2 * invXX))
		else:
			num_depv = endog.shape[1]
			se = se_of_slope(num_depv,invXX,sigma2,k)
		Tvalues = a / se
	# return values
	if output_tvalues and output_fvalues:
		if output_pvalues:
			Pmodel = f.sf(Fvalues,DF_Between,DF_Within)
			Pvalues = t.sf(np.abs(Tvalues), DF_Total)*2
			return (Fvalues, np.array(Fvar), Tvalues, Pmodel, np.array(Pvar), Pvalues)
		else:
			if output_reduced_residuals:
				return (Fvalues, np.array(Fvar), Tvalues, reduced_data)
			else:
				return (Fvalues, np.array(Fvar), Tvalues)
	elif output_tvalues:
		if output_pvalues:
			Pvalues = t.sf(np.abs(Tvalues), DF_Total)*2
			return (Tvalues, Pvalues)
		else:
			if output_reduced_residuals:
				return (Tvalues, reduced_data)
			else:
				return Tvalues
	elif output_fvalues:
		if output_pvalues:
			Pmodel = f.sf(Fvalues,DF_Between,DF_Within)
			return (Fvalues, np.array(Fvar), Pmodel, np.array(Pvar))
		else:
			if output_reduced_residuals:
				return (Fvalues, np.array(Fvar), reduced_data)
			else:
				return (Fvalues, np.array(Fvar))
	else:
		print("No output has been selected")

Answer: _, _, _, _, _, _, _, _, _, tAMPLITUDE_A, _, _ = glm_cosinor(endog = dmy_mediator,