compute_all_pA <- function(expressiondata_normal, expressiondata_cancer) {	
#both matrices should use genes as rows, samples as columns
#use closest normal to each tumor to deconvolve
	
	pairwise_cor = cor(expressiondata_cancer, expressiondata_normal,method='spearman');
	
	if (length(pairwise_cor)==1) {normal_indices = 1;}
	else {normal_indices = apply(pairwise_cor,1,which.max);}
	
	all_pCancer = rep(NA, ncol(expressiondata_cancer));
	
	for (ii in 1:length(all_pCancer)) {
		all_pCancer[ii] = 1-clarke_compute_pA(expressiondata_normal[,normal_indices[ii]], expressiondata_cancer[,ii]);
	}
	
	all_pCancer
}

clarke_compute_pA <- function(expressiondataA, expressiondataAB) {
#	01.13.2010
#	R code to implement method for estimation of proportion of
#	one sample type (A) in a two sample mixture (A and B), by method 
#	of clarke et al. 
#
#   returns pA, the proportion of sample AB that is due to A
#
#   expressiondataA and expressiondataAB should be column vectors of expression data, in linear domain
#exprs <- as.matrix(read.table("E-GEOD-5130-processed-data-titration-2-exp.txt", header = TRUE, sep = "\t", row.names = 1, as.is = TRUE))
exprs = cbind(expressiondataA,expressiondataAB);

#do gene subset selection to find only those genes that are expressed, analogous to pvalue detection used in original code
#we assume top half of genes expressed in sample are present.
idt=intersect(which(exprs[,1] > median(exprs[,1])), which(exprs[,2] > median(exprs[,2])));
exprs = exprs[idt,];
	
## can we determine alpha from mean(Ri) or median(Ri)?
# note: if you have more than one sample at each value of p, you can use
# the average across samples in the estimation process 

# guess an initial range for alpha, the parameter for the data transformation
KK=2000; #number of alpha to try
alpha<-seq(from=0.001,to=10,length.out=KK)

#exprs-- 2 column dataset, first column is pure sample A, second column is mixture AB, trying to compute pA, fraction of AB that is A
alpha_data = matrix(NA, KK, 6);

#column names of alpha will be alpha, mean transformed ratio (meantRi), median transformed ratio (mediantRi), minimum transformed ratio (mintRi), arc length s (s), and a statistic we need to compute radius of curvature, 
# || f''(...)||   (radiusstat)
colnames(alpha_data) = c('alpha','meantRi','mediantRi','mintRi','s','radiusstat');
alpha_data = as.data.frame(alpha_data);
alpha_data$alpha = alpha;

for(ii in 1:KK){
	tE<-log(1+ alpha[ii]*exprs)
	tE_A<-tE[,1]
	tE_AB<-tE[,2]
	tRi<-tE_AB/tE_A
	alpha_data$mintRi[ii] = min(tRi)

	alpha_data$meantRi[ii] = mean(tRi)
	alpha_data$mediantRi[ii] = median(tRi)
}

#we need to re-scale mean(tRi) and median(tRi)
alpha_data$meantRi = ((max(alpha_data$alpha)-min(alpha_data$alpha)) * (alpha_data$meantRi-min(alpha_data$meantRi))) / (max(alpha_data$meantRi) - min(alpha_data$meantRi));
alpha_data$mediantRi = ((max(alpha_data$alpha)-min(alpha_data$alpha)) * (alpha_data$mediantRi-min(alpha_data$mediantRi))) / (max(alpha_data$mediantRi) - min(alpha_data$mediantRi));

#########
# we will assume we are going to use meantRi, not mediantRi, to compute pA
#compute s (arc length) values.  needs to be done after rescaling.  
#arc length for 1st alpha is 0
alpha_data$s[1] = 0; 

#we need to compute derivative(mean(tR(\alpha_i))) as in paper
approx_derivatives = (alpha_data$meantRi[2:KK] - alpha_data$meantRi[1:(KK-1)])/(alpha_data$alpha[2:KK] - alpha_data$alpha[1:(KK-1)]);
for(ii in 2:(KK-1)){
	alpha_data$s[ii] = sum(sqrt(1 + (approx_derivatives[2:ii]^2)) * (1/(alpha_data$alpha[2:ii] - alpha_data$alpha[1:(ii-1)])));
}

#compute summary statistic for radius of curvature, || f''(...) ||
#has to wait till we are done computing arc lengths s, because of certain approximations
#also has to start at ii=2 because the center difference approximation needs points before and after the current point
#set first radiussatat to negative infinity so it is never chosen as the best value
alpha_data$radiusstat[1]=-Inf;
for(ii in 2:KK){
	alpha_data$radiusstat[ii] = abs(    (alpha_data$meantRi[ii+1]- 2*alpha_data$meantRi[ii] + alpha_data$meantRi[ii-1])/((alpha_data$s[ii]-alpha_data$s[ii-1])^2)              ); 
}

alpha_best_ix = which.max(alpha_data$radiusstat);

pA = alpha_data$mintRi[alpha_best_ix];
pA

##diagnostics
## make plot of mean Ri across values of alpha
#plot(1:length(alpha_data$alpha),alpha_data$meantRi)
##points(1:length(alpha_data$alpha),alpha_data$mediantRi,col="red")
##legend("bottomright",c("mean","median"),pch=1,col=c("black","red"))
## add vertical line to plot to indicate minimum radius of curvature
#lines(c(alpha_best_ix,alpha_best_ix),c(0,10))
	
	

}

