def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None):
	
	valsOnly = []
	dataXZ = vals[:]
	for i in range(len(dataXZ)):
		valsOnly.append(dataXZ[i][1])		
	
	traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future
	
	tbl = HT.TableLite(cellpadding=20, cellspacing=0)
	dataXZ = vals[:]
	dataXZ.sort(webqtlUtil.cmpOrder)
	tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180),
			HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60)))
	tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"),
			HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	#tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
	#		HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222")))
	tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	if (trait_type != None and trait_type == 'ProbeSet'):
			#IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14")
			#IRQuest.append(HT.BR())
			#IRQuest.append(" (fold difference)")
			tbl.append(HT.TR(HT.TD("Range (log2)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
				HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
			tbl.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
				HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
			tbl.append(HT.TR(HT.TD(HT.Span(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold")), align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
				HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	
			#XZ, 04/01/2009: don't try to get H2 value for probe.
			if cellid:
				pass
			else:
				if heritability:
					tbl.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
				else:
					pass
			# Lei Yan
			# 2008/12/19
	
	return tbl	
def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None, trait=None):
	
	valsOnly = []
	dataXZ = vals[:]
	for i in range(len(dataXZ)):
		valsOnly.append(dataXZ[i][1])		
	
	traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future
	
	tbl = HT.TableLite(cellpadding=20, cellspacing=0)
	dataXZ = vals[:]
	dataXZ.sort(webqtlUtil.cmpOrder)
	tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180),
			HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60)))
	tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"),
			HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	#tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
	#		HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222")))
	tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
			HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
	if (trait_type != None and trait_type == 'ProbeSet'):
		if trait != None and trait.db.datascale == "linear":
			try:
				tbl.append(HT.TR(
					HT.TD("Range", align="left", Class="fs13 b1 cbw c222", nowrap="yes"),
					HT.TD("%2.3f" % (dataXZ[-1][1] - dataXZ[0][1]), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
			except Exception, e:
				pass
			try:
				tbl.append(HT.TR(
					HT.TD("Range (fold)", align="left", Class="fs13 b1 cbw c222", nowrap="yes"),
					HT.TD("%2.3f" % pow(2.0, (dataXZ[-1][1] - dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
			except Exception, e:
				pass
			try:
				tbl.append(HT.TR(
					HT.TD(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold"), align="left", Class="fs13 b1 cbw c222", nowrap="yes"),
					HT.TD("%2.3f" % pow(2.0, (dataXZ[int((N-1)*3.0/4.0)][1] - dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
			except Exception, e:
				pass
	def __init__(self, fd):

		templatePage.__init__(self, fd)

		if not self.openMysql():
			return
		
		fd.readGenotype()
		TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')
		self.database = fd.formdata.getfirst('database')
		self.ProbeSetID = fd.formdata.getfirst('ProbeSetID')
		self.CellID = fd.formdata.getfirst('CellID')
		
		self.db = webqtlDataset(self.database, self.cursor)
		thisTrait = webqtlTrait(db= self.db, cursor=self.cursor, name=self.ProbeSetID) #, cellid=CellID)
		thisTrait.retrieveInfo()
		
		try:
			self.cursor.execute('SELECT ProbeFreeze.Name FROM ProbeFreeze,ProbeSetFreeze WHERE ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId and ProbeSetFreeze.Name = "%s"' % self.db.name)
			self.probeDatabase = self.cursor.fetchall()[0][0]
			self.probeInfoDatabase = 'Probe'
		except:
			heading = 'Probe Information'
			intro = ['Trying to retrieve the probe information for ProbeSet ',HT.Span('%s' % self.ProbeSetID, Class="fwb cdg"),' in Database ',HT.Href(text='%s' % self.db.fullname,url=webqtlConfig.infopagehref % self.database)]
			detail = ['The information you just requested is not available at this time.']
			self.error(heading=heading,intro=intro,detail=detail)
			return


		form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name='showDatabase', submit=HT.Input(type='hidden'))
		hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','RISet':fd.RISet, 'incparentsf1':'on'}
		if fd.RISet == 'BXD':
			hddn['parentsf1']='ON'
			
		for key in hddn.keys():
			form.append(HT.Input(name=key, value=hddn[key], type='hidden'))


		#Buttons on search page
		linkinfo ="%s/probeInfo.html" % webqtlConfig.PORTADDR
		mintmap = "" 
		probeinfo = HT.Input(type='button' ,name='mintmap',value='Info', onClick="openNewWin('%s');" % linkinfo, Class="button")
		cormatrix = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('showDatabase')[0], 'corMatrix');")
		cormatrix_img = HT.Image("/images/correlation_matrix1_final.jpg", alt="Correlation Matrix and PCA", title="Correlation Matrix and PCA", style="border:none;")
		cormatrix.append(cormatrix_img)
		heatmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('showDatabase')[0], 'heatmap');")
		heatmap_img = HT.Image("/images/heatmap2_final.jpg", name='mintmap', alt="QTL Heat Map and Clustering", title="QTL Heatmap and Clustering", style="border:none;")
		heatmap.append(heatmap_img)
		if self.ProbeSetID[-2:] in ('_A', '_B'):
			thisProbeSetID = self.ProbeSetID[:-2]
		else:
			thisProbeSetID = self.ProbeSetID
		thisurl = 'http://www.ensembl.org/Mus_musculus/featureview?type=AffyProbe&id=%s' % thisProbeSetID
		verifyButton = HT.Input(type="button",value="Verify Ensembl",onClick= "openNewWin('%s')" % thisurl, Class="button")
		
		addselect = HT.Input(type='button' ,name='addselect',value='Add to Collection', onClick="addRmvSelection('%s', this.form, 'addToSelection');"  % fd.RISet,Class="button")
		selectall = HT.Input(type='button' ,name='selectall',value='Select All', onClick="checkAll(this.form);",Class="button")
		selectpm = HT.Input(type='button' ,name='selectall',value='Select PM', onClick="checkPM(this.form);",Class="button")
		selectmm = HT.Input(type='button' ,name='selectall',value='Select MM', onClick="checkMM(this.form);",Class="button")
		selectinvert = HT.Input(type='button' ,name='selectinvert',value='Select Invert', onClick="checkInvert(this.form);",Class="button")
		reset = HT.Input(type='reset',name='',value='Select None',Class="button")
		chrMenu = HT.Input(type='hidden',name='chromosomes',value='all')
		probedata = HT.Input(type='hidden',name='probedata',value='all')
		
		url_rudi_track = self.getProbeTrackURL(self.probeDatabase, self.ProbeSetID)
		if url_rudi_track:		
		   rudi_track = HT.Input(type='button', name='ruditrack', value='Probe Track', onClick="openNewWin('%s')"%url_rudi_track, Class="button")
		else: rudi_track = None
		
		pinfopage = "/probeInfo.html"
		
		#updated by NL: 07-22-2011  get chosenStrains
		_f1, _f12, _mat, _pat = webqtlUtil.ParInfo[fd.RISet]
		chosenStrains="%s,%s"%(_mat,_pat)
		tblobj = {}
		tblobj['header']=[]

		tblobj['header'].append([
			THCell(HT.TD("", Class="cbrb cw fwb fs13 b1", rowspan=2,nowrap='ON'), sort=0),
			THCell(HT.TD(HT.Href(target="_PROBEINFO", url=pinfopage+"#probe", text=HT.Span('Probe', Class="cw fwb fs13")), HT.Sup(HT.Italic('1')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,nowrap='ON'), text="probe", idx=1), 
			THCell(HT.TD(HT.Href(text=HT.Span('Sequence', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#Sequence"),HT.Sup(HT.Italic('2')), Class="cbrb cw fwb fs13 b1", align='center',rowspan=2,nowrap='ON'), text="seq", idx=2), 
			THCell(HT.TD(HT.Href(text=HT.Span('bl2seq', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#bl2seq"),HT.Sup(HT.Italic('3')), Class="cbrb cw fwb fs13 b1", align='center',rowspan=2,nowrap='ON'), sort=0), 
			THCell(HT.TD(HT.Href(text=HT.Span('Exons', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#Exon"),HT.Sup(HT.Italic('4')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,nowrap='ON'), sort=0),
			THCell(HT.TD(HT.Href(text=HT.Span('Tm °C', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#Tm"),HT.Sup(HT.Italic('5')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,nowrap='ON'), text="tm", idx=5),
			THCell(HT.TD(HT.Href(text=HT.Span('Stacking Energy K', HT.Sub('B'),'T', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#KBT"),HT.Sup(HT.Italic('6')), Class="cbrb cw fwb fs13 b1",align='center',colspan=2,NOWRAP="yes",nowrap='ON'), sort=0),
			THCell(HT.TD(HT.Href(text=HT.Span('Mean', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#Mean"),HT.Sup(HT.Italic('7')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,nowrap='ON'), text="mean", idx=8),
			THCell(HT.TD(HT.Href(text=HT.Span('Stdev', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#Stdev"),HT.Sup(HT.Italic('8')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,nowrap='ON'), text="std", idx=9),
			THCell(HT.TD(HT.Href(text=HT.Span('Probe h2', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#h2"),HT.Sup(HT.Italic('9')), Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,NOWRAP="yes"), text="h2", idx=10),
			THCell(HT.TD(HT.Href(text=HT.Span('Probe Location', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#location"), HT.Sup(HT.Italic('10')),Class="cbrb cw fwb fs13 b1",align='center',colspan=3)),
			THCell(HT.TD(HT.Href(text=HT.Span('SNPs', HT.BR(), '(Across all strains)', Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#snps"), HT.Sup(HT.Italic('11')),Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,NOWRAP="yes")),
			THCell(HT.TD(HT.Href(text=HT.Span('SNPs', HT.BR(),'(Different alleles only between %s and %s)'%(_mat,_pat), Class="cw fwb fs13"), target="_PROBEINFO", url=pinfopage+"#snps"), HT.Sup(HT.Italic('11')),Class="cbrb cw fwb fs13 b1",align='center',rowspan=2,NOWRAP="yes"))

		])
		
		tblobj['header'].append([
			THCell(HT.TD(HT.Span('GSB', Class="cw fwb fs13"),align='center', Class="cbrb ffl fwb fs13 b1",), text="gsb", idx=6),
			THCell(HT.TD(HT.Span('NSB', Class="cw fwb fs13"),align='center', Class="cbrb ffl fwb fs13 b1",), text="nsb", idx=7),
			THCell(HT.TD(HT.Span('Chr', Class="cw fwb fs13"), align='center', Class="cbrb ffl2 fwb fs13 b1",)),
			THCell(HT.TD(HT.Span('Start', Class="cw fwb fs13"),align='center', Class="cbrb ffl fwb fs13 b1",)),
			THCell(HT.TD(HT.Span('End', Class="cw fwb fs13"),align='center', Class="cbrb ffl fwb fs13 b1",)),
		])
		
		tblobj['body'] = []
		
		blatbutton = ''

		fetchField = ['Probe.Name','Probe.Sequence','Probe.ExonNo','Probe.Tm', 'Probe.E_GSB','Probe.E_NSB', 'ProbeH2.h2', 'ProbeH2.weight']

		query = "SELECT %s FROM (Probe, ProbeSet, ProbeFreeze) left join ProbeH2  on ProbeH2.ProbeId = Probe.Id and ProbeH2.ProbeFreezeId = ProbeFreeze.Id WHERE ProbeSet.Name = '%s' and Probe.ProbeSetId = ProbeSet.Id and ProbeFreeze.Name = '%s' order by Probe.SerialOrder" % (string.join(fetchField,','), self.ProbeSetID, self.probeDatabase)
		self.cursor.execute(query)
		results = self.cursor.fetchall()
		
		blatsequence = ""
		
		# add by NL: get strains' name in SnpPattern database table
		strainsInSnpPatternDBtable=self.getStrainNameIndexPair()  # after snpBrowserPage.py change to MVC, this function can be removed in this class and called from other class; 
		allStrainNameList=[v[0] for v in strainsInSnpPatternDBtable]
			
		speciesid = webqtlDatabaseFunction.retrieveSpeciesId(cursor=self.cursor,RISet=fd.RISet)
		for result in results:
			"""
			ProbeId, CellID,Sequence,ExonNo,Tm, E_GSB,E_NSB = map(self.nullRecord,result)
			h2 = ''
			query = "SELECT h2 FROM ProbeH2 WHERE ProbeFreezeId = '%s' and ProbeId=%s" % (self.probeDatabase, ProbeId)
			self.cursor.execute(query)
			results = self.cursor.fetchall()
			"""

			CellID,Sequence,ExonNo,Tm, E_GSB,E_NSB,h2, weight = map(self.nullRecord,result)
			
	
			Average = ''
			STDEV = ''
			mean = -10000.0
			stdev = -10000.0
			try:
				thisTrait.cellid = CellID
				thisTrait.retrieveData()
		
				mean, median, var, stdev, sem, N = reaper.anova(thisTrait.exportInformative()[1])
			
				if mean:
					Average = '%2.2f' % mean
				if stdev:
					STDEV = '%2.2f' % stdev
			except:
				pass

			if CellID == self.CellID:
				bkColor = "cbrdull fs11 b1"
			else:
				bkColor = "fs11 b1"
			seqcolor= ''
			
			if thisTrait.blatseq:
				blatsequence = thisTrait.blatseq
				if int(CellID[-1]) % 2 == 1:
					seqcolor= 'cdg'
			else:
				if int(CellID[-1]) % 2 == 1:
					seqcolor= 'cdg'
					blatsequence += string.strip(Sequence)
						
			if thisTrait.genbankid  and (int(CellID[-1]) % 2 == 1):
				probeurl = 'http://www.ncbi.nlm.nih.gov/blast/bl2seq/wblast2.cgi?one=%s&sseq=%s'  % (thisTrait.genbankid, Sequence)
				probefy1 = HT.Input(type="button",value="Blast",onClick= "openNewWin('%s')" % probeurl, Class="buttonsmaller")
			else:  
				probefy1 = ''
			
			traitName = str(thisTrait)

			#XZ, Aug 08, 2011: Note that probesets on some affy chips are not name as "xxx_at" (i.e., Affy Mouse Gene 1.0 ST (GPL6246)). 
			#EnsemblProbeSetID = self.ProbeSetID[0:self.ProbeSetID.index('_at')+3]
			EnsemblProbeSetID = self.ProbeSetID
			if '_at' in self.ProbeSetID:
				EnsemblProbeSetID = self.ProbeSetID[0:self.ProbeSetID.index('_at')+3]

			self.cursor.execute('''
					SELECT EnsemblProbeLocation.* 
					FROM EnsemblProbeLocation, EnsemblProbe, EnsemblChip, GeneChipEnsemblXRef, ProbeFreeze
					WHERE EnsemblProbeLocation.ProbeId=EnsemblProbe.Id and EnsemblProbe.ChipId=GeneChipEnsemblXRef.EnsemblChipId and
						GeneChipEnsemblXRef.GeneChipId=ProbeFreeze.ChipId and EnsemblProbe.Name=%s and EnsemblProbe.ProbeSet=%s and 
						ProbeFreeze.Name=%s group by Chr, Start, End'''
					,(CellID, EnsemblProbeSetID, self.probeDatabase))
			LocationFields = self.cursor.fetchall()

			Chr=''
			Start=''
			End=''
			if (len(LocationFields)>=1):
				Chr,Start,End,Strand,MisMatch,ProbeId = map(self.nullRecord,LocationFields[0])
				Start /= 1000000.0
				End /= 1000000.0
			if (len(LocationFields)>1):
				self.cursor.execute('''
						SELECT ProbeSet.Chr, ProbeSet.Mb FROM ProbeSet, ProbeFreeze 
						WHERE ProbeSet.ChipId=ProbeFreeze.ChipId and ProbeSet.Name=%s and ProbeFreeze.Name=%s'''
						,(self.ProbeSetID, self.probeDatabase))
				ProbeSetChr, ProbeSetMb = map(self.nullRecord,self.cursor.fetchall()[0])
					
				self.cursor.execute('''
						SELECT EnsemblProbeLocation.*, ABS(EnsemblProbeLocation.Start/1000000-%s) as Mb 
						FROM EnsemblProbeLocation, EnsemblProbe, EnsemblChip, GeneChipEnsemblXRef, ProbeFreeze
						WHERE EnsemblProbeLocation.ProbeId=EnsemblProbe.Id and EnsemblProbe.ChipId=GeneChipEnsemblXRef.EnsemblChipId and
							GeneChipEnsemblXRef.GeneChipId=ProbeFreeze.ChipId and EnsemblProbe.Name=%s and EnsemblProbe.ProbeSet=%s and
							EnsemblProbeLocation.Chr=%s and ProbeFreeze.Name=%s order by Mb limit 1'''
						,(ProbeSetMb, CellID, EnsemblProbeSetID, ProbeSetChr, self.probeDatabase))
				NewLocationFields = self.cursor.fetchall()
				if (len(NewLocationFields)>0):
					Chr,Start,End,Strand,MisMatch,ProbeId,Mb = map(self.nullRecord,NewLocationFields[0])
					Start /= 1000000.0
					End /= 1000000.0
					
			snp_collection = []	
			snpDiff_collection=[]
			
			startIndex=3
			if Chr != '' and Start != '' and End != '' and speciesid != None:
									
				self.cursor.execute('''
						   SELECT a.SnpName, a.Id, b.* FROM SnpAll a, SnpPattern b
						   WHERE a.Chromosome=%s and a.Position>=%s and a.Position<=%s 
						   and a.SpeciesId=%s and a.Id=b.SnpId'''
							,(Chr, Start, End, speciesid)) #chr,Start, End, 1))							
				snpresults = self.cursor.fetchall()
				
				index1=allStrainNameList.index(_mat) #_mat index in results
				index2=allStrainNameList.index(_pat) #_pat index in results
			
				for v in snpresults:
					#updated by NL: 07-22-2011  check 'limit to' to get snpBrowser snpresults
					snp_collection.append(HT.Href(text=v[0], url=os.path.join(webqtlConfig.CGIDIR, 
							"main.py?FormID=SnpBrowserResultPage&submitStatus=1&customStrain=1")+ "&geneName=%s" % v[0], Class="fs12 fwn", target="_blank"))
					snp_collection.append(HT.BR())
					#updated by NL: 07-27-2011  link snp info for different allele only	
					strain1_allele=v[startIndex+index1]
					strain2_allele=v[startIndex+index2]
					
					if strain1_allele!=strain2_allele:
						snpDiff_collection.append(HT.Href(text=v[0], url=os.path.join(webqtlConfig.CGIDIR, 
								"main.py?FormID=SnpBrowserResultPage&submitStatus=1&customStrain=1&diffAlleles=1&chosenStrains=%s"%chosenStrains)+ "&geneName=%s" % v[0], Class="fs12 fwn", target="_blank"))
						snpDiff_collection.append(HT.BR())
							

			tr = []	
			tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class='checkbox', name="searchResult",value=traitName, onClick="highlight(this)"), align="right", Class=bkColor, nowrap="on"), text=traitName))
			
			tr.append(TDCell(HT.TD(HT.Href(text=CellID, url = "javascript:showDatabase2('%s','%s','%s');" % (self.database,self.ProbeSetID,CellID),Class="fs12 fwn"),Class=bkColor), traitName, traitName.upper()))
			
			tr.append(TDCell(HT.TD(Sequence, Class=bkColor + " %s ffmono fs14" % seqcolor),Sequence,Sequence.upper()))
			tr.append(TDCell(HT.TD(probefy1,align='center',Class=bkColor))) 
			tr.append(TDCell(HT.TD(ExonNo,align='center',Class=bkColor)))
			
			try:
				TmValue = float(Tm)
			except:
				TmValue = 0.0
			tr.append(TDCell(HT.TD(Tm,align='center',Class=bkColor), Tm, TmValue))
			
			try:
				E_GSBValue = float(E_GSB)
			except:
				E_GSBValue = -10000.0
			tr.append(TDCell(HT.TD(E_GSB,align='center',Class=bkColor), E_GSB, E_GSBValue))

			try:
				E_NSBValue = float(E_NSB)
			except:
				E_NSBValue = -10000.0
			tr.append(TDCell(HT.TD(E_NSB,align='center',Class=bkColor), E_NSB, E_NSBValue))
			
			tr.append(TDCell(HT.TD(Average,align='center',Class=bkColor), Average, mean))
			tr.append(TDCell(HT.TD(STDEV,align='center',Class=bkColor), STDEV, stdev))

			try:
				h2Value = float(h2)
			except:
				h2Value = -10000.0
			tr.append(TDCell(HT.TD(h2,align='center',Class=bkColor), h2, h2Value))

			tr.append(TDCell(HT.TD(Chr,align='left',Class=bkColor)))
			tr.append(TDCell(HT.TD(Start,align='left',Class=bkColor)))
			tr.append(TDCell(HT.TD(End,align='left',Class=bkColor)))

			snp_td = HT.TD(align='left',Class=bkColor)
			for one_snp_href in snp_collection:
			    snp_td.append(one_snp_href)
	
			tr.append(TDCell(snp_td)) 
			
			#07-27-2011:add by NL: show SNP results for different allele only
			snpDiff_td= HT.TD(align='left', valign='top', Class=bkColor)
			for one_snpDiff_href in snpDiff_collection:
			    snpDiff_td.append(one_snpDiff_href)
			tr.append(TDCell(snpDiff_td))
			
			tblobj['body'].append(tr)
		
		# import cPickle
		filename = webqtlUtil.genRandStr("Probe_")
		objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb')
		cPickle.dump(tblobj, objfile)
		objfile.close()
		# NL, 07/27/2010. genTableObj function has been moved from templatePage.py to webqtlUtil.py;		
		div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=("", ""), tableID = "sortable", addIndex = "1"), Id="sortable")

		#UCSC
		_Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet)
		if _Species == "rat":
			thisurl = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', blatsequence)
		elif _Species == "mouse":
			thisurl = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', blatsequence)
		else:
			thisurl = ""
		if thisurl:	
			blatbutton = HT.Input(type='button' ,name='blatPM',value='Verify UCSC', onClick="window.open('%s','_blank')" % thisurl,Class="button")
		else:
			blatbutton = ""
		
		#GenBank
		genbankSeq = ""
		if thisTrait.genbankid:
			self.cursor.execute("SELECT Sequence FROM Genbank WHERE Id = '%s'" % thisTrait.genbankid )
			genbankSeq = self.cursor.fetchone()
			if genbankSeq:
				genbankSeq = genbankSeq[0]
		
		if genbankSeq: 
			if _Species == "rat":
				thisurl2 = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', genbankSeq)
			if _Species == "mouse":
				thisurl2 = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', genbankSeq)
		else:
			thisurl2 = ''
		if thisurl2:	
			blatbutton2 = HT.Input(type='button' ,name='blatPM',value='Verify GenBank', onClick="window.open('%s','_blank')" % thisurl2,Class="button")
		else:
			blatbutton2 = ""
		
		#Snp
		snpBrowser = ""
		if thisTrait.symbol and _Species == 'mouse':
			self.cursor.execute("select geneSymbol from GeneList where geneSymbol = %s", thisTrait.symbol)
			geneName = self.cursor.fetchone()
			if geneName:
				snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=snpBrowser") + "&geneName=%s" % geneName[0]	
			else:
				if thisTrait.chr and thisTrait.mb:
					snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=snpBrowser") + \
							"&chr=%s&start=%2.6f&end=%2.6f" % (thisTrait.chr, thisTrait.mb-0.002, thisTrait.mb+0.002)
				else:
					snpurl = ""

			if snpurl:
				snpBrowser = HT.Input(type="button",value="SNP Browser",onClick= \
						"openNewWin('%s')" % snpurl, Class="button")

			else:
				snpBrowser = ""
		#end if
		
		heading = HT.Paragraph('Probe Information', Class="title")
		intro = HT.Paragraph('The table below lists information of all probes of probe set ',HT.Span(self.ProbeSetID, Class="fwb fs13"),' from database ', HT.Span(self.probeDatabase, Class="fwb fs13"), ".")
		buttons = HT.Paragraph(probedata,probeinfo,heatmap,cormatrix,blatbutton,blatbutton2,verifyButton,snpBrowser, HT.P(),selectall,selectpm,selectmm,selectinvert,reset,addselect)
		if rudi_track:
		   buttons.append(rudi_track)	
		form.append(buttons,div,HT.P())
	
		TD_LR.append(heading,intro,form, HT.P())
		self.dict['basehref'] = ''
		self.dict['body'] = str(TD_LR)
		self.dict['title'] = self.db.shortname + ' : ' + self.ProbeSetID +' / Probe Information'
        # updated by NL, javascript function xmlhttpPost(strURL, div, querystring) and function updatepage(Id, str)
		# have been moved to dhtml.js
	   	self.dict['js1'] = ''
Example #4
0
def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None):
    print("basicStatsTable called - len of vals", len(vals))
    st = {}  # This is the dictionary where we'll put everything for the template
    valsOnly = []
    dataXZ = vals[:]
    for i in range(len(dataXZ)):
        valsOnly.append(dataXZ[i][1])

    (st['traitmean'],
     st['traitmedian'],
     st['traitvar'],
     st['traitstdev'],
     st['traitsem'],
     st['N']) = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future

    #tbl = HT.TableLite(cellpadding=20, cellspacing=0)
    #dataXZ = vals[:]
    dataXZ = sorted(vals, webqtlUtil.cmpOrder)

    print("data for stats is:", pf(dataXZ))
    for num, item in enumerate(dataXZ):
        print(" %i - %s" % (num, item))
    print("  length:", len(dataXZ))

    st['min'] = dataXZ[0][1]
    st['max'] = dataXZ[-1][1]

    numbers = [x[1] for x in dataXZ]
    stats = Stats(numbers)

    at75 = stats.percentile(75)
    at25 = stats.percentile(25)
    print("should get a stack")
    traceback.print_stack()
    print("Interquartile:", at75 - at25)

    #tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180),
    #                HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60)))
    #tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"),
    #                HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    #tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    #tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    ##tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    ##               HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222")))
    #tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    #tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    #tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
    #tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
    #                HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))



    if (trait_type != None and trait_type == 'ProbeSet'):
        #tbl.append(HT.TR(HT.TD("Range (log2)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
        #        HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
        #tbl.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
        #        HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
        #tbl.append(HT.TR(HT.TD(HT.Span(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold")), align="left", Class="fs13 b1 cbw c222",nowrap="yes"),
        #        HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right"))
        st['range_log2'] = dataXZ[-1][1]-dataXZ[0][1]
        st['range_fold'] = pow(2.0, (dataXZ[-1][1]-dataXZ[0][1]))
        st['interquartile'] = pow(2.0, (dataXZ[int((st['N']-1)*3.0/4.0)][1]-dataXZ[int((st['N']-1)/4.0)][1]))

        #XZ, 04/01/2009: don't try to get H2 value for probe.
        if not cellid:
            if heritability:
                # This field needs to still be put into the Jinja2 template
                st['heritability'] = heritability
                #tbl.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222")))

        # Lei Yan
        # 2008/12/19

    return st
    def __init__(self, fd):

        templatePage.__init__(self, fd)

        if not self.openMysql():
            return

        fd.incparentsf1 = 1
        if not fd.genotype:
            fd.readGenotype()

        locusChr = {}
        locusMb = {}
        for chr in fd.genotype:
            for locus in chr:
                locusChr[locus.name] = locus.chr
                locusMb[locus.name] = locus.Mb

        self.searchResult = fd.formdata.getvalue("searchResult")

        if not self.searchResult:
            templatePage.__init__(self, fd)
            heading = "Export Collection"
            detail = ["You need to select at least one trait to export."]
            self.error(heading=heading, detail=detail)
            return

        self.RISet = fd.formdata.getvalue("RISet")
        self.cursor.execute(
            "Select Species.Name from Species, InbredSet where InbredSet.SpeciesId = Species.Id and InbredSet.Name = '%s'"
            % self.RISet
        )
        self.Species = self.cursor.fetchone()[0]

        if type("1") == type(self.searchResult):
            self.searchResult = string.split(self.searchResult, "\t")
        strainlist = fd.f1list + fd.strainlist
        fields = [
            "ID",
            "Species",
            "Cross",
            "Database",
            "ProbeSetID / RecordID",
            "Symbol",
            "Description",
            "ProbeTarget",
            "PubMed_ID",
            "Phenotype",
            "Chr",
            "Mb",
            "Alias",
            "Gene_ID",
            "HomoloGene_ID",
            "UniGene_ID",
            "Strand_Probe ",
            "Strand_Gene ",
            "Probe_set_specificity",
            "Probe_set_BLAT_score",
            "Probe_set_BLAT_Mb_start",
            "Probe_set_BLAT_Mb_end ",
            "QTL_Chr",
            "QTL_Mb",
            "Locus_at_Peak",
            "Max_LRS",
            "P_value_of_MAX",
            "Mean_Expression",
        ] + strainlist

        if self.searchResult:
            traitList = []
            for item in self.searchResult:
                thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
                thisTrait.retrieveInfo(QTL=1)
                thisTrait.retrieveData(strainlist=strainlist)
                traitList.append(thisTrait)

            text = [fields]
            for i, thisTrait in enumerate(traitList):
                if thisTrait.db.type == "ProbeSet":
                    if not thisTrait.cellid:  # ProbeSet
                        # 12/22/2009, XZ: We calculated LRS for each marker(locus) in geno file and record the max LRS and its corresponding marker in MySQL database. But after the calculation, Rob deleted several markers. If one of the deleted markers happen to be the one recorded in database, error will occur. So we have to deal with this situation.
                        if locusChr.has_key(thisTrait.locus) and locusMb.has_key(thisTrait.locus):
                            text.append(
                                [
                                    str(i + 1),
                                    self.Species,
                                    self.RISet,
                                    thisTrait.db.fullname,
                                    thisTrait.name,
                                    thisTrait.symbol,
                                    thisTrait.description,
                                    thisTrait.probe_target_description,
                                    "",
                                    "",
                                    thisTrait.chr,
                                    thisTrait.mb,
                                    thisTrait.alias,
                                    thisTrait.geneid,
                                    thisTrait.homologeneid,
                                    thisTrait.unigeneid,
                                    thisTrait.strand_probe,
                                    thisTrait.strand_gene,
                                    thisTrait.probe_set_specificity,
                                    thisTrait.probe_set_blat_score,
                                    thisTrait.probe_set_blat_mb_start,
                                    thisTrait.probe_set_blat_mb_end,
                                    locusChr[thisTrait.locus],
                                    locusMb[thisTrait.locus],
                                    thisTrait.locus,
                                    thisTrait.lrs,
                                    thisTrait.pvalue,
                                ]
                            )
                        else:
                            text.append(
                                [
                                    str(i + 1),
                                    self.Species,
                                    self.RISet,
                                    thisTrait.db.fullname,
                                    thisTrait.name,
                                    thisTrait.symbol,
                                    thisTrait.description,
                                    thisTrait.probe_target_description,
                                    "",
                                    "",
                                    thisTrait.chr,
                                    thisTrait.mb,
                                    thisTrait.alias,
                                    thisTrait.geneid,
                                    thisTrait.homologeneid,
                                    thisTrait.unigeneid,
                                    thisTrait.strand_probe,
                                    thisTrait.strand_gene,
                                    thisTrait.probe_set_specificity,
                                    thisTrait.probe_set_blat_score,
                                    thisTrait.probe_set_blat_mb_start,
                                    thisTrait.probe_set_blat_mb_end,
                                    "",
                                    "",
                                    "",
                                    "",
                                    "",
                                ]
                            )
                    else:  # Probe
                        text.append(
                            [
                                str(i + 1),
                                self.Species,
                                self.RISet,
                                thisTrait.db.fullname,
                                thisTrait.name + " : " + thisTrait.cellid,
                                thisTrait.symbol,
                                thisTrait.description,
                                thisTrait.probe_target_description,
                                "",
                                "",
                                thisTrait.chr,
                                thisTrait.mb,
                                thisTrait.alias,
                                thisTrait.geneid,
                                thisTrait.homologeneid,
                                thisTrait.unigeneid,
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                                "",
                            ]
                        )

                elif thisTrait.db.type == "Publish":
                    # XZ: need to consider confidential phenotype
                    PhenotypeString = thisTrait.post_publication_description
                    if thisTrait.confidential:
                        if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(
                            privilege=self.privilege,
                            userName=self.userName,
                            authorized_users=thisTrait.authorized_users,
                        ):
                            PhenotypeString = thisTrait.pre_publication_description
                    text.append(
                        [
                            str(i + 1),
                            self.Species,
                            self.RISet,
                            thisTrait.db.fullname,
                            thisTrait.name,
                            "",
                            "",
                            "",
                            thisTrait.pubmed_id,
                            PhenotypeString,
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                        ]
                    )
                elif thisTrait.db.type == "Temp":
                    text.append(
                        [
                            str(i + 1),
                            self.Species,
                            self.RISet,
                            thisTrait.db.fullname,
                            thisTrait.name,
                            "",
                            thisTrait.description,
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                        ]
                    )
                elif thisTrait.db.type == "Geno":
                    text.append(
                        [
                            str(i + 1),
                            self.Species,
                            self.RISet,
                            thisTrait.db.fullname,
                            thisTrait.name,
                            "",
                            thisTrait.name,
                            "",
                            "",
                            "",
                            thisTrait.chr,
                            thisTrait.mb,
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                            "",
                        ]
                    )
                else:
                    continue

                testval = thisTrait.exportData(strainlist)
                try:
                    mean = reaper.anova(testval)[0]
                except:
                    count = 0
                    sum = 0
                    for oneValue in testval:
                        try:
                            oneValue = float(oneValue)
                            sum = sum + oneValue
                            count = count + 1
                        except:
                            pass
                    if count == 0:
                        mean = 0
                    else:
                        mean = sum / count
                text[-1].append(mean)
                text[-1] += testval
            if len(text[0]) < 255 or len(text) < 255:
                transpose = 0
                if len(text[0]) >= 255:
                    text = webqtlUtil.transpose(text)
                    transpose = 1
                filename = os.path.join(webqtlConfig.TMPDIR, webqtlUtil.generate_session() + ".xls")

                # Create a new Excel workbook
                workbook = xl.Writer(filename)
                worksheet = workbook.add_worksheet()
                headingStyle = workbook.add_format(align="center", bold=1, size=13, color="green")
                titleStyle = workbook.add_format(align="left", bold=0, size=13, border=1, border_color="gray")

                ##Write title Info
                # Modified by Hongqiang Li
                # worksheet.write([0, 0], "Data source: The GeneNetwork at web2qtl.utmem.edu:88", titleStyle)
                # worksheet.write([1, 0], "Citations: Please see web2qtl.utmem.edu:88/reference.html", titleStyle)
                worksheet.write([0, 0], "Data source: The GeneNetwork at %s" % webqtlConfig.PORTADDR, titleStyle)
                worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle)
                #
                worksheet.write([2, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle)
                worksheet.write([3, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle)

                # Modified by Hongqiang Li
                # worksheet.write([4, 0], "Status of data ownership: Possibly unpublished data; please see web2qtl.utmem.edu:88/statusandContact.html for details on sources, ownership, and usage of these data.", titleStyle)
                worksheet.write(
                    [4, 0],
                    "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data."
                    % webqtlConfig.PORTADDR,
                    titleStyle,
                )
                #
                worksheet.write(
                    [6, 0],
                    "This output file contains data from %d GeneNetwork databases listed below" % len(traitList),
                    titleStyle,
                )

                # Row and column are zero indexed
                nrow = startRow = 8
                for row in text:
                    for ncol, cell in enumerate(row):
                        if nrow == startRow:
                            worksheet.write([nrow, ncol], cell.strip(), headingStyle)
                            worksheet.set_column([ncol, ncol], 2 * len(cell))
                        else:
                            worksheet.write([nrow, ncol], cell)
                    nrow += 1

                worksheet.write(
                    [nrow + 1, 0],
                    "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA 21131), NCI MMHCC (U01CA105417), and NCRR (U24 RR021760)",
                    titleStyle,
                )
                worksheet.write([nrow + 2, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle)
                workbook.close()

                fp = open(filename, "rb")
                text = fp.read()
                fp.close()

                self.content_type = "application/xls"
                self.content_disposition = "attachment; filename=%s" % (
                    "export-%s.xls" % time.strftime("%y-%m-%d-%H-%M")
                )
                self.attachment = text
            else:
                self.content_type = "application/xls"
                self.content_disposition = "attachment; filename=%s" % (
                    "export-%s.txt" % time.strftime("%y-%m-%d-%H-%M")
                )
                for item in text:
                    self.attachment += string.join(map(str, item), "\t") + "\n"
            self.cursor.close()
        else:
            fd.req.content_type = "text/html"
            heading = "Export Collection"
            detail = [
                HT.Font("Error : ", color="red"),
                HT.Font("Error occurs while retrieving data from database.", color="black"),
            ]
            self.error(heading=heading, detail=detail)
    def getCollectionTableBody(self, RISet=None, traitList=None, formName=None, species=''):

        tblobj_body = []

        className = "fs12 fwn b1 c222"

        for thisTrait in traitList:
            tr = []

            if not thisTrait.haveinfo:
                thisTrait.retrieveInfo(QTL=1)

            if thisTrait.riset != RISet:
                continue

            trId = str(thisTrait)

            #XZ: check box column
            tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkallbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId))

            #XZ: Dataset column
            tr.append(TDCell(HT.TD(thisTrait.db.displayname, Class="fs12 fwn b1 c222"), thisTrait.db.displayname, thisTrait.db.displayname.upper()))

            #XZ: Trait ID column
            if thisTrait.cellid:
                tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.cellid,url="javascript:showDatabase3('%s','%s','%s','%s')" % (formName, thisTrait.db.name, thisTrait.name, thisTrait.cellid), Class="fs12 fwn"), nowrap="yes",align="left", Class=className),str(thisTrait.cellid), thisTrait.cellid))
            else:
                tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.getGivenName(),url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name, thisTrait.name), Class="fs12 fwn"), nowrap="yes",align="left", Class=className),str(thisTrait.name), thisTrait.name))

            #XZ: Symbol column and Description column
            if (thisTrait.db.type == "Publish"):
                AbbreviationString = "--"
                if (thisTrait.post_publication_abbreviation != None):
                    AbbreviationString = thisTrait.post_publication_abbreviation
                PhenotypeString = thisTrait.post_publication_description
                if thisTrait.confidential:
                    if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users):
                        if thisTrait.pre_publication_abbreviation:
                            AbbreviationString = thisTrait.pre_publication_abbreviation
                        else:
                            AbbreviationString = "--"
                        PhenotypeString = thisTrait.pre_publication_description

                if AbbreviationString == "--":
                    tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
                else:
                    tr.append(TDCell(HT.TD(AbbreviationString, Class=className), AbbreviationString, AbbreviationString.upper()))
                if PhenotypeString:
                    PhenotypeString_upper = PhenotypeString.upper()
                else:
                    PhenotypeString_upper = PhenotypeString
                tr.append(TDCell(HT.TD(PhenotypeString, Class=className), PhenotypeString, PhenotypeString_upper))


            elif (thisTrait.db.type == "ProbeSet" or thisTrait.db.type == "Temp"):
                description_string = str(thisTrait.description).strip()
                if (thisTrait.db.type == "ProbeSet"):
                    if (thisTrait.symbol != None):
                        if thisTrait.geneid:
                            symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % thisTrait.geneid, Class="font_black fs12 fwn")
                        else:
                            symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % thisTrait.symbol, Class="font_black fs12 fwn")
                        tr.append(TDCell(HT.TD(symbolurl, align="left", Class="fs12 fwn b1 c222 fsI"), thisTrait.symbol, thisTrait.symbol))
                    else:
                        tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
                    target_string = str(thisTrait.probe_target_description).strip()

                    description_display = ''

                    if len(description_string) > 1 and description_string != 'None':
                        description_display = description_string
                    else:
                        description_display = thisTrait.symbol

                    if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None':
                        description_display = description_display + '; ' + target_string.strip()

                    description_string = description_display
                else:
                    tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
                tr.append(TDCell(HT.TD(description_string, Class=className), description_string, description_string))
            else:
                if (thisTrait.name != None):
                    tr.append(TDCell(HT.TD(thisTrait.name, Class="fs12 fwn b1 c222"), thisTrait.name, thisTrait.name))
                else:
                    tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
                tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))

            #XZ: Location column
            if (thisTrait.db.type == "Publish"):
                tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", "Zz"))
            else:
                if thisTrait.db.type == "ProbeSet" and thisTrait.cellid:
                    EnsemblProbeSetID = thisTrait.name
                    if '_at' in thisTrait.name:
                        EnsemblProbeSetID = thisTrait.name[0:thisTrait.name.index('_at')+3]

                    #These tables (Ensembl) were created by Xusheng Wang in 2010 and are mm9 (so they'll need to be changed at some point to be mm10.
                    self.cursor.execute('''
                                    SELECT EnsemblProbeLocation.*
                                    FROM EnsemblProbeLocation, EnsemblProbe, EnsemblChip, GeneChipEnsemblXRef, ProbeFreeze, ProbeSetFreeze
                                    WHERE EnsemblProbeLocation.ProbeId=EnsemblProbe.Id and EnsemblProbe.ChipId=GeneChipEnsemblXRef.EnsemblChipId and
                                            GeneChipEnsemblXRef.GeneChipId=ProbeFreeze.ChipId and EnsemblProbe.Name=%s and EnsemblProbe.ProbeSet=%s and
                                            ProbeSetFreeze.Id=%s and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id group by Chr, Start, End'''
                                    ,(thisTrait.cellid, EnsemblProbeSetID, thisTrait.db.id))
                    LocationFields = self.cursor.fetchall()

                    Chr=''
                    Mb=''
                    Start=''
                    End=''
                    if (len(LocationFields)>=1):
                        Chr,Start,Start_2016,End,End_2016,Strand,MisMatch,ProbeId = map(self.nullRecord,LocationFields[0])
                        Start /= 1000000.0
                        End /= 1000000.0
                        Mb = Start
                    if (len(LocationFields)>1):
                        self.cursor.execute('''
                                        SELECT ProbeSet.Chr, ProbeSet.Mb FROM ProbeSet, ProbeFreeze, ProbeSetFreeze
                                        WHERE ProbeSet.ChipId=ProbeFreeze.ChipId and ProbeSet.Name=%s and ProbeSetFreeze.Id=%s and
                                                ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id'''
                                        ,(thisTrait.name, thisTrait.db.id))
                        ProbeSetChr, ProbeSetMb = map(self.nullRecord,self.cursor.fetchall()[0])

                        self.cursor.execute('''
                                        SELECT EnsemblProbeLocation.*, ABS(EnsemblProbeLocation.Start/1000000-%s) as Mb
                                        FROM EnsemblProbeLocation, EnsemblProbe, EnsemblChip, GeneChipEnsemblXRef, ProbeFreeze, ProbeSetFreeze
                                        WHERE EnsemblProbeLocation.ProbeId=EnsemblProbe.Id and EnsemblProbe.ChipId=GeneChipEnsemblXRef.EnsemblChipId and
                                                GeneChipEnsemblXRef.GeneChipId=ProbeFreeze.ChipId and EnsemblProbe.Name=%s and EnsemblProbe.ProbeSet=%s and
                                                EnsemblProbeLocation.Chr=%s and ProbeSetFreeze.Id=%s and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id order by Mb limit 1'''
                                        ,(ProbeSetMb, thisTrait.cellid, EnsemblProbeSetID, ProbeSetChr, thisTrait.db.id))
                        NewLocationFields = self.cursor.fetchall()
                        if (len(NewLocationFields)>0):
                            Chr,Start,Start_2016,End,End_2016,Strand,MisMatch,ProbeId,Mb = map(self.nullRecord,NewLocationFields[0])
                            Start /= 1000000.0
                            End /= 1000000.0
                            Mb = Start

                    #ZS: trait_location_value is used for sorting
                    trait_location_repr = "--"
                    trait_location_value = 1000000

                    if Chr and Mb:
                        try:
                            trait_location_value = int(Chr)*1000 + Mb
                        except:
                            if Chr.upper() == "X":
                                trait_location_value = 20*1000 + Mb
                            else:
                                trait_location_value = ord(str(Chr).upper()[0])*1000 + Mb

                        trait_location_repr = "Chr%s: %.6f" % (Chr, float(Mb) )

                    tr.append(TDCell(HT.TD(trait_location_repr, nowrap='ON', Class=className), trait_location_repr, trait_location_value))

                else:

                    #ZS: trait_location_value is used for sorting
                    trait_location_repr = "--"
                    trait_location_value = 1000000

                    if hasattr(thisTrait, 'chr') and hasattr(thisTrait, 'mb') and thisTrait.chr and thisTrait.mb:
                        try:
                            trait_location_value = int(thisTrait.chr)*1000 + thisTrait.mb
                        except:
                            if thisTrait.chr.upper() == "X":
                                trait_location_value = 20*1000 + thisTrait.mb
                            else:
                                trait_location_value = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb

                        trait_location_repr = "Chr%s: %.6f" % (thisTrait.chr, float(thisTrait.mb) )

                    tr.append(TDCell(HT.TD(trait_location_repr, nowrap='ON', Class=className), trait_location_repr, trait_location_value))

            #XZ: Mean column
            if (thisTrait.db.type == "ProbeSet"):
                if thisTrait.cellid:
                    mean = -10000.0
                    try:
                        thisTrait.retrieveData()
                        mean, median, var, stdev, sem, N = reaper.anova(thisTrait.exportInformative()[1])
                    except:
                        pass
                    repr = '%2.3f' % mean
                    mean = '%2.2f' % mean
                    tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean))
                else:
                    self.cursor.execute("""
                            select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet
                            where ProbeSetXRef.ProbeSetFreezeId = %d and
                                    ProbeSet.Id = ProbeSetXRef.ProbeSetId and
                                    ProbeSet.Name = '%s'
                    """ % (thisTrait.db.id, thisTrait.name))
                    result = self.cursor.fetchone()
                    if result:
                        if result[0]:
                            mean = result[0]
                        else:
                            mean=0
                    else:
                        mean = 0

                    #XZ, 06/05/2009: It is neccessary to turn on nowrap
                    repr = "%2.3f" % mean
                    tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean))

            elif (thisTrait.db.type == "Publish"):
                self.cursor.execute("""
                select count(PublishData.value), sum(PublishData.value) from PublishData, PublishXRef, PublishFreeze
                where PublishData.Id = PublishXRef.DataId and
                        PublishXRef.Id = %s and
                        PublishXRef.InbredSetId = PublishFreeze.InbredSetId and
                        PublishFreeze.Id = %d
                """ % (thisTrait.name, thisTrait.db.id))
                result = self.cursor.fetchone()

                if result:
                    if result[0] and result[1]:
                        mean = result[1]/result[0]
                    else:
                        mean = 0
                else:
                    mean = 0

                repr = "%2.3f" % mean
                tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean))
            else:
                tr.append(TDCell(HT.TD("--", Class=className, align='left', nowrap='ON'),"--", 0))

            #Number of cases
            n_cases_value = 0
            n_cases_repr = "--"
            if (thisTrait.db.type == "Publish"):
                self.cursor.execute("""
                select count(PublishData.value) from PublishData, PublishXRef, PublishFreeze
                where PublishData.Id = PublishXRef.DataId and
                        PublishXRef.Id = %s and
                        PublishXRef.InbredSetId = PublishFreeze.InbredSetId and
                        PublishFreeze.Id = %d
                """ % (thisTrait.name, thisTrait.db.id))
                result = self.cursor.fetchone()

                if result:
                    if result[0]:
                        n_cases_value = result[0]
                        n_cases_repr = result[0]

                if (n_cases_value == "--"):
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='left', nowrap="on"), n_cases_repr, n_cases_value))
                else:
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='right', nowrap="on"), n_cases_repr, n_cases_value))

            elif (thisTrait.db.type == "ProbeSet"):
                self.cursor.execute("""
                select count(ProbeSetData.value) from ProbeSet, ProbeSetXRef, ProbeSetData, ProbeSetFreeze
                where ProbeSet.Name='%s' and
                        ProbeSetXRef.ProbeSetId = ProbeSet.Id and
                        ProbeSetXRef.DataId = ProbeSetData.Id and
                        ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id and
                        ProbeSetFreeze.Name = '%s'
                """ % (thisTrait.name, thisTrait.db.name))
                result = self.cursor.fetchone()

                if result:
                    if result[0]:
                        n_cases_value = result[0]
                        n_cases_repr = result[0]
                if (n_cases_value == "--"):
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='left', nowrap="on"), n_cases_repr, n_cases_value))
                else:
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='right', nowrap="on"), n_cases_repr, n_cases_value))

            elif (thisTrait.db.type == "Geno"):
                self.cursor.execute("""
                select count(GenoData.value) from GenoData, GenoXRef, GenoFreeze, Geno, Strain
                where Geno.SpeciesId = %s and Geno.Name='%s' and
                        GenoXRef.GenoId = Geno.Id and
                        GenoXRef.DataId = GenoData.Id and
                        GenoXRef.GenoFreezeId = GenoFreeze.Id and
                        GenoData.StrainId = Strain.Id and
                        GenoFreeze.Name = '%s'
                """ % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, thisTrait.db.riset), thisTrait.name, thisTrait.db.name))
                result = self.cursor.fetchone()

                if result:
                    if result[0]:
                        n_cases_value = result[0]
                        n_cases_repr = result[0]
                if (n_cases_value == "--"):
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='left', nowrap="on"), n_cases_repr, n_cases_value))
                else:
                    tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='right', nowrap="on"), n_cases_repr, n_cases_value))

            else:
                tr.append(TDCell(HT.TD(n_cases_repr, Class=className, align='left', nowrap="on"), n_cases_repr, n_cases_value))

            #XZ: Max LRS column and Max LRS Location column
            if (thisTrait.db.type != "Geno"):
                #LRS value
                LRS_score_repr = '--'
                LRS_score_value = 0
		if hasattr(thisTrait, 'lrs') and thisTrait.lrs:
			LRS_score_repr = '%3.1f' % thisTrait.lrs
			LRS_score_value = thisTrait.lrs
		tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value))

		#LRS location
                LRS_location_repr = '--'
                LRS_location_value = 1000000
                LRS_flag = 1

                #Max LRS and its Locus location
                if hasattr(thisTrait, 'lrs') and hasattr(thisTrait, 'locus') and thisTrait.lrs and thisTrait.locus:
                    self.cursor.execute("""
                    select Geno.Chr, Geno.Mb from Geno, Species
                    where Species.Name = '%s' and
                            Geno.Name = '%s' and
                            Geno.SpeciesId = Species.Id
                    """ % (species, thisTrait.locus))
                    result = self.cursor.fetchone()

                    if result:
                        if result[0] and result[1]:
                            LRS_Chr = result[0]
                            LRS_Mb = result[1]

                            #XZ: LRS_location_value is used for sorting
                            try:
                                LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb)
                            except:
                                if LRS_Chr.upper() == 'X':
                                    LRS_location_value = 20*1000 + float(LRS_Mb)
                                else:
                                    LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb)

                            LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb))
                            LRS_flag = 0

                            tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value))

                if LRS_flag:
                    tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value))
            else:
                tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", 0))
                tr.append(TDCell(HT.TD("--", align="left", Class=className), "--", 1000000))

            try:
                additive = 	'%3.3f' % thisTrait.additive
            except Exception:
                additive = 	''
            tr.append(TDCell(HT.TD(additive, Class=className, align="right", nowrap="on"), additive, additive))
			
            tblobj_body.append(tr)

        return tblobj_body
	def __init__(self, fd):

		templatePage.__init__(self, fd)

		if not fd.genotype:
			fd.readData()
		
		fd.parentsf14regression = fd.formdata.getvalue('parentsf14regression')
		
		weightedRegression = fd.formdata.getvalue('applyVarianceSE')
		
		if fd.parentsf14regression and fd.genotype_2:
			_genotype = fd.genotype_2
		else:
			_genotype = fd.genotype_1
		
		_strains, _vals, _vars, N = fd.informativeStrains(_genotype.prgy, weightedRegression)
		
		self.data = fd
		if self.data.identification:
			heading2 = HT.Paragraph('Trait ID: %s' % self.data.identification)
			heading2.__setattr__("class","subtitle")
			self.dict['title'] = '%s: Composite Regression' % self.data.identification
		else:
			heading2 = ""
			self.dict['title'] = 'Composite Regression'
		
		if self.data.traitInfo:
			symbol,chromosome,MB = string.split(fd.traitInfo,'\t')
			heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB))
		else:
			heading3 = ""
		if N < webqtlConfig.KMININFORMATIVE:
			heading = "Composite Regression"
			detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, self.data.RISet)]
			self.error(heading=heading,detail=detail)
			return
		else:
			heading = HT.Paragraph('Trait Data Entered for %s Set' % self.data.RISet)
			heading.__setattr__("class","title")
			tt = HT.TableLite()
			for ii in range(N/2):
				tt.append(HT.TR(HT.TD(_strains[2*ii],nowrap="yes"),HT.TD(width=10),  HT.TD(_vals[2*ii], nowrap="yes"), \
				HT.TD(width=20), HT.TD(_strains[2*ii+1],nowrap="yes"),HT.TD(width=10),  HT.TD(_vals[2*ii+1],nowrap="yes")))
			if N % 2:
				tt.append(HT.TR(HT.TD(_strains[N-1],nowrap="yes"),HT.TD(width=10),  HT.TD(_vals[N-1],nowrap="yes"), \
				HT.TD(width=20), HT.TD("",nowrap="yes"),HT.TD(width=10), HT.TD("",nowrap="yes")))
			indata = tt 
			
			mean, median, var, stdev, sem, N = reaper.anova(_vals)
			 
			stats = HT.Paragraph('Number of entered values = %d ' % N,HT.BR(),\
				'Mean value = %8.3f ' % mean, HT.BR(), \
				'Median value = %8.3f ' % median, HT.BR(), \
				'Variance = %8.3f ' % var, HT.BR(), \
				'Standard Deviation = %8.3f ' % stdev, HT.BR(), \
				'Standard Error = %8.3f ' % sem)
				
			self.controlLocus = fd.formdata.getvalue('controlLocus')
			heading4 = HT.Blockquote('Control Background Selected for %s Data Set:' % self.data.RISet)
			heading4.__setattr__("class","subtitle")
			
			datadiv = HT.TD(heading, HT.Center(heading2,heading3,indata, stats, heading4,HT.Center(self.controlLocus)), width='45%',valign='top', bgColor='#eeeeee')
			
			resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars)
			self.dict['body'] = str(datadiv)+str(resultstable)
    def exportDatasetPage(self, fd, PublishFreeze_Name):

        #return PublishFreeze_Name

                if not self.openMysql():
                        return

                self.cursor.execute( "select InbredSet.Name from PublishFreeze, InbredSet where PublishFreeze.InbredSetId=InbredSet.Id and PublishFreeze.Name='%s'" % PublishFreeze_Name )
                self.RISet = self.cursor.fetchone()[0]

                fd.RISet = self.RISet
                fd.incparentsf1 = 1
                fd.readGenotype()
                strainlist = fd.f1list + fd.strainlist

                #return str(strainlist)

                self.cursor.execute("Select Species.Name from Species, InbredSet where InbredSet.SpeciesId = Species.Id and InbredSet.Name = '%s'" % fd.RISet)
                self.Species = self.cursor.fetchone()[0]

                #return Species

                self.searchResult = []

                self.cursor.execute("Select PublishXRef.Id from PublishXRef, InbredSet where PublishXRef.InbredSetId = InbredSet.Id and InbredSet.Name = '%s'" % self.RISet)
                result = self.cursor.fetchall()

                for one_result in result:
                    self.searchResult.append( "%s::%s" % (PublishFreeze_Name, one_result[0]) )
                
                #return self.searchResult

                strainlisthead = []
                for strain in strainlist:
                    strainlisthead += [strain + "_Value"]
                    strainlisthead += [strain + "_SE"]
                    strainlisthead += [strain + "_N"]

                fields = ["Index", "Species", "Cross", "Database", "ProbeSetID/RecordID", "PubMed_ID",
                    "Pre Publication Description", "Post Publication Description", "Original Description", "Pre Publication Abbreviation", "Post Publication Abbreviation",
                    "Mean_Expression"] + strainlisthead

                if self.searchResult:
                        traitList = []
                        for item in self.searchResult:
                                thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
                                thisTrait.retrieveInfo(QTL=1)
                                thisTrait.retrieveData(strainlist=strainlist)
                                traitList.append(thisTrait)

                        text = [fields]
                        for i, thisTrait in enumerate(traitList):
                                text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, thisTrait.pubmed_id,
                                    thisTrait.pre_publication_description, thisTrait.post_publication_description,
                                    thisTrait.original_description,
                                    thisTrait.pre_publication_abbreviation, thisTrait.post_publication_abbreviation])

                                testval = thisTrait.exportData(strainlist)
                                try:
                                    mean = reaper.anova(testval)[0]
                                except:
                                    mean = 'N/A'
                                text[-1].append(mean)
                                testvar = thisTrait.exportData(strainlist, type="var")
                                testn = thisTrait.exportData(strainlist, type="N")
                                testdata = zip(testval, testvar, testn)
                                testdatalist = []
                                for data in testdata:
                                        testdatalist += list(data)
                                text[-1] += testdatalist

                        self.content_type = 'application/xls'
                        self.content_disposition = 'attachment; filename=%s' % ('export-%s.txt' % time.strftime("%y-%m-%d-%H-%M"))
                        self.attachment += ("Data source: The GeneNetwork at %s\n" % webqtlConfig.PORTADDR)
                        self.attachment += ("Citations: Please see %s/reference.html\n" % webqtlConfig.PORTADDR)
                        self.attachment += ("Date: %s\n" % time.strftime("%B %d, %Y", time.gmtime()))
                        self.attachment += ("Time: %s GMT\n" % time.strftime("%H:%M", time.gmtime()))
                        self.attachment += ("Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data.\n" % webqtlConfig.PORTADDR)
                        self.attachment += ("This output file contains data from %d GeneNetwork databases listed below.\n" % len(traitList))
                        self.attachment += ("\n")
                        self.attachment += ("Funding for The GeneNetwork:\n")
                        self.attachment += ("NIGMS Systems Genetics and Precision Medicine project (R01 GM123489, 2017-2021)\n")
                        self.attachment += ("NIDA NIDA Core Center of Excellence in Transcriptomics, Systems Genetics, and the Addictome (P30 DA044223, 2017-2022)\n")
                        self.attachment += ("NIA Translational Systems Genetics of Mitochondria, Metabolism, and Aging (R01AG043930, 2013-2018)\n")
                        self.attachment += ("NIAAA Integrative Neuroscience Initiative on Alcoholism (U01 AA016662, U01 AA013499, U24 AA013513, U01 AA014425, 2006-2017)\n")
                        self.attachment += ("NIDA, NIMH, and NIAAA (P20-DA 21131, 2001-2012)\n")
                        self.attachment += ("NCI MMHCC (U01CA105417), NCRR, BIRN, (U24 RR021760)\n")
                        self.attachment += ("PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE\n")
                        self.attachment += ("\n")
                        for item in text:
                                self.attachment += string.join(map(lambda cell : self.trim(str(cell)), item), '\t') + "\n"
                        self.cursor.close()
                else:
                        fd.req.content_type = 'text/html'
                        heading = 'Export Collection'
                        detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data from database.',color='black')]
                        self.error(heading=heading,detail=detail)
    def exportDatasetPage(self, fd, PublishFreeze_Name):

        #return PublishFreeze_Name

                if not self.openMysql():
                        return

                self.cursor.execute( "select InbredSet.Name from PublishFreeze, InbredSet where PublishFreeze.InbredSetId=InbredSet.Id and PublishFreeze.Name='%s'" % PublishFreeze_Name )
                self.RISet = self.cursor.fetchone()[0]

                fd.RISet = self.RISet
                fd.incparentsf1 = 1
                fd.readGenotype()
                strainlist = fd.f1list + fd.strainlist

                #return str(strainlist)

                self.cursor.execute("Select Species.Name from Species, InbredSet where InbredSet.SpeciesId = Species.Id and InbredSet.Name = '%s'" % fd.RISet)
                self.Species = self.cursor.fetchone()[0]

                #return Species

                self.searchResult = []

                self.cursor.execute("Select PublishXRef.Id from PublishXRef, InbredSet where PublishXRef.InbredSetId = InbredSet.Id and InbredSet.Name = '%s'" % self.RISet)
                result = self.cursor.fetchall()

                for one_result in result:
                    self.searchResult.append( "%s::%s" % (PublishFreeze_Name, one_result[0]) )
                
                #return self.searchResult


                fields = ["ID", "Species", "Cross", "Database", "ProbeSetID / RecordID", "Symbol", "Description", "ProbeTarget", "PubMed_ID", "Phenotype", "Chr", "Mb", "Alias", "Gene_ID", "UniGene_ID", "Strand_Probe ", "Strand_Gene ", 
"Probe_set_specificity", "Probe_set_BLAT_score", "Probe_set_BLAT_Mb_start", "Probe_set_BLAT_Mb_end ", "QTL_Chr", "Locus_at_Peak", "Max_LRS", "P_value_of_MAX", "Mean_Expression"] + strainlist


                if self.searchResult:
                        traitList = []
                        for item in self.searchResult:
                                thisTrait = webqtlTrait(fullname=item, cursor=self.cursor)
                                thisTrait.retrieveInfo(QTL=1)
                                thisTrait.retrieveData(strainlist=strainlist)
                                traitList.append(thisTrait)

                        text = [fields]
                        for i, thisTrait in enumerate(traitList):
                                if thisTrait.db.type == 'ProbeSet':
                                        if not thisTrait.cellid: #ProbeSet
                                                text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, thisTrait.symbol, thisTrait.description, thisTrait.probe_target_description,"", "", thisTrait.chr, thisTrait.mb, thisTrait.alias, thisTrait.geneid, thisTrait.unigeneid, thisTrait.strand_probe, thisTrait.strand_gene, thisTrait.probe_set_specificity, thisTrait.probe_set_blat_score, thisTrait.probe_set_blat_mb_start, thisTrait.probe_set_blat_mb_end, locusChr[thisTrait.locus], thisTrait.locus, thisTrait.lrs, thisTrait.pvalue])
                                        else: #Probe
                                                text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name + " : " + thisTrait.cellid, thisTrait.symbol, thisTrait.description, thisTrait.probe_target_description,"", "", thisTrait.chr, thisTrait.mb, thisTrait.alias, thisTrait.geneid, thisTrait.unigeneid, "", "", "", "", "", "", "", "", "", ""])
                                elif thisTrait.db.type == 'Publish':
                                    if thisTrait.pre_publication_description:
                                        if thisTrait.pubmed_id:
                                            text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, "", "", "", thisTrait.pubmed_id, thisTrait.post_publication_description, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""])
                                        else:
                                            text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, "", "", "", "", thisTrait.pre_publication_description, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""])
                                    else:
                                            text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, "", "", "", thisTrait.pubmed_id, thisTrait.post_publication_description, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""])  

                                elif thisTrait.db.type == 'Temp':
                                        text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, "", thisTrait.description, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""])
                                elif thisTrait.db.type == 'Geno':
                                        text.append([str(i+1), self.Species, self.RISet, thisTrait.db.fullname, thisTrait.name, "", thisTrait.name,"", "", "", thisTrait.chr, thisTrait.mb, "", "", "", "", "", "", "", "", "", "", "", "", ""])
                                else:
                                        continue

                                testval = thisTrait.exportData(strainlist)
                                try:
                                    mean = reaper.anova(testval)[0]
                                except:
                                    mean = 'N/A'
                                text[-1].append(mean)
                                text[-1] += testval
                        if len(text[0]) < 255 or len(text) < 255:
                                transpose = 0
                                if len(text[0]) >= 255:
                                        text = webqtlUtil.transpose(text)
                                        transpose = 1
                                filename = os.path.join(webqtlConfig.TMPDIR, webqtlUtil.generate_session() +'.xls')

                                # Create a new Excel workbook
                                workbook = xl.Writer(filename)
                                worksheet = workbook.add_worksheet()
                                headingStyle = workbook.add_format(align = 'center', bold = 1, size=13, color = 'green')
                                titleStyle = workbook.add_format(align = 'left', bold = 0, size=13, border = 1, border_color="gray")

                                ##Write title Info
                                worksheet.write([0, 0], "Data source: The GeneNetwork at %s" % webqtlConfig.PORTADDR, titleStyle)
                                worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle)
                                worksheet.write([2, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle)
                                worksheet.write([3, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle)
                                worksheet.write([4, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle)
                                worksheet.write([6, 0], "This output file contains data from %d GeneNetwork databases listed below" % len(traitList), titleStyle)

                                # Row and column are zero indexed
                                nrow = startRow = 8
                                for row in text:
                                    for ncol, cell in enumerate(row):
                                        if nrow == startRow:
                                                worksheet.write([nrow, ncol], cell.strip(), headingStyle)
                                                worksheet.set_column([ncol, ncol], 2*len(cell))
                                        else:
                                                worksheet.write([nrow, ncol], cell)
                                    nrow += 1

                                worksheet.write([nrow+1, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA 21131), NCI MMHCC (U01CA105417), and NCRR (U24 RR021760)", titleStyle)
                                worksheet.write([nrow+2, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle)
                                workbook.close()

                                fp = open(filename, 'rb')
                                text = fp.read()
                                fp.close()

                                self.content_type = 'application/xls'
                                self.content_disposition = 'attachment; filename=%s' % ('export-%s.xls' % time.strftime("%y-%m-%d-%H-%M"))
                                self.attachment = text
                        else:
                                self.content_type = 'application/xls'
                                self.content_disposition = 'attachment; filename=%s' % ('export-%s.txt' % time.strftime("%y-%m-%d-%H-%M"))
                                for item in text:
                                        self.attachment += string.join(map(str, item), '\t')+ "\n"
                        self.cursor.close()
                else:
                        fd.req.content_type = 'text/html'
                        heading = 'Export Collection'
                        detail = [HT.Font('Error : ',color='red'),HT.Font('Error occurs while retrieving data from database.',color='black')]
                        self.error(heading=heading,detail=detail)
    def __init__(self, fd):

        templatePage.__init__(self, fd)

        if not fd.genotype:
            fd.readGenotype()
            strainlist2 = fd.strainlist

        if fd.allstrainlist:
            strainlist2 = fd.allstrainlist

        fd.readData(strainlist2)

        specialStrains = []
        setStrains = []
        for item in strainlist2:
            if item not in fd.strainlist and item.find('F1') < 0:
                specialStrains.append(item)
            else:
                setStrains.append(item)
        specialStrains.sort()
        #So called MDP Panel
        if specialStrains:
            specialStrains = fd.f1list+fd.parlist+specialStrains

        self.plotType = fd.formdata.getvalue('ptype', '0')
        plotStrains = strainlist2
        if specialStrains:
            if self.plotType == '1':
                plotStrains = setStrains
            if self.plotType == '2':
                plotStrains = specialStrains

        self.dict['title'] = 'Basic Statistics'
        if not self.openMysql():
            return

        self.showstrains = 1
        self.identification = "unnamed trait"

        self.fullname = fd.formdata.getvalue('fullname', '')
        if self.fullname:
            self.Trait = webqtlTrait(fullname=self.fullname, cursor=self.cursor)
            self.Trait.retrieveInfo()
        else:
            self.Trait = None

        if fd.identification:
            self.identification = fd.identification
            self.dict['title'] = self.identification + ' / '+self.dict['title']
        TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee')

        ##should not display Variance, but cannot convert Variance to SE
        #print plotStrains, fd.allTraitData.keys()
        if len(fd.allTraitData) > 0:
            vals=[]
            InformData = []
            for _strain in plotStrains:
                if fd.allTraitData.has_key(_strain):
                    _val, _var = fd.allTraitData[_strain].val, fd.allTraitData[_strain].var
                    if _val != None:
                        vals.append([_strain, _val, _var])
                        InformData.append(_val)

            if len(vals) >= self.plotMinInformative:
                supertable2 = HT.TableLite(border=0, cellspacing=0, cellpadding=5,width="800")

                staIntro1 = HT.Paragraph("The table and plots below list the basic statistical analysis result of trait",HT.Strong(" %s" % self.identification))

                #####
                #anova
                #####
                traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(InformData)
                TDStatis = HT.TD(width="360", valign="top")
                tbl2 = HT.TableLite(cellpadding=5, cellspacing=0, Class="collap")
                dataXZ = vals[:]
                dataXZ.sort(self.cmpValue)
                tbl2.append(HT.TR(HT.TD("Statistic",align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 200),
                                HT.TD("Value", align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 140)))
                tbl2.append(HT.TR(HT.TD("N of Cases",align="center", Class="fs13 b1 cbw c222"),
                                HT.TD(N,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("Mean",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%2.3f" % traitmean,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("Median",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%2.3f" % traitmedian,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                #tbl2.append(HT.TR(HT.TD("Variance",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                #               HT.TD("%2.3f" % traitvar,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("SEM",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%2.3f" % traitsem,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("SD",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%2.3f" % traitstdev,nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("Minimum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%s" % dataXZ[0][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                tbl2.append(HT.TR(HT.TD("Maximum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                                HT.TD("%s" % dataXZ[-1][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                if self.Trait and self.Trait.db.type == 'ProbeSet':
                    #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14")
                    #IRQuest.append(HT.BR())
                    #IRQuest.append(" (fold difference)")
                    tbl2.append(HT.TR(HT.TD("Range (log2)",align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                            HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                    tbl2.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                            HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                    tbl2.append(HT.TR(HT.TD(HT.Span("Quartile Range",HT.BR()," (fold difference)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),
                            HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222")))

                    # (Lei Yan)
                    # 2008/12/19
                    self.Trait.retrieveData()
                    #XZ, 04/01/2009: don't try to get H2 value for probe.
                    if self.Trait.cellid:
                        pass
                    else:
                        self.cursor.execute("SELECT DataId, h2 from ProbeSetXRef WHERE DataId = %d" % self.Trait.mysqlid)
                        dataid, heritability = self.cursor.fetchone()
                        if heritability:
                            tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222")))
                        else:
                            tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("NaN", nowrap="yes",align="center", Class="fs13 b1 cbw c222")))

                    # Lei Yan
                    # 2008/12/19

                TDStatis.append(tbl2)

                plotHeight = 220
                plotWidth = 120
                xLeftOffset = 60
                xRightOffset = 25
                yTopOffset = 20
                yBottomOffset = 53

                canvasHeight = plotHeight + yTopOffset + yBottomOffset
                canvasWidth = plotWidth + xLeftOffset + xRightOffset
                canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight))
                XXX = [('', InformData[:])]

                Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait")
                filename= webqtlUtil.genRandStr("Box_")
                canvas.save(webqtlConfig.IMGDIR+filename, format='gif')
                img=HT.Image('/image/'+filename+'.gif',border=0)

                #supertable2.append(HT.TR(HT.TD(staIntro1, colspan=3 )))
                tb = HT.TableLite(border=0, cellspacing=0, cellpadding=0)
                tb.append(HT.TR(HT.TD(img, align="left", style="border: 1px solid #999999; padding:0px;")))
                supertable2.append(HT.TR(TDStatis, HT.TD(tb)))

                dataXZ = vals[:]
                tvals = []
                tnames = []
                tvars = []
                for i in range(len(dataXZ)):
                    tvals.append(dataXZ[i][1])
                    tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0]))
                    tvars.append(dataXZ[i][2])
                nnStrain = len(tnames)

                sLabel = 1

                ###determine bar width and space width
                if nnStrain < 20:
                    sw = 4
                elif nnStrain < 40:
                    sw = 3
                else:
                    sw = 2

                ### 700 is the default plot width minus Xoffsets for 40 strains
                defaultWidth = 650
                if nnStrain > 40:
                    defaultWidth += (nnStrain-40)*10
                defaultOffset = 100
                bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain)
                if bw < 10:
                    bw = 10

                plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset
                plotHeight = 500
                #print [plotWidth, plotHeight, bw, sw, nnStrain]
                c = pid.PILCanvas(size=(plotWidth,plotHeight))
                Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (sorted by name)' % self.identification, sLabel = sLabel, barSpace = sw)

                filename= webqtlUtil.genRandStr("Bar_")
                c.save(webqtlConfig.IMGDIR+filename, format='gif')
                img0=HT.Image('/image/'+filename+'.gif',border=0)

                dataXZ = vals[:]
                dataXZ.sort(self.cmpValue)
                tvals = []
                tnames = []
                tvars = []
                for i in range(len(dataXZ)):
                    tvals.append(dataXZ[i][1])
                    tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0]))
                    tvars.append(dataXZ[i][2])

                c = pid.PILCanvas(size=(plotWidth,plotHeight))
                Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (ranked)' % self.identification, sLabel = sLabel, barSpace = sw)

                filename= webqtlUtil.genRandStr("Bar_")
                c.save(webqtlConfig.IMGDIR+filename, format='gif')
                img1=HT.Image('/image/'+filename+'.gif',border=0)

                # Lei Yan
                # 05/18/2009
                # report

                title = HT.Paragraph('REPORT on the variation of Shh (or PCA Composite Trait XXXX) (sonic hedgehog) in the (insert Data set name) of (insert Species informal name, e.g., Mouse, Rat, Human, Barley, Arabidopsis)', Class="title")
                header = HT.Paragraph('''This report was generated by GeneNetwork on May 11, 2009, at 11.20 AM using the Basic Statistics module (v 1.0) and data from the Hippocampus Consortium M430v2 (Jun06) PDNN data set. For more details and updates on this data set please link to URL:get Basic Statistics''')
                hr = HT.HR()
                p1 = HT.Paragraph('''Trait values for Shh were taken from the (insert Database name, Hippocampus Consortium M430v2 (Jun06) PDNN). GeneNetwork contains data for NN (e.g., 99) cases. In general, data are averages for each case. A summary of mean, median, and the range of these data are provided in Table 1 and in the box plot (Figure 1). Data for individual cases are provided in Figure 2A and 2B, often with error bars (SEM). ''')
                p2 = HT.Paragraph('''Trait values for Shh range 5.1-fold: from a low of 8.2 (please round value) in 129S1/SvImJ to a high of 10.6 (please round value) in BXD9.  The interquartile range (the difference between values closest to the 25% and 75% levels) is a more modest 1.8-fold. The mean value is XX. ''')
                t1 = HT.Paragraph('''Table 1.  Summary of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''')
                f1 = HT.Paragraph('''Figure 1. ''')
                f1.append(HT.Href(text="Box plot", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs14"))
                f1.append(HT.Text(''' of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set'''))
                f2A = HT.Paragraph('''Figure 2A: Bar chart of Shh data ordered by case from the Hippocampus Consortium M430v2 (june06) PDNN data set''')
                f2B = HT.Paragraph('''Figure 2B: Bar chart of Shh values ordered by from the Hippocampus Consortium M430v2 (june06) PDNN data set''')
                TD_LR.append(HT.Blockquote(title, HT.P(), header, hr, p1, HT.P(), p2, HT.P(), supertable2, t1, f1, HT.P(), img0, f2A, HT.P(), img1, f2B))
                self.dict['body'] = str(TD_LR)
            else:
                heading = "Basic Statistics"
                detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)]
                self.error(heading=heading,detail=detail)
                return
        else:
            heading = "Basic Statistics"
            detail = ['Empty data set, please check your data.']
            self.error(heading=heading,detail=detail)
            return