###################### percentile.py ###################################################

# This script calculates the percentile for columns in a given dataset in ArrayAssist.
# The user interface allows the user to give a percentile p and select continuous columns.
# For each one of these selected continuous columns from the dataset, the
# p percentile value for columns are displayed in a table

#########################################################################################

# Including libraries.
from script.algorithm import *
from script.view import *
from script.dataset import *
from script.omega import createComponent, showDialog
from com.strandgenomics.cube.dataset import ColumnFactory, DatasetFactory
from com.strandgenomics.cube.dataset import DatasetUtil
from java.lang import Float
from javax.swing import *
import string, math


# Function for finding percentile value for data in a column.
def findPercentile(aslist, perc):
	perc = perc/100.0
	numPoints = len(aslist)
	number = (numPoints + 1)*perc
	# For a given number of data points, there is an upper and lower limits to percentiles 
	upper_p = numPoints*1.0/((numPoints + 1)*1.0)
	lower_p = 1.0/(numPoints + 1)
	integerNum = int(number)
	fractionNum = number - integerNum
	if perc > lower_p and perc < upper_p :
		percentilePoint = (1.0 - fractionNum)*aslist[integerNum - 1] + fractionNum*aslist[integerNum]
	#If the requested percentile is lower than the lower limit, take first data point as percentile.
	if perc <= lower_p:
		percentilePoint = aslist[0]
	#If the requested percentile is higher than the higher limit, take last data point as percentile.
	if perc >= upper_p:
		percentilePoint = aslist[numPoints-1]
	return percentilePoint

# Function for opening a dialog box for input data.
def openDialogBox1():
	p1 = createComponent(type="float", id="num", description="Percentile" )
	p2 = createComponent(type="columnlist", columnType = "continuous", id="cont", description="Continuous", dataset=d )
	panel = createComponent(type="Group", id="both_boxes",description="Percentile Computation", components=[p1,p2])  
	res = showDialog(panel)
	pc = p1.getValue()
	listContCol = script.coercion.to_py(p2.getValue())
	return res, pc, listContCol




# Main script starts here.

#get current data set
node=script.project.getActiveDatasetNode()
d=node.getDataset()

[result, percentile, contColList] = openDialogBox1()

nameList = []
numberList = []

# Calculating percentile values for all columns in the dataset.
if result!=None:
	if percentile>0.0 and percentile<100.0:
		round1=round(percentile,3)
		for colnum in contColList:
			rorder = d[colnum].getRowIndicesInSortedOrder(1)
			ascendList = []
			for rownum in rorder:
				if(d[colnum].isMissingValue(rownum) == 0): 
					ascendList.append(d[colnum][rownum])
			percentilePoint = findPercentile(ascendList, percentile)
			round2 = round(percentilePoint, 5)
			nameList.append(d[colnum].getName())
			numberList.append(round2)
		# Displaying results in a table.
		c1 = script.dataset.createStringColumn("Column Name", nameList)
		displayString = "Percentile " + str(percentile)
		c2 = script.dataset.createFloatColumn(displayString, numberList)
		cols = (c1, c2)
		disp = DatasetFactory.createDataset("dataset", cols)
		script.view.Table(title="Percentile", dataset=disp, sortEnabled=0).show()
			
	else:
		script.omega.error("Illegal entry: Float value greater than 0.0 and less than 100.0 expected for Percentile")




